@adonisjs/http-server 8.1.0 → 8.1.2

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/index.js CHANGED
@@ -1,92 +1,27 @@
1
- import "./chunk-B2GA45YG.js";
2
- import { _ as Qs, a as CookieSerializer, c as HttpRequest, d as Redirect, f as E_CANNOT_LOOKUP_ROUTE, g as errors_exports, h as E_ROUTE_NOT_FOUND, i as HttpResponse, l as CookieParser, m as E_HTTP_REQUEST_ABORTED, n as Server, o as ResponseStatus, p as E_HTTP_EXCEPTION, r as HttpContext, s as Router, t as defineConfig, u as CookieClient } from "./define_config-t7GL92UR.js";
3
- import { C as canWriteResponseBody, S as tracing_channels_exports, _ as Route, g as BriskRoute, h as RouteResource, m as RouteGroup, u as parseRange } from "./helpers-aa47NQc6.js";
4
- import "./helpers-XD4_pfkD.js";
1
+ import { a as RouteGroup, c as Route, m as canWriteResponseBody, o as RouteResource, p as tracing_channels_exports, s as BriskRoute, t as parseRange } from "./utils-BjSHKI3s.js";
2
+ import { _ as Qs, a as CookieSerializer, c as HttpRequest, d as Redirect, f as E_CANNOT_LOOKUP_ROUTE, g as errors_exports, h as E_ROUTE_NOT_FOUND, i as HttpResponse, l as CookieParser, m as E_HTTP_REQUEST_ABORTED, n as Server, o as ResponseStatus, p as E_HTTP_EXCEPTION, r as HttpContext, s as Router, t as defineConfig, u as CookieClient } from "./define_config-BRmlbWlB.js";
3
+ import "./helpers-C_2HouOe.js";
4
+ import "./types-AUwURgIL.js";
5
5
  import Macroable from "@poppinss/macroable";
6
6
  import is from "@sindresorhus/is";
7
- //#region src/exception_handler.ts
8
- /**
9
- * The base HTTP exception handler that provides comprehensive error handling capabilities.
10
- *
11
- * This class can be inherited to create custom exception handlers for your application.
12
- * It provides built-in support for:
13
- *
14
- * - Self-handling exceptions via their own render/handle methods
15
- * - Custom status page rendering for different HTTP error codes
16
- * - Debug-friendly error display during development
17
- * - Content negotiation for JSON, JSON API, and HTML error responses
18
- * - Configurable error reporting and logging
19
- * - Validation error handling with field-specific messages
20
- *
21
- * @example
22
- * ```ts
23
- * export default class HttpExceptionHandler extends ExceptionHandler {
24
- * protected debug = app.inDev
25
- * protected renderStatusPages = app.inProduction
26
- *
27
- * protected statusPages = {
28
- * '404': (error, ctx) => ctx.view.render('errors/404')
29
- * }
30
- * }
31
- * ```
32
- */
33
7
  var ExceptionHandler = class extends Macroable {
34
- /**
35
- * Cached expanded status pages mapping individual status codes to their renderers
36
- * Computed from the statusPages property when first accessed
37
- */
38
8
  #expandedStatusPages;
39
- /**
40
- * Controls whether to include debug information in error responses
41
- * When enabled, errors include complete stack traces and detailed debugging info
42
- * Defaults to true in non-production environments
43
- */
44
9
  debug = process.env.NODE_ENV !== "production";
45
- /**
46
- * Controls whether to render custom status pages for unhandled errors
47
- * When enabled, errors with matching status codes use configured status page renderers
48
- * Defaults to true in production environments
49
- */
50
10
  renderStatusPages = process.env.NODE_ENV === "production";
51
- /**
52
- * Mapping of HTTP status code ranges to their corresponding page renderers
53
- * Supports ranges like '400-499' or individual codes like '404'
54
- */
55
11
  statusPages = {};
56
- /**
57
- * Controls whether errors should be reported to logging systems
58
- * When disabled, errors are handled but not logged or reported
59
- */
60
12
  reportErrors = true;
61
- /**
62
- * Array of exception class constructors to exclude from error reporting
63
- * These exceptions are handled but not logged or reported to external systems
64
- */
65
13
  ignoreExceptions = [
66
14
  E_HTTP_EXCEPTION,
67
15
  E_ROUTE_NOT_FOUND,
68
16
  E_CANNOT_LOOKUP_ROUTE,
69
17
  E_HTTP_REQUEST_ABORTED
70
18
  ];
71
- /**
72
- * Array of HTTP status codes to exclude from error reporting
73
- * Errors with these status codes are handled but not logged
74
- */
75
19
  ignoreStatuses = [
76
20
  400,
77
21
  422,
78
22
  401
79
23
  ];
80
- /**
81
- * Array of custom error codes to exclude from error reporting
82
- * Errors with these codes are handled but not logged
83
- */
84
24
  ignoreCodes = [];
85
- /**
86
- * Expands status page ranges into individual status code mappings
87
- * Creates a cached lookup table for faster status page resolution
88
- * @returns Mapping of status codes to renderers
89
- */
90
25
  #expandStatusPages() {
91
26
  if (!this.#expandedStatusPages) this.#expandedStatusPages = Object.keys(this.statusPages).reduce((result, range) => {
92
27
  const renderer = this.statusPages[range];
@@ -95,54 +30,24 @@ var ExceptionHandler = class extends Macroable {
95
30
  }, {});
96
31
  return this.#expandedStatusPages;
97
32
  }
