Skip to content

Commit

Permalink
Stringify names with unsafe text chars after
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Sep 3, 2024
1 parent e537daa commit c909d1f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
16 changes: 16 additions & 0 deletions src/cases.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ export const PARSER_TESTS: ParserTestSet[] = [
{ type: "wildcard", name: "path" },
]),
},
{
path: '/:"test"stuff',
expected: new TokenData([
{ type: "text", value: "/" },
{ type: "param", name: "test" },
{ type: "text", value: "stuff" },
]),
},
];

export const STRINGIFY_TESTS: StringifyTestSet[] = [
Expand Down Expand Up @@ -152,6 +160,14 @@ export const STRINGIFY_TESTS: StringifyTestSet[] = [
data: new TokenData([{ type: "text", value: "/:+?*" }]),
expected: "/\\:\\+\\?\\*",
},
{
data: new TokenData([
{ type: "text", value: "/" },
{ type: "param", name: "test" },
{ type: "text", value: "stuff" },
]),
expected: '/:"test"stuff',
},
];

export const COMPILE_TESTS: CompileTestSet[] = [
Expand Down
32 changes: 19 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,25 +607,31 @@ function negate(delimiter: string, backtrack: string) {
* Stringify token data into a path string.
*/
export function stringify(data: TokenData) {
return data.tokens.map(stringifyToken).join("");
}

function stringifyToken(token: Token): string {
if (token.type === "text") return escapeText(token.value);
if (token.type === "group") {
return `{${token.tokens.map(stringifyToken).join("")}}`;
}
return data.tokens
.map(function stringifyToken(token, index, tokens): string {
if (token.type === "text") return escapeText(token.value);
if (token.type === "group") {
return `{${token.tokens.map(stringifyToken).join("")}}`;
}

const isSafe = isNameSafe(token.name);
const key = isSafe ? token.name : JSON.stringify(token.name);
const isSafe =
isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);
const key = isSafe ? token.name : JSON.stringify(token.name);

if (token.type === "param") return `:${key}`;
if (token.type === "wildcard") return `*${key}`;
throw new TypeError(`Unexpected token: ${token}`);
if (token.type === "param") return `:${key}`;
if (token.type === "wildcard") return `*${key}`;
throw new TypeError(`Unexpected token: ${token}`);
})
.join("");
}

function isNameSafe(name: string) {
const [first, ...rest] = name;
if (!ID_START.test(first)) return false;
return rest.every((char) => ID_CONTINUE.test(char));
}

function isNextNameSafe(token: Token | undefined) {
if (token?.type !== "text") return true;
return !ID_CONTINUE.test(token.value[0]);
}

0 comments on commit c909d1f

Please sign in to comment.