Skip to content

Commit

Permalink
Remove redundant tokensToRegexp helper
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Jul 31, 2024
1 parent 08a00a1 commit cbf0cb9
Showing 1 changed file with 31 additions and 42 deletions.
73 changes: 31 additions & 42 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,61 +365,61 @@ export function isOptional(key: Key) {
* Convert a single token into a path building function.
*/
function keyToFunction(
token: Key,
key: Key,
encode: Encode | false,
): (data: ParamData) => string {
const encodeValue = encode || NOOP_VALUE;
const { prefix = "", suffix = "", separator = suffix + prefix } = token;
const { prefix = "", suffix = "", separator = suffix + prefix } = key;

if (encode && isRepeat(token)) {
if (encode && isRepeat(key)) {
const stringify = (value: string, index: number) => {
if (typeof value !== "string") {
throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
throw new TypeError(`Expected "${key.name}/${index}" to be a string`);
}
return encodeValue(value);
};

const compile = (value: unknown) => {
if (!Array.isArray(value)) {
throw new TypeError(`Expected "${token.name}" to be an array`);
throw new TypeError(`Expected "${key.name}" to be an array`);
}

if (value.length === 0) return "";

return prefix + value.map(stringify).join(separator) + suffix;
};

if (isOptional(token)) {
if (isOptional(key)) {
return (data): string => {
const value = data[token.name];
const value = data[key.name];
if (value == null) return "";
return value.length ? compile(value) : "";
};
}

return (data): string => {
const value = data[token.name];
const value = data[key.name];
return compile(value);
};
}

const stringify = (value: unknown) => {
if (typeof value !== "string") {
throw new TypeError(`Expected "${token.name}" to be a string`);
throw new TypeError(`Expected "${key.name}" to be a string`);
}
return prefix + encodeValue(value) + suffix;
};

if (isOptional(token)) {
if (isOptional(key)) {
return (data): string => {
const value = data[token.name];
const value = data[key.name];
if (value == null) return "";
return stringify(value);
};
}

return (data): string => {
const value = data[token.name];
const value = data[key.name];
return stringify(value);
};
}
Expand Down Expand Up @@ -480,18 +480,7 @@ export type Match<P extends ParamData> = false | MatchResult<P>;
/**
* The match function takes a string and returns whether it matched the path.
*/
export type MatchFunction<P extends ParamData> = ((
path: string,
) => Match<P>) & { re: RegExp };

const isEnd = (input: string, match: string) => input.length === match.length;
const isDelimiterOrEnd =
(delimiter: string) => (input: string, match: string) => {
return (
match.length === input.length ||
input.slice(match.length, match.length + delimiter.length) === delimiter
);
};
export type MatchFunction<P extends ParamData> = (path: string) => Match<P>;

/**
* Create path match function from `path-to-regexp` spec.
Expand All @@ -501,32 +490,43 @@ export function $match<P extends ParamData>(
options: MatchOptions = {},
): MatchFunction<P> {
const { decode = decodeURIComponent, end = true } = options;
const re = tokensToRegexp(data, options);
const { delimiter } = data;
const keys: Key[] = [];
const flags = toFlags(options);
const sources = toRegExpSource(data, keys);
const re = new RegExp(
`^${sources.join("")}(?=${escape(delimiter)}|$)`,
flags,
);

const decoders = keys.map((key) => {
if (!decode) return NOOP_VALUE;

const decoders = re.keys.map((key) => {
if (decode && (key.modifier === "+" || key.modifier === "*")) {
if (isRepeat(key)) {
const { prefix = "", suffix = "", separator = suffix + prefix } = key;
return (value: string) => value.split(separator).map(decode);
}

return decode || NOOP_VALUE;
return decode;
});

const validate = end ? isEnd : isDelimiterOrEnd(data.delimiter);
const isValid = end
? (a: string, b: string) => a.length === b.length
: () => true;

return Object.assign(
function match(input: string) {
const m = re.exec(input);
if (!m) return false;

const { 0: path } = m;
if (!validate(input, path)) return false;
if (!isValid(input, path)) return false;
const params = Object.create(null);

for (let i = 1; i < m.length; i++) {
if (m[i] === undefined) continue;

const key = re.keys[i - 1];
const key = keys[i - 1];
const decoder = decoders[i - 1];
params[key.name] = decoder(m[i]);
}
Expand Down Expand Up @@ -575,17 +575,6 @@ export interface Key {
*/
export type Token = string | Key;

/**
* Expose a function for taking tokens and returning a RegExp.
*/
function tokensToRegexp(data: TokenData, options: PathOptions) {
const flags = toFlags(options);
const keys: Key[] = [];
const sources = toRegExpSource(data, keys);
const regexp = new RegExp(`^${sources.join("")}`, flags);
return Object.assign(regexp, { keys });
}

/**
* Convert a token into a regexp string (re-used for path validation).
*/
Expand Down

0 comments on commit cbf0cb9

Please sign in to comment.