diff --git a/src/index.spec.ts b/src/index.spec.ts index f807e48..88f9caf 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -81,12 +81,22 @@ const COMPILE_TESTS: CompileTestSet[] = [ { input: undefined, expected: null }, { input: {}, expected: null }, { input: { test: "123" }, expected: "/123" }, - { input: { test: "123/xyz" }, expected: null }, // Requires encoding. + { input: { test: "123/xyz" }, expected: "/123%2Fxyz" }, ], }, { path: "/:test", options: { validate: false }, + tests: [ + { input: undefined, expected: null }, + { input: {}, expected: null }, + { input: { test: "123" }, expected: "/123" }, + { input: { test: "123/xyz" }, expected: "/123%2Fxyz" }, + ], + }, + { + path: "/:test", + options: { validate: false, encode: false }, tests: [ { input: undefined, expected: null }, { input: {}, expected: null }, @@ -116,16 +126,18 @@ const COMPILE_TESTS: CompileTestSet[] = [ }, { path: "/:test?", + options: { encode: false }, tests: [ { input: undefined, expected: "" }, { input: {}, expected: "" }, { input: { test: undefined }, expected: "" }, { input: { test: "123" }, expected: "/123" }, - { input: { test: "123/xyz" }, expected: null }, // Requires encoding. + { input: { test: "123/xyz" }, expected: null }, ], }, { path: "/:test(.*)", + options: { encode: false }, tests: [ { input: undefined, expected: null }, { input: {}, expected: null }, @@ -134,6 +146,30 @@ const COMPILE_TESTS: CompileTestSet[] = [ { input: { test: "123/xyz" }, expected: "/123/xyz" }, ], }, + { + path: "/:test*", + tests: [ + { input: undefined, expected: "" }, + { input: {}, expected: "" }, + { input: { test: [] }, expected: "" }, + { input: { test: [""] }, expected: null }, + { input: { test: ["123"] }, expected: "/123" }, + { input: { test: "123/xyz" }, expected: null }, + { input: { test: ["123", "xyz"] }, expected: "/123/xyz" }, + ], + }, + { + path: "/:test*", + options: { encode: false }, + tests: [ + { input: undefined, expected: "" }, + { input: {}, expected: "" }, + { input: { test: "" }, expected: null }, + { input: { test: "123" }, expected: "/123" }, + { input: { test: "123/xyz" }, expected: "/123/xyz" }, + { input: { test: ["123", "xyz"] }, expected: null }, + ], + }, ]; /** @@ -235,7 +271,7 @@ const MATCH_TESTS: MatchTestSet[] = [ expected: { path: "/caf%C3%A9", index: 0, - params: { test: "caf%C3%A9" }, + params: { test: "café" }, }, }, { @@ -531,7 +567,7 @@ const MATCH_TESTS: MatchTestSet[] = [ expected: { path: "/caf%C3%A9", index: 0, - params: { test: "caf%C3%A9" }, + params: { test: "café" }, }, }, ], @@ -2257,13 +2293,17 @@ const MATCH_TESTS: MatchTestSet[] = [ { path: "/:foo", options: { - decode: encodeURIComponent, + decode: false, }, tests: [ { - input: "/café", - matches: ["/café", "café"], - expected: { path: "/café", index: 0, params: { foo: "caf%C3%A9" } }, + input: "/caf%C3%A9", + matches: ["/caf%C3%A9", "caf%C3%A9"], + expected: { + path: "/caf%C3%A9", + index: 0, + params: { foo: "caf%C3%A9" }, + }, }, ], }, @@ -2771,6 +2811,22 @@ const MATCH_TESTS: MatchTestSet[] = [ }, ], }, + { + path: "*", + options: { decode: false }, + tests: [ + { + input: "/", + matches: ["/", "/"], + expected: { path: "/", index: 0, params: { "0": "/" } }, + }, + { + input: "/test", + matches: ["/test", "/test"], + expected: { path: "/test", index: 0, params: { "0": "/test" } }, + }, + ], + }, /** * No loose. diff --git a/src/index.ts b/src/index.ts index 6615fb9..82961d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -54,7 +54,7 @@ export interface MatchOptions extends PathToRegexpOptions { /** * Function for decoding strings for params. */ - decode?: Decode; + decode?: Decode | false; } export interface CompileOptions extends ParseOptions { @@ -73,7 +73,7 @@ export interface CompileOptions extends ParseOptions { /** * Function for encoding input strings for output into the path. (default: `encodeURIComponent`) */ - encode?: Encode; + encode?: Encode | false; } type TokenType = @@ -383,20 +383,21 @@ export type PathFunction

= (data?: P) => string; */ function tokenToFunction( token: Token, - encode: Encode, + encode: Encode | false, ): (data: ParamData) => string { if (typeof token === "string") { return () => token; } const optional = token.modifier === "?" || token.modifier === "*"; + const encodeValue = encode || NOOP_VALUE; - if (token.separator) { + if (encode && token.separator) { const stringify = (value: string, index: number) => { if (typeof value !== "string") { throw new TypeError(`Expected "${token.name}/${index}" to be a string`); } - return encode(value); + return encodeValue(value); }; const compile = (value: unknown) => { @@ -429,7 +430,7 @@ function tokenToFunction( if (typeof value !== "string") { throw new TypeError(`Expected "${token.name}" to be a string`); } - return token.prefix + encode(value) + token.suffix; + return token.prefix + encodeValue(value) + token.suffix; }; if (optional) { @@ -454,9 +455,9 @@ function compileTokens

( options: CompileOptions, ): PathFunction

{ const { - encode = NOOP_VALUE, - validate = true, + encode = encodeURIComponent, loose = DEFAULT_DELIMITER, + validate = true, } = options; const reFlags = flags(options); const stringify = toStringify(loose); @@ -527,17 +528,16 @@ function matchRegexp

( re: PathRegExp, options: MatchOptions, ): MatchFunction

{ - const { decode = NOOP_VALUE, loose = DEFAULT_DELIMITER } = options; + const { decode = decodeURIComponent, loose = DEFAULT_DELIMITER } = options; const stringify = toStringify(loose); const decoders = re.keys.map((key) => { - if (key.separator) { + if (decode && key.separator) { const re = new RegExp(stringify(key.separator), "g"); - return (value: string) => value.split(re).map(decode); } - return decode; + return decode || NOOP_VALUE; }); return function match(pathname: string) {