feat: remove the 10,000-character article body limit and make the New article body optional

This commit is contained in:
Florian Sylvain committed 2026-10-11 08:49:11 +02:00
1 parent 5e05b606a7
commit 10ec74c8cf
28 files changed
+860 -397

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
import { describe, expect, it } from 'vitest'
import { bodyCounts, isLargeBody, LARGE_BODY_CHARACTERS } from '../bodyCounts'
describe('bodyCounts', () => {
it('counts words across block boundaries and characters as the string length', () => {
const html =
'<h2>Price</h2><ul><li>One</li><li>Two</li></ul><p>A <strong>bold</strong> end.</p>'
expect(bodyCounts(html)).toEqual({ words: 6, characters: html.length })
})
it('splits adjacent blocks and line breaks into separate words', () => {
expect(bodyCounts('<p>one</p><p>two</p>').words).toBe(2)
expect(bodyCounts('<p>one<br>two</p>').words).toBe(2)
expect(bodyCounts('<p> one two </p>').words).toBe(2)
})
it('counts no words in markup without text', () => {
expect(bodyCounts('<p> </p>')).toEqual({ words: 0, characters: 8 })
})
it('reads an empty document as zero', () => {
expect(bodyCounts('')).toEqual({ words: 0, characters: 0 })
expect(bodyCounts('<p></p>')).toEqual({ words: 0, characters: 0 })
})
})
describe('isLargeBody', () => {
it('flips exactly at the threshold', () => {
expect(isLargeBody(LARGE_BODY_CHARACTERS - 1)).toBe(false)
expect(isLargeBody(LARGE_BODY_CHARACTERS)).toBe(true)
})
})
+23
View File
@@ -0,0 +1,23 @@
const HTML_MIME = 'text/html'
const WHITESPACE = /\s+/
const EMPTY_DOCUMENT = '<p></p>'
const BLOCK_END = /<\/(?:p|h[1-6]|li|blockquote|pre|div)>|<br\s*\/?>/gi
export const LARGE_BODY_CHARACTERS = 50000
export function isLargeBody(characters: number) {
return characters >= LARGE_BODY_CHARACTERS
}
export type BodyCounts = { words: number; characters: number }
export function bodyCounts(html: string): BodyCounts {
if (html.length === 0 || html === EMPTY_DOCUMENT) {
return { words: 0, characters: 0 }
}
const text =
new DOMParser().parseFromString(html.replace(BLOCK_END, '$& '), HTML_MIME).body
.textContent ?? ''
const words = text.split(WHITESPACE).filter(Boolean).length
return { words, characters: html.length }
}