98
- /**
99
- * Normalizes any thrown value into a standardized HttpError object
100
- * Ensures the error has required properties like message and status
101
- * @param error - Any thrown value (Error, string, object, etc.)
102
- * @returns {HttpError} Normalized error object with status and message
103
- */
104
33
  toHttpError(error) {
105
34
  const httpError = is.object(error) ? error : new Error(String(error));
106
35
  if (!httpError.message) httpError.message = "Internal server error";
107
36
  if (!httpError.status) httpError.status = 500;
108
37
  return httpError;
109
38
  }
110
- /**
111
- * Provides additional context information for error reporting
112
- * Includes request ID when available for correlation across logs
113
- * @param ctx - HTTP context containing request information
114
- * @returns Additional context data for error reporting
115
- */
116
39
  context(ctx) {
117
40
  const requestId = ctx.request.id();
118
41
  return requestId ? { "x-request-id": requestId } : {};
119
42
  }
120
- /**
121
- * Determines the appropriate log level based on HTTP status code
122
- * 5xx errors are logged as 'error', 4xx as 'warn', others as 'info'
123
- * @param error - HTTP error object with status code
124
- * @returns {Level} Appropriate logging level for the error
125
- */
126
43
  getErrorLogLevel(error) {
127
44
  if (error.status >= 500) return "error";
128
45
  if (error.status >= 400) return "warn";
129
46
  return "info";
130
47
  }
131
- /**
132
- * Determines whether debug information should be included in error responses
133
- * Override this method to implement context-specific debug control
134
- * @param _ - HTTP context (unused in base implementation)
135
- * @returns {boolean} True if debugging should be enabled
136
- */
137
48
  isDebuggingEnabled(_) {
138
49
  return this.debug;
139
50
  }
140
- /**
141
- * Determines whether an error should be reported to logging systems
142
- * Checks against ignore lists for exceptions, status codes, and error codes
143
- * @param error - HTTP error to evaluate for reporting
144
- * @returns {boolean} True if the error should be reported
145
- */
146
51
  shouldReport(error) {
147
52
  if (this.reportErrors === false) return false;
148
53
  if (this.ignoreStatuses.includes(error.status)) return false;
@@ -150,12 +55,6 @@ var ExceptionHandler = class extends Macroable {
150
55
  if (this.ignoreExceptions.find((exception) => error instanceof exception)) return false;
151
56
  return true;
152
57
  }
153
- /**
154
- * Renders an error as a JSON response
155
- * In debug mode, includes full stack trace using Youch
156
- * @param error - HTTP error to render
157
- * @param ctx - HTTP context for the request
158
- */
159
58
  async renderErrorAsJSON(error, ctx) {
160
59
  if (this.isDebuggingEnabled(ctx)) {
161
60
  const { Youch } = await import("youch");
@@ -165,12 +64,6 @@ var ExceptionHandler = class extends Macroable {
165
64
  }
166
65
  ctx.response.status(error.status).send({ message: error.message });
167
66
  }
168
- /**
169
- * Renders an error as a JSON API compliant response
170
- * Follows JSON API specification for error objects
171
- * @param error - HTTP error to render
172
- * @param ctx - HTTP context for the request
173
- */
174
67
  async renderErrorAsJSONAPI(error, ctx) {
175
68
  if (this.isDebuggingEnabled(ctx)) {
176
69
  const { Youch } = await import("youch");
@@ -184,22 +77,10 @@ var ExceptionHandler = class extends Macroable {
184
77
  status: error.status
185
78
  }] });
186
79
  }
