@adonisjs/http-server 6.8.2-0 → 6.8.2-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.
Files changed (103) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -6
  3. package/build/factories/http_context.d.ts +10 -0
  4. package/build/factories/http_context.js +27 -0
  5. package/build/factories/http_server.d.ts +8 -0
  6. package/build/factories/http_server.js +26 -0
  7. package/build/factories/main.js +8 -0
  8. package/build/factories/qs_parser_factory.d.ts +10 -0
  9. package/build/factories/qs_parser_factory.js +18 -0
  10. package/build/factories/request.d.ts +10 -0
  11. package/build/factories/request.js +31 -0
  12. package/build/factories/response.d.ts +10 -0
  13. package/build/factories/response.js +34 -0
  14. package/build/factories/router.d.ts +10 -0
  15. package/build/factories/router.js +25 -0
  16. package/build/factories/server_factory.d.ts +10 -0
  17. package/build/factories/server_factory.js +34 -0
  18. package/build/index.js +8 -0
  19. package/build/src/cookies/client.d.ts +25 -0
  20. package/build/src/cookies/client.js +42 -0
  21. package/build/src/cookies/drivers/encrypted.d.ts +12 -0
  22. package/build/src/cookies/drivers/encrypted.js +20 -0
  23. package/build/src/cookies/drivers/plain.d.ts +12 -0
  24. package/build/src/cookies/drivers/plain.js +20 -0
  25. package/build/src/cookies/drivers/signed.d.ts +12 -0
  26. package/build/src/cookies/drivers/signed.js +20 -0
  27. package/build/src/cookies/parser.d.ts +28 -0
  28. package/build/src/cookies/parser.js +98 -0
  29. package/build/src/cookies/serializer.d.ts +22 -0
  30. package/build/src/cookies/serializer.js +40 -0
  31. package/build/src/debug.js +8 -0
  32. package/build/src/define_config.d.ts +3 -0
  33. package/build/src/define_config.js +11 -0
  34. package/build/src/define_middleware.d.ts +5 -0
  35. package/build/src/define_middleware.js +18 -0
  36. package/build/src/exception_handler.d.ts +93 -6
  37. package/build/src/exception_handler.js +203 -44
  38. package/build/src/exceptions.d.ts +6 -0
  39. package/build/src/exceptions.js +11 -0
  40. package/build/src/helpers.d.ts +14 -0
  41. package/build/src/helpers.js +43 -0
  42. package/build/src/http_context/local_storage.d.ts +3 -0
  43. package/build/src/http_context/local_storage.js +25 -0
  44. package/build/src/http_context/main.d.ts +36 -0
  45. package/build/src/http_context/main.js +54 -0
  46. package/build/src/qs.d.ts +4 -0
  47. package/build/src/qs.js +12 -0
  48. package/build/src/redirect.d.ts +24 -0
  49. package/build/src/redirect.js +60 -0
  50. package/build/src/request.d.ts +466 -0
  51. package/build/src/request.js +544 -2
  52. package/build/src/response.d.ts +425 -1
  53. package/build/src/response.js +611 -11
  54. package/build/src/router/brisk.d.ts +22 -0
  55. package/build/src/router/brisk.js +44 -2
  56. package/build/src/router/executor.d.ts +6 -1
  57. package/build/src/router/executor.js +14 -1
  58. package/build/src/router/factories/use_return_value.d.ts +4 -0
  59. package/build/src/router/factories/use_return_value.js +16 -3
  60. package/build/src/router/group.d.ts +47 -0
  61. package/build/src/router/group.js +88 -0
  62. package/build/src/router/lookup_store/main.d.ts +32 -0
  63. package/build/src/router/lookup_store/main.js +49 -0
  64. package/build/src/router/lookup_store/route_finder.d.ts +13 -0
  65. package/build/src/router/lookup_store/route_finder.js +21 -0
  66. package/build/src/router/lookup_store/url_builder.d.ts +36 -0
  67. package/build/src/router/lookup_store/url_builder.js +99 -2
  68. package/build/src/router/main.d.ts +92 -4
  69. package/build/src/router/main.js +146 -0
  70. package/build/src/router/matchers.d.ts +13 -0
  71. package/build/src/router/matchers.js +21 -0
  72. package/build/src/router/parser.d.ts +5 -0
  73. package/build/src/router/parser.js +17 -0
  74. package/build/src/router/resource.d.ts +30 -1
  75. package/build/src/router/resource.js +93 -1
  76. package/build/src/router/route.d.ts +65 -0
  77. package/build/src/router/route.js +151 -2
  78. package/build/src/router/store.d.ts +54 -0
  79. package/build/src/router/store.js +110 -2
  80. package/build/src/server/factories/final_handler.d.ts +7 -1
  81. package/build/src/server/factories/final_handler.js +15 -2
  82. package/build/src/server/factories/middleware_handler.d.ts +3 -0
  83. package/build/src/server/factories/middleware_handler.js +11 -0
  84. package/build/src/server/factories/write_response.d.ts +4 -0
  85. package/build/src/server/factories/write_response.js +12 -0
  86. package/build/src/server/main.d.ts +48 -0
  87. package/build/src/server/main.js +142 -5
  88. package/build/src/types/base.d.ts +12 -0
  89. package/build/src/types/base.js +8 -0
  90. package/build/src/types/main.js +8 -0
  91. package/build/src/types/middleware.d.ts +18 -0
  92. package/build/src/types/middleware.js +8 -0
  93. package/build/src/types/qs.d.ts +53 -0
  94. package/build/src/types/qs.js +8 -0
  95. package/build/src/types/request.d.ts +32 -0
  96. package/build/src/types/request.js +8 -0
  97. package/build/src/types/response.d.ts +27 -0
  98. package/build/src/types/response.js +8 -0
  99. package/build/src/types/route.d.ts +89 -1
  100. package/build/src/types/route.js +8 -0
  101. package/build/src/types/server.d.ts +36 -1
  102. package/build/src/types/server.js +8 -0
  103. package/package.json +53 -76
