@eggjs/router 4.0.0-beta.18 → 4.0.0-beta.20
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/dist/EggRouter-DcO6PAYI.d.ts +108 -0
- package/dist/EggRouter-DvjBpJdR.js +208 -0
- package/dist/EggRouter.d.ts +4 -107
- package/dist/EggRouter.js +4 -206
- package/dist/Layer-Br45DupW.d.ts +118 -0
- package/dist/Layer-CPiRgFSm.js +201 -0
- package/dist/Layer.d.ts +2 -117
- package/dist/Layer.js +1 -199
- package/dist/Router-BGI5feOg.d.ts +496 -0
- package/dist/Router-CWrZ5wcC.js +676 -0
- package/dist/Router.d.ts +3 -495
- package/dist/Router.js +3 -674
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -3
- package/dist/types-CxAOQAAb.js +1 -0
- package/dist/types-DvonNcgV.d.ts +21 -0
- package/dist/types.d.ts +1 -20
- package/dist/types.js +2 -0
- package/package.json +6 -6
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { MiddlewareFunc, MiddlewareFuncWithParamProperty, ParamMiddlewareFunc } from "./types-DvonNcgV.js";
|
|
2
|
+
import { Key } from "path-to-regexp";
|
|
3
|
+
|
|
4
|
+
//#region src/Layer.d.ts
|
|
5
|
+
interface LayerOptions {
|
|
6
|
+
prefix?: string;
|
|
7
|
+
/** route name */
|
|
8
|
+
name?: string;
|
|
9
|
+
/** case sensitive (default: false) */
|
|
10
|
+
sensitive?: boolean;
|
|
11
|
+
/** require the trailing slash (default: false) */
|
|
12
|
+
strict?: boolean;
|
|
13
|
+
ignoreCaptures?: boolean;
|
|
14
|
+
end?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface LayerURLOptions {
|
|
17
|
+
query?: string | object;
|
|
18
|
+
}
|
|
19
|
+
declare class Layer {
|
|
20
|
+
readonly opts: LayerOptions;
|
|
21
|
+
readonly name?: string;
|
|
22
|
+
readonly methods: string[];
|
|
23
|
+
readonly stack: MiddlewareFuncWithParamProperty[];
|
|
24
|
+
path: string | RegExp;
|
|
25
|
+
regexp: RegExp;
|
|
26
|
+
paramNames: Key[];
|
|
27
|
+
/**
|
|
28
|
+
* Initialize a new routing Layer with given `method`, `path`, and `middleware`.
|
|
29
|
+
*
|
|
30
|
+
* @param {String|RegExp} path Path string or regular expression.
|
|
31
|
+
* @param {Array} methods Array of HTTP verbs.
|
|
32
|
+
* @param {Array|Function} middlewares Layer callback/middleware or series of.
|
|
33
|
+
* @param {Object=} opts optional params
|
|
34
|
+
* @param {String=} opts.name route name
|
|
35
|
+
* @param {String=} opts.sensitive case sensitive (default: false)
|
|
36
|
+
* @param {String=} opts.strict require the trailing slash (default: false)
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
constructor(path: string | RegExp, methods: string[], middlewares: MiddlewareFunc | MiddlewareFunc[], opts?: LayerOptions | string);
|
|
40
|
+
/**
|
|
41
|
+
* Returns whether request `path` matches route.
|
|
42
|
+
*
|
|
43
|
+
* @param {String} path path string
|
|
44
|
+
* @return {Boolean} matched or not
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
match(path: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Returns map of URL parameters for given `path` and `paramNames`.
|
|
50
|
+
*
|
|
51
|
+
* @param {String} _path path string
|
|
52
|
+
* @param {Array.<String>} captures captures strings
|
|
53
|
+
* @param {Object=} [existingParams] existing params
|
|
54
|
+
* @return {Object} params object
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
params(_path: string, captures: Array<string>, existingParams?: Record<string, string>): Record<string, string>;
|
|
58
|
+
/**
|
|
59
|
+
* Returns array of regexp url path captures.
|
|
60
|
+
*
|
|
61
|
+
* @param {String} path path string
|
|
62
|
+
* @return {Array.<String>} captures strings
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
captures(path: string): Array<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Generate URL for route using given `params`.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
*
|
|
71
|
+
* ```javascript
|
|
72
|
+
* var route = new Layer(['GET'], '/users/:id', fn);
|
|
73
|
+
*
|
|
74
|
+
* route.url(123); // => "/users/123"
|
|
75
|
+
* route.url('123'); // => "/users/123"
|
|
76
|
+
* route.url({ id: 123 }); // => "/users/123"
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @param {Object} params url parameters
|
|
80
|
+
* @param {Object} paramsOrOptions optional parameters
|
|
81
|
+
* @return {String} url string
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
url(params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string;
|
|
85
|
+
/**
|
|
86
|
+
* Run validations on route named parameters.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
*
|
|
90
|
+
* ```javascript
|
|
91
|
+
* router
|
|
92
|
+
* .param('user', function (id, ctx, next) {
|
|
93
|
+
* ctx.user = users[id];
|
|
94
|
+
* if (!user) return ctx.status = 404;
|
|
95
|
+
* next();
|
|
96
|
+
* })
|
|
97
|
+
* .get('/users/:user', function (ctx, next) {
|
|
98
|
+
* ctx.body = ctx.user;
|
|
99
|
+
* });
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @param {String} param param string
|
|
103
|
+
* @param {Function} fn middleware function
|
|
104
|
+
* @return {Layer} layer instance
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
param(param: string, fn: ParamMiddlewareFunc): Layer;
|
|
108
|
+
/**
|
|
109
|
+
* Prefix route path.
|
|
110
|
+
*
|
|
111
|
+
* @param {String} prefix prefix string
|
|
112
|
+
* @return {Layer} layer instance
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
setPrefix(prefix: string): Layer;
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
export { Layer, LayerOptions, LayerURLOptions };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { decodeURIComponent } from "utility";
|
|
2
|
+
import { isGeneratorFunction } from "is-type-of";
|
|
3
|
+
import { debuglog } from "node:util";
|
|
4
|
+
import pathToRegExp from "path-to-regexp";
|
|
5
|
+
import URI from "urijs";
|
|
6
|
+
|
|
7
|
+
//#region src/Layer.ts
|
|
8
|
+
const debug = debuglog("egg/router:Layer");
|
|
9
|
+
var Layer = class {
|
|
10
|
+
opts;
|
|
11
|
+
name;
|
|
12
|
+
methods = [];
|
|
13
|
+
stack;
|
|
14
|
+
path;
|
|
15
|
+
regexp;
|
|
16
|
+
paramNames = [];
|
|
17
|
+
/**
|
|
18
|
+
* Initialize a new routing Layer with given `method`, `path`, and `middleware`.
|
|
19
|
+
*
|
|
20
|
+
* @param {String|RegExp} path Path string or regular expression.
|
|
21
|
+
* @param {Array} methods Array of HTTP verbs.
|
|
22
|
+
* @param {Array|Function} middlewares Layer callback/middleware or series of.
|
|
23
|
+
* @param {Object=} opts optional params
|
|
24
|
+
* @param {String=} opts.name route name
|
|
25
|
+
* @param {String=} opts.sensitive case sensitive (default: false)
|
|
26
|
+
* @param {String=} opts.strict require the trailing slash (default: false)
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
constructor(path, methods, middlewares, opts) {
|
|
30
|
+
if (typeof opts === "string") opts = { name: opts };
|
|
31
|
+
this.opts = opts ?? {};
|
|
32
|
+
this.opts.prefix = this.opts.prefix ?? "";
|
|
33
|
+
this.name = this.opts.name;
|
|
34
|
+
this.stack = Array.isArray(middlewares) ? middlewares : [middlewares];
|
|
35
|
+
for (const method of methods) {
|
|
36
|
+
const l = this.methods.push(method.toUpperCase());
|
|
37
|
+
if (this.methods[l - 1] === "GET") this.methods.unshift("HEAD");
|
|
38
|
+
}
|
|
39
|
+
this.stack.forEach((fn) => {
|
|
40
|
+
const type = typeof fn;
|
|
41
|
+
if (type !== "function") throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: `middleware` must be a function, not `" + type + "`");
|
|
42
|
+
if (isGeneratorFunction(fn)) throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: Please use async function instead of generator function");
|
|
43
|
+
});
|
|
44
|
+
this.path = path;
|
|
45
|
+
this.regexp = pathToRegExp(path, this.paramNames, this.opts);
|
|
46
|
+
debug("defined route %s %s", this.methods, this.opts.prefix + this.path);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns whether request `path` matches route.
|
|
50
|
+
*
|
|
51
|
+
* @param {String} path path string
|
|
52
|
+
* @return {Boolean} matched or not
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
match(path) {
|
|
56
|
+
return this.regexp.test(path);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns map of URL parameters for given `path` and `paramNames`.
|
|
60
|
+
*
|
|
61
|
+
* @param {String} _path path string
|
|
62
|
+
* @param {Array.<String>} captures captures strings
|
|
63
|
+
* @param {Object=} [existingParams] existing params
|
|
64
|
+
* @return {Object} params object
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
params(_path, captures, existingParams) {
|
|
68
|
+
const params = existingParams ?? {};
|
|
69
|
+
for (let len = captures.length, i = 0; i < len; i++) {
|
|
70
|
+
const paramName = this.paramNames[i];
|
|
71
|
+
if (paramName) {
|
|
72
|
+
const c = captures[i];
|
|
73
|
+
params[paramName.name] = c ? decodeURIComponent(c) : c;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return params;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Returns array of regexp url path captures.
|
|
80
|
+
*
|
|
81
|
+
* @param {String} path path string
|
|
82
|
+
* @return {Array.<String>} captures strings
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
captures(path) {
|
|
86
|
+
if (this.opts.ignoreCaptures) return [];
|
|
87
|
+
const m = path.match(this.regexp);
|
|
88
|
+
return m ? m.slice(1) : [];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generate URL for route using given `params`.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
*
|
|
95
|
+
* ```javascript
|
|
96
|
+
* var route = new Layer(['GET'], '/users/:id', fn);
|
|
97
|
+
*
|
|
98
|
+
* route.url(123); // => "/users/123"
|
|
99
|
+
* route.url('123'); // => "/users/123"
|
|
100
|
+
* route.url({ id: 123 }); // => "/users/123"
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @param {Object} params url parameters
|
|
104
|
+
* @param {Object} paramsOrOptions optional parameters
|
|
105
|
+
* @return {String} url string
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
url(params, ...paramsOrOptions) {
|
|
109
|
+
let args = params;
|
|
110
|
+
const url = this.path.replace(/\(\.\*\)/g, "");
|
|
111
|
+
const toPath = pathToRegExp.compile(url);
|
|
112
|
+
let options;
|
|
113
|
+
if (params !== void 0 && typeof params !== "object") {
|
|
114
|
+
args = [params, ...paramsOrOptions];
|
|
115
|
+
if (Array.isArray(args)) {
|
|
116
|
+
const lastIndex = args.length - 1;
|
|
117
|
+
if (typeof args[lastIndex] === "object") {
|
|
118
|
+
options = args[lastIndex];
|
|
119
|
+
args = args.slice(0, lastIndex);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} else if (typeof params === "object") {
|
|
123
|
+
if (typeof paramsOrOptions[0] === "object" && "query" in paramsOrOptions[0]) options = paramsOrOptions[0];
|
|
124
|
+
}
|
|
125
|
+
const tokens = pathToRegExp.parse(url);
|
|
126
|
+
let replace = {};
|
|
127
|
+
if (Array.isArray(args)) for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
|
|
128
|
+
const token = tokens[i];
|
|
129
|
+
if (typeof token === "object" && token.name) replace[token.name] = args[j++];
|
|
130
|
+
}
|
|
131
|
+
else if (tokens.some((token) => typeof token === "object" && token.name)) replace = params;
|
|
132
|
+
else options = params;
|
|
133
|
+
const replaced = toPath(replace);
|
|
134
|
+
if (options?.query) {
|
|
135
|
+
const urlObject = new URI(replaced);
|
|
136
|
+
urlObject.search(options.query);
|
|
137
|
+
return urlObject.toString();
|
|
138
|
+
}
|
|
139
|
+
return replaced;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Run validations on route named parameters.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
*
|
|
146
|
+
* ```javascript
|
|
147
|
+
* router
|
|
148
|
+
* .param('user', function (id, ctx, next) {
|
|
149
|
+
* ctx.user = users[id];
|
|
150
|
+
* if (!user) return ctx.status = 404;
|
|
151
|
+
* next();
|
|
152
|
+
* })
|
|
153
|
+
* .get('/users/:user', function (ctx, next) {
|
|
154
|
+
* ctx.body = ctx.user;
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @param {String} param param string
|
|
159
|
+
* @param {Function} fn middleware function
|
|
160
|
+
* @return {Layer} layer instance
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
param(param, fn) {
|
|
164
|
+
const stack = this.stack;
|
|
165
|
+
const params = this.paramNames;
|
|
166
|
+
const middleware = function(ctx, next) {
|
|
167
|
+
return fn.call(this, ctx.params[param], ctx, next);
|
|
168
|
+
};
|
|
169
|
+
middleware.param = param;
|
|
170
|
+
const names = params.map((p) => {
|
|
171
|
+
return p.name;
|
|
172
|
+
});
|
|
173
|
+
const x = names.indexOf(param);
|
|
174
|
+
if (x > -1) stack.some(function(fn$1, i) {
|
|
175
|
+
if (!fn$1.param || names.indexOf(fn$1.param) > x) {
|
|
176
|
+
stack.splice(i, 0, middleware);
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
});
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Prefix route path.
|
|
185
|
+
*
|
|
186
|
+
* @param {String} prefix prefix string
|
|
187
|
+
* @return {Layer} layer instance
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
setPrefix(prefix) {
|
|
191
|
+
if (this.path) {
|
|
192
|
+
this.path = prefix + this.path;
|
|
193
|
+
this.paramNames = [];
|
|
194
|
+
this.regexp = pathToRegExp(this.path, this.paramNames, this.opts);
|
|
195
|
+
}
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
export { Layer };
|
package/dist/Layer.d.ts
CHANGED
|
@@ -1,118 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
//#region src/Layer.d.ts
|
|
5
|
-
interface LayerOptions {
|
|
6
|
-
prefix?: string;
|
|
7
|
-
/** route name */
|
|
8
|
-
name?: string;
|
|
9
|
-
/** case sensitive (default: false) */
|
|
10
|
-
sensitive?: boolean;
|
|
11
|
-
/** require the trailing slash (default: false) */
|
|
12
|
-
strict?: boolean;
|
|
13
|
-
ignoreCaptures?: boolean;
|
|
14
|
-
end?: boolean;
|
|
15
|
-
}
|
|
16
|
-
interface LayerURLOptions {
|
|
17
|
-
query?: string | object;
|
|
18
|
-
}
|
|
19
|
-
declare class Layer {
|
|
20
|
-
readonly opts: LayerOptions;
|
|
21
|
-
readonly name?: string;
|
|
22
|
-
readonly methods: string[];
|
|
23
|
-
readonly stack: MiddlewareFuncWithParamProperty[];
|
|
24
|
-
path: string | RegExp;
|
|
25
|
-
regexp: RegExp;
|
|
26
|
-
paramNames: Key[];
|
|
27
|
-
/**
|
|
28
|
-
* Initialize a new routing Layer with given `method`, `path`, and `middleware`.
|
|
29
|
-
*
|
|
30
|
-
* @param {String|RegExp} path Path string or regular expression.
|
|
31
|
-
* @param {Array} methods Array of HTTP verbs.
|
|
32
|
-
* @param {Array|Function} middlewares Layer callback/middleware or series of.
|
|
33
|
-
* @param {Object=} opts optional params
|
|
34
|
-
* @param {String=} opts.name route name
|
|
35
|
-
* @param {String=} opts.sensitive case sensitive (default: false)
|
|
36
|
-
* @param {String=} opts.strict require the trailing slash (default: false)
|
|
37
|
-
* @private
|
|
38
|
-
*/
|
|
39
|
-
constructor(path: string | RegExp, methods: string[], middlewares: MiddlewareFunc | MiddlewareFunc[], opts?: LayerOptions | string);
|
|
40
|
-
/**
|
|
41
|
-
* Returns whether request `path` matches route.
|
|
42
|
-
*
|
|
43
|
-
* @param {String} path path string
|
|
44
|
-
* @return {Boolean} matched or not
|
|
45
|
-
* @private
|
|
46
|
-
*/
|
|
47
|
-
match(path: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Returns map of URL parameters for given `path` and `paramNames`.
|
|
50
|
-
*
|
|
51
|
-
* @param {String} _path path string
|
|
52
|
-
* @param {Array.<String>} captures captures strings
|
|
53
|
-
* @param {Object=} [existingParams] existing params
|
|
54
|
-
* @return {Object} params object
|
|
55
|
-
* @private
|
|
56
|
-
*/
|
|
57
|
-
params(_path: string, captures: Array<string>, existingParams?: Record<string, string>): Record<string, string>;
|
|
58
|
-
/**
|
|
59
|
-
* Returns array of regexp url path captures.
|
|
60
|
-
*
|
|
61
|
-
* @param {String} path path string
|
|
62
|
-
* @return {Array.<String>} captures strings
|
|
63
|
-
* @private
|
|
64
|
-
*/
|
|
65
|
-
captures(path: string): Array<string>;
|
|
66
|
-
/**
|
|
67
|
-
* Generate URL for route using given `params`.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
*
|
|
71
|
-
* ```javascript
|
|
72
|
-
* var route = new Layer(['GET'], '/users/:id', fn);
|
|
73
|
-
*
|
|
74
|
-
* route.url(123); // => "/users/123"
|
|
75
|
-
* route.url('123'); // => "/users/123"
|
|
76
|
-
* route.url({ id: 123 }); // => "/users/123"
|
|
77
|
-
* ```
|
|
78
|
-
*
|
|
79
|
-
* @param {Object} params url parameters
|
|
80
|
-
* @param {Object} paramsOrOptions optional parameters
|
|
81
|
-
* @return {String} url string
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
url(params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string;
|
|
85
|
-
/**
|
|
86
|
-
* Run validations on route named parameters.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
*
|
|
90
|
-
* ```javascript
|
|
91
|
-
* router
|
|
92
|
-
* .param('user', function (id, ctx, next) {
|
|
93
|
-
* ctx.user = users[id];
|
|
94
|
-
* if (!user) return ctx.status = 404;
|
|
95
|
-
* next();
|
|
96
|
-
* })
|
|
97
|
-
* .get('/users/:user', function (ctx, next) {
|
|
98
|
-
* ctx.body = ctx.user;
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*
|
|
102
|
-
* @param {String} param param string
|
|
103
|
-
* @param {Function} fn middleware function
|
|
104
|
-
* @return {Layer} layer instance
|
|
105
|
-
* @private
|
|
106
|
-
*/
|
|
107
|
-
param(param: string, fn: ParamMiddlewareFunc): Layer;
|
|
108
|
-
/**
|
|
109
|
-
* Prefix route path.
|
|
110
|
-
*
|
|
111
|
-
* @param {String} prefix prefix string
|
|
112
|
-
* @return {Layer} layer instance
|
|
113
|
-
* @private
|
|
114
|
-
*/
|
|
115
|
-
setPrefix(prefix: string): Layer;
|
|
116
|
-
}
|
|
117
|
-
//#endregion
|
|
1
|
+
import "./types-DvonNcgV.js";
|
|
2
|
+
import { Layer, LayerOptions, LayerURLOptions } from "./Layer-Br45DupW.js";
|
|
118
3
|
export { Layer, LayerOptions, LayerURLOptions };
|
package/dist/Layer.js
CHANGED
|
@@ -1,201 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isGeneratorFunction } from "is-type-of";
|
|
3
|
-
import { debuglog } from "node:util";
|
|
4
|
-
import pathToRegExp from "path-to-regexp";
|
|
5
|
-
import URI from "urijs";
|
|
1
|
+
import { Layer } from "./Layer-CPiRgFSm.js";
|
|
6
2
|
|
|
7
|
-
//#region src/Layer.ts
|
|
8
|
-
const debug = debuglog("egg/router:Layer");
|
|
9
|
-
var Layer = class {
|
|
10
|
-
opts;
|
|
11
|
-
name;
|
|
12
|
-
methods = [];
|
|
13
|
-
stack;
|
|
14
|
-
path;
|
|
15
|
-
regexp;
|
|
16
|
-
paramNames = [];
|
|
17
|
-
/**
|
|
18
|
-
* Initialize a new routing Layer with given `method`, `path`, and `middleware`.
|
|
19
|
-
*
|
|
20
|
-
* @param {String|RegExp} path Path string or regular expression.
|
|
21
|
-
* @param {Array} methods Array of HTTP verbs.
|
|
22
|
-
* @param {Array|Function} middlewares Layer callback/middleware or series of.
|
|
23
|
-
* @param {Object=} opts optional params
|
|
24
|
-
* @param {String=} opts.name route name
|
|
25
|
-
* @param {String=} opts.sensitive case sensitive (default: false)
|
|
26
|
-
* @param {String=} opts.strict require the trailing slash (default: false)
|
|
27
|
-
* @private
|
|
28
|
-
*/
|
|
29
|
-
constructor(path, methods, middlewares, opts) {
|
|
30
|
-
if (typeof opts === "string") opts = { name: opts };
|
|
31
|
-
this.opts = opts ?? {};
|
|
32
|
-
this.opts.prefix = this.opts.prefix ?? "";
|
|
33
|
-
this.name = this.opts.name;
|
|
34
|
-
this.stack = Array.isArray(middlewares) ? middlewares : [middlewares];
|
|
35
|
-
for (const method of methods) {
|
|
36
|
-
const l = this.methods.push(method.toUpperCase());
|
|
37
|
-
if (this.methods[l - 1] === "GET") this.methods.unshift("HEAD");
|
|
38
|
-
}
|
|
39
|
-
this.stack.forEach((fn) => {
|
|
40
|
-
const type = typeof fn;
|
|
41
|
-
if (type !== "function") throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: `middleware` must be a function, not `" + type + "`");
|
|
42
|
-
if (isGeneratorFunction(fn)) throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: Please use async function instead of generator function");
|
|
43
|
-
});
|
|
44
|
-
this.path = path;
|
|
45
|
-
this.regexp = pathToRegExp(path, this.paramNames, this.opts);
|
|
46
|
-
debug("defined route %s %s", this.methods, this.opts.prefix + this.path);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Returns whether request `path` matches route.
|
|
50
|
-
*
|
|
51
|
-
* @param {String} path path string
|
|
52
|
-
* @return {Boolean} matched or not
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
match(path) {
|
|
56
|
-
return this.regexp.test(path);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Returns map of URL parameters for given `path` and `paramNames`.
|
|
60
|
-
*
|
|
61
|
-
* @param {String} _path path string
|
|
62
|
-
* @param {Array.<String>} captures captures strings
|
|
63
|
-
* @param {Object=} [existingParams] existing params
|
|
64
|
-
* @return {Object} params object
|
|
65
|
-
* @private
|
|
66
|
-
*/
|
|
67
|
-
params(_path, captures, existingParams) {
|
|
68
|
-
const params = existingParams ?? {};
|
|
69
|
-
for (let len = captures.length, i = 0; i < len; i++) {
|
|
70
|
-
const paramName = this.paramNames[i];
|
|
71
|
-
if (paramName) {
|
|
72
|
-
const c = captures[i];
|
|
73
|
-
params[paramName.name] = c ? decodeURIComponent(c) : c;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return params;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Returns array of regexp url path captures.
|
|
80
|
-
*
|
|
81
|
-
* @param {String} path path string
|
|
82
|
-
* @return {Array.<String>} captures strings
|
|
83
|
-
* @private
|
|
84
|
-
*/
|
|
85
|
-
captures(path) {
|
|
86
|
-
if (this.opts.ignoreCaptures) return [];
|
|
87
|
-
const m = path.match(this.regexp);
|
|
88
|
-
return m ? m.slice(1) : [];
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Generate URL for route using given `params`.
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
*
|
|
95
|
-
* ```javascript
|
|
96
|
-
* var route = new Layer(['GET'], '/users/:id', fn);
|
|
97
|
-
*
|
|
98
|
-
* route.url(123); // => "/users/123"
|
|
99
|
-
* route.url('123'); // => "/users/123"
|
|
100
|
-
* route.url({ id: 123 }); // => "/users/123"
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* @param {Object} params url parameters
|
|
104
|
-
* @param {Object} paramsOrOptions optional parameters
|
|
105
|
-
* @return {String} url string
|
|
106
|
-
* @private
|
|
107
|
-
*/
|
|
108
|
-
url(params, ...paramsOrOptions) {
|
|
109
|
-
let args = params;
|
|
110
|
-
const url = this.path.replace(/\(\.\*\)/g, "");
|
|
111
|
-
const toPath = pathToRegExp.compile(url);
|
|
112
|
-
let options;
|
|
113
|
-
if (params !== void 0 && typeof params !== "object") {
|
|
114
|
-
args = [params, ...paramsOrOptions];
|
|
115
|
-
if (Array.isArray(args)) {
|
|
116
|
-
const lastIndex = args.length - 1;
|
|
117
|
-
if (typeof args[lastIndex] === "object") {
|
|
118
|
-
options = args[lastIndex];
|
|
119
|
-
args = args.slice(0, lastIndex);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
} else if (typeof params === "object") {
|
|
123
|
-
if (typeof paramsOrOptions[0] === "object" && "query" in paramsOrOptions[0]) options = paramsOrOptions[0];
|
|
124
|
-
}
|
|
125
|
-
const tokens = pathToRegExp.parse(url);
|
|
126
|
-
let replace = {};
|
|
127
|
-
if (Array.isArray(args)) for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
|
|
128
|
-
const token = tokens[i];
|
|
129
|
-
if (typeof token === "object" && token.name) replace[token.name] = args[j++];
|
|
130
|
-
}
|
|
131
|
-
else if (tokens.some((token) => typeof token === "object" && token.name)) replace = params;
|
|
132
|
-
else options = params;
|
|
133
|
-
const replaced = toPath(replace);
|
|
134
|
-
if (options?.query) {
|
|
135
|
-
const urlObject = new URI(replaced);
|
|
136
|
-
urlObject.search(options.query);
|
|
137
|
-
return urlObject.toString();
|
|
138
|
-
}
|
|
139
|
-
return replaced;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Run validations on route named parameters.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
*
|
|
146
|
-
* ```javascript
|
|
147
|
-
* router
|
|
148
|
-
* .param('user', function (id, ctx, next) {
|
|
149
|
-
* ctx.user = users[id];
|
|
150
|
-
* if (!user) return ctx.status = 404;
|
|
151
|
-
* next();
|
|
152
|
-
* })
|
|
153
|
-
* .get('/users/:user', function (ctx, next) {
|
|
154
|
-
* ctx.body = ctx.user;
|
|
155
|
-
* });
|
|
156
|
-
* ```
|
|
157
|
-
*
|
|
158
|
-
* @param {String} param param string
|
|
159
|
-
* @param {Function} fn middleware function
|
|
160
|
-
* @return {Layer} layer instance
|
|
161
|
-
* @private
|
|
162
|
-
*/
|
|
163
|
-
param(param, fn) {
|
|
164
|
-
const stack = this.stack;
|
|
165
|
-
const params = this.paramNames;
|
|
166
|
-
const middleware = function(ctx, next) {
|
|
167
|
-
return fn.call(this, ctx.params[param], ctx, next);
|
|
168
|
-
};
|
|
169
|
-
middleware.param = param;
|
|
170
|
-
const names = params.map((p) => {
|
|
171
|
-
return p.name;
|
|
172
|
-
});
|
|
173
|
-
const x = names.indexOf(param);
|
|
174
|
-
if (x > -1) stack.some(function(fn$1, i) {
|
|
175
|
-
if (!fn$1.param || names.indexOf(fn$1.param) > x) {
|
|
176
|
-
stack.splice(i, 0, middleware);
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
|
-
return false;
|
|
180
|
-
});
|
|
181
|
-
return this;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Prefix route path.
|
|
185
|
-
*
|
|
186
|
-
* @param {String} prefix prefix string
|
|
187
|
-
* @return {Layer} layer instance
|
|
188
|
-
* @private
|
|
189
|
-
*/
|
|
190
|
-
setPrefix(prefix) {
|
|
191
|
-
if (this.path) {
|
|
192
|
-
this.path = prefix + this.path;
|
|
193
|
-
this.paramNames = [];
|
|
194
|
-
this.regexp = pathToRegExp(this.path, this.paramNames, this.opts);
|
|
195
|
-
}
|
|
196
|
-
return this;
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
//#endregion
|
|
201
3
|
export { Layer };
|