* test(#2849): add failing regression for trailing-hyphen-after-truncation The strip ran before .substring(0, 60), so a cut landing on a separator produced a slug ending in '-'. Four cases: the exact issue repro (59 a's + space + tail), a boundary landing before a separator, leading-hyphen survival, and a long-Cyrillic transliteration+truncation case. * fix(#2849): strip trailing hyphen after 60-char truncation generateSlugInternal ran the ^-+|-+$ hyphen strip BEFORE .substring(0, 60), so a title whose 60-character cut landed on a separator yielded a slug ending in '-' — the very thing the strip step exists to prevent. Reorder so the strip runs after truncation. Truncation cannot introduce a leading hyphen, so the full ^-+|-+$ pass last is equivalent for leading hyphens and fixes the trailing-hyphen-after-truncation case. Latin-script output for titles ≤ 60 chars is byte-identical; only titles whose truncation boundary lands on a separator change (from broken to clean). * test(#2849): add all-separator collapses-to-empty boundary case Surfaced by isolated adversarial review: pin the contract that input which is entirely separators ('!!!', '!'.repeat(70)) reduces to '' — not null, not a stray hyphen — both short and past the 60-char truncation. * chore(#2849): add changeset fragment pr:0 placeholder; will backfill the real PR number after the PR exists. * chore(#2849): backfill changeset PR number 2967 --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -95,7 +95,12 @@ function pathExistsInternal(cwd: string, targetPath: string): boolean {
|
||||
|
||||
function generateSlugInternal(text: string | null | undefined): string | null {
|
||||
if (!text) return null;
|
||||
return transliterateForSlug(text).replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').substring(0, 60);
|
||||
// #2849: strip leading/trailing hyphens AFTER truncation, not only before.
|
||||
// .substring(0, 60) can land on a separator, re-introducing a trailing hyphen
|
||||
// the strip step exists to prevent. Truncation cannot add a leading hyphen, so
|
||||
// running the full ^-+|-+$ pass last is equivalent for leading hyphens and
|
||||
// fixes the trailing-hyphen-after-truncation case.
|
||||
return transliterateForSlug(text).replace(/[^a-z0-9]+/g, '-').substring(0, 60).replace(/^-+|-+$/g, '');
|
||||
}
|
||||
|
||||
// ─── Transliteration (#2848) ─────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user