@@ -1,4 +1,11 @@
1
- import cuid from 'cuid';
1
+ /*
2
+ * @adonisjs/http-server
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
2
9
  import fresh from 'fresh';
3
10
  import typeIs from 'type-is';
4
11
  import accepts from 'accepts';
@@ -8,23 +15,75 @@ import proxyaddr from 'proxy-addr';
8
15
  import { safeEqual } from '@poppinss/utils';
9
16
  import Macroable from '@poppinss/macroable';
10
17
  import lodash from '@poppinss/utils/lodash';
18
+ import { createId } from '@paralleldrive/cuid2';
11
19
  import { parse } from 'node:url';
12
20
  import { trustProxy } from './helpers.js';
13
21
  import { CookieParser } from './cookies/parser.js';
22
+ /**
23
+ * HTTP Request class exposes the interface to consistently read values
24
+ * related to a given HTTP request. The class is wrapper over
25
+ * [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
26
+ * and has extended API.
27
+ *
28
+ * You can access the original [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
29
+ * using `request.request` property.
30
+ */
14
31
  export class Request extends Macroable {
15
32
  request;
16
33
  response;
34
+ /**
35
+ * Query string parser
36
+ */
17
37
  #qsParser;
38
+ /**
39
+ * Encryption module to verify signed URLs and unsign/decrypt
40
+ * cookies
41
+ */
18
42
  #encryption;
43
+ /**
44
+ * Request config
45
+ */
19
46
  #config;
47
+ /**
48
+ * Request body set using `setBody` method
49
+ */
20
50
  #requestBody = {};
51
+ /**
52
+ * A merged copy of `request body` and `querystring`
53
+ */
21
54
  #requestData = {};
55
+ /**
56
+ * Original merged copy of `request body` and `querystring`.
57
+ * Further mutation to this object are not allowed
58
+ */
22
59
  #originalRequestData = {};
60
+ /**
61
+ * Parsed query string
62
+ */
23
63
  #requestQs = {};
64
+ /**
65
+ * Raw request body as text
66
+ */
24
67
  #rawRequestBody;
68
+ /**
69
+ * Cached copy of `accepts` fn to do content
70
+ * negotiation.
71
+ */
25
72
  #lazyAccepts;
73
+ /**
74
+ * Copy of lazily parsed signed and plain cookies.
75
+ */
26
76
  #cookieParser;
77
+ /**
78
+ * Parses copy of the URL with query string as a string and not
79
+ * object. This is done to build URL's with query string without
80
+ * stringifying the object
81
+ */
27
82
  parsedUrl;
83
+ /**
84
+ * The ctx will be set by the context itself. It creates a circular
85
+ * reference
86
+ */
28
87
  ctx;
29
88
  constructor(request, response, encryption, config, qsParser) {
30
89
  super();
@@ -36,88 +95,220 @@ export class Request extends Macroable {
36
95
  this.parsedUrl = parse(this.request.url, false);
37
96
  this.#parseQueryString();
38
97
  }
98
+ /**
99
+ * Parses the query string
100
+ */
39
101
  #parseQueryString() {
40
102
  if (this.parsedUrl.query) {
41
103
  this.updateQs(this.#qsParser.parse(this.parsedUrl.query));
42
104
  this.#originalRequestData = { ...this.#requestData };
43
105
  }
44
106
  }
107
+ /**
108
+ * Initiates the cookie parser lazily
109
+ */
45
110
  #initiateCookieParser() {
46
111
  if (!this.#cookieParser) {
47
112
  this.#cookieParser = new CookieParser(this.header('cookie'), this.#encryption);
48
113
  }
49
114
  }
115
+ /**
116
+ * Lazily initiates the `accepts` module to make sure to parse
117
+ * the request headers only when one of the content-negotiation
118
+ * methods are used.
119
+ */
50
120
  #initiateAccepts() {
51
121
  this.#lazyAccepts = this.#lazyAccepts || accepts(this.request);
52
122
  }