187
- /**
188
- * Renders an error as an HTML response
189
- * Uses status pages if configured, otherwise shows debug info or simple message
190
- * @param error - HTTP error to render
191
- * @param ctx - HTTP context for the request
192
- */
193
80
  async renderErrorAsHTML(error, ctx) {
194
- /**
195
- * Render status page
196
- */
197
81
  const statusPages = this.#expandStatusPages();
198
82
  if (this.renderStatusPages && statusPages[error.status]) {
199
83
  const statusPageResponse = await statusPages[error.status](error, ctx);
200
- /**
201
- * Use return value and convert it into a response
202
- */
203
84
  if (canWriteResponseBody(statusPageResponse, ctx)) return ctx.response.safeStatus(error.status).send(statusPageResponse);
204
85
  return statusPageResponse;
205
86
  }
@@ -214,21 +95,9 @@ var ExceptionHandler = class extends Macroable {
214
95
  }
215
96
  ctx.response.status(error.status).send(`<p> ${error.message} </p>`);
216
97
  }
217
- /**
218
- * Renders validation error messages as a JSON response
219
- * Returns errors in a simple format with field-specific messages
220
- * @param error - Validation error containing messages array
221
- * @param ctx - HTTP context for the request
222
- */
223
98
  async renderValidationErrorAsJSON(error, ctx) {
224
99
  ctx.response.status(error.status).send({ errors: error.messages });
225
100
  }
