path-to-regexp 6.2.2 → 7.0.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 +113 -172
- package/dist/index.d.ts +78 -71
- package/dist/index.js +296 -302
- package/dist/index.js.map +1 -1
- package/package.json +9 -11
- package/dist.es2015/index.js +0 -400
- package/dist.es2015/index.js.map +0 -1
package/dist/index.js
CHANGED
@@ -1,397 +1,392 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.pathToRegexp = exports.
|
3
|
+
exports.pathToRegexp = exports.match = exports.compile = exports.parse = exports.TokenData = void 0;
|
4
|
+
const DEFAULT_DELIMITER = "/";
|
5
|
+
const NOOP_VALUE = (value) => value;
|
6
|
+
const ID_CHAR = /^\p{XID_Continue}$/u;
|
7
|
+
const SIMPLE_TOKENS = {
|
8
|
+
"!": "!",
|
9
|
+
"@": "@",
|
10
|
+
";": ";",
|
11
|
+
",": ",",
|
12
|
+
"*": "*",
|
13
|
+
"+": "+",
|
14
|
+
"?": "?",
|
15
|
+
"{": "{",
|
16
|
+
"}": "}",
|
17
|
+
};
|
4
18
|
/**
|
5
19
|
* Tokenize input string.
|
6
20
|
*/
|
7
21
|
function lexer(str) {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
22
|
+
const chars = [...str];
|
23
|
+
const tokens = [];
|
24
|
+
let i = 0;
|
25
|
+
while (i < chars.length) {
|
26
|
+
const value = chars[i];
|
27
|
+
const type = SIMPLE_TOKENS[value];
|
28
|
+
if (type) {
|
29
|
+
tokens.push({ type, index: i++, value });
|
14
30
|
continue;
|
15
31
|
}
|
16
|
-
if (
|
17
|
-
tokens.push({ type: "
|
32
|
+
if (value === "\\") {
|
33
|
+
tokens.push({ type: "ESCAPED", index: i++, value: chars[i++] });
|
18
34
|
continue;
|
19
35
|
}
|
20
|
-
if (
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
28
|
-
if (char === ":") {
|
29
|
-
var name = "";
|
30
|
-
var j = i + 1;
|
31
|
-
while (j < str.length) {
|
32
|
-
var code = str.charCodeAt(j);
|
33
|
-
if (
|
34
|
-
// `0-9`
|
35
|
-
(code >= 48 && code <= 57) ||
|
36
|
-
// `A-Z`
|
37
|
-
(code >= 65 && code <= 90) ||
|
38
|
-
// `a-z`
|
39
|
-
(code >= 97 && code <= 122) ||
|
40
|
-
// `_`
|
41
|
-
code === 95) {
|
42
|
-
name += str[j++];
|
43
|
-
continue;
|
44
|
-
}
|
45
|
-
break;
|
36
|
+
if (value === ":") {
|
37
|
+
let name = "";
|
38
|
+
while (ID_CHAR.test(chars[++i])) {
|
39
|
+
name += chars[i];
|
40
|
+
}
|
41
|
+
if (!name) {
|
42
|
+
throw new TypeError(`Missing parameter name at ${i}`);
|
46
43
|
}
|
47
|
-
if (!name)
|
48
|
-
throw new TypeError("Missing parameter name at ".concat(i));
|
49
44
|
tokens.push({ type: "NAME", index: i, value: name });
|
50
|
-
i = j;
|
51
45
|
continue;
|
52
46
|
}
|
53
|
-
if (
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
if (
|
58
|
-
throw new TypeError(
|
47
|
+
if (value === "(") {
|
48
|
+
const pos = i++;
|
49
|
+
let count = 1;
|
50
|
+
let pattern = "";
|
51
|
+
if (chars[i] === "?") {
|
52
|
+
throw new TypeError(`Pattern cannot start with "?" at ${i}`);
|
59
53
|
}
|
60
|
-
while (
|
61
|
-
if (
|
62
|
-
pattern +=
|
54
|
+
while (i < chars.length) {
|
55
|
+
if (chars[i] === "\\") {
|
56
|
+
pattern += chars[i++] + chars[i++];
|
63
57
|
continue;
|
64
58
|
}
|
65
|
-
if (
|
59
|
+
if (chars[i] === ")") {
|
66
60
|
count--;
|
67
61
|
if (count === 0) {
|
68
|
-
|
62
|
+
i++;
|
69
63
|
break;
|
70
64
|
}
|
71
65
|
}
|
72
|
-
else if (
|
66
|
+
else if (chars[i] === "(") {
|
73
67
|
count++;
|
74
|
-
if (
|
75
|
-
throw new TypeError(
|
68
|
+
if (chars[i + 1] !== "?") {
|
69
|
+
throw new TypeError(`Capturing groups are not allowed at ${i}`);
|
76
70
|
}
|
77
71
|
}
|
78
|
-
pattern +=
|
72
|
+
pattern += chars[i++];
|
79
73
|
}
|
80
74
|
if (count)
|
81
|
-
throw new TypeError(
|
75
|
+
throw new TypeError(`Unbalanced pattern at ${pos}`);
|
82
76
|
if (!pattern)
|
83
|
-
throw new TypeError(
|
77
|
+
throw new TypeError(`Missing pattern at ${pos}`);
|
84
78
|
tokens.push({ type: "PATTERN", index: i, value: pattern });
|
85
|
-
i = j;
|
86
79
|
continue;
|
87
80
|
}
|
88
|
-
tokens.push({ type: "CHAR", index: i, value:
|
81
|
+
tokens.push({ type: "CHAR", index: i, value: chars[i++] });
|
89
82
|
}
|
90
83
|
tokens.push({ type: "END", index: i, value: "" });
|
91
|
-
return tokens;
|
84
|
+
return new Iter(tokens);
|
92
85
|
}
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
var value = tryConsume(type);
|
86
|
+
class Iter {
|
87
|
+
constructor(tokens) {
|
88
|
+
this.tokens = tokens;
|
89
|
+
this.index = 0;
|
90
|
+
}
|
91
|
+
peek() {
|
92
|
+
return this.tokens[this.index];
|
93
|
+
}
|
94
|
+
tryConsume(type) {
|
95
|
+
const token = this.peek();
|
96
|
+
if (token.type !== type)
|
97
|
+
return;
|
98
|
+
this.index++;
|
99
|
+
return token.value;
|
100
|
+
}
|
101
|
+
consume(type) {
|
102
|
+
const value = this.tryConsume(type);
|
111
103
|
if (value !== undefined)
|
112
104
|
return value;
|
113
|
-
|
114
|
-
throw new TypeError(
|
115
|
-
}
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
while ((value = tryConsume("CHAR") || tryConsume("
|
105
|
+
const { type: nextType, index } = this.peek();
|
106
|
+
throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: https://git.new/pathToRegexpError`);
|
107
|
+
}
|
108
|
+
text() {
|
109
|
+
let result = "";
|
110
|
+
let value;
|
111
|
+
while ((value = this.tryConsume("CHAR") || this.tryConsume("ESCAPED"))) {
|
120
112
|
result += value;
|
121
113
|
}
|
122
114
|
return result;
|
123
|
-
}
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
115
|
+
}
|
116
|
+
modifier() {
|
117
|
+
return (this.tryConsume("?") || this.tryConsume("*") || this.tryConsume("+") || "");
|
118
|
+
}
|
119
|
+
}
|
120
|
+
/**
|
121
|
+
* Tokenized path instance. Can we passed around instead of string.
|
122
|
+
*/
|
123
|
+
class TokenData {
|
124
|
+
constructor(tokens, delimiter) {
|
125
|
+
this.tokens = tokens;
|
126
|
+
this.delimiter = delimiter;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
exports.TokenData = TokenData;
|
130
|
+
/**
|
131
|
+
* Parse a string for the raw tokens.
|
132
|
+
*/
|
133
|
+
function parse(str, options = {}) {
|
134
|
+
const { delimiter = DEFAULT_DELIMITER, encodePath = NOOP_VALUE } = options;
|
135
|
+
const tokens = [];
|
136
|
+
const it = lexer(str);
|
137
|
+
let key = 0;
|
138
|
+
do {
|
139
|
+
const path = it.text();
|
140
|
+
if (path)
|
141
|
+
tokens.push(encodePath(path));
|
142
|
+
const name = it.tryConsume("NAME");
|
143
|
+
const pattern = it.tryConsume("PATTERN");
|
128
144
|
if (name || pattern) {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
prefix = "";
|
133
|
-
}
|
134
|
-
if (path) {
|
135
|
-
result.push(path);
|
136
|
-
path = "";
|
137
|
-
}
|
138
|
-
result.push({
|
139
|
-
name: name || key++,
|
140
|
-
prefix: prefix,
|
141
|
-
suffix: "",
|
142
|
-
pattern: pattern || defaultPattern,
|
143
|
-
modifier: tryConsume("MODIFIER") || "",
|
145
|
+
tokens.push({
|
146
|
+
name: name || String(key++),
|
147
|
+
pattern,
|
144
148
|
});
|
149
|
+
const next = it.peek();
|
150
|
+
if (next.type === "*") {
|
151
|
+
throw new TypeError(`Unexpected * at ${next.index}, you probably want \`/*\` or \`{/:foo}*\`: https://git.new/pathToRegexpError`);
|
152
|
+
}
|
145
153
|
continue;
|
146
154
|
}
|
147
|
-
|
148
|
-
if (
|
149
|
-
|
155
|
+
const asterisk = it.tryConsume("*");
|
156
|
+
if (asterisk) {
|
157
|
+
tokens.push({
|
158
|
+
name: String(key++),
|
159
|
+
pattern: `[^${escape(delimiter)}]*`,
|
160
|
+
modifier: "*",
|
161
|
+
separator: delimiter,
|
162
|
+
});
|
150
163
|
continue;
|
151
164
|
}
|
152
|
-
|
153
|
-
result.push(path);
|
154
|
-
path = "";
|
155
|
-
}
|
156
|
-
var open = tryConsume("OPEN");
|
165
|
+
const open = it.tryConsume("{");
|
157
166
|
if (open) {
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
167
|
+
const prefix = it.text();
|
168
|
+
const name = it.tryConsume("NAME");
|
169
|
+
const pattern = it.tryConsume("PATTERN");
|
170
|
+
const suffix = it.text();
|
171
|
+
const separator = it.tryConsume(";") ? it.text() : prefix + suffix;
|
172
|
+
it.consume("}");
|
173
|
+
const modifier = it.modifier();
|
174
|
+
tokens.push({
|
175
|
+
name: name || (pattern ? String(key++) : ""),
|
176
|
+
prefix: encodePath(prefix),
|
177
|
+
suffix: encodePath(suffix),
|
178
|
+
pattern,
|
179
|
+
modifier,
|
180
|
+
separator,
|
169
181
|
});
|
170
182
|
continue;
|
171
183
|
}
|
172
|
-
|
173
|
-
|
174
|
-
|
184
|
+
it.consume("END");
|
185
|
+
break;
|
186
|
+
} while (true);
|
187
|
+
return new TokenData(tokens, delimiter);
|
175
188
|
}
|
176
189
|
exports.parse = parse;
|
177
190
|
/**
|
178
191
|
* Compile a string to a template function for the path.
|
179
192
|
*/
|
180
|
-
function compile(
|
181
|
-
|
193
|
+
function compile(path, options = {}) {
|
194
|
+
const data = path instanceof TokenData ? path : parse(path, options);
|
195
|
+
return compileTokens(data, options);
|
182
196
|
}
|
183
197
|
exports.compile = compile;
|
184
198
|
/**
|
185
|
-
*
|
199
|
+
* Convert a single token into a path building function.
|
186
200
|
*/
|
187
|
-
function
|
188
|
-
if (
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
for (var i = 0; i < tokens.length; i++) {
|
200
|
-
var token = tokens[i];
|
201
|
-
if (typeof token === "string") {
|
202
|
-
path += token;
|
203
|
-
continue;
|
204
|
-
}
|
205
|
-
var value = data ? data[token.name] : undefined;
|
206
|
-
var optional = token.modifier === "?" || token.modifier === "*";
|
207
|
-
var repeat = token.modifier === "*" || token.modifier === "+";
|
208
|
-
if (Array.isArray(value)) {
|
209
|
-
if (!repeat) {
|
210
|
-
throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array"));
|
211
|
-
}
|
212
|
-
if (value.length === 0) {
|
213
|
-
if (optional)
|
214
|
-
continue;
|
215
|
-
throw new TypeError("Expected \"".concat(token.name, "\" to not be empty"));
|
216
|
-
}
|
217
|
-
for (var j = 0; j < value.length; j++) {
|
218
|
-
var segment = encode(value[j], token);
|
219
|
-
if (validate && !matches[i].test(segment)) {
|
220
|
-
throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
221
|
-
}
|
222
|
-
path += token.prefix + segment + token.suffix;
|
223
|
-
}
|
224
|
-
continue;
|
201
|
+
function tokenToFunction(token, encode) {
|
202
|
+
if (typeof token === "string") {
|
203
|
+
return () => token;
|
204
|
+
}
|
205
|
+
const encodeValue = encode || NOOP_VALUE;
|
206
|
+
const repeated = token.modifier === "+" || token.modifier === "*";
|
207
|
+
const optional = token.modifier === "?" || token.modifier === "*";
|
208
|
+
const { prefix = "", suffix = "", separator = "" } = token;
|
209
|
+
if (encode && repeated) {
|
210
|
+
const stringify = (value, index) => {
|
211
|
+
if (typeof value !== "string") {
|
212
|
+
throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
|
225
213
|
}
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
}
|
231
|
-
path += token.prefix + segment + token.suffix;
|
232
|
-
continue;
|
214
|
+
return encodeValue(value);
|
215
|
+
};
|
216
|
+
const compile = (value) => {
|
217
|
+
if (!Array.isArray(value)) {
|
218
|
+
throw new TypeError(`Expected "${token.name}" to be an array`);
|
233
219
|
}
|
234
|
-
if (
|
235
|
-
|
236
|
-
|
237
|
-
|
220
|
+
if (value.length === 0)
|
221
|
+
return "";
|
222
|
+
return prefix + value.map(stringify).join(separator) + suffix;
|
223
|
+
};
|
224
|
+
if (optional) {
|
225
|
+
return (data) => {
|
226
|
+
const value = data[token.name];
|
227
|
+
if (value == null)
|
228
|
+
return "";
|
229
|
+
return value.length ? compile(value) : "";
|
230
|
+
};
|
238
231
|
}
|
239
|
-
return
|
232
|
+
return (data) => {
|
233
|
+
const value = data[token.name];
|
234
|
+
return compile(value);
|
235
|
+
};
|
236
|
+
}
|
237
|
+
const stringify = (value) => {
|
238
|
+
if (typeof value !== "string") {
|
239
|
+
throw new TypeError(`Expected "${token.name}" to be a string`);
|
240
|
+
}
|
241
|
+
return prefix + encodeValue(value) + suffix;
|
242
|
+
};
|
243
|
+
if (optional) {
|
244
|
+
return (data) => {
|
245
|
+
const value = data[token.name];
|
246
|
+
if (value == null)
|
247
|
+
return "";
|
248
|
+
return stringify(value);
|
249
|
+
};
|
250
|
+
}
|
251
|
+
return (data) => {
|
252
|
+
const value = data[token.name];
|
253
|
+
return stringify(value);
|
240
254
|
};
|
241
255
|
}
|
242
|
-
exports.tokensToFunction = tokensToFunction;
|
243
256
|
/**
|
244
|
-
*
|
257
|
+
* Transform tokens into a path building function.
|
245
258
|
*/
|
246
|
-
function
|
247
|
-
|
248
|
-
|
249
|
-
|
259
|
+
function compileTokens(data, options) {
|
260
|
+
const { encode = encodeURIComponent, loose = true, validate = true, } = options;
|
261
|
+
const reFlags = flags(options);
|
262
|
+
const stringify = toStringify(loose, data.delimiter);
|
263
|
+
const keyToRegexp = toKeyRegexp(stringify, data.delimiter);
|
264
|
+
// Compile all the tokens into regexps.
|
265
|
+
const encoders = data.tokens.map((token) => {
|
266
|
+
const fn = tokenToFunction(token, encode);
|
267
|
+
if (!validate || typeof token === "string")
|
268
|
+
return fn;
|
269
|
+
const pattern = keyToRegexp(token);
|
270
|
+
const validRe = new RegExp(`^${pattern}$`, reFlags);
|
271
|
+
return (data) => {
|
272
|
+
const value = fn(data);
|
273
|
+
if (!validRe.test(value)) {
|
274
|
+
throw new TypeError(`Invalid value for "${token.name}": ${JSON.stringify(value)}`);
|
275
|
+
}
|
276
|
+
return value;
|
277
|
+
};
|
278
|
+
});
|
279
|
+
return function path(data = {}) {
|
280
|
+
let path = "";
|
281
|
+
for (const encoder of encoders)
|
282
|
+
path += encoder(data);
|
283
|
+
return path;
|
284
|
+
};
|
250
285
|
}
|
251
|
-
exports.match = match;
|
252
286
|
/**
|
253
|
-
* Create
|
287
|
+
* Create path match function from `path-to-regexp` spec.
|
254
288
|
*/
|
255
|
-
function
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
289
|
+
function match(path, options = {}) {
|
290
|
+
const { decode = decodeURIComponent, loose = true } = options;
|
291
|
+
const data = path instanceof TokenData ? path : parse(path, options);
|
292
|
+
const stringify = toStringify(loose, data.delimiter);
|
293
|
+
const keys = [];
|
294
|
+
const re = tokensToRegexp(data, keys, options);
|
295
|
+
const decoders = keys.map((key) => {
|
296
|
+
if (decode && (key.modifier === "+" || key.modifier === "*")) {
|
297
|
+
const re = new RegExp(stringify(key.separator || ""), "g");
|
298
|
+
return (value) => value.split(re).map(decode);
|
299
|
+
}
|
300
|
+
return decode || NOOP_VALUE;
|
301
|
+
});
|
302
|
+
return function match(pathname) {
|
303
|
+
const m = re.exec(pathname);
|
260
304
|
if (!m)
|
261
305
|
return false;
|
262
|
-
|
263
|
-
|
264
|
-
|
306
|
+
const { 0: path, index } = m;
|
307
|
+
const params = Object.create(null);
|
308
|
+
for (let i = 1; i < m.length; i++) {
|
265
309
|
if (m[i] === undefined)
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
return decode(value, key);
|
271
|
-
});
|
272
|
-
}
|
273
|
-
else {
|
274
|
-
params[key.name] = decode(m[i], key);
|
275
|
-
}
|
276
|
-
};
|
277
|
-
for (var i = 1; i < m.length; i++) {
|
278
|
-
_loop_1(i);
|
310
|
+
continue;
|
311
|
+
const key = keys[i - 1];
|
312
|
+
const decoder = decoders[i - 1];
|
313
|
+
params[key.name] = decoder(m[i]);
|
279
314
|
}
|
280
|
-
return { path
|
315
|
+
return { path, index, params };
|
281
316
|
};
|
282
317
|
}
|
283
|
-
exports.
|
318
|
+
exports.match = match;
|
284
319
|
/**
|
285
320
|
* Escape a regular expression string.
|
286
321
|
*/
|
287
|
-
function
|
322
|
+
function escape(str) {
|
288
323
|
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
289
324
|
}
|
290
325
|
/**
|
291
|
-
*
|
326
|
+
* Escape and repeat loose characters for regular expressions.
|
292
327
|
*/
|
293
|
-
function
|
294
|
-
return
|
295
|
-
}
|
296
|
-
/**
|
297
|
-
* Pull out keys from a regexp.
|
298
|
-
*/
|
299
|
-
function regexpToRegexp(path, keys) {
|
300
|
-
if (!keys)
|
301
|
-
return path;
|
302
|
-
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
|
303
|
-
var index = 0;
|
304
|
-
var execResult = groupsRegex.exec(path.source);
|
305
|
-
while (execResult) {
|
306
|
-
keys.push({
|
307
|
-
// Use parenthesized substring match if available, index otherwise
|
308
|
-
name: execResult[1] || index++,
|
309
|
-
prefix: "",
|
310
|
-
suffix: "",
|
311
|
-
modifier: "",
|
312
|
-
pattern: "",
|
313
|
-
});
|
314
|
-
execResult = groupsRegex.exec(path.source);
|
315
|
-
}
|
316
|
-
return path;
|
328
|
+
function looseReplacer(value, loose) {
|
329
|
+
return loose ? `${escape(value)}+` : escape(value);
|
317
330
|
}
|
318
331
|
/**
|
319
|
-
*
|
332
|
+
* Encode all non-delimiter characters using the encode function.
|
320
333
|
*/
|
321
|
-
function
|
322
|
-
|
323
|
-
|
334
|
+
function toStringify(loose, delimiter) {
|
335
|
+
if (!loose)
|
336
|
+
return escape;
|
337
|
+
const re = new RegExp(`[^${escape(delimiter)}]+|(.)`, "g");
|
338
|
+
return (value) => value.replace(re, looseReplacer);
|
324
339
|
}
|
325
340
|
/**
|
326
|
-
*
|
341
|
+
* Get the flags for a regexp from the options.
|
327
342
|
*/
|
328
|
-
function
|
329
|
-
return
|
343
|
+
function flags(options) {
|
344
|
+
return options.sensitive ? "" : "i";
|
330
345
|
}
|
331
346
|
/**
|
332
347
|
* Expose a function for taking tokens and returning a RegExp.
|
333
348
|
*/
|
334
|
-
function tokensToRegexp(
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
// Iterate over the tokens and create our regexp string.
|
341
|
-
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
|
342
|
-
var token = tokens_1[_i];
|
349
|
+
function tokensToRegexp(data, keys, options) {
|
350
|
+
const { trailing = true, start = true, end = true, loose = true } = options;
|
351
|
+
const stringify = toStringify(loose, data.delimiter);
|
352
|
+
const keyToRegexp = toKeyRegexp(stringify, data.delimiter);
|
353
|
+
let pattern = start ? "^" : "";
|
354
|
+
for (const token of data.tokens) {
|
343
355
|
if (typeof token === "string") {
|
344
|
-
|
356
|
+
pattern += stringify(token);
|
345
357
|
}
|
346
358
|
else {
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
if (keys)
|
351
|
-
keys.push(token);
|
352
|
-
if (prefix || suffix) {
|
353
|
-
if (token.modifier === "+" || token.modifier === "*") {
|
354
|
-
var mod = token.modifier === "*" ? "?" : "";
|
355
|
-
route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod);
|
356
|
-
}
|
357
|
-
else {
|
358
|
-
route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier);
|
359
|
-
}
|
360
|
-
}
|
361
|
-
else {
|
362
|
-
if (token.modifier === "+" || token.modifier === "*") {
|
363
|
-
route += "((?:".concat(token.pattern, ")").concat(token.modifier, ")");
|
364
|
-
}
|
365
|
-
else {
|
366
|
-
route += "(".concat(token.pattern, ")").concat(token.modifier);
|
367
|
-
}
|
368
|
-
}
|
369
|
-
}
|
370
|
-
else {
|
371
|
-
route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier);
|
372
|
-
}
|
359
|
+
if (token.name)
|
360
|
+
keys.push(token);
|
361
|
+
pattern += keyToRegexp(token);
|
373
362
|
}
|
374
363
|
}
|
375
|
-
if (
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
364
|
+
if (trailing)
|
365
|
+
pattern += `(?:${stringify(data.delimiter)})?`;
|
366
|
+
pattern += end ? "$" : `(?=${escape(data.delimiter)}|$)`;
|
367
|
+
return new RegExp(pattern, flags(options));
|
368
|
+
}
|
369
|
+
/**
|
370
|
+
* Convert a token into a regexp string (re-used for path validation).
|
371
|
+
*/
|
372
|
+
function toKeyRegexp(stringify, delimiter) {
|
373
|
+
const segmentPattern = `[^${escape(delimiter)}]+?`;
|
374
|
+
return (key) => {
|
375
|
+
const prefix = key.prefix ? stringify(key.prefix) : "";
|
376
|
+
const suffix = key.suffix ? stringify(key.suffix) : "";
|
377
|
+
const modifier = key.modifier || "";
|
378
|
+
if (key.name) {
|
379
|
+
const pattern = key.pattern || segmentPattern;
|
380
|
+
if (key.modifier === "+" || key.modifier === "*") {
|
381
|
+
const mod = key.modifier === "*" ? "?" : "";
|
382
|
+
const split = key.separator ? stringify(key.separator) : "";
|
383
|
+
return `(?:${prefix}((?:${pattern})(?:${split}(?:${pattern}))*)${suffix})${mod}`;
|
384
|
+
}
|
385
|
+
return `(?:${prefix}(${pattern})${suffix})${modifier}`;
|
390
386
|
}
|
391
|
-
|
392
|
-
|
387
|
+
return `(?:${prefix}${suffix})${modifier}`;
|
388
|
+
};
|
393
389
|
}
|
394
|
-
exports.tokensToRegexp = tokensToRegexp;
|
395
390
|
/**
|
396
391
|
* Normalize the given path string, returning a regular expression.
|
397
392
|
*
|
@@ -399,12 +394,11 @@ exports.tokensToRegexp = tokensToRegexp;
|
|
399
394
|
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
400
395
|
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
401
396
|
*/
|
402
|
-
function pathToRegexp(path,
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
return stringToRegexp(path, keys, options);
|
397
|
+
function pathToRegexp(path, options = {}) {
|
398
|
+
const data = path instanceof TokenData ? path : parse(path, options);
|
399
|
+
const keys = [];
|
400
|
+
const regexp = tokensToRegexp(data, keys, options);
|
401
|
+
return Object.assign(regexp, { keys });
|
408
402
|
}
|
409
403
|
exports.pathToRegexp = pathToRegexp;
|
410
404
|
//# sourceMappingURL=index.js.map
|