123
+ /**
124
+ * Returns the request id from the `x-request-id` header. The
125
+ * header is untouched, if it already exists.
126
+ */
53
127
  id() {
54
128
  let requestId = this.header('x-request-id');
55
129
  if (!requestId && this.#config.generateRequestId) {
56
- requestId = cuid();
130
+ requestId = createId();
57
131
  this.request.headers['x-request-id'] = requestId;
58
132
  }
59
133
  return requestId;
60
134
  }
135
+ /**
136
+ * Set initial request body. A copy of the input will be maintained as the original
137
+ * request body. Since the request body and query string is subject to mutations, we
138
+ * keep one original reference to flash old data (whenever required).
139
+ *
140
+ * This method is supposed to be invoked by the body parser and must be called only
141
+ * once. For further mutations make use of `updateBody` method.
142
+ */
61
143
  setInitialBody(body) {
62
144
  if (this.#originalRequestData && Object.isFrozen(this.#originalRequestData)) {
63
145
  throw new Error('Cannot re-set initial body. Use "request.updateBody" instead');
64
146
  }
65
147
  this.updateBody(body);
148
+ /*
149
+ * Freeze the original object
150
+ */
66
151
  this.#originalRequestData = Object.freeze(lodash.cloneDeep(this.#requestData));
67
152
  }
153
+ /**
154
+ * Update the request body with new data object. The `all` property
155
+ * will be re-computed by merging the query string and request
156
+ * body.
157
+ */
68
158
  updateBody(body) {
69
159
  this.#requestBody = body;
70
160
  this.#requestData = { ...this.#requestBody, ...this.#requestQs };
71
161
  }
162
+ /**
163
+ * Update the request raw body. Bodyparser sets this when unable to parse
164
+ * the request body or when request is multipart/form-data.
165
+ */
72
166
  updateRawBody(rawBody) {
73
167
  this.#rawRequestBody = rawBody;
74
168
  }
169
+ /**
170
+ * Update the query string with the new data object. The `all` property
171
+ * will be re-computed by merging the query and the request body.
172
+ */
75
173
  updateQs(data) {
76
174
  this.#requestQs = data;
77
175
  this.#requestData = { ...this.#requestBody, ...this.#requestQs };
78
176
  }
177
+ /**
178
+ * Returns route params
179
+ */
79
180
  params() {
80
181
  return this.ctx?.params || {};
81
182
  }
183
+ /**
184
+ * Returns the query string object by reference
185
+ */
82
186
  qs() {
83
187
  return this.#requestQs;
84
188
  }
189
+ /**
190
+ * Returns reference to the request body
191
+ */
85
192
  body() {
86
193
  return this.#requestBody;
87
194
  }
195
+ /**
196
+ * Returns reference to the merged copy of request body
197
+ * and query string
198
+ */
88
199
  all() {
89
200
  return this.#requestData;
90
201
  }