226
- /**
227
- * Renders validation error messages as JSON API compliant response
228
- * Transforms validation messages to JSON API error object format
229
- * @param error - Validation error containing messages array
230
- * @param ctx - HTTP context for the request
231
- */
232
101
  async renderValidationErrorAsJSONAPI(error, ctx) {
233
102
  ctx.response.status(error.status).send({ errors: error.messages.map((message) => {
234
103
  return {
@@ -239,23 +108,11 @@ var ExceptionHandler = class extends Macroable {
239
108
  };
240
109
  }) });
241
110
  }
242
- /**
243
- * Renders validation error messages as an HTML response
244
- * Creates simple HTML list of field errors separated by line breaks
245
- * @param error - Validation error containing messages array
246
- * @param ctx - HTTP context for the request
247
- */
248
111
  async renderValidationErrorAsHTML(error, ctx) {
249
112
  ctx.response.status(error.status).type("html").send(error.messages.map((message) => {
250
113
  return `${message.field} - ${message.message}`;
251
114
  }).join("<br />"));
252
115
  }
253
- /**
254
- * Renders an error to the appropriate response format based on content negotiation
255
- * Supports HTML, JSON API, and JSON formats based on Accept headers
256
- * @param error - HTTP error to render
257
- * @param ctx - HTTP context for the request
258
- */
259
116
  renderError(error, ctx) {
260
117
  switch (ctx.request.accepts([
261
118
  "html",
@@ -267,12 +124,6 @@ var ExceptionHandler = class extends Macroable {
267
124
  default: return this.renderErrorAsHTML(error, ctx);
268
125
  }
269
126
  }
270
- /**
271
- * Renders validation errors to the appropriate response format based on content negotiation
272
- * Supports HTML, JSON API, and JSON formats for validation error messages
273
- * @param error - Validation error to render
274
- * @param ctx - HTTP context for the request
275
- */
276
127
  renderValidationError(error, ctx) {
277
128
  switch (ctx.request.accepts([
278
129
  "html",
@@ -284,12 +135,6 @@ var ExceptionHandler = class extends Macroable {
284
135
  default: return this.renderValidationErrorAsHTML(error, ctx);
285
136
  }
286
137
  }
287
- /**
288
- * Reports an error to logging systems if reporting is enabled
289
- * Allows errors to self-report via their own report method if available
290
- * @param error - Any error object to report
291
- * @param ctx - HTTP context for additional reporting context
292
- */
293
138
  async report(error, ctx) {
294
139
  const httpError = this.toHttpError(error);
295
140
  if (!this.shouldReport(httpError)) return;
@@ -297,37 +142,17 @@ var ExceptionHandler = class extends Macroable {
297
142
  httpError.report(httpError, ctx);
298
143
  return;
299
144
  }
300
- /**
301
- * Log the error using the logger
302
- */
303
145
  const level = this.getErrorLogLevel(httpError);
304
146
  ctx.logger.log(level, {
305
147
  ...level === "error" || level === "fatal" ? { err: httpError } : {},
306
148
  ...this.context(ctx)
307
149
  }, httpError.message);
308
150
  }
309
- /**
310
- * Handles errors during HTTP request processing
311
- * Delegates to error's own handle method if available, otherwise renders response
312
- * @param error - Any error object to handle
313
- * @param ctx - HTTP context for error handling
314
- */
315
151
  async handle(error, ctx) {
316
152
  const httpError = this.toHttpError(error);
317
- /**
318
- * Self handle exception
319
- */
320
153
  if (typeof httpError.handle === "function") return httpError.handle(httpError, ctx);
321
- /**
322
- * Handle validation error using the validation error
323
- * renderers
324
- */
325
154
  if (httpError.code === "E_VALIDATION_ERROR" && "messages" in httpError) return this.renderValidationError(httpError, ctx);
326
- /**
327
- * Use the format renderers.
328
- */
329
155
  return this.renderError(httpError, ctx);
330
156
  }
331
157
  };
332
- //#endregion
333
158
  export { BriskRoute, CookieClient, CookieParser, CookieSerializer, ExceptionHandler, HttpContext, HttpRequest, HttpResponse, Qs, Redirect, ResponseStatus, Route, RouteGroup, RouteResource, Router, Server, defineConfig, errors_exports as errors, tracing_channels_exports as tracingChannels };
@@ -1,12 +1,5 @@
1
- import "../../chunk-B2GA45YG.js";
2
- import { n as findRoute, t as createURL } from "../../helpers-XD4_pfkD.js";
3
- //#region src/client/url_builder.ts
4
- /**
5
- * Creates the URLBuilder helper
6
- * @param router - The router instance
7
- * @param searchParamsStringifier - Function to stringify query string parameters
8
- * @returns URL builder function for creating URLs
9
- */
1
+ import { n as findRoute, t as createURL } from "../../helpers-C_2HouOe.js";
2
+ import "../../types-AUwURgIL.js";
10
3
  function createUrlBuilder(routesLoader, searchParamsStringifier, defaultOptions) {
11
4
  let domainsList;
12
5
  let domainsRoutes;
@@ -29,10 +22,6 @@ function createUrlBuilder(routesLoader, searchParamsStringifier, defaultOptions)
29
22
  } : void 0;
30
23
  return createURL(route.name ?? route.pattern, route.tokens, searchParamsStringifier, params, mergedOptions);
31
24
  }
32
- /**
33
- * The urlFor helper is used to make URLs for pre-existing known routes. You can
34
- * make a URL using the route name or the route pattern.
35
- */
36
25
  const urlFor = function route(...[identifier, params, options]) {
37
26
  return createUrlForRoute(identifier, params, options);
38
27
  };
@@ -127,5 +116,4 @@ function createUrlBuilder(routesLoader, searchParamsStringifier, defaultOptions)
127
116
  };
128
117
  return urlFor;
129
118
  }
130
- //#endregion
131
119
  export { createURL, createUrlBuilder, findRoute };
@@ -1,4 +1,76 @@
1
- import "../chunk-B2GA45YG.js";
2
- import { a as middlewareInfo, c as routeInfo, i as matchRoute, l as serializeCookie, n as createSignedURL, o as mime, r as encodeUrl, s as parseRoute, t as appendQueryString } from "../helpers-aa47NQc6.js";
3
- import { t as createURL } from "../helpers-XD4_pfkD.js";
1
+ import { n as safeDecodeURI } from "../utils-BjSHKI3s.js";
2
+ import { t as createURL } from "../helpers-C_2HouOe.js";
3
+ import { serialize } from "cookie-es";
4
+ import matchit from "@poppinss/matchit";
5
+ import string from "@poppinss/utils/string";
6
+ import { parseBindingReference } from "@adonisjs/fold";
7
+ import encodeUrl from "encodeurl";
8
+ import mime from "mime-types";
9
+ function parseRoute(pattern, matchers) {
10
+ return matchit.parse(pattern, matchers);
11
+ }
12
+ function createSignedURL(identifier, tokens, searchParamsStringifier, encryption, params, options) {
13
+ const signature = encryption.getMessageVerifier().sign(createURL(identifier, tokens, searchParamsStringifier, params, {
14
+ ...options,
15
+ prefixUrl: void 0
16
+ }), options?.expiresIn, options?.purpose);
17
+ return createURL(identifier, tokens, searchParamsStringifier, params, {
18
+ ...options,
19
+ qs: {
20
+ ...options?.qs,
21
+ signature
22
+ }
23
+ });
24
+ }
25
+ function matchRoute(url, patterns) {
26
+ const tokensBucket = patterns.map((pattern) => parseRoute(pattern));
27
+ const match = matchit.match(url, tokensBucket);
28
+ if (!match.length) return null;
29
+ return matchit.exec(url, match);
30
+ }
31
+ function serializeCookie(key, value, options) {
32
+ let expires;
33
+ let maxAge;
34
+ if (options) {
35
+ expires = typeof options.expires === "function" ? options.expires() : options.expires;
36
+ maxAge = options.maxAge ? string.seconds.parse(options.maxAge) : void 0;
37
+ }
38
+ return serialize(key, value, {
39
+ ...options,
40
+ maxAge,
41
+ expires
42
+ });
43
+ }
44
+ async function middlewareInfo(middleware) {
45
+ if (typeof middleware === "function") return {
46
+ type: "closure",
47
+ name: middleware.name || "closure"
48
+ };
49
+ if ("args" in middleware) return {
50
+ type: "named",
51
+ name: middleware.name,
52
+ args: middleware.args,
53
+ ...await parseBindingReference([middleware.reference])
54
+ };
55
+ return {
56
+ type: "global",
57
+ name: middleware.name,
58
+ ...await parseBindingReference([middleware.reference])
59
+ };
60
+ }
61
+ async function routeInfo(route) {
62
+ return "reference" in route.handler ? {
63
+ type: "controller",
64
+ ...await parseBindingReference(route.handler.reference)
65
+ } : {
66
+ type: "closure",
67
+ name: route.handler.name || "closure",
68
+ args: "listArgs" in route.handler ? String(route.handler.listArgs) : void 0
69
+ };
70
+ }
71
+ function appendQueryString(uri, queryString, qsParser) {
72
+ const { query, pathname } = safeDecodeURI(uri, false);
73
+ const mergedQueryString = qsParser.stringify(Object.assign(qsParser.parse(query), queryString));
74
+ return mergedQueryString ? `${pathname}?${mergedQueryString}` : pathname;
75
+ }
4
76
  export { appendQueryString, createSignedURL, createURL, encodeUrl, matchRoute, middlewareInfo, mime, parseRoute, routeInfo, serializeCookie };
@@ -136,5 +136,5 @@ export declare class Server {
136
136
  * @param res - Node.js ServerResponse
137
137
  * @returns Promise that resolves when request processing is complete
138
138
  */
139
- handle(req: IncomingMessage, res: ServerResponse): Promise<any>;
139
+ handle(req: IncomingMessage, res: ServerResponse): Promise<any> | undefined;
140
140
  }
@@ -1,2 +1 @@
1
- import "../../chunk-B2GA45YG.js";
2
1
  export {};
@@ -1,3 +1,4 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
1
2
  import type { Constructor } from '@poppinss/utils/types';
2
3
  import type { ErrorHandler, FinalHandler } from '@poppinss/middleware/types';
3
4
  import type { QSParserConfig } from './qs.ts';
@@ -115,4 +116,13 @@ export type ServerConfig = RequestConfig & ResponseConfig & {
115
116
  * @default 0 (as per Node.js defaults)
116
117
  */
117
118
  timeout?: number;
119
+ /**
120
+ * A callback invoked when the request URI contains malformed
121
+ * percent-encoded sequences (e.g. `%C0%80`). The callback
122
+ * receives the raw Node.js request and response objects and
123
+ * is responsible for sending a response.
124
+ *
125
+ * Defaults to a plain-text `400 Bad Request` response.
126
+ */
127
+ onBadUrl: (req: IncomingMessage, res: ServerResponse) => void;
118
128
  };
@@ -0,0 +1 @@
1
+ export {};