path-to-regexp 8.1.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Readme.md CHANGED
@@ -66,7 +66,7 @@ fn("/users/123/delete");
66
66
 
67
67
  The `match` function returns a function for matching strings against a path:
68
68
 
69
- - **path** String or array of strings.
69
+ - **path** String, `TokenData` object, or array of strings and `TokenData` objects.
70
70
  - **options** _(optional)_ (Extends [pathToRegexp](#pathToRegexp) options)
71
71
  - **decode** Function for decoding strings to params, or `false` to disable all processing. (default: `decodeURIComponent`)
72
72
 
@@ -78,9 +78,9 @@ const fn = match("/foo/:bar");
78
78
 
79
79
  ## PathToRegexp
80
80
 
81
- The `pathToRegexp` function returns a regular expression for matching strings against paths. It
81
+ The `pathToRegexp` function returns the `regexp` for matching strings against paths, and an array of `keys` for understanding the `RegExp#exec` matches.
82
82
 
83
- - **path** String or array of strings.
83
+ - **path** String, `TokenData` object, or array of strings and `TokenData` objects.
84
84
  - **options** _(optional)_ (See [parse](#parse) for more options)
85
85
  - **sensitive** Regexp will be case sensitive. (default: `false`)
86
86
  - **end** Validate the match reaches the end of the string. (default: `true`)
@@ -89,13 +89,15 @@ The `pathToRegexp` function returns a regular expression for matching strings ag
89
89
 
90
90
  ```js
91
91
  const { regexp, keys } = pathToRegexp("/foo/:bar");
92
+
93
+ regexp.exec("/foo/123"); //=> ["/foo/123", "123"]
92
94
  ```
93
95
 
94
96
  ## Compile ("Reverse" Path-To-RegExp)
95
97
 
96
98
  The `compile` function will return a function for transforming parameters into a valid path:
97
99
 
98
- - **path** A string.
100
+ - **path** A string or `TokenData` object.
99
101
  - **options** (See [parse](#parse) for more options)
100
102
  - **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
101
103
  - **encode** Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
@@ -119,15 +121,17 @@ toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
119
121
 
120
122
  ## Stringify
121
123
 
122
- Transform `TokenData` (a sequence of tokens) back into a Path-to-RegExp string.
124
+ Transform a `TokenData` object to a Path-to-RegExp string.
123
125
 
124
- - **data** A `TokenData` instance
126
+ - **data** A `TokenData` object.
125
127
 
126
128
  ```js
127
- const data = new TokenData([
128
- { type: "text", value: "/" },
129
- { type: "param", name: "foo" },
130
- ]);
129
+ const data = {
130
+ tokens: [
131
+ { type: "text", value: "/" },
132
+ { type: "param", name: "foo" },
133
+ ],
134
+ };
131
135
 
132
136
  const path = stringify(data); //=> "/:foo"
133
137
  ```
@@ -139,7 +143,7 @@ const path = stringify(data); //=> "/:foo"
139
143
 
140
144
  ### Parse
141
145
 
142
- The `parse` function accepts a string and returns `TokenData`, the set of tokens and other metadata parsed from the input string. `TokenData` is can used with `match` and `compile`.
146
+ The `parse` function accepts a string and returns `TokenData`, which can be used with `match` and `compile`.
143
147
 
144
148
  - **path** A string.
145
149
  - **options** _(optional)_
@@ -147,20 +151,24 @@ The `parse` function accepts a string and returns `TokenData`, the set of tokens
147
151
 
148
152
  ### Tokens
149
153
 
150
- `TokenData` is a sequence of tokens, currently of types `text`, `parameter`, `wildcard`, or `group`.
154
+ `TokenData` has two properties:
155
+
156
+ - **tokens** A sequence of tokens, currently of types `text`, `parameter`, `wildcard`, or `group`.
157
+ - **originalPath** The original path used with `parse`, shown in error messages to assist debugging.
151
158
 
152
159
  ### Custom path
153
160
 
154
- In some applications, you may not be able to use the `path-to-regexp` syntax, but still want to use this library for `match` and `compile`. For example:
161
+ In some applications you may not be able to use the `path-to-regexp` syntax, but you still want to use this library for `match` and `compile`. For example:
155
162
 
156
163
  ```js
157
- import { TokenData, match } from "path-to-regexp";
164
+ import { match } from "path-to-regexp";
158
165
 
159
166
  const tokens = [
160
167
  { type: "text", value: "/" },
161
168
  { type: "parameter", name: "foo" },
162
169
  ];
163
- const path = new TokenData(tokens);
170
+ const originalPath = "/[foo]"; // To help debug error messages.
171
+ const path = { tokens, originalPath };
164
172
  const fn = match(path);
165
173
 
166
174
  fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } }
@@ -170,34 +178,35 @@ fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } }
170
178
 
171
179
  An effort has been made to ensure ambiguous paths from previous releases throw an error. This means you might be seeing an error when things worked before.
172
180
 
181
+ ### Missing parameter name
182
+
183
+ Parameter names must be provided after `:` or `*`, for example `/*path`. They can be valid JavaScript identifiers (e.g. `:myName`) or JSON strings (`:"my-name"`).
184
+
173
185
  ### Unexpected `?` or `+`
174
186
 
175
187
  In past releases, `?`, `*`, and `+` were used to denote optional or repeating parameters. As an alternative, try these:
176
188
 
177
- - For optional (`?`), use an empty segment in a group such as `/:file{.:ext}`.
178
- - For repeating (`+`), only wildcard matching is supported, such as `/*path`.
179
- - For optional repeating (`*`), use a group and a wildcard parameter such as `/files{/*path}`.
189
+ - For optional (`?`), use braces: `/file{.:ext}`.
190
+ - For one or more (`+`), use a wildcard: `/*path`.
191
+ - For zero or more (`*`), use both: `/files{/*path}`.
180
192
 
181
193
  ### Unexpected `(`, `)`, `[`, `]`, etc.
182
194
 
183
- Previous versions of Path-to-RegExp used these for RegExp features. This version no longer supports them so they've been reserved to avoid ambiguity. To use these characters literally, escape them with a backslash, e.g. `"\\("`.
184
-
185
- ### Missing parameter name
186
-
187
- Parameter names, the part after `:` or `*`, must be a valid JavaScript identifier. For example, it cannot start with a number or contain a dash. If you want a parameter name that uses these characters you can wrap the name in quotes, e.g. `:"my-name"`.
195
+ Previous versions of Path-to-RegExp used these for RegExp features. This version no longer supports them so they've been reserved to avoid ambiguity. To match these characters literally, escape them with a backslash, e.g. `"\\("`.
188
196
 
189
197
  ### Unterminated quote
190
198
 
191
- Parameter names can be wrapped in double quote characters, and this error means you forgot to close the quote character.
199
+ Parameter names can be wrapped in double quote characters, and this error means you forgot to close the quote character. For example, `:"foo`.
192
200
 
193
201
  ### Express <= 4.x
194
202
 
195
203
  Path-To-RegExp breaks compatibility with Express <= `4.x` in the following ways:
196
204
 
197
- - Regexp characters can no longer be provided.
205
+ - The wildcard `*` must have a name and matches the behavior of parameters `:`.
198
206
  - The optional character `?` is no longer supported, use braces instead: `/:file{.:ext}`.
199
- - Some characters have new meaning or have been reserved (`{}?*+@!;`).
200
- - The parameter name now supports all JavaScript identifier characters, previously it was only `[a-z0-9]`.
207
+ - Regexp characters are not supported.
208
+ - Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`).
209
+ - Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
201
210
 
202
211
  ## License
203
212
 
package/dist/index.d.ts CHANGED
@@ -91,7 +91,15 @@ export type Token = Text | Parameter | Wildcard | Group;
91
91
  */
92
92
  export declare class TokenData {
93
93
  readonly tokens: Token[];
94
- constructor(tokens: Token[]);
94
+ readonly originalPath?: string | undefined;
95
+ constructor(tokens: Token[], originalPath?: string | undefined);
96
+ }
97
+ /**
98
+ * ParseError is thrown when there is an error processing the path.
99
+ */
100
+ export declare class PathError extends TypeError {
101
+ readonly originalPath: string | undefined;
102
+ constructor(message: string, originalPath: string | undefined);
95
103
  }
96
104
  /**
97
105
  * Parse a string for the raw tokens.
@@ -100,7 +108,7 @@ export declare function parse(str: string, options?: ParseOptions): TokenData;
100
108
  /**
101
109
  * Compile a string to a template function for the path.
102
110
  */
103
- export declare function compile<P extends ParamData = ParamData>(path: Path, options?: CompileOptions & ParseOptions): (data?: P) => string;
111
+ export declare function compile<P extends ParamData = ParamData>(path: Path, options?: CompileOptions & ParseOptions): (params?: P) => string;
104
112
  export type ParamData = Partial<Record<string, string | string[]>>;
105
113
  export type PathFunction<P extends ParamData> = (data?: P) => string;
106
114
  /**
package/dist/index.js CHANGED
@@ -1,18 +1,6 @@
1
1
  "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
- if (kind === "m") throw new TypeError("Private method is not writable");
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
- };
13
- var _Iter_peek;
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.TokenData = void 0;
3
+ exports.PathError = exports.TokenData = void 0;
16
4
  exports.parse = parse;
17
5
  exports.compile = compile;
18
6
  exports.match = match;
@@ -22,7 +10,6 @@ const DEFAULT_DELIMITER = "/";
22
10
  const NOOP_VALUE = (value) => value;
23
11
  const ID_START = /^[$_\p{ID_Start}]$/u;
24
12
  const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
25
- const DEBUG_URL = "https://git.new/pathToRegexpError";
26
13
  const SIMPLE_TOKENS = {
27
14
  // Groups.
28
15
  "{": "{",
@@ -40,7 +27,7 @@ const SIMPLE_TOKENS = {
40
27
  * Escape text for stringify to path.
41
28
  */
42
29
  function escapeText(str) {
43
- return str.replace(/[{}()\[\]+?!:*]/g, "\\$&");
30
+ return str.replace(/[{}()\[\]+?!:*\\]/g, "\\$&");
44
31
  }
45
32
  /**
46
33
  * Escape a regular expression string.
@@ -49,163 +36,135 @@ function escape(str) {
49
36
  return str.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&");
50
37
  }
51
38
  /**
52
- * Tokenize input string.
39
+ * Tokenized path instance.
40
+ */
41
+ class TokenData {
42
+ constructor(tokens, originalPath) {
43
+ this.tokens = tokens;
44
+ this.originalPath = originalPath;
45
+ }
46
+ }
47
+ exports.TokenData = TokenData;
48
+ /**
49
+ * ParseError is thrown when there is an error processing the path.
50
+ */
51
+ class PathError extends TypeError {
52
+ constructor(message, originalPath) {
53
+ let text = message;
54
+ if (originalPath)
55
+ text += `: ${originalPath}`;
56
+ text += `; visit https://git.new/pathToRegexpError for info`;
57
+ super(text);
58
+ this.originalPath = originalPath;
59
+ }
60
+ }
61
+ exports.PathError = PathError;
62
+ /**
63
+ * Parse a string for the raw tokens.
53
64
  */
54
- function* lexer(str) {
65
+ function parse(str, options = {}) {
66
+ const { encodePath = NOOP_VALUE } = options;
55
67
  const chars = [...str];
56
- let i = 0;
68
+ const tokens = [];
69
+ let index = 0;
70
+ let pos = 0;
57
71
  function name() {
58
72
  let value = "";
59
- if (ID_START.test(chars[++i])) {
60
- value += chars[i];
61
- while (ID_CONTINUE.test(chars[++i])) {
62
- value += chars[i];
63
- }
73
+ if (ID_START.test(chars[index])) {
74
+ do {
75
+ value += chars[index++];
76
+ } while (ID_CONTINUE.test(chars[index]));
64
77
  }
65
- else if (chars[i] === '"') {
66
- let pos = i;
67
- while (i < chars.length) {
68
- if (chars[++i] === '"') {
69
- i++;
70
- pos = 0;
78
+ else if (chars[index] === '"') {
79
+ let quoteStart = index;
80
+ while (index++ < chars.length) {
81
+ if (chars[index] === '"') {
82
+ index++;
83
+ quoteStart = 0;
71
84
  break;
72
85
  }
73
- if (chars[i] === "\\") {
74
- value += chars[++i];
75
- }
76
- else {
77
- value += chars[i];
78
- }
86
+ // Increment over escape characters.
87
+ if (chars[index] === "\\")
88
+ index++;
89
+ value += chars[index];
79
90
  }
80
- if (pos) {
81
- throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);
91
+ if (quoteStart) {
92
+ throw new PathError(`Unterminated quote at index ${quoteStart}`, str);
82
93
  }
83
94
  }
84
95
  if (!value) {
85
- throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
96
+ throw new PathError(`Missing parameter name at index ${index}`, str);
86
97
  }
87
98
  return value;
88
99
  }
89
- while (i < chars.length) {
90
- const value = chars[i];
100
+ while (index < chars.length) {
101
+ const value = chars[index];
91
102
  const type = SIMPLE_TOKENS[value];
92
103
  if (type) {
93
- yield { type, index: i++, value };
104
+ tokens.push({ type, index: index++, value });
94
105
  }
95
106
  else if (value === "\\") {
96
- yield { type: "ESCAPED", index: i++, value: chars[i++] };
107
+ tokens.push({ type: "escape", index: index++, value: chars[index++] });
97
108
  }
98
109
  else if (value === ":") {
99
- const value = name();
100
- yield { type: "PARAM", index: i, value };
110
+ tokens.push({ type: "param", index: index++, value: name() });
101
111
  }
102
112
  else if (value === "*") {
103
- const value = name();
104
- yield { type: "WILDCARD", index: i, value };
113
+ tokens.push({ type: "wildcard", index: index++, value: name() });
105
114
  }
106
115
  else {
107
- yield { type: "CHAR", index: i, value: chars[i++] };
108
- }
109
- }
110
- return { type: "END", index: i, value: "" };
111
- }
112
- class Iter {
113
- constructor(tokens) {
114
- this.tokens = tokens;
115
- _Iter_peek.set(this, void 0);
116
- }
117
- peek() {
118
- if (!__classPrivateFieldGet(this, _Iter_peek, "f")) {
119
- const next = this.tokens.next();
120
- __classPrivateFieldSet(this, _Iter_peek, next.value, "f");
116
+ tokens.push({ type: "char", index: index++, value });
121
117
  }
122
- return __classPrivateFieldGet(this, _Iter_peek, "f");
123
- }
124
- tryConsume(type) {
125
- const token = this.peek();
126
- if (token.type !== type)
127
- return;
128
- __classPrivateFieldSet(this, _Iter_peek, undefined, "f"); // Reset after consumed.
129
- return token.value;
130
- }
131
- consume(type) {
132
- const value = this.tryConsume(type);
133
- if (value !== undefined)
134
- return value;
135
- const { type: nextType, index } = this.peek();
136
- throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`);
137
118
  }
138
- text() {
139
- let result = "";
140
- let value;
141
- while ((value = this.tryConsume("CHAR") || this.tryConsume("ESCAPED"))) {
142
- result += value;
143
- }
144
- return result;
145
- }
146
- }
147
- _Iter_peek = new WeakMap();
148
- /**
149
- * Tokenized path instance.
150
- */
151
- class TokenData {
152
- constructor(tokens) {
153
- this.tokens = tokens;
154
- }
155
- }
156
- exports.TokenData = TokenData;
157
- /**
158
- * Parse a string for the raw tokens.
159
- */
160
- function parse(str, options = {}) {
161
- const { encodePath = NOOP_VALUE } = options;
162
- const it = new Iter(lexer(str));
163
- function consume(endType) {
164
- const tokens = [];
119
+ tokens.push({ type: "end", index, value: "" });
120
+ function consumeUntil(endType) {
121
+ const output = [];
165
122
  while (true) {
166
- const path = it.text();
167
- if (path)
168
- tokens.push({ type: "text", value: encodePath(path) });
169
- const param = it.tryConsume("PARAM");
170
- if (param) {
171
- tokens.push({
172
- type: "param",
173
- name: param,
123
+ const token = tokens[pos++];
124
+ if (token.type === endType)
125
+ break;
126
+ if (token.type === "char" || token.type === "escape") {
127
+ let path = token.value;
128
+ let cur = tokens[pos];
129
+ while (cur.type === "char" || cur.type === "escape") {
130
+ path += cur.value;
131
+ cur = tokens[++pos];
132
+ }
133
+ output.push({
134
+ type: "text",
135
+ value: encodePath(path),
174
136
  });
175
137
  continue;
176
138
  }
177
- const wildcard = it.tryConsume("WILDCARD");
178
- if (wildcard) {
179
- tokens.push({
180
- type: "wildcard",
181
- name: wildcard,
139
+ if (token.type === "param" || token.type === "wildcard") {
140
+ output.push({
141
+ type: token.type,
142
+ name: token.value,
182
143
  });
183
144
  continue;
184
145
  }
185
- const open = it.tryConsume("{");
186
- if (open) {
187
- tokens.push({
146
+ if (token.type === "{") {
147
+ output.push({
188
148
  type: "group",
189
- tokens: consume("}"),
149
+ tokens: consumeUntil("}"),
190
150
  });
191
151
  continue;
192
152
  }
193
- it.consume(endType);
194
- return tokens;
153
+ throw new PathError(`Unexpected ${token.type} at index ${token.index}, expected ${endType}`, str);
195
154
  }
155
+ return output;
196
156
  }
197
- const tokens = consume("END");
198
- return new TokenData(tokens);
157
+ return new TokenData(consumeUntil("end"), str);
199
158
  }
200
159
  /**
201
160
  * Compile a string to a template function for the path.
202
161
  */
203
162
  function compile(path, options = {}) {
204
163
  const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
205
- const data = path instanceof TokenData ? path : parse(path, options);
164
+ const data = typeof path === "object" ? path : parse(path, options);
206
165
  const fn = tokensToFunction(data.tokens, delimiter, encode);
207
- return function path(data = {}) {
208
- const [path, ...missing] = fn(data);
166
+ return function path(params = {}) {
167
+ const [path, ...missing] = fn(params);
209
168
  if (missing.length) {
210
169
  throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
211
170
  }
@@ -302,14 +261,12 @@ function match(path, options = {}) {
302
261
  function pathToRegexp(path, options = {}) {
303
262
  const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true, } = options;
304
263
  const keys = [];
264
+ const flags = sensitive ? "" : "i";
305
265
  const sources = [];
306
- const flags = sensitive ? "s" : "is";
307
- const paths = Array.isArray(path) ? path : [path];
308
- const items = paths.map((path) => path instanceof TokenData ? path : parse(path, options));
309
- for (const { tokens } of items) {
310
- for (const seq of flatten(tokens, 0, [])) {
311
- const regexp = sequenceToRegExp(seq, delimiter, keys);
312
- sources.push(regexp);
266
+ for (const input of pathsToArray(path, [])) {
267
+ const data = typeof input === "object" ? input : parse(input, options);
268
+ for (const tokens of flatten(data.tokens, 0, [])) {
269
+ sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath));
313
270
  }
314
271
  }
315
272
  let pattern = `^(?:${sources.join("|")})`;
@@ -319,6 +276,19 @@ function pathToRegexp(path, options = {}) {
319
276
  const regexp = new RegExp(pattern, flags);
320
277
  return { regexp, keys };
321
278
  }
279
+ /**
280
+ * Convert a path or array of paths into a flat array.
281
+ */
282
+ function pathsToArray(paths, init) {
283
+ if (Array.isArray(paths)) {
284
+ for (const p of paths)
285
+ pathsToArray(p, init);
286
+ }
287
+ else {
288
+ init.push(paths);
289
+ }
290
+ return init;
291
+ }
322
292
  /**
323
293
  * Generate a flat list of sequence tokens from the given tokens.
324
294
  */
@@ -328,8 +298,7 @@ function* flatten(tokens, index, init) {
328
298
  }
329
299
  const token = tokens[index];
330
300
  if (token.type === "group") {
331
- const fork = init.slice();
332
- for (const seq of flatten(token.tokens, 0, fork)) {
301
+ for (const seq of flatten(token.tokens, 0, init.slice())) {
333
302
  yield* flatten(tokens, index + 1, seq);
334
303
  }
335
304
  }
@@ -341,27 +310,26 @@ function* flatten(tokens, index, init) {
341
310
  /**
342
311
  * Transform a flat sequence of tokens into a regular expression.
343
312
  */
344
- function sequenceToRegExp(tokens, delimiter, keys) {
313
+ function toRegExpSource(tokens, delimiter, keys, originalPath) {
345
314
  let result = "";
346
315
  let backtrack = "";
347
316
  let isSafeSegmentParam = true;
348
- for (let i = 0; i < tokens.length; i++) {
349
- const token = tokens[i];
317
+ for (const token of tokens) {
350
318
  if (token.type === "text") {
351
319
  result += escape(token.value);
352
- backtrack = token.value;
320
+ backtrack += token.value;
353
321
  isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter));
354
322
  continue;
355
323
  }
356
324
  if (token.type === "param" || token.type === "wildcard") {
357
325
  if (!isSafeSegmentParam && !backtrack) {
358
- throw new TypeError(`Missing text after "${token.name}": ${DEBUG_URL}`);
326
+ throw new PathError(`Missing text before "${token.name}" ${token.type}`, originalPath);
359
327
  }
360
328
  if (token.type === "param") {
361
329
  result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`;
362
330
  }
363
331
  else {
364
- result += `(.+)`;
332
+ result += `([\\s\\S]+)`;
365
333
  }
366
334
  keys.push(token);
367
335
  backtrack = "";
@@ -371,43 +339,71 @@ function sequenceToRegExp(tokens, delimiter, keys) {
371
339
  }
372
340
  return result;
373
341
  }
342
+ /**
343
+ * Block backtracking on previous text and ignore delimiter string.
344
+ */
374
345
  function negate(delimiter, backtrack) {
375
- const values = [delimiter, backtrack].filter(Boolean);
376
- const isSimple = values.every((value) => value.length === 1);
377
- if (isSimple)
378
- return `[^${escape(values.join(""))}]`;
379
- return `(?:(?!${values.map(escape).join("|")}).)`;
346
+ if (backtrack.length < 2) {
347
+ if (delimiter.length < 2)
348
+ return `[^${escape(delimiter + backtrack)}]`;
349
+ return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;
350
+ }
351
+ if (delimiter.length < 2) {
352
+ return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;
353
+ }
354
+ return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`;
380
355
  }
381
356
  /**
382
- * Stringify token data into a path string.
357
+ * Stringify an array of tokens into a path string.
383
358
  */
384
- function stringify(data) {
385
- return data.tokens
386
- .map(function stringifyToken(token, index, tokens) {
387
- if (token.type === "text")
388
- return escapeText(token.value);
359
+ function stringifyTokens(tokens) {
360
+ let value = "";
361
+ let i = 0;
362
+ function name(value) {
363
+ const isSafe = isNameSafe(value) && isNextNameSafe(tokens[i]);
364
+ return isSafe ? value : JSON.stringify(value);
365
+ }
366
+ while (i < tokens.length) {
367
+ const token = tokens[i++];
368
+ if (token.type === "text") {
369
+ value += escapeText(token.value);
370
+ continue;
371
+ }
389
372
  if (token.type === "group") {
390
- return `{${token.tokens.map(stringifyToken).join("")}}`;
373
+ value += `{${stringifyTokens(token.tokens)}}`;
374
+ continue;
391
375
  }
392
- const isSafe = isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);
393
- const key = isSafe ? token.name : JSON.stringify(token.name);
394
- if (token.type === "param")
395
- return `:${key}`;
396
- if (token.type === "wildcard")
397
- return `*${key}`;
398
- throw new TypeError(`Unexpected token: ${token}`);
399
- })
400
- .join("");
376
+ if (token.type === "param") {
377
+ value += `:${name(token.name)}`;
378
+ continue;
379
+ }
380
+ if (token.type === "wildcard") {
381
+ value += `*${name(token.name)}`;
382
+ continue;
383
+ }
384
+ throw new TypeError(`Unknown token type: ${token.type}`);
385
+ }
386
+ return value;
401
387
  }
388
+ /**
389
+ * Stringify token data into a path string.
390
+ */
391
+ function stringify(data) {
392
+ return stringifyTokens(data.tokens);
393
+ }
394
+ /**
395
+ * Validate the parameter name contains valid ID characters.
396
+ */
402
397
  function isNameSafe(name) {
403
398
  const [first, ...rest] = name;
404
- if (!ID_START.test(first))
405
- return false;
406
- return rest.every((char) => ID_CONTINUE.test(char));
399
+ return ID_START.test(first) && rest.every((char) => ID_CONTINUE.test(char));
407
400
  }
401
+ /**
402
+ * Validate the next token does not interfere with the current param name.
403
+ */
408
404
  function isNextNameSafe(token) {
409
- if (token?.type !== "text")
410
- return true;
411
- return !ID_CONTINUE.test(token.value[0]);
405
+ if (token && token.type === "text")
406
+ return !ID_CONTINUE.test(token.value[0]);
407
+ return true;
412
408
  }
413
409
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["const DEFAULT_DELIMITER = \"/\";\nconst NOOP_VALUE = (value: string) => value;\nconst ID_START = /^[$_\\p{ID_Start}]$/u;\nconst ID_CONTINUE = /^[$\\u200c\\u200d\\p{ID_Continue}]$/u;\nconst DEBUG_URL = \"https://git.new/pathToRegexpError\";\n\n/**\n * Encode a string into another string.\n */\nexport type Encode = (value: string) => string;\n\n/**\n * Decode a string into another string.\n */\nexport type Decode = (value: string) => string;\n\nexport interface ParseOptions {\n /**\n * A function for encoding input strings.\n */\n encodePath?: Encode;\n}\n\nexport interface PathToRegexpOptions {\n /**\n * Matches the path completely without trailing characters. (default: `true`)\n */\n end?: boolean;\n /**\n * Allows optional trailing delimiter to match. (default: `true`)\n */\n trailing?: boolean;\n /**\n * Match will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\nexport interface MatchOptions extends PathToRegexpOptions {\n /**\n * Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)\n */\n decode?: Decode | false;\n}\n\nexport interface CompileOptions {\n /**\n * Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)\n */\n encode?: Encode | false;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\ntype TokenType =\n | \"{\"\n | \"}\"\n | \"WILDCARD\"\n | \"PARAM\"\n | \"CHAR\"\n | \"ESCAPED\"\n | \"END\"\n // Reserved for use or ambiguous due to past use.\n | \"(\"\n | \")\"\n | \"[\"\n | \"]\"\n | \"+\"\n | \"?\"\n | \"!\";\n\n/**\n * Tokenizer results.\n */\ninterface LexToken {\n type: TokenType;\n index: number;\n value: string;\n}\n\nconst SIMPLE_TOKENS: Record<string, TokenType> = {\n // Groups.\n \"{\": \"{\",\n \"}\": \"}\",\n // Reserved.\n \"(\": \"(\",\n \")\": \")\",\n \"[\": \"[\",\n \"]\": \"]\",\n \"+\": \"+\",\n \"?\": \"?\",\n \"!\": \"!\",\n};\n\n/**\n * Escape text for stringify to path.\n */\nfunction escapeText(str: string) {\n return str.replace(/[{}()\\[\\]+?!:*]/g, \"\\\\$&\");\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escape(str: string) {\n return str.replace(/[.+*?^${}()[\\]|/\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Tokenize input string.\n */\nfunction* lexer(str: string): Generator<LexToken, LexToken> {\n const chars = [...str];\n let i = 0;\n\n function name() {\n let value = \"\";\n\n if (ID_START.test(chars[++i])) {\n value += chars[i];\n while (ID_CONTINUE.test(chars[++i])) {\n value += chars[i];\n }\n } else if (chars[i] === '\"') {\n let pos = i;\n\n while (i < chars.length) {\n if (chars[++i] === '\"') {\n i++;\n pos = 0;\n break;\n }\n\n if (chars[i] === \"\\\\\") {\n value += chars[++i];\n } else {\n value += chars[i];\n }\n }\n\n if (pos) {\n throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);\n }\n }\n\n if (!value) {\n throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);\n }\n\n return value;\n }\n\n while (i < chars.length) {\n const value = chars[i];\n const type = SIMPLE_TOKENS[value];\n\n if (type) {\n yield { type, index: i++, value };\n } else if (value === \"\\\\\") {\n yield { type: \"ESCAPED\", index: i++, value: chars[i++] };\n } else if (value === \":\") {\n const value = name();\n yield { type: \"PARAM\", index: i, value };\n } else if (value === \"*\") {\n const value = name();\n yield { type: \"WILDCARD\", index: i, value };\n } else {\n yield { type: \"CHAR\", index: i, value: chars[i++] };\n }\n }\n\n return { type: \"END\", index: i, value: \"\" };\n}\n\nclass Iter {\n #peek?: LexToken;\n\n constructor(private tokens: Generator<LexToken, LexToken>) {}\n\n peek(): LexToken {\n if (!this.#peek) {\n const next = this.tokens.next();\n this.#peek = next.value;\n }\n return this.#peek;\n }\n\n tryConsume(type: TokenType): string | undefined {\n const token = this.peek();\n if (token.type !== type) return;\n this.#peek = undefined; // Reset after consumed.\n return token.value;\n }\n\n consume(type: TokenType): string {\n const value = this.tryConsume(type);\n if (value !== undefined) return value;\n const { type: nextType, index } = this.peek();\n throw new TypeError(\n `Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`,\n );\n }\n\n text(): string {\n let result = \"\";\n let value: string | undefined;\n while ((value = this.tryConsume(\"CHAR\") || this.tryConsume(\"ESCAPED\"))) {\n result += value;\n }\n return result;\n }\n}\n\n/**\n * Plain text.\n */\nexport interface Text {\n type: \"text\";\n value: string;\n}\n\n/**\n * A parameter designed to match arbitrary text within a segment.\n */\nexport interface Parameter {\n type: \"param\";\n name: string;\n}\n\n/**\n * A wildcard parameter designed to match multiple segments.\n */\nexport interface Wildcard {\n type: \"wildcard\";\n name: string;\n}\n\n/**\n * A set of possible tokens to expand when matching.\n */\nexport interface Group {\n type: \"group\";\n tokens: Token[];\n}\n\n/**\n * A token that corresponds with a regexp capture.\n */\nexport type Key = Parameter | Wildcard;\n\n/**\n * A sequence of `path-to-regexp` keys that match capturing groups.\n */\nexport type Keys = Array<Key>;\n\n/**\n * A sequence of path match characters.\n */\nexport type Token = Text | Parameter | Wildcard | Group;\n\n/**\n * Tokenized path instance.\n */\nexport class TokenData {\n constructor(public readonly tokens: Token[]) {}\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): TokenData {\n const { encodePath = NOOP_VALUE } = options;\n const it = new Iter(lexer(str));\n\n function consume(endType: TokenType): Token[] {\n const tokens: Token[] = [];\n\n while (true) {\n const path = it.text();\n if (path) tokens.push({ type: \"text\", value: encodePath(path) });\n\n const param = it.tryConsume(\"PARAM\");\n if (param) {\n tokens.push({\n type: \"param\",\n name: param,\n });\n continue;\n }\n\n const wildcard = it.tryConsume(\"WILDCARD\");\n if (wildcard) {\n tokens.push({\n type: \"wildcard\",\n name: wildcard,\n });\n continue;\n }\n\n const open = it.tryConsume(\"{\");\n if (open) {\n tokens.push({\n type: \"group\",\n tokens: consume(\"}\"),\n });\n continue;\n }\n\n it.consume(endType);\n return tokens;\n }\n }\n\n const tokens = consume(\"END\");\n return new TokenData(tokens);\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile<P extends ParamData = ParamData>(\n path: Path,\n options: CompileOptions & ParseOptions = {},\n) {\n const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const data = path instanceof TokenData ? path : parse(path, options);\n const fn = tokensToFunction(data.tokens, delimiter, encode);\n\n return function path(data: P = {} as P) {\n const [path, ...missing] = fn(data);\n if (missing.length) {\n throw new TypeError(`Missing parameters: ${missing.join(\", \")}`);\n }\n return path;\n };\n}\n\nexport type ParamData = Partial<Record<string, string | string[]>>;\nexport type PathFunction<P extends ParamData> = (data?: P) => string;\n\nfunction tokensToFunction(\n tokens: Token[],\n delimiter: string,\n encode: Encode | false,\n) {\n const encoders = tokens.map((token) =>\n tokenToFunction(token, delimiter, encode),\n );\n\n return (data: ParamData) => {\n const result: string[] = [\"\"];\n\n for (const encoder of encoders) {\n const [value, ...extras] = encoder(data);\n result[0] += value;\n result.push(...extras);\n }\n\n return result;\n };\n}\n\n/**\n * Convert a single token into a path building function.\n */\nfunction tokenToFunction(\n token: Token,\n delimiter: string,\n encode: Encode | false,\n): (data: ParamData) => string[] {\n if (token.type === \"text\") return () => [token.value];\n\n if (token.type === \"group\") {\n const fn = tokensToFunction(token.tokens, delimiter, encode);\n\n return (data) => {\n const [value, ...missing] = fn(data);\n if (!missing.length) return [value];\n return [\"\"];\n };\n }\n\n const encodeValue = encode || NOOP_VALUE;\n\n if (token.type === \"wildcard\" && encode !== false) {\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (!Array.isArray(value) || value.length === 0) {\n throw new TypeError(`Expected \"${token.name}\" to be a non-empty array`);\n }\n\n return [\n value\n .map((value, index) => {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `Expected \"${token.name}/${index}\" to be a string`,\n );\n }\n\n return encodeValue(value);\n })\n .join(delimiter),\n ];\n };\n }\n\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected \"${token.name}\" to be a string`);\n }\n\n return [encodeValue(value)];\n };\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult<P extends ParamData> {\n path: string;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match<P extends ParamData> = false | MatchResult<P>;\n\n/**\n * The match function takes a string and returns whether it matched the path.\n */\nexport type MatchFunction<P extends ParamData> = (path: string) => Match<P>;\n\n/**\n * Supported path types.\n */\nexport type Path = string | TokenData;\n\n/**\n * Transform a path into a match function.\n */\nexport function match<P extends ParamData>(\n path: Path | Path[],\n options: MatchOptions & ParseOptions = {},\n): MatchFunction<P> {\n const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const { regexp, keys } = pathToRegexp(path, options);\n\n const decoders = keys.map((key) => {\n if (decode === false) return NOOP_VALUE;\n if (key.type === \"param\") return decode;\n return (value: string) => value.split(delimiter).map(decode);\n });\n\n return function match(input: string) {\n const m = regexp.exec(input);\n if (!m) return false;\n\n const path = m[0];\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n const decoder = decoders[i - 1];\n params[key.name] = decoder(m[i]);\n }\n\n return { path, params };\n };\n}\n\nexport function pathToRegexp(\n path: Path | Path[],\n options: PathToRegexpOptions & ParseOptions = {},\n) {\n const {\n delimiter = DEFAULT_DELIMITER,\n end = true,\n sensitive = false,\n trailing = true,\n } = options;\n const keys: Keys = [];\n const sources: string[] = [];\n const flags = sensitive ? \"s\" : \"is\";\n const paths = Array.isArray(path) ? path : [path];\n const items = paths.map((path) =>\n path instanceof TokenData ? path : parse(path, options),\n );\n\n for (const { tokens } of items) {\n for (const seq of flatten(tokens, 0, [])) {\n const regexp = sequenceToRegExp(seq, delimiter, keys);\n sources.push(regexp);\n }\n }\n\n let pattern = `^(?:${sources.join(\"|\")})`;\n if (trailing) pattern += `(?:${escape(delimiter)}$)?`;\n pattern += end ? \"$\" : `(?=${escape(delimiter)}|$)`;\n\n const regexp = new RegExp(pattern, flags);\n return { regexp, keys };\n}\n\n/**\n * Flattened token set.\n */\ntype Flattened = Text | Parameter | Wildcard;\n\n/**\n * Generate a flat list of sequence tokens from the given tokens.\n */\nfunction* flatten(\n tokens: Token[],\n index: number,\n init: Flattened[],\n): Generator<Flattened[]> {\n if (index === tokens.length) {\n return yield init;\n }\n\n const token = tokens[index];\n\n if (token.type === \"group\") {\n const fork = init.slice();\n for (const seq of flatten(token.tokens, 0, fork)) {\n yield* flatten(tokens, index + 1, seq);\n }\n } else {\n init.push(token);\n }\n\n yield* flatten(tokens, index + 1, init);\n}\n\n/**\n * Transform a flat sequence of tokens into a regular expression.\n */\nfunction sequenceToRegExp(tokens: Flattened[], delimiter: string, keys: Keys) {\n let result = \"\";\n let backtrack = \"\";\n let isSafeSegmentParam = true;\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n if (token.type === \"text\") {\n result += escape(token.value);\n backtrack = token.value;\n isSafeSegmentParam ||= token.value.includes(delimiter);\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n if (!isSafeSegmentParam && !backtrack) {\n throw new TypeError(`Missing text after \"${token.name}\": ${DEBUG_URL}`);\n }\n\n if (token.type === \"param\") {\n result += `(${negate(delimiter, isSafeSegmentParam ? \"\" : backtrack)}+)`;\n } else {\n result += `(.+)`;\n }\n\n keys.push(token);\n backtrack = \"\";\n isSafeSegmentParam = false;\n continue;\n }\n }\n\n return result;\n}\n\nfunction negate(delimiter: string, backtrack: string) {\n const values = [delimiter, backtrack].filter(Boolean);\n const isSimple = values.every((value) => value.length === 1);\n if (isSimple) return `[^${escape(values.join(\"\"))}]`;\n return `(?:(?!${values.map(escape).join(\"|\")}).)`;\n}\n\n/**\n * Stringify token data into a path string.\n */\nexport function stringify(data: TokenData) {\n return data.tokens\n .map(function stringifyToken(token, index, tokens): string {\n if (token.type === \"text\") return escapeText(token.value);\n if (token.type === \"group\") {\n return `{${token.tokens.map(stringifyToken).join(\"\")}}`;\n }\n\n const isSafe =\n isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);\n const key = isSafe ? token.name : JSON.stringify(token.name);\n\n if (token.type === \"param\") return `:${key}`;\n if (token.type === \"wildcard\") return `*${key}`;\n throw new TypeError(`Unexpected token: ${token}`);\n })\n .join(\"\");\n}\n\nfunction isNameSafe(name: string) {\n const [first, ...rest] = name;\n if (!ID_START.test(first)) return false;\n return rest.every((char) => ID_CONTINUE.test(char));\n}\n\nfunction isNextNameSafe(token: Token | undefined) {\n if (token?.type !== \"text\") return true;\n return !ID_CONTINUE.test(token.value[0]);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["const DEFAULT_DELIMITER = \"/\";\nconst NOOP_VALUE = (value: string) => value;\nconst ID_START = /^[$_\\p{ID_Start}]$/u;\nconst ID_CONTINUE = /^[$\\u200c\\u200d\\p{ID_Continue}]$/u;\n\n/**\n * Encode a string into another string.\n */\nexport type Encode = (value: string) => string;\n\n/**\n * Decode a string into another string.\n */\nexport type Decode = (value: string) => string;\n\nexport interface ParseOptions {\n /**\n * A function for encoding input strings.\n */\n encodePath?: Encode;\n}\n\nexport interface PathToRegexpOptions {\n /**\n * Matches the path completely without trailing characters. (default: `true`)\n */\n end?: boolean;\n /**\n * Allows optional trailing delimiter to match. (default: `true`)\n */\n trailing?: boolean;\n /**\n * Match will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\nexport interface MatchOptions extends PathToRegexpOptions {\n /**\n * Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)\n */\n decode?: Decode | false;\n}\n\nexport interface CompileOptions {\n /**\n * Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)\n */\n encode?: Encode | false;\n /**\n * The default delimiter for segments. (default: `'/'`)\n */\n delimiter?: string;\n}\n\ntype TokenType =\n | \"{\"\n | \"}\"\n | \"wildcard\"\n | \"param\"\n | \"char\"\n | \"escape\"\n | \"end\"\n // Reserved for use or ambiguous due to past use.\n | \"(\"\n | \")\"\n | \"[\"\n | \"]\"\n | \"+\"\n | \"?\"\n | \"!\";\n\n/**\n * Tokenizer results.\n */\ninterface LexToken {\n type: TokenType;\n index: number;\n value: string;\n}\n\nconst SIMPLE_TOKENS: Record<string, TokenType> = {\n // Groups.\n \"{\": \"{\",\n \"}\": \"}\",\n // Reserved.\n \"(\": \"(\",\n \")\": \")\",\n \"[\": \"[\",\n \"]\": \"]\",\n \"+\": \"+\",\n \"?\": \"?\",\n \"!\": \"!\",\n};\n\n/**\n * Escape text for stringify to path.\n */\nfunction escapeText(str: string) {\n return str.replace(/[{}()\\[\\]+?!:*\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escape(str: string) {\n return str.replace(/[.+*?^${}()[\\]|/\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Plain text.\n */\nexport interface Text {\n type: \"text\";\n value: string;\n}\n\n/**\n * A parameter designed to match arbitrary text within a segment.\n */\nexport interface Parameter {\n type: \"param\";\n name: string;\n}\n\n/**\n * A wildcard parameter designed to match multiple segments.\n */\nexport interface Wildcard {\n type: \"wildcard\";\n name: string;\n}\n\n/**\n * A set of possible tokens to expand when matching.\n */\nexport interface Group {\n type: \"group\";\n tokens: Token[];\n}\n\n/**\n * A token that corresponds with a regexp capture.\n */\nexport type Key = Parameter | Wildcard;\n\n/**\n * A sequence of `path-to-regexp` keys that match capturing groups.\n */\nexport type Keys = Array<Key>;\n\n/**\n * A sequence of path match characters.\n */\nexport type Token = Text | Parameter | Wildcard | Group;\n\n/**\n * Tokenized path instance.\n */\nexport class TokenData {\n constructor(\n public readonly tokens: Token[],\n public readonly originalPath?: string,\n ) {}\n}\n\n/**\n * ParseError is thrown when there is an error processing the path.\n */\nexport class PathError extends TypeError {\n constructor(\n message: string,\n public readonly originalPath: string | undefined,\n ) {\n let text = message;\n if (originalPath) text += `: ${originalPath}`;\n text += `; visit https://git.new/pathToRegexpError for info`;\n super(text);\n }\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): TokenData {\n const { encodePath = NOOP_VALUE } = options;\n const chars = [...str];\n const tokens: Array<LexToken> = [];\n let index = 0;\n let pos = 0;\n\n function name() {\n let value = \"\";\n\n if (ID_START.test(chars[index])) {\n do {\n value += chars[index++];\n } while (ID_CONTINUE.test(chars[index]));\n } else if (chars[index] === '\"') {\n let quoteStart = index;\n\n while (index++ < chars.length) {\n if (chars[index] === '\"') {\n index++;\n quoteStart = 0;\n break;\n }\n\n // Increment over escape characters.\n if (chars[index] === \"\\\\\") index++;\n\n value += chars[index];\n }\n\n if (quoteStart) {\n throw new PathError(`Unterminated quote at index ${quoteStart}`, str);\n }\n }\n\n if (!value) {\n throw new PathError(`Missing parameter name at index ${index}`, str);\n }\n\n return value;\n }\n\n while (index < chars.length) {\n const value = chars[index];\n const type = SIMPLE_TOKENS[value];\n\n if (type) {\n tokens.push({ type, index: index++, value });\n } else if (value === \"\\\\\") {\n tokens.push({ type: \"escape\", index: index++, value: chars[index++] });\n } else if (value === \":\") {\n tokens.push({ type: \"param\", index: index++, value: name() });\n } else if (value === \"*\") {\n tokens.push({ type: \"wildcard\", index: index++, value: name() });\n } else {\n tokens.push({ type: \"char\", index: index++, value });\n }\n }\n\n tokens.push({ type: \"end\", index, value: \"\" });\n\n function consumeUntil(endType: TokenType): Token[] {\n const output: Token[] = [];\n\n while (true) {\n const token = tokens[pos++];\n if (token.type === endType) break;\n\n if (token.type === \"char\" || token.type === \"escape\") {\n let path = token.value;\n let cur = tokens[pos];\n\n while (cur.type === \"char\" || cur.type === \"escape\") {\n path += cur.value;\n cur = tokens[++pos];\n }\n\n output.push({\n type: \"text\",\n value: encodePath(path),\n });\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n output.push({\n type: token.type,\n name: token.value,\n });\n continue;\n }\n\n if (token.type === \"{\") {\n output.push({\n type: \"group\",\n tokens: consumeUntil(\"}\"),\n });\n continue;\n }\n\n throw new PathError(\n `Unexpected ${token.type} at index ${token.index}, expected ${endType}`,\n str,\n );\n }\n\n return output;\n }\n\n return new TokenData(consumeUntil(\"end\"), str);\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile<P extends ParamData = ParamData>(\n path: Path,\n options: CompileOptions & ParseOptions = {},\n) {\n const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const data = typeof path === \"object\" ? path : parse(path, options);\n const fn = tokensToFunction(data.tokens, delimiter, encode);\n\n return function path(params: P = {} as P) {\n const [path, ...missing] = fn(params);\n if (missing.length) {\n throw new TypeError(`Missing parameters: ${missing.join(\", \")}`);\n }\n return path;\n };\n}\n\nexport type ParamData = Partial<Record<string, string | string[]>>;\nexport type PathFunction<P extends ParamData> = (data?: P) => string;\n\nfunction tokensToFunction(\n tokens: Token[],\n delimiter: string,\n encode: Encode | false,\n) {\n const encoders = tokens.map((token) =>\n tokenToFunction(token, delimiter, encode),\n );\n\n return (data: ParamData) => {\n const result: string[] = [\"\"];\n\n for (const encoder of encoders) {\n const [value, ...extras] = encoder(data);\n result[0] += value;\n result.push(...extras);\n }\n\n return result;\n };\n}\n\n/**\n * Convert a single token into a path building function.\n */\nfunction tokenToFunction(\n token: Token,\n delimiter: string,\n encode: Encode | false,\n): (data: ParamData) => string[] {\n if (token.type === \"text\") return () => [token.value];\n\n if (token.type === \"group\") {\n const fn = tokensToFunction(token.tokens, delimiter, encode);\n\n return (data) => {\n const [value, ...missing] = fn(data);\n if (!missing.length) return [value];\n return [\"\"];\n };\n }\n\n const encodeValue = encode || NOOP_VALUE;\n\n if (token.type === \"wildcard\" && encode !== false) {\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (!Array.isArray(value) || value.length === 0) {\n throw new TypeError(`Expected \"${token.name}\" to be a non-empty array`);\n }\n\n return [\n value\n .map((value, index) => {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `Expected \"${token.name}/${index}\" to be a string`,\n );\n }\n\n return encodeValue(value);\n })\n .join(delimiter),\n ];\n };\n }\n\n return (data) => {\n const value = data[token.name];\n if (value == null) return [\"\", token.name];\n\n if (typeof value !== \"string\") {\n throw new TypeError(`Expected \"${token.name}\" to be a string`);\n }\n\n return [encodeValue(value)];\n };\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult<P extends ParamData> {\n path: string;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match<P extends ParamData> = false | MatchResult<P>;\n\n/**\n * The match function takes a string and returns whether it matched the path.\n */\nexport type MatchFunction<P extends ParamData> = (path: string) => Match<P>;\n\n/**\n * Supported path types.\n */\nexport type Path = string | TokenData;\n\n/**\n * Transform a path into a match function.\n */\nexport function match<P extends ParamData>(\n path: Path | Path[],\n options: MatchOptions & ParseOptions = {},\n): MatchFunction<P> {\n const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } =\n options;\n const { regexp, keys } = pathToRegexp(path, options);\n\n const decoders = keys.map((key) => {\n if (decode === false) return NOOP_VALUE;\n if (key.type === \"param\") return decode;\n return (value: string) => value.split(delimiter).map(decode);\n });\n\n return function match(input: string) {\n const m = regexp.exec(input);\n if (!m) return false;\n\n const path = m[0];\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n const decoder = decoders[i - 1];\n params[key.name] = decoder(m[i]);\n }\n\n return { path, params };\n };\n}\n\nexport function pathToRegexp(\n path: Path | Path[],\n options: PathToRegexpOptions & ParseOptions = {},\n) {\n const {\n delimiter = DEFAULT_DELIMITER,\n end = true,\n sensitive = false,\n trailing = true,\n } = options;\n const keys: Keys = [];\n const flags = sensitive ? \"\" : \"i\";\n const sources: string[] = [];\n\n for (const input of pathsToArray(path, [])) {\n const data = typeof input === \"object\" ? input : parse(input, options);\n for (const tokens of flatten(data.tokens, 0, [])) {\n sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath));\n }\n }\n\n let pattern = `^(?:${sources.join(\"|\")})`;\n if (trailing) pattern += `(?:${escape(delimiter)}$)?`;\n pattern += end ? \"$\" : `(?=${escape(delimiter)}|$)`;\n\n const regexp = new RegExp(pattern, flags);\n return { regexp, keys };\n}\n\n/**\n * Convert a path or array of paths into a flat array.\n */\nfunction pathsToArray(paths: Path | Path[], init: Path[]): Path[] {\n if (Array.isArray(paths)) {\n for (const p of paths) pathsToArray(p, init);\n } else {\n init.push(paths);\n }\n return init;\n}\n\n/**\n * Flattened token set.\n */\ntype FlatToken = Text | Parameter | Wildcard;\n\n/**\n * Generate a flat list of sequence tokens from the given tokens.\n */\nfunction* flatten(\n tokens: Token[],\n index: number,\n init: FlatToken[],\n): Generator<FlatToken[]> {\n if (index === tokens.length) {\n return yield init;\n }\n\n const token = tokens[index];\n\n if (token.type === \"group\") {\n for (const seq of flatten(token.tokens, 0, init.slice())) {\n yield* flatten(tokens, index + 1, seq);\n }\n } else {\n init.push(token);\n }\n\n yield* flatten(tokens, index + 1, init);\n}\n\n/**\n * Transform a flat sequence of tokens into a regular expression.\n */\nfunction toRegExpSource(\n tokens: FlatToken[],\n delimiter: string,\n keys: Keys,\n originalPath: string | undefined,\n): string {\n let result = \"\";\n let backtrack = \"\";\n let isSafeSegmentParam = true;\n\n for (const token of tokens) {\n if (token.type === \"text\") {\n result += escape(token.value);\n backtrack += token.value;\n isSafeSegmentParam ||= token.value.includes(delimiter);\n continue;\n }\n\n if (token.type === \"param\" || token.type === \"wildcard\") {\n if (!isSafeSegmentParam && !backtrack) {\n throw new PathError(\n `Missing text before \"${token.name}\" ${token.type}`,\n originalPath,\n );\n }\n\n if (token.type === \"param\") {\n result += `(${negate(delimiter, isSafeSegmentParam ? \"\" : backtrack)}+)`;\n } else {\n result += `([\\\\s\\\\S]+)`;\n }\n\n keys.push(token);\n backtrack = \"\";\n isSafeSegmentParam = false;\n continue;\n }\n }\n\n return result;\n}\n\n/**\n * Block backtracking on previous text and ignore delimiter string.\n */\nfunction negate(delimiter: string, backtrack: string): string {\n if (backtrack.length < 2) {\n if (delimiter.length < 2) return `[^${escape(delimiter + backtrack)}]`;\n return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;\n }\n if (delimiter.length < 2) {\n return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;\n }\n return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\\\s\\\\S])`;\n}\n\n/**\n * Stringify an array of tokens into a path string.\n */\nfunction stringifyTokens(tokens: Token[]): string {\n let value = \"\";\n let i = 0;\n\n function name(value: string) {\n const isSafe = isNameSafe(value) && isNextNameSafe(tokens[i]);\n return isSafe ? value : JSON.stringify(value);\n }\n\n while (i < tokens.length) {\n const token = tokens[i++];\n\n if (token.type === \"text\") {\n value += escapeText(token.value);\n continue;\n }\n\n if (token.type === \"group\") {\n value += `{${stringifyTokens(token.tokens)}}`;\n continue;\n }\n\n if (token.type === \"param\") {\n value += `:${name(token.name)}`;\n continue;\n }\n\n if (token.type === \"wildcard\") {\n value += `*${name(token.name)}`;\n continue;\n }\n\n throw new TypeError(`Unknown token type: ${(token as any).type}`);\n }\n\n return value;\n}\n\n/**\n * Stringify token data into a path string.\n */\nexport function stringify(data: TokenData): string {\n return stringifyTokens(data.tokens);\n}\n\n/**\n * Validate the parameter name contains valid ID characters.\n */\nfunction isNameSafe(name: string): boolean {\n const [first, ...rest] = name;\n return ID_START.test(first) && rest.every((char) => ID_CONTINUE.test(char));\n}\n\n/**\n * Validate the next token does not interfere with the current param name.\n */\nfunction isNextNameSafe(token: Token | undefined): boolean {\n if (token && token.type === \"text\") return !ID_CONTINUE.test(token.value[0]);\n return true;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "path-to-regexp",
3
- "version": "8.1.0",
3
+ "version": "8.3.0",
4
4
  "description": "Express style path to RegExp utility",
5
5
  "keywords": [
6
6
  "express",
@@ -12,6 +12,10 @@
12
12
  "type": "git",
13
13
  "url": "https://github.com/pillarjs/path-to-regexp.git"
14
14
  },
15
+ "funding": {
16
+ "type": "opencollective",
17
+ "url": "https://opencollective.com/express"
18
+ },
15
19
  "license": "MIT",
16
20
  "exports": "./dist/index.js",
17
21
  "main": "dist/index.js",
@@ -32,15 +36,13 @@
32
36
  "devDependencies": {
33
37
  "@borderless/ts-scripts": "^0.15.0",
34
38
  "@size-limit/preset-small-lib": "^11.1.2",
35
- "@types/node": "^20.4.9",
39
+ "@types/node": "^22.7.2",
36
40
  "@types/semver": "^7.3.1",
37
- "@vitest/coverage-v8": "^1.4.0",
41
+ "@vitest/coverage-v8": "^3.0.5",
38
42
  "recheck": "^4.4.5",
39
43
  "size-limit": "^11.1.2",
40
- "typescript": "^5.5.3"
41
- },
42
- "engines": {
43
- "node": ">=16"
44
+ "typescript": "^5.7.3",
45
+ "vitest": "^3.0.5"
44
46
  },
45
47
  "publishConfig": {
46
48
  "access": "public"
@@ -48,7 +50,7 @@
48
50
  "size-limit": [
49
51
  {
50
52
  "path": "dist/index.js",
51
- "limit": "2.2 kB"
53
+ "limit": "2 kB"
52
54
  }
53
55
  ],
54
56
  "ts-scripts": {