202
+ /**
203
+ * Returns reference to the merged copy of original request
204
+ * query string and body
205
+ */
91
206
  original() {
92
207
  return this.#originalRequestData;
93
208
  }
209
+ /**
210
+ * Returns the request raw body (if exists), or returns `null`.
211
+ *
212
+ * Ideally you must be dealing with the parsed body accessed using [[input]], [[all]] or
213
+ * [[post]] methods. The `raw` body is always a string.
214
+ */
94
215
  raw() {
95
216
  return this.#rawRequestBody || null;
96
217
  }
218
+ /**
219
+ * Returns value for a given key from the request body or query string.
220
+ * The `defaultValue` is used when original value is `undefined`.
221
+ *
222
+ * @example
223
+ * ```js
224
+ * request.input('username')
225
+ *
226
+ * // with default value
227
+ * request.input('username', 'virk')
228
+ * ```
229
+ */
97
230
  input(key, defaultValue) {
98
231
  return lodash.get(this.#requestData, key, defaultValue);
99
232
  }
233
+ /**
234
+ * Returns value for a given key from route params
235
+ *
236
+ * @example
237
+ * ```js
238
+ * request.param('id')
239
+ *
240
+ * // with default value
241
+ * request.param('id', 1)
242
+ * ```
243
+ */
100
244
  param(key, defaultValue) {
101
245
  return lodash.get(this.params(), key, defaultValue);
102
246
  }
247
+ /**
248
+ * Get everything from the request body except the given keys.
249
+ *
250
+ * @example
251
+ * ```js
252
+ * request.except(['_csrf'])
253
+ * ```
254
+ */
103
255
  except(keys) {
104
256
  return lodash.omit(this.#requestData, keys);
105
257
  }
258
+ /**
259
+ * Get value for specified keys.
260
+ *
261
+ * @example
262
+ * ```js
263
+ * request.only(['username', 'age'])
264
+ * ```
265
+ */
106
266
  only(keys) {
107
267
  return lodash.pick(this.#requestData, keys);
108
268
  }
269
+ /**
270
+ * Returns the HTTP request method. This is the original
271
+ * request method. For spoofed request method, make
272
+ * use of [[method]].
273
+ *
274
+ * @example
275
+ * ```js
276
+ * request.intended()
277
+ * ```
278
+ */
109
279
  intended() {
110
280
  return this.request.method;
111
281
  }
282
+ /**
283
+ * Returns the request HTTP method by taking method spoofing into account.
284
+ *
285
+ * Method spoofing works when all of the following are true.
286
+ *
287
+ * 1. `app.http.allowMethodSpoofing` config value is true.
288
+ * 2. request query string has `_method`.
289
+ * 3. The [[intended]] request method is `POST`.
290
+ *
291
+ * @example
292
+ * ```js
293
+ * request.method()
294
+ * ```
295
+ */
112
296
  method() {
113
297
  if (this.#config.allowMethodSpoofing && this.intended() === 'POST') {
114
298
  return this.input('_method', this.intended()).toUpperCase();
115
299
  }
116
300
  return this.intended();
117
301
  }
302
+ /**
303
+ * Returns a copy of headers as an object
304
+ */
118
305
  headers() {
119
306
  return this.request.headers;
120
307
  }
308
+ /**
309
+ * Returns value for a given header key. The default value is
310
+ * used when original value is `undefined`.
311
+ */
121
312
  header(key, defaultValue) {
122
313
  key = key.toLowerCase();
123
314
  const headers = this.headers();
@@ -129,6 +320,37 @@ export class Request extends Macroable {
129
320
  return headers[key] || defaultValue;
130
321
  }
131
322
  }
323
+ /**
324
+ * Returns the ip address of the user. This method is optimize to fetch
325
+ * ip address even when running your AdonisJs app behind a proxy.
326
+ *
327
+ * You can also define your own custom function to compute the ip address by
328
+ * defining `app.http.getIp` as a function inside the config file.
329
+ *
330
+ * ```js
331
+ * {
332
+ * http: {
333
+ * getIp (request) {
334
+ * // I am using nginx as a proxy server and want to trust 'x-real-ip'
335
+ * return request.header('x-real-ip')
336
+ * }
337
+ * }
338
+ * }
339
+ * ```
340
+ *
341
+ * You can control the behavior of trusting the proxy values by defining it
342
+ * inside the `config/app.js` file.
343
+ *
344
+ * ```js
345
+ * {
346
+ * http: {
347
+ * trustProxy: '127.0.0.1'
348
+ * }
349
+ * }
350
+ * ```
351
+ *
352
+ * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
353
+ */
132
354
  ip() {
133
355
  const ipFn = this.#config.getIp;
134
356
  if (typeof ipFn === 'function') {
@@ -136,9 +358,47 @@ export class Request extends Macroable {
136
358
  }
137
359
  return proxyaddr(this.request, this.#config.trustProxy);
138
360
  }
361
+ /**
362
+ * Returns an array of ip addresses from most to least trusted one.
363
+ * This method is optimize to fetch ip address even when running
364
+ * your AdonisJs app behind a proxy.
365
+ *
366
+ * You can control the behavior of trusting the proxy values by defining it
367
+ * inside the `config/app.js` file.
368
+ *
369
+ * ```js
370
+ * {
371
+ * http: {
372
+ * trustProxy: '127.0.0.1'
373
+ * }
374
+ * }
375
+ * ```
376
+ *
377
+ * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
378
+ */
139
379
  ips() {
140
380
  return proxyaddr.all(this.request, this.#config.trustProxy);
141
381
  }
382
+ /**
383
+ * Returns the request protocol by checking for the URL protocol or
384
+ * `X-Forwarded-Proto` header.
385
+ *
386
+ * If the `trust` is evaluated to `false`, then URL protocol is returned,
387
+ * otherwise `X-Forwarded-Proto` header is used (if exists).
388
+ *
389
+ * You can control the behavior of trusting the proxy values by defining it
390
+ * inside the `config/app.js` file.
391
+ *
392
+ * ```js
393
+ * {
394
+ * http: {
395
+ * trustProxy: '127.0.0.1'
396
+ * }
397
+ * }
398
+ * ```
399
+ *
400
+ * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
401
+ */
142
402
  protocol() {
143
403
  if ('encrypted' in this.request.socket) {
144
404
  return 'https';
@@ -149,11 +409,37 @@ export class Request extends Macroable {
149
409
  const forwardedProtocol = this.header('X-Forwarded-Proto');
150
410
  return forwardedProtocol ? forwardedProtocol.split(/\s*,\s*/)[0] : 'http';
151
411
  }
412
+ /**
413
+ * Returns a boolean telling if request is served over `https`
414
+ * or not. Check [[protocol]] method to know how protocol is
415
+ * fetched.
416
+ */
152
417
  secure() {
153
418
  return this.protocol() === 'https';
154
419
  }
420
+ /**
421
+ * Returns the request host. If proxy headers are trusted, then
422
+ * `X-Forwarded-Host` is given priority over the `Host` header.
423
+ *
424
+ * You can control the behavior of trusting the proxy values by defining it
425
+ * inside the `config/app.js` file.
426
+ *
427
+ * ```js
428
+ * {
429
+ * http: {
430
+ * trustProxy: '127.0.0.1'
431
+ * }
432
+ * }
433
+ * ```
434
+ *
435
+ * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
436
+ */
155
437
  host() {
156
438
  let host = this.header('host');
439
+ /*
440
+ * Use X-Fowarded-Host when we trust the proxy header and it
441
+ * exists
442
+ */
157
443
  if (trustProxy(this.request.socket.remoteAddress, this.#config.trustProxy)) {
158
444
  host = this.header('X-Forwarded-Host') || host;
159
445
  }
@@ -162,50 +448,125 @@ export class Request extends Macroable {
162
448
  }
163
449
  return host;
164
450
  }
451
+ /**
452
+ * Returns the request hostname. If proxy headers are trusted, then
453
+ * `X-Forwarded-Host` is given priority over the `Host` header.
454
+ *
455
+ * You can control the behavior of trusting the proxy values by defining it
456
+ * inside the `config/app.js` file.
457
+ *
458
+ * ```js
459
+ * {
460
+ * http: {
461
+ * trustProxy: '127.0.0.1'
462
+ * }
463
+ * }
464
+ * ```
465
+ *
466
+ * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
467
+ */
165
468
  hostname() {
166
469
  const host = this.host();
167
470
  if (!host) {
168
471
  return null;
169
472
  }
473
+ /*
474
+ * Support for IPv6
475
+ * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
476
+ * https://github.com/nodejs/node/pull/5314
477
+ */
170
478
  const offset = host[0] === '[' ? host.indexOf(']') + 1 : 0;
171
479
  const index = host.indexOf(':', offset);
172
480
  return index !== -1 ? host.substring(0, index) : host;
173
481
  }
482
+ /**
483
+ * Returns an array of subdomains for the given host. An empty array is
484
+ * returned if [[hostname]] is `null` or is an IP address.
485
+ *
486
+ * Also `www` is not considered as a subdomain
487
+ */
174
488
  subdomains() {
175
489
  const hostname = this.hostname();
490
+ /*
491
+ * Return empty array when hostname is missing or it's
492
+ * an IP address
493
+ */
176
494
  if (!hostname || isIP(hostname)) {
177
495
  return [];
178
496
  }
179
497
  const offset = this.#config.subdomainOffset;
180
498
  const subdomains = hostname.split('.').reverse().slice(offset);
499
+ /*
500
+ * Remove www from the subdomains list
501
+ */
181
502
  if (subdomains[subdomains.length - 1] === 'www') {
182
503
  subdomains.splice(subdomains.length - 1, 1);
183
504
  }
184
505
  return subdomains;
185
506
  }
507
+ /**
508
+ * Returns a boolean telling, if request `X-Requested-With === 'xmlhttprequest'`
509
+ * or not.
510
+ */
186
511
  ajax() {
187
512
  const xRequestedWith = this.header('X-Requested-With', '');
188
513
  return xRequestedWith.toLowerCase() === 'xmlhttprequest';
189
514
  }
515
+ /**
516
+ * Returns a boolean telling, if request has `X-Pjax` header
517
+ * set or not
518
+ */
190
519
  pjax() {
191
520
  return !!this.header('X-Pjax');
192
521
  }
522
+ /**
523
+ * Returns the request relative URL.
524
+ *
525
+ * @example
526
+ * ```js
527
+ * request.url()
528
+ *
529
+ * // include query string
530
+ * request.url(true)
531
+ * ```
532
+ */
193
533
  url(includeQueryString) {
194
534
  const pathname = this.parsedUrl.pathname;
195
535
  return includeQueryString && this.parsedUrl.query
196
536
  ? `${pathname}?${this.parsedUrl.query}`
197
537
  : pathname;
198
538
  }
539
+ /**
540
+ * Returns the complete HTTP url by combining
541
+ * [[protocol]]://[[hostname]]/[[url]]
542
+ *
543
+ * @example
544
+ * ```js
545
+ * request.completeUrl()
546
+ *
547
+ * // include query string
548
+ * request.completeUrl(true)
549
+ * ```
550
+ */
199
551
  completeUrl(includeQueryString) {
200
552
  const protocol = this.protocol();
201
553
  const hostname = this.host();
202
554
  return `${protocol}://${hostname}${this.url(includeQueryString)}`;
203
555
  }
556
+ /**
557
+ * Find if the current HTTP request is for the given route or the routes
558
+ */
204
559
  matchesRoute(routeIdentifier) {
560
+ /**
561
+ * The context is missing inside the HTTP server hooks.
562
+ */
205
563
  if (!this.ctx || !this.ctx.route) {
206
564
  return false;
207
565
  }
208
566
  const route = this.ctx.route;
567
+ /**
568
+ * Search the identifier(s) against the route "pattern", "name" and the route handler
569
+ */
209
570
  return !!(Array.isArray(routeIdentifier) ? routeIdentifier : [routeIdentifier]).find((identifier) => {
210
571
  if (route.pattern === identifier || route.name === identifier) {
211
572
  return true;
@@ -216,44 +577,197 @@ export class Request extends Macroable {
216
577
  return route.handler.reference === identifier;
217
578
  });
218
579
  }
580
+ /**
581
+ * Returns the best matching content type of the request by
582
+ * matching against the given types.
583
+ *
584
+ * The content type is picked from the `content-type` header and request
585
+ * must have body.
586
+ *
587
+ * The method response highly depends upon the types array values. Described below:
588
+ *
589
+ * | Type(s) | Return value |
590
+ * |----------|---------------|
591
+ * | ['json'] | json |
592
+ * | ['application/*'] | application/json |
593
+ * | ['vnd+json'] | application/json |
594
+ *
595
+ * @example
596
+ * ```js
597
+ * const bodyType = request.is(['json', 'xml'])
598
+ *
599
+ * if (bodyType === 'json') {
600
+ * // process JSON
601
+ * }
602
+ *
603
+ * if (bodyType === 'xml') {
604
+ * // process XML
605
+ * }
606
+ * ```
607
+ */
219
608
  is(types) {
220
609
  return typeIs(this.request, types) || null;
221
610
  }
611
+ /**
612
+ * Returns the best type using `Accept` header and
613
+ * by matching it against the given types.
614
+ *
615
+ * If nothing is matched, then `null` will be returned
616
+ *
617
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
618
+ * docs too.
619
+ *
620
+ * @example
621
+ * ```js
622
+ * switch (request.accepts(['json', 'html'])) {
623
+ * case 'json':
624
+ * return response.json(user)
625
+ * case 'html':
626
+ * return view.render('user', { user })
627
+ * default:
628
+ * // decide yourself
629
+ * }
630
+ * ```
631
+ */
222
632
  accepts(types) {
223
633
  this.#initiateAccepts();
224
634
  return this.#lazyAccepts.type(types) || null;
225
635
  }
636
+ /**
637
+ * Return the types that the request accepts, in the order of the
638
+ * client's preference (most preferred first).
639
+ *
640
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
641
+ * docs too.
642
+ */
226
643
  types() {
227
644
  this.#initiateAccepts();
228
645
  return this.#lazyAccepts.types();
229
646
  }
647
+ /**
648
+ * Returns the best language using `Accept-language` header
649
+ * and by matching it against the given languages.
650
+ *
651
+ * If nothing is matched, then `null` will be returned
652
+ *
653
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
654
+ * docs too.
655
+ *
656
+ * @example
657
+ * ```js
658
+ * switch (request.language(['fr', 'de'])) {
659
+ * case 'fr':
660
+ * return view.render('about', { lang: 'fr' })
661
+ * case 'de':
662
+ * return view.render('about', { lang: 'de' })
663
+ * default:
664
+ * return view.render('about', { lang: 'en' })
665
+ * }
666
+ * ```
667
+ */
230
668
  language(languages) {
231
669
  this.#initiateAccepts();
232
670
  return this.#lazyAccepts.language(languages) || null;
233
671
  }
672
+ /**
673
+ * Return the languages that the request accepts, in the order of the
674
+ * client's preference (most preferred first).
675
+ *
676
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
677
+ * docs too.
678
+ */
234
679
  languages() {
235
680
  this.#initiateAccepts();
236
681
  return this.#lazyAccepts.languages();
237
682
  }
683
+ /**
684
+ * Returns the best charset using `Accept-charset` header
685
+ * and by matching it against the given charsets.
686
+ *
687
+ * If nothing is matched, then `null` will be returned
688
+ *
689
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
690
+ * docs too.
691
+ *
692
+ * @example
693
+ * ```js
694
+ * switch (request.charset(['utf-8', 'ISO-8859-1'])) {
695
+ * case 'utf-8':
696
+ * // make utf-8 friendly response
697
+ * case 'ISO-8859-1':
698
+ * // make ISO-8859-1 friendly response
699
+ * }
700
+ * ```
701
+ */
238
702
  charset(charsets) {
239
703
  this.#initiateAccepts();
240
704
  return this.#lazyAccepts.charset(charsets) || null;
241
705
  }
706
+ /**
707
+ * Return the charsets that the request accepts, in the order of the
708
+ * client's preference (most preferred first).
709
+ *
710
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
711
+ * docs too.
712
+ */
242
713
  charsets() {
243
714
  this.#initiateAccepts();
244
715
  return this.#lazyAccepts.charsets();
245
716
  }
717
+ /**
718
+ * Returns the best encoding using `Accept-encoding` header
719
+ * and by matching it against the given encodings.
720
+ *
721
+ * If nothing is matched, then `null` will be returned
722
+ *
723
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
724
+ * docs too.
725
+ */
246
726
  encoding(encodings) {
247
727
  this.#initiateAccepts();
248
728
  return this.#lazyAccepts.encoding(encodings) || null;
249
729
  }
730
+ /**
731
+ * Return the charsets that the request accepts, in the order of the
732
+ * client's preference (most preferred first).
733
+ *
734
+ * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
735
+ * docs too.
736
+ */
250
737
  encodings() {
251
738
  this.#initiateAccepts();
252
739
  return this.#lazyAccepts.encodings();
253
740
  }
741
+ /**
742
+ * Returns a boolean telling if request has body
743
+ */
254
744
  hasBody() {
255
745
  return typeIs.hasBody(this.request);
256
746
  }
747
+ /**
748
+ * Returns a boolean telling if the new response etag evaluates same
749
+ * as the request header `if-none-match`. In case of `true`, the
750
+ * server must return `304` response, telling the browser to
751
+ * use the client cache.
752
+ *
753
+ * You won't have to deal with this method directly, since AdonisJs will
754
+ * handle this for you when `http.etag = true` inside `config/app.js` file.
755
+ *
756
+ * However, this is how you can use it manually.
757
+ *
758
+ * ```js
759
+ * const responseBody = view.render('some-view')
760
+ *
761
+ * // sets the HTTP etag header for response
762
+ * response.setEtag(responseBody)
763
+ *
764
+ * if (request.fresh()) {
765
+ * response.sendStatus(304)
766
+ * } else {
767
+ * response.send(responseBody)
768
+ * }
769
+ * ```
770
+ */
257
771
  fresh() {
258
772
  if (['GET', 'HEAD'].indexOf(this.intended()) === -1) {
259
773
  return false;
@@ -264,17 +778,32 @@ export class Request extends Macroable {
264
778
  }
265
779
  return false;
266
780
  }
781
+ /**
782
+ * Opposite of [[fresh]]
783
+ */
267
784
  stale() {
268
785
  return !this.fresh();
269
786
  }
787
+ /**
788
+ * Returns all parsed and signed cookies. Signed cookies ensures
789
+ * that their value isn't tampered.
790
+ */
270
791
  cookiesList() {
271
792
  this.#initiateCookieParser();
272
793
  return this.#cookieParser.list();
273
794
  }
795
+ /**
796
+ * Returns value for a given key from signed cookies. Optional
797
+ * defaultValue is returned when actual value is undefined.
798
+ */
274
799
  cookie(key, defaultValue) {
275
800
  this.#initiateCookieParser();
276
801
  return this.#cookieParser.unsign(key) || defaultValue;
277
802
  }
803
+ /**
804
+ * Returns value for a given key from signed cookies. Optional
805
+ * defaultValue is returned when actual value is undefined.
806
+ */
278
807
  encryptedCookie(key, defaultValue) {
279
808
  this.#initiateCookieParser();
280
809
  return this.#cookieParser.decrypt(key) || defaultValue;
@@ -287,11 +816,18 @@ export class Request extends Macroable {
287
816
  }
288
817
  return this.#cookieParser.decode(key, encoded) || defaultValueOrOptions;
289
818
  }
819
+ /**
820
+ * Returns a boolean telling if a signed url as a valid signature
821
+ * or not.
822
+ */
290
823
  hasValidSignature(purpose) {
291
824
  const { signature, ...rest } = this.qs();
292
825
  if (!signature) {
293
826
  return false;
294
827
  }
828
+ /*
829
+ * Return false when signature fails
830
+ */
295
831
  const signedUrl = this.#encryption.verifier.unsign(signature, purpose);
296
832
  if (!signedUrl) {
297
833
  return false;
@@ -301,6 +837,9 @@ export class Request extends Macroable {
301
837
  ? safeEqual(signedUrl, `${this.url()}?${queryString}`)
302
838
  : safeEqual(signedUrl, this.url());
303
839
  }
840
+ /**
841
+ * Serializes request to JSON format
842
+ */
304
843
  serialize() {
305
844
  return {
306
845
  id: this.id(),
@@ -317,6 +856,9 @@ export class Request extends Macroable {
317
856
  subdomains: this.ctx?.subdomains || {},
318
857
  };
319
858
  }
859
+ /**
860
+ * toJSON copy of the request
861
+ */
320
862
  toJSON() {
321
863
  return this.serialize();
322
864
  }