@adonisjs/http-server 8.0.0-next.1 → 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-HMYAZG76.js → chunk-YBLFT4O6.js} +1146 -1663
- package/build/factories/http_context.d.ts +2 -1
- package/build/factories/http_server.d.ts +7 -0
- package/build/factories/main.js +33 -5
- package/build/factories/qs_parser_factory.d.ts +3 -2
- package/build/factories/request.d.ts +1 -0
- package/build/factories/response.d.ts +1 -0
- package/build/factories/router.d.ts +1 -0
- package/build/factories/server_factory.d.ts +1 -0
- package/build/factories/url_builder_factory.d.ts +3 -2
- package/build/index.d.ts +4 -1
- package/build/index.js +97 -42
- package/build/src/client/helpers.d.ts +37 -0
- package/build/src/client/types.d.ts +203 -0
- package/build/src/client/url_builder.d.ts +15 -0
- 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 +21 -2
- package/build/src/debug.d.ts +13 -0
- package/build/src/define_config.d.ts +20 -4
- package/build/src/define_middleware.d.ts +20 -4
- package/build/src/errors.d.ts +60 -5
- package/build/src/exception_handler.d.ts +93 -39
- package/build/src/helpers.d.ts +57 -0
- package/build/src/helpers.js +9 -1
- package/build/src/http_context/local_storage.d.ts +17 -0
- package/build/src/http_context/main.d.ts +68 -10
- package/build/src/qs.d.ts +30 -2
- package/build/src/redirect.d.ts +84 -12
- package/build/src/request.d.ts +118 -12
- package/build/src/response.d.ts +416 -203
- package/build/src/response_status.d.ts +14 -0
- package/build/src/router/brisk.d.ts +15 -4
- package/build/src/router/executor.d.ts +4 -0
- package/build/src/router/factories/use_return_value.d.ts +5 -0
- package/build/src/router/group.d.ts +18 -1
- package/build/src/router/legacy/url_builder.d.ts +14 -14
- package/build/src/router/main.d.ts +79 -22
- package/build/src/router/matchers.d.ts +3 -0
- package/build/src/router/resource.d.ts +34 -1
- package/build/src/router/route.d.ts +28 -3
- package/build/src/router/signed_url_builder.d.ts +4 -8
- package/build/src/router/store.d.ts +9 -0
- package/build/src/server/factories/middleware_handler.d.ts +10 -1
- package/build/src/server/factories/route_finder.d.ts +13 -3
- package/build/src/server/factories/write_response.d.ts +9 -2
- package/build/src/server/main.d.ts +77 -23
- package/build/src/tracing_channels.d.ts +4 -4
- package/build/src/types/middleware.d.ts +34 -9
- 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 +42 -42
- package/build/src/types/server.d.ts +26 -11
- package/build/src/types/tracing_channels.d.ts +21 -3
- package/build/src/types/url_builder.d.ts +10 -135
- package/build/src/utils.d.ts +71 -6
- package/package.json +26 -22
- package/build/chunk-ASX56VAK.js +0 -76
- package/build/src/router/url_builder.d.ts +0 -14
|
@@ -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) {
|
|
@@ -71,1093 +133,155 @@ function unpack(encodedValue) {
|
|
|
71
133
|
|
|
72
134
|
// src/cookies/drivers/signed.ts
|
|
73
135
|
function pack2(key, value, encryption) {
|
|
74
|
-
if (value === void 0 || value === null) {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
return `s:${encryption.verifier.sign(value, void 0, key)}`;
|
|
78
|
-
}
|
|
79
|
-
function canUnpack2(signedValue) {
|
|
80
|
-
return typeof signedValue === "string" && signedValue.substring(0, 2) === "s:";
|
|
81
|
-
}
|
|
82
|
-
function unpack2(key, signedValue, encryption) {
|
|
83
|
-
const value = signedValue.slice(2);
|
|
84
|
-
if (!value) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
return encryption.verifier.unsign(value, key);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// src/cookies/drivers/encrypted.ts
|
|
91
|
-
function pack3(key, value, encryption) {
|
|
92
|
-
if (value === void 0 || value === null) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
return `e:${encryption.encrypt(value, void 0, key)}`;
|
|
96
|
-
}
|
|
97
|
-
function canUnpack3(encryptedValue) {
|
|
98
|
-
return typeof encryptedValue === "string" && encryptedValue.substring(0, 2) === "e:";
|
|
99
|
-
}
|
|
100
|
-
function unpack3(key, encryptedValue, encryption) {
|
|
101
|
-
const value = encryptedValue.slice(2);
|
|
102
|
-
if (!value) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
return encryption.decrypt(value, key);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// src/cookies/client.ts
|
|
109
|
-
var CookieClient = class {
|
|
110
|
-
#encryption;
|
|
111
|
-
constructor(encryption) {
|
|
112
|
-
this.#encryption = encryption;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Encrypt a key value pair to be sent in the cookie header
|
|
116
|
-
*/
|
|
117
|
-
encrypt(key, value) {
|
|
118
|
-
return pack3(key, value, this.#encryption);
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Sign a key value pair to be sent in the cookie header
|
|
122
|
-
*/
|
|
123
|
-
sign(key, value) {
|
|
124
|
-
return pack2(key, value, this.#encryption);
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Encode a key value pair to be sent in the cookie header
|
|
128
|
-
*/
|
|
129
|
-
encode(_, value, stringify2 = true) {
|
|
130
|
-
return stringify2 ? pack(value) : value;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Unsign a signed cookie value
|
|
134
|
-
*/
|
|
135
|
-
unsign(key, value) {
|
|
136
|
-
return canUnpack2(value) ? unpack2(key, value, this.#encryption) : null;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Decrypt an encrypted cookie value
|
|
140
|
-
*/
|
|
141
|
-
decrypt(key, value) {
|
|
142
|
-
return canUnpack3(value) ? unpack3(key, value, this.#encryption) : null;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Decode an encoded cookie value
|
|
146
|
-
*/
|
|
147
|
-
decode(_, value, stringified = true) {
|
|
148
|
-
if (!stringified) {
|
|
149
|
-
return value;
|
|
150
|
-
}
|
|
151
|
-
return canUnpack(value) ? unpack(value) : null;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Parse response cookie
|
|
155
|
-
*/
|
|
156
|
-
parse(key, value) {
|
|
157
|
-
if (canUnpack2(value)) {
|
|
158
|
-
return unpack2(key, value, this.#encryption);
|
|
159
|
-
}
|
|
160
|
-
if (canUnpack3(value)) {
|
|
161
|
-
return unpack3(key, value, this.#encryption);
|
|
162
|
-
}
|
|
163
|
-
if (canUnpack(value)) {
|
|
164
|
-
return unpack(value);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
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 };
|
|
136
|
+
if (value === void 0 || value === null) {
|
|
137
|
+
return null;
|
|
980
138
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
139
|
+
return `s:${encryption.verifier.sign(value, void 0, key)}`;
|
|
140
|
+
}
|
|
141
|
+
function canUnpack2(signedValue) {
|
|
142
|
+
return typeof signedValue === "string" && signedValue.substring(0, 2) === "s:";
|
|
143
|
+
}
|
|
144
|
+
function unpack2(key, signedValue, encryption) {
|
|
145
|
+
const value = signedValue.slice(2);
|
|
146
|
+
if (!value) {
|
|
147
|
+
return null;
|
|
988
148
|
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
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;
|
|
149
|
+
return encryption.verifier.unsign(value, key);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/cookies/drivers/encrypted.ts
|
|
153
|
+
function pack3(key, value, encryption) {
|
|
154
|
+
if (value === void 0 || value === null) {
|
|
155
|
+
return null;
|
|
1015
156
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
157
|
+
return `e:${encryption.encrypt(value, void 0, key)}`;
|
|
158
|
+
}
|
|
159
|
+
function canUnpack3(encryptedValue) {
|
|
160
|
+
return typeof encryptedValue === "string" && encryptedValue.substring(0, 2) === "e:";
|
|
161
|
+
}
|
|
162
|
+
function unpack3(key, encryptedValue, encryption) {
|
|
163
|
+
const value = encryptedValue.slice(2);
|
|
164
|
+
if (!value) {
|
|
165
|
+
return null;
|
|
1023
166
|
}
|
|
167
|
+
return encryption.decrypt(value, key);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/cookies/client.ts
|
|
171
|
+
var CookieClient = class {
|
|
1024
172
|
/**
|
|
1025
|
-
*
|
|
1026
|
-
* unless `overwrite` flag is set to true.
|
|
173
|
+
* Private encryption instance used for signing and encrypting cookies
|
|
1027
174
|
*/
|
|
1028
|
-
|
|
1029
|
-
if (this.#routeDomain === "root" || overwrite) {
|
|
1030
|
-
this.#routeDomain = domain;
|
|
1031
|
-
}
|
|
1032
|
-
return this;
|
|
1033
|
-
}
|
|
175
|
+
#encryption;
|
|
1034
176
|
/**
|
|
1035
|
-
*
|
|
1036
|
-
* handler.
|
|
177
|
+
* Create a new instance of CookieClient
|
|
1037
178
|
*
|
|
1038
|
-
*
|
|
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
|
|
179
|
+
* @param encryption - The encryption instance for cookie operations
|
|
1047
180
|
*/
|
|
1048
|
-
|
|
1049
|
-
|
|
181
|
+
constructor(encryption) {
|
|
182
|
+
this.#encryption = encryption;
|
|
1050
183
|
}
|
|
1051
184
|
/**
|
|
1052
|
-
*
|
|
1053
|
-
* existing name of the route.
|
|
185
|
+
* Encrypt a key value pair to be sent in the cookie header
|
|
1054
186
|
*
|
|
1055
|
-
*
|
|
1056
|
-
|
|
1057
|
-
|
|
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
|
|
187
|
+
* @param key - The cookie key
|
|
188
|
+
* @param value - The value to encrypt
|
|
189
|
+
* @returns The encrypted cookie string or null if encryption fails
|
|
1079
190
|
*/
|
|
1080
|
-
|
|
1081
|
-
this.#
|
|
191
|
+
encrypt(key, value) {
|
|
192
|
+
return pack3(key, value, this.#encryption);
|
|
1082
193
|
}
|
|
1083
194
|
/**
|
|
1084
|
-
*
|
|
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
|
|
1085
200
|
*/
|
|
1086
|
-
|
|
1087
|
-
return this.#
|
|
201
|
+
sign(key, value) {
|
|
202
|
+
return pack2(key, value, this.#encryption);
|
|
1088
203
|
}
|
|
1089
204
|
/**
|
|
1090
|
-
*
|
|
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
|
|
1091
211
|
*/
|
|
1092
|
-
|
|
1093
|
-
return
|
|
212
|
+
encode(_, value, stringify2 = true) {
|
|
213
|
+
return stringify2 ? pack(value) : value;
|
|
1094
214
|
}
|
|
1095
215
|
/**
|
|
1096
|
-
*
|
|
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
|
|
1097
221
|
*/
|
|
1098
|
-
|
|
1099
|
-
this.#
|
|
1100
|
-
return this;
|
|
222
|
+
unsign(key, value) {
|
|
223
|
+
return canUnpack2(value) ? unpack2(key, value, this.#encryption) : null;
|
|
1101
224
|
}
|
|
1102
225
|
/**
|
|
1103
|
-
*
|
|
1104
|
-
*
|
|
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
|
|
1105
231
|
*/
|
|
1106
|
-
|
|
1107
|
-
return this.#
|
|
232
|
+
decrypt(key, value) {
|
|
233
|
+
return canUnpack3(value) ? unpack3(key, value, this.#encryption) : null;
|
|
1108
234
|
}
|
|
1109
235
|
/**
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
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
|
|
1112
242
|
*/
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
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;
|
|
243
|
+
decode(_, value, stringified = true) {
|
|
244
|
+
if (!stringified) {
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
return canUnpack(value) ? unpack(value) : null;
|
|
1125
248
|
}
|
|
1126
249
|
/**
|
|
1127
|
-
*
|
|
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
|
+
* ```
|
|
1128
265
|
*/
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
handler: this.#handler,
|
|
1140
|
-
methods: this.#methods,
|
|
1141
|
-
middleware: this.#getMiddlewareForStore(),
|
|
1142
|
-
execute
|
|
1143
|
-
};
|
|
266
|
+
parse(key, value) {
|
|
267
|
+
if (canUnpack2(value)) {
|
|
268
|
+
return unpack2(key, value, this.#encryption);
|
|
269
|
+
}
|
|
270
|
+
if (canUnpack3(value)) {
|
|
271
|
+
return unpack3(key, value, this.#encryption);
|
|
272
|
+
}
|
|
273
|
+
if (canUnpack(value)) {
|
|
274
|
+
return unpack(value);
|
|
275
|
+
}
|
|
1144
276
|
}
|
|
1145
277
|
};
|
|
1146
278
|
|
|
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,13 +2854,13 @@ var Response = class extends Macroable6 {
|
|
|
3365
2854
|
};
|
|
3366
2855
|
|
|
3367
2856
|
// src/router/main.ts
|
|
3368
|
-
import
|
|
3369
|
-
import { moduleImporter as
|
|
3370
|
-
import { RuntimeException as
|
|
2857
|
+
import is2 from "@sindresorhus/is";
|
|
2858
|
+
import { moduleImporter as moduleImporter2 } from "@adonisjs/fold";
|
|
2859
|
+
import { RuntimeException as RuntimeException3 } from "@poppinss/utils/exception";
|
|
3371
2860
|
|
|
3372
2861
|
// src/router/store.ts
|
|
3373
2862
|
import matchit from "@poppinss/matchit";
|
|
3374
|
-
import { RuntimeException as
|
|
2863
|
+
import { RuntimeException as RuntimeException2 } from "@poppinss/utils/exception";
|
|
3375
2864
|
var RoutesStore = class {
|
|
3376
2865
|
/**
|
|
3377
2866
|
* A flag to know if routes for explicit domains
|
|
@@ -3410,7 +2899,7 @@ var RoutesStore = class {
|
|
|
3410
2899
|
for (let token of tokens) {
|
|
3411
2900
|
if ([1, 3].includes(token.type)) {
|
|
3412
2901
|
if (collectedParams.has(token.val)) {
|
|
3413
|
-
throw new
|
|
2902
|
+
throw new RuntimeException2(`Duplicate param "${token.val}" found in "${route.pattern}"`);
|
|
3414
2903
|
} else {
|
|
3415
2904
|
collectedParams.add(token.val);
|
|
3416
2905
|
}
|
|
@@ -3426,7 +2915,7 @@ var RoutesStore = class {
|
|
|
3426
2915
|
#registerRoute(domain, method, tokens, route) {
|
|
3427
2916
|
const methodRoutes = this.#getMethodNode(domain, method);
|
|
3428
2917
|
if (methodRoutes.routes[route.pattern]) {
|
|
3429
|
-
throw new
|
|
2918
|
+
throw new RuntimeException2(
|
|
3430
2919
|
`Duplicate route found. "${method}: ${route.pattern}" route already exists`
|
|
3431
2920
|
);
|
|
3432
2921
|
}
|
|
@@ -3451,6 +2940,8 @@ var RoutesStore = class {
|
|
|
3451
2940
|
* }
|
|
3452
2941
|
* })
|
|
3453
2942
|
* ```
|
|
2943
|
+
* @param route - The route to add to the store
|
|
2944
|
+
* @returns Current RoutesStore instance for method chaining
|
|
3454
2945
|
*/
|
|
3455
2946
|
add(route) {
|
|
3456
2947
|
if (route.domain !== "root") {
|
|
@@ -3471,6 +2962,11 @@ var RoutesStore = class {
|
|
|
3471
2962
|
* The domain parameter has to be a registered pattern and not the fully
|
|
3472
2963
|
* qualified runtime domain. You must call `matchDomain` first to fetch
|
|
3473
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
|
|
3474
2970
|
*/
|
|
3475
2971
|
match(url, method, shouldDecodeParam, domain) {
|
|
3476
2972
|
const domainName = domain?.tokens[0]?.old || "root";
|
|
@@ -3496,6 +2992,8 @@ var RoutesStore = class {
|
|
|
3496
2992
|
}
|
|
3497
2993
|
/**
|
|
3498
2994
|
* Match hostname against registered domains.
|
|
2995
|
+
* @param hostname - The hostname to match
|
|
2996
|
+
* @returns Array of matched domain tokens
|
|
3499
2997
|
*/
|
|
3500
2998
|
matchDomain(hostname) {
|
|
3501
2999
|
if (!hostname || !this.usingDomains) {
|
|
@@ -3528,15 +3026,22 @@ var UrlBuilder = class {
|
|
|
3528
3026
|
* Route finder for finding route pattern
|
|
3529
3027
|
*/
|
|
3530
3028
|
#router;
|
|
3029
|
+
/**
|
|
3030
|
+
* Domain to use for URL generation
|
|
3031
|
+
*/
|
|
3531
3032
|
#domain;
|
|
3033
|
+
/**
|
|
3034
|
+
* Creates a new UrlBuilder instance
|
|
3035
|
+
* @param router - The router instance
|
|
3036
|
+
* @param domain - Optional domain for URL generation
|
|
3037
|
+
*/
|
|
3532
3038
|
constructor(router, domain) {
|
|
3533
3039
|
this.#router = router;
|
|
3534
3040
|
this.#domain = domain;
|
|
3535
3041
|
}
|
|
3536
3042
|
/**
|
|
3537
3043
|
* Prefix a custom base URL to the final URI
|
|
3538
|
-
* @deprecated
|
|
3539
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3044
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3540
3045
|
*/
|
|
3541
3046
|
prefixUrl(url) {
|
|
3542
3047
|
this.#baseUrl = url;
|
|
@@ -3545,8 +3050,7 @@ var UrlBuilder = class {
|
|
|
3545
3050
|
/**
|
|
3546
3051
|
* Disable route lookup. Calling this method considers
|
|
3547
3052
|
* the "identifier" as the route pattern
|
|
3548
|
-
* @deprecated
|
|
3549
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3053
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3550
3054
|
*/
|
|
3551
3055
|
disableRouteLookup() {
|
|
3552
3056
|
this.#shouldPerformLookup = false;
|
|
@@ -3554,8 +3058,7 @@ var UrlBuilder = class {
|
|
|
3554
3058
|
}
|
|
3555
3059
|
/**
|
|
3556
3060
|
* Append query string to the final URI
|
|
3557
|
-
* @deprecated
|
|
3558
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3061
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3559
3062
|
*/
|
|
3560
3063
|
qs(queryString) {
|
|
3561
3064
|
if (!queryString) {
|
|
@@ -3566,8 +3069,7 @@ var UrlBuilder = class {
|
|
|
3566
3069
|
}
|
|
3567
3070
|
/**
|
|
3568
3071
|
* Specify params to apply to the route pattern
|
|
3569
|
-
* @deprecated
|
|
3570
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3072
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3571
3073
|
*/
|
|
3572
3074
|
params(params) {
|
|
3573
3075
|
if (!params) {
|
|
@@ -3581,8 +3083,9 @@ var UrlBuilder = class {
|
|
|
3581
3083
|
* route name, controller.method name or the route pattern
|
|
3582
3084
|
* itself.
|
|
3583
3085
|
*
|
|
3584
|
-
* @deprecated
|
|
3585
|
-
*
|
|
3086
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3087
|
+
* @param identifier - Route identifier to generate URL for
|
|
3088
|
+
* @returns Generated URL string
|
|
3586
3089
|
*/
|
|
3587
3090
|
make(identifier) {
|
|
3588
3091
|
return this.#router.makeUrl(identifier, this.#params, {
|
|
@@ -3597,8 +3100,7 @@ var UrlBuilder = class {
|
|
|
3597
3100
|
* route name, controller.method name or the route pattern
|
|
3598
3101
|
* itself.
|
|
3599
3102
|
*
|
|
3600
|
-
* @deprecated
|
|
3601
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3103
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
3602
3104
|
*
|
|
3603
3105
|
*/
|
|
3604
3106
|
makeSigned(identifier, options) {
|
|
@@ -3613,17 +3115,19 @@ var UrlBuilder = class {
|
|
|
3613
3115
|
};
|
|
3614
3116
|
|
|
3615
3117
|
// src/router/matchers.ts
|
|
3616
|
-
import
|
|
3617
|
-
var RouteMatchers = class extends
|
|
3118
|
+
import Macroable3 from "@poppinss/macroable";
|
|
3119
|
+
var RouteMatchers = class extends Macroable3 {
|
|
3618
3120
|
/**
|
|
3619
3121
|
* Enforce value to be a number and also casts it to number data
|
|
3620
3122
|
* type
|
|
3123
|
+
* @returns Route matcher configuration for numeric values
|
|
3621
3124
|
*/
|
|
3622
3125
|
number() {
|
|
3623
3126
|
return { match: /^[0-9]+$/, cast: (value) => Number(value) };
|
|
3624
3127
|
}
|
|
3625
3128
|
/**
|
|
3626
3129
|
* Enforce value to be formatted as uuid
|
|
3130
|
+
* @returns Route matcher configuration for UUID values
|
|
3627
3131
|
*/
|
|
3628
3132
|
uuid() {
|
|
3629
3133
|
return {
|
|
@@ -3633,137 +3137,17 @@ var RouteMatchers = class extends Macroable7 {
|
|
|
3633
3137
|
}
|
|
3634
3138
|
/**
|
|
3635
3139
|
* Enforce value to be formatted as slug
|
|
3140
|
+
* @returns Route matcher configuration for slug values
|
|
3636
3141
|
*/
|
|
3637
3142
|
slug() {
|
|
3638
3143
|
return { match: /^[^\s-_](?!.*?[-_]{2,})([a-z0-9-\\]{1,})[^\s]*[^-_\s]$/ };
|
|
3639
3144
|
}
|
|
3640
3145
|
};
|
|
3641
3146
|
|
|
3642
|
-
// src/router/url_builder.ts
|
|
3643
|
-
function createURL(identifier, tokens, searchParamsStringifier, params, options) {
|
|
3644
|
-
const uriSegments = [];
|
|
3645
|
-
const paramsArray = Array.isArray(params) ? params : null;
|
|
3646
|
-
const paramsObject = !Array.isArray(params) ? params ?? {} : {};
|
|
3647
|
-
let paramsIndex = 0;
|
|
3648
|
-
for (const token of tokens) {
|
|
3649
|
-
if (token.type === 0) {
|
|
3650
|
-
uriSegments.push(token.val === "/" ? "" : `${token.val}${token.end}`);
|
|
3651
|
-
continue;
|
|
3652
|
-
}
|
|
3653
|
-
if (token.type === 2) {
|
|
3654
|
-
const values = paramsArray ? paramsArray.slice(paramsIndex) : paramsObject["*"];
|
|
3655
|
-
if (!Array.isArray(values) || !values.length) {
|
|
3656
|
-
throw new Error(
|
|
3657
|
-
`Cannot make URL for "${identifier}". Invalid value provided for the wildcard param`
|
|
3658
|
-
);
|
|
3659
|
-
}
|
|
3660
|
-
uriSegments.push(`${values.join("/")}${token.end}`);
|
|
3661
|
-
break;
|
|
3662
|
-
}
|
|
3663
|
-
const paramName = token.val;
|
|
3664
|
-
const value = paramsArray ? paramsArray[paramsIndex] : paramsObject[paramName];
|
|
3665
|
-
const isDefined = value !== void 0 && value !== null;
|
|
3666
|
-
if (token.type === 1 && !isDefined) {
|
|
3667
|
-
throw new Error(
|
|
3668
|
-
`Cannot make URL for "${identifier}". Missing value for the "${paramName}" param`
|
|
3669
|
-
);
|
|
3670
|
-
}
|
|
3671
|
-
if (isDefined) {
|
|
3672
|
-
uriSegments.push(`${value}${token.end}`);
|
|
3673
|
-
}
|
|
3674
|
-
paramsIndex++;
|
|
3675
|
-
}
|
|
3676
|
-
let URI = `/${uriSegments.join("/")}`;
|
|
3677
|
-
if (options?.prefixUrl) {
|
|
3678
|
-
URI = `${options?.prefixUrl.replace(/\/$/, "")}${URI}`;
|
|
3679
|
-
}
|
|
3680
|
-
if (options?.qs) {
|
|
3681
|
-
const queryString = searchParamsStringifier(options?.qs);
|
|
3682
|
-
URI = queryString ? `${URI}?${queryString}` : URI;
|
|
3683
|
-
}
|
|
3684
|
-
return URI;
|
|
3685
|
-
}
|
|
3686
|
-
function createUrlBuilder(router, searchParamsStringifier) {
|
|
3687
|
-
let domainsList;
|
|
3688
|
-
function createUrlForRoute(identifier, params, options, method) {
|
|
3689
|
-
if (!domainsList) {
|
|
3690
|
-
domainsList = Object.keys(router.toJSON()).filter((domain2) => domain2 !== "root");
|
|
3691
|
-
}
|
|
3692
|
-
const domain = domainsList.find((name) => identifier.startsWith(`${name}@`));
|
|
3693
|
-
const routeIdentifier = domain ? identifier.replace(new RegExp(`^${domain}@`), "") : identifier;
|
|
3694
|
-
const route = router.findOrFail(routeIdentifier, domain, method, true);
|
|
3695
|
-
return createURL(
|
|
3696
|
-
route.name ?? route.pattern,
|
|
3697
|
-
route.tokens,
|
|
3698
|
-
searchParamsStringifier,
|
|
3699
|
-
params,
|
|
3700
|
-
options
|
|
3701
|
-
);
|
|
3702
|
-
}
|
|
3703
|
-
const urlFor = function route(...[identifier, params, options]) {
|
|
3704
|
-
return createUrlForRoute(identifier, params, options);
|
|
3705
|
-
};
|
|
3706
|
-
urlFor.get = function urlForMethodGet(...[identifier, params, options]) {
|
|
3707
|
-
return {
|
|
3708
|
-
url: createUrlForRoute(identifier, params, options, "GET"),
|
|
3709
|
-
method: "get",
|
|
3710
|
-
toString() {
|
|
3711
|
-
return this.url;
|
|
3712
|
-
}
|
|
3713
|
-
};
|
|
3714
|
-
};
|
|
3715
|
-
urlFor.post = function urlForMethodPost(...[identifier, params, options]) {
|
|
3716
|
-
return {
|
|
3717
|
-
url: createUrlForRoute(identifier, params, options, "POST"),
|
|
3718
|
-
method: "post",
|
|
3719
|
-
toString() {
|
|
3720
|
-
return this.url;
|
|
3721
|
-
}
|
|
3722
|
-
};
|
|
3723
|
-
};
|
|
3724
|
-
urlFor.put = function urlForMethodPut(...[identifier, params, options]) {
|
|
3725
|
-
return {
|
|
3726
|
-
url: createUrlForRoute(identifier, params, options, "PUT"),
|
|
3727
|
-
method: "put",
|
|
3728
|
-
toString() {
|
|
3729
|
-
return this.url;
|
|
3730
|
-
}
|
|
3731
|
-
};
|
|
3732
|
-
};
|
|
3733
|
-
urlFor.patch = function urlForMethodPatch(...[identifier, params, options]) {
|
|
3734
|
-
return {
|
|
3735
|
-
url: createUrlForRoute(identifier, params, options, "PATCH"),
|
|
3736
|
-
method: "patch",
|
|
3737
|
-
toString() {
|
|
3738
|
-
return this.url;
|
|
3739
|
-
}
|
|
3740
|
-
};
|
|
3741
|
-
};
|
|
3742
|
-
urlFor.delete = function urlForMethodDelete(...[identifier, params, options]) {
|
|
3743
|
-
return {
|
|
3744
|
-
url: createUrlForRoute(identifier, params, options, "DELETE"),
|
|
3745
|
-
method: "delete",
|
|
3746
|
-
toString() {
|
|
3747
|
-
return this.url;
|
|
3748
|
-
}
|
|
3749
|
-
};
|
|
3750
|
-
};
|
|
3751
|
-
urlFor.method = function urlForCustomMethod(method, ...[identifier, params, options]) {
|
|
3752
|
-
return {
|
|
3753
|
-
url: createUrlForRoute(identifier, params, options, method),
|
|
3754
|
-
method,
|
|
3755
|
-
toString() {
|
|
3756
|
-
return this.url;
|
|
3757
|
-
}
|
|
3758
|
-
};
|
|
3759
|
-
};
|
|
3760
|
-
return urlFor;
|
|
3761
|
-
}
|
|
3762
|
-
|
|
3763
3147
|
// src/define_middleware.ts
|
|
3764
|
-
import { moduleImporter
|
|
3148
|
+
import { moduleImporter } from "@adonisjs/fold";
|
|
3765
3149
|
function middlewareReferenceBuilder(name, middleware) {
|
|
3766
|
-
const handler =
|
|
3150
|
+
const handler = moduleImporter(middleware, "handle").toHandleMethod();
|
|
3767
3151
|
return function(...args) {
|
|
3768
3152
|
return {
|
|
3769
3153
|
...handler,
|
|
@@ -3784,20 +3168,6 @@ function defineNamedMiddleware(collection) {
|
|
|
3784
3168
|
}
|
|
3785
3169
|
|
|
3786
3170
|
// src/router/signed_url_builder.ts
|
|
3787
|
-
function createSignedURL(identifier, tokens, searchParamsStringifier, encryption, params, options) {
|
|
3788
|
-
const signature = encryption.verifier.sign(
|
|
3789
|
-
createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
3790
|
-
...options,
|
|
3791
|
-
prefixUrl: void 0
|
|
3792
|
-
}),
|
|
3793
|
-
options?.expiresIn,
|
|
3794
|
-
options?.purpose
|
|
3795
|
-
);
|
|
3796
|
-
return createURL(identifier, tokens, searchParamsStringifier, params, {
|
|
3797
|
-
...options,
|
|
3798
|
-
qs: { ...options?.qs, signature }
|
|
3799
|
-
});
|
|
3800
|
-
}
|
|
3801
3171
|
function createSignedUrlBuilder(router, encryption, searchParamsStringifier) {
|
|
3802
3172
|
let domainsList;
|
|
3803
3173
|
function createSignedUrlForRoute(identifier, params, options, method) {
|
|
@@ -3820,56 +3190,91 @@ function createSignedUrlBuilder(router, encryption, searchParamsStringifier) {
|
|
|
3820
3190
|
return createSignedUrlForRoute(identifier, params, options);
|
|
3821
3191
|
};
|
|
3822
3192
|
signedRoute.get = function routeGet(...[identifier, params, options]) {
|
|
3193
|
+
const method = "GET";
|
|
3194
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3823
3195
|
return {
|
|
3824
|
-
url
|
|
3825
|
-
method
|
|
3196
|
+
url,
|
|
3197
|
+
method,
|
|
3826
3198
|
toString() {
|
|
3827
|
-
return
|
|
3199
|
+
return url;
|
|
3200
|
+
},
|
|
3201
|
+
form: {
|
|
3202
|
+
action: url,
|
|
3203
|
+
method
|
|
3828
3204
|
}
|
|
3829
3205
|
};
|
|
3830
3206
|
};
|
|
3831
3207
|
signedRoute.post = function routePost(...[identifier, params, options]) {
|
|
3208
|
+
const method = "POST";
|
|
3209
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3832
3210
|
return {
|
|
3833
|
-
url
|
|
3834
|
-
method
|
|
3211
|
+
url,
|
|
3212
|
+
method,
|
|
3835
3213
|
toString() {
|
|
3836
|
-
return
|
|
3214
|
+
return url;
|
|
3215
|
+
},
|
|
3216
|
+
form: {
|
|
3217
|
+
action: url,
|
|
3218
|
+
method
|
|
3837
3219
|
}
|
|
3838
3220
|
};
|
|
3839
3221
|
};
|
|
3840
3222
|
signedRoute.put = function routePut(...[identifier, params, options]) {
|
|
3223
|
+
const method = "PUT";
|
|
3224
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3841
3225
|
return {
|
|
3842
|
-
url
|
|
3843
|
-
method
|
|
3226
|
+
url,
|
|
3227
|
+
method,
|
|
3844
3228
|
toString() {
|
|
3845
|
-
return
|
|
3229
|
+
return url;
|
|
3230
|
+
},
|
|
3231
|
+
form: {
|
|
3232
|
+
action: url,
|
|
3233
|
+
method
|
|
3846
3234
|
}
|
|
3847
3235
|
};
|
|
3848
3236
|
};
|
|
3849
3237
|
signedRoute.patch = function routePatch(...[identifier, params, options]) {
|
|
3238
|
+
const method = "PATCH";
|
|
3239
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3850
3240
|
return {
|
|
3851
|
-
url
|
|
3852
|
-
method
|
|
3241
|
+
url,
|
|
3242
|
+
method,
|
|
3853
3243
|
toString() {
|
|
3854
|
-
return
|
|
3244
|
+
return url;
|
|
3245
|
+
},
|
|
3246
|
+
form: {
|
|
3247
|
+
action: url,
|
|
3248
|
+
method
|
|
3855
3249
|
}
|
|
3856
3250
|
};
|
|
3857
3251
|
};
|
|
3858
3252
|
signedRoute.delete = function routeDelete(...[identifier, params, options]) {
|
|
3253
|
+
const method = "DELETE";
|
|
3254
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3859
3255
|
return {
|
|
3860
|
-
url
|
|
3861
|
-
method
|
|
3256
|
+
url,
|
|
3257
|
+
method,
|
|
3862
3258
|
toString() {
|
|
3863
|
-
return
|
|
3259
|
+
return url;
|
|
3260
|
+
},
|
|
3261
|
+
form: {
|
|
3262
|
+
action: url,
|
|
3263
|
+
method
|
|
3864
3264
|
}
|
|
3865
3265
|
};
|
|
3866
3266
|
};
|
|
3867
3267
|
signedRoute.method = function routeGet(method, ...[identifier, params, options]) {
|
|
3268
|
+
const url = createSignedUrlForRoute(identifier, params, options, method);
|
|
3868
3269
|
return {
|
|
3869
|
-
url
|
|
3270
|
+
url,
|
|
3870
3271
|
method,
|
|
3871
3272
|
toString() {
|
|
3872
|
-
return
|
|
3273
|
+
return url;
|
|
3274
|
+
},
|
|
3275
|
+
form: {
|
|
3276
|
+
action: url,
|
|
3277
|
+
method
|
|
3873
3278
|
}
|
|
3874
3279
|
};
|
|
3875
3280
|
};
|
|
@@ -3945,12 +3350,18 @@ var Router = class {
|
|
|
3945
3350
|
* List of route references kept for lookup.
|
|
3946
3351
|
*/
|
|
3947
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
|
+
*/
|
|
3948
3359
|
constructor(app, encryption, qsParser) {
|
|
3949
3360
|
this.#app = app;
|
|
3950
3361
|
this.#encryption = encryption;
|
|
3951
3362
|
this.qs = qsParser;
|
|
3952
3363
|
this.urlBuilder = {
|
|
3953
|
-
urlFor: createUrlBuilder(this, this.qs.stringify),
|
|
3364
|
+
urlFor: createUrlBuilder(() => this.toJSON(), this.qs.stringify),
|
|
3954
3365
|
signedUrlFor: createSignedUrlBuilder(this, this.#encryption, this.qs.stringify)
|
|
3955
3366
|
};
|
|
3956
3367
|
}
|
|
@@ -3975,6 +3386,8 @@ var Router = class {
|
|
|
3975
3386
|
}
|
|
3976
3387
|
/**
|
|
3977
3388
|
* Parses the route pattern
|
|
3389
|
+
* @param pattern - The route pattern to parse
|
|
3390
|
+
* @param matchers - Optional route matchers
|
|
3978
3391
|
*/
|
|
3979
3392
|
parsePattern(pattern, matchers) {
|
|
3980
3393
|
return parseRoute(pattern, matchers);
|
|
@@ -3983,12 +3396,14 @@ var Router = class {
|
|
|
3983
3396
|
* Define an array of middleware to use on all the routes.
|
|
3984
3397
|
* Calling this method multiple times pushes to the
|
|
3985
3398
|
* existing list of middleware
|
|
3399
|
+
* @param middleware - Array of middleware classes to apply globally
|
|
3400
|
+
* @returns Current Router instance for method chaining
|
|
3986
3401
|
*/
|
|
3987
3402
|
use(middleware) {
|
|
3988
3403
|
middleware.forEach(
|
|
3989
3404
|
(one) => this.#middleware.push({
|
|
3990
3405
|
reference: one,
|
|
3991
|
-
...
|
|
3406
|
+
...moduleImporter2(one, "handle").toHandleMethod()
|
|
3992
3407
|
})
|
|
3993
3408
|
);
|
|
3994
3409
|
return this;
|
|
@@ -3997,12 +3412,18 @@ var Router = class {
|
|
|
3997
3412
|
* Define a collection of named middleware. The defined collection is
|
|
3998
3413
|
* not registered anywhere, but instead converted in a new collection
|
|
3999
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
|
|
4000
3417
|
*/
|
|
4001
3418
|
named(collection) {
|
|
4002
3419
|
return defineNamedMiddleware(collection);
|
|
4003
3420
|
}
|
|
4004
3421
|
/**
|
|
4005
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
|
|
4006
3427
|
*/
|
|
4007
3428
|
route(pattern, methods, handler) {
|
|
4008
3429
|
const route = new Route(this.#app, this.#middleware, {
|
|
@@ -4016,6 +3437,9 @@ var Router = class {
|
|
|
4016
3437
|
}
|
|
4017
3438
|
/**
|
|
4018
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
|
|
4019
3443
|
*/
|
|
4020
3444
|
any(pattern, handler) {
|
|
4021
3445
|
return this.route(
|
|
@@ -4026,30 +3450,45 @@ var Router = class {
|
|
|
4026
3450
|
}
|
|
4027
3451
|
/**
|
|
4028
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
|
|
4029
3456
|
*/
|
|
4030
3457
|
get(pattern, handler) {
|
|
4031
3458
|
return this.route(pattern, ["GET", "HEAD"], handler);
|
|
4032
3459
|
}
|
|
4033
3460
|
/**
|
|
4034
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
|
|
4035
3465
|
*/
|
|
4036
3466
|
post(pattern, handler) {
|
|
4037
3467
|
return this.route(pattern, ["POST"], handler);
|
|
4038
3468
|
}
|
|
4039
3469
|
/**
|
|
4040
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
|
|
4041
3474
|
*/
|
|
4042
3475
|
put(pattern, handler) {
|
|
4043
3476
|
return this.route(pattern, ["PUT"], handler);
|
|
4044
3477
|
}
|
|
4045
3478
|
/**
|
|
4046
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
|
|
4047
3483
|
*/
|
|
4048
3484
|
patch(pattern, handler) {
|
|
4049
3485
|
return this.route(pattern, ["PATCH"], handler);
|
|
4050
3486
|
}
|
|
4051
3487
|
/**
|
|
4052
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
|
|
4053
3492
|
*/
|
|
4054
3493
|
delete(pattern, handler) {
|
|
4055
3494
|
return this.route(pattern, ["DELETE"], handler);
|
|
@@ -4057,6 +3496,8 @@ var Router = class {
|
|
|
4057
3496
|
/**
|
|
4058
3497
|
* Creates a group of routes. A route group can apply transforms
|
|
4059
3498
|
* to routes in bulk
|
|
3499
|
+
* @param callback - Function that defines routes within the group
|
|
3500
|
+
* @returns The created route group instance
|
|
4060
3501
|
*/
|
|
4061
3502
|
group(callback) {
|
|
4062
3503
|
const group = new RouteGroup([]);
|
|
@@ -4068,6 +3509,9 @@ var Router = class {
|
|
|
4068
3509
|
}
|
|
4069
3510
|
/**
|
|
4070
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
|
|
4071
3515
|
*/
|
|
4072
3516
|
resource(resource, controller) {
|
|
4073
3517
|
const resourceInstance = new RouteResource(this.#app, this.#middleware, {
|
|
@@ -4081,6 +3525,9 @@ var Router = class {
|
|
|
4081
3525
|
}
|
|
4082
3526
|
/**
|
|
4083
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
|
|
4084
3531
|
*/
|
|
4085
3532
|
shallowResource(resource, controller) {
|
|
4086
3533
|
const resourceInstance = new RouteResource(this.#app, this.#middleware, {
|
|
@@ -4094,6 +3541,8 @@ var Router = class {
|
|
|
4094
3541
|
}
|
|
4095
3542
|
/**
|
|
4096
3543
|
* Returns a brisk route instance for a given URL pattern
|
|
3544
|
+
* @param pattern - The route pattern
|
|
3545
|
+
* @returns The created brisk route instance
|
|
4097
3546
|
*/
|
|
4098
3547
|
on(pattern) {
|
|
4099
3548
|
const briskRoute = new BriskRoute(this.#app, this.#middleware, {
|
|
@@ -4106,11 +3555,14 @@ var Router = class {
|
|
|
4106
3555
|
/**
|
|
4107
3556
|
* Define matcher for a given param. The global params are applied
|
|
4108
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
|
|
4109
3561
|
*/
|
|
4110
3562
|
where(param, matcher) {
|
|
4111
3563
|
if (typeof matcher === "string") {
|
|
4112
3564
|
this.#globalMatchers[param] = { match: new RegExp(matcher) };
|
|
4113
|
-
} else if (
|
|
3565
|
+
} else if (is2.regExp(matcher)) {
|
|
4114
3566
|
this.#globalMatchers[param] = { match: matcher };
|
|
4115
3567
|
} else {
|
|
4116
3568
|
this.#globalMatchers[param] = matcher;
|
|
@@ -4133,8 +3585,8 @@ var Router = class {
|
|
|
4133
3585
|
}
|
|
4134
3586
|
const routeNames = routeNamesByDomain.get(route.domain);
|
|
4135
3587
|
if (route.name && routeNames.has(route.name)) {
|
|
4136
|
-
throw new
|
|
4137
|
-
`
|
|
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`
|
|
4138
3590
|
);
|
|
4139
3591
|
}
|
|
4140
3592
|
if (route.name) {
|
|
@@ -4151,58 +3603,21 @@ var Router = class {
|
|
|
4151
3603
|
this.#openedGroups = [];
|
|
4152
3604
|
this.#commited = true;
|
|
4153
3605
|
}
|
|
4154
|
-
/**
|
|
4155
|
-
* The lookup strategies to follow when generating URL builder
|
|
4156
|
-
* types and client
|
|
4157
|
-
*/
|
|
4158
|
-
lookupStrategies = ["name", "pattern"];
|
|
4159
|
-
/**
|
|
4160
|
-
* Define the lookup strategies to follow when generating URL builder
|
|
4161
|
-
* types and client.
|
|
4162
|
-
*/
|
|
4163
|
-
updateLookupStrategies(strategies) {
|
|
4164
|
-
this.lookupStrategies = strategies;
|
|
4165
|
-
return this;
|
|
4166
|
-
}
|
|
4167
3606
|
/**
|
|
4168
3607
|
* Finds a route by its identifier. The identifier can be the
|
|
4169
3608
|
* route name, controller.method name or the route pattern
|
|
4170
3609
|
* itself.
|
|
4171
3610
|
*
|
|
4172
|
-
* When "
|
|
4173
|
-
*
|
|
4174
|
-
*
|
|
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
|
|
4175
3618
|
*/
|
|
4176
|
-
find(routeIdentifier, domain, method,
|
|
4177
|
-
|
|
4178
|
-
let route = null;
|
|
4179
|
-
for (const routeDomain of Object.keys(this.routes)) {
|
|
4180
|
-
route = this.find(routeIdentifier, routeDomain, method, followLookupStrategy);
|
|
4181
|
-
if (route) {
|
|
4182
|
-
break;
|
|
4183
|
-
}
|
|
4184
|
-
}
|
|
4185
|
-
return route;
|
|
4186
|
-
}
|
|
4187
|
-
const routes = this.routes[domain];
|
|
4188
|
-
if (!routes) {
|
|
4189
|
-
return null;
|
|
4190
|
-
}
|
|
4191
|
-
const lookupByName = !followLookupStrategy || this.lookupStrategies.includes("name");
|
|
4192
|
-
const lookupByPattern = !followLookupStrategy || this.lookupStrategies.includes("pattern");
|
|
4193
|
-
const lookupByController = !followLookupStrategy || this.lookupStrategies.includes("controller");
|
|
4194
|
-
return routes.find((route) => {
|
|
4195
|
-
if (method && !route.methods.includes(method)) {
|
|
4196
|
-
return false;
|
|
4197
|
-
}
|
|
4198
|
-
if (route.name === routeIdentifier && lookupByName || route.pattern === routeIdentifier && lookupByPattern) {
|
|
4199
|
-
return true;
|
|
4200
|
-
}
|
|
4201
|
-
if (typeof route.handler === "function" || !lookupByController) {
|
|
4202
|
-
return false;
|
|
4203
|
-
}
|
|
4204
|
-
return route.handler.reference === routeIdentifier;
|
|
4205
|
-
}) || null;
|
|
3619
|
+
find(routeIdentifier, domain, method, disableLegacyLookup) {
|
|
3620
|
+
return findRoute(this.routes, routeIdentifier, domain, method, disableLegacyLookup);
|
|
4206
3621
|
}
|
|
4207
3622
|
/**
|
|
4208
3623
|
* Finds a route by its identifier. The identifier can be the
|
|
@@ -4211,12 +3626,17 @@ var Router = class {
|
|
|
4211
3626
|
*
|
|
4212
3627
|
* An error is raised when unable to find the route.
|
|
4213
3628
|
*
|
|
4214
|
-
* When "
|
|
4215
|
-
*
|
|
4216
|
-
*
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
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);
|
|
4220
3640
|
if (!route) {
|
|
4221
3641
|
throw new Error(`Cannot lookup route "${routeIdentifier}"`);
|
|
4222
3642
|
}
|
|
@@ -4230,12 +3650,18 @@ var Router = class {
|
|
|
4230
3650
|
* When "followLookupStrategy" is enabled, the lookup will be performed
|
|
4231
3651
|
* on the basis of the lookup strategy enabled via the "lookupStrategies"
|
|
4232
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
|
|
4233
3658
|
*/
|
|
4234
3659
|
has(routeIdentifier, domain, method, followLookupStrategy) {
|
|
4235
3660
|
return !!this.find(routeIdentifier, domain, method, followLookupStrategy);
|
|
4236
3661
|
}
|
|
4237
3662
|
/**
|
|
4238
3663
|
* Returns a list of routes grouped by their domain names
|
|
3664
|
+
* @returns Object mapping domain names to route arrays
|
|
4239
3665
|
*/
|
|
4240
3666
|
toJSON() {
|
|
4241
3667
|
return this.routes;
|
|
@@ -4244,6 +3670,8 @@ var Router = class {
|
|
|
4244
3670
|
* Generates types for the URL builder. These types must
|
|
4245
3671
|
* be written inside a file for the URL builder to
|
|
4246
3672
|
* pick them up.
|
|
3673
|
+
* @param indentation - Indentation level for generated types
|
|
3674
|
+
* @returns Generated TypeScript types as string
|
|
4247
3675
|
*/
|
|
4248
3676
|
generateTypes(indentation = 0) {
|
|
4249
3677
|
const routesList = {};
|
|
@@ -4270,21 +3698,11 @@ var Router = class {
|
|
|
4270
3698
|
routesList["ALL"] = routesList["ALL"] ?? {};
|
|
4271
3699
|
routesList[method] = routesList[method] ?? {};
|
|
4272
3700
|
const identifiers = [];
|
|
4273
|
-
if (
|
|
4274
|
-
if (!routesList[method][route.pattern]) {
|
|
4275
|
-
identifiers.push(route.pattern);
|
|
4276
|
-
}
|
|
4277
|
-
}
|
|
4278
|
-
if (this.lookupStrategies.includes("name") && route.name) {
|
|
3701
|
+
if (route.name) {
|
|
4279
3702
|
identifiers.push(
|
|
4280
3703
|
domain && routesList[method][route.name] ? `${domain}@${route.name}` : route.name
|
|
4281
3704
|
);
|
|
4282
3705
|
}
|
|
4283
|
-
if (this.lookupStrategies.includes("controller") && "reference" in route.handler && typeof route.handler.reference === "string") {
|
|
4284
|
-
identifiers.push(
|
|
4285
|
-
domain && routesList[method][route.handler.reference] ? `${domain}@${route.handler.reference}` : route.handler.reference
|
|
4286
|
-
);
|
|
4287
|
-
}
|
|
4288
3706
|
identifiers.forEach((identifier) => {
|
|
4289
3707
|
routesList["ALL"][identifier] = {
|
|
4290
3708
|
params,
|
|
@@ -4300,12 +3718,12 @@ var Router = class {
|
|
|
4300
3718
|
});
|
|
4301
3719
|
}
|
|
4302
3720
|
const domains = Object.keys(this.routes).filter((domain) => domain !== "root");
|
|
4303
|
-
this.routes["root"]
|
|
3721
|
+
this.routes["root"]?.forEach((route) => trackRoute.bind(this)(route));
|
|
4304
3722
|
domains.forEach(
|
|
4305
3723
|
(domain) => this.routes[domain].forEach((route) => trackRoute.bind(this)(route, domain))
|
|
4306
3724
|
);
|
|
4307
3725
|
return Object.keys(routesList).reduce((result, method) => {
|
|
4308
|
-
result.push(`${" ".repeat(indentation)}
|
|
3726
|
+
result.push(`${" ".repeat(indentation)}${method}: {`);
|
|
4309
3727
|
Object.keys(routesList[method]).forEach((identifier) => {
|
|
4310
3728
|
const key = `'${identifier}'`;
|
|
4311
3729
|
const { paramsTuple, hasRequiredParams, params } = routesList[method][identifier];
|
|
@@ -4313,15 +3731,20 @@ var Router = class {
|
|
|
4313
3731
|
const tupleName = hasRequiredParams ? "paramsTuple" : "paramsTuple?";
|
|
4314
3732
|
const dictValue = `{${params.join(",")}}`;
|
|
4315
3733
|
const tupleValue = `[${paramsTuple?.join(",")}]`;
|
|
4316
|
-
const value = `{ ${tupleName}: ${tupleValue}
|
|
4317
|
-
result.push(`${" ".repeat(indentation + 2)}${key}: ${value}
|
|
3734
|
+
const value = `{ ${tupleName}: ${tupleValue}; ${dictName}: ${dictValue} }`;
|
|
3735
|
+
result.push(`${" ".repeat(indentation + 2)}${key}: ${value}`);
|
|
4318
3736
|
});
|
|
4319
|
-
result.push(`${" ".repeat(indentation)}}
|
|
3737
|
+
result.push(`${" ".repeat(indentation)}}`);
|
|
4320
3738
|
return result;
|
|
4321
3739
|
}, []).join("\n");
|
|
4322
3740
|
}
|
|
4323
3741
|
/**
|
|
4324
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
|
|
4325
3748
|
*/
|
|
4326
3749
|
match(uri, method, shouldDecodeParam, hostname) {
|
|
4327
3750
|
const matchingDomain = this.#store.matchDomain(hostname);
|
|
@@ -4332,9 +3755,7 @@ var Router = class {
|
|
|
4332
3755
|
}
|
|
4333
3756
|
/**
|
|
4334
3757
|
* Create URL builder instance.
|
|
4335
|
-
* @deprecated
|
|
4336
|
-
*
|
|
4337
|
-
* Instead use "@adonisjs/core/services/url_builder" instead
|
|
3758
|
+
* @deprecated Instead use "@adonisjs/core/services/url_builder" instead
|
|
4338
3759
|
*/
|
|
4339
3760
|
builder() {
|
|
4340
3761
|
return new UrlBuilder(this);
|
|
@@ -4400,33 +3821,19 @@ var Router = class {
|
|
|
4400
3821
|
|
|
4401
3822
|
// src/http_context/main.ts
|
|
4402
3823
|
import { inspect } from "util";
|
|
4403
|
-
import
|
|
4404
|
-
import { RuntimeException as
|
|
3824
|
+
import Macroable4 from "@poppinss/macroable";
|
|
3825
|
+
import { RuntimeException as RuntimeException4 } from "@poppinss/utils/exception";
|
|
4405
3826
|
|
|
4406
3827
|
// src/http_context/local_storage.ts
|
|
4407
3828
|
import { AsyncLocalStorage } from "async_hooks";
|
|
4408
3829
|
var asyncLocalStorage = {
|
|
4409
|
-
/**
|
|
4410
|
-
* Check if the async local storage for the HTTP
|
|
4411
|
-
* context is enabled or not
|
|
4412
|
-
*/
|
|
4413
3830
|
isEnabled: false,
|
|
4414
|
-
/**
|
|
4415
|
-
* HTTP context storage instance for the current scope
|
|
4416
|
-
*/
|
|
4417
3831
|
storage: null,
|
|
4418
|
-
/**
|
|
4419
|
-
* Create the storage instance. This method must be called only
|
|
4420
|
-
* once.
|
|
4421
|
-
*/
|
|
4422
3832
|
create() {
|
|
4423
3833
|
this.isEnabled = true;
|
|
4424
3834
|
this.storage = new AsyncLocalStorage();
|
|
4425
3835
|
return this.storage;
|
|
4426
3836
|
},
|
|
4427
|
-
/**
|
|
4428
|
-
* Destroy the create storage instance
|
|
4429
|
-
*/
|
|
4430
3837
|
destroy() {
|
|
4431
3838
|
this.isEnabled = false;
|
|
4432
3839
|
this.storage = null;
|
|
@@ -4434,7 +3841,15 @@ var asyncLocalStorage = {
|
|
|
4434
3841
|
};
|
|
4435
3842
|
|
|
4436
3843
|
// src/http_context/main.ts
|
|
4437
|
-
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
|
+
*/
|
|
4438
3853
|
constructor(request, response, logger, containerResolver) {
|
|
4439
3854
|
super();
|
|
4440
3855
|
this.request = request;
|
|
@@ -4445,15 +3860,27 @@ var HttpContext = class extends Macroable8 {
|
|
|
4445
3860
|
this.response.ctx = this;
|
|
4446
3861
|
}
|
|
4447
3862
|
/**
|
|
4448
|
-
*
|
|
4449
|
-
*
|
|
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().
|
|
4450
3867
|
*/
|
|
4451
3868
|
static get usingAsyncLocalStorage() {
|
|
4452
3869
|
return asyncLocalStorage.isEnabled;
|
|
4453
3870
|
}
|
|
4454
3871
|
/**
|
|
4455
|
-
* Get access to the HTTP context
|
|
4456
|
-
*
|
|
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
|
+
* ```
|
|
4457
3884
|
*/
|
|
4458
3885
|
static get() {
|
|
4459
3886
|
if (!this.usingAsyncLocalStorage || !asyncLocalStorage.storage) {
|
|
@@ -4462,24 +3889,48 @@ var HttpContext = class extends Macroable8 {
|
|
|
4462
3889
|
return asyncLocalStorage.storage.getStore() || null;
|
|
4463
3890
|
}
|
|
4464
3891
|
/**
|
|
4465
|
-
* Get the HttpContext instance or raise an exception if not
|
|
4466
|
-
*
|
|
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
|
+
* ```
|
|
4467
3904
|
*/
|
|
4468
3905
|
static getOrFail() {
|
|
4469
3906
|
if (!this.usingAsyncLocalStorage || !asyncLocalStorage.storage) {
|
|
4470
|
-
throw new
|
|
3907
|
+
throw new RuntimeException4(
|
|
4471
3908
|
'HTTP context is not available. Enable "useAsyncLocalStorage" inside "config/app.ts" file'
|
|
4472
3909
|
);
|
|
4473
3910
|
}
|
|
4474
3911
|
const store = this.get();
|
|
4475
3912
|
if (!store) {
|
|
4476
|
-
throw new
|
|
3913
|
+
throw new RuntimeException4("Http context is not available outside of an HTTP request");
|
|
4477
3914
|
}
|
|
4478
3915
|
return store;
|
|
4479
3916
|
}
|
|
4480
3917
|
/**
|
|
4481
|
-
* Run a method
|
|
4482
|
-
*
|
|
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
|
+
* ```
|
|
4483
3934
|
*/
|
|
4484
3935
|
static runOutsideContext(callback, ...args) {
|
|
4485
3936
|
if (!asyncLocalStorage.storage) {
|
|
@@ -4515,23 +3966,8 @@ var HttpContext = class extends Macroable8 {
|
|
|
4515
3966
|
|
|
4516
3967
|
// src/server/main.ts
|
|
4517
3968
|
import onFinished2 from "on-finished";
|
|
4518
|
-
import
|
|
4519
|
-
import { moduleCaller
|
|
4520
|
-
|
|
4521
|
-
// src/qs.ts
|
|
4522
|
-
import { parse as parse2, stringify } from "qs";
|
|
4523
|
-
var Qs = class {
|
|
4524
|
-
#config;
|
|
4525
|
-
constructor(config) {
|
|
4526
|
-
this.#config = config;
|
|
4527
|
-
}
|
|
4528
|
-
parse = (value) => {
|
|
4529
|
-
return parse2(value, this.#config.parse);
|
|
4530
|
-
};
|
|
4531
|
-
stringify = (value) => {
|
|
4532
|
-
return stringify(value, this.#config.stringify);
|
|
4533
|
-
};
|
|
4534
|
-
};
|
|
3969
|
+
import Middleware from "@poppinss/middleware";
|
|
3970
|
+
import { moduleCaller, moduleImporter as moduleImporter3 } from "@adonisjs/fold";
|
|
4535
3971
|
|
|
4536
3972
|
// src/server/factories/route_finder.ts
|
|
4537
3973
|
function routeFinder(router, resolver, ctx, errorResponder) {
|
|
@@ -4570,7 +4006,7 @@ function middlewareHandler(resolver, ctx) {
|
|
|
4570
4006
|
debug_default("executing middleware %s", fn.name);
|
|
4571
4007
|
return httpMiddleware.tracePromise(
|
|
4572
4008
|
fn.handle,
|
|
4573
|
-
fn,
|
|
4009
|
+
httpMiddleware.hasSubscribers ? { middleware: fn } : void 0,
|
|
4574
4010
|
void 0,
|
|
4575
4011
|
resolver,
|
|
4576
4012
|
ctx,
|
|
@@ -4581,9 +4017,12 @@ function middlewareHandler(resolver, ctx) {
|
|
|
4581
4017
|
|
|
4582
4018
|
// src/server/main.ts
|
|
4583
4019
|
var Server = class {
|
|
4020
|
+
/**
|
|
4021
|
+
* Flag indicating whether the server has been booted and initialized
|
|
4022
|
+
*/
|
|
4584
4023
|
#booted = false;
|
|
4585
4024
|
/**
|
|
4586
|
-
*
|
|
4025
|
+
* Built-in fallback error handler used when no custom handler is registered
|
|
4587
4026
|
*/
|
|
4588
4027
|
#defaultErrorHandler = {
|
|
4589
4028
|
report() {
|
|
@@ -4593,86 +4032,88 @@ var Server = class {
|
|
|
4593
4032
|
}
|
|
4594
4033
|
};
|
|
4595
4034
|
/**
|
|
4596
|
-
* Logger instance
|
|
4597
|
-
* to the context to have request specific
|
|
4598
|
-
* logging capabilities.
|
|
4035
|
+
* Logger instance for server-level logging (child loggers are created per request)
|
|
4599
4036
|
*/
|
|
4600
4037
|
#logger;
|
|
4601
4038
|
/**
|
|
4602
|
-
*
|
|
4039
|
+
* Lazy import reference to the custom error handler class
|
|
4603
4040
|
*/
|
|
4604
4041
|
#errorHandler;
|
|
4605
4042
|
/**
|
|
4606
|
-
*
|
|
4607
|
-
* handler class.
|
|
4043
|
+
* Active error handler instance (either custom or default)
|
|
4608
4044
|
*/
|
|
4609
4045
|
#resolvedErrorHandler = this.#defaultErrorHandler;
|
|
4610
4046
|
/**
|
|
4611
|
-
*
|
|
4047
|
+
* Event emitter for HTTP server lifecycle events
|
|
4612
4048
|
*/
|
|
4613
4049
|
#emitter;
|
|
4614
4050
|
/**
|
|
4615
|
-
*
|
|
4051
|
+
* AdonisJS application instance providing IoC container and configuration
|
|
4616
4052
|
*/
|
|
4617
4053
|
#app;
|
|
4618
4054
|
/**
|
|
4619
|
-
*
|
|
4055
|
+
* Encryption service for secure cookie handling and data encryption
|
|
4620
4056
|
*/
|
|
4621
4057
|
#encryption;
|
|
4622
4058
|
/**
|
|
4623
|
-
* Server
|
|
4059
|
+
* Server configuration settings including timeouts, middleware options, etc.
|
|
4624
4060
|
*/
|
|
4625
4061
|
#config;
|
|
4626
4062
|
/**
|
|
4627
|
-
* Query string parser
|
|
4063
|
+
* Query string parser instance for URL parameter processing
|
|
4628
4064
|
*/
|
|
4629
4065
|
#qsParser;
|
|
4630
4066
|
/**
|
|
4631
|
-
*
|
|
4067
|
+
* Compiled middleware stack that executes on every incoming HTTP request
|
|
4632
4068
|
*/
|
|
4633
4069
|
#serverMiddlewareStack;
|
|
4634
4070
|
/**
|
|
4635
|
-
*
|
|
4071
|
+
* Router instance responsible for route registration and matching
|
|
4636
4072
|
*/
|
|
4637
4073
|
#router;
|
|
4638
4074
|
/**
|
|
4639
|
-
* Reference to the underlying Node HTTP server
|
|
4075
|
+
* Reference to the underlying Node.js HTTP or HTTPS server instance
|
|
4640
4076
|
*/
|
|
4641
4077
|
#nodeHttpServer;
|
|
4642
4078
|
/**
|
|
4643
|
-
*
|
|
4079
|
+
* Collection of registered global middleware before compilation
|
|
4644
4080
|
*/
|
|
4645
4081
|
#middleware = [];
|
|
4646
4082
|
/**
|
|
4647
|
-
*
|
|
4648
|
-
*
|
|
4649
|
-
* registered error handler.
|
|
4650
|
-
*
|
|
4651
|
-
* We share this with the route middleware pipeline as well,
|
|
4652
|
-
* 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.
|
|
4653
4085
|
*/
|
|
4654
4086
|
#requestErrorResponder = (error, ctx) => {
|
|
4655
4087
|
this.#resolvedErrorHandler.report(error, ctx);
|
|
4656
4088
|
return httpExceptionHandler.tracePromise(
|
|
4657
4089
|
this.#resolvedErrorHandler.handle,
|
|
4658
4090
|
void 0,
|
|
4659
|
-
|
|
4091
|
+
this.#resolvedErrorHandler,
|
|
4660
4092
|
error,
|
|
4661
4093
|
ctx
|
|
4662
4094
|
);
|
|
4663
4095
|
};
|
|
4664
4096
|
/**
|
|
4665
|
-
*
|
|
4097
|
+
* Indicates whether the server has completed its boot process
|
|
4666
4098
|
*/
|
|
4667
4099
|
get booted() {
|
|
4668
4100
|
return this.#booted;
|
|
4669
4101
|
}
|
|
4670
4102
|
/**
|
|
4671
|
-
*
|
|
4103
|
+
* Indicates whether async local storage is enabled for request context
|
|
4672
4104
|
*/
|
|
4673
4105
|
get usingAsyncLocalStorage() {
|
|
4674
4106
|
return asyncLocalStorage.isEnabled;
|
|
4675
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
|
+
*/
|
|
4676
4117
|
constructor(app, encryption, emitter, logger, config) {
|
|
4677
4118
|
this.#app = app;
|
|
4678
4119
|
this.#emitter = emitter;
|
|
@@ -4685,7 +4126,7 @@ var Server = class {
|
|
|
4685
4126
|
debug_default("server config: %O", this.#config);
|
|
4686
4127
|
}
|
|
4687
4128
|
/**
|
|
4688
|
-
*
|
|
4129
|
+
* Initializes or destroys async local storage based on configuration
|
|
4689
4130
|
*/
|
|
4690
4131
|
#createAsyncLocalStore() {
|
|
4691
4132
|
if (this.#config.useAsyncLocalStorage) {
|
|
@@ -4696,16 +4137,20 @@ var Server = class {
|
|
|
4696
4137
|
}
|
|
4697
4138
|
}
|
|
4698
4139
|
/**
|
|
4699
|
-
*
|
|
4140
|
+
* Compiles registered middleware into a frozen middleware stack for execution
|
|
4700
4141
|
*/
|
|
4701
4142
|
#createServerMiddlewareStack() {
|
|
4702
|
-
this.#serverMiddlewareStack = new
|
|
4143
|
+
this.#serverMiddlewareStack = new Middleware();
|
|
4703
4144
|
this.#middleware.forEach((middleware) => this.#serverMiddlewareStack.add(middleware));
|
|
4704
4145
|
this.#serverMiddlewareStack.freeze();
|
|
4705
4146
|
this.#middleware = [];
|
|
4706
4147
|
}
|
|
4707
4148
|
/**
|
|
4708
|
-
*
|
|
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
|
|
4709
4154
|
*/
|
|
4710
4155
|
#handleRequest(ctx, resolver) {
|
|
4711
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) => {
|
|
@@ -4714,14 +4159,17 @@ var Server = class {
|
|
|
4714
4159
|
}).finally(writeResponse(ctx));
|
|
4715
4160
|
}
|
|
4716
4161
|
/**
|
|
4717
|
-
* 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
|
|
4718
4166
|
*/
|
|
4719
4167
|
pipeline(middleware) {
|
|
4720
|
-
const middlewareStack = new
|
|
4168
|
+
const middlewareStack = new Middleware();
|
|
4721
4169
|
middleware.forEach((one) => {
|
|
4722
4170
|
middlewareStack.add({
|
|
4723
4171
|
reference: one,
|
|
4724
|
-
...
|
|
4172
|
+
...moduleCaller(one, "handle").toHandleMethod()
|
|
4725
4173
|
});
|
|
4726
4174
|
});
|
|
4727
4175
|
middlewareStack.freeze();
|
|
@@ -4743,32 +4191,37 @@ var Server = class {
|
|
|
4743
4191
|
};
|
|
4744
4192
|
}
|
|
4745
4193
|
/**
|
|
4746
|
-
*
|
|
4747
|
-
*
|
|
4748
|
-
* 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
|
|
4749
4198
|
*/
|
|
4750
4199
|
use(middleware) {
|
|
4751
4200
|
middleware.forEach(
|
|
4752
4201
|
(one) => this.#middleware.push({
|
|
4753
4202
|
reference: one,
|
|
4754
|
-
...
|
|
4203
|
+
...moduleImporter3(one, "handle").toHandleMethod()
|
|
4755
4204
|
})
|
|
4756
4205
|
);
|
|
4757
4206
|
return this;
|
|
4758
4207
|
}
|
|
4759
4208
|
/**
|
|
4760
|
-
*
|
|
4761
|
-
*
|
|
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
|
|
4762
4213
|
*/
|
|
4763
4214
|
errorHandler(handler) {
|
|
4764
4215
|
this.#errorHandler = handler;
|
|
4765
4216
|
return this;
|
|
4766
4217
|
}
|
|
4767
4218
|
/**
|
|
4768
|
-
*
|
|
4219
|
+
* Initializes the server by compiling middleware, committing routes, and resolving handlers
|
|
4769
4220
|
*
|
|
4770
|
-
*
|
|
4771
|
-
* -
|
|
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
|
|
4772
4225
|
*/
|
|
4773
4226
|
async boot() {
|
|
4774
4227
|
if (this.#booted) {
|
|
@@ -4787,7 +4240,9 @@ var Server = class {
|
|
|
4787
4240
|
this.#booted = true;
|
|
4788
4241
|
}
|
|
4789
4242
|
/**
|
|
4790
|
-
*
|
|
4243
|
+
* Configures the underlying Node.js HTTP/HTTPS server with timeout settings
|
|
4244
|
+
*
|
|
4245
|
+
* @param server - Node.js HTTP or HTTPS server instance
|
|
4791
4246
|
*/
|
|
4792
4247
|
setNodeServer(server) {
|
|
4793
4248
|
server.timeout = this.#config.timeout ?? server.timeout;
|
|
@@ -4797,33 +4252,48 @@ var Server = class {
|
|
|
4797
4252
|
this.#nodeHttpServer = server;
|
|
4798
4253
|
}
|
|
4799
4254
|
/**
|
|
4800
|
-
*
|
|
4801
|
-
*
|
|
4255
|
+
* Gets the underlying Node.js HTTP/HTTPS server instance
|
|
4256
|
+
*
|
|
4257
|
+
* @returns The configured server instance or undefined if not set
|
|
4802
4258
|
*/
|
|
4803
4259
|
getNodeServer() {
|
|
4804
4260
|
return this.#nodeHttpServer;
|
|
4805
4261
|
}
|
|
4806
4262
|
/**
|
|
4807
|
-
*
|
|
4808
|
-
*
|
|
4263
|
+
* Gets the router instance used for route registration and matching
|
|
4264
|
+
*
|
|
4265
|
+
* @returns The Router instance
|
|
4809
4266
|
*/
|
|
4810
4267
|
getRouter() {
|
|
4811
4268
|
return this.#router;
|
|
4812
4269
|
}
|
|
4813
4270
|
/**
|
|
4814
|
-
* 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
|
|
4815
4276
|
*/
|
|
4816
4277
|
createRequest(req, res) {
|
|
4817
4278
|
return new Request(req, res, this.#encryption, this.#config, this.#qsParser);
|
|
4818
4279
|
}
|
|
4819
4280
|
/**
|
|
4820
|
-
* 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
|
|
4821
4286
|
*/
|
|
4822
4287
|
createResponse(req, res) {
|
|
4823
4288
|
return new Response(req, res, this.#encryption, this.#config, this.#router, this.#qsParser);
|
|
4824
4289
|
}
|
|
4825
4290
|
/**
|
|
4826
|
-
* 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
|
|
4827
4297
|
*/
|
|
4828
4298
|
createHttpContext(request, response, resolver) {
|
|
4829
4299
|
return new HttpContext(
|
|
@@ -4834,13 +4304,19 @@ var Server = class {
|
|
|
4834
4304
|
);
|
|
4835
4305
|
}
|
|
4836
4306
|
/**
|
|
4837
|
-
*
|
|
4307
|
+
* Gets the list of registered global middleware
|
|
4308
|
+
*
|
|
4309
|
+
* @returns Array of parsed global middleware
|
|
4838
4310
|
*/
|
|
4839
4311
|
getMiddlewareList() {
|
|
4840
4312
|
return this.#serverMiddlewareStack ? Array.from(this.#serverMiddlewareStack.all()) : [...this.#middleware];
|
|
4841
4313
|
}
|
|
4842
4314
|
/**
|
|
4843
|
-
*
|
|
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
|
|
4844
4320
|
*/
|
|
4845
4321
|
handle(req, res) {
|
|
4846
4322
|
const hasRequestListener = this.#emitter.hasListeners("http:request_completed");
|
|
@@ -4862,16 +4338,28 @@ var Server = class {
|
|
|
4862
4338
|
if (this.usingAsyncLocalStorage) {
|
|
4863
4339
|
return asyncLocalStorage.storage.run(
|
|
4864
4340
|
ctx,
|
|
4865
|
-
() => httpRequest.tracePromise(
|
|
4341
|
+
() => httpRequest.tracePromise(
|
|
4342
|
+
this.#handleRequest,
|
|
4343
|
+
httpRequest.hasSubscribers ? { ctx } : void 0,
|
|
4344
|
+
this,
|
|
4345
|
+
ctx,
|
|
4346
|
+
resolver
|
|
4347
|
+
)
|
|
4866
4348
|
);
|
|
4867
4349
|
}
|
|
4868
|
-
return httpRequest.tracePromise(
|
|
4350
|
+
return httpRequest.tracePromise(
|
|
4351
|
+
this.#handleRequest,
|
|
4352
|
+
httpRequest.hasSubscribers ? { ctx } : void 0,
|
|
4353
|
+
this,
|
|
4354
|
+
ctx,
|
|
4355
|
+
resolver
|
|
4356
|
+
);
|
|
4869
4357
|
}
|
|
4870
4358
|
};
|
|
4871
4359
|
|
|
4872
4360
|
// src/define_config.ts
|
|
4873
4361
|
import proxyAddr from "proxy-addr";
|
|
4874
|
-
import
|
|
4362
|
+
import string from "@poppinss/utils/string";
|
|
4875
4363
|
import lodash2 from "@poppinss/utils/lodash";
|
|
4876
4364
|
function defineConfig(config) {
|
|
4877
4365
|
const { trustProxy: trustProxy2, ...rest } = config;
|
|
@@ -4911,7 +4399,7 @@ function defineConfig(config) {
|
|
|
4911
4399
|
};
|
|
4912
4400
|
const normalizedConfig = lodash2.merge({}, defaults, rest);
|
|
4913
4401
|
if (normalizedConfig.cookie.maxAge) {
|
|
4914
|
-
normalizedConfig.cookie.maxAge =
|
|
4402
|
+
normalizedConfig.cookie.maxAge = string.seconds.parse(normalizedConfig.cookie.maxAge);
|
|
4915
4403
|
}
|
|
4916
4404
|
if (typeof trustProxy2 === "boolean") {
|
|
4917
4405
|
const tpValue = trustProxy2;
|
|
@@ -4926,24 +4414,19 @@ function defineConfig(config) {
|
|
|
4926
4414
|
}
|
|
4927
4415
|
|
|
4928
4416
|
export {
|
|
4417
|
+
Qs,
|
|
4929
4418
|
E_ROUTE_NOT_FOUND,
|
|
4930
4419
|
E_CANNOT_LOOKUP_ROUTE,
|
|
4931
4420
|
E_HTTP_EXCEPTION,
|
|
4932
4421
|
E_HTTP_REQUEST_ABORTED,
|
|
4933
4422
|
errors_exports,
|
|
4934
4423
|
CookieClient,
|
|
4935
|
-
|
|
4936
|
-
tracing_channels_exports,
|
|
4937
|
-
Route,
|
|
4938
|
-
BriskRoute,
|
|
4939
|
-
RouteResource,
|
|
4940
|
-
RouteGroup,
|
|
4941
|
-
parseRange,
|
|
4424
|
+
CookieParser,
|
|
4942
4425
|
Request,
|
|
4943
4426
|
Redirect,
|
|
4944
4427
|
ResponseStatus,
|
|
4428
|
+
CookieSerializer,
|
|
4945
4429
|
Response,
|
|
4946
|
-
Qs,
|
|
4947
4430
|
Router,
|
|
4948
4431
|
HttpContext,
|
|
4949
4432
|
Server,
|