@eggjs/router 2.0.1 → 3.0.1

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.
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EggRouter = void 0;
7
+ const node_assert_1 = __importDefault(require("node:assert"));
8
+ const utility_1 = require("utility");
9
+ const inflection_1 = __importDefault(require("inflection"));
10
+ const methods_1 = __importDefault(require("methods"));
11
+ const Router_js_1 = require("./Router.js");
12
+ const REST_MAP = {
13
+ index: {
14
+ suffix: '',
15
+ method: 'GET',
16
+ },
17
+ new: {
18
+ namePrefix: 'new_',
19
+ member: true,
20
+ suffix: 'new',
21
+ method: 'GET',
22
+ },
23
+ create: {
24
+ suffix: '',
25
+ method: 'POST',
26
+ },
27
+ show: {
28
+ member: true,
29
+ suffix: ':id',
30
+ method: 'GET',
31
+ },
32
+ edit: {
33
+ member: true,
34
+ namePrefix: 'edit_',
35
+ suffix: ':id/edit',
36
+ method: 'GET',
37
+ },
38
+ update: {
39
+ member: true,
40
+ namePrefix: '',
41
+ suffix: ':id',
42
+ method: ['PATCH', 'PUT'],
43
+ },
44
+ destroy: {
45
+ member: true,
46
+ namePrefix: 'destroy_',
47
+ suffix: ':id',
48
+ method: 'DELETE',
49
+ },
50
+ };
51
+ /**
52
+ * FIXME: move these patch into @eggjs/router
53
+ */
54
+ class EggRouter extends Router_js_1.Router {
55
+ app;
56
+ /**
57
+ * @class
58
+ * @param {Object} opts - Router options.
59
+ * @param {Application} app - Application object.
60
+ */
61
+ constructor(opts, app) {
62
+ super(opts);
63
+ this.app = app;
64
+ }
65
+ verb(method, nameOrPath, pathOrMiddleware, ...middleware) {
66
+ const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware);
67
+ if (typeof method === 'string') {
68
+ method = [method];
69
+ }
70
+ this.register(path, method, middlewares, options);
71
+ return this;
72
+ }
73
+ head(nameOrPath, pathOrMiddleware, ...middlewares) {
74
+ return this.verb('head', nameOrPath, pathOrMiddleware, ...middlewares);
75
+ }
76
+ options(nameOrPath, pathOrMiddleware, ...middlewares) {
77
+ return this.verb('options', nameOrPath, pathOrMiddleware, ...middlewares);
78
+ }
79
+ get(nameOrPath, pathOrMiddleware, ...middlewares) {
80
+ return this.verb('get', nameOrPath, pathOrMiddleware, ...middlewares);
81
+ }
82
+ put(nameOrPath, pathOrMiddleware, ...middlewares) {
83
+ return this.verb('put', nameOrPath, pathOrMiddleware, ...middlewares);
84
+ }
85
+ patch(nameOrPath, pathOrMiddleware, ...middlewares) {
86
+ return this.verb('patch', nameOrPath, pathOrMiddleware, ...middlewares);
87
+ }
88
+ post(nameOrPath, pathOrMiddleware, ...middlewares) {
89
+ return this.verb('post', nameOrPath, pathOrMiddleware, ...middlewares);
90
+ }
91
+ delete(nameOrPath, pathOrMiddleware, ...middlewares) {
92
+ return this.verb('delete', nameOrPath, pathOrMiddleware, ...middlewares);
93
+ }
94
+ all(nameOrPath, pathOrMiddleware, ...middlewares) {
95
+ return this.verb(methods_1.default, nameOrPath, pathOrMiddleware, ...middlewares);
96
+ }
97
+ register(path, methods, middleware, opts) {
98
+ // patch register to support generator function middleware and string controller
99
+ middleware = Array.isArray(middleware) ? middleware : [middleware];
100
+ const middlewares = convertMiddlewares(middleware, this.app);
101
+ return super.register(path, methods, middlewares, opts);
102
+ }
103
+ resources(nameOrPath, pathOrMiddleware, ...middleware) {
104
+ const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware);
105
+ // last argument is Controller object
106
+ const controller = resolveController(middlewares.pop(), this.app);
107
+ for (const key in REST_MAP) {
108
+ const action = controller[key];
109
+ if (!action)
110
+ continue;
111
+ const opts = REST_MAP[key];
112
+ let routeName;
113
+ if (opts.member) {
114
+ routeName = inflection_1.default.singularize(options.name ?? '');
115
+ }
116
+ else {
117
+ routeName = inflection_1.default.pluralize(options.name ?? '');
118
+ }
119
+ if (opts.namePrefix) {
120
+ routeName = opts.namePrefix + routeName;
121
+ }
122
+ const prefix = path.replace(/\/$/, '');
123
+ const urlPath = opts.suffix ? `${prefix}/${opts.suffix}` : prefix;
124
+ const method = Array.isArray(opts.method) ? opts.method : [opts.method];
125
+ this.register(urlPath, method, middlewares.concat(action), { name: routeName });
126
+ }
127
+ return this;
128
+ }
129
+ /**
130
+ * @param {String} name - Router name
131
+ * @param {Object} params - more parameters
132
+ * @example
133
+ * ```js
134
+ * router.url('edit_post', { id: 1, name: 'foo', page: 2 })
135
+ * => /posts/1/edit?name=foo&page=2
136
+ * router.url('posts', { name: 'foo&1', page: 2 })
137
+ * => /posts?name=foo%261&page=2
138
+ * ```
139
+ * @return {String} url by path name and query params.
140
+ * @since 1.0.0
141
+ */
142
+ url(name, params) {
143
+ const route = this.route(name);
144
+ if (!route)
145
+ return '';
146
+ const args = params;
147
+ let url = route.path;
148
+ (0, node_assert_1.default)(!(url instanceof RegExp), `Can't get the url for regExp ${url} for by name '${name}'`);
149
+ const queries = [];
150
+ if (typeof args === 'object' && args !== null) {
151
+ const replacedParams = [];
152
+ url = url.replace(/:([a-zA-Z_]\w*)/g, ($0, key) => {
153
+ if (key in args) {
154
+ const values = args[key];
155
+ replacedParams.push(key);
156
+ return (0, utility_1.encodeURIComponent)(Array.isArray(values) ? String(values[0]) : String(values));
157
+ }
158
+ return $0;
159
+ });
160
+ for (const key in args) {
161
+ if (replacedParams.includes(key)) {
162
+ continue;
163
+ }
164
+ const values = args[key];
165
+ const encodedKey = (0, utility_1.encodeURIComponent)(key);
166
+ if (Array.isArray(values)) {
167
+ for (const val of values) {
168
+ queries.push(`${encodedKey}=${(0, utility_1.encodeURIComponent)(String(val))}`);
169
+ }
170
+ }
171
+ else {
172
+ queries.push(`${encodedKey}=${(0, utility_1.encodeURIComponent)(String(values))}`);
173
+ }
174
+ }
175
+ }
176
+ if (queries.length > 0) {
177
+ const queryStr = queries.join('&');
178
+ if (!url.includes('?')) {
179
+ url = `${url}?${queryStr}`;
180
+ }
181
+ else {
182
+ url = `${url}&${queryStr}`;
183
+ }
184
+ }
185
+ return url;
186
+ }
187
+ /**
188
+ * @alias to url()
189
+ */
190
+ pathFor(name, params) {
191
+ return this.url(name, params);
192
+ }
193
+ }
194
+ exports.EggRouter = EggRouter;
195
+ /**
196
+ * resolve controller from string to function
197
+ * @param {String|Function} controller input controller
198
+ * @param {Application} app egg application instance
199
+ */
200
+ function resolveController(controller, app) {
201
+ if (typeof controller === 'string') {
202
+ // resolveController('foo.bar.Home', app)
203
+ const actions = controller.split('.');
204
+ let obj = app.controller;
205
+ actions.forEach(key => {
206
+ obj = obj[key];
207
+ if (!obj)
208
+ throw new Error(`app.controller.${controller} not exists`);
209
+ });
210
+ controller = obj;
211
+ }
212
+ // ensure controller is exists
213
+ if (!controller)
214
+ throw new Error('controller not exists');
215
+ return controller;
216
+ }
217
+ /**
218
+ * 1. ensure controller(last argument) support string
219
+ * - [url, controller]: app.get('/home', 'home');
220
+ * - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list');
221
+ * - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list);
222
+ * - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index');
223
+ * - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');`
224
+ *
225
+ * 2. make middleware support generator function
226
+ *
227
+ * @param {Array} middlewares middlewares and controller(last middleware)
228
+ * @param {Application} app egg application instance
229
+ */
230
+ function convertMiddlewares(middlewares, app) {
231
+ // ensure controller is resolved
232
+ const controller = resolveController(middlewares.pop(), app);
233
+ return [...middlewares, controller];
234
+ }
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWdnUm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL0VnZ1JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSw4REFBaUM7QUFDakMscUNBQXVFO0FBQ3ZFLDREQUFvQztBQUNwQyxzREFBOEI7QUFDOUIsMkNBQW1GO0FBVW5GLE1BQU0sUUFBUSxHQUFtQztJQUMvQyxLQUFLLEVBQUU7UUFDTCxNQUFNLEVBQUUsRUFBRTtRQUNWLE1BQU0sRUFBRSxLQUFLO0tBQ2Q7SUFDRCxHQUFHLEVBQUU7UUFDSCxVQUFVLEVBQUUsTUFBTTtRQUNsQixNQUFNLEVBQUUsSUFBSTtRQUNaLE1BQU0sRUFBRSxLQUFLO1FBQ2IsTUFBTSxFQUFFLEtBQUs7S0FDZDtJQUNELE1BQU0sRUFBRTtRQUNOLE1BQU0sRUFBRSxFQUFFO1FBQ1YsTUFBTSxFQUFFLE1BQU07S0FDZjtJQUNELElBQUksRUFBRTtRQUNKLE1BQU0sRUFBRSxJQUFJO1FBQ1osTUFBTSxFQUFFLEtBQUs7UUFDYixNQUFNLEVBQUUsS0FBSztLQUNkO0lBQ0QsSUFBSSxFQUFFO1FBQ0osTUFBTSxFQUFFLElBQUk7UUFDWixVQUFVLEVBQUUsT0FBTztRQUNuQixNQUFNLEVBQUUsVUFBVTtRQUNsQixNQUFNLEVBQUUsS0FBSztLQUNkO0lBQ0QsTUFBTSxFQUFFO1FBQ04sTUFBTSxFQUFFLElBQUk7UUFDWixVQUFVLEVBQUUsRUFBRTtRQUNkLE1BQU0sRUFBRSxLQUFLO1FBQ2IsTUFBTSxFQUFFLENBQUUsT0FBTyxFQUFFLEtBQUssQ0FBRTtLQUMzQjtJQUNELE9BQU8sRUFBRTtRQUNQLE1BQU0sRUFBRSxJQUFJO1FBQ1osVUFBVSxFQUFFLFVBQVU7UUFDdEIsTUFBTSxFQUFFLEtBQUs7UUFDYixNQUFNLEVBQUUsUUFBUTtLQUNqQjtDQUNGLENBQUM7QUFNRjs7R0FFRztBQUNILE1BQWEsU0FBVSxTQUFRLGtCQUFNO0lBQzFCLEdBQUcsQ0FBYztJQUUxQjs7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
@@ -0,0 +1,114 @@
1
+ import { type Key } from 'path-to-regexp';
2
+ import type { MiddlewareFunc, MiddlewareFuncWithParamProperty, ParamMiddlewareFunc } from './types.js';
3
+ export interface LayerOptions {
4
+ prefix?: string;
5
+ /** route name */
6
+ name?: string;
7
+ /** case sensitive (default: false) */
8
+ sensitive?: boolean;
9
+ /** require the trailing slash (default: false) */
10
+ strict?: boolean;
11
+ ignoreCaptures?: boolean;
12
+ end?: boolean;
13
+ }
14
+ export interface LayerURLOptions {
15
+ query?: string | object;
16
+ }
17
+ export declare class Layer {
18
+ readonly opts: LayerOptions;
19
+ readonly name?: string;
20
+ readonly methods: string[];
21
+ readonly stack: MiddlewareFuncWithParamProperty[];
22
+ path: string | RegExp;
23
+ regexp: RegExp;
24
+ paramNames: Key[];
25
+ /**
26
+ * Initialize a new routing Layer with given `method`, `path`, and `middleware`.
27
+ *
28
+ * @param {String|RegExp} path Path string or regular expression.
29
+ * @param {Array} methods Array of HTTP verbs.
30
+ * @param {Array|Function} middlewares Layer callback/middleware or series of.
31
+ * @param {Object=} opts optional params
32
+ * @param {String=} opts.name route name
33
+ * @param {String=} opts.sensitive case sensitive (default: false)
34
+ * @param {String=} opts.strict require the trailing slash (default: false)
35
+ * @private
36
+ */
37
+ constructor(path: string | RegExp, methods: string[], middlewares: MiddlewareFunc | MiddlewareFunc[], opts?: LayerOptions | string);
38
+ /**
39
+ * Returns whether request `path` matches route.
40
+ *
41
+ * @param {String} path path string
42
+ * @return {Boolean} matched or not
43
+ * @private
44
+ */
45
+ match(path: string): boolean;
46
+ /**
47
+ * Returns map of URL parameters for given `path` and `paramNames`.
48
+ *
49
+ * @param {String} _path path string
50
+ * @param {Array.<String>} captures captures strings
51
+ * @param {Object=} [existingParams] existing params
52
+ * @return {Object} params object
53
+ * @private
54
+ */
55
+ params(_path: string, captures: Array<string>, existingParams?: Record<string, string>): Record<string, string>;
56
+ /**
57
+ * Returns array of regexp url path captures.
58
+ *
59
+ * @param {String} path path string
60
+ * @return {Array.<String>} captures strings
61
+ * @private
62
+ */
63
+ captures(path: string): Array<string>;
64
+ /**
65
+ * Generate URL for route using given `params`.
66
+ *
67
+ * @example
68
+ *
69
+ * ```javascript
70
+ * var route = new Layer(['GET'], '/users/:id', fn);
71
+ *
72
+ * route.url(123); // => "/users/123"
73
+ * route.url('123'); // => "/users/123"
74
+ * route.url({ id: 123 }); // => "/users/123"
75
+ * ```
76
+ *
77
+ * @param {Object} params url parameters
78
+ * @param {Object} paramsOrOptions optional parameters
79
+ * @return {String} url string
80
+ * @private
81
+ */
82
+ url(params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string;
83
+ /**
84
+ * Run validations on route named parameters.
85
+ *
86
+ * @example
87
+ *
88
+ * ```javascript
89
+ * router
90
+ * .param('user', function (id, ctx, next) {
91
+ * ctx.user = users[id];
92
+ * if (!user) return ctx.status = 404;
93
+ * next();
94
+ * })
95
+ * .get('/users/:user', function (ctx, next) {
96
+ * ctx.body = ctx.user;
97
+ * });
98
+ * ```
99
+ *
100
+ * @param {String} param param string
101
+ * @param {Function} fn middleware function
102
+ * @return {Layer} layer instance
103
+ * @private
104
+ */
105
+ param(param: string, fn: ParamMiddlewareFunc): Layer;
106
+ /**
107
+ * Prefix route path.
108
+ *
109
+ * @param {String} prefix prefix string
110
+ * @return {Layer} layer instance
111
+ * @private
112
+ */
113
+ setPrefix(prefix: string): Layer;
114
+ }
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Layer = void 0;
7
+ const node_util_1 = require("node:util");
8
+ const path_to_regexp_1 = __importDefault(require("path-to-regexp"));
9
+ const urijs_1 = __importDefault(require("urijs"));
10
+ const utility_1 = require("utility");
11
+ const is_type_of_1 = require("is-type-of");
12
+ const debug = (0, node_util_1.debuglog)('egg-router:layer');
13
+ class Layer {
14
+ opts;
15
+ name;
16
+ methods = [];
17
+ stack;
18
+ path;
19
+ regexp;
20
+ paramNames = [];
21
+ /**
22
+ * Initialize a new routing Layer with given `method`, `path`, and `middleware`.
23
+ *
24
+ * @param {String|RegExp} path Path string or regular expression.
25
+ * @param {Array} methods Array of HTTP verbs.
26
+ * @param {Array|Function} middlewares Layer callback/middleware or series of.
27
+ * @param {Object=} opts optional params
28
+ * @param {String=} opts.name route name
29
+ * @param {String=} opts.sensitive case sensitive (default: false)
30
+ * @param {String=} opts.strict require the trailing slash (default: false)
31
+ * @private
32
+ */
33
+ constructor(path, methods, middlewares, opts) {
34
+ if (typeof opts === 'string') {
35
+ // new Layer(path, methods, middlewares, name);
36
+ opts = { name: opts };
37
+ }
38
+ this.opts = opts ?? {};
39
+ this.opts.prefix = this.opts.prefix ?? '';
40
+ this.name = this.opts.name;
41
+ this.stack = Array.isArray(middlewares) ? middlewares : [middlewares];
42
+ for (const method of methods) {
43
+ const l = this.methods.push(method.toUpperCase());
44
+ if (this.methods[l - 1] === 'GET') {
45
+ this.methods.unshift('HEAD');
46
+ }
47
+ }
48
+ // ensure middleware is a function
49
+ this.stack.forEach(fn => {
50
+ const type = typeof fn;
51
+ if (type !== 'function') {
52
+ throw new TypeError(methods.toString() + ' `' + (this.opts.name || path) + '`: `middleware` '
53
+ + 'must be a function, not `' + type + '`');
54
+ }
55
+ if ((0, is_type_of_1.isGeneratorFunction)(fn)) {
56
+ throw new TypeError(methods.toString() + ' `' + (this.opts.name || path) + '`: Please use async function instead of generator function');
57
+ }
58
+ });
59
+ this.path = path;
60
+ this.regexp = (0, path_to_regexp_1.default)(path, this.paramNames, this.opts);
61
+ debug('defined route %s %s', this.methods, this.opts.prefix + this.path);
62
+ }
63
+ /**
64
+ * Returns whether request `path` matches route.
65
+ *
66
+ * @param {String} path path string
67
+ * @return {Boolean} matched or not
68
+ * @private
69
+ */
70
+ match(path) {
71
+ return this.regexp.test(path);
72
+ }
73
+ /**
74
+ * Returns map of URL parameters for given `path` and `paramNames`.
75
+ *
76
+ * @param {String} _path path string
77
+ * @param {Array.<String>} captures captures strings
78
+ * @param {Object=} [existingParams] existing params
79
+ * @return {Object} params object
80
+ * @private
81
+ */
82
+ params(_path, captures, existingParams) {
83
+ const params = existingParams ?? {};
84
+ for (let len = captures.length, i = 0; i < len; i++) {
85
+ const paramName = this.paramNames[i];
86
+ if (paramName) {
87
+ const c = captures[i];
88
+ params[paramName.name] = c ? (0, utility_1.decodeURIComponent)(c) : c;
89
+ }
90
+ }
91
+ return params;
92
+ }
93
+ /**
94
+ * Returns array of regexp url path captures.
95
+ *
96
+ * @param {String} path path string
97
+ * @return {Array.<String>} captures strings
98
+ * @private
99
+ */
100
+ captures(path) {
101
+ if (this.opts.ignoreCaptures)
102
+ return [];
103
+ const m = path.match(this.regexp);
104
+ return m ? m.slice(1) : [];
105
+ }
106
+ /**
107
+ * Generate URL for route using given `params`.
108
+ *
109
+ * @example
110
+ *
111
+ * ```javascript
112
+ * var route = new Layer(['GET'], '/users/:id', fn);
113
+ *
114
+ * route.url(123); // => "/users/123"
115
+ * route.url('123'); // => "/users/123"
116
+ * route.url({ id: 123 }); // => "/users/123"
117
+ * ```
118
+ *
119
+ * @param {Object} params url parameters
120
+ * @param {Object} paramsOrOptions optional parameters
121
+ * @return {String} url string
122
+ * @private
123
+ */
124
+ url(params, ...paramsOrOptions) {
125
+ let args = params;
126
+ const url = this.path.replace(/\(\.\*\)/g, '');
127
+ const toPath = path_to_regexp_1.default.compile(url);
128
+ let options;
129
+ if (params !== undefined && typeof params !== 'object') {
130
+ args = [params, ...paramsOrOptions];
131
+ // route.url(stringOrNumber, params1, ..., options);
132
+ if (Array.isArray(args)) {
133
+ const lastIndex = args.length - 1;
134
+ if (typeof args[lastIndex] === 'object') {
135
+ options = args[lastIndex];
136
+ args = args.slice(0, lastIndex);
137
+ }
138
+ }
139
+ }
140
+ else if (typeof params === 'object') {
141
+ if (typeof paramsOrOptions[0] === 'object' && 'query' in paramsOrOptions[0]) {
142
+ // route.url(param, options);
143
+ options = paramsOrOptions[0];
144
+ }
145
+ }
146
+ const tokens = path_to_regexp_1.default.parse(url);
147
+ let replace = {};
148
+ if (Array.isArray(args)) {
149
+ for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
150
+ const token = tokens[i];
151
+ if (typeof token === 'object' && token.name) {
152
+ replace[token.name] = args[j++];
153
+ }
154
+ }
155
+ }
156
+ else if (tokens.some(token => typeof token === 'object' && token.name)) {
157
+ // route.url(params);
158
+ replace = params;
159
+ }
160
+ else {
161
+ // route.url(options);
162
+ options = params;
163
+ }
164
+ const replaced = toPath(replace);
165
+ if (options?.query) {
166
+ const urlObject = new urijs_1.default(replaced);
167
+ urlObject.search(options.query);
168
+ return urlObject.toString();
169
+ }
170
+ return replaced;
171
+ }
172
+ /**
173
+ * Run validations on route named parameters.
174
+ *
175
+ * @example
176
+ *
177
+ * ```javascript
178
+ * router
179
+ * .param('user', function (id, ctx, next) {
180
+ * ctx.user = users[id];
181
+ * if (!user) return ctx.status = 404;
182
+ * next();
183
+ * })
184
+ * .get('/users/:user', function (ctx, next) {
185
+ * ctx.body = ctx.user;
186
+ * });
187
+ * ```
188
+ *
189
+ * @param {String} param param string
190
+ * @param {Function} fn middleware function
191
+ * @return {Layer} layer instance
192
+ * @private
193
+ */
194
+ param(param, fn) {
195
+ const stack = this.stack;
196
+ const params = this.paramNames;
197
+ const middleware = function (ctx, next) {
198
+ return fn.call(this, ctx.params[param], ctx, next);
199
+ };
200
+ middleware.param = param;
201
+ const names = params.map(p => {
202
+ return p.name;
203
+ });
204
+ const x = names.indexOf(param);
205
+ if (x > -1) {
206
+ // iterate through the stack, to figure out where to place the handler fn
207
+ stack.some(function (fn, i) {
208
+ // param handlers are always first, so when we find an fn w/o a param property, stop here
209
+ // if the param handler at this part of the stack comes after the one we are adding, stop here
210
+ if (!fn.param || names.indexOf(fn.param) > x) {
211
+ // inject this param handler right before the current item
212
+ stack.splice(i, 0, middleware);
213
+ return true; // then break the loop
214
+ }
215
+ return false;
216
+ });
217
+ }
218
+ return this;
219
+ }
220
+ /**
221
+ * Prefix route path.
222
+ *
223
+ * @param {String} prefix prefix string
224
+ * @return {Layer} layer instance
225
+ * @private
226
+ */
227
+ setPrefix(prefix) {
228
+ if (this.path) {
229
+ this.path = prefix + this.path;
230
+ this.paramNames = [];
231
+ this.regexp = (0, path_to_regexp_1.default)(this.path, this.paramNames, this.opts);
232
+ }
233
+ return this;
234
+ }
235
+ }
236
+ exports.Layer = Layer;
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvTGF5ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEseUNBQXFDO0FBQ3JDLG9FQUF3RDtBQUN4RCxrREFBd0I7QUFDeEIscUNBQXVFO0FBQ3ZFLDJDQUFpRDtBQU9qRCxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFRLEVBQUMsa0JBQWtCLENBQUMsQ0FBQztBQWtCM0MsTUFBYSxLQUFLO0lBQ1AsSUFBSSxDQUFlO0lBQ25CLElBQUksQ0FBVTtJQUNkLE9BQU8sR0FBYSxFQUFFLENBQUM7SUFDdkIsS0FBSyxDQUFvQztJQUNsRCxJQUFJLENBQWtCO0lBQ3RCLE1BQU0sQ0FBUztJQUNmLFVBQVUsR0FBVSxFQUFFLENBQUM7SUFFdkI7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxZQUFZLElBQXFCLEVBQUUsT0FBaUIsRUFBRSxXQUE4QyxFQUNsRyxJQUE0QjtRQUM1QixJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzdCLCtDQUErQztZQUMvQyxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDeEIsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBRSxXQUFXLENBQUUsQ0FBQztRQUV4RSxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzdCLE1BQU0sQ0FB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