Update checked-in dependencies
This commit is contained in:
parent
1afca056e3
commit
6989ba7bd2
3942 changed files with 55190 additions and 132206 deletions
385
node_modules/path-to-regexp/Readme.md
generated
vendored
385
node_modules/path-to-regexp/Readme.md
generated
vendored
|
|
@ -16,323 +16,188 @@ npm install path-to-regexp --save
|
|||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
const { pathToRegexp, match, parse, compile } = require("path-to-regexp");
|
||||
|
||||
// pathToRegexp(path, keys?, options?)
|
||||
// match(path)
|
||||
// parse(path)
|
||||
// compile(path)
|
||||
```js
|
||||
const {
|
||||
match,
|
||||
pathToRegexp,
|
||||
compile,
|
||||
parse,
|
||||
stringify,
|
||||
} = require("path-to-regexp");
|
||||
```
|
||||
|
||||
### Path to regexp
|
||||
|
||||
The `pathToRegexp` function will return a regular expression object based on the provided `path` argument. It accepts the following arguments:
|
||||
|
||||
- **path** A string, array of strings, or a regular expression.
|
||||
- **keys** _(optional)_ An array to populate with keys found in the path.
|
||||
- **options** _(optional)_
|
||||
- **sensitive** When `true` the regexp will be case sensitive. (default: `false`)
|
||||
- **strict** When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)
|
||||
- **end** When `true` the regexp will match to the end of the string. (default: `true`)
|
||||
- **start** When `true` the regexp will match from the beginning of the string. (default: `true`)
|
||||
- **delimiter** The default delimiter for segments, e.g. `[^/#?]` for `:named` patterns. (default: `'/#?'`)
|
||||
- **endsWith** Optional character, or list of characters, to treat as "end" characters.
|
||||
- **encode** A function to encode strings before inserting into `RegExp`. (default: `x => x`)
|
||||
- **prefixes** List of characters to automatically consider prefixes when parsing. (default: `./`)
|
||||
|
||||
```javascript
|
||||
const keys = [];
|
||||
const regexp = pathToRegexp("/foo/:bar", keys);
|
||||
// regexp = /^\/foo(?:\/([^\/#\?]+?))[\/#\?]?$/i
|
||||
// keys = [{ name: 'bar', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }]
|
||||
```
|
||||
|
||||
**Please note:** The `RegExp` returned by `path-to-regexp` is intended for ordered data (e.g. pathnames, hostnames). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc). When using paths that contain query strings, you need to escape the question mark (`?`) to ensure it does not flag the parameter as [optional](#optional).
|
||||
|
||||
### Parameters
|
||||
|
||||
The path argument is used to define parameters and populate keys.
|
||||
|
||||
#### Named Parameters
|
||||
|
||||
Named parameters are defined by prefixing a colon to the parameter name (`:foo`).
|
||||
Parameters match arbitrary strings in a path by matching up to the end of the segment, or up to any proceeding tokens. They are defined by prefixing a colon to the parameter name (`:foo`). Parameter names can use any valid JavaScript identifier, or be double quoted to use other characters (`:"param-name"`).
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:foo/:bar");
|
||||
// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]
|
||||
const fn = match("/:foo/:bar");
|
||||
|
||||
regexp.exec("/test/route");
|
||||
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
||||
fn("/test/route");
|
||||
//=> { path: '/test/route', params: { foo: 'test', bar: 'route' } }
|
||||
```
|
||||
|
||||
**Please note:** Parameter names must use "word characters" (`[A-Za-z0-9_]`).
|
||||
### Wildcard
|
||||
|
||||
##### Custom Matching Parameters
|
||||
|
||||
Parameters can have a custom regexp, which overrides the default match (`[^/]+`). For example, you can match digits or names in a path:
|
||||
Wildcard parameters match one or more characters across multiple segments. They are defined the same way as regular parameters, but are prefixed with an asterisk (`*foo`).
|
||||
|
||||
```js
|
||||
const regexpNumbers = pathToRegexp("/icon-:foo(\\d+).png");
|
||||
// keys = [{ name: 'foo', ... }]
|
||||
const fn = match("/*splat");
|
||||
|
||||
regexpNumbers.exec("/icon-123.png");
|
||||
//=> ['/icon-123.png', '123']
|
||||
|
||||
regexpNumbers.exec("/icon-abc.png");
|
||||
//=> null
|
||||
|
||||
const regexpWord = pathToRegexp("/(user|u)");
|
||||
// keys = [{ name: 0, ... }]
|
||||
|
||||
regexpWord.exec("/u");
|
||||
//=> ['/u', 'u']
|
||||
|
||||
regexpWord.exec("/users");
|
||||
//=> null
|
||||
fn("/bar/baz");
|
||||
//=> { path: '/bar/baz', params: { splat: [ 'bar', 'baz' ] } }
|
||||
```
|
||||
|
||||
**Tip:** Backslashes need to be escaped with another backslash in JavaScript strings.
|
||||
### Optional
|
||||
|
||||
##### Custom Prefix and Suffix
|
||||
|
||||
Parameters can be wrapped in `{}` to create custom prefixes or suffixes for your segment:
|
||||
Braces can be used to define parts of the path that are optional.
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:attr1?{-:attr2}?{-:attr3}?");
|
||||
const fn = match("/users{/:id}/delete");
|
||||
|
||||
regexp.exec("/test");
|
||||
// => ['/test', 'test', undefined, undefined]
|
||||
fn("/users/delete");
|
||||
//=> { path: '/users/delete', params: {} }
|
||||
|
||||
regexp.exec("/test-test");
|
||||
// => ['/test', 'test', 'test', undefined]
|
||||
fn("/users/123/delete");
|
||||
//=> { path: '/users/123/delete', params: { id: '123' } }
|
||||
```
|
||||
|
||||
#### Unnamed Parameters
|
||||
## Match
|
||||
|
||||
It is possible to write an unnamed parameter that only consists of a regexp. It works the same the named parameter, except it will be numerically indexed:
|
||||
The `match` function returns a function for matching strings against a path:
|
||||
|
||||
- **path** String or array of strings.
|
||||
- **options** _(optional)_ (Extends [pathToRegexp](#pathToRegexp) options)
|
||||
- **decode** Function for decoding strings to params, or `false` to disable all processing. (default: `decodeURIComponent`)
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:foo/(.*)");
|
||||
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
|
||||
|
||||
regexp.exec("/test/route");
|
||||
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
||||
const fn = match("/foo/:bar");
|
||||
```
|
||||
|
||||
#### Modifiers
|
||||
**Please note:** `path-to-regexp` is intended for ordered data (e.g. paths, hosts). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc).
|
||||
|
||||
Modifiers must be placed after the parameter (e.g. `/:foo?`, `/(test)?`, `/:foo(test)?`, or `{-:foo(test)}?`).
|
||||
## PathToRegexp
|
||||
|
||||
##### Optional
|
||||
The `pathToRegexp` function returns a regular expression for matching strings against paths. It
|
||||
|
||||
Parameters can be suffixed with a question mark (`?`) to make the parameter optional.
|
||||
- **path** String or array of strings.
|
||||
- **options** _(optional)_ (See [parse](#parse) for more options)
|
||||
- **sensitive** Regexp will be case sensitive. (default: `false`)
|
||||
- **end** Validate the match reaches the end of the string. (default: `true`)
|
||||
- **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
|
||||
- **trailing** Allows optional trailing delimiter to match. (default: `true`)
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:foo/:bar?");
|
||||
// keys = [{ name: 'foo', ... }, { name: 'bar', prefix: '/', modifier: '?' }]
|
||||
|
||||
regexp.exec("/test");
|
||||
//=> [ '/test', 'test', undefined, index: 0, input: '/test', groups: undefined ]
|
||||
|
||||
regexp.exec("/test/route");
|
||||
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
||||
const { regexp, keys } = pathToRegexp("/foo/:bar");
|
||||
```
|
||||
|
||||
**Tip:** The prefix is also optional, escape the prefix `\/` to make it required.
|
||||
|
||||
When dealing with query strings, escape the question mark (`?`) so it doesn't mark the parameter as optional. Handling unordered data is outside the scope of this library.
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/search/:tableName\\?useIndex=true&term=amazing");
|
||||
|
||||
regexp.exec("/search/people?useIndex=true&term=amazing");
|
||||
//=> [ '/search/people?useIndex=true&term=amazing', 'people', index: 0, input: '/search/people?useIndex=true&term=amazing', groups: undefined ]
|
||||
|
||||
// This library does not handle query strings in different orders
|
||||
regexp.exec("/search/people?term=amazing&useIndex=true");
|
||||
//=> null
|
||||
```
|
||||
|
||||
##### Zero or more
|
||||
|
||||
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches.
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:foo*");
|
||||
// keys = [{ name: 'foo', prefix: '/', modifier: '*' }]
|
||||
|
||||
regexp.exec("/");
|
||||
//=> [ '/', undefined, index: 0, input: '/', groups: undefined ]
|
||||
|
||||
regexp.exec("/bar/baz");
|
||||
//=> [ '/bar/baz', 'bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
|
||||
```
|
||||
|
||||
##### One or more
|
||||
|
||||
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches.
|
||||
|
||||
```js
|
||||
const regexp = pathToRegexp("/:foo+");
|
||||
// keys = [{ name: 'foo', prefix: '/', modifier: '+' }]
|
||||
|
||||
regexp.exec("/");
|
||||
//=> null
|
||||
|
||||
regexp.exec("/bar/baz");
|
||||
//=> [ '/bar/baz','bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
|
||||
```
|
||||
|
||||
### Match
|
||||
|
||||
The `match` function will return a function for transforming paths into parameters:
|
||||
|
||||
```js
|
||||
// Make sure you consistently `decode` segments.
|
||||
const fn = match("/user/:id", { decode: decodeURIComponent });
|
||||
|
||||
fn("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
|
||||
fn("/invalid"); //=> false
|
||||
fn("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }
|
||||
```
|
||||
|
||||
The `match` function can be used to custom match named parameters. For example, this can be used to whitelist a small number of valid paths:
|
||||
|
||||
```js
|
||||
const urlMatch = match("/users/:id/:tab(home|photos|bio)", {
|
||||
decode: decodeURIComponent,
|
||||
});
|
||||
|
||||
urlMatch("/users/1234/photos");
|
||||
//=> { path: '/users/1234/photos', index: 0, params: { id: '1234', tab: 'photos' } }
|
||||
|
||||
urlMatch("/users/1234/bio");
|
||||
//=> { path: '/users/1234/bio', index: 0, params: { id: '1234', tab: 'bio' } }
|
||||
|
||||
urlMatch("/users/1234/otherstuff");
|
||||
//=> false
|
||||
```
|
||||
|
||||
#### Process Pathname
|
||||
|
||||
You should make sure variations of the same path match the expected `path`. Here's one possible solution using `encode`:
|
||||
|
||||
```js
|
||||
const fn = match("/café", { encode: encodeURI });
|
||||
|
||||
fn("/caf%C3%A9"); //=> { path: '/caf%C3%A9', index: 0, params: {} }
|
||||
```
|
||||
|
||||
**Note:** [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) encodes paths, so `/café` would be normalized to `/caf%C3%A9` and match in the above example.
|
||||
|
||||
##### Alternative Using Normalize
|
||||
|
||||
Sometimes you won't have already normalized paths to use, so you could normalize it yourself before matching:
|
||||
|
||||
```js
|
||||
/**
|
||||
* Normalize a pathname for matching, replaces multiple slashes with a single
|
||||
* slash and normalizes unicode characters to "NFC". When using this method,
|
||||
* `decode` should be an identity function so you don't decode strings twice.
|
||||
*/
|
||||
function normalizePathname(pathname: string) {
|
||||
return (
|
||||
decodeURI(pathname)
|
||||
// Replaces repeated slashes in the URL.
|
||||
.replace(/\/+/g, "/")
|
||||
// Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
|
||||
// Note: Missing native IE support, may want to skip this step.
|
||||
.normalize()
|
||||
);
|
||||
}
|
||||
|
||||
// Two possible ways of writing `/café`:
|
||||
const re = pathToRegexp("/caf\u00E9");
|
||||
const input = encodeURI("/cafe\u0301");
|
||||
|
||||
re.test(input); //=> false
|
||||
re.test(normalizePathname(input)); //=> true
|
||||
```
|
||||
|
||||
### Parse
|
||||
|
||||
The `parse` function will return a list of strings and keys from a path string:
|
||||
|
||||
```js
|
||||
const tokens = parse("/route/:foo/(.*)");
|
||||
|
||||
console.log(tokens[0]);
|
||||
//=> "/route"
|
||||
|
||||
console.log(tokens[1]);
|
||||
//=> { name: 'foo', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }
|
||||
|
||||
console.log(tokens[2]);
|
||||
//=> { name: 0, prefix: '/', suffix: '', pattern: '.*', modifier: '' }
|
||||
```
|
||||
|
||||
**Note:** This method only works with strings.
|
||||
|
||||
### Compile ("Reverse" Path-To-RegExp)
|
||||
## Compile ("Reverse" Path-To-RegExp)
|
||||
|
||||
The `compile` function will return a function for transforming parameters into a valid path:
|
||||
|
||||
- **path** A string.
|
||||
- **options** (See [parse](#parse) for more options)
|
||||
- **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
|
||||
- **encode** Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
|
||||
|
||||
```js
|
||||
// Make sure you encode your path segments consistently.
|
||||
const toPath = compile("/user/:id", { encode: encodeURIComponent });
|
||||
const toPath = compile("/user/:id");
|
||||
|
||||
toPath({ id: 123 }); //=> "/user/123"
|
||||
toPath({ id: "name" }); //=> "/user/name"
|
||||
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
|
||||
toPath({ id: ":/" }); //=> "/user/%3A%2F"
|
||||
|
||||
// Without `encode`, you need to make sure inputs are encoded correctly.
|
||||
// (Note: You can use `validate: false` to create an invalid paths.)
|
||||
const toPathRaw = compile("/user/:id", { validate: false });
|
||||
const toPathRepeated = compile("/*segment");
|
||||
|
||||
toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
|
||||
toPathRaw({ id: ":/" }); //=> "/user/:/"
|
||||
|
||||
const toPathRepeated = compile("/:segment+");
|
||||
|
||||
toPathRepeated({ segment: "foo" }); //=> "/foo"
|
||||
toPathRepeated({ segment: ["foo"] }); //=> "/foo"
|
||||
toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"
|
||||
|
||||
const toPathRegexp = compile("/user/:id(\\d+)");
|
||||
// When disabling `encode`, you need to make sure inputs are encoded correctly. No arrays are accepted.
|
||||
const toPathRaw = compile("/user/:id", { encode: false });
|
||||
|
||||
toPathRegexp({ id: 123 }); //=> "/user/123"
|
||||
toPathRegexp({ id: "123" }); //=> "/user/123"
|
||||
toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
|
||||
```
|
||||
|
||||
**Note:** The generated function will throw on invalid input.
|
||||
## Stringify
|
||||
|
||||
### Working with Tokens
|
||||
Transform `TokenData` (a sequence of tokens) back into a Path-to-RegExp string.
|
||||
|
||||
Path-To-RegExp exposes the two functions used internally that accept an array of tokens:
|
||||
- **data** A `TokenData` instance
|
||||
|
||||
- `tokensToRegexp(tokens, keys?, options?)` Transform an array of tokens into a matching regular expression.
|
||||
- `tokensToFunction(tokens)` Transform an array of tokens into a path generator function.
|
||||
```js
|
||||
const data = new TokenData([
|
||||
{ type: "text", value: "/" },
|
||||
{ type: "param", name: "foo" },
|
||||
]);
|
||||
|
||||
#### Token Information
|
||||
const path = stringify(data); //=> "/:foo"
|
||||
```
|
||||
|
||||
- `name` The name of the token (`string` for named or `number` for unnamed index)
|
||||
- `prefix` The prefix string for the segment (e.g. `"/"`)
|
||||
- `suffix` The suffix string for the segment (e.g. `""`)
|
||||
- `pattern` The RegExp used to match this token (`string`)
|
||||
- `modifier` The modifier character used for the segment (e.g. `?`)
|
||||
## Developers
|
||||
|
||||
## Compatibility with Express <= 4.x
|
||||
- If you are rewriting paths with match and compile, consider using `encode: false` and `decode: false` to keep raw paths passed around.
|
||||
- To ensure matches work on paths containing characters usually encoded, such as emoji, consider using [encodeurl](https://github.com/pillarjs/encodeurl) for `encodePath`.
|
||||
|
||||
Path-To-RegExp breaks compatibility with Express <= `4.x`:
|
||||
### Parse
|
||||
|
||||
- RegExp special characters can only be used in a parameter
|
||||
- Express.js 4.x supported `RegExp` special characters regardless of position - this is considered a bug
|
||||
- Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*`
|
||||
- No wildcard asterisk (`*`) - use parameters instead (`(.*)` or `:splat*`)
|
||||
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`.
|
||||
|
||||
## Live Demo
|
||||
- **path** A string.
|
||||
- **options** _(optional)_
|
||||
- **encodePath** A function for encoding input strings. (default: `x => x`, recommended: [`encodeurl`](https://github.com/pillarjs/encodeurl))
|
||||
|
||||
You can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.io/express-route-tester/).
|
||||
### Tokens
|
||||
|
||||
`TokenData` is a sequence of tokens, currently of types `text`, `parameter`, `wildcard`, or `group`.
|
||||
|
||||
### Custom path
|
||||
|
||||
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:
|
||||
|
||||
```js
|
||||
import { TokenData, match } from "path-to-regexp";
|
||||
|
||||
const tokens = [
|
||||
{ type: "text", value: "/" },
|
||||
{ type: "parameter", name: "foo" },
|
||||
];
|
||||
const path = new TokenData(tokens);
|
||||
const fn = match(path);
|
||||
|
||||
fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } }
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
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.
|
||||
|
||||
### Unexpected `?` or `+`
|
||||
|
||||
In past releases, `?`, `*`, and `+` were used to denote optional or repeating parameters. As an alternative, try these:
|
||||
|
||||
- For optional (`?`), use an empty segment in a group such as `/:file{.:ext}`.
|
||||
- For repeating (`+`), only wildcard matching is supported, such as `/*path`.
|
||||
- For optional repeating (`*`), use a group and a wildcard parameter such as `/files{/*path}`.
|
||||
|
||||
### Unexpected `(`, `)`, `[`, `]`, etc.
|
||||
|
||||
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. `"\\("`.
|
||||
|
||||
### Missing parameter name
|
||||
|
||||
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"`.
|
||||
|
||||
### Unterminated quote
|
||||
|
||||
Parameter names can be wrapped in double quote characters, and this error means you forgot to close the quote character.
|
||||
|
||||
### Express <= 4.x
|
||||
|
||||
Path-To-RegExp breaks compatibility with Express <= `4.x` in the following ways:
|
||||
|
||||
- Regexp characters can no longer be provided.
|
||||
- The optional character `?` is no longer supported, use braces instead: `/:file{.:ext}`.
|
||||
- Some characters have new meaning or have been reserved (`{}?*+@!;`).
|
||||
- The parameter name now supports all JavaScript identifier characters, previously it was only `[a-z0-9]`.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
400
node_modules/path-to-regexp/dist.es2015/index.js
generated
vendored
400
node_modules/path-to-regexp/dist.es2015/index.js
generated
vendored
|
|
@ -1,400 +0,0 @@
|
|||
/**
|
||||
* Tokenize input string.
|
||||
*/
|
||||
function lexer(str) {
|
||||
var tokens = [];
|
||||
var i = 0;
|
||||
while (i < str.length) {
|
||||
var char = str[i];
|
||||
if (char === "*" || char === "+" || char === "?") {
|
||||
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "\\") {
|
||||
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "{") {
|
||||
tokens.push({ type: "OPEN", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "}") {
|
||||
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === ":") {
|
||||
var name = "";
|
||||
var j = i + 1;
|
||||
while (j < str.length) {
|
||||
var code = str.charCodeAt(j);
|
||||
if (
|
||||
// `0-9`
|
||||
(code >= 48 && code <= 57) ||
|
||||
// `A-Z`
|
||||
(code >= 65 && code <= 90) ||
|
||||
// `a-z`
|
||||
(code >= 97 && code <= 122) ||
|
||||
// `_`
|
||||
code === 95) {
|
||||
name += str[j++];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!name)
|
||||
throw new TypeError("Missing parameter name at ".concat(i));
|
||||
tokens.push({ type: "NAME", index: i, value: name });
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
if (char === "(") {
|
||||
var count = 1;
|
||||
var pattern = "";
|
||||
var j = i + 1;
|
||||
if (str[j] === "?") {
|
||||
throw new TypeError("Pattern cannot start with \"?\" at ".concat(j));
|
||||
}
|
||||
while (j < str.length) {
|
||||
if (str[j] === "\\") {
|
||||
pattern += str[j++] + str[j++];
|
||||
continue;
|
||||
}
|
||||
if (str[j] === ")") {
|
||||
count--;
|
||||
if (count === 0) {
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (str[j] === "(") {
|
||||
count++;
|
||||
if (str[j + 1] !== "?") {
|
||||
throw new TypeError("Capturing groups are not allowed at ".concat(j));
|
||||
}
|
||||
}
|
||||
pattern += str[j++];
|
||||
}
|
||||
if (count)
|
||||
throw new TypeError("Unbalanced pattern at ".concat(i));
|
||||
if (!pattern)
|
||||
throw new TypeError("Missing pattern at ".concat(i));
|
||||
tokens.push({ type: "PATTERN", index: i, value: pattern });
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
tokens.push({ type: "CHAR", index: i, value: str[i++] });
|
||||
}
|
||||
tokens.push({ type: "END", index: i, value: "" });
|
||||
return tokens;
|
||||
}
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
export function parse(str, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var tokens = lexer(str);
|
||||
var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
|
||||
var defaultPattern = "[^".concat(escapeString(options.delimiter || "/#?"), "]+?");
|
||||
var result = [];
|
||||
var key = 0;
|
||||
var i = 0;
|
||||
var path = "";
|
||||
var tryConsume = function (type) {
|
||||
if (i < tokens.length && tokens[i].type === type)
|
||||
return tokens[i++].value;
|
||||
};
|
||||
var mustConsume = function (type) {
|
||||
var value = tryConsume(type);
|
||||
if (value !== undefined)
|
||||
return value;
|
||||
var _a = tokens[i], nextType = _a.type, index = _a.index;
|
||||
throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type));
|
||||
};
|
||||
var consumeText = function () {
|
||||
var result = "";
|
||||
var value;
|
||||
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
|
||||
result += value;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
while (i < tokens.length) {
|
||||
var char = tryConsume("CHAR");
|
||||
var name = tryConsume("NAME");
|
||||
var pattern = tryConsume("PATTERN");
|
||||
if (name || pattern) {
|
||||
var prefix = char || "";
|
||||
if (prefixes.indexOf(prefix) === -1) {
|
||||
path += prefix;
|
||||
prefix = "";
|
||||
}
|
||||
if (path) {
|
||||
result.push(path);
|
||||
path = "";
|
||||
}
|
||||
result.push({
|
||||
name: name || key++,
|
||||
prefix: prefix,
|
||||
suffix: "",
|
||||
pattern: pattern || defaultPattern,
|
||||
modifier: tryConsume("MODIFIER") || "",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
var value = char || tryConsume("ESCAPED_CHAR");
|
||||
if (value) {
|
||||
path += value;
|
||||
continue;
|
||||
}
|
||||
if (path) {
|
||||
result.push(path);
|
||||
path = "";
|
||||
}
|
||||
var open = tryConsume("OPEN");
|
||||
if (open) {
|
||||
var prefix = consumeText();
|
||||
var name_1 = tryConsume("NAME") || "";
|
||||
var pattern_1 = tryConsume("PATTERN") || "";
|
||||
var suffix = consumeText();
|
||||
mustConsume("CLOSE");
|
||||
result.push({
|
||||
name: name_1 || (pattern_1 ? key++ : ""),
|
||||
pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
|
||||
prefix: prefix,
|
||||
suffix: suffix,
|
||||
modifier: tryConsume("MODIFIER") || "",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
mustConsume("END");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
export function compile(str, options) {
|
||||
return tokensToFunction(parse(str, options), options);
|
||||
}
|
||||
/**
|
||||
* Expose a method for transforming tokens into the path function.
|
||||
*/
|
||||
export function tokensToFunction(tokens, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var reFlags = flags(options);
|
||||
var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b;
|
||||
// Compile all the tokens into regexps.
|
||||
var matches = tokens.map(function (token) {
|
||||
if (typeof token === "object") {
|
||||
return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags);
|
||||
}
|
||||
});
|
||||
return function (data) {
|
||||
var path = "";
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (typeof token === "string") {
|
||||
path += token;
|
||||
continue;
|
||||
}
|
||||
var value = data ? data[token.name] : undefined;
|
||||
var optional = token.modifier === "?" || token.modifier === "*";
|
||||
var repeat = token.modifier === "*" || token.modifier === "+";
|
||||
if (Array.isArray(value)) {
|
||||
if (!repeat) {
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array"));
|
||||
}
|
||||
if (value.length === 0) {
|
||||
if (optional)
|
||||
continue;
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to not be empty"));
|
||||
}
|
||||
for (var j = 0; j < value.length; j++) {
|
||||
var segment = encode(value[j], token);
|
||||
if (validate && !matches[i].test(segment)) {
|
||||
throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
||||
}
|
||||
path += token.prefix + segment + token.suffix;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (typeof value === "string" || typeof value === "number") {
|
||||
var segment = encode(String(value), token);
|
||||
if (validate && !matches[i].test(segment)) {
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
||||
}
|
||||
path += token.prefix + segment + token.suffix;
|
||||
continue;
|
||||
}
|
||||
if (optional)
|
||||
continue;
|
||||
var typeOfMessage = repeat ? "an array" : "a string";
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to be ").concat(typeOfMessage));
|
||||
}
|
||||
return path;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create path match function from `path-to-regexp` spec.
|
||||
*/
|
||||
export function match(str, options) {
|
||||
var keys = [];
|
||||
var re = pathToRegexp(str, keys, options);
|
||||
return regexpToFunction(re, keys, options);
|
||||
}
|
||||
/**
|
||||
* Create a path match function from `path-to-regexp` output.
|
||||
*/
|
||||
export function regexpToFunction(re, keys, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a;
|
||||
return function (pathname) {
|
||||
var m = re.exec(pathname);
|
||||
if (!m)
|
||||
return false;
|
||||
var path = m[0], index = m.index;
|
||||
var params = Object.create(null);
|
||||
var _loop_1 = function (i) {
|
||||
if (m[i] === undefined)
|
||||
return "continue";
|
||||
var key = keys[i - 1];
|
||||
if (key.modifier === "*" || key.modifier === "+") {
|
||||
params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) {
|
||||
return decode(value, key);
|
||||
});
|
||||
}
|
||||
else {
|
||||
params[key.name] = decode(m[i], key);
|
||||
}
|
||||
};
|
||||
for (var i = 1; i < m.length; i++) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return { path: path, index: index, params: params };
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Escape a regular expression string.
|
||||
*/
|
||||
function escapeString(str) {
|
||||
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
||||
}
|
||||
/**
|
||||
* Get the flags for a regexp from the options.
|
||||
*/
|
||||
function flags(options) {
|
||||
return options && options.sensitive ? "" : "i";
|
||||
}
|
||||
/**
|
||||
* Pull out keys from a regexp.
|
||||
*/
|
||||
function regexpToRegexp(path, keys) {
|
||||
if (!keys)
|
||||
return path;
|
||||
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
|
||||
var index = 0;
|
||||
var execResult = groupsRegex.exec(path.source);
|
||||
while (execResult) {
|
||||
keys.push({
|
||||
// Use parenthesized substring match if available, index otherwise
|
||||
name: execResult[1] || index++,
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
modifier: "",
|
||||
pattern: "",
|
||||
});
|
||||
execResult = groupsRegex.exec(path.source);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Transform an array into a regexp.
|
||||
*/
|
||||
function arrayToRegexp(paths, keys, options) {
|
||||
var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; });
|
||||
return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options));
|
||||
}
|
||||
/**
|
||||
* Create a path regexp from string input.
|
||||
*/
|
||||
function stringToRegexp(path, keys, options) {
|
||||
return tokensToRegexp(parse(path, options), keys, options);
|
||||
}
|
||||
/**
|
||||
* Expose a function for taking tokens and returning a RegExp.
|
||||
*/
|
||||
export function tokensToRegexp(tokens, keys, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
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, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f;
|
||||
var endsWithRe = "[".concat(escapeString(endsWith), "]|$");
|
||||
var delimiterRe = "[".concat(escapeString(delimiter), "]");
|
||||
var route = start ? "^" : "";
|
||||
// Iterate over the tokens and create our regexp string.
|
||||
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
|
||||
var token = tokens_1[_i];
|
||||
if (typeof token === "string") {
|
||||
route += escapeString(encode(token));
|
||||
}
|
||||
else {
|
||||
var prefix = escapeString(encode(token.prefix));
|
||||
var suffix = escapeString(encode(token.suffix));
|
||||
if (token.pattern) {
|
||||
if (keys)
|
||||
keys.push(token);
|
||||
if (prefix || suffix) {
|
||||
if (token.modifier === "+" || token.modifier === "*") {
|
||||
var mod = token.modifier === "*" ? "?" : "";
|
||||
route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod);
|
||||
}
|
||||
else {
|
||||
route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (token.modifier === "+" || token.modifier === "*") {
|
||||
route += "((?:".concat(token.pattern, ")").concat(token.modifier, ")");
|
||||
}
|
||||
else {
|
||||
route += "(".concat(token.pattern, ")").concat(token.modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (end) {
|
||||
if (!strict)
|
||||
route += "".concat(delimiterRe, "?");
|
||||
route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")");
|
||||
}
|
||||
else {
|
||||
var endToken = tokens[tokens.length - 1];
|
||||
var isEndDelimited = typeof endToken === "string"
|
||||
? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1
|
||||
: endToken === undefined;
|
||||
if (!strict) {
|
||||
route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?");
|
||||
}
|
||||
if (!isEndDelimited) {
|
||||
route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")");
|
||||
}
|
||||
}
|
||||
return new RegExp(route, flags(options));
|
||||
}
|
||||
/**
|
||||
* Normalize the given path string, returning a regular expression.
|
||||
*
|
||||
* An empty array can be passed in for the keys, which will hold the
|
||||
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
||||
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
||||
*/
|
||||
export function pathToRegexp(path, keys, options) {
|
||||
if (path instanceof RegExp)
|
||||
return regexpToRegexp(path, keys);
|
||||
if (Array.isArray(path))
|
||||
return arrayToRegexp(path, keys, options);
|
||||
return stringToRegexp(path, keys, options);
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/path-to-regexp/dist.es2015/index.js.map
generated
vendored
1
node_modules/path-to-regexp/dist.es2015/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
201
node_modules/path-to-regexp/dist/index.d.ts
generated
vendored
201
node_modules/path-to-regexp/dist/index.d.ts
generated
vendored
|
|
@ -1,127 +1,136 @@
|
|||
/**
|
||||
* Encode a string into another string.
|
||||
*/
|
||||
export type Encode = (value: string) => string;
|
||||
/**
|
||||
* Decode a string into another string.
|
||||
*/
|
||||
export type Decode = (value: string) => string;
|
||||
export interface ParseOptions {
|
||||
/**
|
||||
* Set the default delimiter for repeat parameters. (default: `'/'`)
|
||||
* A function for encoding input strings.
|
||||
*/
|
||||
encodePath?: Encode;
|
||||
}
|
||||
export interface PathToRegexpOptions {
|
||||
/**
|
||||
* Matches the path completely without trailing characters. (default: `true`)
|
||||
*/
|
||||
end?: boolean;
|
||||
/**
|
||||
* Allows optional trailing delimiter to match. (default: `true`)
|
||||
*/
|
||||
trailing?: boolean;
|
||||
/**
|
||||
* Match will be case sensitive. (default: `false`)
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* The default delimiter for segments. (default: `'/'`)
|
||||
*/
|
||||
delimiter?: string;
|
||||
}
|
||||
export interface MatchOptions extends PathToRegexpOptions {
|
||||
/**
|
||||
* List of characters to automatically consider prefixes when parsing.
|
||||
* Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)
|
||||
*/
|
||||
prefixes?: string;
|
||||
decode?: Decode | false;
|
||||
}
|
||||
export interface CompileOptions {
|
||||
/**
|
||||
* Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
|
||||
*/
|
||||
encode?: Encode | false;
|
||||
/**
|
||||
* The default delimiter for segments. (default: `'/'`)
|
||||
*/
|
||||
delimiter?: string;
|
||||
}
|
||||
/**
|
||||
* Plain text.
|
||||
*/
|
||||
export interface Text {
|
||||
type: "text";
|
||||
value: string;
|
||||
}
|
||||
/**
|
||||
* A parameter designed to match arbitrary text within a segment.
|
||||
*/
|
||||
export interface Parameter {
|
||||
type: "param";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* A wildcard parameter designed to match multiple segments.
|
||||
*/
|
||||
export interface Wildcard {
|
||||
type: "wildcard";
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* A set of possible tokens to expand when matching.
|
||||
*/
|
||||
export interface Group {
|
||||
type: "group";
|
||||
tokens: Token[];
|
||||
}
|
||||
/**
|
||||
* A token that corresponds with a regexp capture.
|
||||
*/
|
||||
export type Key = Parameter | Wildcard;
|
||||
/**
|
||||
* A sequence of `path-to-regexp` keys that match capturing groups.
|
||||
*/
|
||||
export type Keys = Array<Key>;
|
||||
/**
|
||||
* A sequence of path match characters.
|
||||
*/
|
||||
export type Token = Text | Parameter | Wildcard | Group;
|
||||
/**
|
||||
* Tokenized path instance.
|
||||
*/
|
||||
export declare class TokenData {
|
||||
readonly tokens: Token[];
|
||||
constructor(tokens: Token[]);
|
||||
}
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
export declare function parse(str: string, options?: ParseOptions): Token[];
|
||||
export interface TokensToFunctionOptions {
|
||||
/**
|
||||
* When `true` the regexp will be case sensitive. (default: `false`)
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* Function for encoding input strings for output.
|
||||
*/
|
||||
encode?: (value: string, token: Key) => string;
|
||||
/**
|
||||
* When `false` the function can produce an invalid (unmatched) path. (default: `true`)
|
||||
*/
|
||||
validate?: boolean;
|
||||
}
|
||||
export declare function parse(str: string, options?: ParseOptions): TokenData;
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
export declare function compile<P extends object = object>(str: string, options?: ParseOptions & TokensToFunctionOptions): PathFunction<P>;
|
||||
export type PathFunction<P extends object = object> = (data?: P) => string;
|
||||
/**
|
||||
* Expose a method for transforming tokens into the path function.
|
||||
*/
|
||||
export declare function tokensToFunction<P extends object = object>(tokens: Token[], options?: TokensToFunctionOptions): PathFunction<P>;
|
||||
export interface RegexpToFunctionOptions {
|
||||
/**
|
||||
* Function for decoding strings for params.
|
||||
*/
|
||||
decode?: (value: string, token: Key) => string;
|
||||
}
|
||||
export declare function compile<P extends ParamData = ParamData>(path: Path, options?: CompileOptions & ParseOptions): (data?: P) => string;
|
||||
export type ParamData = Partial<Record<string, string | string[]>>;
|
||||
export type PathFunction<P extends ParamData> = (data?: P) => string;
|
||||
/**
|
||||
* A match result contains data about the path match.
|
||||
*/
|
||||
export interface MatchResult<P extends object = object> {
|
||||
export interface MatchResult<P extends ParamData> {
|
||||
path: string;
|
||||
index: number;
|
||||
params: P;
|
||||
}
|
||||
/**
|
||||
* A match is either `false` (no match) or a match result.
|
||||
*/
|
||||
export type Match<P extends object = object> = false | MatchResult<P>;
|
||||
export type Match<P extends ParamData> = false | MatchResult<P>;
|
||||
/**
|
||||
* The match function takes a string and returns whether it matched the path.
|
||||
*/
|
||||
export type MatchFunction<P extends object = object> = (path: string) => Match<P>;
|
||||
export type MatchFunction<P extends ParamData> = (path: string) => Match<P>;
|
||||
/**
|
||||
* Create path match function from `path-to-regexp` spec.
|
||||
* Supported path types.
|
||||
*/
|
||||
export declare function match<P extends object = object>(str: Path, options?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions): MatchFunction<P>;
|
||||
export type Path = string | TokenData;
|
||||
/**
|
||||
* Create a path match function from `path-to-regexp` output.
|
||||
* Transform a path into a match function.
|
||||
*/
|
||||
export declare function regexpToFunction<P extends object = object>(re: RegExp, keys: Key[], options?: RegexpToFunctionOptions): MatchFunction<P>;
|
||||
export declare function match<P extends ParamData>(path: Path | Path[], options?: MatchOptions & ParseOptions): MatchFunction<P>;
|
||||
export declare function pathToRegexp(path: Path | Path[], options?: PathToRegexpOptions & ParseOptions): {
|
||||
regexp: RegExp;
|
||||
keys: Keys;
|
||||
};
|
||||
/**
|
||||
* Metadata about a key.
|
||||
* Stringify token data into a path string.
|
||||
*/
|
||||
export interface Key {
|
||||
name: string | number;
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
pattern: string;
|
||||
modifier: string;
|
||||
}
|
||||
/**
|
||||
* A token is a string (nothing special) or key metadata (capture group).
|
||||
*/
|
||||
export type Token = string | Key;
|
||||
export interface TokensToRegexpOptions {
|
||||
/**
|
||||
* When `true` the regexp will be case sensitive. (default: `false`)
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)
|
||||
*/
|
||||
strict?: boolean;
|
||||
/**
|
||||
* When `true` the regexp will match to the end of the string. (default: `true`)
|
||||
*/
|
||||
end?: boolean;
|
||||
/**
|
||||
* When `true` the regexp will match from the beginning of the string. (default: `true`)
|
||||
*/
|
||||
start?: boolean;
|
||||
/**
|
||||
* Sets the final character for non-ending optimistic matches. (default: `/`)
|
||||
*/
|
||||
delimiter?: string;
|
||||
/**
|
||||
* List of characters that can also be "end" characters.
|
||||
*/
|
||||
endsWith?: string;
|
||||
/**
|
||||
* Encode path tokens for use in the `RegExp`.
|
||||
*/
|
||||
encode?: (value: string) => string;
|
||||
}
|
||||
/**
|
||||
* Expose a function for taking tokens and returning a RegExp.
|
||||
*/
|
||||
export declare function tokensToRegexp(tokens: Token[], keys?: Key[], options?: TokensToRegexpOptions): RegExp;
|
||||
/**
|
||||
* Supported `path-to-regexp` input types.
|
||||
*/
|
||||
export type Path = string | RegExp | Array<string | RegExp>;
|
||||
/**
|
||||
* Normalize the given path string, returning a regular expression.
|
||||
*
|
||||
* An empty array can be passed in for the keys, which will hold the
|
||||
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
||||
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
||||
*/
|
||||
export declare function pathToRegexp(path: Path, keys?: Key[], options?: TokensToRegexpOptions & ParseOptions): RegExp;
|
||||
export declare function stringify(data: TokenData): string;
|
||||
|
|
|
|||
759
node_modules/path-to-regexp/dist/index.js
generated
vendored
759
node_modules/path-to-regexp/dist/index.js
generated
vendored
|
|
@ -1,410 +1,413 @@
|
|||
"use strict";
|
||||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
||||
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");
|
||||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
||||
};
|
||||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
||||
if (kind === "m") throw new TypeError("Private method is not writable");
|
||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
||||
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");
|
||||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
||||
};
|
||||
var _Iter_peek;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pathToRegexp = exports.tokensToRegexp = exports.regexpToFunction = exports.match = exports.tokensToFunction = exports.compile = exports.parse = void 0;
|
||||
/**
|
||||
* Tokenize input string.
|
||||
*/
|
||||
function lexer(str) {
|
||||
var tokens = [];
|
||||
var i = 0;
|
||||
while (i < str.length) {
|
||||
var char = str[i];
|
||||
if (char === "*" || char === "+" || char === "?") {
|
||||
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "\\") {
|
||||
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "{") {
|
||||
tokens.push({ type: "OPEN", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === "}") {
|
||||
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
|
||||
continue;
|
||||
}
|
||||
if (char === ":") {
|
||||
var name = "";
|
||||
var j = i + 1;
|
||||
while (j < str.length) {
|
||||
var code = str.charCodeAt(j);
|
||||
if (
|
||||
// `0-9`
|
||||
(code >= 48 && code <= 57) ||
|
||||
// `A-Z`
|
||||
(code >= 65 && code <= 90) ||
|
||||
// `a-z`
|
||||
(code >= 97 && code <= 122) ||
|
||||
// `_`
|
||||
code === 95) {
|
||||
name += str[j++];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!name)
|
||||
throw new TypeError("Missing parameter name at ".concat(i));
|
||||
tokens.push({ type: "NAME", index: i, value: name });
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
if (char === "(") {
|
||||
var count = 1;
|
||||
var pattern = "";
|
||||
var j = i + 1;
|
||||
if (str[j] === "?") {
|
||||
throw new TypeError("Pattern cannot start with \"?\" at ".concat(j));
|
||||
}
|
||||
while (j < str.length) {
|
||||
if (str[j] === "\\") {
|
||||
pattern += str[j++] + str[j++];
|
||||
continue;
|
||||
}
|
||||
if (str[j] === ")") {
|
||||
count--;
|
||||
if (count === 0) {
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (str[j] === "(") {
|
||||
count++;
|
||||
if (str[j + 1] !== "?") {
|
||||
throw new TypeError("Capturing groups are not allowed at ".concat(j));
|
||||
}
|
||||
}
|
||||
pattern += str[j++];
|
||||
}
|
||||
if (count)
|
||||
throw new TypeError("Unbalanced pattern at ".concat(i));
|
||||
if (!pattern)
|
||||
throw new TypeError("Missing pattern at ".concat(i));
|
||||
tokens.push({ type: "PATTERN", index: i, value: pattern });
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
tokens.push({ type: "CHAR", index: i, value: str[i++] });
|
||||
}
|
||||
tokens.push({ type: "END", index: i, value: "" });
|
||||
return tokens;
|
||||
}
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
function parse(str, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var tokens = lexer(str);
|
||||
var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
|
||||
var defaultPattern = "[^".concat(escapeString(options.delimiter || "/#?"), "]+?");
|
||||
var result = [];
|
||||
var key = 0;
|
||||
var i = 0;
|
||||
var path = "";
|
||||
var tryConsume = function (type) {
|
||||
if (i < tokens.length && tokens[i].type === type)
|
||||
return tokens[i++].value;
|
||||
};
|
||||
var mustConsume = function (type) {
|
||||
var value = tryConsume(type);
|
||||
if (value !== undefined)
|
||||
return value;
|
||||
var _a = tokens[i], nextType = _a.type, index = _a.index;
|
||||
throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type));
|
||||
};
|
||||
var consumeText = function () {
|
||||
var result = "";
|
||||
var value;
|
||||
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
|
||||
result += value;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
while (i < tokens.length) {
|
||||
var char = tryConsume("CHAR");
|
||||
var name = tryConsume("NAME");
|
||||
var pattern = tryConsume("PATTERN");
|
||||
if (name || pattern) {
|
||||
var prefix = char || "";
|
||||
if (prefixes.indexOf(prefix) === -1) {
|
||||
path += prefix;
|
||||
prefix = "";
|
||||
}
|
||||
if (path) {
|
||||
result.push(path);
|
||||
path = "";
|
||||
}
|
||||
result.push({
|
||||
name: name || key++,
|
||||
prefix: prefix,
|
||||
suffix: "",
|
||||
pattern: pattern || defaultPattern,
|
||||
modifier: tryConsume("MODIFIER") || "",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
var value = char || tryConsume("ESCAPED_CHAR");
|
||||
if (value) {
|
||||
path += value;
|
||||
continue;
|
||||
}
|
||||
if (path) {
|
||||
result.push(path);
|
||||
path = "";
|
||||
}
|
||||
var open = tryConsume("OPEN");
|
||||
if (open) {
|
||||
var prefix = consumeText();
|
||||
var name_1 = tryConsume("NAME") || "";
|
||||
var pattern_1 = tryConsume("PATTERN") || "";
|
||||
var suffix = consumeText();
|
||||
mustConsume("CLOSE");
|
||||
result.push({
|
||||
name: name_1 || (pattern_1 ? key++ : ""),
|
||||
pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
|
||||
prefix: prefix,
|
||||
suffix: suffix,
|
||||
modifier: tryConsume("MODIFIER") || "",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
mustConsume("END");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.TokenData = void 0;
|
||||
exports.parse = parse;
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
function compile(str, options) {
|
||||
return tokensToFunction(parse(str, options), options);
|
||||
}
|
||||
exports.compile = compile;
|
||||
/**
|
||||
* Expose a method for transforming tokens into the path function.
|
||||
*/
|
||||
function tokensToFunction(tokens, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var reFlags = flags(options);
|
||||
var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b;
|
||||
// Compile all the tokens into regexps.
|
||||
var matches = tokens.map(function (token) {
|
||||
if (typeof token === "object") {
|
||||
return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags);
|
||||
}
|
||||
});
|
||||
return function (data) {
|
||||
var path = "";
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (typeof token === "string") {
|
||||
path += token;
|
||||
continue;
|
||||
}
|
||||
var value = data ? data[token.name] : undefined;
|
||||
var optional = token.modifier === "?" || token.modifier === "*";
|
||||
var repeat = token.modifier === "*" || token.modifier === "+";
|
||||
if (Array.isArray(value)) {
|
||||
if (!repeat) {
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array"));
|
||||
}
|
||||
if (value.length === 0) {
|
||||
if (optional)
|
||||
continue;
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to not be empty"));
|
||||
}
|
||||
for (var j = 0; j < value.length; j++) {
|
||||
var segment = encode(value[j], token);
|
||||
if (validate && !matches[i].test(segment)) {
|
||||
throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
||||
}
|
||||
path += token.prefix + segment + token.suffix;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (typeof value === "string" || typeof value === "number") {
|
||||
var segment = encode(String(value), token);
|
||||
if (validate && !matches[i].test(segment)) {
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\""));
|
||||
}
|
||||
path += token.prefix + segment + token.suffix;
|
||||
continue;
|
||||
}
|
||||
if (optional)
|
||||
continue;
|
||||
var typeOfMessage = repeat ? "an array" : "a string";
|
||||
throw new TypeError("Expected \"".concat(token.name, "\" to be ").concat(typeOfMessage));
|
||||
}
|
||||
return path;
|
||||
};
|
||||
}
|
||||
exports.tokensToFunction = tokensToFunction;
|
||||
/**
|
||||
* Create path match function from `path-to-regexp` spec.
|
||||
*/
|
||||
function match(str, options) {
|
||||
var keys = [];
|
||||
var re = pathToRegexp(str, keys, options);
|
||||
return regexpToFunction(re, keys, options);
|
||||
}
|
||||
exports.match = match;
|
||||
exports.pathToRegexp = pathToRegexp;
|
||||
exports.stringify = stringify;
|
||||
const DEFAULT_DELIMITER = "/";
|
||||
const NOOP_VALUE = (value) => value;
|
||||
const ID_START = /^[$_\p{ID_Start}]$/u;
|
||||
const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
|
||||
const DEBUG_URL = "https://git.new/pathToRegexpError";
|
||||
const SIMPLE_TOKENS = {
|
||||
// Groups.
|
||||
"{": "{",
|
||||
"}": "}",
|
||||
// Reserved.
|
||||
"(": "(",
|
||||
")": ")",
|
||||
"[": "[",
|
||||
"]": "]",
|
||||
"+": "+",
|
||||
"?": "?",
|
||||
"!": "!",
|
||||
};
|
||||
/**
|
||||
* Create a path match function from `path-to-regexp` output.
|
||||
* Escape text for stringify to path.
|
||||
*/
|
||||
function regexpToFunction(re, keys, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a;
|
||||
return function (pathname) {
|
||||
var m = re.exec(pathname);
|
||||
if (!m)
|
||||
return false;
|
||||
var path = m[0], index = m.index;
|
||||
var params = Object.create(null);
|
||||
var _loop_1 = function (i) {
|
||||
if (m[i] === undefined)
|
||||
return "continue";
|
||||
var key = keys[i - 1];
|
||||
if (key.modifier === "*" || key.modifier === "+") {
|
||||
params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) {
|
||||
return decode(value, key);
|
||||
});
|
||||
}
|
||||
else {
|
||||
params[key.name] = decode(m[i], key);
|
||||
}
|
||||
};
|
||||
for (var i = 1; i < m.length; i++) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return { path: path, index: index, params: params };
|
||||
};
|
||||
function escapeText(str) {
|
||||
return str.replace(/[{}()\[\]+?!:*]/g, "\\$&");
|
||||
}
|
||||
exports.regexpToFunction = regexpToFunction;
|
||||
/**
|
||||
* Escape a regular expression string.
|
||||
*/
|
||||
function escapeString(str) {
|
||||
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
||||
function escape(str) {
|
||||
return str.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&");
|
||||
}
|
||||
/**
|
||||
* Get the flags for a regexp from the options.
|
||||
* Tokenize input string.
|
||||
*/
|
||||
function flags(options) {
|
||||
return options && options.sensitive ? "" : "i";
|
||||
}
|
||||
/**
|
||||
* Pull out keys from a regexp.
|
||||
*/
|
||||
function regexpToRegexp(path, keys) {
|
||||
if (!keys)
|
||||
return path;
|
||||
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
|
||||
var index = 0;
|
||||
var execResult = groupsRegex.exec(path.source);
|
||||
while (execResult) {
|
||||
keys.push({
|
||||
// Use parenthesized substring match if available, index otherwise
|
||||
name: execResult[1] || index++,
|
||||
prefix: "",
|
||||
suffix: "",
|
||||
modifier: "",
|
||||
pattern: "",
|
||||
});
|
||||
execResult = groupsRegex.exec(path.source);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Transform an array into a regexp.
|
||||
*/
|
||||
function arrayToRegexp(paths, keys, options) {
|
||||
var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; });
|
||||
return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options));
|
||||
}
|
||||
/**
|
||||
* Create a path regexp from string input.
|
||||
*/
|
||||
function stringToRegexp(path, keys, options) {
|
||||
return tokensToRegexp(parse(path, options), keys, options);
|
||||
}
|
||||
/**
|
||||
* Expose a function for taking tokens and returning a RegExp.
|
||||
*/
|
||||
function tokensToRegexp(tokens, keys, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
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, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f;
|
||||
var endsWithRe = "[".concat(escapeString(endsWith), "]|$");
|
||||
var delimiterRe = "[".concat(escapeString(delimiter), "]");
|
||||
var route = start ? "^" : "";
|
||||
// Iterate over the tokens and create our regexp string.
|
||||
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
|
||||
var token = tokens_1[_i];
|
||||
if (typeof token === "string") {
|
||||
route += escapeString(encode(token));
|
||||
function* lexer(str) {
|
||||
const chars = [...str];
|
||||
let i = 0;
|
||||
function name() {
|
||||
let value = "";
|
||||
if (ID_START.test(chars[++i])) {
|
||||
value += chars[i];
|
||||
while (ID_CONTINUE.test(chars[++i])) {
|
||||
value += chars[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
var prefix = escapeString(encode(token.prefix));
|
||||
var suffix = escapeString(encode(token.suffix));
|
||||
if (token.pattern) {
|
||||
if (keys)
|
||||
keys.push(token);
|
||||
if (prefix || suffix) {
|
||||
if (token.modifier === "+" || token.modifier === "*") {
|
||||
var mod = token.modifier === "*" ? "?" : "";
|
||||
route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod);
|
||||
}
|
||||
else {
|
||||
route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier);
|
||||
}
|
||||
else if (chars[i] === '"') {
|
||||
let pos = i;
|
||||
while (i < chars.length) {
|
||||
if (chars[++i] === '"') {
|
||||
i++;
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
if (chars[i] === "\\") {
|
||||
value += chars[++i];
|
||||
}
|
||||
else {
|
||||
if (token.modifier === "+" || token.modifier === "*") {
|
||||
route += "((?:".concat(token.pattern, ")").concat(token.modifier, ")");
|
||||
}
|
||||
else {
|
||||
route += "(".concat(token.pattern, ")").concat(token.modifier);
|
||||
}
|
||||
value += chars[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier);
|
||||
if (pos) {
|
||||
throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
if (end) {
|
||||
if (!strict)
|
||||
route += "".concat(delimiterRe, "?");
|
||||
route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")");
|
||||
while (i < chars.length) {
|
||||
const value = chars[i];
|
||||
const type = SIMPLE_TOKENS[value];
|
||||
if (type) {
|
||||
yield { type, index: i++, value };
|
||||
}
|
||||
else if (value === "\\") {
|
||||
yield { type: "ESCAPED", index: i++, value: chars[i++] };
|
||||
}
|
||||
else if (value === ":") {
|
||||
const value = name();
|
||||
yield { type: "PARAM", index: i, value };
|
||||
}
|
||||
else if (value === "*") {
|
||||
const value = name();
|
||||
yield { type: "WILDCARD", index: i, value };
|
||||
}
|
||||
else {
|
||||
yield { type: "CHAR", index: i, value: chars[i++] };
|
||||
}
|
||||
}
|
||||
return { type: "END", index: i, value: "" };
|
||||
}
|
||||
class Iter {
|
||||
constructor(tokens) {
|
||||
this.tokens = tokens;
|
||||
_Iter_peek.set(this, void 0);
|
||||
}
|
||||
peek() {
|
||||
if (!__classPrivateFieldGet(this, _Iter_peek, "f")) {
|
||||
const next = this.tokens.next();
|
||||
__classPrivateFieldSet(this, _Iter_peek, next.value, "f");
|
||||
}
|
||||
return __classPrivateFieldGet(this, _Iter_peek, "f");
|
||||
}
|
||||
tryConsume(type) {
|
||||
const token = this.peek();
|
||||
if (token.type !== type)
|
||||
return;
|
||||
__classPrivateFieldSet(this, _Iter_peek, undefined, "f"); // Reset after consumed.
|
||||
return token.value;
|
||||
}
|
||||
consume(type) {
|
||||
const value = this.tryConsume(type);
|
||||
if (value !== undefined)
|
||||
return value;
|
||||
const { type: nextType, index } = this.peek();
|
||||
throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`);
|
||||
}
|
||||
text() {
|
||||
let result = "";
|
||||
let value;
|
||||
while ((value = this.tryConsume("CHAR") || this.tryConsume("ESCAPED"))) {
|
||||
result += value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
_Iter_peek = new WeakMap();
|
||||
/**
|
||||
* Tokenized path instance.
|
||||
*/
|
||||
class TokenData {
|
||||
constructor(tokens) {
|
||||
this.tokens = tokens;
|
||||
}
|
||||
}
|
||||
exports.TokenData = TokenData;
|
||||
/**
|
||||
* Parse a string for the raw tokens.
|
||||
*/
|
||||
function parse(str, options = {}) {
|
||||
const { encodePath = NOOP_VALUE } = options;
|
||||
const it = new Iter(lexer(str));
|
||||
function consume(endType) {
|
||||
const tokens = [];
|
||||
while (true) {
|
||||
const path = it.text();
|
||||
if (path)
|
||||
tokens.push({ type: "text", value: encodePath(path) });
|
||||
const param = it.tryConsume("PARAM");
|
||||
if (param) {
|
||||
tokens.push({
|
||||
type: "param",
|
||||
name: param,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const wildcard = it.tryConsume("WILDCARD");
|
||||
if (wildcard) {
|
||||
tokens.push({
|
||||
type: "wildcard",
|
||||
name: wildcard,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const open = it.tryConsume("{");
|
||||
if (open) {
|
||||
tokens.push({
|
||||
type: "group",
|
||||
tokens: consume("}"),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
it.consume(endType);
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
const tokens = consume("END");
|
||||
return new TokenData(tokens);
|
||||
}
|
||||
/**
|
||||
* Compile a string to a template function for the path.
|
||||
*/
|
||||
function compile(path, options = {}) {
|
||||
const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
||||
const data = path instanceof TokenData ? path : parse(path, options);
|
||||
const fn = tokensToFunction(data.tokens, delimiter, encode);
|
||||
return function path(data = {}) {
|
||||
const [path, ...missing] = fn(data);
|
||||
if (missing.length) {
|
||||
throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
|
||||
}
|
||||
return path;
|
||||
};
|
||||
}
|
||||
function tokensToFunction(tokens, delimiter, encode) {
|
||||
const encoders = tokens.map((token) => tokenToFunction(token, delimiter, encode));
|
||||
return (data) => {
|
||||
const result = [""];
|
||||
for (const encoder of encoders) {
|
||||
const [value, ...extras] = encoder(data);
|
||||
result[0] += value;
|
||||
result.push(...extras);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert a single token into a path building function.
|
||||
*/
|
||||
function tokenToFunction(token, delimiter, encode) {
|
||||
if (token.type === "text")
|
||||
return () => [token.value];
|
||||
if (token.type === "group") {
|
||||
const fn = tokensToFunction(token.tokens, delimiter, encode);
|
||||
return (data) => {
|
||||
const [value, ...missing] = fn(data);
|
||||
if (!missing.length)
|
||||
return [value];
|
||||
return [""];
|
||||
};
|
||||
}
|
||||
const encodeValue = encode || NOOP_VALUE;
|
||||
if (token.type === "wildcard" && encode !== false) {
|
||||
return (data) => {
|
||||
const value = data[token.name];
|
||||
if (value == null)
|
||||
return ["", token.name];
|
||||
if (!Array.isArray(value) || value.length === 0) {
|
||||
throw new TypeError(`Expected "${token.name}" to be a non-empty array`);
|
||||
}
|
||||
return [
|
||||
value
|
||||
.map((value, index) => {
|
||||
if (typeof value !== "string") {
|
||||
throw new TypeError(`Expected "${token.name}/${index}" to be a string`);
|
||||
}
|
||||
return encodeValue(value);
|
||||
})
|
||||
.join(delimiter),
|
||||
];
|
||||
};
|
||||
}
|
||||
return (data) => {
|
||||
const value = data[token.name];
|
||||
if (value == null)
|
||||
return ["", token.name];
|
||||
if (typeof value !== "string") {
|
||||
throw new TypeError(`Expected "${token.name}" to be a string`);
|
||||
}
|
||||
return [encodeValue(value)];
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Transform a path into a match function.
|
||||
*/
|
||||
function match(path, options = {}) {
|
||||
const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
||||
const { regexp, keys } = pathToRegexp(path, options);
|
||||
const decoders = keys.map((key) => {
|
||||
if (decode === false)
|
||||
return NOOP_VALUE;
|
||||
if (key.type === "param")
|
||||
return decode;
|
||||
return (value) => value.split(delimiter).map(decode);
|
||||
});
|
||||
return function match(input) {
|
||||
const m = regexp.exec(input);
|
||||
if (!m)
|
||||
return false;
|
||||
const path = m[0];
|
||||
const params = Object.create(null);
|
||||
for (let i = 1; i < m.length; i++) {
|
||||
if (m[i] === undefined)
|
||||
continue;
|
||||
const key = keys[i - 1];
|
||||
const decoder = decoders[i - 1];
|
||||
params[key.name] = decoder(m[i]);
|
||||
}
|
||||
return { path, params };
|
||||
};
|
||||
}
|
||||
function pathToRegexp(path, options = {}) {
|
||||
const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true, } = options;
|
||||
const keys = [];
|
||||
const sources = [];
|
||||
const flags = sensitive ? "s" : "is";
|
||||
const paths = Array.isArray(path) ? path : [path];
|
||||
const items = paths.map((path) => path instanceof TokenData ? path : parse(path, options));
|
||||
for (const { tokens } of items) {
|
||||
for (const seq of flatten(tokens, 0, [])) {
|
||||
const regexp = sequenceToRegExp(seq, delimiter, keys);
|
||||
sources.push(regexp);
|
||||
}
|
||||
}
|
||||
let pattern = `^(?:${sources.join("|")})`;
|
||||
if (trailing)
|
||||
pattern += `(?:${escape(delimiter)}$)?`;
|
||||
pattern += end ? "$" : `(?=${escape(delimiter)}|$)`;
|
||||
const regexp = new RegExp(pattern, flags);
|
||||
return { regexp, keys };
|
||||
}
|
||||
/**
|
||||
* Generate a flat list of sequence tokens from the given tokens.
|
||||
*/
|
||||
function* flatten(tokens, index, init) {
|
||||
if (index === tokens.length) {
|
||||
return yield init;
|
||||
}
|
||||
const token = tokens[index];
|
||||
if (token.type === "group") {
|
||||
const fork = init.slice();
|
||||
for (const seq of flatten(token.tokens, 0, fork)) {
|
||||
yield* flatten(tokens, index + 1, seq);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var endToken = tokens[tokens.length - 1];
|
||||
var isEndDelimited = typeof endToken === "string"
|
||||
? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1
|
||||
: endToken === undefined;
|
||||
if (!strict) {
|
||||
route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?");
|
||||
init.push(token);
|
||||
}
|
||||
yield* flatten(tokens, index + 1, init);
|
||||
}
|
||||
/**
|
||||
* Transform a flat sequence of tokens into a regular expression.
|
||||
*/
|
||||
function sequenceToRegExp(tokens, delimiter, keys) {
|
||||
let result = "";
|
||||
let backtrack = "";
|
||||
let isSafeSegmentParam = true;
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
if (token.type === "text") {
|
||||
result += escape(token.value);
|
||||
backtrack = token.value;
|
||||
isSafeSegmentParam || (isSafeSegmentParam = token.value.includes(delimiter));
|
||||
continue;
|
||||
}
|
||||
if (!isEndDelimited) {
|
||||
route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")");
|
||||
if (token.type === "param" || token.type === "wildcard") {
|
||||
if (!isSafeSegmentParam && !backtrack) {
|
||||
throw new TypeError(`Missing text after "${token.name}": ${DEBUG_URL}`);
|
||||
}
|
||||
if (token.type === "param") {
|
||||
result += `(${negate(delimiter, isSafeSegmentParam ? "" : backtrack)}+)`;
|
||||
}
|
||||
else {
|
||||
result += `(.+)`;
|
||||
}
|
||||
keys.push(token);
|
||||
backtrack = "";
|
||||
isSafeSegmentParam = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return new RegExp(route, flags(options));
|
||||
return result;
|
||||
}
|
||||
function negate(delimiter, backtrack) {
|
||||
const values = [delimiter, backtrack].filter(Boolean);
|
||||
const isSimple = values.every((value) => value.length === 1);
|
||||
if (isSimple)
|
||||
return `[^${escape(values.join(""))}]`;
|
||||
return `(?:(?!${values.map(escape).join("|")}).)`;
|
||||
}
|
||||
exports.tokensToRegexp = tokensToRegexp;
|
||||
/**
|
||||
* Normalize the given path string, returning a regular expression.
|
||||
*
|
||||
* An empty array can be passed in for the keys, which will hold the
|
||||
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
||||
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
||||
* Stringify token data into a path string.
|
||||
*/
|
||||
function pathToRegexp(path, keys, options) {
|
||||
if (path instanceof RegExp)
|
||||
return regexpToRegexp(path, keys);
|
||||
if (Array.isArray(path))
|
||||
return arrayToRegexp(path, keys, options);
|
||||
return stringToRegexp(path, keys, options);
|
||||
function stringify(data) {
|
||||
return data.tokens
|
||||
.map(function stringifyToken(token, index, tokens) {
|
||||
if (token.type === "text")
|
||||
return escapeText(token.value);
|
||||
if (token.type === "group") {
|
||||
return `{${token.tokens.map(stringifyToken).join("")}}`;
|
||||
}
|
||||
const isSafe = isNameSafe(token.name) && isNextNameSafe(tokens[index + 1]);
|
||||
const key = isSafe ? token.name : JSON.stringify(token.name);
|
||||
if (token.type === "param")
|
||||
return `:${key}`;
|
||||
if (token.type === "wildcard")
|
||||
return `*${key}`;
|
||||
throw new TypeError(`Unexpected token: ${token}`);
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
function isNameSafe(name) {
|
||||
const [first, ...rest] = name;
|
||||
if (!ID_START.test(first))
|
||||
return false;
|
||||
return rest.every((char) => ID_CONTINUE.test(char));
|
||||
}
|
||||
function isNextNameSafe(token) {
|
||||
if (token?.type !== "text")
|
||||
return true;
|
||||
return !ID_CONTINUE.test(token.value[0]);
|
||||
}
|
||||
exports.pathToRegexp = pathToRegexp;
|
||||
//# sourceMappingURL=index.js.map
|
||||
2
node_modules/path-to-regexp/dist/index.js.map
generated
vendored
2
node_modules/path-to-regexp/dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
24
node_modules/path-to-regexp/package.json
generated
vendored
24
node_modules/path-to-regexp/package.json
generated
vendored
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "path-to-regexp",
|
||||
"version": "6.2.2",
|
||||
"version": "8.1.0",
|
||||
"description": "Express style path to RegExp utility",
|
||||
"keywords": [
|
||||
"express",
|
||||
|
|
@ -13,15 +13,14 @@
|
|||
"url": "https://github.com/pillarjs/path-to-regexp.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"exports": "./dist/index.js",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist.es2015/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist.es2015/",
|
||||
"dist/"
|
||||
],
|
||||
"scripts": {
|
||||
"bench": "vitest bench",
|
||||
"build": "ts-scripts build",
|
||||
"format": "ts-scripts format",
|
||||
"lint": "ts-scripts lint",
|
||||
|
|
@ -36,27 +35,28 @@
|
|||
"@types/node": "^20.4.9",
|
||||
"@types/semver": "^7.3.1",
|
||||
"@vitest/coverage-v8": "^1.4.0",
|
||||
"semver": "^7.3.5",
|
||||
"recheck": "^4.4.5",
|
||||
"size-limit": "^11.1.2",
|
||||
"typescript": "^5.1.6"
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"size-limit": [
|
||||
{
|
||||
"path": "dist.es2015/index.js",
|
||||
"limit": "2 kB"
|
||||
"path": "dist/index.js",
|
||||
"limit": "2.2 kB"
|
||||
}
|
||||
],
|
||||
"ts-scripts": {
|
||||
"dist": [
|
||||
"dist",
|
||||
"dist.es2015"
|
||||
"dist"
|
||||
],
|
||||
"project": [
|
||||
"tsconfig.build.json",
|
||||
"tsconfig.es2015.json"
|
||||
"tsconfig.build.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue