@adonisjs/http-server 8.0.0-next.0 → 8.0.0-next.10
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-2QM3D5BN.js +87 -0
- package/build/chunk-5PWHBE2E.js +128 -0
- package/build/chunk-QDK57QGB.js +1176 -0
- package/build/{chunk-VYBTM3NC.js → chunk-YBLFT4O6.js} +1161 -1719
- package/build/factories/http_context.d.ts +5 -4
- package/build/factories/http_server.d.ts +7 -0
- package/build/factories/main.d.ts +6 -6
- package/build/factories/main.js +33 -5
- package/build/factories/qs_parser_factory.d.ts +5 -4
- package/build/factories/request.d.ts +3 -2
- package/build/factories/response.d.ts +4 -3
- package/build/factories/router.d.ts +2 -1
- package/build/factories/server_factory.d.ts +3 -2
- package/build/factories/url_builder_factory.d.ts +3 -2
- package/build/index.d.ts +19 -16
- package/build/index.js +97 -42
- package/build/src/client/helpers.d.ts +37 -0
- package/build/src/client/types.d.ts +88 -66
- package/build/src/client/url_builder.d.ts +12 -10
- package/build/src/client/url_builder.js +12 -0
- package/build/src/cookies/client.d.ts +61 -3
- package/build/src/cookies/drivers/encrypted.d.ts +13 -0
- package/build/src/cookies/drivers/plain.d.ts +9 -0
- package/build/src/cookies/drivers/signed.d.ts +13 -0
- package/build/src/cookies/parser.d.ts +18 -0
- package/build/src/cookies/serializer.d.ts +22 -3
- package/build/src/debug.d.ts +13 -0
- package/build/src/define_config.d.ts +21 -5
- package/build/src/define_middleware.d.ts +20 -4
- package/build/src/errors.d.ts +67 -10
- package/build/src/exception_handler.d.ts +95 -41
- package/build/src/helpers.d.ts +60 -4
- package/build/src/helpers.js +9 -1
- package/build/src/http_context/local_storage.d.ts +18 -1
- package/build/src/http_context/main.d.ts +71 -13
- package/build/src/qs.d.ts +31 -3
- package/build/src/redirect.d.ts +87 -16
- package/build/src/request.d.ts +121 -15
- package/build/src/response.d.ts +421 -208
- package/build/src/response_status.d.ts +14 -0
- package/build/src/router/brisk.d.ts +18 -7
- package/build/src/router/executor.d.ts +7 -3
- package/build/src/router/factories/use_return_value.d.ts +6 -1
- package/build/src/router/group.d.ts +23 -6
- package/build/src/router/legacy/url_builder.d.ts +15 -15
- package/build/src/router/main.d.ts +133 -20
- package/build/src/router/matchers.d.ts +3 -0
- package/build/src/router/resource.d.ts +37 -5
- package/build/src/router/route.d.ts +30 -6
- package/build/src/router/signed_url_builder.d.ts +7 -10
- package/build/src/router/store.d.ts +10 -2
- package/build/src/server/factories/middleware_handler.d.ts +12 -3
- package/build/src/server/factories/route_finder.d.ts +16 -6
- package/build/src/server/factories/write_response.d.ts +10 -3
- package/build/src/server/main.d.ts +83 -29
- package/build/src/tracing_channels.d.ts +4 -4
- package/build/src/types/main.d.ts +1 -1
- package/build/src/types/middleware.d.ts +35 -10
- package/build/src/types/qs.d.ts +5 -0
- package/build/src/types/request.d.ts +1 -1
- package/build/src/types/response.d.ts +14 -6
- package/build/src/types/route.d.ts +53 -51
- package/build/src/types/server.d.ts +30 -15
- package/build/src/types/tracing_channels.d.ts +24 -6
- package/build/src/types/url_builder.d.ts +22 -0
- package/build/src/utils.d.ts +76 -11
- package/package.json +29 -30
- package/build/chunk-ASX56VAK.js +0 -76
- package/build/client.cjs +0 -232
- package/build/client.d.cts +0 -258
- package/build/client.d.ts +0 -258
- package/build/client.js +0 -229
- package/build/src/client/main.d.ts +0 -3
- package/build/src/client/router.d.ts +0 -68
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
BriskRoute,
|
|
3
|
+
Route,
|
|
4
|
+
RouteGroup,
|
|
5
|
+
RouteResource,
|
|
6
|
+
createSignedURL,
|
|
7
|
+
debug_default,
|
|
3
8
|
default as default2,
|
|
4
9
|
default2 as default3,
|
|
10
|
+
httpExceptionHandler,
|
|
11
|
+
httpMiddleware,
|
|
12
|
+
httpRequest,
|
|
13
|
+
httpResponseSerializer,
|
|
5
14
|
parseRoute,
|
|
6
|
-
|
|
7
|
-
|
|
15
|
+
safeDecodeURI,
|
|
16
|
+
serializeCookie,
|
|
17
|
+
toRoutesJSON,
|
|
18
|
+
trustProxy
|
|
19
|
+
} from "./chunk-QDK57QGB.js";
|
|
20
|
+
import {
|
|
21
|
+
createUrlBuilder
|
|
22
|
+
} from "./chunk-5PWHBE2E.js";
|
|
23
|
+
import {
|
|
24
|
+
__export,
|
|
25
|
+
createURL,
|
|
26
|
+
findRoute
|
|
27
|
+
} from "./chunk-2QM3D5BN.js";
|
|
28
|
+
|
|
29
|
+
// src/qs.ts
|
|
30
|
+
import { parse, stringify } from "qs";
|
|
31
|
+
var Qs = class {
|
|
32
|
+
/**
|
|
33
|
+
* Configuration object containing parse and stringify options for query strings
|
|
34
|
+
*/
|
|
35
|
+
#config;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new query string parser instance with the provided configuration
|
|
38
|
+
* @param config - Configuration object with parse and stringify options
|
|
39
|
+
*/
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.#config = config;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parses a query string into a JavaScript object using the configured options
|
|
45
|
+
* @param value - Query string to parse (e.g., "foo=bar&baz=qux")
|
|
46
|
+
* @returns Parsed object representation of the query string
|
|
47
|
+
*/
|
|
48
|
+
parse = (value) => {
|
|
49
|
+
return parse(value, this.#config.parse);
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Converts a JavaScript object into a query string using the configured options
|
|
53
|
+
* @param value - Object to convert to query string
|
|
54
|
+
* @returns Stringified query string representation of the object
|
|
55
|
+
*/
|
|
56
|
+
stringify = (value) => {
|
|
57
|
+
return stringify(value, this.#config.stringify);
|
|
58
|
+
};
|
|
59
|
+
};
|
|
8
60
|
|
|
9
61
|
// src/errors.ts
|
|
10
62
|
var errors_exports = {};
|
|
@@ -29,7 +81,17 @@ var E_HTTP_EXCEPTION = class HttpException extends Exception {
|
|
|
29
81
|
body;
|
|
30
82
|
static code = "E_HTTP_EXCEPTION";
|
|
31
83
|
/**
|
|
32
|
-
*
|
|
84
|
+
* Creates and returns an instance of the HttpException class.
|
|
85
|
+
*
|
|
86
|
+
* @param body - The response body (string, object, or null/undefined)
|
|
87
|
+
* @param status - HTTP status code for the response
|
|
88
|
+
* @param code - Optional error code (defaults to 'E_HTTP_EXCEPTION')
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const error = HttpException.invoke('Resource not found', 404)
|
|
93
|
+
* const error2 = HttpException.invoke({ message: 'Validation failed' }, 422)
|
|
94
|
+
* ```
|
|
33
95
|
*/
|
|
34
96
|
static invoke(body, status, code = "E_HTTP_EXCEPTION") {
|
|
35
97
|
if (body === null || body === void 0) {
|
|
@@ -107,42 +169,76 @@ function unpack3(key, encryptedValue, encryption) {
|
|
|
107
169
|
|
|
108
170
|
// src/cookies/client.ts
|
|
109
171
|
var CookieClient = class {
|
|
172
|
+
/**
|
|
173
|
+
* Private encryption instance used for signing and encrypting cookies
|
|
174
|
+
*/
|
|
110
175
|
#encryption;
|
|
176
|
+
/**
|
|
177
|
+
* Create a new instance of CookieClient
|
|
178
|
+
*
|
|
179
|
+
* @param encryption - The encryption instance for cookie operations
|
|
180
|
+
*/
|
|
111
181
|
constructor(encryption) {
|
|
112
182
|
this.#encryption = encryption;
|
|
113
183
|
}
|
|
114
184
|
/**
|
|
115
185
|
* Encrypt a key value pair to be sent in the cookie header
|
|
186
|
+
*
|
|
187
|
+
* @param key - The cookie key
|
|
188
|
+
* @param value - The value to encrypt
|
|
189
|
+
* @returns The encrypted cookie string or null if encryption fails
|
|
116
190
|
*/
|
|
117
191
|
encrypt(key, value) {
|
|
118
192
|
return pack3(key, value, this.#encryption);
|
|
119
193
|
}
|
|
120
194
|
/**
|
|
121
195
|
* Sign a key value pair to be sent in the cookie header
|
|
196
|
+
*
|
|
197
|
+
* @param key - The cookie key
|
|
198
|
+
* @param value - The value to sign
|
|
199
|
+
* @returns The signed cookie string or null if signing fails
|
|
122
200
|
*/
|
|
123
201
|
sign(key, value) {
|
|
124
202
|
return pack2(key, value, this.#encryption);
|
|
125
203
|
}
|
|
126
204
|
/**
|
|
127
205
|
* Encode a key value pair to be sent in the cookie header
|
|
206
|
+
*
|
|
207
|
+
* @param _ - Unused key parameter
|
|
208
|
+
* @param value - The value to encode
|
|
209
|
+
* @param stringify - Whether to stringify the value before encoding
|
|
210
|
+
* @returns The encoded cookie string or null if encoding fails
|
|
128
211
|
*/
|
|
129
212
|
encode(_, value, stringify2 = true) {
|
|
130
213
|
return stringify2 ? pack(value) : value;
|
|
131
214
|
}
|
|
132
215
|
/**
|
|
133
216
|
* Unsign a signed cookie value
|
|
217
|
+
*
|
|
218
|
+
* @param key - The cookie key
|
|
219
|
+
* @param value - The signed cookie value to unsign
|
|
220
|
+
* @returns The original value if valid signature, null otherwise
|
|
134
221
|
*/
|
|
135
222
|
unsign(key, value) {
|
|
136
223
|
return canUnpack2(value) ? unpack2(key, value, this.#encryption) : null;
|
|
137
224
|
}
|
|
138
225
|
/**
|
|
139
226
|
* Decrypt an encrypted cookie value
|
|
227
|
+
*
|
|
228
|
+
* @param key - The cookie key
|
|
229
|
+
* @param value - The encrypted cookie value to decrypt
|
|
230
|
+
* @returns The decrypted value or null if decryption fails
|
|
140
231
|
*/
|
|
141
232
|
decrypt(key, value) {
|
|
142
233
|
return canUnpack3(value) ? unpack3(key, value, this.#encryption) : null;
|
|
143
234
|
}
|
|
144
235
|
/**
|
|
145
236
|
* Decode an encoded cookie value
|
|
237
|
+
*
|
|
238
|
+
* @param _ - Unused key parameter
|
|
239
|
+
* @param value - The encoded cookie value to decode
|
|
240
|
+
* @param stringified - Whether the value was stringified during encoding
|
|
241
|
+
* @returns The decoded value or null if decoding fails
|
|
146
242
|
*/
|
|
147
243
|
decode(_, value, stringified = true) {
|
|
148
244
|
if (!stringified) {
|
|
@@ -151,7 +247,21 @@ var CookieClient = class {
|
|
|
151
247
|
return canUnpack(value) ? unpack(value) : null;
|
|
152
248
|
}
|
|
153
249
|
/**
|
|
154
|
-
* Parse
|
|
250
|
+
* Parse a cookie value by attempting to decrypt, unsign, or decode it.
|
|
251
|
+
*
|
|
252
|
+
* This method tries different unpacking strategies in order:
|
|
253
|
+
* 1. Unsign if it's a signed cookie
|
|
254
|
+
* 2. Decrypt if it's an encrypted cookie
|
|
255
|
+
* 3. Decode if it's a plain encoded cookie
|
|
256
|
+
*
|
|
257
|
+
* @param key - The cookie key
|
|
258
|
+
* @param value - The cookie value to parse
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* const parsed = client.parse('session', 'e30.abc123def')
|
|
263
|
+
* // Returns the original value if successfully parsed
|
|
264
|
+
* ```
|
|
155
265
|
*/
|
|
156
266
|
parse(key, value) {
|
|
157
267
|
if (canUnpack2(value)) {
|
|
@@ -166,998 +276,12 @@ var CookieClient = class {
|
|
|
166
276
|
}
|
|
167
277
|
};
|
|
168
278
|
|
|
169
|
-
// src/tracing_channels.ts
|
|
170
|
-
var tracing_channels_exports = {};
|
|
171
|
-
__export(tracing_channels_exports, {
|
|
172
|
-
httpExceptionHandler: () => httpExceptionHandler,
|
|
173
|
-
httpMiddleware: () => httpMiddleware,
|
|
174
|
-
httpRequest: () => httpRequest,
|
|
175
|
-
httpResponseSerializer: () => httpResponseSerializer,
|
|
176
|
-
httpRouteHandler: () => httpRouteHandler
|
|
177
|
-
});
|
|
178
|
-
import diagnostics_channel from "diagnostics_channel";
|
|
179
|
-
var httpRequest = diagnostics_channel.tracingChannel("adonisjs:http.request");
|
|
180
|
-
var httpMiddleware = diagnostics_channel.tracingChannel("adonisjs:http.middleware");
|
|
181
|
-
var httpExceptionHandler = diagnostics_channel.tracingChannel(
|
|
182
|
-
"adonisjs:http.exception.handler"
|
|
183
|
-
);
|
|
184
|
-
var httpRouteHandler = diagnostics_channel.tracingChannel("adonisjs:http.route.handler");
|
|
185
|
-
var httpResponseSerializer = diagnostics_channel.tracingChannel(
|
|
186
|
-
"adonisjs:http.response.serializer"
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// src/router/route.ts
|
|
190
|
-
import is from "@sindresorhus/is";
|
|
191
|
-
import Macroable4 from "@poppinss/macroable";
|
|
192
|
-
import Middleware from "@poppinss/middleware";
|
|
193
|
-
import { RuntimeException as RuntimeException2 } from "@poppinss/utils/exception";
|
|
194
|
-
import { moduleCaller, moduleImporter } from "@adonisjs/fold";
|
|
195
|
-
|
|
196
|
-
// src/debug.ts
|
|
197
|
-
import { debuglog } from "util";
|
|
198
|
-
var debug_default = debuglog("adonisjs:http");
|
|
199
|
-
|
|
200
|
-
// src/router/factories/use_return_value.ts
|
|
201
|
-
function canWriteResponseBody(value, ctx) {
|
|
202
|
-
return value !== void 0 && // Return value is explicitly defined
|
|
203
|
-
!ctx.response.hasLazyBody && // Lazy body is not set
|
|
204
|
-
value !== ctx.response;
|
|
205
|
-
}
|
|
206
|
-
function useReturnValue(ctx) {
|
|
207
|
-
return function(value) {
|
|
208
|
-
if (canWriteResponseBody(value, ctx)) {
|
|
209
|
-
ctx.response.send(value);
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// src/router/executor.ts
|
|
215
|
-
function execute(route, resolver, ctx, errorResponder) {
|
|
216
|
-
return route.middleware.runner().errorHandler((error) => errorResponder(error, ctx)).finalHandler(() => {
|
|
217
|
-
if (typeof route.handler === "function") {
|
|
218
|
-
return httpRouteHandler.tracePromise(
|
|
219
|
-
($ctx) => Promise.resolve(route.handler($ctx)),
|
|
220
|
-
route,
|
|
221
|
-
void 0,
|
|
222
|
-
ctx
|
|
223
|
-
).then(useReturnValue(ctx));
|
|
224
|
-
}
|
|
225
|
-
return httpRouteHandler.tracePromise(
|
|
226
|
-
route.handler.handle,
|
|
227
|
-
route,
|
|
228
|
-
void 0,
|
|
229
|
-
resolver,
|
|
230
|
-
ctx
|
|
231
|
-
).then(useReturnValue(ctx));
|
|
232
|
-
}).run(async (middleware, next) => {
|
|
233
|
-
if (typeof middleware === "function") {
|
|
234
|
-
return httpMiddleware.tracePromise(
|
|
235
|
-
middleware,
|
|
236
|
-
middleware,
|
|
237
|
-
void 0,
|
|
238
|
-
ctx,
|
|
239
|
-
next
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
return httpMiddleware.tracePromise(
|
|
243
|
-
middleware.handle,
|
|
244
|
-
middleware,
|
|
245
|
-
void 0,
|
|
246
|
-
resolver,
|
|
247
|
-
ctx,
|
|
248
|
-
next,
|
|
249
|
-
middleware.args
|
|
250
|
-
);
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// src/utils.ts
|
|
255
|
-
import Cache from "tmp-cache";
|
|
256
|
-
import { InvalidArgumentsException } from "@poppinss/utils/exception";
|
|
257
|
-
|
|
258
|
-
// src/router/group.ts
|
|
259
|
-
import Macroable3 from "@poppinss/macroable";
|
|
260
|
-
|
|
261
|
-
// src/router/brisk.ts
|
|
262
|
-
import Macroable from "@poppinss/macroable";
|
|
263
|
-
var BriskRoute = class extends Macroable {
|
|
264
|
-
/**
|
|
265
|
-
* Route pattern
|
|
266
|
-
*/
|
|
267
|
-
#pattern;
|
|
268
|
-
/**
|
|
269
|
-
* Matchers inherited from the router
|
|
270
|
-
*/
|
|
271
|
-
#globalMatchers;
|
|
272
|
-
/**
|
|
273
|
-
* Reference to the AdonisJS application
|
|
274
|
-
*/
|
|
275
|
-
#app;
|
|
276
|
-
/**
|
|
277
|
-
* Middleware registered on the router
|
|
278
|
-
*/
|
|
279
|
-
#routerMiddleware;
|
|
280
|
-
/**
|
|
281
|
-
* Reference to route instance. Set after `setHandler` is called
|
|
282
|
-
*/
|
|
283
|
-
route = null;
|
|
284
|
-
constructor(app, routerMiddleware, options) {
|
|
285
|
-
super();
|
|
286
|
-
this.#app = app;
|
|
287
|
-
this.#routerMiddleware = routerMiddleware;
|
|
288
|
-
this.#pattern = options.pattern;
|
|
289
|
-
this.#globalMatchers = options.globalMatchers;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Set handler for the brisk route
|
|
293
|
-
*/
|
|
294
|
-
setHandler(handler) {
|
|
295
|
-
this.route = new Route(this.#app, this.#routerMiddleware, {
|
|
296
|
-
pattern: this.#pattern,
|
|
297
|
-
globalMatchers: this.#globalMatchers,
|
|
298
|
-
methods: ["GET", "HEAD"],
|
|
299
|
-
handler
|
|
300
|
-
});
|
|
301
|
-
return this.route;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Redirects to a given route. Params from the original request will
|
|
305
|
-
* be used when no custom params are defined.
|
|
306
|
-
*/
|
|
307
|
-
redirect(...args) {
|
|
308
|
-
const [identifier, params, options] = args;
|
|
309
|
-
function redirectsToRoute(ctx) {
|
|
310
|
-
const redirector = ctx.response.redirect();
|
|
311
|
-
if (options?.status) {
|
|
312
|
-
redirector.status(options.status);
|
|
313
|
-
}
|
|
314
|
-
return redirector.toRoute(identifier, params || ctx.params, options);
|
|
315
|
-
}
|
|
316
|
-
Object.defineProperty(redirectsToRoute, "listArgs", { value: identifier, writable: false });
|
|
317
|
-
return this.setHandler(redirectsToRoute);
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Redirect request to a fixed URL
|
|
321
|
-
*/
|
|
322
|
-
redirectToPath(url, options) {
|
|
323
|
-
function redirectsToPath(ctx) {
|
|
324
|
-
const redirector = ctx.response.redirect();
|
|
325
|
-
if (options?.status) {
|
|
326
|
-
redirector.status(options.status);
|
|
327
|
-
}
|
|
328
|
-
return redirector.toPath(url);
|
|
329
|
-
}
|
|
330
|
-
Object.defineProperty(redirectsToPath, "listArgs", { value: url, writable: false });
|
|
331
|
-
return this.setHandler(redirectsToPath);
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// src/router/resource.ts
|
|
336
|
-
import string from "@poppinss/utils/string";
|
|
337
|
-
import Macroable2 from "@poppinss/macroable";
|
|
338
|
-
import { RuntimeException } from "@poppinss/utils/exception";
|
|
339
|
-
var RouteResource = class extends Macroable2 {
|
|
340
|
-
/**
|
|
341
|
-
* Resource identifier. Nested resources are separated
|
|
342
|
-
* with a dot notation
|
|
343
|
-
*/
|
|
344
|
-
#resource;
|
|
345
|
-
/**
|
|
346
|
-
* The controller to handle resource routing requests
|
|
347
|
-
*/
|
|
348
|
-
#controller;
|
|
349
|
-
/**
|
|
350
|
-
* Is it a shallow resource? Shallow resources URLs do not have parent
|
|
351
|
-
* resource name and id once they can be identified with the id.
|
|
352
|
-
*/
|
|
353
|
-
#shallow = false;
|
|
354
|
-
/**
|
|
355
|
-
* Matchers inherited from the router
|
|
356
|
-
*/
|
|
357
|
-
#globalMatchers;
|
|
358
|
-
/**
|
|
359
|
-
* Reference to the AdonisJS application
|
|
360
|
-
*/
|
|
361
|
-
#app;
|
|
362
|
-
/**
|
|
363
|
-
* Middleware registered on the router
|
|
364
|
-
*/
|
|
365
|
-
#routerMiddleware;
|
|
366
|
-
/**
|
|
367
|
-
* Parameter names for the resources. Defaults to `id` for
|
|
368
|
-
* a singular resource and `resource_id` for nested
|
|
369
|
-
* resources.
|
|
370
|
-
*/
|
|
371
|
-
#params = {};
|
|
372
|
-
/**
|
|
373
|
-
* Base name for the routes. We suffix action names
|
|
374
|
-
* on top of the base name
|
|
375
|
-
*/
|
|
376
|
-
#routesBaseName;
|
|
377
|
-
/**
|
|
378
|
-
* A collection of routes instances that belongs to this resource
|
|
379
|
-
*/
|
|
380
|
-
routes = [];
|
|
381
|
-
constructor(app, routerMiddleware, options) {
|
|
382
|
-
super();
|
|
383
|
-
this.#validateResourceName(options.resource);
|
|
384
|
-
this.#app = app;
|
|
385
|
-
this.#shallow = options.shallow;
|
|
386
|
-
this.#routerMiddleware = routerMiddleware;
|
|
387
|
-
this.#controller = options.controller;
|
|
388
|
-
this.#globalMatchers = options.globalMatchers;
|
|
389
|
-
this.#resource = this.#normalizeResourceName(options.resource);
|
|
390
|
-
this.#routesBaseName = this.#getRoutesBaseName();
|
|
391
|
-
this.#buildRoutes();
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Normalizes the resource name to dropping leading and trailing
|
|
395
|
-
* slashes.
|
|
396
|
-
*/
|
|
397
|
-
#normalizeResourceName(resource) {
|
|
398
|
-
return resource.replace(/^\//, "").replace(/\/$/, "");
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Ensure resource name is not an empty string
|
|
402
|
-
*/
|
|
403
|
-
#validateResourceName(resource) {
|
|
404
|
-
if (!resource || resource === "/") {
|
|
405
|
-
throw new RuntimeException(`Invalid resource name "${resource}"`);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Converting segments of a resource to snake case to
|
|
410
|
-
* make the route name.
|
|
411
|
-
*/
|
|
412
|
-
#getRoutesBaseName() {
|
|
413
|
-
return this.#resource.split(".").map((token) => string.snakeCase(token)).join(".");
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Create a new route for the given pattern, methods and controller action
|
|
417
|
-
*/
|
|
418
|
-
#createRoute(pattern, methods, action) {
|
|
419
|
-
const route = new Route(this.#app, this.#routerMiddleware, {
|
|
420
|
-
pattern,
|
|
421
|
-
methods,
|
|
422
|
-
handler: typeof this.#controller === "string" ? `${this.#controller}.${action}` : [this.#controller, action],
|
|
423
|
-
globalMatchers: this.#globalMatchers
|
|
424
|
-
});
|
|
425
|
-
route.as(`${this.#routesBaseName}.${action}`);
|
|
426
|
-
this.routes.push(route);
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Returns the `resource_id` name for a given resource. The
|
|
430
|
-
* resource name is converted to singular form and
|
|
431
|
-
* transformed to snake case.
|
|
432
|
-
*
|
|
433
|
-
* photos becomes photo_id
|
|
434
|
-
* users becomes user_id
|
|
435
|
-
*/
|
|
436
|
-
#getResourceId(resource) {
|
|
437
|
-
return `${string.snakeCase(string.singular(resource))}_id`;
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Build routes for the given resource
|
|
441
|
-
*/
|
|
442
|
-
#buildRoutes() {
|
|
443
|
-
const resources = this.#resource.split(".");
|
|
444
|
-
const mainResource = resources.pop();
|
|
445
|
-
this.#params[mainResource] = ":id";
|
|
446
|
-
const baseURI = `${resources.map((resource) => {
|
|
447
|
-
const paramName = `:${this.#getResourceId(resource)}`;
|
|
448
|
-
this.#params[resource] = paramName;
|
|
449
|
-
return `${resource}/${paramName}`;
|
|
450
|
-
}).join("/")}/${mainResource}`;
|
|
451
|
-
this.#createRoute(baseURI, ["GET", "HEAD"], "index");
|
|
452
|
-
this.#createRoute(`${baseURI}/create`, ["GET", "HEAD"], "create");
|
|
453
|
-
this.#createRoute(baseURI, ["POST"], "store");
|
|
454
|
-
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["GET", "HEAD"], "show");
|
|
455
|
-
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id/edit`, ["GET", "HEAD"], "edit");
|
|
456
|
-
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["PUT", "PATCH"], "update");
|
|
457
|
-
this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ["DELETE"], "destroy");
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Filter the routes based on their partial names
|
|
461
|
-
*/
|
|
462
|
-
#filter(names, inverse) {
|
|
463
|
-
const actions = Array.isArray(names) ? names : [names];
|
|
464
|
-
return this.routes.filter((route) => {
|
|
465
|
-
const match = actions.find((name) => route.getName().endsWith(name));
|
|
466
|
-
return inverse ? !match : match;
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Register only given routes and remove others
|
|
471
|
-
*/
|
|
472
|
-
only(names) {
|
|
473
|
-
this.#filter(names, true).forEach((route) => route.markAsDeleted());
|
|
474
|
-
return this;
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* Register all routes, except the one's defined
|
|
478
|
-
*/
|
|
479
|
-
except(names) {
|
|
480
|
-
this.#filter(names, false).forEach((route) => route.markAsDeleted());
|
|
481
|
-
return this;
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Register api only routes. The `create` and `edit` routes, which
|
|
485
|
-
* are meant to show forms will not be registered
|
|
486
|
-
*/
|
|
487
|
-
apiOnly() {
|
|
488
|
-
return this.except(["create", "edit"]);
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Define matcher for params inside the resource
|
|
492
|
-
*/
|
|
493
|
-
where(key, matcher) {
|
|
494
|
-
this.routes.forEach((route) => {
|
|
495
|
-
route.where(key, matcher);
|
|
496
|
-
});
|
|
497
|
-
return this;
|
|
498
|
-
}
|
|
499
|
-
tap(actions, callback) {
|
|
500
|
-
if (typeof actions === "function") {
|
|
501
|
-
this.routes.forEach((route) => {
|
|
502
|
-
if (!route.isDeleted()) {
|
|
503
|
-
actions(route);
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
return this;
|
|
507
|
-
}
|
|
508
|
-
this.#filter(actions, false).forEach((route) => {
|
|
509
|
-
if (!route.isDeleted()) {
|
|
510
|
-
callback(route);
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
return this;
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Set the param name for a given resource
|
|
517
|
-
*/
|
|
518
|
-
params(resources) {
|
|
519
|
-
Object.keys(resources).forEach((resource) => {
|
|
520
|
-
const param = resources[resource];
|
|
521
|
-
const existingParam = this.#params[resource];
|
|
522
|
-
this.#params[resource] = `:${param}`;
|
|
523
|
-
this.routes.forEach((route) => {
|
|
524
|
-
route.setPattern(
|
|
525
|
-
route.getPattern().replace(`${resource}/${existingParam}`, `${resource}/:${param}`)
|
|
526
|
-
);
|
|
527
|
-
});
|
|
528
|
-
});
|
|
529
|
-
return this;
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* Define one or more middleware on the routes created by
|
|
533
|
-
* the resource.
|
|
534
|
-
*
|
|
535
|
-
* Calling this method multiple times will append middleware
|
|
536
|
-
* to existing list.
|
|
537
|
-
*/
|
|
538
|
-
use(actions, middleware) {
|
|
539
|
-
if (actions === "*") {
|
|
540
|
-
this.tap((route) => route.use(middleware));
|
|
541
|
-
} else {
|
|
542
|
-
this.tap(actions, (route) => route.use(middleware));
|
|
543
|
-
}
|
|
544
|
-
return this;
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* @alias use
|
|
548
|
-
*/
|
|
549
|
-
middleware(actions, middleware) {
|
|
550
|
-
return this.use(actions, middleware);
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Prepend name to all the routes
|
|
554
|
-
*/
|
|
555
|
-
as(name, normalizeName = true) {
|
|
556
|
-
name = normalizeName ? string.snakeCase(name) : name;
|
|
557
|
-
this.routes.forEach((route) => {
|
|
558
|
-
route.as(route.getName().replace(this.#routesBaseName, name), false);
|
|
559
|
-
});
|
|
560
|
-
this.#routesBaseName = name;
|
|
561
|
-
return this;
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
|
|
565
|
-
// src/router/group.ts
|
|
566
|
-
var RouteGroup = class _RouteGroup extends Macroable3 {
|
|
567
|
-
constructor(routes) {
|
|
568
|
-
super();
|
|
569
|
-
this.routes = routes;
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* Array of middleware registered on the group.
|
|
573
|
-
*/
|
|
574
|
-
#middleware = [];
|
|
575
|
-
/**
|
|
576
|
-
* Shares midldeware stack with the routes. The method is invoked recursively
|
|
577
|
-
* to only register middleware with the route class and not with the
|
|
578
|
-
* resource or the child group
|
|
579
|
-
*/
|
|
580
|
-
#shareMiddlewareStackWithRoutes(route) {
|
|
581
|
-
if (route instanceof _RouteGroup) {
|
|
582
|
-
route.routes.forEach((child) => this.#shareMiddlewareStackWithRoutes(child));
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
if (route instanceof RouteResource) {
|
|
586
|
-
route.routes.forEach((child) => child.getMiddleware().unshift(this.#middleware));
|
|
587
|
-
return;
|
|
588
|
-
}
|
|
589
|
-
if (route instanceof BriskRoute) {
|
|
590
|
-
route.route.getMiddleware().unshift(this.#middleware);
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
route.getMiddleware().unshift(this.#middleware);
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Updates the route name. The method is invoked recursively to only update
|
|
597
|
-
* the name with the route class and not with the resource or the child
|
|
598
|
-
* group.
|
|
599
|
-
*/
|
|
600
|
-
#updateRouteName(route, name) {
|
|
601
|
-
if (route instanceof _RouteGroup) {
|
|
602
|
-
route.routes.forEach((child) => this.#updateRouteName(child, name));
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
if (route instanceof RouteResource) {
|
|
606
|
-
route.routes.forEach((child) => child.as(name, true));
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
if (route instanceof BriskRoute) {
|
|
610
|
-
route.route.as(name, true);
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
route.as(name, true);
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Sets prefix on the route. The method is invoked recursively to only set
|
|
617
|
-
* the prefix with the route class and not with the resource or the
|
|
618
|
-
* child group.
|
|
619
|
-
*/
|
|
620
|
-
#setRoutePrefix(route, prefix) {
|
|
621
|
-
if (route instanceof _RouteGroup) {
|
|
622
|
-
route.routes.forEach((child) => this.#setRoutePrefix(child, prefix));
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
if (route instanceof RouteResource) {
|
|
626
|
-
route.routes.forEach((child) => child.prefix(prefix));
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
if (route instanceof BriskRoute) {
|
|
630
|
-
route.route.prefix(prefix);
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
633
|
-
route.prefix(prefix);
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Updates domain on the route. The method is invoked recursively to only update
|
|
637
|
-
* the domain with the route class and not with the resource or the child
|
|
638
|
-
* group.
|
|
639
|
-
*/
|
|
640
|
-
#updateRouteDomain(route, domain) {
|
|
641
|
-
if (route instanceof _RouteGroup) {
|
|
642
|
-
route.routes.forEach((child) => this.#updateRouteDomain(child, domain));
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (route instanceof RouteResource) {
|
|
646
|
-
route.routes.forEach((child) => child.domain(domain));
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
if (route instanceof BriskRoute) {
|
|
650
|
-
route.route.domain(domain, false);
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
route.domain(domain, false);
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* Updates matchers on the route. The method is invoked recursively to only update
|
|
657
|
-
* the matchers with the route class and not with the resource or the child
|
|
658
|
-
* group.
|
|
659
|
-
*/
|
|
660
|
-
#updateRouteMatchers(route, param, matcher) {
|
|
661
|
-
if (route instanceof _RouteGroup) {
|
|
662
|
-
route.routes.forEach((child) => this.#updateRouteMatchers(child, param, matcher));
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
if (route instanceof RouteResource) {
|
|
666
|
-
route.routes.forEach((child) => child.where(param, matcher));
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
if (route instanceof BriskRoute) {
|
|
670
|
-
route.route.where(param, matcher);
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
route.where(param, matcher);
|
|
674
|
-
}
|
|
675
|
-
/**
|
|
676
|
-
* Define route param matcher
|
|
677
|
-
*
|
|
678
|
-
* ```ts
|
|
679
|
-
* Route.group(() => {
|
|
680
|
-
* }).where('id', /^[0-9]+/)
|
|
681
|
-
* ```
|
|
682
|
-
*/
|
|
683
|
-
where(param, matcher) {
|
|
684
|
-
this.routes.forEach((route) => this.#updateRouteMatchers(route, param, matcher));
|
|
685
|
-
return this;
|
|
686
|
-
}
|
|
687
|
-
/**
|
|
688
|
-
* Define prefix all the routes in the group.
|
|
689
|
-
*
|
|
690
|
-
* ```ts
|
|
691
|
-
* Route.group(() => {
|
|
692
|
-
* }).prefix('v1')
|
|
693
|
-
* ```
|
|
694
|
-
*/
|
|
695
|
-
prefix(prefix) {
|
|
696
|
-
this.routes.forEach((route) => this.#setRoutePrefix(route, prefix));
|
|
697
|
-
return this;
|
|
698
|
-
}
|
|
699
|
-
/**
|
|
700
|
-
* Define domain for all the routes.
|
|
701
|
-
*
|
|
702
|
-
* ```ts
|
|
703
|
-
* Route.group(() => {
|
|
704
|
-
* }).domain(':name.adonisjs.com')
|
|
705
|
-
* ```
|
|
706
|
-
*/
|
|
707
|
-
domain(domain) {
|
|
708
|
-
this.routes.forEach((route) => this.#updateRouteDomain(route, domain));
|
|
709
|
-
return this;
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* Prepend name to the routes name.
|
|
713
|
-
*
|
|
714
|
-
* ```ts
|
|
715
|
-
* Route.group(() => {
|
|
716
|
-
* }).as('version1')
|
|
717
|
-
* ```
|
|
718
|
-
*/
|
|
719
|
-
as(name) {
|
|
720
|
-
this.routes.forEach((route) => this.#updateRouteName(route, name));
|
|
721
|
-
return this;
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* Prepend an array of middleware to all routes middleware.
|
|
725
|
-
*
|
|
726
|
-
* ```ts
|
|
727
|
-
* Route.group(() => {
|
|
728
|
-
* }).use(middleware.auth())
|
|
729
|
-
* ```
|
|
730
|
-
*/
|
|
731
|
-
use(middleware) {
|
|
732
|
-
if (!this.#middleware.length) {
|
|
733
|
-
this.routes.forEach((route) => this.#shareMiddlewareStackWithRoutes(route));
|
|
734
|
-
}
|
|
735
|
-
if (Array.isArray(middleware)) {
|
|
736
|
-
for (let one of middleware) {
|
|
737
|
-
this.#middleware.push(one);
|
|
738
|
-
}
|
|
739
|
-
} else {
|
|
740
|
-
this.#middleware.push(middleware);
|
|
741
|
-
}
|
|
742
|
-
return this;
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* @alias use
|
|
746
|
-
*/
|
|
747
|
-
middleware(middleware) {
|
|
748
|
-
return this.use(middleware);
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
// src/utils.ts
|
|
753
|
-
var proxyCache = new Cache({ max: 200 });
|
|
754
|
-
function dropSlash(input) {
|
|
755
|
-
if (input === "/") {
|
|
756
|
-
return "/";
|
|
757
|
-
}
|
|
758
|
-
return `/${input.replace(/^\//, "").replace(/\/$/, "")}`;
|
|
759
|
-
}
|
|
760
|
-
function toRoutesJSON(routes) {
|
|
761
|
-
return routes.reduce((list, route) => {
|
|
762
|
-
if (route instanceof RouteGroup) {
|
|
763
|
-
list = list.concat(toRoutesJSON(route.routes));
|
|
764
|
-
return list;
|
|
765
|
-
}
|
|
766
|
-
if (route instanceof RouteResource) {
|
|
767
|
-
list = list.concat(toRoutesJSON(route.routes));
|
|
768
|
-
return list;
|
|
769
|
-
}
|
|
770
|
-
if (route instanceof BriskRoute) {
|
|
771
|
-
if (route.route && !route.route.isDeleted()) {
|
|
772
|
-
list.push(route.route.toJSON());
|
|
773
|
-
}
|
|
774
|
-
return list;
|
|
775
|
-
}
|
|
776
|
-
if (!route.isDeleted()) {
|
|
777
|
-
list.push(route.toJSON());
|
|
778
|
-
}
|
|
779
|
-
return list;
|
|
780
|
-
}, []);
|
|
781
|
-
}
|
|
782
|
-
function trustProxy(remoteAddress, proxyFn) {
|
|
783
|
-
if (proxyCache.has(remoteAddress)) {
|
|
784
|
-
return proxyCache.get(remoteAddress);
|
|
785
|
-
}
|
|
786
|
-
const result = proxyFn(remoteAddress, 0);
|
|
787
|
-
proxyCache.set(remoteAddress, result);
|
|
788
|
-
return result;
|
|
789
|
-
}
|
|
790
|
-
function parseRange(range, value) {
|
|
791
|
-
const parts = range.split("..");
|
|
792
|
-
const min = Number(parts[0]);
|
|
793
|
-
const max = Number(parts[1]);
|
|
794
|
-
if (parts.length === 1 && !Number.isNaN(min)) {
|
|
795
|
-
return {
|
|
796
|
-
[min]: value
|
|
797
|
-
};
|
|
798
|
-
}
|
|
799
|
-
if (Number.isNaN(min) || Number.isNaN(max)) {
|
|
800
|
-
return {};
|
|
801
|
-
}
|
|
802
|
-
if (min === max) {
|
|
803
|
-
return {
|
|
804
|
-
[min]: value
|
|
805
|
-
};
|
|
806
|
-
}
|
|
807
|
-
if (max < min) {
|
|
808
|
-
throw new InvalidArgumentsException(`Invalid range "${range}"`);
|
|
809
|
-
}
|
|
810
|
-
return [...Array(max - min + 1).keys()].reduce(
|
|
811
|
-
(result, step) => {
|
|
812
|
-
result[min + step] = value;
|
|
813
|
-
return result;
|
|
814
|
-
},
|
|
815
|
-
{}
|
|
816
|
-
);
|
|
817
|
-
}
|
|
818
|
-
function decodeComponentChar(highCharCode, lowCharCode) {
|
|
819
|
-
if (highCharCode === 50) {
|
|
820
|
-
if (lowCharCode === 53) return "%";
|
|
821
|
-
if (lowCharCode === 51) return "#";
|
|
822
|
-
if (lowCharCode === 52) return "$";
|
|
823
|
-
if (lowCharCode === 54) return "&";
|
|
824
|
-
if (lowCharCode === 66) return "+";
|
|
825
|
-
if (lowCharCode === 98) return "+";
|
|
826
|
-
if (lowCharCode === 67) return ",";
|
|
827
|
-
if (lowCharCode === 99) return ",";
|
|
828
|
-
if (lowCharCode === 70) return "/";
|
|
829
|
-
if (lowCharCode === 102) return "/";
|
|
830
|
-
return null;
|
|
831
|
-
}
|
|
832
|
-
if (highCharCode === 51) {
|
|
833
|
-
if (lowCharCode === 65) return ":";
|
|
834
|
-
if (lowCharCode === 97) return ":";
|
|
835
|
-
if (lowCharCode === 66) return ";";
|
|
836
|
-
if (lowCharCode === 98) return ";";
|
|
837
|
-
if (lowCharCode === 68) return "=";
|
|
838
|
-
if (lowCharCode === 100) return "=";
|
|
839
|
-
if (lowCharCode === 70) return "?";
|
|
840
|
-
if (lowCharCode === 102) return "?";
|
|
841
|
-
return null;
|
|
842
|
-
}
|
|
843
|
-
if (highCharCode === 52 && lowCharCode === 48) {
|
|
844
|
-
return "@";
|
|
845
|
-
}
|
|
846
|
-
return null;
|
|
847
|
-
}
|
|
848
|
-
function safeDecodeURI(path, useSemicolonDelimiter) {
|
|
849
|
-
let shouldDecode = false;
|
|
850
|
-
let shouldDecodeParam = false;
|
|
851
|
-
let querystring = "";
|
|
852
|
-
for (let i = 1; i < path.length; i++) {
|
|
853
|
-
const charCode = path.charCodeAt(i);
|
|
854
|
-
if (charCode === 37) {
|
|
855
|
-
const highCharCode = path.charCodeAt(i + 1);
|
|
856
|
-
const lowCharCode = path.charCodeAt(i + 2);
|
|
857
|
-
if (decodeComponentChar(highCharCode, lowCharCode) === null) {
|
|
858
|
-
shouldDecode = true;
|
|
859
|
-
} else {
|
|
860
|
-
shouldDecodeParam = true;
|
|
861
|
-
if (highCharCode === 50 && lowCharCode === 53) {
|
|
862
|
-
shouldDecode = true;
|
|
863
|
-
path = path.slice(0, i + 1) + "25" + path.slice(i + 1);
|
|
864
|
-
i += 2;
|
|
865
|
-
}
|
|
866
|
-
i += 2;
|
|
867
|
-
}
|
|
868
|
-
} else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
|
|
869
|
-
querystring = path.slice(i + 1);
|
|
870
|
-
path = path.slice(0, i);
|
|
871
|
-
break;
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
const decodedPath = shouldDecode ? decodeURI(path) : path;
|
|
875
|
-
return { pathname: decodedPath, query: querystring, shouldDecodeParam };
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
// src/router/route.ts
|
|
879
|
-
var Route = class extends Macroable4 {
|
|
880
|
-
/**
|
|
881
|
-
* Route pattern
|
|
882
|
-
*/
|
|
883
|
-
#pattern;
|
|
884
|
-
/**
|
|
885
|
-
* HTTP Methods for the route
|
|
886
|
-
*/
|
|
887
|
-
#methods;
|
|
888
|
-
/**
|
|
889
|
-
* A unique name for the route
|
|
890
|
-
*/
|
|
891
|
-
#name;
|
|
892
|
-
/**
|
|
893
|
-
* A boolean to prevent route from getting registered within
|
|
894
|
-
* the store.
|
|
895
|
-
*
|
|
896
|
-
* This flag must be set before "Router.commit" method
|
|
897
|
-
*/
|
|
898
|
-
#isDeleted = false;
|
|
899
|
-
/**
|
|
900
|
-
* Route handler
|
|
901
|
-
*/
|
|
902
|
-
#handler;
|
|
903
|
-
/**
|
|
904
|
-
* Matchers inherited from the router
|
|
905
|
-
*/
|
|
906
|
-
#globalMatchers;
|
|
907
|
-
/**
|
|
908
|
-
* Reference to the AdonisJS application
|
|
909
|
-
*/
|
|
910
|
-
#app;
|
|
911
|
-
/**
|
|
912
|
-
* Middleware registered on the router
|
|
913
|
-
*/
|
|
914
|
-
#routerMiddleware;
|
|
915
|
-
/**
|
|
916
|
-
* By default the route is part of the `root` domain. Root domain is used
|
|
917
|
-
* when no domain is defined
|
|
918
|
-
*/
|
|
919
|
-
#routeDomain = "root";
|
|
920
|
-
/**
|
|
921
|
-
* An object of matchers to be forwarded to the store. The matchers
|
|
922
|
-
* list is populated by calling `where` method
|
|
923
|
-
*/
|
|
924
|
-
#matchers = {};
|
|
925
|
-
/**
|
|
926
|
-
* Custom prefixes defined on the route or the route parent
|
|
927
|
-
* groups
|
|
928
|
-
*/
|
|
929
|
-
#prefixes = [];
|
|
930
|
-
/**
|
|
931
|
-
* Middleware defined directly on the route or the route parent
|
|
932
|
-
* routes. We mantain an array for each layer of the stack
|
|
933
|
-
*/
|
|
934
|
-
#middleware = [];
|
|
935
|
-
constructor(app, routerMiddleware, options) {
|
|
936
|
-
super();
|
|
937
|
-
this.#app = app;
|
|
938
|
-
this.#routerMiddleware = routerMiddleware;
|
|
939
|
-
this.#pattern = options.pattern;
|
|
940
|
-
this.#methods = options.methods;
|
|
941
|
-
this.#handler = this.#resolveRouteHandle(options.handler);
|
|
942
|
-
this.#globalMatchers = options.globalMatchers;
|
|
943
|
-
}
|
|
944
|
-
/**
|
|
945
|
-
* Resolves the route handler string expression to a
|
|
946
|
-
* handler method object
|
|
947
|
-
*/
|
|
948
|
-
#resolveRouteHandle(handler) {
|
|
949
|
-
if (typeof handler === "string") {
|
|
950
|
-
const parts = handler.split(".");
|
|
951
|
-
const method = parts.length === 1 ? "handle" : parts.pop();
|
|
952
|
-
const moduleRefId = parts.join(".");
|
|
953
|
-
return {
|
|
954
|
-
reference: handler,
|
|
955
|
-
...moduleImporter(() => this.#app.import(moduleRefId), method).toHandleMethod(),
|
|
956
|
-
name: handler
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
if (Array.isArray(handler)) {
|
|
960
|
-
if (is.class(handler[0])) {
|
|
961
|
-
return {
|
|
962
|
-
reference: handler,
|
|
963
|
-
...moduleCaller(handler[0], handler[1] || "handle").toHandleMethod()
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
return {
|
|
967
|
-
reference: handler,
|
|
968
|
-
...moduleImporter(handler[0], handler[1] || "handle").toHandleMethod()
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
return handler;
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Returns an object of param matchers by merging global and local
|
|
975
|
-
* matchers. The local copy is given preference over the global
|
|
976
|
-
* one's
|
|
977
|
-
*/
|
|
978
|
-
#getMatchers() {
|
|
979
|
-
return { ...this.#globalMatchers, ...this.#matchers };
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Returns a normalized pattern string by prefixing the `prefix` (if defined).
|
|
983
|
-
*/
|
|
984
|
-
#computePattern() {
|
|
985
|
-
const pattern = dropSlash(this.#pattern);
|
|
986
|
-
const prefix = this.#prefixes.slice().reverse().map((one) => dropSlash(one)).join("");
|
|
987
|
-
return prefix ? `${prefix}${pattern === "/" ? "" : pattern}` : pattern;
|
|
988
|
-
}
|
|
989
|
-
/**
|
|
990
|
-
* Define matcher for a given param. If a matcher exists, then we do not
|
|
991
|
-
* override that, since the routes inside a group will set matchers
|
|
992
|
-
* before the group, so they should have priority over the group
|
|
993
|
-
* matchers.
|
|
994
|
-
*
|
|
995
|
-
* ```ts
|
|
996
|
-
* Route.group(() => {
|
|
997
|
-
* Route.get('/:id', 'handler').where('id', /^[0-9]$/)
|
|
998
|
-
* }).where('id', /[^a-z$]/)
|
|
999
|
-
* ```
|
|
1000
|
-
*
|
|
1001
|
-
* The `/^[0-9]$/` will win over the matcher defined by the group
|
|
1002
|
-
*/
|
|
1003
|
-
where(param, matcher) {
|
|
1004
|
-
if (this.#matchers[param]) {
|
|
1005
|
-
return this;
|
|
1006
|
-
}
|
|
1007
|
-
if (typeof matcher === "string") {
|
|
1008
|
-
this.#matchers[param] = { match: new RegExp(matcher) };
|
|
1009
|
-
} else if (is.regExp(matcher)) {
|
|
1010
|
-
this.#matchers[param] = { match: matcher };
|
|
1011
|
-
} else {
|
|
1012
|
-
this.#matchers[param] = matcher;
|
|
1013
|
-
}
|
|
1014
|
-
return this;
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Define prefix for the route. Calling this method multiple times
|
|
1018
|
-
* applies multiple prefixes in the reverse order.
|
|
1019
|
-
*/
|
|
1020
|
-
prefix(prefix) {
|
|
1021
|
-
this.#prefixes.push(prefix);
|
|
1022
|
-
return this;
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Define a custom domain for the route. We do not overwrite the domain
|
|
1026
|
-
* unless `overwrite` flag is set to true.
|
|
1027
|
-
*/
|
|
1028
|
-
domain(domain, overwrite = false) {
|
|
1029
|
-
if (this.#routeDomain === "root" || overwrite) {
|
|
1030
|
-
this.#routeDomain = domain;
|
|
1031
|
-
}
|
|
1032
|
-
return this;
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Define one or more middleware to be executed before the route
|
|
1036
|
-
* handler.
|
|
1037
|
-
*
|
|
1038
|
-
* Named middleware can be referenced using the name registered with
|
|
1039
|
-
* the router middleware store.
|
|
1040
|
-
*/
|
|
1041
|
-
use(middleware) {
|
|
1042
|
-
this.#middleware.push(Array.isArray(middleware) ? middleware : [middleware]);
|
|
1043
|
-
return this;
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* @alias use
|
|
1047
|
-
*/
|
|
1048
|
-
middleware(middleware) {
|
|
1049
|
-
return this.use(middleware);
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Give a unique name to the route. Assinging a new unique removes the
|
|
1053
|
-
* existing name of the route.
|
|
1054
|
-
*
|
|
1055
|
-
* Setting prepends to true prefixes the name to the existing name.
|
|
1056
|
-
*/
|
|
1057
|
-
as(name, prepend = false) {
|
|
1058
|
-
if (prepend) {
|
|
1059
|
-
if (!this.#name) {
|
|
1060
|
-
throw new RuntimeException2(
|
|
1061
|
-
`Routes inside a group must have names before calling "router.group.as"`
|
|
1062
|
-
);
|
|
1063
|
-
}
|
|
1064
|
-
this.#name = `${name}.${this.#name}`;
|
|
1065
|
-
return this;
|
|
1066
|
-
}
|
|
1067
|
-
this.#name = name;
|
|
1068
|
-
return this;
|
|
1069
|
-
}
|
|
1070
|
-
/**
|
|
1071
|
-
* Check if the route was marked to be deleted
|
|
1072
|
-
*/
|
|
1073
|
-
isDeleted() {
|
|
1074
|
-
return this.#isDeleted;
|
|
1075
|
-
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Mark route as deleted. Deleted routes are not registered
|
|
1078
|
-
* with the route store
|
|
1079
|
-
*/
|
|
1080
|
-
markAsDeleted() {
|
|
1081
|
-
this.#isDeleted = true;
|
|
1082
|
-
}
|
|
1083
|
-
/**
|
|
1084
|
-
* Get the route name
|
|
1085
|
-
*/
|
|
1086
|
-
getName() {
|
|
1087
|
-
return this.#name;
|
|
1088
|
-
}
|
|
1089
|
-
/**
|
|
1090
|
-
* Get the route pattern
|
|
1091
|
-
*/
|
|
1092
|
-
getPattern() {
|
|
1093
|
-
return this.#pattern;
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Set the route pattern
|
|
1097
|
-
*/
|
|
1098
|
-
setPattern(pattern) {
|
|
1099
|
-
this.#pattern = pattern;
|
|
1100
|
-
return this;
|
|
1101
|
-
}
|
|
1102
|
-
/**
|
|
1103
|
-
* Returns the stack of middleware registered on the route.
|
|
1104
|
-
* The value is shared by reference.
|
|
1105
|
-
*/
|
|
1106
|
-
getMiddleware() {
|
|
1107
|
-
return this.#middleware;
|
|
1108
|
-
}
|
|
1109
|
-
/**
|
|
1110
|
-
* Returns the middleware instance for persistence inside the
|
|
1111
|
-
* store
|
|
1112
|
-
*/
|
|
1113
|
-
#getMiddlewareForStore() {
|
|
1114
|
-
const middleware = new Middleware();
|
|
1115
|
-
this.#routerMiddleware.forEach((one) => {
|
|
1116
|
-
debug_default("adding global middleware to route %s, %O", this.#pattern, one);
|
|
1117
|
-
middleware.add(one);
|
|
1118
|
-
});
|
|
1119
|
-
this.#middleware.flat().forEach((one) => {
|
|
1120
|
-
debug_default("adding named middleware to route %s, %O", this.#pattern, one);
|
|
1121
|
-
middleware.add(one);
|
|
1122
|
-
});
|
|
1123
|
-
middleware.freeze();
|
|
1124
|
-
return middleware;
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Returns JSON representation of the route
|
|
1128
|
-
*/
|
|
1129
|
-
toJSON() {
|
|
1130
|
-
const pattern = this.#computePattern();
|
|
1131
|
-
const matchers = this.#getMatchers();
|
|
1132
|
-
return {
|
|
1133
|
-
domain: this.#routeDomain,
|
|
1134
|
-
pattern,
|
|
1135
|
-
matchers,
|
|
1136
|
-
tokens: parseRoute(pattern, matchers),
|
|
1137
|
-
meta: {},
|
|
1138
|
-
name: this.#name,
|
|
1139
|
-
handler: this.#handler,
|
|
1140
|
-
methods: this.#methods,
|
|
1141
|
-
middleware: this.#getMiddlewareForStore(),
|
|
1142
|
-
execute
|
|
1143
|
-
};
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
|
|
1147
|
-
// src/request.ts
|
|
1148
|
-
import fresh from "fresh";
|
|
1149
|
-
import typeIs from "type-is";
|
|
1150
|
-
import accepts from "accepts";
|
|
1151
|
-
import { isIP } from "net";
|
|
1152
|
-
import is2 from "@sindresorhus/is";
|
|
1153
|
-
import proxyaddr from "proxy-addr";
|
|
1154
|
-
import { safeEqual } from "@poppinss/utils";
|
|
1155
|
-
import Macroable5 from "@poppinss/macroable";
|
|
1156
|
-
import lodash from "@poppinss/utils/lodash";
|
|
1157
|
-
|
|
1158
279
|
// src/cookies/parser.ts
|
|
1159
280
|
import cookie from "cookie";
|
|
1160
281
|
var CookieParser = class {
|
|
282
|
+
/**
|
|
283
|
+
* Cookie client instance for handling cookie operations
|
|
284
|
+
*/
|
|
1161
285
|
#client;
|
|
1162
286
|
/**
|
|
1163
287
|
* A copy of cached cookies, they are cached during a request after
|
|
@@ -1173,12 +297,21 @@ var CookieParser = class {
|
|
|
1173
297
|
* the request cookie header.
|
|
1174
298
|
*/
|
|
1175
299
|
#cookies;
|
|
300
|
+
/**
|
|
301
|
+
* Create a new instance of CookieParser
|
|
302
|
+
*
|
|
303
|
+
* @param cookieHeader - The raw cookie header string from the request
|
|
304
|
+
* @param encryption - The encryption instance for cookie operations
|
|
305
|
+
*/
|
|
1176
306
|
constructor(cookieHeader, encryption) {
|
|
1177
307
|
this.#client = new CookieClient(encryption);
|
|
1178
308
|
this.#cookies = this.#parse(cookieHeader);
|
|
1179
309
|
}
|
|
1180
310
|
/**
|
|
1181
311
|
* Parses the request `cookie` header
|
|
312
|
+
*
|
|
313
|
+
* @param cookieHeader - The cookie header string to parse
|
|
314
|
+
* @returns Parsed cookies as key-value pairs
|
|
1182
315
|
*/
|
|
1183
316
|
#parse(cookieHeader) {
|
|
1184
317
|
if (!cookieHeader) {
|
|
@@ -1190,6 +323,10 @@ var CookieParser = class {
|
|
|
1190
323
|
* Attempts to decode a cookie by the name. When calling this method,
|
|
1191
324
|
* you are assuming that the cookie was just stringified in the first
|
|
1192
325
|
* place and not signed or encrypted.
|
|
326
|
+
*
|
|
327
|
+
* @param key - The cookie key to decode
|
|
328
|
+
* @param stringified - Whether the cookie value was stringified
|
|
329
|
+
* @returns The decoded cookie value or null if decoding fails
|
|
1193
330
|
*/
|
|
1194
331
|
decode(key, stringified = true) {
|
|
1195
332
|
const value = this.#cookies[key];
|
|
@@ -1209,6 +346,9 @@ var CookieParser = class {
|
|
|
1209
346
|
/**
|
|
1210
347
|
* Attempts to unsign a cookie by the name. When calling this method,
|
|
1211
348
|
* you are assuming that the cookie was signed in the first place.
|
|
349
|
+
*
|
|
350
|
+
* @param key - The cookie key to unsign
|
|
351
|
+
* @returns The original cookie value or null if unsigning fails
|
|
1212
352
|
*/
|
|
1213
353
|
unsign(key) {
|
|
1214
354
|
const value = this.#cookies[key];
|
|
@@ -1228,6 +368,9 @@ var CookieParser = class {
|
|
|
1228
368
|
/**
|
|
1229
369
|
* Attempts to decrypt a cookie by the name. When calling this method,
|
|
1230
370
|
* you are assuming that the cookie was encrypted in the first place.
|
|
371
|
+
*
|
|
372
|
+
* @param key - The cookie key to decrypt
|
|
373
|
+
* @returns The decrypted cookie value or null if decryption fails
|
|
1231
374
|
*/
|
|
1232
375
|
decrypt(key) {
|
|
1233
376
|
const value = this.#cookies[key];
|
|
@@ -1248,6 +391,8 @@ var CookieParser = class {
|
|
|
1248
391
|
* Returns an object of cookies key-value pair. Do note, the
|
|
1249
392
|
* cookies are not decoded, unsigned or decrypted inside this
|
|
1250
393
|
* list.
|
|
394
|
+
*
|
|
395
|
+
* @returns Raw cookies as key-value pairs
|
|
1251
396
|
*/
|
|
1252
397
|
list() {
|
|
1253
398
|
return this.#cookies;
|
|
@@ -1255,7 +400,24 @@ var CookieParser = class {
|
|
|
1255
400
|
};
|
|
1256
401
|
|
|
1257
402
|
// src/request.ts
|
|
1258
|
-
|
|
403
|
+
import fresh from "fresh";
|
|
404
|
+
import typeIs from "type-is";
|
|
405
|
+
import accepts from "accepts";
|
|
406
|
+
import { isIP } from "net";
|
|
407
|
+
import is from "@sindresorhus/is";
|
|
408
|
+
import proxyaddr from "proxy-addr";
|
|
409
|
+
import { safeEqual } from "@poppinss/utils";
|
|
410
|
+
import Macroable from "@poppinss/macroable";
|
|
411
|
+
import lodash from "@poppinss/utils/lodash";
|
|
412
|
+
var Request = class extends Macroable {
|
|
413
|
+
/**
|
|
414
|
+
* Creates a new Request instance wrapping the native Node.js HTTP request
|
|
415
|
+
* @param request - Native Node.js incoming message instance
|
|
416
|
+
* @param response - Native Node.js server response instance
|
|
417
|
+
* @param encryption - Encryption module for cookie and URL signing
|
|
418
|
+
* @param config - Request configuration options
|
|
419
|
+
* @param qsParser - Query string parser instance
|
|
420
|
+
*/
|
|
1259
421
|
constructor(request, response, encryption, config, qsParser) {
|
|
1260
422
|
super();
|
|
1261
423
|
this.request = request;
|
|
@@ -1310,16 +472,18 @@ var Request = class extends Macroable5 {
|
|
|
1310
472
|
*/
|
|
1311
473
|
#cookieParser;
|
|
1312
474
|
/**
|
|
1313
|
-
* Parsed URL with query string stored as a string
|
|
475
|
+
* Parsed URL with query string stored as a string and decode flag
|
|
1314
476
|
*/
|
|
1315
477
|
parsedUrl;
|
|
1316
478
|
/**
|
|
1317
|
-
*
|
|
1318
|
-
* reference
|
|
479
|
+
* HTTP context reference - creates a circular reference when set by the context
|
|
1319
480
|
*/
|
|
1320
481
|
ctx;
|
|
1321
482
|
/**
|
|
1322
|
-
* Parses the query string
|
|
483
|
+
* Parses the query string from the parsed URL and updates internal state.
|
|
484
|
+
*
|
|
485
|
+
* This method extracts query parameters from the URL and merges them into
|
|
486
|
+
* the request data object, also creating a frozen copy for original data reference.
|
|
1323
487
|
*/
|
|
1324
488
|
#parseQueryString() {
|
|
1325
489
|
if (this.parsedUrl.query) {
|
|
@@ -1328,7 +492,10 @@ var Request = class extends Macroable5 {
|
|
|
1328
492
|
}
|
|
1329
493
|
}
|
|
1330
494
|
/**
|
|
1331
|
-
* Initiates the cookie parser lazily
|
|
495
|
+
* Initiates the cookie parser lazily when first needed.
|
|
496
|
+
*
|
|
497
|
+
* Creates a CookieParser instance with the current request's cookie header
|
|
498
|
+
* and the configured encryption service for handling signed/encrypted cookies.
|
|
1332
499
|
*/
|
|
1333
500
|
#initiateCookieParser() {
|
|
1334
501
|
if (!this.#cookieParser) {
|
|
@@ -1336,16 +503,26 @@ var Request = class extends Macroable5 {
|
|
|
1336
503
|
}
|
|
1337
504
|
}
|
|
1338
505
|
/**
|
|
1339
|
-
* Lazily initiates the `accepts` module
|
|
1340
|
-
*
|
|
1341
|
-
*
|
|
506
|
+
* Lazily initiates the `accepts` module for content negotiation.
|
|
507
|
+
*
|
|
508
|
+
* Creates an accepts instance that parses the request headers only when
|
|
509
|
+
* one of the content-negotiation methods (like accepts, acceptsLanguages) are used.
|
|
510
|
+
* This improves performance by avoiding unnecessary header parsing.
|
|
1342
511
|
*/
|
|
1343
512
|
#initiateAccepts() {
|
|
1344
513
|
this.#lazyAccepts = this.#lazyAccepts || accepts(this.request);
|
|
1345
514
|
}
|
|
1346
515
|
/**
|
|
1347
|
-
* Returns the request
|
|
1348
|
-
*
|
|
516
|
+
* Returns the request ID from the `x-request-id` header.
|
|
517
|
+
*
|
|
518
|
+
* If the header doesn't exist and request ID generation is enabled,
|
|
519
|
+
* a new UUID will be generated and added to the request headers.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```ts
|
|
523
|
+
* const requestId = request.id()
|
|
524
|
+
* console.log(requestId) // '550e8400-e29b-41d4-a716-446655440000'
|
|
525
|
+
* ```
|
|
1349
526
|
*/
|
|
1350
527
|
id() {
|
|
1351
528
|
let requestId = this.header("x-request-id");
|
|
@@ -1362,6 +539,8 @@ var Request = class extends Macroable5 {
|
|
|
1362
539
|
*
|
|
1363
540
|
* This method is supposed to be invoked by the body parser and must be called only
|
|
1364
541
|
* once. For further mutations make use of `updateBody` method.
|
|
542
|
+
* @param body - Parsed request body data
|
|
543
|
+
* @returns {void}
|
|
1365
544
|
*/
|
|
1366
545
|
setInitialBody(body) {
|
|
1367
546
|
if (this.#originalRequestData && Object.isFrozen(this.#originalRequestData)) {
|
|
@@ -1374,6 +553,8 @@ var Request = class extends Macroable5 {
|
|
|
1374
553
|
* Update the request body with new data object. The `all` property
|
|
1375
554
|
* will be re-computed by merging the query string and request
|
|
1376
555
|
* body.
|
|
556
|
+
* @param body - New request body data to set
|
|
557
|
+
* @returns {void}
|
|
1377
558
|
*/
|
|
1378
559
|
updateBody(body) {
|
|
1379
560
|
this.#requestBody = body;
|
|
@@ -1382,6 +563,8 @@ var Request = class extends Macroable5 {
|
|
|
1382
563
|
/**
|
|
1383
564
|
* Update the request raw body. Bodyparser sets this when unable to parse
|
|
1384
565
|
* the request body or when request is multipart/form-data.
|
|
566
|
+
* @param rawBody - Raw request body as string
|
|
567
|
+
* @returns {void}
|
|
1385
568
|
*/
|
|
1386
569
|
updateRawBody(rawBody) {
|
|
1387
570
|
this.#rawRequestBody = rawBody;
|
|
@@ -1389,6 +572,8 @@ var Request = class extends Macroable5 {
|
|
|
1389
572
|
/**
|
|
1390
573
|
* Update the query string with the new data object. The `all` property
|
|
1391
574
|
* will be re-computed by merging the query and the request body.
|
|
575
|
+
* @param data - New query string data to set
|
|
576
|
+
* @returns {void}
|
|
1392
577
|
*/
|
|
1393
578
|
updateQs(data) {
|
|
1394
579
|
this.#requestQs = data;
|
|
@@ -1396,18 +581,21 @@ var Request = class extends Macroable5 {
|
|
|
1396
581
|
}
|
|
1397
582
|
/**
|
|
1398
583
|
* Returns route params
|
|
584
|
+
* @returns {Record<string, any>} Object containing route parameters
|
|
1399
585
|
*/
|
|
1400
586
|
params() {
|
|
1401
587
|
return this.ctx?.params || {};
|
|
1402
588
|
}
|
|
1403
589
|
/**
|
|
1404
590
|
* Returns the query string object by reference
|
|
591
|
+
* @returns {Record<string, any>} Object containing parsed query string parameters
|
|
1405
592
|
*/
|
|
1406
593
|
qs() {
|
|
1407
594
|
return this.#requestQs;
|
|
1408
595
|
}
|
|
1409
596
|
/**
|
|
1410
597
|
* Returns reference to the request body
|
|
598
|
+
* @returns {Record<string, any>} Object containing parsed request body
|
|
1411
599
|
*/
|
|
1412
600
|
body() {
|
|
1413
601
|
return this.#requestBody;
|
|
@@ -1415,6 +603,7 @@ var Request = class extends Macroable5 {
|
|
|
1415
603
|
/**
|
|
1416
604
|
* Returns reference to the merged copy of request body
|
|
1417
605
|
* and query string
|
|
606
|
+
* @returns {Record<string, any>} Object containing merged request body and query parameters
|
|
1418
607
|
*/
|
|
1419
608
|
all() {
|
|
1420
609
|
return this.#requestData;
|
|
@@ -1422,6 +611,7 @@ var Request = class extends Macroable5 {
|
|
|
1422
611
|
/**
|
|
1423
612
|
* Returns reference to the merged copy of original request
|
|
1424
613
|
* query string and body
|
|
614
|
+
* @returns {Record<string, any>} Object containing original merged request data
|
|
1425
615
|
*/
|
|
1426
616
|
original() {
|
|
1427
617
|
return this.#originalRequestData;
|
|
@@ -1431,6 +621,7 @@ var Request = class extends Macroable5 {
|
|
|
1431
621
|
*
|
|
1432
622
|
* Ideally you must be dealing with the parsed body accessed using [[input]], [[all]] or
|
|
1433
623
|
* [[post]] methods. The `raw` body is always a string.
|
|
624
|
+
* @returns {string | null} Raw request body as string or null if not set
|
|
1434
625
|
*/
|
|
1435
626
|
raw() {
|
|
1436
627
|
return this.#rawRequestBody || null;
|
|
@@ -1446,6 +637,9 @@ var Request = class extends Macroable5 {
|
|
|
1446
637
|
* // with default value
|
|
1447
638
|
* request.input('username', 'virk')
|
|
1448
639
|
* ```
|
|
640
|
+
* @param key - Key to lookup in request data
|
|
641
|
+
* @param defaultValue - Default value when key is not found
|
|
642
|
+
* @returns Value from request data or default value
|
|
1449
643
|
*/
|
|
1450
644
|
input(key, defaultValue) {
|
|
1451
645
|
return lodash.get(this.#requestData, key, defaultValue);
|
|
@@ -1460,6 +654,9 @@ var Request = class extends Macroable5 {
|
|
|
1460
654
|
* // with default value
|
|
1461
655
|
* request.param('id', 1)
|
|
1462
656
|
* ```
|
|
657
|
+
* @param key - Parameter key to lookup
|
|
658
|
+
* @param defaultValue - Default value when parameter is not found
|
|
659
|
+
* @returns Value from route parameters or default value
|
|
1463
660
|
*/
|
|
1464
661
|
param(key, defaultValue) {
|
|
1465
662
|
return lodash.get(this.params(), key, defaultValue);
|
|
@@ -1471,6 +668,8 @@ var Request = class extends Macroable5 {
|
|
|
1471
668
|
* ```js
|
|
1472
669
|
* request.except(['_csrf'])
|
|
1473
670
|
* ```
|
|
671
|
+
* @param keys - Array of keys to exclude from the result
|
|
672
|
+
* @returns {Record<string, any>} Object with all request data except specified keys
|
|
1474
673
|
*/
|
|
1475
674
|
except(keys) {
|
|
1476
675
|
return lodash.omit(this.#requestData, keys);
|
|
@@ -1482,6 +681,8 @@ var Request = class extends Macroable5 {
|
|
|
1482
681
|
* ```js
|
|
1483
682
|
* request.only(['username', 'age'])
|
|
1484
683
|
* ```
|
|
684
|
+
* @param keys - Array of keys to include in the result
|
|
685
|
+
* @returns {{ [K in T]: any }} Object with only the specified keys from request data
|
|
1485
686
|
*/
|
|
1486
687
|
only(keys) {
|
|
1487
688
|
return lodash.pick(this.#requestData, keys);
|
|
@@ -1495,6 +696,7 @@ var Request = class extends Macroable5 {
|
|
|
1495
696
|
* ```js
|
|
1496
697
|
* request.intended()
|
|
1497
698
|
* ```
|
|
699
|
+
* @returns {string} Original HTTP method from the request
|
|
1498
700
|
*/
|
|
1499
701
|
intended() {
|
|
1500
702
|
return this.request.method;
|
|
@@ -1512,6 +714,7 @@ var Request = class extends Macroable5 {
|
|
|
1512
714
|
* ```js
|
|
1513
715
|
* request.method()
|
|
1514
716
|
* ```
|
|
717
|
+
* @returns {string} HTTP method (potentially spoofed)
|
|
1515
718
|
*/
|
|
1516
719
|
method() {
|
|
1517
720
|
if (this.#config.allowMethodSpoofing && this.intended() === "POST") {
|
|
@@ -1521,6 +724,7 @@ var Request = class extends Macroable5 {
|
|
|
1521
724
|
}
|
|
1522
725
|
/**
|
|
1523
726
|
* Returns a copy of headers as an object
|
|
727
|
+
* @returns {IncomingHttpHeaders} Object containing all HTTP headers
|
|
1524
728
|
*/
|
|
1525
729
|
headers() {
|
|
1526
730
|
return this.request.headers;
|
|
@@ -1528,6 +732,9 @@ var Request = class extends Macroable5 {
|
|
|
1528
732
|
/**
|
|
1529
733
|
* Returns value for a given header key. The default value is
|
|
1530
734
|
* used when original value is `undefined`.
|
|
735
|
+
* @param key - Header name to lookup
|
|
736
|
+
* @param defaultValue - Default value when header is not found
|
|
737
|
+
* @returns {string | undefined} Header value or default value if not found
|
|
1531
738
|
*/
|
|
1532
739
|
header(key, defaultValue) {
|
|
1533
740
|
key = key.toLowerCase();
|
|
@@ -1570,6 +777,7 @@ var Request = class extends Macroable5 {
|
|
|
1570
777
|
* ```
|
|
1571
778
|
*
|
|
1572
779
|
* The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
|
|
780
|
+
* @returns {string} Client IP address
|
|
1573
781
|
*/
|
|
1574
782
|
ip() {
|
|
1575
783
|
const ipFn = this.#config.getIp;
|
|
@@ -1595,6 +803,7 @@ var Request = class extends Macroable5 {
|
|
|
1595
803
|
* ```
|
|
1596
804
|
*
|
|
1597
805
|
* The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
|
|
806
|
+
* @returns {string[]} Array of IP addresses from most to least trusted
|
|
1598
807
|
*/
|
|
1599
808
|
ips() {
|
|
1600
809
|
return proxyaddr.all(this.request, this.#config.trustProxy);
|
|
@@ -1618,6 +827,7 @@ var Request = class extends Macroable5 {
|
|
|
1618
827
|
* ```
|
|
1619
828
|
*
|
|
1620
829
|
* The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
|
|
830
|
+
* @returns {string} Request protocol ('http' or 'https')
|
|
1621
831
|
*/
|
|
1622
832
|
protocol() {
|
|
1623
833
|
if ("encrypted" in this.request.socket) {
|
|
@@ -1633,6 +843,7 @@ var Request = class extends Macroable5 {
|
|
|
1633
843
|
* Returns a boolean telling if request is served over `https`
|
|
1634
844
|
* or not. Check [[protocol]] method to know how protocol is
|
|
1635
845
|
* fetched.
|
|
846
|
+
* @returns {boolean} True if request is served over HTTPS
|
|
1636
847
|
*/
|
|
1637
848
|
secure() {
|
|
1638
849
|
return this.protocol() === "https";
|
|
@@ -1653,6 +864,7 @@ var Request = class extends Macroable5 {
|
|
|
1653
864
|
* ```
|
|
1654
865
|
*
|
|
1655
866
|
* The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
|
|
867
|
+
* @returns {string | null} Request host or null if not found
|
|
1656
868
|
*/
|
|
1657
869
|
host() {
|
|
1658
870
|
let host = this.header("host");
|
|
@@ -1680,6 +892,7 @@ var Request = class extends Macroable5 {
|
|
|
1680
892
|
* ```
|
|
1681
893
|
*
|
|
1682
894
|
* The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
|
|
895
|
+
* @returns {string | null} Request hostname (without port) or null if not found
|
|
1683
896
|
*/
|
|
1684
897
|
hostname() {
|
|
1685
898
|
const host = this.host();
|
|
@@ -1695,6 +908,7 @@ var Request = class extends Macroable5 {
|
|
|
1695
908
|
* returned if [[hostname]] is `null` or is an IP address.
|
|
1696
909
|
*
|
|
1697
910
|
* Also `www` is not considered as a subdomain
|
|
911
|
+
* @returns {string[]} Array of subdomains (excluding www)
|
|
1698
912
|
*/
|
|
1699
913
|
subdomains() {
|
|
1700
914
|
const hostname = this.hostname();
|
|
@@ -1711,6 +925,7 @@ var Request = class extends Macroable5 {
|
|
|
1711
925
|
/**
|
|
1712
926
|
* Returns a boolean telling, if request `X-Requested-With === 'xmlhttprequest'`
|
|
1713
927
|
* or not.
|
|
928
|
+
* @returns {boolean} True if request is an AJAX request
|
|
1714
929
|
*/
|
|
1715
930
|
ajax() {
|
|
1716
931
|
const xRequestedWith = this.header("X-Requested-With", "");
|
|
@@ -1719,6 +934,7 @@ var Request = class extends Macroable5 {
|
|
|
1719
934
|
/**
|
|
1720
935
|
* Returns a boolean telling, if request has `X-Pjax` header
|
|
1721
936
|
* set or not
|
|
937
|
+
* @returns {boolean} True if request is a PJAX request
|
|
1722
938
|
*/
|
|
1723
939
|
pjax() {
|
|
1724
940
|
return !!this.header("X-Pjax");
|
|
@@ -1733,6 +949,8 @@ var Request = class extends Macroable5 {
|
|
|
1733
949
|
* // include query string
|
|
1734
950
|
* request.url(true)
|
|
1735
951
|
* ```
|
|
952
|
+
* @param includeQueryString - Whether to include query string in the URL
|
|
953
|
+
* @returns {string} Request pathname, optionally with query string
|
|
1736
954
|
*/
|
|
1737
955
|
url(includeQueryString) {
|
|
1738
956
|
const pathname = this.parsedUrl.pathname;
|
|
@@ -1749,6 +967,8 @@ var Request = class extends Macroable5 {
|
|
|
1749
967
|
* // include query string
|
|
1750
968
|
* request.completeUrl(true)
|
|
1751
969
|
* ```
|
|
970
|
+
* @param includeQueryString - Whether to include query string in the URL
|
|
971
|
+
* @returns {string} Complete URL including protocol and host
|
|
1752
972
|
*/
|
|
1753
973
|
completeUrl(includeQueryString) {
|
|
1754
974
|
const protocol = this.protocol();
|
|
@@ -1757,6 +977,8 @@ var Request = class extends Macroable5 {
|
|
|
1757
977
|
}
|
|
1758
978
|
/**
|
|
1759
979
|
* Find if the current HTTP request is for the given route or the routes
|
|
980
|
+
* @param routeIdentifier - Route name, pattern, or handler reference to match
|
|
981
|
+
* @returns {boolean} True if the request matches any of the given route identifiers
|
|
1760
982
|
*/
|
|
1761
983
|
matchesRoute(routeIdentifier) {
|
|
1762
984
|
if (!this.ctx || !this.ctx.route) {
|
|
@@ -1802,6 +1024,8 @@ var Request = class extends Macroable5 {
|
|
|
1802
1024
|
* // process XML
|
|
1803
1025
|
* }
|
|
1804
1026
|
* ```
|
|
1027
|
+
* @param types - Array of content types to match against
|
|
1028
|
+
* @returns {string | null} Best matching content type or null if no match
|
|
1805
1029
|
*/
|
|
1806
1030
|
is(types) {
|
|
1807
1031
|
return typeIs(this.request, types) || null;
|
|
@@ -1826,6 +1050,8 @@ var Request = class extends Macroable5 {
|
|
|
1826
1050
|
* // decide yourself
|
|
1827
1051
|
* }
|
|
1828
1052
|
* ```
|
|
1053
|
+
* @param types - Array of types to match against Accept header
|
|
1054
|
+
* @returns {T | null} Best matching accept type or null if no match
|
|
1829
1055
|
*/
|
|
1830
1056
|
accepts(types) {
|
|
1831
1057
|
this.#initiateAccepts();
|
|
@@ -1837,6 +1063,7 @@ var Request = class extends Macroable5 {
|
|
|
1837
1063
|
*
|
|
1838
1064
|
* Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
|
|
1839
1065
|
* docs too.
|
|
1066
|
+
* @returns {string[]} Array of accepted types in preference order
|
|
1840
1067
|
*/
|
|
1841
1068
|
types() {
|
|
1842
1069
|
this.#initiateAccepts();
|
|
@@ -1862,6 +1089,8 @@ var Request = class extends Macroable5 {
|
|
|
1862
1089
|
* return view.render('about', { lang: 'en' })
|
|
1863
1090
|
* }
|
|
1864
1091
|
* ```
|
|
1092
|
+
* @param languages - Array of languages to match against Accept-Language header
|
|
1093
|
+
* @returns {T | null} Best matching language or null if no match
|
|
1865
1094
|
*/
|
|
1866
1095
|
language(languages) {
|
|
1867
1096
|
this.#initiateAccepts();
|
|
@@ -1873,6 +1102,7 @@ var Request = class extends Macroable5 {
|
|
|
1873
1102
|
*
|
|
1874
1103
|
* Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
|
|
1875
1104
|
* docs too.
|
|
1105
|
+
* @returns {string[]} Array of accepted languages in preference order
|
|
1876
1106
|
*/
|
|
1877
1107
|
languages() {
|
|
1878
1108
|
this.#initiateAccepts();
|
|
@@ -1896,6 +1126,8 @@ var Request = class extends Macroable5 {
|
|
|
1896
1126
|
* // make ISO-8859-1 friendly response
|
|
1897
1127
|
* }
|
|
1898
1128
|
* ```
|
|
1129
|
+
* @param charsets - Array of charsets to match against Accept-Charset header
|
|
1130
|
+
* @returns {T | null} Best matching charset or null if no match
|
|
1899
1131
|
*/
|
|
1900
1132
|
charset(charsets) {
|
|
1901
1133
|
this.#initiateAccepts();
|
|
@@ -1907,6 +1139,7 @@ var Request = class extends Macroable5 {
|
|
|
1907
1139
|
*
|
|
1908
1140
|
* Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
|
|
1909
1141
|
* docs too.
|
|
1142
|
+
* @returns {string[]} Array of accepted charsets in preference order
|
|
1910
1143
|
*/
|
|
1911
1144
|
charsets() {
|
|
1912
1145
|
this.#initiateAccepts();
|
|
@@ -1920,17 +1153,20 @@ var Request = class extends Macroable5 {
|
|
|
1920
1153
|
*
|
|
1921
1154
|
* Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
|
|
1922
1155
|
* docs too.
|
|
1156
|
+
* @param encodings - Array of encodings to match against Accept-Encoding header
|
|
1157
|
+
* @returns {T | null} Best matching encoding or null if no match
|
|
1923
1158
|
*/
|
|
1924
1159
|
encoding(encodings) {
|
|
1925
1160
|
this.#initiateAccepts();
|
|
1926
1161
|
return this.#lazyAccepts.encoding(encodings) || null;
|
|
1927
1162
|
}
|
|
1928
1163
|
/**
|
|
1929
|
-
* Return the
|
|
1164
|
+
* Return the encodings that the request accepts, in the order of the
|
|
1930
1165
|
* client's preference (most preferred first).
|
|
1931
1166
|
*
|
|
1932
1167
|
* Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
|
|
1933
1168
|
* docs too.
|
|
1169
|
+
* @returns {string[]} Array of accepted encodings in preference order
|
|
1934
1170
|
*/
|
|
1935
1171
|
encodings() {
|
|
1936
1172
|
this.#initiateAccepts();
|
|
@@ -1938,6 +1174,7 @@ var Request = class extends Macroable5 {
|
|
|
1938
1174
|
}
|
|
1939
1175
|
/**
|
|
1940
1176
|
* Returns a boolean telling if request has body
|
|
1177
|
+
* @returns {boolean} True if request contains a body
|
|
1941
1178
|
*/
|
|
1942
1179
|
hasBody() {
|
|
1943
1180
|
return typeIs.hasBody(this.request);
|
|
@@ -1965,6 +1202,7 @@ var Request = class extends Macroable5 {
|
|
|
1965
1202
|
* response.send(responseBody)
|
|
1966
1203
|
* }
|
|
1967
1204
|
* ```
|
|
1205
|
+
* @returns {boolean} True if client cache is fresh (should return 304)
|
|
1968
1206
|
*/
|
|
1969
1207
|
fresh() {
|
|
1970
1208
|
if (["GET", "HEAD"].indexOf(this.intended()) === -1) {
|
|
@@ -1978,6 +1216,7 @@ var Request = class extends Macroable5 {
|
|
|
1978
1216
|
}
|
|
1979
1217
|
/**
|
|
1980
1218
|
* Opposite of [[fresh]]
|
|
1219
|
+
* @returns {boolean} True if client cache is stale (should send new response)
|
|
1981
1220
|
*/
|
|
1982
1221
|
stale() {
|
|
1983
1222
|
return !this.fresh();
|
|
@@ -1985,6 +1224,7 @@ var Request = class extends Macroable5 {
|
|
|
1985
1224
|
/**
|
|
1986
1225
|
* Returns all parsed and signed cookies. Signed cookies ensures
|
|
1987
1226
|
* that their value isn't tampered.
|
|
1227
|
+
* @returns {{ [key: string]: any }} Object containing all parsed cookies
|
|
1988
1228
|
*/
|
|
1989
1229
|
cookiesList() {
|
|
1990
1230
|
this.#initiateCookieParser();
|
|
@@ -1993,14 +1233,20 @@ var Request = class extends Macroable5 {
|
|
|
1993
1233
|
/**
|
|
1994
1234
|
* Returns value for a given key from signed cookies. Optional
|
|
1995
1235
|
* defaultValue is returned when actual value is undefined.
|
|
1236
|
+
* @param key - Cookie name to lookup
|
|
1237
|
+
* @param defaultValue - Default value when cookie is not found
|
|
1238
|
+
* @returns Cookie value or default value if not found
|
|
1996
1239
|
*/
|
|
1997
1240
|
cookie(key, defaultValue) {
|
|
1998
1241
|
this.#initiateCookieParser();
|
|
1999
1242
|
return this.#cookieParser.unsign(key) || defaultValue;
|
|
2000
1243
|
}
|
|
2001
1244
|
/**
|
|
2002
|
-
* Returns value for a given key from
|
|
1245
|
+
* Returns value for a given key from encrypted cookies. Optional
|
|
2003
1246
|
* defaultValue is returned when actual value is undefined.
|
|
1247
|
+
* @param key - Cookie name to lookup
|
|
1248
|
+
* @param defaultValue - Default value when cookie is not found
|
|
1249
|
+
* @returns Decrypted cookie value or default value if not found
|
|
2004
1250
|
*/
|
|
2005
1251
|
encryptedCookie(key, defaultValue) {
|
|
2006
1252
|
this.#initiateCookieParser();
|
|
@@ -2008,14 +1254,16 @@ var Request = class extends Macroable5 {
|
|
|
2008
1254
|
}
|
|
2009
1255
|
plainCookie(key, defaultValueOrOptions, encoded) {
|
|
2010
1256
|
this.#initiateCookieParser();
|
|
2011
|
-
if (
|
|
1257
|
+
if (is.object(defaultValueOrOptions)) {
|
|
2012
1258
|
return this.#cookieParser.decode(key, defaultValueOrOptions?.encoded) || defaultValueOrOptions.defaultValue;
|
|
2013
1259
|
}
|
|
2014
1260
|
return this.#cookieParser.decode(key, encoded) || defaultValueOrOptions;
|
|
2015
1261
|
}
|
|
2016
1262
|
/**
|
|
2017
|
-
* Returns a boolean telling if a signed url
|
|
1263
|
+
* Returns a boolean telling if a signed url has a valid signature
|
|
2018
1264
|
* or not.
|
|
1265
|
+
* @param purpose - Optional purpose for signature verification
|
|
1266
|
+
* @returns {boolean} True if the signed URL has a valid signature
|
|
2019
1267
|
*/
|
|
2020
1268
|
hasValidSignature(purpose) {
|
|
2021
1269
|
const { signature, ...rest } = this.qs();
|
|
@@ -2031,6 +1279,7 @@ var Request = class extends Macroable5 {
|
|
|
2031
1279
|
}
|
|
2032
1280
|
/**
|
|
2033
1281
|
* Serializes request to JSON format
|
|
1282
|
+
* @returns Object representation of the request
|
|
2034
1283
|
*/
|
|
2035
1284
|
serialize() {
|
|
2036
1285
|
return {
|
|
@@ -2050,6 +1299,7 @@ var Request = class extends Macroable5 {
|
|
|
2050
1299
|
}
|
|
2051
1300
|
/**
|
|
2052
1301
|
* toJSON copy of the request
|
|
1302
|
+
* @returns JSON representation of the request
|
|
2053
1303
|
*/
|
|
2054
1304
|
toJSON() {
|
|
2055
1305
|
return this.serialize();
|
|
@@ -2057,24 +1307,42 @@ var Request = class extends Macroable5 {
|
|
|
2057
1307
|
};
|
|
2058
1308
|
|
|
2059
1309
|
// src/redirect.ts
|
|
2060
|
-
import { parse } from "url";
|
|
2061
1310
|
var Redirect = class {
|
|
2062
1311
|
/**
|
|
2063
|
-
*
|
|
1312
|
+
* Flag indicating whether to forward the existing query string from the current request
|
|
2064
1313
|
*/
|
|
2065
1314
|
#forwardQueryString = false;
|
|
2066
1315
|
/**
|
|
2067
|
-
*
|
|
1316
|
+
* HTTP status code to use for the redirect response (defaults to 302)
|
|
2068
1317
|
*/
|
|
2069
1318
|
#statusCode = 302;
|
|
2070
1319
|
/**
|
|
2071
|
-
*
|
|
1320
|
+
* Custom query string parameters to include in the redirect URL
|
|
2072
1321
|
*/
|
|
2073
1322
|
#queryString = {};
|
|
1323
|
+
/**
|
|
1324
|
+
* Reference to the Node.js incoming HTTP request
|
|
1325
|
+
*/
|
|
2074
1326
|
#request;
|
|
1327
|
+
/**
|
|
1328
|
+
* Reference to the AdonisJS response instance
|
|
1329
|
+
*/
|
|
2075
1330
|
#response;
|
|
1331
|
+
/**
|
|
1332
|
+
* Reference to the AdonisJS router instance for URL building
|
|
1333
|
+
*/
|
|
2076
1334
|
#router;
|
|
1335
|
+
/**
|
|
1336
|
+
* Query string parser instance
|
|
1337
|
+
*/
|
|
2077
1338
|
#qs;
|
|
1339
|
+
/**
|
|
1340
|
+
* Creates a new Redirect instance for handling HTTP redirects
|
|
1341
|
+
* @param request - Node.js incoming HTTP request
|
|
1342
|
+
* @param response - AdonisJS response instance
|
|
1343
|
+
* @param router - AdonisJS router instance
|
|
1344
|
+
* @param qs - Query string parser instance
|
|
1345
|
+
*/
|
|
2078
1346
|
constructor(request, response, router, qs) {
|
|
2079
1347
|
this.#request = request;
|
|
2080
1348
|
this.#response = response;
|
|
@@ -2082,7 +1350,9 @@ var Redirect = class {
|
|
|
2082
1350
|
this.#qs = qs;
|
|
2083
1351
|
}
|
|
2084
1352
|
/**
|
|
2085
|
-
* Sends response by setting
|
|
1353
|
+
* Sends the redirect response by setting required headers and status code
|
|
1354
|
+
* @param url - Target URL for redirection
|
|
1355
|
+
* @param query - Query string parameters to append
|
|
2086
1356
|
*/
|
|
2087
1357
|
#sendResponse(url, query) {
|
|
2088
1358
|
const stringified = this.#qs.stringify(query);
|
|
@@ -2094,22 +1364,25 @@ var Redirect = class {
|
|
|
2094
1364
|
this.#response.send(`Redirecting to ${url}`);
|
|
2095
1365
|
}
|
|
2096
1366
|
/**
|
|
2097
|
-
*
|
|
1367
|
+
* Extracts and returns the referrer URL from request headers
|
|
1368
|
+
* @returns {string} The referrer URL or '/' if not found
|
|
2098
1369
|
*/
|
|
2099
1370
|
#getReferrerUrl() {
|
|
2100
1371
|
let url = this.#request.headers["referer"] || this.#request.headers["referrer"] || "/";
|
|
2101
1372
|
return Array.isArray(url) ? url[0] : url;
|
|
2102
1373
|
}
|
|
2103
1374
|
/**
|
|
2104
|
-
*
|
|
1375
|
+
* Sets a custom HTTP status code for the redirect response
|
|
1376
|
+
* @param statusCode - HTTP status code to use (e.g., 301, 302, 307)
|
|
1377
|
+
* @returns {this} The Redirect instance for method chaining
|
|
2105
1378
|
*/
|
|
2106
1379
|
status(statusCode) {
|
|
2107
1380
|
this.#statusCode = statusCode;
|
|
2108
1381
|
return this;
|
|
2109
1382
|
}
|
|
2110
1383
|
/**
|
|
2111
|
-
*
|
|
2112
|
-
*
|
|
1384
|
+
* Clears any query string values previously added using the withQs method
|
|
1385
|
+
* @returns {this} The Redirect instance for method chaining
|
|
2113
1386
|
*/
|
|
2114
1387
|
clearQs() {
|
|
2115
1388
|
this.#forwardQueryString = false;
|
|
@@ -2129,12 +1402,13 @@ var Redirect = class {
|
|
|
2129
1402
|
return this;
|
|
2130
1403
|
}
|
|
2131
1404
|
/**
|
|
2132
|
-
*
|
|
1405
|
+
* Redirects to the previous path using the Referer header
|
|
1406
|
+
* Falls back to '/' if no referrer is found
|
|
2133
1407
|
*/
|
|
2134
1408
|
back() {
|
|
2135
1409
|
let query = {};
|
|
2136
1410
|
const referrerUrl = this.#getReferrerUrl();
|
|
2137
|
-
const url =
|
|
1411
|
+
const url = safeDecodeURI(referrerUrl, false);
|
|
2138
1412
|
debug_default('referrer url "%s"', referrerUrl);
|
|
2139
1413
|
debug_default('referrer base url "%s"', url.pathname);
|
|
2140
1414
|
if (this.#forwardQueryString) {
|
|
@@ -2144,7 +1418,8 @@ var Redirect = class {
|
|
|
2144
1418
|
this.#sendResponse(url.pathname || "", query);
|
|
2145
1419
|
}
|
|
2146
1420
|
/**
|
|
2147
|
-
*
|
|
1421
|
+
* Redirects to a route using its identifier (name, pattern, or handler reference)
|
|
1422
|
+
* @param args - Route identifier, parameters, and options for URL building
|
|
2148
1423
|
*/
|
|
2149
1424
|
toRoute(...args) {
|
|
2150
1425
|
const [identifier, params, options] = args;
|
|
@@ -2156,12 +1431,13 @@ var Redirect = class {
|
|
|
2156
1431
|
return this.toPath(url);
|
|
2157
1432
|
}
|
|
2158
1433
|
/**
|
|
2159
|
-
*
|
|
1434
|
+
* Redirects to a specific URL path
|
|
1435
|
+
* @param url - Target URL path for redirection
|
|
2160
1436
|
*/
|
|
2161
1437
|
toPath(url) {
|
|
2162
1438
|
let query = {};
|
|
2163
1439
|
if (this.#forwardQueryString) {
|
|
2164
|
-
query = this.#qs.parse(
|
|
1440
|
+
query = this.#qs.parse(safeDecodeURI(this.#request.url, false).query || "");
|
|
2165
1441
|
}
|
|
2166
1442
|
Object.assign(query, this.#queryString);
|
|
2167
1443
|
this.#sendResponse(url, query);
|
|
@@ -2234,24 +1510,17 @@ var ResponseStatus = {
|
|
|
2234
1510
|
NetworkAuthenticationRequired: 511
|
|
2235
1511
|
};
|
|
2236
1512
|
|
|
2237
|
-
// src/response.ts
|
|
2238
|
-
import etag from "etag";
|
|
2239
|
-
import vary from "vary";
|
|
2240
|
-
import fresh2 from "fresh";
|
|
2241
|
-
import destroy from "destroy";
|
|
2242
|
-
import { extname } from "path";
|
|
2243
|
-
import { Buffer } from "buffer";
|
|
2244
|
-
import onFinished from "on-finished";
|
|
2245
|
-
import { stat } from "fs/promises";
|
|
2246
|
-
import Macroable6 from "@poppinss/macroable";
|
|
2247
|
-
import { createReadStream } from "fs";
|
|
2248
|
-
import contentDisposition from "content-disposition";
|
|
2249
|
-
import { safeStringify } from "@poppinss/utils/json";
|
|
2250
|
-
import { RuntimeException as RuntimeException3 } from "@poppinss/utils/exception";
|
|
2251
|
-
|
|
2252
1513
|
// src/cookies/serializer.ts
|
|
2253
1514
|
var CookieSerializer = class {
|
|
1515
|
+
/**
|
|
1516
|
+
* Cookie client instance for handling cookie operations
|
|
1517
|
+
*/
|
|
2254
1518
|
#client;
|
|
1519
|
+
/**
|
|
1520
|
+
* Create a new instance of CookieSerializer
|
|
1521
|
+
*
|
|
1522
|
+
* @param encryption - The encryption instance for cookie operations
|
|
1523
|
+
*/
|
|
2255
1524
|
constructor(encryption) {
|
|
2256
1525
|
this.#client = new CookieClient(encryption);
|
|
2257
1526
|
}
|
|
@@ -2265,6 +1534,11 @@ var CookieSerializer = class {
|
|
|
2265
1534
|
* serializer.encode('name', 'virk')
|
|
2266
1535
|
* serializer.encode('name', 'virk', { stringify: false })
|
|
2267
1536
|
* ```
|
|
1537
|
+
*
|
|
1538
|
+
* @param key - The cookie key
|
|
1539
|
+
* @param value - The value to encode
|
|
1540
|
+
* @param options - Cookie encoding options
|
|
1541
|
+
* @returns The serialized cookie string or null if encoding fails
|
|
2268
1542
|
*/
|
|
2269
1543
|
encode(key, value, options) {
|
|
2270
1544
|
const stringify2 = options?.stringify ?? options?.encode;
|
|
@@ -2277,6 +1551,11 @@ var CookieSerializer = class {
|
|
|
2277
1551
|
/**
|
|
2278
1552
|
* Sign a key-value pair to a signed cookie. The signed value has a
|
|
2279
1553
|
* verification hash attached to it to detect data tampering.
|
|
1554
|
+
*
|
|
1555
|
+
* @param key - The cookie key
|
|
1556
|
+
* @param value - The value to sign
|
|
1557
|
+
* @param options - Cookie options
|
|
1558
|
+
* @returns The serialized signed cookie string or null if signing fails
|
|
2280
1559
|
*/
|
|
2281
1560
|
sign(key, value, options) {
|
|
2282
1561
|
const packedValue = this.#client.sign(key, value);
|
|
@@ -2287,6 +1566,11 @@ var CookieSerializer = class {
|
|
|
2287
1566
|
}
|
|
2288
1567
|
/**
|
|
2289
1568
|
* Encrypts a key-value pair to an encrypted cookie.
|
|
1569
|
+
*
|
|
1570
|
+
* @param key - The cookie key
|
|
1571
|
+
* @param value - The value to encrypt
|
|
1572
|
+
* @param options - Cookie options
|
|
1573
|
+
* @returns The serialized encrypted cookie string or null if encryption fails
|
|
2290
1574
|
*/
|
|
2291
1575
|
encrypt(key, value, options) {
|
|
2292
1576
|
const packedValue = this.#client.encrypt(key, value);
|
|
@@ -2298,8 +1582,31 @@ var CookieSerializer = class {
|
|
|
2298
1582
|
};
|
|
2299
1583
|
|
|
2300
1584
|
// src/response.ts
|
|
1585
|
+
import etag from "etag";
|
|
1586
|
+
import vary from "vary";
|
|
1587
|
+
import fresh2 from "fresh";
|
|
1588
|
+
import destroy from "destroy";
|
|
1589
|
+
import { extname } from "path";
|
|
1590
|
+
import { Buffer } from "buffer";
|
|
1591
|
+
import onFinished from "on-finished";
|
|
1592
|
+
import { stat } from "fs/promises";
|
|
1593
|
+
import Macroable2 from "@poppinss/macroable";
|
|
1594
|
+
import { createReadStream } from "fs";
|
|
1595
|
+
import contentDisposition from "content-disposition";
|
|
1596
|
+
import { safeStringify } from "@poppinss/utils/json";
|
|
1597
|
+
import { RuntimeException } from "@poppinss/utils/exception";
|
|
2301
1598
|
var CACHEABLE_HTTP_METHODS = ["GET", "HEAD"];
|
|
2302
|
-
var Response = class extends
|
|
1599
|
+
var Response = class extends Macroable2 {
|
|
1600
|
+
/**
|
|
1601
|
+
* Creates a new Response instance
|
|
1602
|
+
*
|
|
1603
|
+
* @param request - Node.js IncomingMessage instance
|
|
1604
|
+
* @param response - Node.js ServerResponse instance
|
|
1605
|
+
* @param encryption - Encryption service for cookie handling
|
|
1606
|
+
* @param config - Response configuration settings
|
|
1607
|
+
* @param router - Router instance for URL generation
|
|
1608
|
+
* @param qs - Query string parser
|
|
1609
|
+
*/
|
|
2303
1610
|
constructor(request, response, encryption, config, router, qs) {
|
|
2304
1611
|
super();
|
|
2305
1612
|
this.request = request;
|
|
@@ -2310,73 +1617,67 @@ var Response = class extends Macroable6 {
|
|
|
2310
1617
|
this.#cookieSerializer = new CookieSerializer(encryption);
|
|
2311
1618
|
}
|
|
2312
1619
|
/**
|
|
2313
|
-
* Query string parser
|
|
1620
|
+
* Query string parser instance used for URL manipulation
|
|
2314
1621
|
*/
|
|
2315
1622
|
#qs;
|
|
2316
1623
|
/**
|
|
2317
|
-
*
|
|
1624
|
+
* Collection of outgoing HTTP headers to be sent with the response
|
|
2318
1625
|
*/
|
|
2319
1626
|
#headers = {};
|
|
2320
1627
|
/**
|
|
2321
|
-
*
|
|
1628
|
+
* Flag indicating whether an explicit status code has been set
|
|
2322
1629
|
*/
|
|
2323
1630
|
#hasExplicitStatus = false;
|
|
2324
1631
|
/**
|
|
2325
|
-
*
|
|
1632
|
+
* Cookie serializer instance for handling cookie encryption, signing, and encoding
|
|
2326
1633
|
*/
|
|
2327
1634
|
#cookieSerializer;
|
|
2328
1635
|
/**
|
|
2329
|
-
* Router
|
|
1636
|
+
* Router instance used for generating redirect URLs from route definitions
|
|
2330
1637
|
*/
|
|
2331
1638
|
#router;
|
|
2332
1639
|
/**
|
|
2333
|
-
*
|
|
1640
|
+
* Configuration object containing response-related settings
|
|
2334
1641
|
*/
|
|
2335
1642
|
#config;
|
|
2336
1643
|
/**
|
|
2337
|
-
*
|
|
2338
|
-
* response socket at the end of the request
|
|
1644
|
+
* Indicates whether the response has any content (body, stream, or file) ready to be sent
|
|
2339
1645
|
*/
|
|
2340
1646
|
get hasLazyBody() {
|
|
2341
1647
|
return !!(this.lazyBody.content || this.lazyBody.fileToStream || this.lazyBody.stream);
|
|
2342
1648
|
}
|
|
2343
1649
|
/**
|
|
2344
|
-
*
|
|
1650
|
+
* Indicates whether the response has non-stream content set
|
|
2345
1651
|
*/
|
|
2346
1652
|
get hasContent() {
|
|
2347
1653
|
return !!this.lazyBody.content;
|
|
2348
1654
|
}
|
|
2349
1655
|
/**
|
|
2350
|
-
*
|
|
2351
|
-
* method
|
|
1656
|
+
* Indicates whether the response body is set as a readable stream
|
|
2352
1657
|
*/
|
|
2353
1658
|
get hasStream() {
|
|
2354
1659
|
return !!this.lazyBody.stream;
|
|
2355
1660
|
}
|
|
2356
1661
|
/**
|
|
2357
|
-
*
|
|
2358
|
-
* or "response.attachment" methods
|
|
1662
|
+
* Indicates whether the response is configured to stream a file
|
|
2359
1663
|
*/
|
|
2360
1664
|
get hasFileToStream() {
|
|
2361
1665
|
return !!this.lazyBody.fileToStream;
|
|
2362
1666
|
}
|
|
2363
1667
|
/**
|
|
2364
|
-
*
|
|
2365
|
-
* has content using the "hasContent" method
|
|
1668
|
+
* The response content data
|
|
2366
1669
|
*/
|
|
2367
1670
|
get content() {
|
|
2368
1671
|
return this.lazyBody.content;
|
|
2369
1672
|
}
|
|
2370
1673
|
/**
|
|
2371
|
-
*
|
|
2372
|
-
* method
|
|
1674
|
+
* The readable stream instance configured for the response
|
|
2373
1675
|
*/
|
|
2374
1676
|
get outgoingStream() {
|
|
2375
1677
|
return this.lazyBody.stream?.[0];
|
|
2376
1678
|
}
|
|
2377
1679
|
/**
|
|
2378
|
-
*
|
|
2379
|
-
* method.
|
|
1680
|
+
* Configuration for file streaming including path and etag generation flag
|
|
2380
1681
|
*/
|
|
2381
1682
|
get fileToStream() {
|
|
2382
1683
|
return this.lazyBody.fileToStream ? {
|
|
@@ -2385,48 +1686,46 @@ var Response = class extends Macroable6 {
|
|
|
2385
1686
|
} : void 0;
|
|
2386
1687
|
}
|
|
2387
1688
|
/**
|
|
2388
|
-
* Lazy body
|
|
2389
|
-
*
|
|
2390
|
-
* is called.
|
|
1689
|
+
* Lazy body container that holds response content until ready to send.
|
|
1690
|
+
* Contains different types of response data: content, stream, or fileToStream.
|
|
2391
1691
|
*/
|
|
2392
1692
|
lazyBody = {};
|
|
2393
1693
|
/**
|
|
2394
|
-
*
|
|
2395
|
-
* reference
|
|
1694
|
+
* HTTP context reference (creates circular dependency with HttpContext)
|
|
2396
1695
|
*/
|
|
2397
1696
|
ctx;
|
|
2398
1697
|
/**
|
|
2399
|
-
*
|
|
2400
|
-
* Any more attempts to update headers or body will result
|
|
2401
|
-
* in raised exceptions.
|
|
1698
|
+
* Indicates whether the response has been completely sent
|
|
2402
1699
|
*/
|
|
2403
1700
|
get finished() {
|
|
2404
1701
|
return this.response.writableFinished;
|
|
2405
1702
|
}
|
|
2406
1703
|
/**
|
|
2407
|
-
*
|
|
2408
|
-
* Any more attempts to update headers will result in raised
|
|
2409
|
-
* exceptions.
|
|
1704
|
+
* Indicates whether response headers have been sent to the client
|
|
2410
1705
|
*/
|
|
2411
1706
|
get headersSent() {
|
|
2412
1707
|
return this.response.headersSent;
|
|
2413
1708
|
}
|
|
2414
1709
|
/**
|
|
2415
|
-
*
|
|
2416
|
-
* or not. When value is `true`, you can feel free to write headers
|
|
2417
|
-
* and body.
|
|
1710
|
+
* Indicates whether the response is still pending (headers and body can still be modified)
|
|
2418
1711
|
*/
|
|
2419
1712
|
get isPending() {
|
|
2420
1713
|
return !this.headersSent && !this.finished;
|
|
2421
1714
|
}
|
|
2422
1715
|
/**
|
|
2423
|
-
* Normalizes header value to a string or an array of
|
|
1716
|
+
* Normalizes header value to a string or an array of strings
|
|
1717
|
+
*
|
|
1718
|
+
* @param value - The header value to normalize
|
|
1719
|
+
* @returns Normalized header value
|
|
2424
1720
|
*/
|
|
2425
1721
|
#castHeaderValue(value) {
|
|
2426
1722
|
return Array.isArray(value) ? value.map(String) : String(value);
|
|
2427
1723
|
}
|
|
2428
1724
|
/**
|
|
2429
1725
|
* Ends the response by flushing headers and writing body
|
|
1726
|
+
*
|
|
1727
|
+
* @param body - Optional response body
|
|
1728
|
+
* @param statusCode - Optional status code
|
|
2430
1729
|
*/
|
|
2431
1730
|
#endResponse(body, statusCode) {
|
|
2432
1731
|
this.writeHead(statusCode);
|
|
@@ -2434,14 +1733,18 @@ var Response = class extends Macroable6 {
|
|
|
2434
1733
|
res.end(body, null, null);
|
|
2435
1734
|
}
|
|
2436
1735
|
/**
|
|
2437
|
-
*
|
|
1736
|
+
* Determines the data type of the content for serialization
|
|
2438
1737
|
*
|
|
1738
|
+
* Supported types:
|
|
2439
1739
|
* - Dates
|
|
2440
1740
|
* - Arrays
|
|
2441
1741
|
* - Booleans
|
|
2442
1742
|
* - Objects
|
|
2443
1743
|
* - Strings
|
|
2444
1744
|
* - Buffer
|
|
1745
|
+
*
|
|
1746
|
+
* @param content - The content to analyze
|
|
1747
|
+
* @returns The determined data type as string
|
|
2445
1748
|
*/
|
|
2446
1749
|
#getDataType(content) {
|
|
2447
1750
|
const dataType = typeof content;
|
|
@@ -2460,13 +1763,20 @@ var Response = class extends Macroable6 {
|
|
|
2460
1763
|
}
|
|
2461
1764
|
return "object";
|
|
2462
1765
|
}
|
|
2463
|
-
throw new
|
|
1766
|
+
throw new RuntimeException(`Cannot serialize "${dataType}" to HTTP response`);
|
|
2464
1767
|
}
|
|
2465
1768
|
/**
|
|
2466
|
-
* Writes the body with appropriate
|
|
2467
|
-
* when `generateEtag` is set to `true`.
|
|
1769
|
+
* Writes the response body with appropriate headers and content type detection
|
|
2468
1770
|
*
|
|
2469
|
-
*
|
|
1771
|
+
* Automatically sets:
|
|
1772
|
+
* - Content-Type based on content analysis
|
|
1773
|
+
* - Content-Length header
|
|
1774
|
+
* - ETag header (if enabled)
|
|
1775
|
+
* - Status code 204 for empty bodies
|
|
1776
|
+
*
|
|
1777
|
+
* @param content - The response content
|
|
1778
|
+
* @param generateEtag - Whether to generate ETag header
|
|
1779
|
+
* @param jsonpCallbackName - Optional JSONP callback name
|
|
2470
1780
|
*/
|
|
2471
1781
|
writeBody(content, generateEtag, jsonpCallbackName) {
|
|
2472
1782
|
const hasEmptyBody = content === null || content === void 0 || content === "";
|
|
@@ -2536,7 +1846,16 @@ var Response = class extends Macroable6 {
|
|
|
2536
1846
|
this.#endResponse(content);
|
|
2537
1847
|
}
|
|
2538
1848
|
/**
|
|
2539
|
-
*
|
|
1849
|
+
* Streams the response body and handles error cleanup
|
|
1850
|
+
*
|
|
1851
|
+
* Manages stream lifecycle including:
|
|
1852
|
+
* - Error handling with custom callbacks
|
|
1853
|
+
* - Proper stream cleanup to prevent memory leaks
|
|
1854
|
+
* - Response finalization
|
|
1855
|
+
*
|
|
1856
|
+
* @param body - The readable stream to pipe
|
|
1857
|
+
* @param errorCallback - Optional custom error handler
|
|
1858
|
+
* @returns Promise that resolves when streaming is complete
|
|
2540
1859
|
*/
|
|
2541
1860
|
streamBody(body, errorCallback) {
|
|
2542
1861
|
return new Promise((resolve) => {
|
|
@@ -2577,7 +1896,19 @@ var Response = class extends Macroable6 {
|
|
|
2577
1896
|
});
|
|
2578
1897
|
}
|
|
2579
1898
|
/**
|
|
2580
|
-
*
|
|
1899
|
+
* Streams a file for download with proper headers and caching support
|
|
1900
|
+
*
|
|
1901
|
+
* Sets appropriate headers:
|
|
1902
|
+
* - Last-Modified based on file stats
|
|
1903
|
+
* - Content-Type based on file extension
|
|
1904
|
+
* - Content-Length from file size
|
|
1905
|
+
* - ETag (if enabled)
|
|
1906
|
+
*
|
|
1907
|
+
* Handles HEAD requests and cache validation (304 responses).
|
|
1908
|
+
*
|
|
1909
|
+
* @param filePath - Path to the file to stream
|
|
1910
|
+
* @param generateEtag - Whether to generate ETag header
|
|
1911
|
+
* @param errorCallback - Optional custom error handler
|
|
2581
1912
|
*/
|
|
2582
1913
|
async streamFileForDownload(filePath, generateEtag, errorCallback) {
|
|
2583
1914
|
try {
|
|
@@ -2617,18 +1948,18 @@ var Response = class extends Macroable6 {
|
|
|
2617
1948
|
}
|
|
2618
1949
|
}
|
|
2619
1950
|
/**
|
|
2620
|
-
*
|
|
2621
|
-
* to the TCP socket.
|
|
1951
|
+
* Registers a callback to be called when the response is finished
|
|
2622
1952
|
*
|
|
2623
|
-
*
|
|
2624
|
-
* the "
|
|
1953
|
+
* The callback is executed when the response has been completely sent.
|
|
1954
|
+
* Uses the "on-finished" package internally.
|
|
1955
|
+
*
|
|
1956
|
+
* @param callback - Function to call when response is finished
|
|
2625
1957
|
*/
|
|
2626
1958
|
onFinish(callback) {
|
|
2627
1959
|
onFinished(this.response, callback);
|
|
2628
1960
|
}
|
|
2629
1961
|
/**
|
|
2630
|
-
*
|
|
2631
|
-
* response.setHeader method
|
|
1962
|
+
* Transfers all buffered headers to the underlying Node.js response object
|
|
2632
1963
|
*/
|
|
2633
1964
|
relayHeaders() {
|
|
2634
1965
|
if (!this.headersSent) {
|
|
@@ -2641,22 +1972,29 @@ var Response = class extends Macroable6 {
|
|
|
2641
1972
|
}
|
|
2642
1973
|
}
|
|
2643
1974
|
/**
|
|
2644
|
-
*
|
|
1975
|
+
* Writes the response status code and headers
|
|
1976
|
+
*
|
|
1977
|
+
* @param statusCode - Optional status code to set
|
|
1978
|
+
* @returns The Response instance for chaining
|
|
2645
1979
|
*/
|
|
2646
1980
|
writeHead(statusCode) {
|
|
2647
1981
|
this.response.writeHead(statusCode || this.response.statusCode, this.#headers);
|
|
2648
1982
|
return this;
|
|
2649
1983
|
}
|
|
2650
1984
|
/**
|
|
2651
|
-
*
|
|
2652
|
-
*
|
|
1985
|
+
* Gets the value of a response header
|
|
1986
|
+
*
|
|
1987
|
+
* @param key - Header name
|
|
1988
|
+
* @returns The header value
|
|
2653
1989
|
*/
|
|
2654
1990
|
getHeader(key) {
|
|
2655
1991
|
const value = this.#headers[key.toLowerCase()];
|
|
2656
1992
|
return value === void 0 ? this.response.getHeader(key) : value;
|
|
2657
1993
|
}
|
|
2658
1994
|
/**
|
|
2659
|
-
*
|
|
1995
|
+
* Gets all response headers as an object
|
|
1996
|
+
*
|
|
1997
|
+
* @returns Object containing all headers
|
|
2660
1998
|
*/
|
|
2661
1999
|
getHeaders() {
|
|
2662
2000
|
return {
|
|
@@ -2665,14 +2003,15 @@ var Response = class extends Macroable6 {
|
|
|
2665
2003
|
};
|
|
2666
2004
|
}
|
|
2667
2005
|
/**
|
|
2668
|
-
*
|
|
2669
|
-
* using [[append]] method.
|
|
2006
|
+
* Sets a response header (replaces existing value)
|
|
2670
2007
|
*
|
|
2671
|
-
*
|
|
2008
|
+
* @param key - Header name
|
|
2009
|
+
* @param value - Header value (ignored if null/undefined)
|
|
2010
|
+
* @returns The Response instance for chaining
|
|
2672
2011
|
*
|
|
2673
2012
|
* @example
|
|
2674
|
-
* ```
|
|
2675
|
-
* response.header('
|
|
2013
|
+
* ```ts
|
|
2014
|
+
* response.header('Content-Type', 'application/json')
|
|
2676
2015
|
* ```
|
|
2677
2016
|
*/
|
|
2678
2017
|
header(key, value) {
|
|
@@ -2683,14 +2022,15 @@ var Response = class extends Macroable6 {
|
|
|
2683
2022
|
return this;
|
|
2684
2023
|
}
|
|
2685
2024
|
/**
|
|
2686
|
-
*
|
|
2687
|
-
* [[header]] method.
|
|
2025
|
+
* Appends a value to an existing response header
|
|
2688
2026
|
*
|
|
2689
|
-
*
|
|
2027
|
+
* @param key - Header name
|
|
2028
|
+
* @param value - Header value to append (ignored if null/undefined)
|
|
2029
|
+
* @returns The Response instance for chaining
|
|
2690
2030
|
*
|
|
2691
2031
|
* @example
|
|
2692
|
-
* ```
|
|
2693
|
-
* response.append('
|
|
2032
|
+
* ```ts
|
|
2033
|
+
* response.append('Set-Cookie', 'session=abc123')
|
|
2694
2034
|
* ```
|
|
2695
2035
|
*/
|
|
2696
2036
|
append(key, value) {
|
|
@@ -2710,7 +2050,11 @@ var Response = class extends Macroable6 {
|
|
|
2710
2050
|
return this;
|
|
2711
2051
|
}
|
|
2712
2052
|
/**
|
|
2713
|
-
*
|
|
2053
|
+
* Sets a header only if it doesn't already exist
|
|
2054
|
+
*
|
|
2055
|
+
* @param key - Header name
|
|
2056
|
+
* @param value - Header value
|
|
2057
|
+
* @returns The Response instance for chaining
|
|
2714
2058
|
*/
|
|
2715
2059
|
safeHeader(key, value) {
|
|
2716
2060
|
if (!this.getHeader(key)) {
|
|
@@ -2719,7 +2063,10 @@ var Response = class extends Macroable6 {
|
|
|
2719
2063
|
return this;
|
|
2720
2064
|
}
|
|
2721
2065
|
/**
|
|
2722
|
-
* Removes
|
|
2066
|
+
* Removes a response header
|
|
2067
|
+
*
|
|
2068
|
+
* @param key - Header name to remove
|
|
2069
|
+
* @returns The Response instance for chaining
|
|
2723
2070
|
*/
|
|
2724
2071
|
removeHeader(key) {
|
|
2725
2072
|
key = key.toLowerCase();
|
|
@@ -2730,13 +2077,18 @@ var Response = class extends Macroable6 {
|
|
|
2730
2077
|
return this;
|
|
2731
2078
|
}
|
|
2732
2079
|
/**
|
|
2733
|
-
*
|
|
2080
|
+
* Gets the current response status code
|
|
2081
|
+
*
|
|
2082
|
+
* @returns The HTTP status code
|
|
2734
2083
|
*/
|
|
2735
2084
|
getStatus() {
|
|
2736
2085
|
return this.response.statusCode;
|
|
2737
2086
|
}
|
|
2738
2087
|
/**
|
|
2739
|
-
*
|
|
2088
|
+
* Sets the response status code
|
|
2089
|
+
*
|
|
2090
|
+
* @param code - HTTP status code
|
|
2091
|
+
* @returns The Response instance for chaining
|
|
2740
2092
|
*/
|
|
2741
2093
|
status(code) {
|
|
2742
2094
|
this.#hasExplicitStatus = true;
|
|
@@ -2744,8 +2096,10 @@ var Response = class extends Macroable6 {
|
|
|
2744
2096
|
return this;
|
|
2745
2097
|
}
|
|
2746
2098
|
/**
|
|
2747
|
-
*
|
|
2748
|
-
*
|
|
2099
|
+
* Sets the status code only if not explicitly set already
|
|
2100
|
+
*
|
|
2101
|
+
* @param code - HTTP status code
|
|
2102
|
+
* @returns The Response instance for chaining
|
|
2749
2103
|
*/
|
|
2750
2104
|
safeStatus(code) {
|
|
2751
2105
|
if (this.#hasExplicitStatus) {
|
|
@@ -2755,15 +2109,16 @@ var Response = class extends Macroable6 {
|
|
|
2755
2109
|
return this;
|
|
2756
2110
|
}
|
|
2757
2111
|
/**
|
|
2758
|
-
*
|
|
2759
|
-
* partial types like file extensions.
|
|
2112
|
+
* Sets the Content-Type header based on mime type lookup
|
|
2760
2113
|
*
|
|
2761
|
-
*
|
|
2762
|
-
*
|
|
2114
|
+
* @param type - File extension or mime type
|
|
2115
|
+
* @param charset - Optional character encoding
|
|
2116
|
+
* @returns The Response instance for chaining
|
|
2763
2117
|
*
|
|
2764
2118
|
* @example
|
|
2765
|
-
* ```
|
|
2766
|
-
* response.type('.json') // Content-
|
|
2119
|
+
* ```ts
|
|
2120
|
+
* response.type('.json') // Content-Type: application/json
|
|
2121
|
+
* response.type('html', 'utf-8') // Content-Type: text/html; charset=utf-8
|
|
2767
2122
|
* ```
|
|
2768
2123
|
*/
|
|
2769
2124
|
type(type, charset) {
|
|
@@ -2772,25 +2127,30 @@ var Response = class extends Macroable6 {
|
|
|
2772
2127
|
return this;
|
|
2773
2128
|
}
|
|
2774
2129
|
/**
|
|
2775
|
-
*
|
|
2130
|
+
* Sets the Vary HTTP header for cache control
|
|
2131
|
+
*
|
|
2132
|
+
* @param field - Header field name(s) to vary on
|
|
2133
|
+
* @returns The Response instance for chaining
|
|
2776
2134
|
*/
|
|
2777
2135
|
vary(field) {
|
|
2778
2136
|
vary(this.response, field);
|
|
2779
2137
|
return this;
|
|
2780
2138
|
}
|
|
2781
2139
|
/**
|
|
2782
|
-
*
|
|
2783
|
-
* when `etag = true` in the defined config object.
|
|
2140
|
+
* Sets the ETag header by computing a hash from the response body
|
|
2784
2141
|
*
|
|
2785
|
-
*
|
|
2142
|
+
* @param body - The response body to hash
|
|
2143
|
+
* @param weak - Whether to generate a weak ETag
|
|
2144
|
+
* @returns The Response instance for chaining
|
|
2786
2145
|
*/
|
|
2787
2146
|
setEtag(body, weak = false) {
|
|
2788
2147
|
this.header("Etag", etag(body, { weak }));
|
|
2789
2148
|
return this;
|
|
2790
2149
|
}
|
|
2791
2150
|
/**
|
|
2792
|
-
*
|
|
2151
|
+
* Sets the X-Request-Id header by copying from the incoming request
|
|
2793
2152
|
*
|
|
2153
|
+
* @returns The Response instance for chaining
|
|
2794
2154
|
*/
|
|
2795
2155
|
setRequestId() {
|
|
2796
2156
|
const requestId = this.request.headers["x-request-id"];
|
|
@@ -2800,27 +2160,20 @@ var Response = class extends Macroable6 {
|
|
|
2800
2160
|
return this;
|
|
2801
2161
|
}
|
|
2802
2162
|
/**
|
|
2803
|
-
*
|
|
2804
|
-
* as the request header `if-none-match`. In case of `true`, the
|
|
2805
|
-
* server must return `304` response, telling the browser to
|
|
2806
|
-
* use the client cache.
|
|
2163
|
+
* Checks if the response is fresh (client cache is valid)
|
|
2807
2164
|
*
|
|
2808
|
-
*
|
|
2809
|
-
*
|
|
2165
|
+
* Compares ETags and modified dates between request and response
|
|
2166
|
+
* to determine if a 304 Not Modified response should be sent.
|
|
2810
2167
|
*
|
|
2811
|
-
*
|
|
2168
|
+
* @returns True if client cache is fresh, false otherwise
|
|
2812
2169
|
*
|
|
2813
2170
|
* @example
|
|
2814
|
-
* ```
|
|
2815
|
-
*
|
|
2816
|
-
*
|
|
2817
|
-
* // sets the HTTP etag header for response
|
|
2818
|
-
* response.setEtag(responseBody)
|
|
2819
|
-
*
|
|
2171
|
+
* ```ts
|
|
2172
|
+
* response.setEtag(content)
|
|
2820
2173
|
* if (response.fresh()) {
|
|
2821
|
-
* response.
|
|
2174
|
+
* response.status(304).send(null)
|
|
2822
2175
|
* } else {
|
|
2823
|
-
* response.send(
|
|
2176
|
+
* response.send(content)
|
|
2824
2177
|
* }
|
|
2825
2178
|
* ```
|
|
2826
2179
|
*/
|
|
@@ -2835,8 +2188,9 @@ var Response = class extends Macroable6 {
|
|
|
2835
2188
|
return false;
|
|
2836
2189
|
}
|
|
2837
2190
|
/**
|
|
2838
|
-
*
|
|
2839
|
-
*
|
|
2191
|
+
* Gets the response body content
|
|
2192
|
+
*
|
|
2193
|
+
* @returns The response body or null if not set or is a stream
|
|
2840
2194
|
*/
|
|
2841
2195
|
getBody() {
|
|
2842
2196
|
if (this.lazyBody.content) {
|
|
@@ -2845,58 +2199,54 @@ var Response = class extends Macroable6 {
|
|
|
2845
2199
|
return null;
|
|
2846
2200
|
}
|
|
2847
2201
|
/**
|
|
2848
|
-
*
|
|
2849
|
-
* is read from `config/app.js` file, using `http.etag` property.
|
|
2202
|
+
* Sends the response body with optional ETag generation
|
|
2850
2203
|
*
|
|
2851
|
-
*
|
|
2852
|
-
*
|
|
2204
|
+
* @param body - The response body
|
|
2205
|
+
* @param generateEtag - Whether to generate ETag header (defaults to config)
|
|
2853
2206
|
*/
|
|
2854
2207
|
send(body, generateEtag = this.#config.etag) {
|
|
2855
2208
|
this.lazyBody.content = [body, generateEtag];
|
|
2856
2209
|
}
|
|
2857
2210
|
/**
|
|
2858
|
-
*
|
|
2211
|
+
* Sends a JSON response (alias for send)
|
|
2212
|
+
*
|
|
2213
|
+
* @param body - The response body to serialize as JSON
|
|
2214
|
+
* @param generateEtag - Whether to generate ETag header
|
|
2859
2215
|
*/
|
|
2860
2216
|
json(body, generateEtag = this.#config.etag) {
|
|
2861
2217
|
return this.send(body, generateEtag);
|
|
2862
2218
|
}
|
|
2863
2219
|
/**
|
|
2864
|
-
*
|
|
2865
|
-
* from top to bottom.
|
|
2220
|
+
* Sends a JSONP response with callback wrapping
|
|
2866
2221
|
*
|
|
2867
|
-
*
|
|
2868
|
-
*
|
|
2869
|
-
*
|
|
2870
|
-
*
|
|
2222
|
+
* Callback name resolution priority:
|
|
2223
|
+
* 1. Explicit callbackName parameter
|
|
2224
|
+
* 2. Query string parameter
|
|
2225
|
+
* 3. Config value
|
|
2226
|
+
* 4. Default "callback"
|
|
2871
2227
|
*
|
|
2872
|
-
*
|
|
2873
|
-
*
|
|
2228
|
+
* @param body - The response body
|
|
2229
|
+
* @param callbackName - JSONP callback function name
|
|
2230
|
+
* @param generateEtag - Whether to generate ETag header
|
|
2874
2231
|
*/
|
|
2875
2232
|
jsonp(body, callbackName = this.#config.jsonpCallbackName, generateEtag = this.#config.etag) {
|
|
2876
2233
|
this.lazyBody.content = [body, generateEtag, callbackName];
|
|
2877
2234
|
}
|
|
2878
2235
|
/**
|
|
2879
|
-
*
|
|
2880
|
-
* the stream, avoiding memory leaks.
|
|
2236
|
+
* Pipes a readable stream to the response with graceful error handling
|
|
2881
2237
|
*
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
2884
|
-
* recommended to set `raiseErrors=true` and wrap this function inside a
|
|
2885
|
-
* `try/catch` statement.
|
|
2886
|
-
*
|
|
2887
|
-
* Streaming a file from the disk and showing 404 when file is missing.
|
|
2238
|
+
* @param body - The readable stream to pipe
|
|
2239
|
+
* @param errorCallback - Optional custom error handler
|
|
2888
2240
|
*
|
|
2889
2241
|
* @example
|
|
2890
|
-
* ```
|
|
2891
|
-
* //
|
|
2242
|
+
* ```ts
|
|
2243
|
+
* // Auto error handling
|
|
2892
2244
|
* response.stream(fs.createReadStream('file.txt'))
|
|
2893
2245
|
*
|
|
2894
|
-
* //
|
|
2895
|
-
*
|
|
2896
|
-
*
|
|
2897
|
-
* }
|
|
2898
|
-
* response.status(404).send('File not found')
|
|
2899
|
-
* }
|
|
2246
|
+
* // Custom error handling
|
|
2247
|
+
* response.stream(stream, (error) => {
|
|
2248
|
+
* return error.code === 'ENOENT' ? ['Not found', 404] : ['Error', 500]
|
|
2249
|
+
* })
|
|
2900
2250
|
* ```
|
|
2901
2251
|
*/
|
|
2902
2252
|
stream(body, errorCallback) {
|
|
@@ -2906,38 +2256,35 @@ var Response = class extends Macroable6 {
|
|
|
2906
2256
|
this.lazyBody.stream = [body, errorCallback];
|
|
2907
2257
|
}
|
|
2908
2258
|
/**
|
|
2909
|
-
*
|
|
2910
|
-
* appropriate `Content-type`, `Content-type` and `Last-modified` headers.
|
|
2259
|
+
* Downloads a file by streaming it with appropriate headers
|
|
2911
2260
|
*
|
|
2912
|
-
*
|
|
2261
|
+
* Automatically sets:
|
|
2262
|
+
* - Content-Type from file extension
|
|
2263
|
+
* - Content-Length from file size
|
|
2264
|
+
* - Last-Modified from file stats
|
|
2265
|
+
* - ETag (if enabled)
|
|
2913
2266
|
*
|
|
2914
|
-
*
|
|
2915
|
-
*
|
|
2916
|
-
*
|
|
2917
|
-
* `try/catch` statement.
|
|
2267
|
+
* @param filePath - Path to the file to download
|
|
2268
|
+
* @param generateEtag - Whether to generate ETag header
|
|
2269
|
+
* @param errorCallback - Optional custom error handler
|
|
2918
2270
|
*
|
|
2919
2271
|
* @example
|
|
2920
|
-
* ```
|
|
2921
|
-
*
|
|
2922
|
-
* response.download('
|
|
2923
|
-
*
|
|
2924
|
-
* // Manually handle (note the await call)
|
|
2925
|
-
* try {
|
|
2926
|
-
* await response.download('somefile.jpg')
|
|
2927
|
-
* } catch (error) {
|
|
2928
|
-
* response.status(error.code === 'ENOENT' ? 404 : 500)
|
|
2929
|
-
* response.send('Cannot process file')
|
|
2930
|
-
* }
|
|
2272
|
+
* ```ts
|
|
2273
|
+
* response.download('/path/to/file.pdf')
|
|
2274
|
+
* response.download('/images/photo.jpg', true, (err) => ['Custom error', 500])
|
|
2931
2275
|
* ```
|
|
2932
2276
|
*/
|
|
2933
2277
|
download(filePath, generateEtag = this.#config.etag, errorCallback) {
|
|
2934
2278
|
this.lazyBody.fileToStream = [filePath, generateEtag, errorCallback];
|
|
2935
2279
|
}
|
|
2936
2280
|
/**
|
|
2937
|
-
*
|
|
2938
|
-
* within the browser.
|
|
2281
|
+
* Forces file download by setting Content-Disposition header
|
|
2939
2282
|
*
|
|
2940
|
-
*
|
|
2283
|
+
* @param filePath - Path to the file to download
|
|
2284
|
+
* @param name - Optional filename for download (defaults to original filename)
|
|
2285
|
+
* @param disposition - Content-Disposition type (defaults to 'attachment')
|
|
2286
|
+
* @param generateEtag - Whether to generate ETag header
|
|
2287
|
+
* @param errorCallback - Optional custom error handler
|
|
2941
2288
|
*/
|
|
2942
2289
|
attachment(filePath, name, disposition, generateEtag, errorCallback) {
|
|
2943
2290
|
name = name || filePath;
|
|
@@ -2945,11 +2292,14 @@ var Response = class extends Macroable6 {
|
|
|
2945
2292
|
return this.download(filePath, generateEtag, errorCallback);
|
|
2946
2293
|
}
|
|
2947
2294
|
/**
|
|
2948
|
-
*
|
|
2295
|
+
* Sets the Location header for redirects
|
|
2296
|
+
*
|
|
2297
|
+
* @param url - The URL to redirect to
|
|
2298
|
+
* @returns The Response instance for chaining
|
|
2949
2299
|
*
|
|
2950
2300
|
* @example
|
|
2951
|
-
* ```
|
|
2952
|
-
* response.location('/
|
|
2301
|
+
* ```ts
|
|
2302
|
+
* response.location('/dashboard')
|
|
2953
2303
|
* ```
|
|
2954
2304
|
*/
|
|
2955
2305
|
location(url) {
|
|
@@ -2970,15 +2320,21 @@ var Response = class extends Macroable6 {
|
|
|
2970
2320
|
return handler;
|
|
2971
2321
|
}
|
|
2972
2322
|
/**
|
|
2973
|
-
*
|
|
2974
|
-
*
|
|
2323
|
+
* Aborts the request with a custom response body and status code
|
|
2324
|
+
*
|
|
2325
|
+
* @param body - Response body for the aborted request
|
|
2326
|
+
* @param status - HTTP status code (defaults to 400)
|
|
2327
|
+
* @throws Always throws an HTTP exception
|
|
2975
2328
|
*/
|
|
2976
2329
|
abort(body, status) {
|
|
2977
2330
|
throw E_HTTP_REQUEST_ABORTED.invoke(body, status || ResponseStatus.BadRequest);
|
|
2978
2331
|
}
|
|
2979
2332
|
/**
|
|
2980
|
-
*
|
|
2981
|
-
*
|
|
2333
|
+
* Conditionally aborts the request if the condition is truthy
|
|
2334
|
+
*
|
|
2335
|
+
* @param condition - Condition to evaluate
|
|
2336
|
+
* @param body - Response body for the aborted request
|
|
2337
|
+
* @param status - HTTP status code (defaults to 400)
|
|
2982
2338
|
*/
|
|
2983
2339
|
abortIf(condition, body, status) {
|
|
2984
2340
|
if (condition) {
|
|
@@ -2986,8 +2342,11 @@ var Response = class extends Macroable6 {
|
|
|
2986
2342
|
}
|
|
2987
2343
|
}
|
|
2988
2344
|
/**
|
|
2989
|
-
*
|
|
2990
|
-
*
|
|
2345
|
+
* Conditionally aborts the request if the condition is falsy
|
|
2346
|
+
*
|
|
2347
|
+
* @param condition - Condition to evaluate
|
|
2348
|
+
* @param body - Response body for the aborted request
|
|
2349
|
+
* @param status - HTTP status code (defaults to 400)
|
|
2991
2350
|
*/
|
|
2992
2351
|
abortUnless(condition, body, status) {
|
|
2993
2352
|
if (!condition) {
|
|
@@ -2995,8 +2354,12 @@ var Response = class extends Macroable6 {
|
|
|
2995
2354
|
}
|
|
2996
2355
|
}
|
|
2997
2356
|
/**
|
|
2998
|
-
*
|
|
2999
|
-
*
|
|
2357
|
+
* Sets a signed cookie in the response
|
|
2358
|
+
*
|
|
2359
|
+
* @param key - Cookie name
|
|
2360
|
+
* @param value - Cookie value
|
|
2361
|
+
* @param options - Cookie options (overrides config defaults)
|
|
2362
|
+
* @returns The Response instance for chaining
|
|
3000
2363
|
*/
|
|
3001
2364
|
cookie(key, value, options) {
|
|
3002
2365
|
options = Object.assign({}, this.#config.cookie, options);
|
|
@@ -3008,8 +2371,12 @@ var Response = class extends Macroable6 {
|
|
|
3008
2371
|
return this;
|
|
3009
2372
|
}
|
|
3010
2373
|
/**
|
|
3011
|
-
*
|
|
3012
|
-
*
|
|
2374
|
+
* Sets an encrypted cookie in the response
|
|
2375
|
+
*
|
|
2376
|
+
* @param key - Cookie name
|
|
2377
|
+
* @param value - Cookie value
|
|
2378
|
+
* @param options - Cookie options (overrides config defaults)
|
|
2379
|
+
* @returns The Response instance for chaining
|
|
3013
2380
|
*/
|
|
3014
2381
|
encryptedCookie(key, value, options) {
|
|
3015
2382
|
options = Object.assign({}, this.#config.cookie, options);
|
|
@@ -3021,8 +2388,12 @@ var Response = class extends Macroable6 {
|
|
|
3021
2388
|
return this;
|
|
3022
2389
|
}
|
|
3023
2390
|
/**
|
|
3024
|
-
*
|
|
3025
|
-
*
|
|
2391
|
+
* Sets a plain (unsigned/unencrypted) cookie in the response
|
|
2392
|
+
*
|
|
2393
|
+
* @param key - Cookie name
|
|
2394
|
+
* @param value - Cookie value
|
|
2395
|
+
* @param options - Cookie options including encode flag
|
|
2396
|
+
* @returns The Response instance for chaining
|
|
3026
2397
|
*/
|
|
3027
2398
|
plainCookie(key, value, options) {
|
|
3028
2399
|
options = Object.assign({}, this.#config.cookie, options);
|
|
@@ -3034,7 +2405,11 @@ var Response = class extends Macroable6 {
|
|
|
3034
2405
|
return this;
|
|
3035
2406
|
}
|
|
3036
2407
|
/**
|
|
3037
|
-
*
|
|
2408
|
+
* Clears an existing cookie by setting it to expire
|
|
2409
|
+
*
|
|
2410
|
+
* @param key - Cookie name to clear
|
|
2411
|
+
* @param options - Cookie options (should match original cookie options)
|
|
2412
|
+
* @returns The Response instance for chaining
|
|
3038
2413
|
*/
|
|
3039
2414
|
clearCookie(key, options) {
|
|
3040
2415
|
options = Object.assign({}, this.#config.cookie, options);
|
|
@@ -3045,10 +2420,10 @@ var Response = class extends Macroable6 {
|
|
|
3045
2420
|
return this;
|
|
3046
2421
|
}
|
|
3047
2422
|
/**
|
|
3048
|
-
*
|
|
3049
|
-
* and response is already pending.
|
|
2423
|
+
* Finalizes and sends the response
|
|
3050
2424
|
*
|
|
3051
|
-
*
|
|
2425
|
+
* Writes the buffered body (content, stream, or file) to the client.
|
|
2426
|
+
* This method is idempotent - calling it multiple times has no effect.
|
|
3052
2427
|
*/
|
|
3053
2428
|
finish() {
|
|
3054
2429
|
if (!this.isPending) {
|
|
@@ -3069,294 +2444,408 @@ var Response = class extends Macroable6 {
|
|
|
3069
2444
|
this.#endResponse();
|
|
3070
2445
|
}
|
|
3071
2446
|
/**
|
|
3072
|
-
*
|
|
2447
|
+
* Sends a 100 Continue response
|
|
3073
2448
|
*/
|
|
3074
2449
|
continue() {
|
|
3075
2450
|
this.status(ResponseStatus.Continue);
|
|
3076
2451
|
return this.send(null, false);
|
|
3077
2452
|
}
|
|
3078
2453
|
/**
|
|
3079
|
-
*
|
|
2454
|
+
* Sends a 101 Switching Protocols response
|
|
3080
2455
|
*/
|
|
3081
2456
|
switchingProtocols() {
|
|
3082
2457
|
this.status(ResponseStatus.SwitchingProtocols);
|
|
3083
2458
|
return this.send(null, false);
|
|
3084
2459
|
}
|
|
3085
2460
|
/**
|
|
3086
|
-
*
|
|
2461
|
+
* Sends a 200 OK response
|
|
2462
|
+
*
|
|
2463
|
+
* @param body - Response body
|
|
2464
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3087
2465
|
*/
|
|
3088
2466
|
ok(body, generateEtag) {
|
|
3089
2467
|
this.status(ResponseStatus.Ok);
|
|
3090
2468
|
return this.send(body, generateEtag);
|
|
3091
2469
|
}
|
|
3092
2470
|
/**
|
|
3093
|
-
*
|
|
2471
|
+
* Sends a 201 Created response
|
|
2472
|
+
*
|
|
2473
|
+
* @param body - Response body
|
|
2474
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3094
2475
|
*/
|
|
3095
2476
|
created(body, generateEtag) {
|
|
3096
2477
|
this.status(ResponseStatus.Created);
|
|
3097
2478
|
return this.send(body, generateEtag);
|
|
3098
2479
|
}
|
|
3099
2480
|
/**
|
|
3100
|
-
*
|
|
2481
|
+
* Sends a 202 Accepted response
|
|
2482
|
+
*
|
|
2483
|
+
* @param body - Response body
|
|
2484
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3101
2485
|
*/
|
|
3102
2486
|
accepted(body, generateEtag) {
|
|
3103
2487
|
this.status(ResponseStatus.Accepted);
|
|
3104
2488
|
return this.send(body, generateEtag);
|
|
3105
2489
|
}
|
|
3106
2490
|
/**
|
|
3107
|
-
*
|
|
2491
|
+
* Sends a 203 Non-Authoritative Information response
|
|
2492
|
+
*
|
|
2493
|
+
* @param body - Response body
|
|
2494
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3108
2495
|
*/
|
|
3109
2496
|
nonAuthoritativeInformation(body, generateEtag) {
|
|
3110
2497
|
this.status(ResponseStatus.NonAuthoritativeInformation);
|
|
3111
2498
|
return this.send(body, generateEtag);
|
|
3112
2499
|
}
|
|
3113
2500
|
/**
|
|
3114
|
-
*
|
|
2501
|
+
* Sends a 204 No Content response
|
|
3115
2502
|
*/
|
|
3116
2503
|
noContent() {
|
|
3117
2504
|
this.status(ResponseStatus.NoContent);
|
|
3118
2505
|
return this.send(null, false);
|
|
3119
2506
|
}
|
|
3120
2507
|
/**
|
|
3121
|
-
*
|
|
2508
|
+
* Sends a 205 Reset Content response
|
|
3122
2509
|
*/
|
|
3123
2510
|
resetContent() {
|
|
3124
2511
|
this.status(ResponseStatus.ResetContent);
|
|
3125
2512
|
return this.send(null, false);
|
|
3126
2513
|
}
|
|
3127
2514
|
/**
|
|
3128
|
-
*
|
|
2515
|
+
* Sends a 206 Partial Content response
|
|
2516
|
+
*
|
|
2517
|
+
* @param body - Response body
|
|
2518
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3129
2519
|
*/
|
|
3130
2520
|
partialContent(body, generateEtag) {
|
|
3131
2521
|
this.status(ResponseStatus.PartialContent);
|
|
3132
2522
|
return this.send(body, generateEtag);
|
|
3133
2523
|
}
|
|
3134
2524
|
/**
|
|
3135
|
-
*
|
|
2525
|
+
* Sends a 300 Multiple Choices response
|
|
2526
|
+
*
|
|
2527
|
+
* @param body - Response body
|
|
2528
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3136
2529
|
*/
|
|
3137
2530
|
multipleChoices(body, generateEtag) {
|
|
3138
2531
|
this.status(ResponseStatus.MultipleChoices);
|
|
3139
2532
|
return this.send(body, generateEtag);
|
|
3140
2533
|
}
|
|
3141
2534
|
/**
|
|
3142
|
-
*
|
|
2535
|
+
* Sends a 301 Moved Permanently response
|
|
2536
|
+
*
|
|
2537
|
+
* @param body - Response body
|
|
2538
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3143
2539
|
*/
|
|
3144
2540
|
movedPermanently(body, generateEtag) {
|
|
3145
2541
|
this.status(ResponseStatus.MovedPermanently);
|
|
3146
2542
|
return this.send(body, generateEtag);
|
|
3147
2543
|
}
|
|
3148
2544
|
/**
|
|
3149
|
-
*
|
|
2545
|
+
* Sends a 302 Found (Moved Temporarily) response
|
|
2546
|
+
*
|
|
2547
|
+
* @param body - Response body
|
|
2548
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3150
2549
|
*/
|
|
3151
2550
|
movedTemporarily(body, generateEtag) {
|
|
3152
2551
|
this.status(ResponseStatus.Found);
|
|
3153
2552
|
return this.send(body, generateEtag);
|
|
3154
2553
|
}
|
|
3155
2554
|
/**
|
|
3156
|
-
*
|
|
2555
|
+
* Sends a 303 See Other response
|
|
2556
|
+
*
|
|
2557
|
+
* @param body - Response body
|
|
2558
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3157
2559
|
*/
|
|
3158
2560
|
seeOther(body, generateEtag) {
|
|
3159
2561
|
this.status(ResponseStatus.SeeOther);
|
|
3160
2562
|
return this.send(body, generateEtag);
|
|
3161
2563
|
}
|
|
3162
2564
|
/**
|
|
3163
|
-
*
|
|
2565
|
+
* Sends a 304 Not Modified response
|
|
2566
|
+
*
|
|
2567
|
+
* @param body - Response body
|
|
2568
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3164
2569
|
*/
|
|
3165
2570
|
notModified(body, generateEtag) {
|
|
3166
2571
|
this.status(ResponseStatus.NotModified);
|
|
3167
2572
|
return this.send(body, generateEtag);
|
|
3168
2573
|
}
|
|
3169
2574
|
/**
|
|
3170
|
-
*
|
|
2575
|
+
* Sends a 305 Use Proxy response
|
|
2576
|
+
*
|
|
2577
|
+
* @param body - Response body
|
|
2578
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3171
2579
|
*/
|
|
3172
2580
|
useProxy(body, generateEtag) {
|
|
3173
2581
|
this.status(ResponseStatus.UseProxy);
|
|
3174
2582
|
return this.send(body, generateEtag);
|
|
3175
2583
|
}
|
|
3176
2584
|
/**
|
|
3177
|
-
*
|
|
2585
|
+
* Sends a 307 Temporary Redirect response
|
|
2586
|
+
*
|
|
2587
|
+
* @param body - Response body
|
|
2588
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3178
2589
|
*/
|
|
3179
2590
|
temporaryRedirect(body, generateEtag) {
|
|
3180
2591
|
this.status(ResponseStatus.TemporaryRedirect);
|
|
3181
2592
|
return this.send(body, generateEtag);
|
|
3182
2593
|
}
|
|
3183
2594
|
/**
|
|
3184
|
-
*
|
|
2595
|
+
* Sends a 400 Bad Request response
|
|
2596
|
+
*
|
|
2597
|
+
* @param body - Response body
|
|
2598
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3185
2599
|
*/
|
|
3186
2600
|
badRequest(body, generateEtag) {
|
|
3187
2601
|
this.status(ResponseStatus.BadRequest);
|
|
3188
2602
|
return this.send(body, generateEtag);
|
|
3189
2603
|
}
|
|
3190
2604
|
/**
|
|
3191
|
-
*
|
|
2605
|
+
* Sends a 401 Unauthorized response
|
|
2606
|
+
*
|
|
2607
|
+
* @param body - Response body
|
|
2608
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3192
2609
|
*/
|
|
3193
2610
|
unauthorized(body, generateEtag) {
|
|
3194
2611
|
this.status(ResponseStatus.Unauthorized);
|
|
3195
2612
|
return this.send(body, generateEtag);
|
|
3196
2613
|
}
|
|
3197
2614
|
/**
|
|
3198
|
-
*
|
|
2615
|
+
* Sends a 402 Payment Required response
|
|
2616
|
+
*
|
|
2617
|
+
* @param body - Response body
|
|
2618
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3199
2619
|
*/
|
|
3200
2620
|
paymentRequired(body, generateEtag) {
|
|
3201
2621
|
this.status(ResponseStatus.PaymentRequired);
|
|
3202
2622
|
return this.send(body, generateEtag);
|
|
3203
2623
|
}
|
|
3204
2624
|
/**
|
|
3205
|
-
*
|
|
2625
|
+
* Sends a 403 Forbidden response
|
|
2626
|
+
*
|
|
2627
|
+
* @param body - Response body
|
|
2628
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3206
2629
|
*/
|
|
3207
2630
|
forbidden(body, generateEtag) {
|
|
3208
2631
|
this.status(ResponseStatus.Forbidden);
|
|
3209
2632
|
return this.send(body, generateEtag);
|
|
3210
2633
|
}
|
|
3211
2634
|
/**
|
|
3212
|
-
*
|
|
2635
|
+
* Sends a 404 Not Found response
|
|
2636
|
+
*
|
|
2637
|
+
* @param body - Response body
|
|
2638
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3213
2639
|
*/
|
|
3214
2640
|
notFound(body, generateEtag) {
|
|
3215
2641
|
this.status(ResponseStatus.NotFound);
|
|
3216
2642
|
return this.send(body, generateEtag);
|
|
3217
2643
|
}
|
|
3218
2644
|
/**
|
|
3219
|
-
*
|
|
2645
|
+
* Sends a 405 Method Not Allowed response
|
|
2646
|
+
*
|
|
2647
|
+
* @param body - Response body
|
|
2648
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3220
2649
|
*/
|
|
3221
2650
|
methodNotAllowed(body, generateEtag) {
|
|
3222
2651
|
this.status(ResponseStatus.MethodNotAllowed);
|
|
3223
2652
|
return this.send(body, generateEtag);
|
|
3224
2653
|
}
|
|
3225
2654
|
/**
|
|
3226
|
-
*
|
|
2655
|
+
* Sends a 406 Not Acceptable response
|
|
2656
|
+
*
|
|
2657
|
+
* @param body - Response body
|
|
2658
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3227
2659
|
*/
|
|
3228
2660
|
notAcceptable(body, generateEtag) {
|
|
3229
2661
|
this.status(ResponseStatus.NotAcceptable);
|
|
3230
2662
|
return this.send(body, generateEtag);
|
|
3231
2663
|
}
|
|
3232
2664
|
/**
|
|
3233
|
-
*
|
|
2665
|
+
* Sends a 407 Proxy Authentication Required response
|
|
2666
|
+
*
|
|
2667
|
+
* @param body - Response body
|
|
2668
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3234
2669
|
*/
|
|
3235
2670
|
proxyAuthenticationRequired(body, generateEtag) {
|
|
3236
2671
|
this.status(ResponseStatus.ProxyAuthenticationRequired);
|
|
3237
2672
|
return this.send(body, generateEtag);
|
|
3238
2673
|
}
|
|
3239
2674
|
/**
|
|
3240
|
-
*
|
|
2675
|
+
* Sends a 408 Request Timeout response
|
|
2676
|
+
*
|
|
2677
|
+
* @param body - Response body
|
|
2678
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3241
2679
|
*/
|
|
3242
2680
|
requestTimeout(body, generateEtag) {
|
|
3243
2681
|
this.status(ResponseStatus.RequestTimeout);
|
|
3244
2682
|
return this.send(body, generateEtag);
|
|
3245
2683
|
}
|
|
3246
2684
|
/**
|
|
3247
|
-
*
|
|
2685
|
+
* Sends a 409 Conflict response
|
|
2686
|
+
*
|
|
2687
|
+
* @param body - Response body
|
|
2688
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3248
2689
|
*/
|
|
3249
2690
|
conflict(body, generateEtag) {
|
|
3250
2691
|
this.status(ResponseStatus.Conflict);
|
|
3251
2692
|
return this.send(body, generateEtag);
|
|
3252
2693
|
}
|
|
3253
2694
|
/**
|
|
3254
|
-
*
|
|
2695
|
+
* Sends a 410 Gone response
|
|
2696
|
+
*
|
|
2697
|
+
* @param body - Response body
|
|
2698
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3255
2699
|
*/
|
|
3256
2700
|
gone(body, generateEtag) {
|
|
3257
2701
|
this.status(ResponseStatus.Gone);
|
|
3258
2702
|
return this.send(body, generateEtag);
|
|
3259
2703
|
}
|
|
3260
2704
|
/**
|
|
3261
|
-
*
|
|
2705
|
+
* Sends a 411 Length Required response
|
|
2706
|
+
*
|
|
2707
|
+
* @param body - Response body
|
|
2708
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3262
2709
|
*/
|
|
3263
2710
|
lengthRequired(body, generateEtag) {
|
|
3264
2711
|
this.status(ResponseStatus.LengthRequired);
|
|
3265
2712
|
return this.send(body, generateEtag);
|
|
3266
2713
|
}
|
|
3267
2714
|
/**
|
|
3268
|
-
*
|
|
2715
|
+
* Sends a 412 Precondition Failed response
|
|
2716
|
+
*
|
|
2717
|
+
* @param body - Response body
|
|
2718
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3269
2719
|
*/
|
|
3270
2720
|
preconditionFailed(body, generateEtag) {
|
|
3271
2721
|
this.status(ResponseStatus.PreconditionFailed);
|
|
3272
2722
|
return this.send(body, generateEtag);
|
|
3273
2723
|
}
|
|
3274
2724
|
/**
|
|
3275
|
-
*
|
|
2725
|
+
* Sends a 413 Payload Too Large response
|
|
2726
|
+
*
|
|
2727
|
+
* @param body - Response body
|
|
2728
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3276
2729
|
*/
|
|
3277
2730
|
requestEntityTooLarge(body, generateEtag) {
|
|
3278
2731
|
this.status(ResponseStatus.PayloadTooLarge);
|
|
3279
2732
|
return this.send(body, generateEtag);
|
|
3280
2733
|
}
|
|
3281
2734
|
/**
|
|
3282
|
-
*
|
|
2735
|
+
* Sends a 414 URI Too Long response
|
|
2736
|
+
*
|
|
2737
|
+
* @param body - Response body
|
|
2738
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3283
2739
|
*/
|
|
3284
2740
|
requestUriTooLong(body, generateEtag) {
|
|
3285
2741
|
this.status(ResponseStatus.URITooLong);
|
|
3286
2742
|
return this.send(body, generateEtag);
|
|
3287
2743
|
}
|
|
3288
2744
|
/**
|
|
3289
|
-
*
|
|
2745
|
+
* Sends a 415 Unsupported Media Type response
|
|
2746
|
+
*
|
|
2747
|
+
* @param body - Response body
|
|
2748
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3290
2749
|
*/
|
|
3291
2750
|
unsupportedMediaType(body, generateEtag) {
|
|
3292
2751
|
this.status(ResponseStatus.UnsupportedMediaType);
|
|
3293
2752
|
return this.send(body, generateEtag);
|
|
3294
2753
|
}
|
|
3295
2754
|
/**
|
|
3296
|
-
*
|
|
2755
|
+
* Sends a 416 Range Not Satisfiable response
|
|
2756
|
+
*
|
|
2757
|
+
* @param body - Response body
|
|
2758
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3297
2759
|
*/
|
|
3298
2760
|
requestedRangeNotSatisfiable(body, generateEtag) {
|
|
3299
2761
|
this.status(ResponseStatus.RangeNotSatisfiable);
|
|
3300
2762
|
return this.send(body, generateEtag);
|
|
3301
2763
|
}
|
|
3302
2764
|
/**
|
|
3303
|
-
*
|
|
2765
|
+
* Sends a 417 Expectation Failed response
|
|
2766
|
+
*
|
|
2767
|
+
* @param body - Response body
|
|
2768
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3304
2769
|
*/
|
|
3305
2770
|
expectationFailed(body, generateEtag) {
|
|
3306
2771
|
this.status(ResponseStatus.ExpectationFailed);
|
|
3307
2772
|
return this.send(body, generateEtag);
|
|
3308
2773
|
}
|
|
3309
2774
|
/**
|
|
3310
|
-
*
|
|
2775
|
+
* Sends a 422 Unprocessable Entity response
|
|
2776
|
+
*
|
|
2777
|
+
* @param body - Response body
|
|
2778
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3311
2779
|
*/
|
|
3312
2780
|
unprocessableEntity(body, generateEtag) {
|
|
3313
2781
|
this.status(ResponseStatus.UnprocessableEntity);
|
|
3314
2782
|
return this.send(body, generateEtag);
|
|
3315
2783
|
}
|
|
3316
2784
|
/**
|
|
3317
|
-
*
|
|
2785
|
+
* Sends a 429 Too Many Requests response
|
|
2786
|
+
*
|
|
2787
|
+
* @param body - Response body
|
|
2788
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3318
2789
|
*/
|
|
3319
2790
|
tooManyRequests(body, generateEtag) {
|
|
3320
2791
|
this.status(ResponseStatus.TooManyRequests);
|
|
3321
2792
|
return this.send(body, generateEtag);
|
|
3322
2793
|
}
|
|
3323
2794
|
/**
|
|
3324
|
-
*
|
|
2795
|
+
* Sends a 500 Internal Server Error response
|
|
2796
|
+
*
|
|
2797
|
+
* @param body - Response body
|
|
2798
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3325
2799
|
*/
|
|
3326
2800
|
internalServerError(body, generateEtag) {
|
|
3327
2801
|
this.status(ResponseStatus.InternalServerError);
|
|
3328
2802
|
return this.send(body, generateEtag);
|
|
3329
2803
|
}
|
|
3330
2804
|
/**
|
|
3331
|
-
*
|
|
2805
|
+
* Sends a 501 Not Implemented response
|
|
2806
|
+
*
|
|
2807
|
+
* @param body - Response body
|
|
2808
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3332
2809
|
*/
|
|
3333
2810
|
notImplemented(body, generateEtag) {
|
|
3334
2811
|
this.status(ResponseStatus.NotImplemented);
|
|
3335
2812
|
return this.send(body, generateEtag);
|
|
3336
2813
|
}
|
|
3337
2814
|
/**
|
|
3338
|
-
*
|
|
2815
|
+
* Sends a 502 Bad Gateway response
|
|
2816
|
+
*
|
|
2817
|
+
* @param body - Response body
|
|
2818
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3339
2819
|
*/
|
|
3340
2820
|
badGateway(body, generateEtag) {
|
|
3341
2821
|
this.status(ResponseStatus.BadGateway);
|
|
3342
2822
|
return this.send(body, generateEtag);
|
|
3343
2823
|
}
|
|
3344
2824
|
/**
|
|
3345
|
-
*
|
|
2825
|
+
* Sends a 503 Service Unavailable response
|
|
2826
|
+
*
|
|
2827
|
+
* @param body - Response body
|
|
2828
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3346
2829
|
*/
|
|
3347
2830
|
serviceUnavailable(body, generateEtag) {
|
|
3348
2831
|
this.status(ResponseStatus.ServiceUnavailable);
|
|
3349
2832
|
return this.send(body, generateEtag);
|
|
3350
2833
|
}
|
|
3351
2834
|
/**
|
|
3352
|
-
*
|
|
2835
|
+
* Sends a 504 Gateway Timeout response
|
|
2836
|
+
*
|
|
2837
|
+
* @param body - Response body
|
|
2838
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3353
2839
|
*/
|
|
3354
2840
|
gatewayTimeout(body, generateEtag) {
|
|
3355
2841
|
this.status(ResponseStatus.GatewayTimeout);
|
|
3356
2842
|
return this.send(body, generateEtag);
|
|
3357
2843
|
}
|
|
3358
2844
|
/**
|
|
3359
|
-
*
|
|
2845
|
+
* Sends a 505 HTTP Version Not Supported response
|
|
2846
|
+
*
|
|
2847
|
+
* @param body - Response body
|
|
2848
|
+
* @param generateEtag - Whether to generate ETag header
|
|
3360
2849
|
*/
|
|
3361
2850
|
httpVersionNotSupported(body, generateEtag) {
|
|
3362
2851
|
this.status(ResponseStatus.HTTPVersionNotSupported);
|
|
@@ -3365,14 +2854,13 @@ var Response = class extends Macroable6 {
|
|
|
3365
2854
|
};
|
|
3366
2855
|
|
|
3367
2856
|
// src/router/main.ts
|
|
3368
|
-
import
|
|
3369
|
-
import
|
|
3370
|
-
import {
|
|
3371
|
-
import { RuntimeException as RuntimeException5 } from "@poppinss/utils/exception";
|
|
2857
|
+
import is2 from "@sindresorhus/is";
|
|
2858
|
+
import { moduleImporter as moduleImporter2 } from "@adonisjs/fold";
|
|
2859
|
+
import { RuntimeException as RuntimeException3 } from "@poppinss/utils/exception";
|
|
3372
2860
|
|
|
3373
2861
|
// src/router/store.ts
|
|
3374
2862
|
import matchit from "@poppinss/matchit";
|
|
3375
|
-
import { RuntimeException as
|
|
2863
|
+
import { RuntimeException as RuntimeException2 } from "@poppinss/utils/exception";
|
|
3376
2864
|
var RoutesStore = class {
|
|
3377
2865
|
/**
|
|
3378
2866
|
* A flag to know if routes for explicit domains
|
|
@@ -3411,7 +2899,7 @@ var RoutesStore = class {
|
|
|
3411
2899
|
for (let token of tokens) {
|
|
3412
2900
|
if ([1, 3].includes(token.type)) {
|
|
3413
2901
|
if (collectedParams.has(token.val)) {
|
|
3414
|
-
throw new
|
|
2902
|
+
throw new RuntimeException2(`Duplicate param "${token.val}" found in "${route.pattern}"`);
|
|
3415
2903
|
} else {
|
|
3416
2904
|
collectedParams.add(token.val);
|
|
3417
2905
|
}
|
|
@@ -3427,7 +2915,7 @@ var RoutesStore = class {
|
|
|
3427
2915
|
#registerRoute(domain, method, tokens, route) {
|
|
3428
2916
|
const methodRoutes = this.#getMethodNode(domain, method);
|
|
3429
2917
|
if (methodRoutes.routes[route.pattern]) {
|
|
3430
|
-
throw new
|
|
2918
|
+
throw new RuntimeException2(
|
|
3431
2919
|
`Duplicate route found. "${method}: ${route.pattern}" route already exists`
|
|
3432
2920
|
);
|
|
3433
2921
|
}
|
|
@@ -3452,6 +2940,8 @@ var RoutesStore = class {
|
|
|
3452
2940
|
* }
|
|
3453
2941
|
* })
|
|
3454
2942
|
* ```
|
|
2943
|
+
* @param route - The route to add to the store
|
|
2944
|
+
* @returns Current RoutesStore instance for method chaining
|
|
3455
2945
|
*/
|
|
3456
2946
|
add(route) {
|
|
3457
2947
|
if (route.domain !== "root") {
|
|
@@ -3472,144 +2962,44 @@ var RoutesStore = class {
|
|
|
3472
2962
|
* The domain parameter has to be a registered pattern and not the fully
|
|
3473
2963
|
* qualified runtime domain. You must call `matchDomain` first to fetch
|
|
3474
2964
|
* the pattern for qualified domain
|
|
2965
|
+
* @param url - The URL to match
|
|
2966
|
+
* @param method - HTTP method
|
|
2967
|
+
* @param shouldDecodeParam - Whether to decode parameters
|
|
2968
|
+
* @param domain - Optional domain tokens and hostname
|
|
2969
|
+
* @returns Matched route or null if no match found
|
|
3475
2970
|
*/
|
|
3476
2971
|
match(url, method, shouldDecodeParam, domain) {
|
|
3477
2972
|
const domainName = domain?.tokens[0]?.old || "root";
|
|
3478
2973
|
const matchedDomain = this.tree.domains[domainName];
|
|
3479
|
-
if (!matchedDomain) {
|
|
3480
|
-
return null;
|
|
3481
|
-
}
|
|
3482
|
-
const matchedMethod = this.tree.domains[domainName][method];
|
|
3483
|
-
if (!matchedMethod) {
|
|
3484
|
-
return null;
|
|
3485
|
-
}
|
|
3486
|
-
const matchedRoute = matchit.match(url, matchedMethod.tokens);
|
|
3487
|
-
if (!matchedRoute.length) {
|
|
3488
|
-
return null;
|
|
3489
|
-
}
|
|
3490
|
-
const route = matchedMethod.routes[matchedRoute[0].old];
|
|
3491
|
-
return {
|
|
3492
|
-
route,
|
|
3493
|
-
routeKey: matchedMethod.routeKeys[route.pattern],
|
|
3494
|
-
params: matchit.exec(url, matchedRoute, shouldDecodeParam),
|
|
3495
|
-
subdomains: domain?.hostname ? matchit.exec(domain.hostname, domain.tokens) : {}
|
|
3496
|
-
};
|
|
3497
|
-
}
|
|
3498
|
-
/**
|
|
3499
|
-
* Match hostname against registered domains.
|
|
3500
|
-
*/
|
|
3501
|
-
matchDomain(hostname) {
|
|
3502
|
-
if (!hostname || !this.usingDomains) {
|
|
3503
|
-
return [];
|
|
3504
|
-
}
|
|
3505
|
-
return matchit.match(hostname, this.tree.tokens);
|
|
3506
|
-
}
|
|
3507
|
-
};
|
|
3508
|
-
|
|
3509
|
-
// src/client/router.ts
|
|
3510
|
-
var RouterClient = class {
|
|
3511
|
-
/**
|
|
3512
|
-
* List of route references kept for lookup.
|
|
3513
|
-
*/
|
|
3514
|
-
routes;
|
|
3515
|
-
/**
|
|
3516
|
-
* The lookup strategies to follow when generating URL builder
|
|
3517
|
-
* types and client
|
|
3518
|
-
*/
|
|
3519
|
-
lookupStrategies = ["name", "pattern"];
|
|
3520
|
-
constructor(routes) {
|
|
3521
|
-
this.routes = routes ?? {};
|
|
3522
|
-
}
|
|
3523
|
-
/**
|
|
3524
|
-
* Register route JSON payload
|
|
3525
|
-
*/
|
|
3526
|
-
register(route) {
|
|
3527
|
-
this.routes[route.domain] = this.routes[route.domain] || [];
|
|
3528
|
-
this.routes[route.domain].push(route);
|
|
3529
|
-
}
|
|
3530
|
-
/**
|
|
3531
|
-
* Define the lookup strategies to follow when generating URL builder
|
|
3532
|
-
* types and client.
|
|
3533
|
-
*/
|
|
3534
|
-
updateLookupStrategies(strategies) {
|
|
3535
|
-
this.lookupStrategies = strategies;
|
|
3536
|
-
return this;
|
|
3537
|
-
}
|
|
3538
|
-
/**
|
|
3539
|
-
* Finds a route by its identifier. The identifier can be the
|
|
3540
|
-
* route name, controller.method name or the route pattern
|
|
3541
|
-
* itself.
|
|
3542
|
-
*
|
|
3543
|
-
* When "followLookupStrategy" is enabled, the lookup will be performed
|
|
3544
|
-
* on the basis of the lookup strategy enabled via the "lookupStrategies"
|
|
3545
|
-
* method. The default lookupStrategy is "name" and "pattern".
|
|
3546
|
-
*/
|
|
3547
|
-
find(routeIdentifier, domain, method, followLookupStrategy) {
|
|
3548
|
-
if (!domain) {
|
|
3549
|
-
let route = null;
|
|
3550
|
-
for (const routeDomain of Object.keys(this.routes)) {
|
|
3551
|
-
route = this.find(routeIdentifier, routeDomain, method, followLookupStrategy);
|
|
3552
|
-
if (route) {
|
|
3553
|
-
break;
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
return route;
|
|
3557
|
-
}
|
|
3558
|
-
const routes = this.routes[domain];
|
|
3559
|
-
if (!routes) {
|
|
3560
|
-
return null;
|
|
3561
|
-
}
|
|
3562
|
-
const lookupByName = !followLookupStrategy || this.lookupStrategies.includes("name");
|
|
3563
|
-
const lookupByPattern = !followLookupStrategy || this.lookupStrategies.includes("pattern");
|
|
3564
|
-
const lookupByController = !followLookupStrategy || this.lookupStrategies.includes("controller");
|
|
3565
|
-
return routes.find((route) => {
|
|
3566
|
-
if (method && !route.methods.includes(method)) {
|
|
3567
|
-
return false;
|
|
3568
|
-
}
|
|
3569
|
-
if (route.name === routeIdentifier && lookupByName || route.pattern === routeIdentifier && lookupByPattern) {
|
|
3570
|
-
return true;
|
|
3571
|
-
}
|
|
3572
|
-
if (typeof route.handler === "function" || !lookupByController) {
|
|
3573
|
-
return false;
|
|
3574
|
-
}
|
|
3575
|
-
return route.handler.reference === routeIdentifier;
|
|
3576
|
-
}) || null;
|
|
3577
|
-
}
|
|
3578
|
-
/**
|
|
3579
|
-
* Finds a route by its identifier. The identifier can be the
|
|
3580
|
-
* route name, controller.method name or the route pattern
|
|
3581
|
-
* itself.
|
|
3582
|
-
*
|
|
3583
|
-
* An error is raised when unable to find the route.
|
|
3584
|
-
*
|
|
3585
|
-
* When "followLookupStrategy" is enabled, the lookup will be performed
|
|
3586
|
-
* on the basis of the lookup strategy enabled via the "lookupStrategies"
|
|
3587
|
-
* method. The default lookupStrategy is "name" and "pattern".
|
|
3588
|
-
*/
|
|
3589
|
-
findOrFail(routeIdentifier, domain, method, followLookupStrategy) {
|
|
3590
|
-
const route = this.find(routeIdentifier, domain, method, followLookupStrategy);
|
|
3591
|
-
if (!route) {
|
|
3592
|
-
throw new Error(`Cannot lookup route "${routeIdentifier}"`);
|
|
3593
|
-
}
|
|
3594
|
-
return route;
|
|
3595
|
-
}
|
|
3596
|
-
/**
|
|
3597
|
-
* Check if a route exists. The identifier can be the
|
|
3598
|
-
* route name, controller.method name or the route pattern
|
|
3599
|
-
* itself.
|
|
3600
|
-
*
|
|
3601
|
-
* When "followLookupStrategy" is enabled, the lookup will be performed
|
|
3602
|
-
* on the basis of the lookup strategy enabled via the "lookupStrategies"
|
|
3603
|
-
* method. The default lookupStrategy is "name" and "pattern".
|
|
3604
|
-
*/
|
|
3605
|
-
has(routeIdentifier, domain, method, followLookupStrategy) {
|
|
3606
|
-
return !!this.find(routeIdentifier, domain, method, followLookupStrategy);
|
|
2974
|
+
if (!matchedDomain) {
|
|
2975
|
+
return null;
|
|
2976
|
+
}
|
|
2977
|
+
const matchedMethod = this.tree.domains[domainName][method];
|
|
2978
|
+
if (!matchedMethod) {
|
|
2979
|
+
return null;
|
|
2980
|
+
}
|
|
2981
|
+
const matchedRoute = matchit.match(url, matchedMethod.tokens);
|
|
2982
|
+
if (!matchedRoute.length) {
|
|
2983
|
+
return null;
|
|
2984
|
+
}
|
|
2985
|
+
const route = matchedMethod.routes[matchedRoute[0].old];
|
|
2986
|
+
return {
|
|
2987
|
+
route,
|
|
2988
|
+
routeKey: matchedMethod.routeKeys[route.pattern],
|
|
2989
|
+
params: matchit.exec(url, matchedRoute, shouldDecodeParam),
|
|
2990
|
+
subdomains: domain?.hostname ? matchit.exec(domain.hostname, domain.tokens) : {}
|
|
2991
|
+
};
|
|
3607
2992
|
}
|
|
3608
2993
|
/**
|
|
3609
|
-
*
|
|
2994
|
+
* Match hostname against registered domains.
|
|
2995
|
+
* @param hostname - The hostname to match
|
|
2996
|
+
* @returns Array of matched domain tokens
|
|
3610
2997
|
*/
|
|
3611
|
-
|
|
3612
|
-
|
|
2998
|
+
matchDomain(hostname) {
|
|
2999
|
+
if (!hostname || !this.usingDomains) {
|
|
3000
|
+
return [];
|
|
3001
|
+
}
|
|
3002
|
+
return matchit.match(hostname, this.tree.tokens);
|
|
3613
3003
|
}
|
|
3614
3004
|
};
|
|
3615
3005
|
|
|
@@ -3636,15 +3026,22 @@ var UrlBuilder = class {
|
|
|
3636
3026
|
* Route finder for finding route pattern
|
|
3637
3027
|
*/
|
|
3638
3028
|
#router;
|
|
3029
|
+
/**
|
|
3030
|
+
* Domain to use for URL generation
|
|
3031
|
+
*/
|
|
3639
3032
|
#domain;
|
|
3033
|
+
/**
|
|
3034
|
+
* Creates a new UrlBuilder instance
|
|
3035
|
+
* @param router - The router instance
|
|
3036
|
+
* @param domain - Optional domain for URL generation
|
|
3037
|
+
*/
|
|
3640
3038
|
constructor(router, domain) {
|
|
3641
3039
|
this.#router = router;
|
|
3642
3040
|
this.#domain = domain;
|
|
3643
3041
|
}
|
|
3644
3042
|
/**
|
|
3645
3043
|
* Prefix a custom base URL to the final URI
|
|
3646
|
-
* @deprecated
|
|
3647
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3044
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3648
3045
|
*/
|
|
3649
3046
|
prefixUrl(url) {
|
|
3650
3047
|
this.#baseUrl = url;
|
|
@@ -3653,8 +3050,7 @@ var UrlBuilder = class {
|
|
|
3653
3050
|
/**
|
|
3654
3051
|
* Disable route lookup. Calling this method considers
|
|
3655
3052
|
* the "identifier" as the route pattern
|
|
3656
|
-
* @deprecated
|
|
3657
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3053
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3658
3054
|
*/
|
|
3659
3055
|
disableRouteLookup() {
|
|
3660
3056
|
this.#shouldPerformLookup = false;
|
|
@@ -3662,8 +3058,7 @@ var UrlBuilder = class {
|
|
|
3662
3058
|
}
|
|
3663
3059
|
/**
|
|
3664
3060
|
* Append query string to the final URI
|
|
3665
|
-
* @deprecated
|
|
3666
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3061
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3667
3062
|
*/
|
|
3668
3063
|
qs(queryString) {
|
|
3669
3064
|
if (!queryString) {
|
|
@@ -3674,8 +3069,7 @@ var UrlBuilder = class {
|
|
|
3674
3069
|
}
|
|
3675
3070
|
/**
|
|
3676
3071
|
* Specify params to apply to the route pattern
|
|
3677
|
-
* @deprecated
|
|
3678
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3072
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3679
3073
|
*/
|
|
3680
3074
|
params(params) {
|
|
3681
3075
|
if (!params) {
|
|
@@ -3689,8 +3083,9 @@ var UrlBuilder = class {
|
|
|
3689
3083
|
* route name, controller.method name or the route pattern
|
|
3690
3084
|
* itself.
|
|
3691
3085
|
*
|
|
3692
|
-
* @deprecated
|
|
3693
|
-
*
|
|
3086
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3087
|
+
* @param identifier - Route identifier to generate URL for
|
|
3088
|
+
* @returns Generated URL string
|
|
3694
3089
|
*/
|
|
3695
3090
|
make(identifier) {
|
|
3696
3091
|
return this.#router.makeUrl(identifier, this.#params, {
|
|
@@ -3705,8 +3100,7 @@ var UrlBuilder = class {
|
|
|
3705
3100
|
* route name, controller.method name or the route pattern
|
|
3706
3101
|
* itself.
|
|
3707
3102
|
*
|
|
3708
|
-
* @deprecated
|
|
3709
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3103
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3710
3104
|
*
|
|
3711
3105
|
*/
|
|
3712
3106
|
makeSigned(identifier, options) {
|
|
@@ -3721,17 +3115,19 @@ var UrlBuilder = class {
|
|
|
3721
3115
|
};
|
|
3722
3116
|
|
|
3723
3117
|
// src/router/matchers.ts
|
|
3724
|
-
import
|
|
3725
|
-
var RouteMatchers = class extends
|
|
3118
|
+
import Macroable3 from "@poppinss/macroable";
|
|
3119
|
+
var RouteMatchers = class extends Macroable3 {
|
|
3726
3120
|
/**
|
|
3727
3121
|
* Enforce value to be a number and also casts it to number data
|
|
3728
3122
|
* type
|
|
3123
|
+
* @returns Route matcher configuration for numeric values
|
|
3729
3124
|
*/
|
|
3730
3125
|
number() {
|
|
3731
3126
|
return { match: /^[0-9]+$/, cast: (value) => Number(value) };
|
|
3732
3127
|
}
|
|
3733
3128
|
/**
|
|
3734
3129
|
* Enforce value to be formatted as uuid
|
|
3130
|
+
* @returns Route matcher configuration for UUID values
|
|
3735
3131
|
*/
|
|
3736
3132
|
uuid() {
|
|
3737
3133
|
return {
|
|
@@ -3741,6 +3137,7 @@ var RouteMatchers = class extends Macroable7 {
|
|
|
3741
3137
|
}
|
|
3742
3138
|
/**
|
|
3743
3139
|
* Enforce value to be formatted as slug
|
|
3140
|
+
* @returns Route matcher configuration for slug values
|
|
3744
3141
|
*/
|
|
3745
3142
|
slug() {
|
|
3746
3143
|
return { match: /^[^\s-_](?!.*?[-_]{2,})([a-z0-9-\\]{1,})[^\s]*[^-_\s]$/ };
|
|
@@ -3748,9 +3145,9 @@ var RouteMatchers = class extends Macroable7 {
|
|
|
3748
3145
|
};
|
|
3749
3146
|
|
|
3750
3147
|
// src/define_middleware.ts
|
|
3751
|
-
import { moduleImporter
|
|
3148
|
+
import { moduleImporter } from "@adonisjs/fold";
|
|
3752
3149
|
function middlewareReferenceBuilder(name, middleware) {
|
|
3753
|
-
const handler =
|
|
3150
|
+
const handler = moduleImporter(middleware, "handle").toHandleMethod();
|
|
3754
3151
|
return function(...args) {
|
|
3755
3152
|
return {
|
|
3756
3153
|
...handler,
|
|
@@ -3770,142 +3167,7 @@ function defineNamedMiddleware(collection) {
|
|
|
3770
3167
|
);
|
|
3771
3168
|
}
|
|
3772
3169
|
|
|
3773
|
-
// src/client/url_builder.ts
|
|
3774
|
-
function createURL(identifier, tokens, searchParamsStringifier, params, options) {
|
|
3775
|
-
const uriSegments = [];
|
|
3776
|
-
const paramsArray = Array.isArray(params) ? params : null;
|
|
3777
|
-
const paramsObject = !Array.isArray(params) ? params ?? {} : {};
|
|
3778
|
-
let paramsIndex = 0;
|
|
3779
|
-
for (const token of tokens) {
|
|
3780
|
-
if (token.type === 0) {
|
|
3781
|
-
uriSegments.push(token.val === "/" ? "" : `${token.val}${token.end}`);
|
|
3782
|
-
continue;
|
|
3783
|
-
}
|
|
3784
|
-
if (token.type === 2) {
|
|
3785
|
-
const values = paramsArray ? paramsArray.slice(paramsIndex) : paramsObject["*"];
|
|
3786
|
-
if (!Array.isArray(values) || !values.length) {
|
|
3787
|
-
throw new Error(
|
|
3788
|
-
`Cannot make URL for "${identifier}". Invalid value provided for the wildcard param`
|
|
3789
|
-
);
|
|
3790
|
-
}
|
|
3791
|
-
uriSegments.push(`${values.join("/")}${token.end}`);
|
|
3792
|
-
break;
|
|
3793
|
-
}
|
|
3794
|
-
const paramName = token.val;
|
|
3795
|
-
const value = paramsArray ? paramsArray[paramsIndex] : paramsObject[paramName];
|
|
3796
|
-
const isDefined = value !== void 0 && value !== null;
|
|
3797
|
-
if (token.type === 1 && !isDefined) {
|
|
3798
|
-
throw new Error(
|
|
3799
|
-
`Cannot make URL for "${identifier}". Missing value for the "${paramName}" param`
|
|
3800
|
-
);
|
|
3801
|
-
}
|
|
3802
|
-
if (isDefined) {
|
|
3803
|
-
uriSegments.push(`${value}${token.end}`);
|
|
3804
|
-
}
|
|
3805
|
-
paramsIndex++;
|
|
3806
|
-
}
|
|
3807
|
-
let URI = `/${uriSegments.join("/")}`;
|
|
3808
|
-
if (options?.prefixUrl) {
|
|
3809
|
-
URI = `${options?.prefixUrl.replace(/\/$/, "")}${URI}`;
|
|
3810
|
-
}
|
|
3811
|
-
if (options?.qs) {
|
|
3812
|
-
const queryString = searchParamsStringifier(options?.qs);
|
|
3813
|
-
URI = queryString ? `${URI}?${queryString}` : URI;
|
|
3814
|
-
}
|
|
3815
|
-
return URI;
|
|
3816
|
-
}
|
|
3817
|
-
function createUrlBuilder(router, searchParamsStringifier) {
|
|
3818
|
-
let domainsList;
|
|
3819
|
-
function createUrlForRoute(identifier, params, options, method) {
|
|
3820
|
-
if (!domainsList) {
|
|
3821
|
-
domainsList = Object.keys(router.toJSON()).filter((domain2) => domain2 !== "root");
|
|
3822
|
-
}
|
|
3823
|
-
const domain = domainsList.find((name) => identifier.startsWith(`${name}@`));
|
|
3824
|
-
const routeIdentifier = domain ? identifier.replace(new RegExp(`^${domain}@`), "") : identifier;
|
|
3825
|
-
const route = router.findOrFail(routeIdentifier, domain, method, true);
|
|
3826
|
-
return createURL(
|
|
3827
|
-
route.name ?? route.pattern,
|
|
3828
|
-
route.tokens,
|
|
3829
|
-
searchParamsStringifier,
|
|
3830
|
-
params,
|
|
3831
|
-
options
|
|
3832
|
-
);
|
|
3833
|
-
}
|
|
3834
|
-
const urlFor = function route(...[identifier, params, options]) {
|
|
3835
|
-
return createUrlForRoute(identifier, params, options);
|
|
3836
|
-
};
|
|
3837
|
-
urlFor.get = function urlForMethodGet(...[identifier, params, options]) {
|
|
3838
|
-
return {
|
|
3839
|
-
url: createUrlForRoute(identifier, params, options, "GET"),
|
|
3840
|
-
method: "get",
|
|
3841
|
-
toString() {
|
|
3842
|
-
return this.url;
|
|
3843
|
-
}
|
|
3844
|
-
};
|
|
3845
|
-
};
|
|
3846
|
-
urlFor.post = function urlForMethodPost(...[identifier, params, options]) {
|
|
3847
|
-
return {
|
|
3848
|
-
url: createUrlForRoute(identifier, params, options, "POST"),
|
|
3849
|
-
method: "post",
|
|
3850
|
-
toString() {
|
|
3851
|
-
return this.url;
|
|
3852
|
-
}
|
|
3853
|
-
};
|
|
3854
|
-
};
|
|
3855
|
-
urlFor.put = function urlForMethodPut(...[identifier, params, options]) {
|
|
3856
|
-
return {
|
|
3857
|
-
url: createUrlForRoute(identifier, params, options, "PUT"),
|
|
3858
|
-
method: "put",
|
|
3859
|
-
toString() {
|
|
3860
|
-
return this.url;
|
|
3861
|
-
}
|
|
3862
|
-
};
|
|
3863
|
-
};
|
|
3864
|
-
urlFor.patch = function urlForMethodPatch(...[identifier, params, options]) {
|
|
3865
|
-
return {
|
|
3866
|
-
url: createUrlForRoute(identifier, params, options, "PATCH"),
|
|
3867
|
-
method: "patch",
|
|
3868
|
-
toString() {
|
|
3869
|
-
return this.url;
|
|
3870
|
-
}
|
|
3871
|
-
};
|
|
3872
|
-
};
|
|
3873
|
-
urlFor.delete = function urlForMethodDelete(...[identifier, params, options]) {
|
|
3874
|
-
return {
|
|
3875
|
-
url: createUrlForRoute(identifier, params, options, "DELETE"),
|
|
3876
|
-
method: "delete",
|
|
3877
|
-
toString() {
|
|
3878
|
-
return this.url;
|
|
3879
|
-
}
|
|
3880
|
-
};
|
|
3881
|
-
};
|
|
3882
|
-
urlFor.method = function urlForCustomMethod(method, ...[identifier, params, options]) {
|
|
3883
|
-
return {
|
|
3884
|
-
url: createUrlForRoute(identifier, params, options, method),
|
|
3885
|
-
method,
|
|
3886
|
-
toString() {
|
|
3887
|
-
return this.url;
|
|
3888
|
-
}
|
|
3889
|
-
};
|
|
3890
|
-
};
|
|
3891
|
-
return urlFor;
|
|
3892
|
-
}
|
|
3893
|
-
|
|
3894
3170
|
// src/router/signed_url_builder.ts
|
|
3895
|
-
function createSignedURL(identifier, tokens, searchParamsStringifier, encryption, params, options) {
|
|
3896
|
-
const signature = encryption.verifier.sign(
|
|
3897
|
-
createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
3898
|
-
...options,
|
|
3899
|
-
prefixUrl: void 0
|
|
3900
|
-
}),
|
|
3901
|
-
options?.expiresIn,
|
|
3902
|
-
options?.purpose
|
|
3903
|
-
);
|
|
3904
|
-
return createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
3905
|
-
...options,
|
|
3906
|
-
qs: { ...options?.qs, signature }
|
|
3907
|
-
});
|
|
3908
|
-
}
|
|
3909
3171
|
function createSignedUrlBuilder(router, encryption, searchParamsStringifier) {
|
|
3910
3172
|
let domainsList;
|
|
3911
3173
|
function createSignedUrlForRoute(identifier, params, options, method) {
|
|
@@ -3928,56 +3190,91 @@ function createSignedUrlBuilder(router, encryption, searchParamsStringifier) {
|
|
|
3928
3190
|
return createSignedUrlForRoute(identifier, params, options);
|
|
3929
3191
|
};
|
|
3930
3192
|
signedRoute.get = function routeGet(...[identifier, params, options]) {
|
|
3193
|
+
const method = "GET";
|
|
3194
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3931
3195
|
return {
|
|
3932
|
-
url
|
|
3933
|
-
method
|
|
3196
|
+
url,
|
|
3197
|
+
method,
|
|
3934
3198
|
toString() {
|
|
3935
|
-
return
|
|
3199
|
+
return url;
|
|
3200
|
+
},
|
|
3201
|
+
form: {
|
|
3202
|
+
action: url,
|
|
3203
|
+
method
|
|
3936
3204
|
}
|
|
3937
3205
|
};
|
|
3938
3206
|
};
|
|
3939
3207
|
signedRoute.post = function routePost(...[identifier, params, options]) {
|
|
3208
|
+
const method = "POST";
|
|
3209
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3940
3210
|
return {
|
|
3941
|
-
url
|
|
3942
|
-
method
|
|
3211
|
+
url,
|
|
3212
|
+
method,
|
|
3943
3213
|
toString() {
|
|
3944
|
-
return
|
|
3214
|
+
return url;
|
|
3215
|
+
},
|
|
3216
|
+
form: {
|
|
3217
|
+
action: url,
|
|
3218
|
+
method
|
|
3945
3219
|
}
|
|
3946
3220
|
};
|
|
3947
3221
|
};
|
|
3948
3222
|
signedRoute.put = function routePut(...[identifier, params, options]) {
|
|
3223
|
+
const method = "PUT";
|
|
3224
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3949
3225
|
return {
|
|
3950
|
-
url
|
|
3951
|
-
method
|
|
3226
|
+
url,
|
|
3227
|
+
method,
|
|
3952
3228
|
toString() {
|
|
3953
|
-
return
|
|
3229
|
+
return url;
|
|
3230
|
+
},
|
|
3231
|
+
form: {
|
|
3232
|
+
action: url,
|
|
3233
|
+
method
|
|
3954
3234
|
}
|
|
3955
3235
|
};
|
|
3956
3236
|
};
|
|
3957
3237
|
signedRoute.patch = function routePatch(...[identifier, params, options]) {
|
|
3238
|
+
const method = "PATCH";
|
|
3239
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3958
3240
|
return {
|
|
3959
|
-
url
|
|
3960
|
-
method
|
|
3241
|
+
url,
|
|
3242
|
+
method,
|
|
3961
3243
|
toString() {
|
|
3962
|
-
return
|
|
3244
|
+
return url;
|
|
3245
|
+
},
|
|
3246
|
+
form: {
|
|
3247
|
+
action: url,
|
|
3248
|
+
method
|
|
3963
3249
|
}
|
|
3964
3250
|
};
|
|
3965
3251
|
};
|
|
3966
3252
|
signedRoute.delete = function routeDelete(...[identifier, params, options]) {
|
|
3253
|
+
const method = "DELETE";
|
|
3254
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3967
3255
|
return {
|
|
3968
|
-
url
|
|
3969
|
-
method
|
|
3256
|
+
url,
|
|
3257
|
+
method,
|
|
3970
3258
|
toString() {
|
|
3971
|
-
return
|
|
3259
|
+
return url;
|
|
3260
|
+
},
|
|
3261
|
+
form: {
|
|
3262
|
+
action: url,
|
|
3263
|
+
method
|
|
3972
3264
|
}
|
|
3973
3265
|
};
|
|
3974
3266
|
};
|
|
3975
3267
|
signedRoute.method = function routeGet(method, ...[identifier, params, options]) {
|
|
3268
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3976
3269
|
return {
|
|
3977
|
-
url
|
|
3270
|
+
url,
|
|
3978
3271
|
method,
|
|
3979
3272
|
toString() {
|
|
3980
|
-
return
|
|
3273
|
+
return url;
|
|
3274
|
+
},
|
|
3275
|
+
form: {
|
|
3276
|
+
action: url,
|
|
3277
|
+
method
|
|
3981
3278
|
}
|
|
3982
3279
|
};
|
|
3983
3280
|
};
|
|
@@ -3985,7 +3282,7 @@ function createSignedUrlBuilder(router, encryption, searchParamsStringifier) {
|
|
|
3985
3282
|
}
|
|
3986
3283
|
|
|
3987
3284
|
// src/router/main.ts
|
|
3988
|
-
var Router = class
|
|
3285
|
+
var Router = class {
|
|
3989
3286
|
/**
|
|
3990
3287
|
* Flag to avoid re-comitting routes to the store
|
|
3991
3288
|
*/
|
|
@@ -4049,16 +3346,32 @@ var Router = class extends RouterClient {
|
|
|
4049
3346
|
* methods.
|
|
4050
3347
|
*/
|
|
4051
3348
|
urlBuilder;
|
|
3349
|
+
/**
|
|
3350
|
+
* List of route references kept for lookup.
|
|
3351
|
+
*/
|
|
3352
|
+
routes = {};
|
|
3353
|
+
/**
|
|
3354
|
+
* Creates a new Router instance
|
|
3355
|
+
* @param app - The AdonisJS application instance
|
|
3356
|
+
* @param encryption - Encryption service for signed URLs
|
|
3357
|
+
* @param qsParser - Query string parser for URL generation
|
|
3358
|
+
*/
|
|
4052
3359
|
constructor(app, encryption, qsParser) {
|
|
4053
|
-
super();
|
|
4054
3360
|
this.#app = app;
|
|
4055
3361
|
this.#encryption = encryption;
|
|
4056
3362
|
this.qs = qsParser;
|
|
4057
3363
|
this.urlBuilder = {
|
|
4058
|
-
urlFor: createUrlBuilder(this, this.qs.stringify),
|
|
3364
|
+
urlFor: createUrlBuilder(() => this.toJSON(), this.qs.stringify),
|
|
4059
3365
|
signedUrlFor: createSignedUrlBuilder(this, this.#encryption, this.qs.stringify)
|
|
4060
3366
|
};
|
|
4061
3367
|
}
|
|
3368
|
+
/**
|
|
3369
|
+
* Register route JSON payload
|
|
3370
|
+
*/
|
|
3371
|
+
register(route) {
|
|
3372
|
+
this.routes[route.domain] = this.routes[route.domain] || [];
|
|
3373
|
+
this.routes[route.domain].push(route);
|
|
3374
|
+
}
|
|
4062
3375
|
/**
|
|
4063
3376
|
* Push a give router entity to the list of routes or the
|
|
4064
3377
|
* recently opened group.
|
|
@@ -4073,6 +3386,8 @@ var Router = class extends RouterClient {
|
|
|
4073
3386
|
}
|
|
4074
3387
|
/**
|
|
4075
3388
|
* Parses the route pattern
|
|
3389
|
+
* @param pattern - The route pattern to parse
|
|
3390
|
+
* @param matchers - Optional route matchers
|
|
4076
3391
|
*/
|
|
4077
3392
|
parsePattern(pattern, matchers) {
|
|
4078
3393
|
return parseRoute(pattern, matchers);
|
|
@@ -4081,12 +3396,14 @@ var Router = class extends RouterClient {
|
|
|
4081
3396
|
* Define an array of middleware to use on all the routes.
|
|
4082
3397
|
* Calling this method multiple times pushes to the
|
|
4083
3398
|
* existing list of middleware
|
|
3399
|
+
* @param middleware - Array of middleware classes to apply globally
|
|
3400
|
+
* @returns Current Router instance for method chaining
|
|
4084
3401
|
*/
|
|
4085
3402
|
use(middleware) {
|
|
4086
3403
|
middleware.forEach(
|
|
4087
3404
|
(one) => this.#middleware.push({
|
|
4088
3405
|
reference: one,
|
|
4089
|
-
...
|
|
3406
|
+
...moduleImporter2(one, "handle").toHandleMethod()
|
|
4090
3407
|
})
|
|
4091
3408
|
);
|
|
4092
3409
|
return this;
|
|
@@ -4095,12 +3412,18 @@ var Router = class extends RouterClient {
|
|
|
4095
3412
|
* Define a collection of named middleware. The defined collection is
|
|
4096
3413
|
* not registered anywhere, but instead converted in a new collection
|
|
4097
3414
|
* of functions you can apply on the routes, or router groups.
|
|
3415
|
+
* @param collection - Object mapping middleware names to middleware classes
|
|
3416
|
+
* @returns Named middleware functions
|
|
4098
3417
|
*/
|
|
4099
3418
|
named(collection) {
|
|
4100
3419
|
return defineNamedMiddleware(collection);
|
|
4101
3420
|
}
|
|
4102
3421
|
/**
|
|
4103
3422
|
* Add route for a given pattern and methods
|
|
3423
|
+
* @param pattern - The route pattern
|
|
3424
|
+
* @param methods - Array of HTTP methods
|
|
3425
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3426
|
+
* @returns The created route instance
|
|
4104
3427
|
*/
|
|
4105
3428
|
route(pattern, methods, handler) {
|
|
4106
3429
|
const route = new Route(this.#app, this.#middleware, {
|
|
@@ -4114,6 +3437,9 @@ var Router = class extends RouterClient {
|
|
|
4114
3437
|
}
|
|
4115
3438
|
/**
|
|
4116
3439
|
* Define a route that handles all common HTTP methods
|
|
3440
|
+
* @param pattern - The route pattern
|
|
3441
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3442
|
+
* @returns The created route instance
|
|
4117
3443
|
*/
|
|
4118
3444
|
any(pattern, handler) {
|
|
4119
3445
|
return this.route(
|
|
@@ -4124,30 +3450,45 @@ var Router = class extends RouterClient {
|
|
|
4124
3450
|
}
|
|
4125
3451
|
/**
|
|
4126
3452
|
* Define `GET` route
|
|
3453
|
+
* @param pattern - The route pattern
|
|
3454
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3455
|
+
* @returns The created route instance
|
|
4127
3456
|
*/
|
|
4128
3457
|
get(pattern, handler) {
|
|
4129
3458
|
return this.route(pattern, ["GET", "HEAD"], handler);
|
|
4130
3459
|
}
|
|
4131
3460
|
/**
|
|
4132
3461
|
* Define `POST` route
|
|
3462
|
+
* @param pattern - The route pattern
|
|
3463
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3464
|
+
* @returns The created route instance
|
|
4133
3465
|
*/
|
|
4134
3466
|
post(pattern, handler) {
|
|
4135
3467
|
return this.route(pattern, ["POST"], handler);
|
|
4136
3468
|
}
|
|
4137
3469
|
/**
|
|
4138
3470
|
* Define `PUT` route
|
|
3471
|
+
* @param pattern - The route pattern
|
|
3472
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3473
|
+
* @returns The created route instance
|
|
4139
3474
|
*/
|
|
4140
3475
|
put(pattern, handler) {
|
|
4141
3476
|
return this.route(pattern, ["PUT"], handler);
|
|
4142
3477
|
}
|
|
4143
3478
|
/**
|
|
4144
3479
|
* Define `PATCH` route
|
|
3480
|
+
* @param pattern - The route pattern
|
|
3481
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3482
|
+
* @returns The created route instance
|
|
4145
3483
|
*/
|
|
4146
3484
|
patch(pattern, handler) {
|
|
4147
3485
|
return this.route(pattern, ["PATCH"], handler);
|
|
4148
3486
|
}
|
|
4149
3487
|
/**
|
|
4150
3488
|
* Define `DELETE` route
|
|
3489
|
+
* @param pattern - The route pattern
|
|
3490
|
+
* @param handler - Route handler (function, string, or controller tuple)
|
|
3491
|
+
* @returns The created route instance
|
|
4151
3492
|
*/
|
|
4152
3493
|
delete(pattern, handler) {
|
|
4153
3494
|
return this.route(pattern, ["DELETE"], handler);
|
|
@@ -4155,6 +3496,8 @@ var Router = class extends RouterClient {
|
|
|
4155
3496
|
/**
|
|
4156
3497
|
* Creates a group of routes. A route group can apply transforms
|
|
4157
3498
|
* to routes in bulk
|
|
3499
|
+
* @param callback - Function that defines routes within the group
|
|
3500
|
+
* @returns The created route group instance
|
|
4158
3501
|
*/
|
|
4159
3502
|
group(callback) {
|
|
4160
3503
|
const group = new RouteGroup([]);
|
|
@@ -4166,6 +3509,9 @@ var Router = class extends RouterClient {
|
|
|
4166
3509
|
}
|
|
4167
3510
|
/**
|
|
4168
3511
|
* Registers a route resource with conventional set of routes
|
|
3512
|
+
* @param resource - The resource name
|
|
3513
|
+
* @param controller - Controller to handle the resource
|
|
3514
|
+
* @returns The created route resource instance
|
|
4169
3515
|
*/
|
|
4170
3516
|
resource(resource, controller) {
|
|
4171
3517
|
const resourceInstance = new RouteResource(this.#app, this.#middleware, {
|
|
@@ -4179,6 +3525,9 @@ var Router = class extends RouterClient {
|
|
|
4179
3525
|
}
|
|
4180
3526
|
/**
|
|
4181
3527
|
* Register a route resource with shallow nested routes.
|
|
3528
|
+
* @param resource - The resource name
|
|
3529
|
+
* @param controller - Controller to handle the resource
|
|
3530
|
+
* @returns The created route resource instance
|
|
4182
3531
|
*/
|
|
4183
3532
|
shallowResource(resource, controller) {
|
|
4184
3533
|
const resourceInstance = new RouteResource(this.#app, this.#middleware, {
|
|
@@ -4192,6 +3541,8 @@ var Router = class extends RouterClient {
|
|
|
4192
3541
|
}
|
|
4193
3542
|
/**
|
|
4194
3543
|
* Returns a brisk route instance for a given URL pattern
|
|
3544
|
+
* @param pattern - The route pattern
|
|
3545
|
+
* @returns The created brisk route instance
|
|
4195
3546
|
*/
|
|
4196
3547
|
on(pattern) {
|
|
4197
3548
|
const briskRoute = new BriskRoute(this.#app, this.#middleware, {
|
|
@@ -4204,11 +3555,14 @@ var Router = class extends RouterClient {
|
|
|
4204
3555
|
/**
|
|
4205
3556
|
* Define matcher for a given param. The global params are applied
|
|
4206
3557
|
* on all the routes (unless overridden at the route level).
|
|
3558
|
+
* @param param - The parameter name to match
|
|
3559
|
+
* @param matcher - The matcher pattern (RegExp, string, or RouteMatcher)
|
|
3560
|
+
* @returns Current Router instance for method chaining
|
|
4207
3561
|
*/
|
|
4208
3562
|
where(param, matcher) {
|
|
4209
3563
|
if (typeof matcher === "string") {
|
|
4210
3564
|
this.#globalMatchers[param] = { match: new RegExp(matcher) };
|
|
4211
|
-
} else if (
|
|
3565
|
+
} else if (is2.regExp(matcher)) {
|
|
4212
3566
|
this.#globalMatchers[param] = { match: matcher };
|
|
4213
3567
|
} else {
|
|
4214
3568
|
this.#globalMatchers[param] = matcher;
|
|
@@ -4231,8 +3585,8 @@ var Router = class extends RouterClient {
|
|
|
4231
3585
|
}
|
|
4232
3586
|
const routeNames = routeNamesByDomain.get(route.domain);
|
|
4233
3587
|
if (route.name && routeNames.has(route.name)) {
|
|
4234
|
-
throw new
|
|
4235
|
-
`
|
|
3588
|
+
throw new RuntimeException3(
|
|
3589
|
+
`A route with name "${route.name}" already exists. It may happen when two routes use the same controller, so make sure to give explicit names to these routes`
|
|
4236
3590
|
);
|
|
4237
3591
|
}
|
|
4238
3592
|
if (route.name) {
|
|
@@ -4249,10 +3603,75 @@ var Router = class extends RouterClient {
|
|
|
4249
3603
|
this.#openedGroups = [];
|
|
4250
3604
|
this.#commited = true;
|
|
4251
3605
|
}
|
|
3606
|
+
/**
|
|
3607
|
+
* Finds a route by its identifier. The identifier can be the
|
|
3608
|
+
* route name, controller.method name or the route pattern
|
|
3609
|
+
* itself.
|
|
3610
|
+
*
|
|
3611
|
+
* When "disableLegacyLookup" is set, the lookup will be performed
|
|
3612
|
+
* only using the route name
|
|
3613
|
+
* @param routeIdentifier - Route name, pattern, or controller reference
|
|
3614
|
+
* @param domain - Optional domain to search within
|
|
3615
|
+
* @param method - Optional HTTP method to filter by
|
|
3616
|
+
* @param disableLegacyLookup - Whether to disable legacy lookup strategies
|
|
3617
|
+
* @returns Found route or null if not found
|
|
3618
|
+
*/
|
|
3619
|
+
find(routeIdentifier, domain, method, disableLegacyLookup) {
|
|
3620
|
+
return findRoute(this.routes, routeIdentifier, domain, method, disableLegacyLookup);
|
|
3621
|
+
}
|
|
3622
|
+
/**
|
|
3623
|
+
* Finds a route by its identifier. The identifier can be the
|
|
3624
|
+
* route name, controller.method name or the route pattern
|
|
3625
|
+
* itself.
|
|
3626
|
+
*
|
|
3627
|
+
* An error is raised when unable to find the route.
|
|
3628
|
+
*
|
|
3629
|
+
* When "disableLegacyLookup" is set, the lookup will be performed
|
|
3630
|
+
* only using the route name
|
|
3631
|
+
* @param routeIdentifier - Route name, pattern, or controller reference
|
|
3632
|
+
* @param domain - Optional domain to search within
|
|
3633
|
+
* @param method - Optional HTTP method to filter by
|
|
3634
|
+
* @param disableLegacyLookup - Whether to disable legacy lookup strategies
|
|
3635
|
+
* @returns Found route
|
|
3636
|
+
* @throws Error when route is not found
|
|
3637
|
+
*/
|
|
3638
|
+
findOrFail(routeIdentifier, domain, method, disableLegacyLookup) {
|
|
3639
|
+
const route = this.find(routeIdentifier, domain, method, disableLegacyLookup);
|
|
3640
|
+
if (!route) {
|
|
3641
|
+
throw new Error(`Cannot lookup route "${routeIdentifier}"`);
|
|
3642
|
+
}
|
|
3643
|
+
return route;
|
|
3644
|
+
}
|
|
3645
|
+
/**
|
|
3646
|
+
* Check if a route exists. The identifier can be the
|
|
3647
|
+
* route name, controller.method name or the route pattern
|
|
3648
|
+
* itself.
|
|
3649
|
+
*
|
|
3650
|
+
* When "followLookupStrategy" is enabled, the lookup will be performed
|
|
3651
|
+
* on the basis of the lookup strategy enabled via the "lookupStrategies"
|
|
3652
|
+
* method. The default lookupStrategy is "name" and "pattern".
|
|
3653
|
+
* @param routeIdentifier - Route name, pattern, or controller reference
|
|
3654
|
+
* @param domain - Optional domain to search within
|
|
3655
|
+
* @param method - Optional HTTP method to filter by
|
|
3656
|
+
* @param followLookupStrategy - Whether to follow the configured lookup strategy
|
|
3657
|
+
* @returns True if route exists, false otherwise
|
|
3658
|
+
*/
|
|
3659
|
+
has(routeIdentifier, domain, method, followLookupStrategy) {
|
|
3660
|
+
return !!this.find(routeIdentifier, domain, method, followLookupStrategy);
|
|
3661
|
+
}
|
|
3662
|
+
/**
|
|
3663
|
+
* Returns a list of routes grouped by their domain names
|
|
3664
|
+
* @returns Object mapping domain names to route arrays
|
|
3665
|
+
*/
|
|
3666
|
+
toJSON() {
|
|
3667
|
+
return this.routes;
|
|
3668
|
+
}
|
|
4252
3669
|
/**
|
|
4253
3670
|
* Generates types for the URL builder. These types must
|
|
4254
3671
|
* be written inside a file for the URL builder to
|
|
4255
3672
|
* pick them up.
|
|
3673
|
+
* @param indentation - Indentation level for generated types
|
|
3674
|
+
* @returns Generated TypeScript types as string
|
|
4256
3675
|
*/
|
|
4257
3676
|
generateTypes(indentation = 0) {
|
|
4258
3677
|
const routesList = {};
|
|
@@ -4279,21 +3698,11 @@ var Router = class extends RouterClient {
|
|
|
4279
3698
|
routesList["ALL"] = routesList["ALL"] ?? {};
|
|
4280
3699
|
routesList[method] = routesList[method] ?? {};
|
|
4281
3700
|
const identifiers = [];
|
|
4282
|
-
if (
|
|
4283
|
-
if (!routesList[method][route.pattern]) {
|
|
4284
|
-
identifiers.push(route.pattern);
|
|
4285
|
-
}
|
|
4286
|
-
}
|
|
4287
|
-
if (this.lookupStrategies.includes("name") && route.name) {
|
|
3701
|
+
if (route.name) {
|
|
4288
3702
|
identifiers.push(
|
|
4289
3703
|
domain && routesList[method][route.name] ? `${domain}@${route.name}` : route.name
|
|
4290
3704
|
);
|
|
4291
3705
|
}
|
|
4292
|
-
if (this.lookupStrategies.includes("controller") && "reference" in route.handler && typeof route.handler.reference === "string") {
|
|
4293
|
-
identifiers.push(
|
|
4294
|
-
domain && routesList[method][route.handler.reference] ? `${domain}@${route.handler.reference}` : route.handler.reference
|
|
4295
|
-
);
|
|
4296
|
-
}
|
|
4297
3706
|
identifiers.forEach((identifier) => {
|
|
4298
3707
|
routesList["ALL"][identifier] = {
|
|
4299
3708
|
params,
|
|
@@ -4309,12 +3718,12 @@ var Router = class extends RouterClient {
|
|
|
4309
3718
|
});
|
|
4310
3719
|
}
|
|
4311
3720
|
const domains = Object.keys(this.routes).filter((domain) => domain !== "root");
|
|
4312
|
-
this.routes["root"]
|
|
3721
|
+
this.routes["root"]?.forEach((route) => trackRoute.bind(this)(route));
|
|
4313
3722
|
domains.forEach(
|
|
4314
3723
|
(domain) => this.routes[domain].forEach((route) => trackRoute.bind(this)(route, domain))
|
|
4315
3724
|
);
|
|
4316
3725
|
return Object.keys(routesList).reduce((result, method) => {
|
|
4317
|
-
result.push(`${" ".repeat(indentation)}
|
|
3726
|
+
result.push(`${" ".repeat(indentation)}${method}: {`);
|
|
4318
3727
|
Object.keys(routesList[method]).forEach((identifier) => {
|
|
4319
3728
|
const key = `'${identifier}'`;
|
|
4320
3729
|
const { paramsTuple, hasRequiredParams, params } = routesList[method][identifier];
|
|
@@ -4322,47 +3731,20 @@ var Router = class extends RouterClient {
|
|
|
4322
3731
|
const tupleName = hasRequiredParams ? "paramsTuple" : "paramsTuple?";
|
|
4323
3732
|
const dictValue = `{${params.join(",")}}`;
|
|
4324
3733
|
const tupleValue = `[${paramsTuple?.join(",")}]`;
|
|
4325
|
-
const value = `{ ${tupleName}: ${tupleValue}
|
|
4326
|
-
result.push(`${" ".repeat(indentation + 2)}${key}: ${value}
|
|
3734
|
+
const value = `{ ${tupleName}: ${tupleValue}; ${dictName}: ${dictValue} }`;
|
|
3735
|
+
result.push(`${" ".repeat(indentation + 2)}${key}: ${value}`);
|
|
4327
3736
|
});
|
|
4328
|
-
result.push(`${" ".repeat(indentation)}}
|
|
3737
|
+
result.push(`${" ".repeat(indentation)}}`);
|
|
4329
3738
|
return result;
|
|
4330
3739
|
}, []).join("\n");
|
|
4331
3740
|
}
|
|
4332
|
-
generateClient() {
|
|
4333
|
-
const routesForClient = Object.keys(this.routes).reduce(
|
|
4334
|
-
(result, domain) => {
|
|
4335
|
-
const routes = this.routes[domain];
|
|
4336
|
-
result[domain] = routes.map((route) => {
|
|
4337
|
-
const controller = "reference" in route.handler && typeof route.handler.reference === "string" ? route.handler.reference : void 0;
|
|
4338
|
-
return {
|
|
4339
|
-
pattern: route.pattern,
|
|
4340
|
-
name: route.name,
|
|
4341
|
-
handler: {
|
|
4342
|
-
reference: controller
|
|
4343
|
-
},
|
|
4344
|
-
methods: route.methods,
|
|
4345
|
-
domain: route.domain,
|
|
4346
|
-
tokens: route.tokens.map((tokens) => {
|
|
4347
|
-
return lodash2.pick(tokens, ["val", "type", "end"]);
|
|
4348
|
-
})
|
|
4349
|
-
};
|
|
4350
|
-
});
|
|
4351
|
-
return result;
|
|
4352
|
-
},
|
|
4353
|
-
{}
|
|
4354
|
-
);
|
|
4355
|
-
return `import type { RoutesList } from '@adonisjs/core/types/http'
|
|
4356
|
-
import { RouterClient, createUrlBuilder, ClientRouteJSON } from 'adonisjs/core/http/client'
|
|
4357
|
-
|
|
4358
|
-
const routes = ${JSON.stringify(routesForClient)} satisfies { [domain: string]: ClientRouteJSON[] }
|
|
4359
|
-
const router = new RouterClient(routes)
|
|
4360
|
-
export const urlFor = createUrlBuilder<RoutesList>(router, (qs) => {
|
|
4361
|
-
return new URLSearchParams(qs).toString()
|
|
4362
|
-
})`;
|
|
4363
|
-
}
|
|
4364
3741
|
/**
|
|
4365
3742
|
* Find route for a given URL, method and optionally domain
|
|
3743
|
+
* @param uri - The URI to match
|
|
3744
|
+
* @param method - HTTP method
|
|
3745
|
+
* @param shouldDecodeParam - Whether to decode parameters
|
|
3746
|
+
* @param hostname - Optional hostname for domain matching
|
|
3747
|
+
* @returns Matched route or null if no match found
|
|
4366
3748
|
*/
|
|
4367
3749
|
match(uri, method, shouldDecodeParam, hostname) {
|
|
4368
3750
|
const matchingDomain = this.#store.matchDomain(hostname);
|
|
@@ -4373,9 +3755,7 @@ export const urlFor = createUrlBuilder<RoutesList>(router, (qs) => {
|
|
|
4373
3755
|
}
|
|
4374
3756
|
/**
|
|
4375
3757
|
* Create URL builder instance.
|
|
4376
|
-
* @deprecated
|
|
4377
|
-
*
|
|
4378
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3758
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
4379
3759
|
*/
|
|
4380
3760
|
builder() {
|
|
4381
3761
|
return new UrlBuilder(this);
|
|
@@ -4441,33 +3821,19 @@ export const urlFor = createUrlBuilder<RoutesList>(router, (qs) => {
|
|
|
4441
3821
|
|
|
4442
3822
|
// src/http_context/main.ts
|
|
4443
3823
|
import { inspect } from "util";
|
|
4444
|
-
import
|
|
4445
|
-
import { RuntimeException as
|
|
3824
|
+
import Macroable4 from "@poppinss/macroable";
|
|
3825
|
+
import { RuntimeException as RuntimeException4 } from "@poppinss/utils/exception";
|
|
4446
3826
|
|
|
4447
3827
|
// src/http_context/local_storage.ts
|
|
4448
3828
|
import { AsyncLocalStorage } from "async_hooks";
|
|
4449
3829
|
var asyncLocalStorage = {
|
|
4450
|
-
/**
|
|
4451
|
-
* Check if the async local storage for the HTTP
|
|
4452
|
-
* context is enabled or not
|
|
4453
|
-
*/
|
|
4454
3830
|
isEnabled: false,
|
|
4455
|
-
/**
|
|
4456
|
-
* HTTP context storage instance for the current scope
|
|
4457
|
-
*/
|
|
4458
3831
|
storage: null,
|
|
4459
|
-
/**
|
|
4460
|
-
* Create the storage instance. This method must be called only
|
|
4461
|
-
* once.
|
|
4462
|
-
*/
|
|
4463
3832
|
create() {
|
|
4464
3833
|
this.isEnabled = true;
|
|
4465
3834
|
this.storage = new AsyncLocalStorage();
|
|
4466
3835
|
return this.storage;
|
|
4467
3836
|
},
|
|
4468
|
-
/**
|
|
4469
|
-
* Destroy the create storage instance
|
|
4470
|
-
*/
|
|
4471
3837
|
destroy() {
|
|
4472
3838
|
this.isEnabled = false;
|
|
4473
3839
|
this.storage = null;
|
|
@@ -4475,7 +3841,15 @@ var asyncLocalStorage = {
|
|
|
4475
3841
|
};
|
|
4476
3842
|
|
|
4477
3843
|
// src/http_context/main.ts
|
|
4478
|
-
var HttpContext = class extends
|
|
3844
|
+
var HttpContext = class extends Macroable4 {
|
|
3845
|
+
/**
|
|
3846
|
+
* Creates a new HttpContext instance
|
|
3847
|
+
*
|
|
3848
|
+
* @param {Request} request - The HTTP request instance
|
|
3849
|
+
* @param {Response} response - The HTTP response instance
|
|
3850
|
+
* @param {Logger} logger - The logger instance
|
|
3851
|
+
* @param {ContainerResolver<any>} containerResolver - The IoC container resolver
|
|
3852
|
+
*/
|
|
4479
3853
|
constructor(request, response, logger, containerResolver) {
|
|
4480
3854
|
super();
|
|
4481
3855
|
this.request = request;
|
|
@@ -4486,15 +3860,27 @@ var HttpContext = class extends Macroable8 {
|
|
|
4486
3860
|
this.response.ctx = this;
|
|
4487
3861
|
}
|
|
4488
3862
|
/**
|
|
4489
|
-
*
|
|
4490
|
-
*
|
|
3863
|
+
* Indicates whether async local storage is enabled for HTTP requests.
|
|
3864
|
+
*
|
|
3865
|
+
* When enabled, the HTTP context is automatically available within the
|
|
3866
|
+
* scope of request processing through static methods like get() and getOrFail().
|
|
4491
3867
|
*/
|
|
4492
3868
|
static get usingAsyncLocalStorage() {
|
|
4493
3869
|
return asyncLocalStorage.isEnabled;
|
|
4494
3870
|
}
|
|
4495
3871
|
/**
|
|
4496
|
-
* Get access to the HTTP context
|
|
4497
|
-
*
|
|
3872
|
+
* Get access to the current HTTP context from async local storage.
|
|
3873
|
+
*
|
|
3874
|
+
* This method is only available when async local storage is enabled.
|
|
3875
|
+
* Returns null if called outside of an HTTP request context.
|
|
3876
|
+
*
|
|
3877
|
+
* @example
|
|
3878
|
+
* ```ts
|
|
3879
|
+
* const ctx = HttpContext.get()
|
|
3880
|
+
* if (ctx) {
|
|
3881
|
+
* console.log(ctx.request.url())
|
|
3882
|
+
* }
|
|
3883
|
+
* ```
|
|
4498
3884
|
*/
|
|
4499
3885
|
static get() {
|
|
4500
3886
|
if (!this.usingAsyncLocalStorage || !asyncLocalStorage.storage) {
|
|
@@ -4503,24 +3889,48 @@ var HttpContext = class extends Macroable8 {
|
|
|
4503
3889
|
return asyncLocalStorage.storage.getStore() || null;
|
|
4504
3890
|
}
|
|
4505
3891
|
/**
|
|
4506
|
-
* Get the HttpContext instance or raise an exception if not
|
|
4507
|
-
*
|
|
3892
|
+
* Get the HttpContext instance or raise an exception if not available.
|
|
3893
|
+
*
|
|
3894
|
+
* This method is useful when you need guaranteed access to the HTTP context
|
|
3895
|
+
* and want to fail fast if it's not available.
|
|
3896
|
+
*
|
|
3897
|
+
* @throws RuntimeException when async local storage is disabled or context is unavailable
|
|
3898
|
+
*
|
|
3899
|
+
* @example
|
|
3900
|
+
* ```ts
|
|
3901
|
+
* const ctx = HttpContext.getOrFail()
|
|
3902
|
+
* const userId = ctx.request.input('user_id')
|
|
3903
|
+
* ```
|
|
4508
3904
|
*/
|
|
4509
3905
|
static getOrFail() {
|
|
4510
3906
|
if (!this.usingAsyncLocalStorage || !asyncLocalStorage.storage) {
|
|
4511
|
-
throw new
|
|
3907
|
+
throw new RuntimeException4(
|
|
4512
3908
|
'HTTP context is not available. Enable "useAsyncLocalStorage" inside "config/app.ts" file'
|
|
4513
3909
|
);
|
|
4514
3910
|
}
|
|
4515
3911
|
const store = this.get();
|
|
4516
3912
|
if (!store) {
|
|
4517
|
-
throw new
|
|
3913
|
+
throw new RuntimeException4("Http context is not available outside of an HTTP request");
|
|
4518
3914
|
}
|
|
4519
3915
|
return store;
|
|
4520
3916
|
}
|
|
4521
3917
|
/**
|
|
4522
|
-
* Run a method
|
|
4523
|
-
*
|
|
3918
|
+
* Run a method outside of the HTTP context scope.
|
|
3919
|
+
*
|
|
3920
|
+
* This method allows you to execute code that should not have access to
|
|
3921
|
+
* the current HTTP context from async local storage. Useful for background
|
|
3922
|
+
* tasks or operations that should be context-independent.
|
|
3923
|
+
*
|
|
3924
|
+
* @param callback - Function to execute outside the context
|
|
3925
|
+
* @param args - Arguments to pass to the callback
|
|
3926
|
+
*
|
|
3927
|
+
* @example
|
|
3928
|
+
* ```ts
|
|
3929
|
+
* HttpContext.runOutsideContext(() => {
|
|
3930
|
+
* // This code cannot access HttpContext.get()
|
|
3931
|
+
* performBackgroundTask()
|
|
3932
|
+
* })
|
|
3933
|
+
* ```
|
|
4524
3934
|
*/
|
|
4525
3935
|
static runOutsideContext(callback, ...args) {
|
|
4526
3936
|
if (!asyncLocalStorage.storage) {
|
|
@@ -4556,23 +3966,8 @@ var HttpContext = class extends Macroable8 {
|
|
|
4556
3966
|
|
|
4557
3967
|
// src/server/main.ts
|
|
4558
3968
|
import onFinished2 from "on-finished";
|
|
4559
|
-
import
|
|
4560
|
-
import { moduleCaller
|
|
4561
|
-
|
|
4562
|
-
// src/qs.ts
|
|
4563
|
-
import { parse as parse2, stringify } from "qs";
|
|
4564
|
-
var Qs = class {
|
|
4565
|
-
#config;
|
|
4566
|
-
constructor(config) {
|
|
4567
|
-
this.#config = config;
|
|
4568
|
-
}
|
|
4569
|
-
parse = (value) => {
|
|
4570
|
-
return parse2(value, this.#config.parse);
|
|
4571
|
-
};
|
|
4572
|
-
stringify = (value) => {
|
|
4573
|
-
return stringify(value, this.#config.stringify);
|
|
4574
|
-
};
|
|
4575
|
-
};
|
|
3969
|
+
import Middleware from "@poppinss/middleware";
|
|
3970
|
+
import { moduleCaller, moduleImporter as moduleImporter3 } from "@adonisjs/fold";
|
|
4576
3971
|
|
|
4577
3972
|
// src/server/factories/route_finder.ts
|
|
4578
3973
|
function routeFinder(router, resolver, ctx, errorResponder) {
|
|
@@ -4611,7 +4006,7 @@ function middlewareHandler(resolver, ctx) {
|
|
|
4611
4006
|
debug_default("executing middleware %s", fn.name);
|
|
4612
4007
|
return httpMiddleware.tracePromise(
|
|
4613
4008
|
fn.handle,
|
|
4614
|
-
fn,
|
|
4009
|
+
httpMiddleware.hasSubscribers ? { middleware: fn } : void 0,
|
|
4615
4010
|
void 0,
|
|
4616
4011
|
resolver,
|
|
4617
4012
|
ctx,
|
|
@@ -4622,9 +4017,12 @@ function middlewareHandler(resolver, ctx) {
|
|
|
4622
4017
|
|
|
4623
4018
|
// src/server/main.ts
|
|
4624
4019
|
var Server = class {
|
|
4020
|
+
/**
|
|
4021
|
+
* Flag indicating whether the server has been booted and initialized
|
|
4022
|
+
*/
|
|
4625
4023
|
#booted = false;
|
|
4626
4024
|
/**
|
|
4627
|
-
*
|
|
4025
|
+
* Built-in fallback error handler used when no custom handler is registered
|
|
4628
4026
|
*/
|
|
4629
4027
|
#defaultErrorHandler = {
|
|
4630
4028
|
report() {
|
|
@@ -4634,86 +4032,88 @@ var Server = class {
|
|
|
4634
4032
|
}
|
|
4635
4033
|
};
|
|
4636
4034
|
/**
|
|
4637
|
-
* Logger instance
|
|
4638
|
-
* to the context to have request specific
|
|
4639
|
-
* logging capabilities.
|
|
4035
|
+
* Logger instance for server-level logging (child loggers are created per request)
|
|
4640
4036
|
*/
|
|
4641
4037
|
#logger;
|
|
4642
4038
|
/**
|
|
4643
|
-
*
|
|
4039
|
+
* Lazy import reference to the custom error handler class
|
|
4644
4040
|
*/
|
|
4645
4041
|
#errorHandler;
|
|
4646
4042
|
/**
|
|
4647
|
-
*
|
|
4648
|
-
* handler class.
|
|
4043
|
+
* Active error handler instance (either custom or default)
|
|
4649
4044
|
*/
|
|
4650
4045
|
#resolvedErrorHandler = this.#defaultErrorHandler;
|
|
4651
4046
|
/**
|
|
4652
|
-
*
|
|
4047
|
+
* Event emitter for HTTP server lifecycle events
|
|
4653
4048
|
*/
|
|
4654
4049
|
#emitter;
|
|
4655
4050
|
/**
|
|
4656
|
-
*
|
|
4051
|
+
* AdonisJS application instance providing IoC container and configuration
|
|
4657
4052
|
*/
|
|
4658
4053
|
#app;
|
|
4659
4054
|
/**
|
|
4660
|
-
*
|
|
4055
|
+
* Encryption service for secure cookie handling and data encryption
|
|
4661
4056
|
*/
|
|
4662
4057
|
#encryption;
|
|
4663
4058
|
/**
|
|
4664
|
-
* Server
|
|
4059
|
+
* Server configuration settings including timeouts, middleware options, etc.
|
|
4665
4060
|
*/
|
|
4666
4061
|
#config;
|
|
4667
4062
|
/**
|
|
4668
|
-
* Query string parser
|
|
4063
|
+
* Query string parser instance for URL parameter processing
|
|
4669
4064
|
*/
|
|
4670
4065
|
#qsParser;
|
|
4671
4066
|
/**
|
|
4672
|
-
*
|
|
4067
|
+
* Compiled middleware stack that executes on every incoming HTTP request
|
|
4673
4068
|
*/
|
|
4674
4069
|
#serverMiddlewareStack;
|
|
4675
4070
|
/**
|
|
4676
|
-
*
|
|
4071
|
+
* Router instance responsible for route registration and matching
|
|
4677
4072
|
*/
|
|
4678
4073
|
#router;
|
|
4679
4074
|
/**
|
|
4680
|
-
* Reference to the underlying Node HTTP server
|
|
4075
|
+
* Reference to the underlying Node.js HTTP or HTTPS server instance
|
|
4681
4076
|
*/
|
|
4682
4077
|
#nodeHttpServer;
|
|
4683
4078
|
/**
|
|
4684
|
-
*
|
|
4079
|
+
* Collection of registered global middleware before compilation
|
|
4685
4080
|
*/
|
|
4686
4081
|
#middleware = [];
|
|
4687
4082
|
/**
|
|
4688
|
-
*
|
|
4689
|
-
*
|
|
4690
|
-
* registered error handler.
|
|
4691
|
-
*
|
|
4692
|
-
* We share this with the route middleware pipeline as well,
|
|
4693
|
-
* so that it does not throw any exceptions
|
|
4083
|
+
* Error responder function that handles exceptions in middleware and routes.
|
|
4084
|
+
* Reports errors and delegates handling to the configured error handler.
|
|
4694
4085
|
*/
|
|
4695
4086
|
#requestErrorResponder = (error, ctx) => {
|
|
4696
4087
|
this.#resolvedErrorHandler.report(error, ctx);
|
|
4697
4088
|
return httpExceptionHandler.tracePromise(
|
|
4698
4089
|
this.#resolvedErrorHandler.handle,
|
|
4699
4090
|
void 0,
|
|
4700
|
-
|
|
4091
|
+
this.#resolvedErrorHandler,
|
|
4701
4092
|
error,
|
|
4702
4093
|
ctx
|
|
4703
4094
|
);
|
|
4704
4095
|
};
|
|
4705
4096
|
/**
|
|
4706
|
-
*
|
|
4097
|
+
* Indicates whether the server has completed its boot process
|
|
4707
4098
|
*/
|
|
4708
4099
|
get booted() {
|
|
4709
4100
|
return this.#booted;
|
|
4710
4101
|
}
|
|
4711
4102
|
/**
|
|
4712
|
-
*
|
|
4103
|
+
* Indicates whether async local storage is enabled for request context
|
|
4713
4104
|
*/
|
|
4714
4105
|
get usingAsyncLocalStorage() {
|
|
4715
4106
|
return asyncLocalStorage.isEnabled;
|
|
4716
4107
|
}
|
|
4108
|
+
/**
|
|
4109
|
+
* Creates a new Server instance
|
|
4110
|
+
*
|
|
4111
|
+
* @param app - AdonisJS application instance
|
|
4112
|
+
* @param encryption - Encryption service for secure operations
|
|
4113
|
+
* @param emitter - Event emitter for server lifecycle events
|
|
4114
|
+
* @param logger - Logger instance for server operations
|
|
4115
|
+
* @param config - Server configuration settings
|
|
4116
|
+
*/
|
|
4717
4117
|
constructor(app, encryption, emitter, logger, config) {
|
|
4718
4118
|
this.#app = app;
|
|
4719
4119
|
this.#emitter = emitter;
|
|
@@ -4726,7 +4126,7 @@ var Server = class {
|
|
|
4726
4126
|
debug_default("server config: %O", this.#config);
|
|
4727
4127
|
}
|
|
4728
4128
|
/**
|
|
4729
|
-
*
|
|
4129
|
+
* Initializes or destroys async local storage based on configuration
|
|
4730
4130
|
*/
|
|
4731
4131
|
#createAsyncLocalStore() {
|
|
4732
4132
|
if (this.#config.useAsyncLocalStorage) {
|
|
@@ -4737,16 +4137,20 @@ var Server = class {
|
|
|
4737
4137
|
}
|
|
4738
4138
|
}
|
|
4739
4139
|
/**
|
|
4740
|
-
*
|
|
4140
|
+
* Compiles registered middleware into a frozen middleware stack for execution
|
|
4741
4141
|
*/
|
|
4742
4142
|
#createServerMiddlewareStack() {
|
|
4743
|
-
this.#serverMiddlewareStack = new
|
|
4143
|
+
this.#serverMiddlewareStack = new Middleware();
|
|
4744
4144
|
this.#middleware.forEach((middleware) => this.#serverMiddlewareStack.add(middleware));
|
|
4745
4145
|
this.#serverMiddlewareStack.freeze();
|
|
4746
4146
|
this.#middleware = [];
|
|
4747
4147
|
}
|
|
4748
4148
|
/**
|
|
4749
|
-
*
|
|
4149
|
+
* Processes an HTTP request through the middleware pipeline and routing
|
|
4150
|
+
*
|
|
4151
|
+
* @param ctx - HTTP context containing request/response objects
|
|
4152
|
+
* @param resolver - Container resolver for dependency injection
|
|
4153
|
+
* @returns Promise that resolves when request processing is complete
|
|
4750
4154
|
*/
|
|
4751
4155
|
#handleRequest(ctx, resolver) {
|
|
4752
4156
|
return this.#serverMiddlewareStack.runner().errorHandler((error) => this.#requestErrorResponder(error, ctx)).finalHandler(routeFinder(this.#router, resolver, ctx, this.#requestErrorResponder)).run(middlewareHandler(resolver, ctx)).catch((error) => {
|
|
@@ -4755,14 +4159,17 @@ var Server = class {
|
|
|
4755
4159
|
}).finally(writeResponse(ctx));
|
|
4756
4160
|
}
|
|
4757
4161
|
/**
|
|
4758
|
-
* Creates a pipeline
|
|
4162
|
+
* Creates a testing middleware pipeline for unit/integration testing
|
|
4163
|
+
*
|
|
4164
|
+
* @param middleware - Array of middleware classes to include in pipeline
|
|
4165
|
+
* @returns TestingMiddlewarePipeline instance for test execution
|
|
4759
4166
|
*/
|
|
4760
4167
|
pipeline(middleware) {
|
|
4761
|
-
const middlewareStack = new
|
|
4168
|
+
const middlewareStack = new Middleware();
|
|
4762
4169
|
middleware.forEach((one) => {
|
|
4763
4170
|
middlewareStack.add({
|
|
4764
4171
|
reference: one,
|
|
4765
|
-
...
|
|
4172
|
+
...moduleCaller(one, "handle").toHandleMethod()
|
|
4766
4173
|
});
|
|
4767
4174
|
});
|
|
4768
4175
|
middlewareStack.freeze();
|
|
@@ -4784,32 +4191,37 @@ var Server = class {
|
|
|
4784
4191
|
};
|
|
4785
4192
|
}
|
|
4786
4193
|
/**
|
|
4787
|
-
*
|
|
4788
|
-
*
|
|
4789
|
-
* of middleware
|
|
4194
|
+
* Registers global middleware to run on all incoming HTTP requests
|
|
4195
|
+
*
|
|
4196
|
+
* @param middleware - Array of lazy-imported middleware classes
|
|
4197
|
+
* @returns The Server instance for method chaining
|
|
4790
4198
|
*/
|
|
4791
4199
|
use(middleware) {
|
|
4792
4200
|
middleware.forEach(
|
|
4793
4201
|
(one) => this.#middleware.push({
|
|
4794
4202
|
reference: one,
|
|
4795
|
-
...
|
|
4203
|
+
...moduleImporter3(one, "handle").toHandleMethod()
|
|
4796
4204
|
})
|
|
4797
4205
|
);
|
|
4798
4206
|
return this;
|
|
4799
4207
|
}
|
|
4800
4208
|
/**
|
|
4801
|
-
*
|
|
4802
|
-
*
|
|
4209
|
+
* Registers a custom error handler for HTTP request processing
|
|
4210
|
+
*
|
|
4211
|
+
* @param handler - Lazy import of the error handler class
|
|
4212
|
+
* @returns The Server instance for method chaining
|
|
4803
4213
|
*/
|
|
4804
4214
|
errorHandler(handler) {
|
|
4805
4215
|
this.#errorHandler = handler;
|
|
4806
4216
|
return this;
|
|
4807
4217
|
}
|
|
4808
4218
|
/**
|
|
4809
|
-
*
|
|
4219
|
+
* Initializes the server by compiling middleware, committing routes, and resolving handlers
|
|
4810
4220
|
*
|
|
4811
|
-
*
|
|
4812
|
-
* -
|
|
4221
|
+
* Performs the following operations:
|
|
4222
|
+
* - Compiles the middleware stack
|
|
4223
|
+
* - Commits registered routes to the router
|
|
4224
|
+
* - Resolves and instantiates the custom error handler
|
|
4813
4225
|
*/
|
|
4814
4226
|
async boot() {
|
|
4815
4227
|
if (this.#booted) {
|
|
@@ -4828,7 +4240,9 @@ var Server = class {
|
|
|
4828
4240
|
this.#booted = true;
|
|
4829
4241
|
}
|
|
4830
4242
|
/**
|
|
4831
|
-
*
|
|
4243
|
+
* Configures the underlying Node.js HTTP/HTTPS server with timeout settings
|
|
4244
|
+
*
|
|
4245
|
+
* @param server - Node.js HTTP or HTTPS server instance
|
|
4832
4246
|
*/
|
|
4833
4247
|
setNodeServer(server) {
|
|
4834
4248
|
server.timeout = this.#config.timeout ?? server.timeout;
|
|
@@ -4838,33 +4252,48 @@ var Server = class {
|
|
|
4838
4252
|
this.#nodeHttpServer = server;
|
|
4839
4253
|
}
|
|
4840
4254
|
/**
|
|
4841
|
-
*
|
|
4842
|
-
*
|
|
4255
|
+
* Gets the underlying Node.js HTTP/HTTPS server instance
|
|
4256
|
+
*
|
|
4257
|
+
* @returns The configured server instance or undefined if not set
|
|
4843
4258
|
*/
|
|
4844
4259
|
getNodeServer() {
|
|
4845
4260
|
return this.#nodeHttpServer;
|
|
4846
4261
|
}
|
|
4847
4262
|
/**
|
|
4848
|
-
*
|
|
4849
|
-
*
|
|
4263
|
+
* Gets the router instance used for route registration and matching
|
|
4264
|
+
*
|
|
4265
|
+
* @returns The Router instance
|
|
4850
4266
|
*/
|
|
4851
4267
|
getRouter() {
|
|
4852
4268
|
return this.#router;
|
|
4853
4269
|
}
|
|
4854
4270
|
/**
|
|
4855
|
-
* Creates
|
|
4271
|
+
* Creates a Request instance from Node.js request/response objects
|
|
4272
|
+
*
|
|
4273
|
+
* @param req - Node.js IncomingMessage
|
|
4274
|
+
* @param res - Node.js ServerResponse
|
|
4275
|
+
* @returns New Request instance
|
|
4856
4276
|
*/
|
|
4857
4277
|
createRequest(req, res) {
|
|
4858
4278
|
return new Request(req, res, this.#encryption, this.#config, this.#qsParser);
|
|
4859
4279
|
}
|
|
4860
4280
|
/**
|
|
4861
|
-
* Creates
|
|
4281
|
+
* Creates a Response instance from Node.js request/response objects
|
|
4282
|
+
*
|
|
4283
|
+
* @param req - Node.js IncomingMessage
|
|
4284
|
+
* @param res - Node.js ServerResponse
|
|
4285
|
+
* @returns New Response instance
|
|
4862
4286
|
*/
|
|
4863
4287
|
createResponse(req, res) {
|
|
4864
4288
|
return new Response(req, res, this.#encryption, this.#config, this.#router, this.#qsParser);
|
|
4865
4289
|
}
|
|
4866
4290
|
/**
|
|
4867
|
-
* Creates an instance
|
|
4291
|
+
* Creates an HttpContext instance with request-specific logger
|
|
4292
|
+
*
|
|
4293
|
+
* @param request - Request instance
|
|
4294
|
+
* @param response - Response instance
|
|
4295
|
+
* @param resolver - Container resolver for dependency injection
|
|
4296
|
+
* @returns New HttpContext instance
|
|
4868
4297
|
*/
|
|
4869
4298
|
createHttpContext(request, response, resolver) {
|
|
4870
4299
|
return new HttpContext(
|
|
@@ -4875,13 +4304,19 @@ var Server = class {
|
|
|
4875
4304
|
);
|
|
4876
4305
|
}
|
|
4877
4306
|
/**
|
|
4878
|
-
*
|
|
4307
|
+
* Gets the list of registered global middleware
|
|
4308
|
+
*
|
|
4309
|
+
* @returns Array of parsed global middleware
|
|
4879
4310
|
*/
|
|
4880
4311
|
getMiddlewareList() {
|
|
4881
4312
|
return this.#serverMiddlewareStack ? Array.from(this.#serverMiddlewareStack.all()) : [...this.#middleware];
|
|
4882
4313
|
}
|
|
4883
4314
|
/**
|
|
4884
|
-
*
|
|
4315
|
+
* Handles an incoming HTTP request by creating context and processing through pipeline
|
|
4316
|
+
*
|
|
4317
|
+
* @param req - Node.js IncomingMessage
|
|
4318
|
+
* @param res - Node.js ServerResponse
|
|
4319
|
+
* @returns Promise that resolves when request processing is complete
|
|
4885
4320
|
*/
|
|
4886
4321
|
handle(req, res) {
|
|
4887
4322
|
const hasRequestListener = this.#emitter.hasListeners("http:request_completed");
|
|
@@ -4903,17 +4338,29 @@ var Server = class {
|
|
|
4903
4338
|
if (this.usingAsyncLocalStorage) {
|
|
4904
4339
|
return asyncLocalStorage.storage.run(
|
|
4905
4340
|
ctx,
|
|
4906
|
-
() => httpRequest.tracePromise(
|
|
4341
|
+
() => httpRequest.tracePromise(
|
|
4342
|
+
this.#handleRequest,
|
|
4343
|
+
httpRequest.hasSubscribers ? { ctx } : void 0,
|
|
4344
|
+
this,
|
|
4345
|
+
ctx,
|
|
4346
|
+
resolver
|
|
4347
|
+
)
|
|
4907
4348
|
);
|
|
4908
4349
|
}
|
|
4909
|
-
return httpRequest.tracePromise(
|
|
4350
|
+
return httpRequest.tracePromise(
|
|
4351
|
+
this.#handleRequest,
|
|
4352
|
+
httpRequest.hasSubscribers ? { ctx } : void 0,
|
|
4353
|
+
this,
|
|
4354
|
+
ctx,
|
|
4355
|
+
resolver
|
|
4356
|
+
);
|
|
4910
4357
|
}
|
|
4911
4358
|
};
|
|
4912
4359
|
|
|
4913
4360
|
// src/define_config.ts
|
|
4914
4361
|
import proxyAddr from "proxy-addr";
|
|
4915
|
-
import
|
|
4916
|
-
import
|
|
4362
|
+
import string from "@poppinss/utils/string";
|
|
4363
|
+
import lodash2 from "@poppinss/utils/lodash";
|
|
4917
4364
|
function defineConfig(config) {
|
|
4918
4365
|
const { trustProxy: trustProxy2, ...rest } = config;
|
|
4919
4366
|
const defaults = {
|
|
@@ -4950,9 +4397,9 @@ function defineConfig(config) {
|
|
|
4950
4397
|
}
|
|
4951
4398
|
}
|
|
4952
4399
|
};
|
|
4953
|
-
const normalizedConfig =
|
|
4400
|
+
const normalizedConfig = lodash2.merge({}, defaults, rest);
|
|
4954
4401
|
if (normalizedConfig.cookie.maxAge) {
|
|
4955
|
-
normalizedConfig.cookie.maxAge =
|
|
4402
|
+
normalizedConfig.cookie.maxAge = string.seconds.parse(normalizedConfig.cookie.maxAge);
|
|
4956
4403
|
}
|
|
4957
4404
|
if (typeof trustProxy2 === "boolean") {
|
|
4958
4405
|
const tpValue = trustProxy2;
|
|
@@ -4967,24 +4414,19 @@ function defineConfig(config) {
|
|
|
4967
4414
|
}
|
|
4968
4415
|
|
|
4969
4416
|
export {
|
|
4417
|
+
Qs,
|
|
4970
4418
|
E_ROUTE_NOT_FOUND,
|
|
4971
4419
|
E_CANNOT_LOOKUP_ROUTE,
|
|
4972
4420
|
E_HTTP_EXCEPTION,
|
|
4973
4421
|
E_HTTP_REQUEST_ABORTED,
|
|
4974
4422
|
errors_exports,
|
|
4975
4423
|
CookieClient,
|
|
4976
|
-
|
|
4977
|
-
tracing_channels_exports,
|
|
4978
|
-
Route,
|
|
4979
|
-
BriskRoute,
|
|
4980
|
-
RouteResource,
|
|
4981
|
-
RouteGroup,
|
|
4982
|
-
parseRange,
|
|
4424
|
+
CookieParser,
|
|
4983
4425
|
Request,
|
|
4984
4426
|
Redirect,
|
|
4985
4427
|
ResponseStatus,
|
|
4428
|
+
CookieSerializer,
|
|
4986
4429
|
Response,
|
|
4987
|
-
Qs,
|
|
4988
4430
|
Router,
|
|
4989
4431
|
HttpContext,
|
|
4990
4432
|
Server,
|