@adonisjs/http-server 8.0.0-next.8 → 8.0.0-next.9
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/build/chunk-CVZAIRWJ.js +1222 -0
- package/build/{chunk-W6WKITGF.js → chunk-JD6QW4NQ.js} +251 -1309
- package/build/factories/main.js +2 -2
- package/build/index.d.ts +1 -0
- package/build/index.js +10 -7
- package/build/src/helpers.d.ts +19 -0
- package/build/src/helpers.js +3 -1
- package/package.json +4 -4
- package/build/chunk-NQNHMINZ.js +0 -135
|
@@ -0,0 +1,1222 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/helpers.ts
|
|
8
|
+
import cookie from "cookie";
|
|
9
|
+
import matchit from "@poppinss/matchit";
|
|
10
|
+
import string3 from "@poppinss/utils/string";
|
|
11
|
+
import { parseBindingReference } from "@adonisjs/fold";
|
|
12
|
+
|
|
13
|
+
// src/utils.ts
|
|
14
|
+
import Cache from "tmp-cache";
|
|
15
|
+
import { InvalidArgumentsException } from "@poppinss/utils/exception";
|
|
16
|
+
|
|
17
|
+
// src/router/group.ts
|
|
18
|
+
import Macroable4 from "@poppinss/macroable";
|
|
19
|
+
|
|
20
|
+
// src/router/brisk.ts
|
|
21
|
+
import Macroable2 from "@poppinss/macroable";
|
|
22
|
+
|
|
23
|
+
// src/router/route.ts
|
|
24
|
+
import is from "@sindresorhus/is";
|
|
25
|
+
import Macroable from "@poppinss/macroable";
|
|
26
|
+
import Middleware from "@poppinss/middleware";
|
|
27
|
+
import { RuntimeException } from "@poppinss/utils/exception";
|
|
28
|
+
import { moduleCaller, moduleImporter } from "@adonisjs/fold";
|
|
29
|
+
|
|
30
|
+
// src/debug.ts
|
|
31
|
+
import { debuglog } from "util";
|
|
32
|
+
var debug_default = debuglog("adonisjs:http");
|
|
33
|
+
|
|
34
|
+
// src/router/factories/use_return_value.ts
|
|
35
|
+
function canWriteResponseBody(value, ctx) {
|
|
36
|
+
return value !== void 0 && // Return value is explicitly defined
|
|
37
|
+
!ctx.response.hasLazyBody && // Lazy body is not set
|
|
38
|
+
value !== ctx.response;
|
|
39
|
+
}
|
|
40
|
+
function useReturnValue(ctx) {
|
|
41
|
+
return function(value) {
|
|
42
|
+
if (canWriteResponseBody(value, ctx)) {
|
|
43
|
+
ctx.response.send(value);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/tracing_channels.ts
|
|
49
|
+
var tracing_channels_exports = {};
|
|
50
|
+
__export(tracing_channels_exports, {
|
|
51
|
+
httpExceptionHandler: () => httpExceptionHandler,
|
|
52
|
+
httpMiddleware: () => httpMiddleware,
|
|
53
|
+
httpRequest: () => httpRequest,
|
|
54
|
+
httpResponseSerializer: () => httpResponseSerializer,
|
|
55
|
+
httpRouteHandler: () => httpRouteHandler
|
|
56
|
+
});
|
|
57
|
+
import diagnostics_channel from "diagnostics_channel";
|
|
58
|
+
var httpRequest = diagnostics_channel.tracingChannel("adonisjs.http.request");
|
|
59
|
+
var httpMiddleware = diagnostics_channel.tracingChannel("adonisjs.http.middleware");
|
|
60
|
+
var httpExceptionHandler = diagnostics_channel.tracingChannel(
|
|
61
|
+
"adonisjs.http.exception.handler"
|
|
62
|
+
);
|
|
63
|
+
var httpRouteHandler = diagnostics_channel.tracingChannel("adonisjs.http.route.handler");
|
|
64
|
+
var httpResponseSerializer = diagnostics_channel.tracingChannel(
|
|
65
|
+
"adonisjs.http.response.serializer"
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// src/router/executor.ts
|
|
69
|
+
function execute(route, resolver, ctx, errorResponder) {
|
|
70
|
+
return route.middleware.runner().errorHandler((error) => errorResponder(error, ctx)).finalHandler(() => {
|
|
71
|
+
if (typeof route.handler === "function") {
|
|
72
|
+
return httpRouteHandler.tracePromise(
|
|
73
|
+
($ctx) => Promise.resolve(route.handler($ctx)),
|
|
74
|
+
httpRouteHandler.hasSubscribers ? { route } : void 0,
|
|
75
|
+
void 0,
|
|
76
|
+
ctx
|
|
77
|
+
).then(useReturnValue(ctx));
|
|
78
|
+
}
|
|
79
|
+
return httpRouteHandler.tracePromise(
|
|
80
|
+
route.handler.handle,
|
|
81
|
+
httpRouteHandler.hasSubscribers ? { route } : void 0,
|
|
82
|
+
void 0,
|
|
83
|
+
resolver,
|
|
84
|
+
ctx
|
|
85
|
+
).then(useReturnValue(ctx));
|
|
86
|
+
}).run(async (middleware, next) => {
|
|
87
|
+
if (typeof middleware === "function") {
|
|
88
|
+
return httpMiddleware.tracePromise(
|
|
89
|
+
middleware,
|
|
90
|
+
httpMiddleware.hasSubscribers ? { middleware } : void 0,
|
|
91
|
+
void 0,
|
|
92
|
+
ctx,
|
|
93
|
+
next
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return httpMiddleware.tracePromise(
|
|
97
|
+
middleware.handle,
|
|
98
|
+
httpMiddleware.hasSubscribers ? { middleware } : void 0,
|
|
99
|
+
void 0,
|
|
100
|
+
resolver,
|
|
101
|
+
ctx,
|
|
102
|
+
next,
|
|
103
|
+
middleware.args
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/router/route.ts
|
|
109
|
+
import StringBuilder from "@poppinss/utils/string_builder";
|
|
110
|
+
import string from "@poppinss/utils/string";
|
|
111
|
+
var Route = class extends Macroable {
|
|
112
|
+
/**
|
|
113
|
+
* Route pattern
|
|
114
|
+
*/
|
|
115
|
+
#pattern;
|
|
116
|
+
/**
|
|
117
|
+
* HTTP Methods for the route
|
|
118
|
+
*/
|
|
119
|
+
#methods;
|
|
120
|
+
/**
|
|
121
|
+
* A unique name for the route
|
|
122
|
+
*/
|
|
123
|
+
#name;
|
|
124
|
+
/**
|
|
125
|
+
* A boolean to prevent route from getting registered within
|
|
126
|
+
* the store.
|
|
127
|
+
*
|
|
128
|
+
* This flag must be set before "Router.commit" method
|
|
129
|
+
*/
|
|
130
|
+
#isDeleted = false;
|
|
131
|
+
/**
|
|
132
|
+
* Route handler
|
|
133
|
+
*/
|
|
134
|
+
#handler;
|
|
135
|
+
/**
|
|
136
|
+
* Matchers inherited from the router
|
|
137
|
+
*/
|
|
138
|
+
#globalMatchers;
|
|
139
|
+
/**
|
|
140
|
+
* Reference to the AdonisJS application
|
|
141
|
+
*/
|
|
142
|
+
#app;
|
|
143
|
+
/**
|
|
144
|
+
* Middleware registered on the router
|
|
145
|
+
*/
|
|
146
|
+
#routerMiddleware;
|
|
147
|
+
/**
|
|
148
|
+
* By default the route is part of the `root` domain. Root domain is used
|
|
149
|
+
* when no domain is defined
|
|
150
|
+
*/
|
|
151
|
+
#routeDomain = "root";
|
|
152
|
+
/**
|
|
153
|
+
* An object of matchers to be forwarded to the store. The matchers
|
|
154
|
+
* list is populated by calling `where` method
|
|
155
|
+
*/
|
|
156
|
+
#matchers = {};
|
|
157
|
+
/**
|
|
158
|
+
* Custom prefixes defined on the route or the route parent
|
|
159
|
+
* groups
|
|
160
|
+
*/
|
|
161
|
+
#prefixes = [];
|
|
162
|
+
/**
|
|
163
|
+
* Middleware defined directly on the route or the route parent
|
|
164
|
+
* routes. We mantain an array for each layer of the stack
|
|
165
|
+
*/
|
|
166
|
+
#middleware = [];
|
|
167
|
+
/**
|
|
168
|
+
* Creates a new Route instance
|
|
169
|
+
* @param app - The AdonisJS application instance
|
|
170
|
+
* @param routerMiddleware - Array of global middleware registered on the router
|
|
171
|
+
* @param options - Configuration options for the route
|
|
172
|
+
*/
|
|
173
|
+
constructor(app, routerMiddleware, options) {
|
|
174
|
+
super();
|
|
175
|
+
this.#app = app;
|
|
176
|
+
this.#routerMiddleware = routerMiddleware;
|
|
177
|
+
this.#pattern = options.pattern;
|
|
178
|
+
this.#methods = options.methods;
|
|
179
|
+
this.#globalMatchers = options.globalMatchers;
|
|
180
|
+
const { handler, routeName } = this.#resolveRouteHandle(options.handler);
|
|
181
|
+
this.#handler = handler;
|
|
182
|
+
this.#name = routeName;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Resolves the route handler string expression to a
|
|
186
|
+
* handler method object
|
|
187
|
+
*/
|
|
188
|
+
#resolveRouteHandle(handler) {
|
|
189
|
+
if (typeof handler === "string") {
|
|
190
|
+
const parts = handler.split(".");
|
|
191
|
+
const method = parts.length === 1 ? "handle" : parts.pop();
|
|
192
|
+
const moduleRefId = parts.join(".");
|
|
193
|
+
return {
|
|
194
|
+
handler: {
|
|
195
|
+
method,
|
|
196
|
+
reference: handler,
|
|
197
|
+
importExpression: moduleRefId,
|
|
198
|
+
...moduleImporter(() => this.#app.import(moduleRefId), method).toHandleMethod(),
|
|
199
|
+
name: handler
|
|
200
|
+
},
|
|
201
|
+
routeName: `${new StringBuilder(moduleRefId.split("/").pop()).removeSuffix("controller").snakeCase()}.${string.snakeCase(method)}`
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (Array.isArray(handler)) {
|
|
205
|
+
const controller = handler[0];
|
|
206
|
+
const method = handler[1] ?? "handle";
|
|
207
|
+
if (is.class(controller)) {
|
|
208
|
+
return {
|
|
209
|
+
handler: {
|
|
210
|
+
method,
|
|
211
|
+
reference: handler,
|
|
212
|
+
importExpression: null,
|
|
213
|
+
...moduleCaller(controller, method).toHandleMethod()
|
|
214
|
+
},
|
|
215
|
+
routeName: `${new StringBuilder(controller.name).removeSuffix("controller").snakeCase()}.${string.snakeCase(method)}`
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
handler: {
|
|
220
|
+
method,
|
|
221
|
+
reference: handler,
|
|
222
|
+
importExpression: String(controller),
|
|
223
|
+
...moduleImporter(controller, method).toHandleMethod()
|
|
224
|
+
},
|
|
225
|
+
routeName: controller.name ? `${new StringBuilder(controller.name).removeSuffix("controller").snakeCase()}.${string.snakeCase(method)}` : void 0
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return { handler };
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns an object of param matchers by merging global and local
|
|
232
|
+
* matchers. The local copy is given preference over the global
|
|
233
|
+
* one's
|
|
234
|
+
*/
|
|
235
|
+
#getMatchers() {
|
|
236
|
+
return { ...this.#globalMatchers, ...this.#matchers };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Returns a normalized pattern string by prefixing the `prefix` (if defined).
|
|
240
|
+
*/
|
|
241
|
+
#computePattern() {
|
|
242
|
+
const pattern = dropSlash(this.#pattern);
|
|
243
|
+
const prefix = this.#prefixes.slice().reverse().map((one) => dropSlash(one)).join("");
|
|
244
|
+
return prefix ? `${prefix}${pattern === "/" ? "" : pattern}` : pattern;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Define matcher for a given param. If a matcher exists, then we do not
|
|
248
|
+
* override that, since the routes inside a group will set matchers
|
|
249
|
+
* before the group, so they should have priority over the group
|
|
250
|
+
* matchers.
|
|
251
|
+
*
|
|
252
|
+
* ```ts
|
|
253
|
+
* Route.group(() => {
|
|
254
|
+
* Route.get('/:id', 'handler').where('id', /^[0-9]$/)
|
|
255
|
+
* }).where('id', /[^a-z$]/)
|
|
256
|
+
* ```
|
|
257
|
+
*
|
|
258
|
+
* The `/^[0-9]$/` will win over the matcher defined by the group
|
|
259
|
+
*/
|
|
260
|
+
where(param, matcher) {
|
|
261
|
+
if (this.#matchers[param]) {
|
|
262
|
+
return this;
|
|
263
|
+
}
|
|
264
|
+
if (typeof matcher === "string") {
|
|
265
|
+
this.#matchers[param] = { match: new RegExp(matcher) };
|
|
266
|
+
} else if (is.regExp(matcher)) {
|
|
267
|
+
this.#matchers[param] = { match: matcher };
|
|
268
|
+
} else {
|
|
269
|
+
this.#matchers[param] = matcher;
|
|
270
|
+
}
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Define prefix for the route. Calling this method multiple times
|
|
275
|
+
* applies multiple prefixes in the reverse order.
|
|
276
|
+
* @param prefix - The prefix to add to the route
|
|
277
|
+
* @returns Current Route instance for method chaining
|
|
278
|
+
*/
|
|
279
|
+
prefix(prefix) {
|
|
280
|
+
this.#prefixes.push(prefix);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Define a custom domain for the route. We do not overwrite the domain
|
|
285
|
+
* unless `overwrite` flag is set to true.
|
|
286
|
+
*/
|
|
287
|
+
domain(domain, overwrite = false) {
|
|
288
|
+
if (this.#routeDomain === "root" || overwrite) {
|
|
289
|
+
this.#routeDomain = domain;
|
|
290
|
+
}
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Define one or more middleware to be executed before the route
|
|
295
|
+
* handler.
|
|
296
|
+
*
|
|
297
|
+
* Named middleware can be referenced using the name registered with
|
|
298
|
+
* the router middleware store.
|
|
299
|
+
*/
|
|
300
|
+
use(middleware) {
|
|
301
|
+
this.#middleware.push(Array.isArray(middleware) ? middleware : [middleware]);
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Alias for {@link Route.use}
|
|
306
|
+
*/
|
|
307
|
+
middleware(middleware) {
|
|
308
|
+
return this.use(middleware);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Give a unique name to the route. Assinging a new unique removes the
|
|
312
|
+
* existing name of the route.
|
|
313
|
+
*
|
|
314
|
+
* Setting prepends to true prefixes the name to the existing name.
|
|
315
|
+
*/
|
|
316
|
+
as(name, prepend = false) {
|
|
317
|
+
if (prepend) {
|
|
318
|
+
if (!this.#name) {
|
|
319
|
+
throw new RuntimeException(
|
|
320
|
+
`Routes inside a group must have names before calling "router.group.as"`
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
this.#name = `${name}.${this.#name}`;
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
this.#name = name;
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Check if the route was marked to be deleted
|
|
331
|
+
*/
|
|
332
|
+
isDeleted() {
|
|
333
|
+
return this.#isDeleted;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Mark route as deleted. Deleted routes are not registered
|
|
337
|
+
* with the route store
|
|
338
|
+
*/
|
|
339
|
+
markAsDeleted() {
|
|
340
|
+
this.#isDeleted = true;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get the route name
|
|
344
|
+
*/
|
|
345
|
+
getName() {
|
|
346
|
+
return this.#name;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Get the route pattern
|
|
350
|
+
*/
|
|
351
|
+
getPattern() {
|
|
352
|
+
return this.#pattern;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Set the route pattern
|
|
356
|
+
*/
|
|
357
|
+
setPattern(pattern) {
|
|
358
|
+
this.#pattern = pattern;
|
|
359
|
+
return this;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Returns the stack of middleware registered on the route.
|
|
363
|
+
* The value is shared by reference.
|
|
364
|
+
*/
|
|
365
|
+
getMiddleware() {
|
|
366
|
+
return this.#middleware;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Returns the middleware instance for persistence inside the
|
|
370
|
+
* store
|
|
371
|
+
*/
|
|
372
|
+
#getMiddlewareForStore() {
|
|
373
|
+
const middleware = new Middleware();
|
|
374
|
+
this.#routerMiddleware.forEach((one) => {
|
|
375
|
+
debug_default("adding global middleware to route %s, %O", this.#pattern, one);
|
|
376
|
+
middleware.add(one);
|
|
377
|
+
});
|
|
378
|
+
this.#middleware.flat().forEach((one) => {
|
|
379
|
+
debug_default("adding named middleware to route %s, %O", this.#pattern, one);
|
|
380
|
+
middleware.add(one);
|
|
381
|
+
});
|
|
382
|
+
middleware.freeze();
|
|
383
|
+
return middleware;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns JSON representation of the route
|
|
387
|
+
*/
|
|
388
|
+
toJSON() {
|
|
389
|
+
const pattern = this.#computePattern();
|
|
390
|
+
const matchers = this.#getMatchers();
|
|
391
|
+
return {
|
|
392
|
+
domain: this.#routeDomain,
|
|
393
|
+
pattern,
|
|
394
|
+
matchers,
|
|
395
|
+
tokens: parseRoute(pattern, matchers),
|
|
396
|
+
meta: {},
|
|
397
|
+
name: this.#name,
|
|
398
|
+
handler: this.#handler,
|
|
399
|
+
methods: this.#methods,
|
|
400
|
+
middleware: this.#getMiddlewareForStore(),
|
|
401
|
+
execute
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// src/router/brisk.ts
|
|
407
|
+
var BriskRoute = class extends Macroable2 {
|
|
408
|
+
/**
|
|
409
|
+
* Route pattern
|
|
410
|
+
*/
|
|
411
|
+
#pattern;
|
|
412
|
+
/**
|
|
413
|
+
* Matchers inherited from the router
|
|
414
|
+
*/
|
|
415
|
+
#globalMatchers;
|
|
416
|
+
/**
|
|
417
|
+
* Reference to the AdonisJS application
|
|
418
|
+
*/
|
|
419
|
+
#app;
|
|
420
|
+
/**
|
|
421
|
+
* Middleware registered on the router
|
|
422
|
+
*/
|
|
423
|
+
#routerMiddleware;
|
|
424
|
+
/**
|
|
425
|
+
* Reference to route instance. Set after `setHandler` is called
|
|
426
|
+
*/
|
|
427
|
+
route = null;
|
|
428
|
+
/**
|
|
429
|
+
* Creates a new BriskRoute instance
|
|
430
|
+
* @param app - The AdonisJS application instance
|
|
431
|
+
* @param routerMiddleware - Array of global middleware registered on the router
|
|
432
|
+
* @param options - Configuration options for the brisk route
|
|
433
|
+
*/
|
|
434
|
+
constructor(app, routerMiddleware, options) {
|
|
435
|
+
super();
|
|
436
|
+
this.#app = app;
|
|
437
|
+
this.#routerMiddleware = routerMiddleware;
|
|
438
|
+
this.#pattern = options.pattern;
|
|
439
|
+
this.#globalMatchers = options.globalMatchers;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Set handler for the brisk route
|
|
443
|
+
* @param handler - The route handler function
|
|
444
|
+
* @returns The created route instance
|
|
445
|
+
*/
|
|
446
|
+
setHandler(handler) {
|
|
447
|
+
this.route = new Route(this.#app, this.#routerMiddleware, {
|
|
448
|
+
pattern: this.#pattern,
|
|
449
|
+
globalMatchers: this.#globalMatchers,
|
|
450
|
+
methods: ["GET", "HEAD"],
|
|
451
|
+
handler
|
|
452
|
+
});
|
|
453
|
+
return this.route;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Redirects to a given route. Params from the original request will
|
|
457
|
+
* be used when no custom params are defined.
|
|
458
|
+
* @param args - Route identifier, parameters, and options for building the redirect URL
|
|
459
|
+
* @returns The created route instance
|
|
460
|
+
*/
|
|
461
|
+
redirect(...args) {
|
|
462
|
+
const [identifier, params, options] = args;
|
|
463
|
+
function redirectsToRoute(ctx) {
|
|
464
|
+
const redirector = ctx.response.redirect();
|
|
465
|
+
if (options?.status) {
|
|
466
|
+
redirector.status(options.status);
|
|
467
|
+
}
|
|
468
|
+
return redirector.toRoute(identifier, params || ctx.params, options);
|
|
469
|
+
}
|
|
470
|
+
Object.defineProperty(redirectsToRoute, "listArgs", { value: identifier, writable: false });
|
|
471
|
+
return this.setHandler(redirectsToRoute);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Redirect request to a fixed URL
|
|
475
|
+
* @param url - The URL to redirect to
|
|
476
|
+
* @param options - Optional redirect options including HTTP status code
|
|
477
|
+
* @returns The created route instance
|
|
478
|
+
*/
|
|
479
|
+
redirectToPath(url, options) {
|
|
480
|
+
function redirectsToPath(ctx) {
|
|
481
|
+
const redirector = ctx.response.redirect();
|
|
482
|
+
if (options?.status) {
|
|
483
|
+
redirector.status(options.status);
|
|
484
|
+
}
|
|
485
|
+
return redirector.toPath(url);
|
|
486
|
+
}
|
|
487
|
+
Object.defineProperty(redirectsToPath, "listArgs", { value: url, writable: false });
|
|
488
|
+
return this.setHandler(redirectsToPath);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// src/router/resource.ts
|
|
493
|
+
import string2 from "@poppinss/utils/string";
|
|
494
|
+
import Macroable3 from "@poppinss/macroable";
|
|
495
|
+
import { RuntimeException as RuntimeException2 } from "@poppinss/utils/exception";
|
|
496
|
+
var RouteResource = class extends Macroable3 {
|
|
497
|
+
/**
|
|
498
|
+
* Resource identifier. Nested resources are separated
|
|
499
|
+
* with a dot notation
|
|
500
|
+
*/
|
|
501
|
+
#resource;
|
|
502
|
+
/**
|
|
503
|
+
* The controller to handle resource routing requests
|
|
504
|
+
*/
|
|
505
|
+
#controller;
|
|
506
|
+
/**
|
|
507
|
+
* Is it a shallow resource? Shallow resources URLs do not have parent
|
|
508
|
+
* resource name and id once they can be identified with the id.
|
|
509
|
+
*/
|
|
510
|
+
#shallow = false;
|
|
511
|
+
/**
|
|
512
|
+
* Matchers inherited from the router
|
|
513
|
+
*/
|
|
514
|
+
#globalMatchers;
|
|
515
|
+
/**
|
|
516
|
+
* Reference to the AdonisJS application
|
|
517
|
+
*/
|
|
518
|
+
#app;
|
|
519
|
+
/**
|
|
520
|
+
* Middleware registered on the router
|
|
521
|
+
*/
|
|
522
|
+
#routerMiddleware;
|
|
523
|
+
/**
|
|
524
|
+
* Parameter names for the resources. Defaults to `id` for
|
|
525
|
+
* a singular resource and `resource_id` for nested
|
|
526
|
+
* resources.
|
|
527
|
+
*/
|
|
528
|
+
#params = {};
|
|
529
|
+
/**
|
|
530
|
+
* Base name for the routes. We suffix action names
|
|
531
|
+
* on top of the base name
|
|
532
|
+
*/
|
|
533
|
+
#routesBaseName;
|
|
534
|
+
/**
|
|
535
|
+
* A collection of routes instances that belongs to this resource
|
|
536
|
+
*/
|
|
537
|
+
routes = [];
|
|
538
|
+
/**
|
|
539
|
+
* Creates a new RouteResource instance
|
|
540
|
+
* @param app - The AdonisJS application instance
|
|
541
|
+
* @param routerMiddleware - Array of global middleware registered on the router
|
|
542
|
+
* @param options - Configuration options for the route resource
|
|
543
|
+
*/
|
|
544
|
+
constructor(app, routerMiddleware, options) {
|
|
545
|
+
super();
|
|
546
|
+
this.#validateResourceName(options.resource);
|
|
547
|
+
this.#app = app;
|
|
548
|
+
this.#shallow = options.shallow;
|
|
549
|
+
this.#routerMiddleware = routerMiddleware;
|
|
550
|
+
this.#controller = options.controller;
|
|
551
|
+
this.#globalMatchers = options.globalMatchers;
|
|
552
|
+
this.#resource = this.#normalizeResourceName(options.resource);
|
|
553
|
+
this.#routesBaseName = this.#getRoutesBaseName();
|
|
554
|
+
this.#buildRoutes();
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Normalizes the resource name to dropping leading and trailing
|
|
558
|
+
* slashes.
|
|
559
|
+
*/
|
|
560
|
+
#normalizeResourceName(resource) {
|
|
561
|
+
return resource.replace(/^\//, "").replace(/\/$/, "");
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Ensure resource name is not an empty string
|
|
565
|
+
*/
|
|
566
|
+
#validateResourceName(resource) {
|
|
567
|
+
if (!resource || resource === "/") {
|
|
568
|
+
throw new RuntimeException2(`Invalid resource name "${resource}"`);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Converting segments of a resource to snake case to
|
|
573
|
+
* make the route name.
|
|
574
|
+
*/
|
|
575
|
+
#getRoutesBaseName() {
|
|
576
|
+
return this.#resource.split(".").map((token) => string2.snakeCase(token)).join(".");
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Create a new route for the given pattern, methods and controller action
|
|
580
|
+
*/
|
|
581
|
+
#createRoute(pattern, methods, action) {
|
|
582
|
+
const route = new Route(this.#app, this.#routerMiddleware, {
|
|
583
|
+
pattern,
|
|
584
|
+
methods,
|
|
585
|
+
handler: typeof this.#controller === "string" ? `${this.#controller}.${action}` : [this.#controller, action],
|
|
586
|
+
globalMatchers: this.#globalMatchers
|
|
587
|
+
});
|
|
588
|
+
route.as(`${this.#routesBaseName}.${action}`);
|
|
589
|
+
this.routes.push(route);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Returns the `resource_id` name for a given resource. The
|
|
593
|
+
* resource name is converted to singular form and
|
|
594
|
+
* transformed to snake case.
|
|
595
|
+
*
|
|
596
|
+
* photos becomes photo_id
|
|
597
|
+
* users becomes user_id
|
|
598
|
+
*/
|
|
599
|
+
#getResourceId(resource) {
|
|
600
|
+
return `${string2.snakeCase(string2.singular(resource))}_id`;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Build routes for the given resource
|
|
604
|
+
*/
|
|
605
|
+
#buildRoutes() {
|
|
606
|
+
const resources = this.#resource.split(".");
|
|
607
|
+
const mainResource = resources.pop();
|
|
608
|
+
this.#params[mainResource] = ":id";
|
|
609
|
+
const baseURI = `${resources.map((resource) => {
|
|
610
|
+
const paramName = `:${this.#getResourceId(resource)}`;
|
|
611
|
+
this.#params[resource] = paramName;
|
|
612
|
+
return `${resource}/${paramName}`;
|
|
613
|
+
}).join("/")}/${mainResource}`;
|
|
614
|
+
this.#createRoute(baseURI, ["GET", "HEAD"], "index");
|
|
615
|
+
this.#createRoute(`${baseURI}/create`, ["GET", "HEAD"], "create");
|
|
616
|
+
this.#createRoute(baseURI, ["POST"], "store");
|
|
617
|
+
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["GET", "HEAD"], "show");
|
|
618
|
+
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id/edit`, ["GET", "HEAD"], "edit");
|
|
619
|
+
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["PUT", "PATCH"], "update");
|
|
620
|
+
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["DELETE"], "destroy");
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Filter the routes based on their partial names
|
|
624
|
+
*/
|
|
625
|
+
#filter(names, inverse) {
|
|
626
|
+
const actions = Array.isArray(names) ? names : [names];
|
|
627
|
+
return this.routes.filter((route) => {
|
|
628
|
+
const match = actions.find((name) => route.getName().endsWith(name));
|
|
629
|
+
return inverse ? !match : match;
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Register only given routes and remove others
|
|
634
|
+
* @param names - Array of action names to keep
|
|
635
|
+
* @returns Current RouteResource instance with filtered actions
|
|
636
|
+
*/
|
|
637
|
+
only(names) {
|
|
638
|
+
this.#filter(names, true).forEach((route) => route.markAsDeleted());
|
|
639
|
+
return this;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Register all routes, except the one's defined
|
|
643
|
+
* @param names - Array of action names to exclude
|
|
644
|
+
* @returns Current RouteResource instance with filtered actions
|
|
645
|
+
*/
|
|
646
|
+
except(names) {
|
|
647
|
+
this.#filter(names, false).forEach((route) => route.markAsDeleted());
|
|
648
|
+
return this;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Register api only routes. The `create` and `edit` routes, which
|
|
652
|
+
* are meant to show forms will not be registered
|
|
653
|
+
* @returns Current RouteResource instance without create and edit actions
|
|
654
|
+
*/
|
|
655
|
+
apiOnly() {
|
|
656
|
+
return this.except(["create", "edit"]);
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Define matcher for params inside the resource
|
|
660
|
+
* @param key - The parameter name to match
|
|
661
|
+
* @param matcher - The matcher pattern (RegExp, string, or RouteMatcher)
|
|
662
|
+
* @returns Current RouteResource instance for method chaining
|
|
663
|
+
*/
|
|
664
|
+
where(key, matcher) {
|
|
665
|
+
this.routes.forEach((route) => {
|
|
666
|
+
route.where(key, matcher);
|
|
667
|
+
});
|
|
668
|
+
return this;
|
|
669
|
+
}
|
|
670
|
+
tap(actions, callback) {
|
|
671
|
+
if (typeof actions === "function") {
|
|
672
|
+
this.routes.forEach((route) => {
|
|
673
|
+
if (!route.isDeleted()) {
|
|
674
|
+
actions(route);
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
return this;
|
|
678
|
+
}
|
|
679
|
+
this.#filter(actions, false).forEach((route) => {
|
|
680
|
+
if (!route.isDeleted()) {
|
|
681
|
+
callback(route);
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Set the param name for a given resource
|
|
688
|
+
* @param resources - Object mapping resource names to parameter names
|
|
689
|
+
* @returns Current RouteResource instance for method chaining
|
|
690
|
+
*/
|
|
691
|
+
params(resources) {
|
|
692
|
+
Object.keys(resources).forEach((resource) => {
|
|
693
|
+
const param = resources[resource];
|
|
694
|
+
const existingParam = this.#params[resource];
|
|
695
|
+
this.#params[resource] = `:${param}`;
|
|
696
|
+
this.routes.forEach((route) => {
|
|
697
|
+
route.setPattern(
|
|
698
|
+
route.getPattern().replace(`${resource}/${existingParam}`, `${resource}/:${param}`)
|
|
699
|
+
);
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
return this;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Define one or more middleware on the routes created by
|
|
706
|
+
* the resource.
|
|
707
|
+
*
|
|
708
|
+
* Calling this method multiple times will append middleware
|
|
709
|
+
* to existing list.
|
|
710
|
+
* @param actions - Action name(s) or '*' for all actions
|
|
711
|
+
* @param middleware - Middleware function(s) to apply
|
|
712
|
+
* @returns Current RouteResource instance for method chaining
|
|
713
|
+
*/
|
|
714
|
+
use(actions, middleware) {
|
|
715
|
+
if (actions === "*") {
|
|
716
|
+
this.tap((route) => route.use(middleware));
|
|
717
|
+
} else {
|
|
718
|
+
this.tap(actions, (route) => route.use(middleware));
|
|
719
|
+
}
|
|
720
|
+
return this;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Alias for {@link RouteResource.use}
|
|
724
|
+
* @param actions - Action name(s) or '*' for all actions
|
|
725
|
+
* @param middleware - Middleware function(s) to apply
|
|
726
|
+
* @returns Current RouteResource instance for method chaining
|
|
727
|
+
*/
|
|
728
|
+
middleware(actions, middleware) {
|
|
729
|
+
return this.use(actions, middleware);
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Prepend name to all the routes
|
|
733
|
+
* @param name - The name to prepend to all route names
|
|
734
|
+
* @param normalizeName - Whether to normalize the name to snake_case
|
|
735
|
+
* @returns Current RouteResource instance for method chaining
|
|
736
|
+
*/
|
|
737
|
+
as(name, normalizeName = true) {
|
|
738
|
+
name = normalizeName ? string2.snakeCase(name) : name;
|
|
739
|
+
this.routes.forEach((route) => {
|
|
740
|
+
route.as(route.getName().replace(this.#routesBaseName, name), false);
|
|
741
|
+
});
|
|
742
|
+
this.#routesBaseName = name;
|
|
743
|
+
return this;
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
// src/router/group.ts
|
|
748
|
+
var RouteGroup = class _RouteGroup extends Macroable4 {
|
|
749
|
+
/**
|
|
750
|
+
* Creates a new RouteGroup instance
|
|
751
|
+
* @param routes - Array of routes that belong to this group
|
|
752
|
+
*/
|
|
753
|
+
constructor(routes) {
|
|
754
|
+
super();
|
|
755
|
+
this.routes = routes;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Array of middleware registered on the group.
|
|
759
|
+
*/
|
|
760
|
+
#middleware = [];
|
|
761
|
+
/**
|
|
762
|
+
* Shares midldeware stack with the routes. The method is invoked recursively
|
|
763
|
+
* to only register middleware with the route class and not with the
|
|
764
|
+
* resource or the child group
|
|
765
|
+
*/
|
|
766
|
+
#shareMiddlewareStackWithRoutes(route) {
|
|
767
|
+
if (route instanceof _RouteGroup) {
|
|
768
|
+
route.routes.forEach((child) => this.#shareMiddlewareStackWithRoutes(child));
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
if (route instanceof RouteResource) {
|
|
772
|
+
route.routes.forEach((child) => child.getMiddleware().unshift(this.#middleware));
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
if (route instanceof BriskRoute) {
|
|
776
|
+
route.route.getMiddleware().unshift(this.#middleware);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
route.getMiddleware().unshift(this.#middleware);
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Updates the route name. The method is invoked recursively to only update
|
|
783
|
+
* the name with the route class and not with the resource or the child
|
|
784
|
+
* group.
|
|
785
|
+
*/
|
|
786
|
+
#updateRouteName(route, name) {
|
|
787
|
+
if (route instanceof _RouteGroup) {
|
|
788
|
+
route.routes.forEach((child) => this.#updateRouteName(child, name));
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (route instanceof RouteResource) {
|
|
792
|
+
route.routes.forEach((child) => child.as(name, true));
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
if (route instanceof BriskRoute) {
|
|
796
|
+
route.route.as(name, true);
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
route.as(name, true);
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Sets prefix on the route. The method is invoked recursively to only set
|
|
803
|
+
* the prefix with the route class and not with the resource or the
|
|
804
|
+
* child group.
|
|
805
|
+
*/
|
|
806
|
+
#setRoutePrefix(route, prefix) {
|
|
807
|
+
if (route instanceof _RouteGroup) {
|
|
808
|
+
route.routes.forEach((child) => this.#setRoutePrefix(child, prefix));
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (route instanceof RouteResource) {
|
|
812
|
+
route.routes.forEach((child) => child.prefix(prefix));
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
if (route instanceof BriskRoute) {
|
|
816
|
+
route.route.prefix(prefix);
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
route.prefix(prefix);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Updates domain on the route. The method is invoked recursively to only update
|
|
823
|
+
* the domain with the route class and not with the resource or the child
|
|
824
|
+
* group.
|
|
825
|
+
*/
|
|
826
|
+
#updateRouteDomain(route, domain) {
|
|
827
|
+
if (route instanceof _RouteGroup) {
|
|
828
|
+
route.routes.forEach((child) => this.#updateRouteDomain(child, domain));
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (route instanceof RouteResource) {
|
|
832
|
+
route.routes.forEach((child) => child.domain(domain));
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
if (route instanceof BriskRoute) {
|
|
836
|
+
route.route.domain(domain, false);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
route.domain(domain, false);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Updates matchers on the route. The method is invoked recursively to only update
|
|
843
|
+
* the matchers with the route class and not with the resource or the child
|
|
844
|
+
* group.
|
|
845
|
+
*/
|
|
846
|
+
#updateRouteMatchers(route, param, matcher) {
|
|
847
|
+
if (route instanceof _RouteGroup) {
|
|
848
|
+
route.routes.forEach((child) => this.#updateRouteMatchers(child, param, matcher));
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (route instanceof RouteResource) {
|
|
852
|
+
route.routes.forEach((child) => child.where(param, matcher));
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (route instanceof BriskRoute) {
|
|
856
|
+
route.route.where(param, matcher);
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
route.where(param, matcher);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Define route param matcher
|
|
863
|
+
*
|
|
864
|
+
* ```ts
|
|
865
|
+
* Route.group(() => {
|
|
866
|
+
* }).where('id', /^[0-9]+/)
|
|
867
|
+
* ```
|
|
868
|
+
* @param param - The parameter name to match
|
|
869
|
+
* @param matcher - The matcher pattern (RegExp, string, or RouteMatcher)
|
|
870
|
+
* @returns Current RouteGroup instance for method chaining
|
|
871
|
+
*/
|
|
872
|
+
where(param, matcher) {
|
|
873
|
+
this.routes.forEach((route) => this.#updateRouteMatchers(route, param, matcher));
|
|
874
|
+
return this;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Define prefix all the routes in the group.
|
|
878
|
+
*
|
|
879
|
+
* ```ts
|
|
880
|
+
* Route.group(() => {
|
|
881
|
+
* }).prefix('v1')
|
|
882
|
+
* ```
|
|
883
|
+
* @param prefix - The prefix to add to all routes in the group
|
|
884
|
+
* @returns Current RouteGroup instance for method chaining
|
|
885
|
+
*/
|
|
886
|
+
prefix(prefix) {
|
|
887
|
+
this.routes.forEach((route) => this.#setRoutePrefix(route, prefix));
|
|
888
|
+
return this;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Define domain for all the routes.
|
|
892
|
+
*
|
|
893
|
+
* ```ts
|
|
894
|
+
* Route.group(() => {
|
|
895
|
+
* }).domain(':name.adonisjs.com')
|
|
896
|
+
* ```
|
|
897
|
+
* @param domain - The domain pattern for all routes in the group
|
|
898
|
+
* @returns Current RouteGroup instance for method chaining
|
|
899
|
+
*/
|
|
900
|
+
domain(domain) {
|
|
901
|
+
this.routes.forEach((route) => this.#updateRouteDomain(route, domain));
|
|
902
|
+
return this;
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Prepend name to the routes name.
|
|
906
|
+
*
|
|
907
|
+
* ```ts
|
|
908
|
+
* Route.group(() => {
|
|
909
|
+
* }).as('version1')
|
|
910
|
+
* ```
|
|
911
|
+
* @param name - The name to prepend to all route names in the group
|
|
912
|
+
* @returns Current RouteGroup instance for method chaining
|
|
913
|
+
*/
|
|
914
|
+
as(name) {
|
|
915
|
+
this.routes.forEach((route) => this.#updateRouteName(route, name));
|
|
916
|
+
return this;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Prepend an array of middleware to all routes middleware.
|
|
920
|
+
*
|
|
921
|
+
* ```ts
|
|
922
|
+
* Route.group(() => {
|
|
923
|
+
* }).use(middleware.auth())
|
|
924
|
+
* ```
|
|
925
|
+
* @param middleware - Middleware function(s) to apply to all routes in the group
|
|
926
|
+
* @returns Current RouteGroup instance for method chaining
|
|
927
|
+
*/
|
|
928
|
+
use(middleware) {
|
|
929
|
+
if (!this.#middleware.length) {
|
|
930
|
+
this.routes.forEach((route) => this.#shareMiddlewareStackWithRoutes(route));
|
|
931
|
+
}
|
|
932
|
+
if (Array.isArray(middleware)) {
|
|
933
|
+
for (let one of middleware) {
|
|
934
|
+
this.#middleware.push(one);
|
|
935
|
+
}
|
|
936
|
+
} else {
|
|
937
|
+
this.#middleware.push(middleware);
|
|
938
|
+
}
|
|
939
|
+
return this;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Alias for {@link RouteGroup.use}
|
|
943
|
+
* @param middleware - Middleware function(s) to apply to all routes in the group
|
|
944
|
+
* @returns Current RouteGroup instance for method chaining
|
|
945
|
+
*/
|
|
946
|
+
middleware(middleware) {
|
|
947
|
+
return this.use(middleware);
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
// src/utils.ts
|
|
952
|
+
var proxyCache = new Cache({ max: 200 });
|
|
953
|
+
function dropSlash(input) {
|
|
954
|
+
if (input === "/") {
|
|
955
|
+
return "/";
|
|
956
|
+
}
|
|
957
|
+
return `/${input.replace(/^\//, "").replace(/\/$/, "")}`;
|
|
958
|
+
}
|
|
959
|
+
function toRoutesJSON(routes) {
|
|
960
|
+
return routes.reduce((list, route) => {
|
|
961
|
+
if (route instanceof RouteGroup) {
|
|
962
|
+
list = list.concat(toRoutesJSON(route.routes));
|
|
963
|
+
return list;
|
|
964
|
+
}
|
|
965
|
+
if (route instanceof RouteResource) {
|
|
966
|
+
list = list.concat(toRoutesJSON(route.routes));
|
|
967
|
+
return list;
|
|
968
|
+
}
|
|
969
|
+
if (route instanceof BriskRoute) {
|
|
970
|
+
if (route.route && !route.route.isDeleted()) {
|
|
971
|
+
list.push(route.route.toJSON());
|
|
972
|
+
}
|
|
973
|
+
return list;
|
|
974
|
+
}
|
|
975
|
+
if (!route.isDeleted()) {
|
|
976
|
+
list.push(route.toJSON());
|
|
977
|
+
}
|
|
978
|
+
return list;
|
|
979
|
+
}, []);
|
|
980
|
+
}
|
|
981
|
+
function trustProxy(remoteAddress, proxyFn) {
|
|
982
|
+
if (proxyCache.has(remoteAddress)) {
|
|
983
|
+
return proxyCache.get(remoteAddress);
|
|
984
|
+
}
|
|
985
|
+
const result = proxyFn(remoteAddress, 0);
|
|
986
|
+
proxyCache.set(remoteAddress, result);
|
|
987
|
+
return result;
|
|
988
|
+
}
|
|
989
|
+
function parseRange(range, value) {
|
|
990
|
+
const parts = range.split("..");
|
|
991
|
+
const min = Number(parts[0]);
|
|
992
|
+
const max = Number(parts[1]);
|
|
993
|
+
if (parts.length === 1 && !Number.isNaN(min)) {
|
|
994
|
+
return {
|
|
995
|
+
[min]: value
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
if (Number.isNaN(min) || Number.isNaN(max)) {
|
|
999
|
+
return {};
|
|
1000
|
+
}
|
|
1001
|
+
if (min === max) {
|
|
1002
|
+
return {
|
|
1003
|
+
[min]: value
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
if (max < min) {
|
|
1007
|
+
throw new InvalidArgumentsException(`Invalid range "${range}"`);
|
|
1008
|
+
}
|
|
1009
|
+
return [...Array(max - min + 1).keys()].reduce(
|
|
1010
|
+
(result, step) => {
|
|
1011
|
+
result[min + step] = value;
|
|
1012
|
+
return result;
|
|
1013
|
+
},
|
|
1014
|
+
{}
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
function decodeComponentChar(highCharCode, lowCharCode) {
|
|
1018
|
+
if (highCharCode === 50) {
|
|
1019
|
+
if (lowCharCode === 53) return "%";
|
|
1020
|
+
if (lowCharCode === 51) return "#";
|
|
1021
|
+
if (lowCharCode === 52) return "$";
|
|
1022
|
+
if (lowCharCode === 54) return "&";
|
|
1023
|
+
if (lowCharCode === 66) return "+";
|
|
1024
|
+
if (lowCharCode === 98) return "+";
|
|
1025
|
+
if (lowCharCode === 67) return ",";
|
|
1026
|
+
if (lowCharCode === 99) return ",";
|
|
1027
|
+
if (lowCharCode === 70) return "/";
|
|
1028
|
+
if (lowCharCode === 102) return "/";
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
if (highCharCode === 51) {
|
|
1032
|
+
if (lowCharCode === 65) return ":";
|
|
1033
|
+
if (lowCharCode === 97) return ":";
|
|
1034
|
+
if (lowCharCode === 66) return ";";
|
|
1035
|
+
if (lowCharCode === 98) return ";";
|
|
1036
|
+
if (lowCharCode === 68) return "=";
|
|
1037
|
+
if (lowCharCode === 100) return "=";
|
|
1038
|
+
if (lowCharCode === 70) return "?";
|
|
1039
|
+
if (lowCharCode === 102) return "?";
|
|
1040
|
+
return null;
|
|
1041
|
+
}
|
|
1042
|
+
if (highCharCode === 52 && lowCharCode === 48) {
|
|
1043
|
+
return "@";
|
|
1044
|
+
}
|
|
1045
|
+
return null;
|
|
1046
|
+
}
|
|
1047
|
+
function safeDecodeURI(path, useSemicolonDelimiter) {
|
|
1048
|
+
let shouldDecode = false;
|
|
1049
|
+
let shouldDecodeParam = false;
|
|
1050
|
+
let querystring = "";
|
|
1051
|
+
for (let i = 1; i < path.length; i++) {
|
|
1052
|
+
const charCode = path.charCodeAt(i);
|
|
1053
|
+
if (charCode === 37) {
|
|
1054
|
+
const highCharCode = path.charCodeAt(i + 1);
|
|
1055
|
+
const lowCharCode = path.charCodeAt(i + 2);
|
|
1056
|
+
if (decodeComponentChar(highCharCode, lowCharCode) === null) {
|
|
1057
|
+
shouldDecode = true;
|
|
1058
|
+
} else {
|
|
1059
|
+
shouldDecodeParam = true;
|
|
1060
|
+
if (highCharCode === 50 && lowCharCode === 53) {
|
|
1061
|
+
shouldDecode = true;
|
|
1062
|
+
path = path.slice(0, i + 1) + "25" + path.slice(i + 1);
|
|
1063
|
+
i += 2;
|
|
1064
|
+
}
|
|
1065
|
+
i += 2;
|
|
1066
|
+
}
|
|
1067
|
+
} else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
|
|
1068
|
+
querystring = path.slice(i + 1);
|
|
1069
|
+
path = path.slice(0, i);
|
|
1070
|
+
break;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
const decodedPath = shouldDecode ? decodeURI(path) : path;
|
|
1074
|
+
return { pathname: decodedPath, query: querystring, shouldDecodeParam };
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// src/helpers.ts
|
|
1078
|
+
import { default as default2 } from "encodeurl";
|
|
1079
|
+
import { default as default3 } from "mime-types";
|
|
1080
|
+
function parseRoute(pattern, matchers) {
|
|
1081
|
+
const tokens = matchit.parse(pattern, matchers);
|
|
1082
|
+
return tokens;
|
|
1083
|
+
}
|
|
1084
|
+
function createURL(pattern, tokens, searchParamsStringifier, params, options) {
|
|
1085
|
+
const uriSegments = [];
|
|
1086
|
+
const paramsArray = Array.isArray(params) ? params : null;
|
|
1087
|
+
const paramsObject = !Array.isArray(params) ? params ?? {} : {};
|
|
1088
|
+
let paramsIndex = 0;
|
|
1089
|
+
for (const token of tokens) {
|
|
1090
|
+
if (token.type === 0) {
|
|
1091
|
+
uriSegments.push(token.val === "/" ? "" : `${token.val}${token.end}`);
|
|
1092
|
+
continue;
|
|
1093
|
+
}
|
|
1094
|
+
if (token.type === 2) {
|
|
1095
|
+
const values = paramsArray ? paramsArray.slice(paramsIndex) : paramsObject["*"];
|
|
1096
|
+
if (!Array.isArray(values) || !values.length) {
|
|
1097
|
+
throw new Error(
|
|
1098
|
+
`Cannot make URL for "${pattern}". Invalid value provided for the wildcard param`
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
uriSegments.push(`${values.join("/")}${token.end}`);
|
|
1102
|
+
break;
|
|
1103
|
+
}
|
|
1104
|
+
const paramName = token.val;
|
|
1105
|
+
const value = paramsArray ? paramsArray[paramsIndex] : paramsObject[paramName];
|
|
1106
|
+
const isDefined = value !== void 0 && value !== null;
|
|
1107
|
+
if (token.type === 1 && !isDefined) {
|
|
1108
|
+
throw new Error(
|
|
1109
|
+
`Cannot make URL for "${pattern}". Missing value for the "${paramName}" param`
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
if (isDefined) {
|
|
1113
|
+
uriSegments.push(`${value}${token.end}`);
|
|
1114
|
+
}
|
|
1115
|
+
paramsIndex++;
|
|
1116
|
+
}
|
|
1117
|
+
let URI = `/${uriSegments.join("/")}`;
|
|
1118
|
+
if (options?.prefixUrl) {
|
|
1119
|
+
URI = `${options?.prefixUrl.replace(/\/$/, "")}${URI}`;
|
|
1120
|
+
}
|
|
1121
|
+
if (options?.qs) {
|
|
1122
|
+
const queryString = searchParamsStringifier(options?.qs);
|
|
1123
|
+
URI = queryString ? `${URI}?${queryString}` : URI;
|
|
1124
|
+
}
|
|
1125
|
+
return URI;
|
|
1126
|
+
}
|
|
1127
|
+
function createSignedURL(identifier, tokens, searchParamsStringifier, encryption, params, options) {
|
|
1128
|
+
const signature = encryption.verifier.sign(
|
|
1129
|
+
createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
1130
|
+
...options,
|
|
1131
|
+
prefixUrl: void 0
|
|
1132
|
+
}),
|
|
1133
|
+
options?.expiresIn,
|
|
1134
|
+
options?.purpose
|
|
1135
|
+
);
|
|
1136
|
+
return createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
1137
|
+
...options,
|
|
1138
|
+
qs: { ...options?.qs, signature }
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
function matchRoute(url, patterns) {
|
|
1142
|
+
const tokensBucket = patterns.map((pattern) => parseRoute(pattern));
|
|
1143
|
+
const match = matchit.match(url, tokensBucket);
|
|
1144
|
+
if (!match.length) {
|
|
1145
|
+
return null;
|
|
1146
|
+
}
|
|
1147
|
+
return matchit.exec(url, match);
|
|
1148
|
+
}
|
|
1149
|
+
function serializeCookie(key, value, options) {
|
|
1150
|
+
let expires;
|
|
1151
|
+
let maxAge;
|
|
1152
|
+
if (options) {
|
|
1153
|
+
expires = typeof options.expires === "function" ? options.expires() : options.expires;
|
|
1154
|
+
maxAge = options.maxAge ? string3.seconds.parse(options.maxAge) : void 0;
|
|
1155
|
+
}
|
|
1156
|
+
return cookie.serialize(key, value, { ...options, maxAge, expires });
|
|
1157
|
+
}
|
|
1158
|
+
async function middlewareInfo(middleware) {
|
|
1159
|
+
if (typeof middleware === "function") {
|
|
1160
|
+
return {
|
|
1161
|
+
type: "closure",
|
|
1162
|
+
name: middleware.name || "closure"
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
if ("args" in middleware) {
|
|
1166
|
+
return {
|
|
1167
|
+
type: "named",
|
|
1168
|
+
name: middleware.name,
|
|
1169
|
+
args: middleware.args,
|
|
1170
|
+
...await parseBindingReference([middleware.reference])
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
return {
|
|
1174
|
+
type: "global",
|
|
1175
|
+
name: middleware.name,
|
|
1176
|
+
...await parseBindingReference([middleware.reference])
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
async function routeInfo(route) {
|
|
1180
|
+
return "reference" in route.handler ? {
|
|
1181
|
+
type: "controller",
|
|
1182
|
+
...await parseBindingReference(route.handler.reference)
|
|
1183
|
+
} : {
|
|
1184
|
+
type: "closure",
|
|
1185
|
+
name: route.handler.name || "closure",
|
|
1186
|
+
args: "listArgs" in route.handler ? String(route.handler.listArgs) : void 0
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
function appendQueryString(uri, queryString, qsParser) {
|
|
1190
|
+
const { query, pathname } = safeDecodeURI(uri, false);
|
|
1191
|
+
const mergedQueryString = qsParser.stringify(Object.assign(qsParser.parse(query), queryString));
|
|
1192
|
+
return mergedQueryString ? `${pathname}?${mergedQueryString}` : pathname;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
export {
|
|
1196
|
+
__export,
|
|
1197
|
+
debug_default,
|
|
1198
|
+
canWriteResponseBody,
|
|
1199
|
+
httpRequest,
|
|
1200
|
+
httpMiddleware,
|
|
1201
|
+
httpExceptionHandler,
|
|
1202
|
+
httpResponseSerializer,
|
|
1203
|
+
tracing_channels_exports,
|
|
1204
|
+
parseRoute,
|
|
1205
|
+
createURL,
|
|
1206
|
+
createSignedURL,
|
|
1207
|
+
matchRoute,
|
|
1208
|
+
serializeCookie,
|
|
1209
|
+
middlewareInfo,
|
|
1210
|
+
routeInfo,
|
|
1211
|
+
appendQueryString,
|
|
1212
|
+
default2 as default,
|
|
1213
|
+
default3 as default2,
|
|
1214
|
+
Route,
|
|
1215
|
+
BriskRoute,
|
|
1216
|
+
RouteResource,
|
|
1217
|
+
RouteGroup,
|
|
1218
|
+
toRoutesJSON,
|
|
1219
|
+
trustProxy,
|
|
1220
|
+
parseRange,
|
|
1221
|
+
safeDecodeURI
|
|
1222
|
+
};
|