feat: export slugifyPath as public utility

This commit is contained in:
saberzero1 2026-03-20 11:19:40 +01:00
parent d7d93758b2
commit e0b3f658b9
No known key found for this signature in database
9 changed files with 65 additions and 9 deletions

2
dist/index.d.ts vendored
View file

@ -1,4 +1,4 @@
export { RelativeURL, SimpleSlug, TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix } from './path.js';
export { RelativeURL, SimpleSlug, TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix } from './path.js';
export { normalizeRelativeURLs, registerEscapeHandler, removeAllChildren } from './dom.js';
export { capitalize, classNames } from './lang.js';
export { escapeHTML, unescapeHTML } from './escape.js';

7
dist/index.js vendored
View file

@ -172,11 +172,14 @@ function transformLink(src, target, opts) {
return joinSegments(pathToRoot(src), canonicalSlug) + folderTail;
}
}
function _sluggify(s) {
function slugifyPath(s) {
return s.split("/").map(
(segment) => segment.replace(/\s/g, "-").replace(/&/g, "-and-").replace(/%/g, "-percent").replace(/\?/g, "").replace(/#/g, "")
).join("/").replace(/\/$/, "");
}
function _sluggify(s) {
return slugifyPath(s);
}
function _containsForbiddenCharacters(s) {
return s.includes(" ") || s.includes("#") || s.includes("?") || s.includes("&");
}
@ -284,6 +287,6 @@ function htmlToJsx(tree, components) {
});
}
export { capitalize, classNames, endsWith, escapeHTML, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, htmlToJsx, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, normalizeRelativeURLs, pathToRoot, registerEscapeHandler, removeAllChildren, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix, unescapeHTML };
export { capitalize, classNames, endsWith, escapeHTML, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, htmlToJsx, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, normalizeRelativeURLs, pathToRoot, registerEscapeHandler, removeAllChildren, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix, unescapeHTML };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

8
dist/path.d.ts vendored
View file

@ -42,5 +42,11 @@ declare function splitAnchor(link: string): [string, string];
declare function slugTag(tag: string): string;
declare function transformInternalLink(link: string): RelativeURL;
declare function transformLink(src: FullSlug, target: string, opts: TransformOptions): RelativeURL;
/**
* Slugify a file path for use as an href.
* Replaces whitespacehyphens, &-and-, %-percent, removes ? and #.
* Operates per segment so directory separators are preserved.
*/
declare function slugifyPath(s: string): string;
export { type RelativeURL, type SimpleSlug, type TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };
export { type RelativeURL, type SimpleSlug, type TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };

7
dist/path.js vendored
View file

@ -169,11 +169,14 @@ function transformLink(src, target, opts) {
return joinSegments(pathToRoot(src), canonicalSlug) + folderTail;
}
}
function _sluggify(s) {
function slugifyPath(s) {
return s.split("/").map(
(segment) => segment.replace(/\s/g, "-").replace(/&/g, "-and-").replace(/%/g, "-percent").replace(/\?/g, "").replace(/#/g, "")
).join("/").replace(/\/$/, "");
}
function _sluggify(s) {
return slugifyPath(s);
}
function _containsForbiddenCharacters(s) {
return s.includes(" ") || s.includes("#") || s.includes("?") || s.includes("&");
}
@ -193,6 +196,6 @@ function _addRelativeToStart(s) {
return s;
}
export { endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };
export { endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };
//# sourceMappingURL=path.js.map
//# sourceMappingURL=path.js.map

2
dist/path.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -21,6 +21,7 @@ export {
pathToRoot,
resolveRelative,
splitAnchor,
slugifyPath,
slugTag,
transformInternalLink,
transformLink,

View file

@ -245,7 +245,12 @@ export function transformLink(src: FullSlug, target: string, opts: TransformOpti
}
}
function _sluggify(s: string): string {
/**
* Slugify a file path for use as an href.
* Replaces whitespacehyphens, &-and-, %-percent, removes ? and #.
* Operates per segment so directory separators are preserved.
*/
export function slugifyPath(s: string): string {
return s
.split("/")
.map((segment) =>
@ -260,6 +265,11 @@ function _sluggify(s: string): string {
.replace(/\/$/, "");
}
/** @internal */
function _sluggify(s: string): string {
return slugifyPath(s);
}
function _containsForbiddenCharacters(s: string): boolean {
return s.includes(" ") || s.includes("#") || s.includes("?") || s.includes("&");
}

View file

@ -9,6 +9,7 @@ import {
stripSlashes,
isFolderPath,
getAllSegmentPrefixes,
slugifyPath,
} from "../src/path.js";
describe("simplifySlug", () => {
@ -136,3 +137,35 @@ describe("resolveBasePath", () => {
expect(resolveBasePath("page")).toBe("/page");
});
});
describe("slugifyPath", () => {
it("replaces spaces with hyphens", () => {
expect(slugifyPath("Arcanist's Folly")).toBe("Arcanist's-Folly");
});
it("replaces ampersands with -and-", () => {
expect(slugifyPath("Arts & Crafts")).toBe("Arts--and--Crafts");
});
it("replaces percent with -percent", () => {
expect(slugifyPath("100%")).toBe("100-percent");
});
it("removes question marks and hash signs", () => {
expect(slugifyPath("What?#Section")).toBe("WhatSection");
});
it("handles multi-segment paths", () => {
expect(slugifyPath("Compendium/Species/Ratkin/Deific Exaltation")).toBe(
"Compendium/Species/Ratkin/Deific-Exaltation",
);
});
it("strips trailing slashes", () => {
expect(slugifyPath("folder/")).toBe("folder");
});
it("leaves clean paths unchanged", () => {
expect(slugifyPath("Compendium/Species/Dryad/Apple")).toBe("Compendium/Species/Dryad/Apple");
});
});