path-to-regexp 4.0.5 → 6.2.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/History.md +35 -33
- package/Readme.md +129 -67
- package/dist/index.d.ts +15 -24
- package/dist/index.js +189 -153
- package/dist/index.js.map +1 -1
- package/dist.es2015/index.js +188 -152
- package/dist.es2015/index.js.map +1 -1
- package/package.json +16 -16
- package/dist/index.spec.d.ts +0 -1
- package/dist/index.spec.js +0 -2764
- package/dist/index.spec.js.map +0 -1
- package/dist.es2015/index.spec.js +0 -2762
- package/dist.es2015/index.spec.js.map +0 -1
package/dist.es2015/index.js
CHANGED
@@ -1,66 +1,32 @@
|
|
1
1
|
/**
|
2
|
-
*
|
2
|
+
* Tokenize input string.
|
3
3
|
*/
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
* slash and normalizes unicode characters to "NFC". When using this method,
|
8
|
-
* `decode` should be an identity function so you don't decode strings twice.
|
9
|
-
*/
|
10
|
-
export function normalizePathname(pathname) {
|
11
|
-
return decodeURI(pathname).replace(/\/+/g, "/");
|
12
|
-
}
|
13
|
-
/**
|
14
|
-
* Balanced bracket helper function.
|
15
|
-
*/
|
16
|
-
function balanced(open, close, str, index) {
|
17
|
-
var count = 0;
|
18
|
-
var i = index;
|
4
|
+
function lexer(str) {
|
5
|
+
var tokens = [];
|
6
|
+
var i = 0;
|
19
7
|
while (i < str.length) {
|
20
|
-
|
21
|
-
|
8
|
+
var char = str[i];
|
9
|
+
if (char === "*" || char === "+" || char === "?") {
|
10
|
+
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
|
22
11
|
continue;
|
23
12
|
}
|
24
|
-
if (
|
25
|
-
|
26
|
-
|
27
|
-
return i + 1;
|
13
|
+
if (char === "\\") {
|
14
|
+
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
|
15
|
+
continue;
|
28
16
|
}
|
29
|
-
if (
|
30
|
-
|
17
|
+
if (char === "{") {
|
18
|
+
tokens.push({ type: "OPEN", index: i, value: str[i++] });
|
19
|
+
continue;
|
31
20
|
}
|
32
|
-
|
33
|
-
|
34
|
-
return -1;
|
35
|
-
}
|
36
|
-
/**
|
37
|
-
* Parse a string for the raw tokens.
|
38
|
-
*/
|
39
|
-
export function parse(str, options) {
|
40
|
-
if (options === void 0) { options = {}; }
|
41
|
-
var _a, _b;
|
42
|
-
var tokens = [];
|
43
|
-
var defaultDelimiter = (_a = options.delimiter, (_a !== null && _a !== void 0 ? _a : DEFAULT_DELIMITER));
|
44
|
-
var whitelist = (_b = options.whitelist, (_b !== null && _b !== void 0 ? _b : undefined));
|
45
|
-
var i = 0;
|
46
|
-
var key = 0;
|
47
|
-
var path = "";
|
48
|
-
var isEscaped = false;
|
49
|
-
// tslint:disable-next-line
|
50
|
-
while (i < str.length) {
|
51
|
-
var prefix = "";
|
52
|
-
var name = "";
|
53
|
-
var pattern = "";
|
54
|
-
// Ignore escaped sequences.
|
55
|
-
if (str[i] === "\\") {
|
56
|
-
i++;
|
57
|
-
path += str[i++];
|
58
|
-
isEscaped = true;
|
21
|
+
if (char === "}") {
|
22
|
+
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
|
59
23
|
continue;
|
60
24
|
}
|
61
|
-
if (
|
62
|
-
|
63
|
-
|
25
|
+
if (char === ":") {
|
26
|
+
var name = "";
|
27
|
+
var j = i + 1;
|
28
|
+
while (j < str.length) {
|
29
|
+
var code = str.charCodeAt(j);
|
64
30
|
if (
|
65
31
|
// `0-9`
|
66
32
|
(code >= 48 && code <= 57) ||
|
@@ -70,71 +36,140 @@ export function parse(str, options) {
|
|
70
36
|
(code >= 97 && code <= 122) ||
|
71
37
|
// `_`
|
72
38
|
code === 95) {
|
73
|
-
name += str[
|
39
|
+
name += str[j++];
|
74
40
|
continue;
|
75
41
|
}
|
76
42
|
break;
|
77
43
|
}
|
78
|
-
// False positive on param name.
|
79
44
|
if (!name)
|
80
|
-
i
|
45
|
+
throw new TypeError("Missing parameter name at " + i);
|
46
|
+
tokens.push({ type: "NAME", index: i, value: name });
|
47
|
+
i = j;
|
48
|
+
continue;
|
81
49
|
}
|
82
|
-
if (
|
83
|
-
var
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
50
|
+
if (char === "(") {
|
51
|
+
var count = 1;
|
52
|
+
var pattern = "";
|
53
|
+
var j = i + 1;
|
54
|
+
if (str[j] === "?") {
|
55
|
+
throw new TypeError("Pattern cannot start with \"?\" at " + j);
|
56
|
+
}
|
57
|
+
while (j < str.length) {
|
58
|
+
if (str[j] === "\\") {
|
59
|
+
pattern += str[j++] + str[j++];
|
60
|
+
continue;
|
61
|
+
}
|
62
|
+
if (str[j] === ")") {
|
63
|
+
count--;
|
64
|
+
if (count === 0) {
|
65
|
+
j++;
|
66
|
+
break;
|
67
|
+
}
|
90
68
|
}
|
91
|
-
if (
|
92
|
-
|
93
|
-
|
69
|
+
else if (str[j] === "(") {
|
70
|
+
count++;
|
71
|
+
if (str[j + 1] !== "?") {
|
72
|
+
throw new TypeError("Capturing groups are not allowed at " + j);
|
73
|
+
}
|
94
74
|
}
|
75
|
+
pattern += str[j++];
|
95
76
|
}
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
77
|
+
if (count)
|
78
|
+
throw new TypeError("Unbalanced pattern at " + i);
|
79
|
+
if (!pattern)
|
80
|
+
throw new TypeError("Missing pattern at " + i);
|
81
|
+
tokens.push({ type: "PATTERN", index: i, value: pattern });
|
82
|
+
i = j;
|
101
83
|
continue;
|
102
84
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
85
|
+
tokens.push({ type: "CHAR", index: i, value: str[i++] });
|
86
|
+
}
|
87
|
+
tokens.push({ type: "END", index: i, value: "" });
|
88
|
+
return tokens;
|
89
|
+
}
|
90
|
+
/**
|
91
|
+
* Parse a string for the raw tokens.
|
92
|
+
*/
|
93
|
+
export function parse(str, options) {
|
94
|
+
if (options === void 0) { options = {}; }
|
95
|
+
var tokens = lexer(str);
|
96
|
+
var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
|
97
|
+
var defaultPattern = "[^" + escapeString(options.delimiter || "/#?") + "]+?";
|
98
|
+
var result = [];
|
99
|
+
var key = 0;
|
100
|
+
var i = 0;
|
101
|
+
var path = "";
|
102
|
+
var tryConsume = function (type) {
|
103
|
+
if (i < tokens.length && tokens[i].type === type)
|
104
|
+
return tokens[i++].value;
|
105
|
+
};
|
106
|
+
var mustConsume = function (type) {
|
107
|
+
var value = tryConsume(type);
|
108
|
+
if (value !== undefined)
|
109
|
+
return value;
|
110
|
+
var _a = tokens[i], nextType = _a.type, index = _a.index;
|
111
|
+
throw new TypeError("Unexpected " + nextType + " at " + index + ", expected " + type);
|
112
|
+
};
|
113
|
+
var consumeText = function () {
|
114
|
+
var result = "";
|
115
|
+
var value;
|
116
|
+
// tslint:disable-next-line
|
117
|
+
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
|
118
|
+
result += value;
|
119
|
+
}
|
120
|
+
return result;
|
121
|
+
};
|
122
|
+
while (i < tokens.length) {
|
123
|
+
var char = tryConsume("CHAR");
|
124
|
+
var name = tryConsume("NAME");
|
125
|
+
var pattern = tryConsume("PATTERN");
|
126
|
+
if (name || pattern) {
|
127
|
+
var prefix = char || "";
|
128
|
+
if (prefixes.indexOf(prefix) === -1) {
|
129
|
+
path += prefix;
|
130
|
+
prefix = "";
|
131
|
+
}
|
132
|
+
if (path) {
|
133
|
+
result.push(path);
|
134
|
+
path = "";
|
110
135
|
}
|
136
|
+
result.push({
|
137
|
+
name: name || key++,
|
138
|
+
prefix: prefix,
|
139
|
+
suffix: "",
|
140
|
+
pattern: pattern || defaultPattern,
|
141
|
+
modifier: tryConsume("MODIFIER") || ""
|
142
|
+
});
|
143
|
+
continue;
|
144
|
+
}
|
145
|
+
var value = char || tryConsume("ESCAPED_CHAR");
|
146
|
+
if (value) {
|
147
|
+
path += value;
|
148
|
+
continue;
|
111
149
|
}
|
112
|
-
|
113
|
-
|
114
|
-
tokens.push(path);
|
150
|
+
if (path) {
|
151
|
+
result.push(path);
|
115
152
|
path = "";
|
116
153
|
}
|
117
|
-
var
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
154
|
+
var open = tryConsume("OPEN");
|
155
|
+
if (open) {
|
156
|
+
var prefix = consumeText();
|
157
|
+
var name_1 = tryConsume("NAME") || "";
|
158
|
+
var pattern_1 = tryConsume("PATTERN") || "";
|
159
|
+
var suffix = consumeText();
|
160
|
+
mustConsume("CLOSE");
|
161
|
+
result.push({
|
162
|
+
name: name_1 || (pattern_1 ? key++ : ""),
|
163
|
+
pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
|
164
|
+
prefix: prefix,
|
165
|
+
suffix: suffix,
|
166
|
+
modifier: tryConsume("MODIFIER") || ""
|
167
|
+
});
|
168
|
+
continue;
|
169
|
+
}
|
170
|
+
mustConsume("END");
|
134
171
|
}
|
135
|
-
|
136
|
-
tokens.push(path);
|
137
|
-
return tokens;
|
172
|
+
return result;
|
138
173
|
}
|
139
174
|
/**
|
140
175
|
* Compile a string to a template function for the path.
|
@@ -148,7 +183,7 @@ export function compile(str, options) {
|
|
148
183
|
export function tokensToFunction(tokens, options) {
|
149
184
|
if (options === void 0) { options = {}; }
|
150
185
|
var reFlags = flags(options);
|
151
|
-
var _a = options.encode, encode = _a === void 0 ?
|
186
|
+
var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b;
|
152
187
|
// Compile all the tokens into regexps.
|
153
188
|
var matches = tokens.map(function (token) {
|
154
189
|
if (typeof token === "object") {
|
@@ -164,12 +199,14 @@ export function tokensToFunction(tokens, options) {
|
|
164
199
|
continue;
|
165
200
|
}
|
166
201
|
var value = data ? data[token.name] : undefined;
|
202
|
+
var optional = token.modifier === "?" || token.modifier === "*";
|
203
|
+
var repeat = token.modifier === "*" || token.modifier === "+";
|
167
204
|
if (Array.isArray(value)) {
|
168
|
-
if (!
|
205
|
+
if (!repeat) {
|
169
206
|
throw new TypeError("Expected \"" + token.name + "\" to not repeat, but got an array");
|
170
207
|
}
|
171
208
|
if (value.length === 0) {
|
172
|
-
if (
|
209
|
+
if (optional)
|
173
210
|
continue;
|
174
211
|
throw new TypeError("Expected \"" + token.name + "\" to not be empty");
|
175
212
|
}
|
@@ -178,7 +215,7 @@ export function tokensToFunction(tokens, options) {
|
|
178
215
|
if (validate && !matches[i].test(segment)) {
|
179
216
|
throw new TypeError("Expected all \"" + token.name + "\" to match \"" + token.pattern + "\", but got \"" + segment + "\"");
|
180
217
|
}
|
181
|
-
path +=
|
218
|
+
path += token.prefix + segment + token.suffix;
|
182
219
|
}
|
183
220
|
continue;
|
184
221
|
}
|
@@ -187,12 +224,12 @@ export function tokensToFunction(tokens, options) {
|
|
187
224
|
if (validate && !matches[i].test(segment)) {
|
188
225
|
throw new TypeError("Expected \"" + token.name + "\" to match \"" + token.pattern + "\", but got \"" + segment + "\"");
|
189
226
|
}
|
190
|
-
path += token.prefix + segment;
|
227
|
+
path += token.prefix + segment + token.suffix;
|
191
228
|
continue;
|
192
229
|
}
|
193
|
-
if (
|
230
|
+
if (optional)
|
194
231
|
continue;
|
195
|
-
var typeOfMessage =
|
232
|
+
var typeOfMessage = repeat ? "an array" : "a string";
|
196
233
|
throw new TypeError("Expected \"" + token.name + "\" to be " + typeOfMessage);
|
197
234
|
}
|
198
235
|
return path;
|
@@ -223,8 +260,8 @@ export function regexpToFunction(re, keys, options) {
|
|
223
260
|
if (m[i] === undefined)
|
224
261
|
return "continue";
|
225
262
|
var key = keys[i - 1];
|
226
|
-
if (key.
|
227
|
-
params[key.name] = m[i].split(key.
|
263
|
+
if (key.modifier === "*" || key.modifier === "+") {
|
264
|
+
params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) {
|
228
265
|
return decode(value, key);
|
229
266
|
});
|
230
267
|
}
|
@@ -256,19 +293,19 @@ function flags(options) {
|
|
256
293
|
function regexpToRegexp(path, keys) {
|
257
294
|
if (!keys)
|
258
295
|
return path;
|
259
|
-
|
260
|
-
var
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
296
|
+
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
|
297
|
+
var index = 0;
|
298
|
+
var execResult = groupsRegex.exec(path.source);
|
299
|
+
while (execResult) {
|
300
|
+
keys.push({
|
301
|
+
// Use parenthesized substring match if available, index otherwise
|
302
|
+
name: execResult[1] || index++,
|
303
|
+
prefix: "",
|
304
|
+
suffix: "",
|
305
|
+
modifier: "",
|
306
|
+
pattern: ""
|
307
|
+
});
|
308
|
+
execResult = groupsRegex.exec(path.source);
|
272
309
|
}
|
273
310
|
return path;
|
274
311
|
}
|
@@ -290,55 +327,56 @@ function stringToRegexp(path, keys, options) {
|
|
290
327
|
*/
|
291
328
|
export function tokensToRegexp(tokens, keys, options) {
|
292
329
|
if (options === void 0) { options = {}; }
|
293
|
-
var
|
294
|
-
var endsWith = (
|
295
|
-
|
296
|
-
: options.endsWith || [])
|
297
|
-
.map(escapeString)
|
298
|
-
.concat("$")
|
299
|
-
.join("|");
|
330
|
+
var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d;
|
331
|
+
var endsWith = "[" + escapeString(options.endsWith || "") + "]|$";
|
332
|
+
var delimiter = "[" + escapeString(options.delimiter || "/#?") + "]";
|
300
333
|
var route = start ? "^" : "";
|
301
334
|
// Iterate over the tokens and create our regexp string.
|
302
335
|
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
|
303
336
|
var token = tokens_1[_i];
|
304
337
|
if (typeof token === "string") {
|
305
|
-
route += escapeString(token);
|
338
|
+
route += escapeString(encode(token));
|
306
339
|
}
|
307
340
|
else {
|
308
|
-
var
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
341
|
+
var prefix = escapeString(encode(token.prefix));
|
342
|
+
var suffix = escapeString(encode(token.suffix));
|
343
|
+
if (token.pattern) {
|
344
|
+
if (keys)
|
345
|
+
keys.push(token);
|
346
|
+
if (prefix || suffix) {
|
347
|
+
if (token.modifier === "+" || token.modifier === "*") {
|
348
|
+
var mod = token.modifier === "*" ? "?" : "";
|
349
|
+
route += "(?:" + prefix + "((?:" + token.pattern + ")(?:" + suffix + prefix + "(?:" + token.pattern + "))*)" + suffix + ")" + mod;
|
350
|
+
}
|
351
|
+
else {
|
352
|
+
route += "(?:" + prefix + "(" + token.pattern + ")" + suffix + ")" + token.modifier;
|
353
|
+
}
|
316
354
|
}
|
317
355
|
else {
|
318
|
-
route += "(
|
356
|
+
route += "(" + token.pattern + ")" + token.modifier;
|
319
357
|
}
|
320
358
|
}
|
321
359
|
else {
|
322
|
-
route +=
|
360
|
+
route += "(?:" + prefix + suffix + ")" + token.modifier;
|
323
361
|
}
|
324
362
|
}
|
325
363
|
}
|
326
364
|
if (end) {
|
327
365
|
if (!strict)
|
328
|
-
route +=
|
329
|
-
route += endsWith
|
366
|
+
route += delimiter + "?";
|
367
|
+
route += !options.endsWith ? "$" : "(?=" + endsWith + ")";
|
330
368
|
}
|
331
369
|
else {
|
332
370
|
var endToken = tokens[tokens.length - 1];
|
333
371
|
var isEndDelimited = typeof endToken === "string"
|
334
|
-
? endToken[endToken.length - 1]
|
372
|
+
? delimiter.indexOf(endToken[endToken.length - 1]) > -1
|
335
373
|
: // tslint:disable-next-line
|
336
374
|
endToken === undefined;
|
337
375
|
if (!strict) {
|
338
|
-
route += "(?:" +
|
376
|
+
route += "(?:" + delimiter + "(?=" + endsWith + "))?";
|
339
377
|
}
|
340
378
|
if (!isEndDelimited) {
|
341
|
-
route += "(?=" +
|
379
|
+
route += "(?=" + delimiter + "|" + endsWith + ")";
|
342
380
|
}
|
343
381
|
}
|
344
382
|
return new RegExp(route, flags(options));
|
@@ -351,12 +389,10 @@ export function tokensToRegexp(tokens, keys, options) {
|
|
351
389
|
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
352
390
|
*/
|
353
391
|
export function pathToRegexp(path, keys, options) {
|
354
|
-
if (path instanceof RegExp)
|
392
|
+
if (path instanceof RegExp)
|
355
393
|
return regexpToRegexp(path, keys);
|
356
|
-
|
357
|
-
if (Array.isArray(path)) {
|
394
|
+
if (Array.isArray(path))
|
358
395
|
return arrayToRegexp(path, keys, options);
|
359
|
-
}
|
360
396
|
return stringToRegexp(path, keys, options);
|
361
397
|
}
|
362
398
|
//# sourceMappingURL=index.js.map
|
package/dist.es2015/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Default configs.\n */\nconst DEFAULT_DELIMITER = \"/\";\n\nexport interface ParseOptions {\n /**\n * Set the default delimiter for repeat parameters. (default: `'/'`)\n */\n delimiter?: string;\n /**\n * List of characters to consider delimiters when parsing. (default: `undefined`, any character)\n */\n whitelist?: string | string[];\n}\n\n/**\n * Normalize a pathname for matching, replaces multiple slashes with a single\n * slash and normalizes unicode characters to \"NFC\". When using this method,\n * `decode` should be an identity function so you don't decode strings twice.\n */\nexport function normalizePathname(pathname: string) {\n return decodeURI(pathname).replace(/\\/+/g, \"/\");\n}\n\n/**\n * Balanced bracket helper function.\n */\nfunction balanced(open: string, close: string, str: string, index: number) {\n let count = 0;\n let i = index;\n\n while (i < str.length) {\n if (str[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n\n if (str[i] === close) {\n count--;\n\n if (count === 0) return i + 1;\n }\n\n if (str[i] === open) {\n count++;\n }\n\n i++;\n }\n\n return -1;\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): Token[] {\n const tokens = [];\n const defaultDelimiter = options.delimiter ?? DEFAULT_DELIMITER;\n const whitelist = options.whitelist ?? undefined;\n let i = 0;\n let key = 0;\n let path = \"\";\n let isEscaped = false;\n\n // tslint:disable-next-line\n while (i < str.length) {\n let prefix = \"\";\n let name = \"\";\n let pattern = \"\";\n\n // Ignore escaped sequences.\n if (str[i] === \"\\\\\") {\n i++;\n path += str[i++];\n isEscaped = true;\n continue;\n }\n\n if (str[i] === \":\") {\n while (++i < str.length) {\n const code = str.charCodeAt(i);\n\n if (\n // `0-9`\n (code >= 48 && code <= 57) ||\n // `A-Z`\n (code >= 65 && code <= 90) ||\n // `a-z`\n (code >= 97 && code <= 122) ||\n // `_`\n code === 95\n ) {\n name += str[i];\n continue;\n }\n\n break;\n }\n\n // False positive on param name.\n if (!name) i--;\n }\n\n if (str[i] === \"(\") {\n const end = balanced(\"(\", \")\", str, i);\n\n // False positive on matching brackets.\n if (end > -1) {\n pattern = str.slice(i + 1, end - 1);\n i = end;\n\n if (pattern[0] === \"?\") {\n throw new TypeError(\"Path pattern must be a capturing group\");\n }\n\n if (/\\((?=[^?])/.test(pattern)) {\n const validPattern = pattern.replace(/\\((?=[^?])/, \"(?:\");\n\n throw new TypeError(\n `Capturing groups are not allowed in pattern, use a non-capturing group: (${validPattern})`\n );\n }\n }\n }\n\n // Add regular characters to the path string.\n if (name === \"\" && pattern === \"\") {\n path += str[i++];\n isEscaped = false;\n continue;\n }\n\n // Extract the final character from `path` for the prefix.\n if (path.length && !isEscaped) {\n const char = path[path.length - 1];\n const matches = whitelist ? whitelist.indexOf(char) > -1 : true;\n\n if (matches) {\n prefix = char;\n path = path.slice(0, -1);\n }\n }\n\n // Push the current path onto the list of tokens.\n if (path.length) {\n tokens.push(path);\n path = \"\";\n }\n\n const repeat = str[i] === \"+\" || str[i] === \"*\";\n const optional = str[i] === \"?\" || str[i] === \"*\";\n const delimiter = prefix || defaultDelimiter;\n\n // Increment `i` past modifier token.\n if (repeat || optional) i++;\n\n tokens.push({\n name: name || key++,\n prefix,\n delimiter,\n optional,\n repeat,\n pattern:\n pattern ||\n `[^${escapeString(\n delimiter === defaultDelimiter\n ? delimiter\n : delimiter + defaultDelimiter\n )}]+?`\n });\n }\n\n if (path.length) tokens.push(path);\n\n return tokens;\n}\n\nexport interface TokensToFunctionOptions {\n /**\n * When `true` the regexp will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * Function for encoding input strings for output.\n */\n encode?: (value: string, token: Key) => string;\n /**\n * When `false` the function can produce an invalid (unmatched) path. (default: `true`)\n */\n validate?: boolean;\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile<P extends object = object>(\n str: string,\n options?: ParseOptions & TokensToFunctionOptions\n) {\n return tokensToFunction<P>(parse(str, options), options);\n}\n\nexport type PathFunction<P extends object = object> = (data?: P) => string;\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nexport function tokensToFunction<P extends object = object>(\n tokens: Token[],\n options: TokensToFunctionOptions = {}\n): PathFunction<P> {\n const reFlags = flags(options);\n const { encode = encodeURIComponent, validate = true } = options;\n\n // Compile all the tokens into regexps.\n const matches = tokens.map(token => {\n if (typeof token === \"object\") {\n return new RegExp(`^(?:${token.pattern})$`, reFlags);\n }\n });\n\n return (data: Record<string, any> | null | undefined) => {\n let path = \"\";\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n if (typeof token === \"string\") {\n path += token;\n continue;\n }\n\n const value = data ? data[token.name] : undefined;\n\n if (Array.isArray(value)) {\n if (!token.repeat) {\n throw new TypeError(\n `Expected \"${token.name}\" to not repeat, but got an array`\n );\n }\n\n if (value.length === 0) {\n if (token.optional) continue;\n\n throw new TypeError(`Expected \"${token.name}\" to not be empty`);\n }\n\n for (let j = 0; j < value.length; j++) {\n const segment = encode(value[j], token);\n\n if (validate && !(matches[i] as RegExp).test(segment)) {\n throw new TypeError(\n `Expected all \"${token.name}\" to match \"${token.pattern}\", but got \"${segment}\"`\n );\n }\n\n path += (j === 0 ? token.prefix : token.delimiter) + segment;\n }\n\n continue;\n }\n\n if (typeof value === \"string\" || typeof value === \"number\") {\n const segment = encode(String(value), token);\n\n if (validate && !(matches[i] as RegExp).test(segment)) {\n throw new TypeError(\n `Expected \"${token.name}\" to match \"${token.pattern}\", but got \"${segment}\"`\n );\n }\n\n path += token.prefix + segment;\n continue;\n }\n\n if (token.optional) continue;\n\n const typeOfMessage = token.repeat ? \"an array\" : \"a string\";\n throw new TypeError(`Expected \"${token.name}\" to be ${typeOfMessage}`);\n }\n\n return path;\n };\n}\n\nexport interface RegexpToFunctionOptions {\n /**\n * Function for decoding strings for params.\n */\n decode?: (value: string, token: Key) => string;\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult<P extends object = object> {\n path: string;\n index: number;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match<P extends object = object> = 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 object = object> = (\n path: string\n) => Match<P>;\n\n/**\n * Create path match function from `path-to-regexp` spec.\n */\nexport function match<P extends object = object>(\n str: Path,\n options?: ParseOptions & RegexpOptions & RegexpToFunctionOptions\n) {\n const keys: Key[] = [];\n const re = pathToRegexp(str, keys, options);\n return regexpToFunction<P>(re, keys, options);\n}\n\n/**\n * Create a path match function from `path-to-regexp` output.\n */\nexport function regexpToFunction<P extends object = object>(\n re: RegExp,\n keys: Key[],\n options: RegexpToFunctionOptions = {}\n): MatchFunction<P> {\n const { decode = (x: string) => x } = options;\n\n return function(pathname: string) {\n const m = re.exec(pathname);\n if (!m) return false;\n\n const { 0: path, index } = m;\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n // tslint:disable-next-line\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n\n if (key.repeat) {\n params[key.name] = m[i].split(key.delimiter).map(value => {\n return decode(value, key);\n });\n } else {\n params[key.name] = decode(m[i], key);\n }\n }\n\n return { path, index, params };\n };\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escapeString(str: string) {\n return str.replace(/([.+*?=^!:${}()[\\]|/\\\\])/g, \"\\\\$1\");\n}\n\n/**\n * Get the flags for a regexp from the options.\n */\nfunction flags(options?: { sensitive?: boolean }) {\n return options && options.sensitive ? \"\" : \"i\";\n}\n\n/**\n * Metadata about a key.\n */\nexport interface Key {\n name: string | number;\n prefix: string;\n delimiter: string;\n optional: boolean;\n repeat: boolean;\n pattern: string;\n}\n\n/**\n * A token is a string (nothing special) or key metadata (capture group).\n */\nexport type Token = string | Key;\n\n/**\n * Pull out keys from a regexp.\n */\nfunction regexpToRegexp(path: RegExp, keys?: Key[]): RegExp {\n if (!keys) return path;\n\n // Use a negative lookahead to match only capturing groups.\n const groups = path.source.match(/\\((?!\\?)/g);\n\n if (groups) {\n for (let i = 0; i < groups.length; i++) {\n keys.push({\n name: i,\n prefix: \"\",\n delimiter: \"\",\n optional: false,\n repeat: false,\n pattern: \"\"\n });\n }\n }\n\n return path;\n}\n\n/**\n * Transform an array into a regexp.\n */\nfunction arrayToRegexp(\n paths: Array<string | RegExp>,\n keys?: Key[],\n options?: RegexpOptions & ParseOptions\n): RegExp {\n const parts = paths.map(path => pathToRegexp(path, keys, options).source);\n return new RegExp(`(?:${parts.join(\"|\")})`, flags(options));\n}\n\n/**\n * Create a path regexp from string input.\n */\nfunction stringToRegexp(\n path: string,\n keys?: Key[],\n options?: RegexpOptions & ParseOptions\n) {\n return tokensToRegexp(parse(path, options), keys, options);\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n */\nexport function tokensToRegexp(\n tokens: Token[],\n keys?: Key[],\n options: RegexpOptions = {}\n) {\n const {\n strict,\n start = true,\n end = true,\n delimiter = DEFAULT_DELIMITER\n } = options;\n const endsWith = (typeof options.endsWith === \"string\"\n ? options.endsWith.split(\"\")\n : options.endsWith || []\n )\n .map(escapeString)\n .concat(\"$\")\n .join(\"|\");\n let route = start ? \"^\" : \"\";\n\n // Iterate over the tokens and create our regexp string.\n for (const token of tokens) {\n if (typeof token === \"string\") {\n route += escapeString(token);\n } else {\n const capture = token.repeat\n ? `(?:${token.pattern})(?:${escapeString(token.delimiter)}(?:${\n token.pattern\n }))*`\n : token.pattern;\n\n if (keys) keys.push(token);\n\n if (token.optional) {\n if (!token.prefix) {\n route += `(${capture})?`;\n } else {\n route += `(?:${escapeString(token.prefix)}(${capture}))?`;\n }\n } else {\n route += `${escapeString(token.prefix)}(${capture})`;\n }\n }\n }\n\n if (end) {\n if (!strict) route += `(?:${escapeString(delimiter)})?`;\n\n route += endsWith === \"$\" ? \"$\" : `(?=${endsWith})`;\n } else {\n const endToken = tokens[tokens.length - 1];\n const isEndDelimited =\n typeof endToken === \"string\"\n ? endToken[endToken.length - 1] === delimiter\n : // tslint:disable-next-line\n endToken === undefined;\n\n if (!strict) {\n route += `(?:${escapeString(delimiter)}(?=${endsWith}))?`;\n }\n\n if (!isEndDelimited) {\n route += `(?=${escapeString(delimiter)}|${endsWith})`;\n }\n }\n\n return new RegExp(route, flags(options));\n}\n\nexport interface RegexpOptions {\n /**\n * When `true` the regexp will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * When `true` the regexp allows an optional trailing delimiter to match. (default: `false`)\n */\n strict?: boolean;\n /**\n * When `true` the regexp will match to the end of the string. (default: `true`)\n */\n end?: boolean;\n /**\n * When `true` the regexp will match from the beginning of the string. (default: `true`)\n */\n start?: boolean;\n /**\n * Sets the final character for non-ending optimistic matches. (default: `/`)\n */\n delimiter?: string;\n /**\n * List of characters that can also be \"end\" characters.\n */\n endsWith?: string | string[];\n}\n\nexport interface ParseOptions {\n /**\n * Set the default delimiter for repeat parameters. (default: `'/'`)\n */\n delimiter?: string;\n}\n\n/**\n * Supported `path-to-regexp` input types.\n */\nexport type Path = string | RegExp | Array<string | RegExp>;\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n */\nexport function pathToRegexp(\n path: Path,\n keys?: Key[],\n options?: RegexpOptions & ParseOptions\n) {\n if (path instanceof RegExp) {\n return regexpToRegexp(path, keys);\n }\n\n if (Array.isArray(path)) {\n return arrayToRegexp(path, keys, options);\n }\n\n return stringToRegexp(path, keys, options);\n}\n"]}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tokenizer results.\n */\ninterface LexToken {\n type:\n | \"OPEN\"\n | \"CLOSE\"\n | \"PATTERN\"\n | \"NAME\"\n | \"CHAR\"\n | \"ESCAPED_CHAR\"\n | \"MODIFIER\"\n | \"END\";\n index: number;\n value: string;\n}\n\n/**\n * Tokenize input string.\n */\nfunction lexer(str: string): LexToken[] {\n const tokens: LexToken[] = [];\n let i = 0;\n\n while (i < str.length) {\n const char = str[i];\n\n if (char === \"*\" || char === \"+\" || char === \"?\") {\n tokens.push({ type: \"MODIFIER\", index: i, value: str[i++] });\n continue;\n }\n\n if (char === \"\\\\\") {\n tokens.push({ type: \"ESCAPED_CHAR\", index: i++, value: str[i++] });\n continue;\n }\n\n if (char === \"{\") {\n tokens.push({ type: \"OPEN\", index: i, value: str[i++] });\n continue;\n }\n\n if (char === \"}\") {\n tokens.push({ type: \"CLOSE\", index: i, value: str[i++] });\n continue;\n }\n\n if (char === \":\") {\n let name = \"\";\n let j = i + 1;\n\n while (j < str.length) {\n const code = str.charCodeAt(j);\n\n if (\n // `0-9`\n (code >= 48 && code <= 57) ||\n // `A-Z`\n (code >= 65 && code <= 90) ||\n // `a-z`\n (code >= 97 && code <= 122) ||\n // `_`\n code === 95\n ) {\n name += str[j++];\n continue;\n }\n\n break;\n }\n\n if (!name) throw new TypeError(`Missing parameter name at ${i}`);\n\n tokens.push({ type: \"NAME\", index: i, value: name });\n i = j;\n continue;\n }\n\n if (char === \"(\") {\n let count = 1;\n let pattern = \"\";\n let j = i + 1;\n\n if (str[j] === \"?\") {\n throw new TypeError(`Pattern cannot start with \"?\" at ${j}`);\n }\n\n while (j < str.length) {\n if (str[j] === \"\\\\\") {\n pattern += str[j++] + str[j++];\n continue;\n }\n\n if (str[j] === \")\") {\n count--;\n if (count === 0) {\n j++;\n break;\n }\n } else if (str[j] === \"(\") {\n count++;\n if (str[j + 1] !== \"?\") {\n throw new TypeError(`Capturing groups are not allowed at ${j}`);\n }\n }\n\n pattern += str[j++];\n }\n\n if (count) throw new TypeError(`Unbalanced pattern at ${i}`);\n if (!pattern) throw new TypeError(`Missing pattern at ${i}`);\n\n tokens.push({ type: \"PATTERN\", index: i, value: pattern });\n i = j;\n continue;\n }\n\n tokens.push({ type: \"CHAR\", index: i, value: str[i++] });\n }\n\n tokens.push({ type: \"END\", index: i, value: \"\" });\n\n return tokens;\n}\n\nexport interface ParseOptions {\n /**\n * Set the default delimiter for repeat parameters. (default: `'/'`)\n */\n delimiter?: string;\n /**\n * List of characters to automatically consider prefixes when parsing.\n */\n prefixes?: string;\n}\n\n/**\n * Parse a string for the raw tokens.\n */\nexport function parse(str: string, options: ParseOptions = {}): Token[] {\n const tokens = lexer(str);\n const { prefixes = \"./\" } = options;\n const defaultPattern = `[^${escapeString(options.delimiter || \"/#?\")}]+?`;\n const result: Token[] = [];\n let key = 0;\n let i = 0;\n let path = \"\";\n\n const tryConsume = (type: LexToken[\"type\"]): string | undefined => {\n if (i < tokens.length && tokens[i].type === type) return tokens[i++].value;\n };\n\n const mustConsume = (type: LexToken[\"type\"]): string => {\n const value = tryConsume(type);\n if (value !== undefined) return value;\n const { type: nextType, index } = tokens[i];\n throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}`);\n };\n\n const consumeText = (): string => {\n let result = \"\";\n let value: string | undefined;\n // tslint:disable-next-line\n while ((value = tryConsume(\"CHAR\") || tryConsume(\"ESCAPED_CHAR\"))) {\n result += value;\n }\n return result;\n };\n\n while (i < tokens.length) {\n const char = tryConsume(\"CHAR\");\n const name = tryConsume(\"NAME\");\n const pattern = tryConsume(\"PATTERN\");\n\n if (name || pattern) {\n let prefix = char || \"\";\n\n if (prefixes.indexOf(prefix) === -1) {\n path += prefix;\n prefix = \"\";\n }\n\n if (path) {\n result.push(path);\n path = \"\";\n }\n\n result.push({\n name: name || key++,\n prefix,\n suffix: \"\",\n pattern: pattern || defaultPattern,\n modifier: tryConsume(\"MODIFIER\") || \"\"\n });\n continue;\n }\n\n const value = char || tryConsume(\"ESCAPED_CHAR\");\n if (value) {\n path += value;\n continue;\n }\n\n if (path) {\n result.push(path);\n path = \"\";\n }\n\n const open = tryConsume(\"OPEN\");\n if (open) {\n const prefix = consumeText();\n const name = tryConsume(\"NAME\") || \"\";\n const pattern = tryConsume(\"PATTERN\") || \"\";\n const suffix = consumeText();\n\n mustConsume(\"CLOSE\");\n\n result.push({\n name: name || (pattern ? key++ : \"\"),\n pattern: name && !pattern ? defaultPattern : pattern,\n prefix,\n suffix,\n modifier: tryConsume(\"MODIFIER\") || \"\"\n });\n continue;\n }\n\n mustConsume(\"END\");\n }\n\n return result;\n}\n\nexport interface TokensToFunctionOptions {\n /**\n * When `true` the regexp will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * Function for encoding input strings for output.\n */\n encode?: (value: string, token: Key) => string;\n /**\n * When `false` the function can produce an invalid (unmatched) path. (default: `true`)\n */\n validate?: boolean;\n}\n\n/**\n * Compile a string to a template function for the path.\n */\nexport function compile<P extends object = object>(\n str: string,\n options?: ParseOptions & TokensToFunctionOptions\n) {\n return tokensToFunction<P>(parse(str, options), options);\n}\n\nexport type PathFunction<P extends object = object> = (data?: P) => string;\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nexport function tokensToFunction<P extends object = object>(\n tokens: Token[],\n options: TokensToFunctionOptions = {}\n): PathFunction<P> {\n const reFlags = flags(options);\n const { encode = (x: string) => x, validate = true } = options;\n\n // Compile all the tokens into regexps.\n const matches = tokens.map(token => {\n if (typeof token === \"object\") {\n return new RegExp(`^(?:${token.pattern})$`, reFlags);\n }\n });\n\n return (data: Record<string, any> | null | undefined) => {\n let path = \"\";\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n if (typeof token === \"string\") {\n path += token;\n continue;\n }\n\n const value = data ? data[token.name] : undefined;\n const optional = token.modifier === \"?\" || token.modifier === \"*\";\n const repeat = token.modifier === \"*\" || token.modifier === \"+\";\n\n if (Array.isArray(value)) {\n if (!repeat) {\n throw new TypeError(\n `Expected \"${token.name}\" to not repeat, but got an array`\n );\n }\n\n if (value.length === 0) {\n if (optional) continue;\n\n throw new TypeError(`Expected \"${token.name}\" to not be empty`);\n }\n\n for (let j = 0; j < value.length; j++) {\n const segment = encode(value[j], token);\n\n if (validate && !(matches[i] as RegExp).test(segment)) {\n throw new TypeError(\n `Expected all \"${token.name}\" to match \"${token.pattern}\", but got \"${segment}\"`\n );\n }\n\n path += token.prefix + segment + token.suffix;\n }\n\n continue;\n }\n\n if (typeof value === \"string\" || typeof value === \"number\") {\n const segment = encode(String(value), token);\n\n if (validate && !(matches[i] as RegExp).test(segment)) {\n throw new TypeError(\n `Expected \"${token.name}\" to match \"${token.pattern}\", but got \"${segment}\"`\n );\n }\n\n path += token.prefix + segment + token.suffix;\n continue;\n }\n\n if (optional) continue;\n\n const typeOfMessage = repeat ? \"an array\" : \"a string\";\n throw new TypeError(`Expected \"${token.name}\" to be ${typeOfMessage}`);\n }\n\n return path;\n };\n}\n\nexport interface RegexpToFunctionOptions {\n /**\n * Function for decoding strings for params.\n */\n decode?: (value: string, token: Key) => string;\n}\n\n/**\n * A match result contains data about the path match.\n */\nexport interface MatchResult<P extends object = object> {\n path: string;\n index: number;\n params: P;\n}\n\n/**\n * A match is either `false` (no match) or a match result.\n */\nexport type Match<P extends object = object> = 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 object = object> = (\n path: string\n) => Match<P>;\n\n/**\n * Create path match function from `path-to-regexp` spec.\n */\nexport function match<P extends object = object>(\n str: Path,\n options?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions\n) {\n const keys: Key[] = [];\n const re = pathToRegexp(str, keys, options);\n return regexpToFunction<P>(re, keys, options);\n}\n\n/**\n * Create a path match function from `path-to-regexp` output.\n */\nexport function regexpToFunction<P extends object = object>(\n re: RegExp,\n keys: Key[],\n options: RegexpToFunctionOptions = {}\n): MatchFunction<P> {\n const { decode = (x: string) => x } = options;\n\n return function(pathname: string) {\n const m = re.exec(pathname);\n if (!m) return false;\n\n const { 0: path, index } = m;\n const params = Object.create(null);\n\n for (let i = 1; i < m.length; i++) {\n // tslint:disable-next-line\n if (m[i] === undefined) continue;\n\n const key = keys[i - 1];\n\n if (key.modifier === \"*\" || key.modifier === \"+\") {\n params[key.name] = m[i].split(key.prefix + key.suffix).map(value => {\n return decode(value, key);\n });\n } else {\n params[key.name] = decode(m[i], key);\n }\n }\n\n return { path, index, params };\n };\n}\n\n/**\n * Escape a regular expression string.\n */\nfunction escapeString(str: string) {\n return str.replace(/([.+*?=^!:${}()[\\]|/\\\\])/g, \"\\\\$1\");\n}\n\n/**\n * Get the flags for a regexp from the options.\n */\nfunction flags(options?: { sensitive?: boolean }) {\n return options && options.sensitive ? \"\" : \"i\";\n}\n\n/**\n * Metadata about a key.\n */\nexport interface Key {\n name: string | number;\n prefix: string;\n suffix: string;\n pattern: string;\n modifier: string;\n}\n\n/**\n * A token is a string (nothing special) or key metadata (capture group).\n */\nexport type Token = string | Key;\n\n/**\n * Pull out keys from a regexp.\n */\nfunction regexpToRegexp(path: RegExp, keys?: Key[]): RegExp {\n if (!keys) return path;\n\n const groupsRegex = /\\((?:\\?<(.*?)>)?(?!\\?)/g;\n\n let index = 0;\n let execResult = groupsRegex.exec(path.source);\n while (execResult) {\n keys.push({\n // Use parenthesized substring match if available, index otherwise\n name: execResult[1] || index++,\n prefix: \"\",\n suffix: \"\",\n modifier: \"\",\n pattern: \"\"\n });\n execResult = groupsRegex.exec(path.source);\n }\n\n return path;\n}\n\n/**\n * Transform an array into a regexp.\n */\nfunction arrayToRegexp(\n paths: Array<string | RegExp>,\n keys?: Key[],\n options?: TokensToRegexpOptions & ParseOptions\n): RegExp {\n const parts = paths.map(path => pathToRegexp(path, keys, options).source);\n return new RegExp(`(?:${parts.join(\"|\")})`, flags(options));\n}\n\n/**\n * Create a path regexp from string input.\n */\nfunction stringToRegexp(\n path: string,\n keys?: Key[],\n options?: TokensToRegexpOptions & ParseOptions\n) {\n return tokensToRegexp(parse(path, options), keys, options);\n}\n\nexport interface TokensToRegexpOptions {\n /**\n * When `true` the regexp will be case sensitive. (default: `false`)\n */\n sensitive?: boolean;\n /**\n * When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)\n */\n strict?: boolean;\n /**\n * When `true` the regexp will match to the end of the string. (default: `true`)\n */\n end?: boolean;\n /**\n * When `true` the regexp will match from the beginning of the string. (default: `true`)\n */\n start?: boolean;\n /**\n * Sets the final character for non-ending optimistic matches. (default: `/`)\n */\n delimiter?: string;\n /**\n * List of characters that can also be \"end\" characters.\n */\n endsWith?: string;\n /**\n * Encode path tokens for use in the `RegExp`.\n */\n encode?: (value: string) => string;\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n */\nexport function tokensToRegexp(\n tokens: Token[],\n keys?: Key[],\n options: TokensToRegexpOptions = {}\n) {\n const {\n strict = false,\n start = true,\n end = true,\n encode = (x: string) => x\n } = options;\n const endsWith = `[${escapeString(options.endsWith || \"\")}]|$`;\n const delimiter = `[${escapeString(options.delimiter || \"/#?\")}]`;\n let route = start ? \"^\" : \"\";\n\n // Iterate over the tokens and create our regexp string.\n for (const token of tokens) {\n if (typeof token === \"string\") {\n route += escapeString(encode(token));\n } else {\n const prefix = escapeString(encode(token.prefix));\n const suffix = escapeString(encode(token.suffix));\n\n if (token.pattern) {\n if (keys) keys.push(token);\n\n if (prefix || suffix) {\n if (token.modifier === \"+\" || token.modifier === \"*\") {\n const mod = token.modifier === \"*\" ? \"?\" : \"\";\n route += `(?:${prefix}((?:${token.pattern})(?:${suffix}${prefix}(?:${token.pattern}))*)${suffix})${mod}`;\n } else {\n route += `(?:${prefix}(${token.pattern})${suffix})${token.modifier}`;\n }\n } else {\n route += `(${token.pattern})${token.modifier}`;\n }\n } else {\n route += `(?:${prefix}${suffix})${token.modifier}`;\n }\n }\n }\n\n if (end) {\n if (!strict) route += `${delimiter}?`;\n\n route += !options.endsWith ? \"$\" : `(?=${endsWith})`;\n } else {\n const endToken = tokens[tokens.length - 1];\n const isEndDelimited =\n typeof endToken === \"string\"\n ? delimiter.indexOf(endToken[endToken.length - 1]) > -1\n : // tslint:disable-next-line\n endToken === undefined;\n\n if (!strict) {\n route += `(?:${delimiter}(?=${endsWith}))?`;\n }\n\n if (!isEndDelimited) {\n route += `(?=${delimiter}|${endsWith})`;\n }\n }\n\n return new RegExp(route, flags(options));\n}\n\n/**\n * Supported `path-to-regexp` input types.\n */\nexport type Path = string | RegExp | Array<string | RegExp>;\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n */\nexport function pathToRegexp(\n path: Path,\n keys?: Key[],\n options?: TokensToRegexpOptions & ParseOptions\n) {\n if (path instanceof RegExp) return regexpToRegexp(path, keys);\n if (Array.isArray(path)) return arrayToRegexp(path, keys, options);\n return stringToRegexp(path, keys, options);\n}\n"]}
|