routup 5.0.1 → 5.1.1

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.
@@ -1,4 +1,5 @@
1
1
  import { FastURL } from "srvx";
2
+ import { hasInstanceof, markInstanceof } from "@ebec/core";
2
3
  import { HTTPError, isHTTPError } from "@ebec/http";
3
4
  import { subtle } from "uncrypto";
4
5
  import { merge } from "smob";
@@ -65,10 +66,10 @@ function setResponseCacheHeaders(event, options) {
65
66
  //#region src/error/module.ts
66
67
  const ErrorSymbol = Symbol.for("RoutupError");
67
68
  var RoutupError = class extends HTTPError {
68
- "@instanceof" = ErrorSymbol;
69
69
  constructor(input = {}) {
70
70
  super(input);
71
71
  this.name = "RoutupError";
72
+ markInstanceof(this, ErrorSymbol);
72
73
  }
73
74
  };
74
75
  //#endregion
@@ -189,12 +190,6 @@ function buildTrustProxyFn(input) {
189
190
  return compile(input || []);
190
191
  }
191
192
  //#endregion
192
- //#region src/utils/is-instance.ts
193
- function isInstance(input, sym) {
194
- if (!isObject(input)) return false;
195
- return input["@instanceof"] === sym;
196
- }
197
- //#endregion
198
193
  //#region src/utils/mime.ts
199
194
  function getMimeType(type) {
200
195
  if (type.includes("/")) return type;
@@ -288,27 +283,47 @@ function setResponseContentTypeByFileName(event, fileName) {
288
283
  }
289
284
  }
290
285
  //#endregion
291
- //#region src/response/helpers/header-attachment.ts
292
- function sanitizeFilename(filename) {
293
- return filename.replace(/[\r\n]/g, "");
286
+ //#region src/response/helpers/header-disposition.ts
287
+ const ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
288
+ const NON_ASCII_REGEXP = /[^\x20-\x7e]/g;
289
+ const QUOTE_REGEXP = /[\\"]/g;
290
+ const HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
291
+ const ASCII_TEXT_REGEXP = /^[\x20-\x7e]+$/;
292
+ const TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/;
293
+ function pencode(char) {
294
+ return `%${char.charCodeAt(0).toString(16).toUpperCase()}`;
294
295
  }
295
- function toAsciiFilename(filename) {
296
- return filename.replace(/[^\x20-\x7E]/g, "").replace(/"/g, "\\\"");
296
+ function quoteString(value) {
297
+ return `"${value.replace(QUOTE_REGEXP, "\\$&")}"`;
297
298
  }
298
- function encodeRfc5987(filename) {
299
- return encodeURIComponent(filename).replace(/['()]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`).replace(/\*/g, "%2A");
299
+ function getAscii(value) {
300
+ return value.replace(NON_ASCII_REGEXP, "?");
300
301
  }
301
- function setResponseHeaderAttachment(event, filename) {
302
- if (typeof filename === "string") setResponseContentTypeByFileName(event, filename);
303
- let disposition = "attachment";
304
- if (filename) {
305
- const sanitized = sanitizeFilename(filename);
306
- const ascii = toAsciiFilename(sanitized);
307
- disposition += `; filename="${ascii}"`;
308
- disposition += `; filename*=UTF-8''${encodeRfc5987(sanitized)}`;
302
+ function encodeExtended(value) {
303
+ return encodeURIComponent(value).replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode);
304
+ }
305
+ function formatFilename(value) {
306
+ if (TOKEN_REGEXP.test(value)) return `filename=${value}`;
307
+ return `filename=${quoteString(value)}`;
308
+ }
309
+ function setDisposition(event, type, filename) {
310
+ let disposition = type;
311
+ if (typeof filename === "string") {
312
+ setResponseContentTypeByFileName(event, filename);
313
+ if (ASCII_TEXT_REGEXP.test(filename) && !HEX_ESCAPE_REGEXP.test(filename)) disposition += `; ${formatFilename(filename)}`;
314
+ else {
315
+ disposition += `; ${formatFilename(getAscii(filename))}`;
316
+ disposition += `; filename*=UTF-8''${encodeExtended(filename)}`;
317
+ }
309
318
  }
310
319
  event.response.headers.set(HeaderName.CONTENT_DISPOSITION, disposition);
311
320
  }
321
+ function setResponseHeaderAttachment(event, filename) {
322
+ setDisposition(event, "attachment", filename);
323
+ }
324
+ function setResponseHeaderInline(event, filename) {
325
+ setDisposition(event, "inline", filename);
326
+ }
312
327
  //#endregion
313
328
  //#region src/response/helpers/header-content-type.ts
314
329
  function setResponseHeaderContentType(event, input, ifNotExists) {
@@ -321,8 +336,7 @@ function setResponseHeaderContentType(event, input, ifNotExists) {
321
336
  //#endregion
322
337
  //#region src/error/is.ts
323
338
  function isError(input) {
324
- if (!isHTTPError(input)) return false;
325
- return isInstance(input, ErrorSymbol);
339
+ return hasInstanceof(input, ErrorSymbol);
326
340
  }
327
341
  //#endregion
328
342
  //#region src/error/create.ts
@@ -443,13 +457,17 @@ async function sendCreated(event, data) {
443
457
  //#endregion
444
458
  //#region src/response/helpers/send-file.ts
445
459
  async function sendFile(event, options) {
446
- const stats = await options.stats();
460
+ let stats;
461
+ if (typeof options.stats === "function") stats = await options.stats();
462
+ else stats = options.stats;
447
463
  const name = options.name || stats.name;
448
464
  const { headers } = event.response;
465
+ const disposition = options.disposition ?? (options.attachment ? "attachment" : void 0);
449
466
  if (name) {
450
467
  const fileName = basename(name);
451
- if (options.attachment) {
452
- if (!headers.get(HeaderName.CONTENT_DISPOSITION)) setResponseHeaderAttachment(event, fileName);
468
+ if (disposition) {
469
+ if (!headers.get(HeaderName.CONTENT_DISPOSITION)) if (disposition === "inline") setResponseHeaderInline(event, fileName);
470
+ else setResponseHeaderAttachment(event, fileName);
453
471
  } else setResponseContentTypeByFileName(event, fileName);
454
472
  }
455
473
  const contentOptions = {};
@@ -949,7 +967,6 @@ function matchHandlerMethod(handlerMethod, requestMethod) {
949
967
  //#endregion
950
968
  //#region src/handler/module.ts
951
969
  var Handler = class {
952
- "@instanceof" = HandlerSymbol;
953
970
  config;
954
971
  hookManager;
955
972
  pathMatcher;
@@ -961,6 +978,7 @@ var Handler = class {
961
978
  if (typeof handler.path === "string") this.config.path = withLeadingSlash(handler.path);
962
979
  this.pathMatcher = buildHandlerPathMatcher(this.config.path, !!this.config.method);
963
980
  this.method = this.config.method ? toMethodName(this.config.method) : void 0;
981
+ markInstanceof(this, HandlerSymbol);
964
982
  }
965
983
  get type() {
966
984
  return this.config.type;
@@ -1251,7 +1269,7 @@ function isHandlerOptions(input) {
1251
1269
  return isObject(input) && typeof input.fn === "function" && typeof input.type === "string";
1252
1270
  }
1253
1271
  function isHandler(input) {
1254
- return isInstance(input, HandlerSymbol);
1272
+ return hasInstanceof(input, HandlerSymbol);
1255
1273
  }
1256
1274
  //#endregion
1257
1275
  //#region src/request/helpers/cache.ts
@@ -1472,7 +1490,7 @@ const RouterStackEntryType = {
1472
1490
  //#endregion
1473
1491
  //#region src/router/utils.ts
1474
1492
  function isRouterInstance(input) {
1475
- return isInstance(input, RouterSymbol);
1493
+ return hasInstanceof(input, RouterSymbol);
1476
1494
  }
1477
1495
  /**
1478
1496
  * Build a non-terminal `PathMatcher` for a router mount path.
@@ -1497,7 +1515,6 @@ function acceptsJson(request) {
1497
1515
  //#endregion
1498
1516
  //#region src/router/module.ts
1499
1517
  var Router = class Router {
1500
- "@instanceof" = RouterSymbol;
1501
1518
  /**
1502
1519
  * A label for the router instance.
1503
1520
  */
@@ -1537,6 +1554,7 @@ var Router = class Router {
1537
1554
  this.hookManager = new HookManager();
1538
1555
  this._options = normalizeRouterOptions(input);
1539
1556
  this.pathMatcher = buildRouterPathMatcher(input.path);
1557
+ markInstanceof(this, RouterSymbol);
1540
1558
  }
1541
1559
  matchPath(path) {
1542
1560
  if (this.pathMatcher) return this.pathMatcher.test(path);
@@ -1898,6 +1916,6 @@ var Router = class Router {
1898
1916
  }
1899
1917
  };
1900
1918
  //#endregion
1901
- export { setResponseHeaderAttachment as $, Handler as A, sendRedirect as B, fromWebHandler as C, fromNodeMiddleware as D, fromNodeHandler as E, HandlerSymbol as F, getRequestHeader as G, getRequestAcceptableContentType as H, HandlerType as I, sendAccepted as J, sendFile as K, DispatcherEvent as L, matchHandlerMethod as M, isPath as N, defineErrorHandler as O, PathMatcher as P, setResponseHeaderContentType as Q, RoutupEvent as R, isHandlerOptions as S, isWebHandlerProvider as T, getRequestAcceptableContentTypes as U, sendFormat as V, useRequestNegotiator as W, createError as X, toResponse as Y, isError as Z, getRequestAcceptableEncodings as _, PluginInstallError as a, ErrorSymbol as at, isRequestCacheable as b, isPluginError as c, HeaderName as ct, getRequestIP as d, setResponseContentTypeByFileName as et, getRequestHostName as f, getRequestAcceptableEncoding as g, getRequestAcceptableLanguages as h, PluginNotInstalledError as i, serializeEventStreamMessage as it, buildHandlerPathMatcher as j, defineCoreHandler as k, PluginErrorCode as l, MethodName as lt, getRequestAcceptableLanguage as m, normalizeRouterOptions as n, appendResponseHeaderDirective as nt, PluginAlreadyInstalledError as o, RoutupError as ot, matchRequestContentType as p, sendCreated as q, isPlugin as r, createEventStream as rt, PluginError as s, setResponseCacheHeaders as st, Router as t, appendResponseHeader as tt, getRequestProtocol as u, getRequestAcceptableCharset as v, isWebHandler as w, isHandler as x, getRequestAcceptableCharsets as y, sendStream as z };
1919
+ export { setResponseHeaderAttachment as $, Handler as A, sendRedirect as B, fromWebHandler as C, fromNodeMiddleware as D, fromNodeHandler as E, HandlerSymbol as F, getRequestHeader as G, getRequestAcceptableContentType as H, HandlerType as I, sendAccepted as J, sendFile as K, DispatcherEvent as L, matchHandlerMethod as M, isPath as N, defineErrorHandler as O, PathMatcher as P, setResponseHeaderContentType as Q, RoutupEvent as R, isHandlerOptions as S, isWebHandlerProvider as T, getRequestAcceptableContentTypes as U, sendFormat as V, useRequestNegotiator as W, createError as X, toResponse as Y, isError as Z, getRequestAcceptableEncodings as _, PluginInstallError as a, serializeEventStreamMessage as at, isRequestCacheable as b, isPluginError as c, setResponseCacheHeaders as ct, getRequestIP as d, setResponseHeaderInline as et, getRequestHostName as f, getRequestAcceptableEncoding as g, getRequestAcceptableLanguages as h, PluginNotInstalledError as i, createEventStream as it, buildHandlerPathMatcher as j, defineCoreHandler as k, PluginErrorCode as l, HeaderName as lt, getRequestAcceptableLanguage as m, normalizeRouterOptions as n, appendResponseHeader as nt, PluginAlreadyInstalledError as o, ErrorSymbol as ot, matchRequestContentType as p, sendCreated as q, isPlugin as r, appendResponseHeaderDirective as rt, PluginError as s, RoutupError as st, Router as t, setResponseContentTypeByFileName as tt, getRequestProtocol as u, MethodName as ut, getRequestAcceptableCharset as v, isWebHandler as w, isHandler as x, getRequestAcceptableCharsets as y, sendStream as z };
1902
1920
 
1903
- //# sourceMappingURL=src-DwBb11Ty.mjs.map
1921
+ //# sourceMappingURL=src-DFLGrih4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-DFLGrih4.mjs","names":[],"sources":["../src/constants.ts","../src/response/helpers/cache.ts","../src/error/module.ts","../src/response/helpers/event-stream/utils.ts","../src/response/helpers/event-stream/module.ts","../src/utils/header.ts","../src/utils/etag/module.ts","../src/utils/object.ts","../src/utils/etag/utils.ts","../src/utils/trust-proxy/module.ts","../src/utils/mime.ts","../src/utils/method.ts","../src/utils/path.ts","../src/utils/url.ts","../src/response/helpers/header.ts","../src/response/helpers/utils.ts","../src/response/helpers/header-disposition.ts","../src/response/helpers/header-content-type.ts","../src/error/is.ts","../src/error/create.ts","../src/response/to-response.ts","../src/response/helpers/send-accepted.ts","../src/response/helpers/send-created.ts","../src/response/helpers/send-file.ts","../src/request/helpers/header.ts","../src/request/helpers/negotiator.ts","../src/request/helpers/header-accept.ts","../src/response/helpers/send-format.ts","../src/response/helpers/send-redirect.ts","../src/response/helpers/send-stream.ts","../src/event/module.ts","../src/dispatcher/module.ts","../src/handler/constants.ts","../src/hook/constants.ts","../src/hook/module.ts","../src/path/matcher.ts","../src/path/utils.ts","../src/handler/utils.ts","../src/handler/module.ts","../src/handler/core/define.ts","../src/handler/error/define.ts","../src/handler/adapters/node/define.ts","../src/handler/adapters/web/is.ts","../src/handler/adapters/web/define.ts","../src/handler/is.ts","../src/request/helpers/cache.ts","../src/request/helpers/header-accept-charset.ts","../src/request/helpers/header-accept-encoding.ts","../src/request/helpers/header-accept-language.ts","../src/request/helpers/header-content-type.ts","../src/request/helpers/hostname.ts","../src/request/helpers/ip.ts","../src/request/helpers/protocol.ts","../src/plugin/error/constants.ts","../src/plugin/error/is.ts","../src/plugin/error/module.ts","../src/plugin/error/sub/already-installed.ts","../src/plugin/error/sub/install.ts","../src/plugin/error/sub/not-installed.ts","../src/plugin/is.ts","../src/router/options.ts","../src/router/constants.ts","../src/router/utils.ts","../src/router/module.ts"],"sourcesContent":["export const MethodName = {\n GET: 'GET',\n POST: 'POST',\n PUT: 'PUT',\n PATCH: 'PATCH',\n DELETE: 'DELETE',\n OPTIONS: 'OPTIONS',\n HEAD: 'HEAD',\n} as const;\n\nexport type MethodName = typeof MethodName[keyof typeof MethodName];\n\nexport const HeaderName = {\n ACCEPT: 'accept',\n ACCEPT_CHARSET: 'accept-charset',\n ACCEPT_ENCODING: 'accept-encoding',\n ACCEPT_LANGUAGE: 'accept-language',\n ACCEPT_RANGES: 'accept-ranges',\n ALLOW: 'allow',\n CACHE_CONTROL: 'cache-control',\n CONTENT_DISPOSITION: 'content-disposition',\n CONTENT_ENCODING: 'content-encoding',\n CONTENT_LENGTH: 'content-length',\n CONTENT_RANGE: 'content-range',\n CONTENT_TYPE: 'content-type',\n CONNECTION: 'connection',\n COOKIE: 'cookie',\n ETag: 'etag',\n HOST: 'host',\n IF_MODIFIED_SINCE: 'if-modified-since',\n IF_NONE_MATCH: 'if-none-match',\n LAST_MODIFIED: 'last-modified',\n LOCATION: 'location',\n RANGE: 'range',\n RATE_LIMIT_LIMIT: 'ratelimit-limit',\n RATE_LIMIT_REMAINING: 'ratelimit-remaining',\n RATE_LIMIT_RESET: 'ratelimit-reset',\n RETRY_AFTER: 'retry-after',\n SET_COOKIE: 'set-cookie',\n TRANSFER_ENCODING: 'transfer-encoding',\n X_ACCEL_BUFFERING: 'x-accel-buffering',\n X_FORWARDED_HOST: 'x-forwarded-host',\n X_FORWARDED_FOR: 'x-forwarded-for',\n X_FORWARDED_PROTO: 'x-forwarded-proto',\n} as const;\n\nexport type HeaderName = typeof HeaderName[keyof typeof HeaderName];\n","import type { IRoutupEvent } from '../../event/index.ts';\n\nexport type ResponseCacheHeadersOptions = {\n maxAge?: number,\n modifiedTime?: string | Date,\n cacheControls?: string[]\n};\n\nexport function setResponseCacheHeaders(event: IRoutupEvent, options?: ResponseCacheHeadersOptions) {\n options = options || {};\n\n const cacheControls = ['public'].concat(options.cacheControls || []);\n\n if (options.maxAge !== undefined) {\n cacheControls.push(`max-age=${+options.maxAge}`, `s-maxage=${+options.maxAge}`);\n }\n\n if (options.modifiedTime) {\n const modifiedTime = typeof options.modifiedTime === 'string' ?\n new Date(options.modifiedTime) :\n options.modifiedTime;\n\n event.response.headers.set('last-modified', modifiedTime.toUTCString());\n }\n\n event.response.headers.set('cache-control', cacheControls.join(', '));\n}\n","import { markInstanceof } from '@ebec/core';\nimport { HTTPError } from '@ebec/http';\nimport type { HTTPErrorInput } from '@ebec/http';\n\nexport type { HTTPErrorInput };\n\nexport const ErrorSymbol = Symbol.for('RoutupError');\n\nexport class RoutupError extends HTTPError {\n constructor(input: HTTPErrorInput = {}) {\n super(input);\n this.name = 'RoutupError';\n markInstanceof(this, ErrorSymbol);\n }\n}\n","import type { EventStreamMessage } from './types.ts';\n\nfunction stripNewlines(value: string) : string {\n return value.replace(/[\\r\\n]/g, '');\n}\n\nexport function serializeEventStreamMessage(message: EventStreamMessage): string {\n let result = '';\n\n if (message.id) {\n result += `id: ${stripNewlines(message.id)}\\n`;\n }\n\n if (message.event) {\n result += `event: ${stripNewlines(message.event)}\\n`;\n }\n\n if (\n typeof message.retry === 'number' &&\n Number.isInteger(message.retry)\n ) {\n result += `retry: ${message.retry}\\n`;\n }\n\n const lines = message.data.replace(/\\r/g, '').split('\\n');\n for (const line of lines) {\n result += `data: ${line}\\n`;\n }\n result += '\\n';\n\n return result;\n}\n","import { HeaderName } from '../../../constants.ts';\nimport type { IRoutupEvent } from '../../../event/index.ts';\nimport { RoutupError } from '../../../error/module.ts';\nimport type { EventStreamMessage } from './types.ts';\nimport { serializeEventStreamMessage } from './utils.ts';\n\nexport type EventStreamOptions = {\n maxMessageSize?: number,\n};\n\nexport type EventStreamHandle = {\n write(message: string | EventStreamMessage): boolean;\n end(): void;\n response: Response;\n};\n\nexport function createEventStream(\n event: IRoutupEvent,\n options?: EventStreamOptions,\n): EventStreamHandle {\n if (options?.maxMessageSize !== undefined) {\n if (!Number.isInteger(options.maxMessageSize) || options.maxMessageSize < 0) {\n throw new RoutupError('maxMessageSize must be a non-negative integer.');\n }\n }\n\n let controller: ReadableStreamDefaultController<Uint8Array>;\n let closed = false;\n const encoder = new TextEncoder();\n\n const stream = new ReadableStream<Uint8Array>({\n start(ctrl) {\n controller = ctrl;\n },\n cancel() {\n closed = true;\n },\n });\n\n const headers = new Headers(event.response.headers);\n headers.set(HeaderName.CONTENT_TYPE, 'text/event-stream');\n headers.set(HeaderName.CACHE_CONTROL, 'private, no-cache, no-store, no-transform, must-revalidate, max-age=0');\n headers.set(HeaderName.X_ACCEL_BUFFERING, 'no');\n headers.set(HeaderName.CONNECTION, 'keep-alive');\n\n const response = new Response(stream, {\n status: event.response.status,\n headers,\n });\n\n const handle: EventStreamHandle = {\n write(message: string | EventStreamMessage): boolean {\n if (closed) return false;\n\n if (typeof message === 'string') {\n return handle.write({ data: message });\n }\n\n const serialized = serializeEventStreamMessage(message);\n\n if (options?.maxMessageSize !== undefined) {\n const serializedSize = encoder.encode(serialized).byteLength;\n if (serializedSize > options.maxMessageSize) {\n return false;\n }\n }\n\n controller.enqueue(encoder.encode(serialized));\n return true;\n },\n\n end(): void {\n if (closed) return;\n\n closed = true;\n controller.close();\n },\n\n response,\n };\n\n return handle;\n}\n","export function sanitizeHeaderValue(value: string) : string {\n return value.replace(/[\\r\\n]/g, '');\n}","import { subtle } from 'uncrypto';\nimport type { EtagOptions } from './types.ts';\n\nasync function sha1(str: string) : Promise<string> {\n const enc = new TextEncoder();\n const hash = await subtle.digest('SHA-1', enc.encode(str));\n\n return btoa(String.fromCharCode(...new Uint8Array(hash)));\n}\n\n/**\n * Generate an ETag.\n */\nexport async function generateETag(input: string) : Promise<string> {\n if (input.length === 0) {\n // fast-path empty\n return '\"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk\"';\n }\n\n const hash = await sha1(input);\n\n return `\"${input.length.toString(16)}-${hash.substring(0, 27)}\"`;\n}\n\n/**\n * Create a simple ETag.\n */\nexport async function createEtag(\n input: string,\n options: EtagOptions = {},\n) : Promise<string> {\n // generate entity tag\n const tag = await generateETag(input);\n\n return options.weak ?\n `W/${tag}` :\n tag;\n}\n","export function isObject(item: unknown) : item is Record<string, any> {\n return (\n !!item &&\n typeof item === 'object' &&\n !Array.isArray(item)\n );\n}\n\nexport function setProperty(\n record: Record<PropertyKey, any>,\n property: PropertyKey,\n value: any,\n): void {\n (record as any)[property] = value;\n}\n\nexport function getProperty<T = any>(\n req: Record<PropertyKey, any>,\n property: PropertyKey,\n): T {\n return (req as any)[property];\n}\n","import { merge } from 'smob';\nimport { isObject } from '../object.ts';\nimport { createEtag } from './module.ts';\nimport type { EtagFn, EtagOptions } from './types.ts';\n\nconst textEncoder = /* @__PURE__ */ new TextEncoder();\n\nexport function buildEtagFn(input?: boolean | EtagOptions | EtagFn) : EtagFn {\n if (typeof input === 'function') {\n return input;\n }\n\n input = input ?? true;\n\n if (input === false) {\n return () => Promise.resolve(undefined);\n }\n\n let options : EtagOptions = { weak: true };\n\n if (isObject(input)) {\n options = merge(input, options);\n }\n\n return async (body: string, size?: number) => {\n if (typeof options.threshold !== 'undefined') {\n const measured = size ?? textEncoder.encode(body).byteLength;\n\n if (measured <= options.threshold) {\n return undefined;\n }\n }\n\n return createEtag(body, options);\n };\n}\n","import { compile } from 'proxy-addr';\nimport type { TrustProxyFn } from './type.ts';\n\nexport function buildTrustProxyFn(\n input?: boolean | number | string | string[] | TrustProxyFn,\n) : TrustProxyFn {\n if (typeof input === 'function') {\n return input;\n }\n\n if (input === true) {\n return () => true;\n }\n\n if (typeof input === 'number') {\n return (_address, hop) => hop < (input as number);\n }\n\n if (typeof input === 'string') {\n input = input.split(',')\n .map((value) => value.trim());\n }\n\n return compile(input || []);\n}\n","import { get, getType } from 'mime-explorer';\n\nexport function getMimeType(type: string) : string | undefined {\n if (type.includes('/')) {\n return type;\n }\n\n return getType(type);\n}\n\nexport function getCharsetForMimeType(type: string) : string | undefined {\n if ((/^text\\/|^application\\/(javascript|json)/).test(type)) {\n return 'utf-8';\n }\n\n const meta = get(type);\n if (\n meta &&\n meta.charset\n ) {\n return meta.charset.toLowerCase();\n }\n\n return undefined;\n}\n","import type { MethodName } from '../constants.ts';\n\nexport function toMethodName(input: string | undefined) : MethodName | undefined;\nexport function toMethodName(input: string | undefined, alt: MethodName) : MethodName;\nexport function toMethodName(\n input?: string,\n alt?: MethodName,\n) : MethodName | undefined {\n if (input) {\n return input.toUpperCase() as MethodName;\n }\n\n return alt;\n}\n","/**\n * Based on https://github.com/unjs/pathe v1.1.1 (055f50a6f1131f4e5c56cf259dd8816168fba329)\n */\n\nfunction normalizeWindowsPath(input = '') {\n if (!input || !input.includes('\\\\')) {\n return input;\n }\n\n return input.replace(/\\\\/g, '/');\n}\n\nconst EXTNAME_RE = /.(\\.[^./]+)$/;\nexport function extname(input: string) {\n const match = EXTNAME_RE.exec(normalizeWindowsPath(input));\n return (match && match[1]) || '';\n}\n\nexport function basename(input: string, extension? :string) {\n const lastSegment = normalizeWindowsPath(input)\n .split('/')\n .pop();\n\n if (!lastSegment) {\n return input;\n }\n\n return extension && lastSegment.endsWith(extension) ?\n lastSegment.slice(0, -extension.length) :\n lastSegment;\n}\n","const TRAILING_SLASH_RE = /\\/$|\\/\\?/;\n\nexport function hasTrailingSlash(input = '', queryParams = false): boolean {\n if (!queryParams) {\n return input.endsWith('/');\n }\n\n return TRAILING_SLASH_RE.test(input);\n}\n\nexport function withoutTrailingSlash(input = '', queryParams = false): string {\n if (!queryParams) {\n return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || '/';\n }\n\n if (!hasTrailingSlash(input, true)) {\n return input || '/';\n }\n\n const [s0, ...s] = input.split('?');\n\n return (s0!.slice(0, -1) || '/') + (s.length ? `?${s.join('?')}` : '');\n}\n\nexport function withTrailingSlash(input = '', queryParams = false): string {\n if (!queryParams) {\n return input.endsWith('/') ? input : (`${input}/`);\n }\n\n if (hasTrailingSlash(input, true)) {\n return input || '/';\n }\n\n const [s0, ...s] = input.split('?');\n return `${s0}/${s.length ? `?${s.join('?')}` : ''}`;\n}\n\nexport function hasLeadingSlash(input = ''): boolean {\n return input.startsWith('/');\n}\n\nexport function withoutLeadingSlash(input = ''): string {\n return (hasLeadingSlash(input) ? input.substring(1) : input) || '/';\n}\n\nexport function withLeadingSlash(input = ''): string {\n return hasLeadingSlash(input) ? input : `/${input}`;\n}\n\nexport function cleanDoubleSlashes(input = ''): string {\n if (input.includes('://')) {\n return input.split('://')\n .map((str) => cleanDoubleSlashes(str))\n .join('://');\n }\n\n return input.replace(/\\/+/g, '/');\n}\n","import { sanitizeHeaderValue } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport function appendResponseHeader(\n event: IRoutupEvent,\n name: string,\n value: string | string[],\n) {\n const { headers } = event.response;\n\n if (Array.isArray(value)) {\n for (const v of value) {\n headers.append(name, sanitizeHeaderValue(v));\n }\n } else {\n headers.append(name, sanitizeHeaderValue(value));\n }\n}\n\nexport function appendResponseHeaderDirective(\n event: IRoutupEvent,\n name: string,\n value: string | string[],\n) {\n const { headers } = event.response;\n const existing = headers.get(name);\n\n if (!existing) {\n if (Array.isArray(value)) {\n headers.set(name, sanitizeHeaderValue(value.join('; ')));\n } else {\n headers.set(name, sanitizeHeaderValue(value));\n }\n return;\n }\n\n const directives = existing.split('; ');\n\n if (Array.isArray(value)) {\n directives.push(...value);\n } else {\n directives.push(value);\n }\n\n const unique = [...new Set(directives)];\n\n headers.set(name, sanitizeHeaderValue(unique.join('; ')));\n}\n","import { HeaderName } from '../../constants.ts';\nimport { extname, getCharsetForMimeType, getMimeType } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport function setResponseContentTypeByFileName(event: IRoutupEvent, fileName: string) {\n const ext = extname(fileName);\n if (ext) {\n let type = getMimeType(ext.substring(1));\n if (type) {\n const charset = getCharsetForMimeType(type);\n if (charset) {\n type += `; charset=${charset}`;\n }\n event.response.headers.set(HeaderName.CONTENT_TYPE, type);\n }\n }\n}\n","import { HeaderName } from '../../constants.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\nimport { setResponseContentTypeByFileName } from './utils.ts';\n\n// eslint-disable-next-line no-control-regex\nconst ENCODE_URL_ATTR_CHAR_REGEXP = /[\\x00-\\x20\"'()*,/:;<=>?@[\\\\\\]{}\\x7f]/g;\nconst NON_ASCII_REGEXP = /[^\\x20-\\x7e]/g;\nconst QUOTE_REGEXP = /[\\\\\"]/g;\nconst HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;\nconst ASCII_TEXT_REGEXP = /^[\\x20-\\x7e]+$/;\nconst TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/;\n\nfunction pencode(char: string): string {\n return `%${char.charCodeAt(0).toString(16).toUpperCase()}`;\n}\n\nfunction quoteString(value: string): string {\n return `\"${value.replace(QUOTE_REGEXP, '\\\\$&')}\"`;\n}\n\nfunction getAscii(value: string): string {\n return value.replace(NON_ASCII_REGEXP, '?');\n}\n\nfunction encodeExtended(value: string): string {\n return encodeURIComponent(value).replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode);\n}\n\nfunction formatFilename(value: string): string {\n if (TOKEN_REGEXP.test(value)) {\n return `filename=${value}`;\n }\n return `filename=${quoteString(value)}`;\n}\n\nfunction setDisposition(\n event: IRoutupEvent,\n type: 'attachment' | 'inline',\n filename?: string,\n) {\n let disposition: string = type;\n\n if (typeof filename === 'string') {\n setResponseContentTypeByFileName(event, filename);\n\n const isAsciiSafe = ASCII_TEXT_REGEXP.test(filename) &&\n !HEX_ESCAPE_REGEXP.test(filename);\n\n if (isAsciiSafe) {\n disposition += `; ${formatFilename(filename)}`;\n } else {\n disposition += `; ${formatFilename(getAscii(filename))}`;\n disposition += `; filename*=UTF-8''${encodeExtended(filename)}`;\n }\n }\n\n event.response.headers.set(\n HeaderName.CONTENT_DISPOSITION,\n disposition,\n );\n}\n\nexport function setResponseHeaderAttachment(event: IRoutupEvent, filename?: string) {\n setDisposition(event, 'attachment', filename);\n}\n\nexport function setResponseHeaderInline(event: IRoutupEvent, filename?: string) {\n setDisposition(event, 'inline', filename);\n}\n","import { HeaderName } from '../../constants.ts';\nimport { getMimeType } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport function setResponseHeaderContentType(event: IRoutupEvent, input: string, ifNotExists?: boolean) {\n if (ifNotExists) {\n const header = event.response.headers.get(HeaderName.CONTENT_TYPE);\n if (header) {\n return;\n }\n }\n\n const contentType = getMimeType(input);\n if (contentType) {\n event.response.headers.set(HeaderName.CONTENT_TYPE, contentType);\n }\n}\n","import { hasInstanceof } from '@ebec/core';\nimport type { RoutupError } from './module.ts';\nimport { ErrorSymbol } from './module.ts';\n\nexport function isError(input: unknown) : input is RoutupError {\n return hasInstanceof(input, ErrorSymbol);\n}\n","import { isHTTPError } from '@ebec/http';\nimport type { HTTPErrorInput } from '@ebec/http';\nimport { isObject } from '../utils/index.ts';\nimport { isError } from './is.ts';\nimport { RoutupError } from './module.ts';\n\nfunction isNativeError(input: unknown): input is Error {\n return isObject(input) &&\n typeof (input as Record<string, unknown>).message === 'string' &&\n typeof (input as Record<string, unknown>).name === 'string';\n}\n\n/**\n * Create an internal error object by\n * - an existing RoutupError (returned as-is)\n * - an HTTPError (wrapped into a RoutupError preserving status)\n * - an Error (wrapped preserving message and cause)\n * - an options object (status, message, etc.)\n * - a message string\n *\n * @param input\n */\nexport function createError(input: HTTPErrorInput | unknown) : RoutupError {\n if (isError(input)) {\n return input;\n }\n\n if (typeof input === 'string') {\n return new RoutupError(input);\n }\n\n if (isHTTPError(input)) {\n return new RoutupError({\n message: input.message,\n code: input.code,\n status: input.status,\n redirectURL: input.redirectURL,\n cause: input,\n });\n }\n\n if (isNativeError(input)) {\n return new RoutupError({\n message: input.message,\n cause: input,\n });\n }\n\n if (!isObject(input)) {\n return new RoutupError();\n }\n\n const options = { ...input as Record<string, unknown> };\n if (options.cause === undefined) {\n options.cause = input;\n }\n\n return new RoutupError(options as HTTPErrorInput);\n}\n\n","import { createError } from '../error/create.ts';\nimport type { IRoutupEvent } from '../event/index.ts';\n\nfunction stripWeakPrefix(etag: string): string {\n return etag.startsWith('W/') ? etag.slice(2) : etag;\n}\n\nasync function applyEtag(\n body: string,\n event: IRoutupEvent,\n headers: Headers,\n): Promise<Response | undefined> {\n const etagFn = event.routerOptions.etag;\n if (!etagFn) return undefined;\n\n const etag = await etagFn(body);\n if (!etag) return undefined;\n\n headers.set('etag', etag);\n\n const ifNoneMatch = event.headers.get('if-none-match');\n if (ifNoneMatch && (ifNoneMatch === '*' || ifNoneMatch.split(',').some((t) => stripWeakPrefix(t.trim()) === stripWeakPrefix(etag)))) {\n return new Response(null, {\n status: 304,\n headers,\n });\n }\n\n return undefined;\n}\n\nexport async function toResponse(\n value: unknown,\n event: IRoutupEvent,\n): Promise<Response | undefined> {\n if (value === undefined) {\n return undefined;\n }\n\n if (value === null) {\n return new Response(null, {\n status: event.response.status,\n headers: event.response.headers,\n });\n }\n\n if (value instanceof Response) {\n return value;\n }\n\n const {\n status,\n headers,\n } = event.response;\n\n if (typeof value === 'string') {\n if (!headers.has('content-type')) {\n headers.set('content-type', 'text/plain; charset=utf-8');\n }\n\n const cached = await applyEtag(value, event, headers);\n if (cached) return cached;\n\n return new Response(value, {\n status,\n headers,\n });\n }\n\n if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/octet-stream');\n }\n return new Response(value as BodyInit, {\n status,\n headers,\n });\n }\n\n if (value instanceof ReadableStream) {\n return new Response(value, {\n status,\n headers,\n });\n }\n\n if (value instanceof Blob) {\n if (!headers.has('content-type')) {\n headers.set('content-type', value.type || 'application/octet-stream');\n }\n return new Response(value, {\n status,\n headers,\n });\n }\n\n // object/array/number/boolean — JSON serialize\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json; charset=utf-8');\n }\n\n let json: string;\n try {\n json = JSON.stringify(value);\n } catch (e) {\n throw createError({\n message: 'JSON serialization failed',\n status: 500,\n cause: e,\n });\n }\n\n const cached = await applyEtag(json, event, headers);\n if (cached) return cached;\n\n return new Response(json, {\n status,\n headers,\n });\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\nimport { toResponse } from '../to-response.ts';\n\nexport async function sendAccepted(event: IRoutupEvent, data?: unknown): Promise<Response> {\n event.response.status = 202;\n\n return await toResponse(data ?? '', event) as Response;\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\nimport { toResponse } from '../to-response.ts';\n\nexport async function sendCreated(event: IRoutupEvent, data?: unknown): Promise<Response> {\n event.response.status = 201;\n\n return await toResponse(data ?? '', event) as Response;\n}\n","import { HeaderName } from '../../constants.ts';\nimport { basename } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\nimport { setResponseHeaderAttachment, setResponseHeaderInline } from './header-disposition.ts';\nimport { setResponseContentTypeByFileName } from './utils.ts';\n\nexport type SendFileContentOptions = {\n end?: number,\n start?: number;\n};\n\n/**\n * File metadata used by {@link sendFile}. All fields are optional, but each\n * missing field disables related response features:\n *\n * - `size` — without it, range requests, `Accept-Ranges`, `Content-Length`,\n * `ETag`, and `Last-Modified` are all omitted (the response is sent\n * without HTTP-level caching or seekability).\n * - `mtime` — without it, `Last-Modified` is omitted and the `ETag` is not\n * emitted (`ETag` requires both `size` and `mtime`).\n * - `name` — falls back to `SendFileOptions.name` when set; if both are\n * missing, no `Content-Disposition` or extension-derived\n * `Content-Type` is set.\n */\nexport type SendFileStats = {\n size?: number,\n mtime?: Date | number | string,\n name?: string\n};\n\nexport type SendFileDisposition = 'attachment' | 'inline';\n\nexport type SendFileContent = ReadableStream | ArrayBuffer | Uint8Array;\nexport type SendFileOptions = {\n stats: (() => Promise<SendFileStats> | SendFileStats) | SendFileStats,\n content: (options: SendFileContentOptions) => Promise<SendFileContent> | SendFileContent,\n /**\n * @deprecated Use `disposition: 'attachment'` instead. Kept for backwards\n * compatibility — when `disposition` is set, it takes precedence.\n */\n attachment?: boolean,\n disposition?: SendFileDisposition,\n name?: string\n};\n\nexport async function sendFile(\n event: IRoutupEvent,\n options: SendFileOptions,\n) : Promise<Response> {\n let stats : SendFileStats;\n if (typeof options.stats === 'function') {\n stats = await options.stats();\n } else {\n stats = options.stats;\n }\n\n const name = options.name || stats.name;\n const { headers } = event.response;\n\n const disposition = options.disposition ?? (options.attachment ? 'attachment' : undefined);\n\n if (name) {\n const fileName = basename(name);\n\n if (disposition) {\n const dispositionHeader = headers.get(HeaderName.CONTENT_DISPOSITION);\n if (!dispositionHeader) {\n if (disposition === 'inline') {\n setResponseHeaderInline(event, fileName);\n } else {\n setResponseHeaderAttachment(event, fileName);\n }\n }\n } else {\n setResponseContentTypeByFileName(event, fileName);\n }\n }\n\n const contentOptions : SendFileContentOptions = {};\n let statusCode = event.response.status;\n\n if (stats.size) {\n const rangeHeader = event.headers.get(HeaderName.RANGE);\n if (rangeHeader) {\n const [x, y] = rangeHeader.replace('bytes=', '')\n .split('-') as [string, string];\n\n const parsedStart = Number.parseInt(x, 10);\n const parsedEnd = Number.parseInt(y, 10);\n\n contentOptions.start = Number.isFinite(parsedStart) && parsedStart >= 0 ? parsedStart : 0;\n contentOptions.end = Number.isFinite(parsedEnd) && parsedEnd >= 0 ?\n Math.min(parsedEnd, stats.size - 1) :\n stats.size - 1;\n\n if (\n contentOptions.start >= stats.size ||\n contentOptions.start > contentOptions.end\n ) {\n const rangeHeaders = new Headers(headers);\n rangeHeaders.set(HeaderName.CONTENT_RANGE, `bytes */${stats.size}`);\n return new Response(null, {\n status: 416,\n headers: rangeHeaders,\n });\n }\n\n headers.set(HeaderName.CONTENT_RANGE, `bytes ${contentOptions.start}-${contentOptions.end}/${stats.size}`);\n headers.set(HeaderName.CONTENT_LENGTH, `${contentOptions.end - contentOptions.start + 1}`);\n statusCode = 206;\n } else {\n headers.set(HeaderName.CONTENT_LENGTH, `${stats.size}`);\n }\n\n headers.set(HeaderName.ACCEPT_RANGES, 'bytes');\n\n if (stats.mtime) {\n const mtime = new Date(stats.mtime);\n headers.set(HeaderName.LAST_MODIFIED, mtime.toUTCString());\n headers.set(HeaderName.ETag, `W/\"${stats.size}-${mtime.getTime()}\"`);\n }\n }\n\n const content = await options.content(contentOptions);\n\n return new Response(content as BodyInit, {\n status: statusCode,\n headers,\n });\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\n\nexport function getRequestHeader(\n event: IRoutupEvent,\n name: string,\n) : string | null {\n return event.headers.get(name);\n}\n","import Negotiator from 'negotiator';\n\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nconst NEGOTIATOR_KEY = Symbol.for('routup:negotiator');\n\nfunction headersToPlainObject(headers: Headers) : Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n\nexport function useRequestNegotiator(event: IRoutupEvent) : Negotiator {\n let value = event.store[NEGOTIATOR_KEY] as Negotiator | undefined;\n if (value) {\n return value;\n }\n\n value = new Negotiator({ headers: headersToPlainObject(event.headers) });\n event.store[NEGOTIATOR_KEY] = value;\n return value;\n}\n","import { HeaderName } from '../../constants.ts';\nimport { getMimeType } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\nimport { getRequestHeader } from './header.ts';\nimport { useRequestNegotiator } from './negotiator.ts';\n\nexport function getRequestAcceptableContentTypes(event: IRoutupEvent) : string[] {\n const negotiator = useRequestNegotiator(event);\n\n return negotiator.mediaTypes();\n}\n\nexport function getRequestAcceptableContentType(event: IRoutupEvent, input?: string | string[]) : string | undefined {\n input = input || [];\n\n const items = Array.isArray(input) ? input : [input];\n\n if (items.length === 0) {\n return getRequestAcceptableContentTypes(event).shift();\n }\n\n const header = getRequestHeader(event, HeaderName.ACCEPT);\n if (!header) {\n return items[0];\n }\n\n let polluted = false;\n const mimeTypes : string[] = [];\n for (const item of items) {\n const mimeType = getMimeType(item);\n if (mimeType) {\n mimeTypes.push(mimeType);\n } else {\n polluted = true;\n }\n }\n\n const negotiator = useRequestNegotiator(event);\n const matches = negotiator.mediaTypes(mimeTypes);\n if (matches.length > 0) {\n if (polluted) {\n return items[0];\n }\n\n return items[mimeTypes.indexOf(matches[0]!)];\n }\n\n return undefined;\n}\n","import { getRequestAcceptableContentType } from '../../request/helpers/header-accept.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\ntype ResponseFormatHandler = () => Response | unknown;\n\ntype ResponseFormats = {\n default: ResponseFormatHandler,\n [key: string]: ResponseFormatHandler,\n};\n\nexport function sendFormat(event: IRoutupEvent, input: ResponseFormats): Response | unknown | undefined {\n const {\n default: formatDefault,\n ...formats\n } = input;\n\n const contentTypes = Object.keys(formats);\n\n if (contentTypes.length === 0) {\n return formatDefault();\n }\n\n const contentType = getRequestAcceptableContentType(event, contentTypes);\n if (contentType && formats[contentType]) {\n return formats[contentType]();\n }\n\n return formatDefault();\n}\n","import { RoutupError } from '../../error/module.ts';\nimport { sanitizeHeaderValue } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nfunction escapeHtml(str: string) : string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction isAllowedRedirectUrl(location: string) : boolean {\n // Block protocol-relative URLs (e.g. //evil.com)\n if (location.startsWith('//')) {\n return false;\n }\n\n if (location.startsWith('/') || location.startsWith('.')) {\n return true;\n }\n\n try {\n const url = new URL(location);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return true;\n }\n}\n\nexport function sendRedirect(event: IRoutupEvent, location: string, statusCode = 302): Response {\n if (!isAllowedRedirectUrl(location)) {\n throw new RoutupError({\n status: 400,\n message: 'Invalid redirect URL scheme.',\n });\n }\n\n const sanitizedLocation = sanitizeHeaderValue(location);\n const escapedLoc = escapeHtml(location);\n const html = `<!DOCTYPE html><html><head><meta http-equiv=\"refresh\" content=\"0; url=${escapedLoc}\"></head></html>`;\n\n const headers = new Headers(event.response.headers);\n headers.set('location', sanitizedLocation);\n headers.set('content-type', 'text/html; charset=utf-8');\n headers.delete('content-length');\n\n const response = new Response(html, {\n status: statusCode,\n headers,\n });\n\n return response;\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\n\nexport function sendStream(event: IRoutupEvent, stream: ReadableStream): Response {\n const {\n status,\n headers,\n } = event.response;\n\n return new Response(stream, {\n status,\n headers,\n });\n}\n","import type { RouterOptions } from '../router/types.ts';\nimport type {\n IRoutupEvent,\n RoutupRequest,\n RoutupResponse,\n} from './types.ts';\n\nexport type RoutupEventCreateContext = {\n request: RoutupRequest;\n params: Record<string, any>;\n path: string;\n method: string;\n mountPath: string;\n headers: Headers;\n searchParams: URLSearchParams;\n response: RoutupResponse;\n store: Record<string | symbol, unknown>;\n signal: AbortSignal;\n routerOptions: () => RouterOptions;\n next: (event: IRoutupEvent, error?: Error) => Promise<Response | undefined>;\n};\n\nexport class RoutupEvent implements IRoutupEvent {\n readonly request: RoutupRequest;\n\n readonly params: Record<string, any>;\n\n readonly path: string;\n\n readonly method: string;\n\n readonly mountPath: string;\n\n readonly headers: Headers;\n\n readonly searchParams: URLSearchParams;\n\n readonly response: RoutupResponse;\n\n readonly store: Record<string | symbol, unknown>;\n\n readonly signal: AbortSignal;\n\n protected _context: RoutupEventCreateContext;\n\n protected _routerOptions?: RouterOptions;\n\n protected _nextCalled = false;\n\n protected _nextResult: Promise<Response | undefined> | undefined;\n\n protected _nextCalledDeferred: {\n promise: Promise<void>,\n resolve: () => void,\n } | undefined;\n\n constructor(context: RoutupEventCreateContext) {\n this._context = context;\n this.request = context.request;\n this.params = context.params;\n this.path = context.path;\n this.method = context.method;\n this.mountPath = context.mountPath;\n this.headers = context.headers;\n this.searchParams = context.searchParams;\n this.response = context.response;\n this.store = context.store;\n this.signal = context.signal;\n }\n\n get routerOptions(): RouterOptions {\n if (!this._routerOptions) {\n this._routerOptions = this._context.routerOptions();\n }\n\n return this._routerOptions;\n }\n\n get nextCalled(): boolean {\n return this._nextCalled;\n }\n\n get nextResult(): Promise<Response | undefined> | undefined {\n return this._nextResult;\n }\n\n whenNextCalled(): Promise<void> {\n if (!this._nextCalledDeferred) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => { resolve = r; });\n this._nextCalledDeferred = { promise, resolve };\n\n if (this._nextCalled) {\n resolve();\n }\n }\n\n return this._nextCalledDeferred.promise;\n }\n\n async next(error?: Error): Promise<Response | undefined> {\n if (this._nextCalled) {\n return this._nextResult;\n }\n\n this._nextCalled = true;\n this._nextResult = this._context.next(this, error);\n\n if (this._nextCalledDeferred) {\n this._nextCalledDeferred.resolve();\n }\n\n return this._nextResult;\n }\n}\n","import { FastURL } from 'srvx';\nimport type { RoutupError } from '../error/module.ts';\nimport type { RouterOptions, RouterPathNode } from '../router/types.ts';\nimport { toResponse } from '../response/index.ts';\nimport { buildEtagFn } from '../utils/index.ts';\nimport { RoutupEvent } from '../event/module.ts';\nimport type {\n IRoutupEvent,\n NextFn,\n RoutupRequest,\n RoutupResponse,\n} from '../event/types.ts';\nimport type { IDispatcherEvent } from './types.ts';\n\nexport class DispatcherEvent implements IDispatcherEvent {\n readonly request: RoutupRequest;\n\n params: Record<string, any>;\n\n path: string;\n\n readonly method: string;\n\n /**\n * Collected allowed methods (for OPTIONS).\n */\n methodsAllowed: Set<string>;\n\n mountPath: string;\n\n error?: RoutupError;\n\n routerPath: RouterPathNode[];\n\n protected _dispatched: boolean;\n\n protected _response?: RoutupResponse;\n\n protected _store?: Record<string | symbol, unknown>;\n\n /**\n * Cached parsed URL (avoids double-parsing).\n */\n protected _url: InstanceType<typeof FastURL>;\n\n /**\n * Continuation function for middleware onion model.\n */\n protected _next?: (event: IRoutupEvent, error?: Error) => Promise<Response | undefined>;\n\n protected _signal?: AbortSignal;\n\n protected _signalCleanup?: () => void;\n\n /**\n * Whether _next has already been called (guard against double-invocation).\n */\n protected _nextCalled: boolean;\n\n /**\n * The cached result of the next handler.\n */\n protected _nextResult?: Promise<Response | undefined>;\n\n // ------------------------------------------------------------------------\n\n constructor(request: RoutupRequest) {\n this.request = request;\n this._url = new FastURL(request.url);\n this.method = request.method;\n this.path = this._url.pathname;\n this.mountPath = '/';\n this.params = {};\n this.routerPath = [];\n this.methodsAllowed = new Set();\n this._dispatched = false;\n this._nextCalled = false;\n }\n\n // ------------------------------------------------------------------------\n\n get response(): RoutupResponse {\n if (!this._response) {\n this._response = { status: 200, headers: new Headers() };\n }\n\n return this._response;\n }\n\n get signal(): AbortSignal {\n if (!this._signal) {\n this._signal = this.request.signal;\n }\n\n return this._signal;\n }\n\n set signal(value: AbortSignal) {\n // Clean up listeners from a previous merge\n if (this._signalCleanup) {\n this._signalCleanup();\n this._signalCleanup = undefined;\n }\n\n if (value === this.request.signal) {\n this._signal = value;\n return;\n }\n\n const controller = new AbortController();\n const abort = (e?: Event) => {\n const reason = e?.target instanceof AbortSignal ?\n e.target.reason :\n undefined;\n this.request.signal.removeEventListener('abort', abort);\n value.removeEventListener('abort', abort);\n controller.abort(reason);\n };\n\n if (this.request.signal.aborted || value.aborted) {\n const reason = this.request.signal.aborted ?\n this.request.signal.reason :\n value.reason;\n controller.abort(reason);\n } else {\n this.request.signal.addEventListener('abort', abort, { once: true });\n value.addEventListener('abort', abort, { once: true });\n this._signalCleanup = () => {\n this.request.signal.removeEventListener('abort', abort);\n value.removeEventListener('abort', abort);\n };\n }\n\n this._signal = controller.signal;\n }\n\n get dispatched(): boolean {\n return this._dispatched;\n }\n\n set dispatched(value: boolean) {\n this._dispatched = value;\n }\n\n // ------------------------------------------------------------------------\n\n protected async next(event: IRoutupEvent, error?: Error): Promise<Response | undefined> {\n if (this._nextCalled) {\n return this._nextResult;\n }\n this._nextCalled = true;\n\n if (this._next) {\n this._nextResult = this._next(event, error);\n }\n\n return this._nextResult;\n }\n\n setNext(fn?: NextFn): void {\n if (fn) {\n this._next = async (event, error?: Error) => {\n const result = await fn(error);\n return toResponse(result, event);\n };\n } else {\n this._next = undefined;\n }\n\n this._nextCalled = false;\n this._nextResult = undefined;\n }\n\n // ------------------------------------------------------------------------\n\n build(signal?: AbortSignal): RoutupEvent {\n return new RoutupEvent({\n request: this.request,\n params: this.params,\n path: this.path,\n method: this.method,\n mountPath: this.mountPath,\n headers: this.request.headers,\n searchParams: new URLSearchParams(this._url.search),\n response: this.response,\n store: this.store,\n signal: signal ?? this.signal,\n routerOptions: () => this.resolveOptions(),\n next: (event: IRoutupEvent, error?: Error) => this.next(event, error),\n });\n }\n\n // ------------------------------------------------------------------------\n\n protected get store(): Record<string | symbol, unknown> {\n if (!this._store) {\n this._store = Object.create(null) as Record<string | symbol, unknown>;\n }\n\n return this._store!;\n }\n\n protected resolveOptions(): RouterOptions {\n const resolved: RouterOptions = {\n trustProxy: () => false,\n subdomainOffset: 2,\n etag: buildEtagFn(),\n proxyIpMax: 0,\n };\n\n for (let i = 0; i < this.routerPath.length; i++) {\n const node = this.routerPath[i]!;\n const entries = Object.entries(node.options);\n for (const entry of entries) {\n const [key, value] = entry!;\n if (typeof value !== 'undefined') {\n (resolved as Record<string, unknown>)[key] = value;\n }\n }\n }\n\n return resolved;\n }\n}\n","export const HandlerType = {\n CORE: 'core',\n ERROR: 'error',\n} as const;\n\nexport type HandlerType = typeof HandlerType[keyof typeof HandlerType];\n\nexport const HandlerSymbol = Symbol.for('Handler');\n","export const HookName = {\n REQUEST: 'request',\n RESPONSE: 'response',\n ERROR: 'error',\n\n CHILD_MATCH: 'childMatch',\n CHILD_DISPATCH_BEFORE: 'childDispatchBefore',\n CHILD_DISPATCH_AFTER: 'childDispatchAfter',\n} as const;\n\nexport type HookName = typeof HookName[keyof typeof HookName];\n","import type { IDispatcherEvent } from '../dispatcher/types.ts';\nimport { createError } from '../error/create.ts';\nimport { HookName } from './constants.ts';\nimport type {\n HookDefaultListener,\n HookErrorListener,\n HookListener,\n HookUnsubscribeFn,\n} from './types.ts';\n\ntype HookEntry = {\n fn: HookListener;\n priority: number;\n};\n\nexport class HookManager {\n protected items: Record<string, HookEntry[]>;\n\n // --------------------------------------------------\n\n constructor() {\n this.items = {};\n }\n\n // --------------------------------------------------\n\n addListener(\n name: HookName,\n fn: HookListener,\n priority: number = 0,\n ): HookUnsubscribeFn {\n this.items[name] = this.items[name] || [];\n\n const entry: HookEntry = { fn, priority };\n\n // Insert in sorted position (higher priority first)\n let i = 0;\n while (i < this.items[name].length && this.items[name][i]!.priority >= priority) {\n i++;\n }\n this.items[name].splice(i, 0, entry);\n\n return () => {\n this.removeListener(name, fn);\n };\n }\n\n removeListener(name: HookName): void;\n\n removeListener(name: HookName, fn: HookListener): void;\n\n removeListener(name: HookName, fn?: HookListener): void {\n if (!this.items[name]) {\n return;\n }\n\n if (typeof fn === 'undefined') {\n delete this.items[name];\n return;\n }\n\n if (typeof fn === 'function') {\n const index = this.items[name].findIndex((entry) => entry.fn === fn);\n if (index !== -1) {\n this.items[name].splice(index, 1);\n }\n }\n\n if (this.items[name].length === 0) {\n delete this.items[name];\n }\n }\n\n // --------------------------------------------------\n\n async trigger(\n name: HookName,\n event: IDispatcherEvent,\n ): Promise<void> {\n if (!this.items[name] || this.items[name].length === 0) {\n return;\n }\n\n try {\n for (let i = 0; i < this.items[name].length; i++) {\n const { fn } = this.items[name][i]!;\n await this.triggerListener(name, event, fn);\n\n if (event.dispatched) {\n if (event.error) {\n event.error = undefined;\n }\n return;\n }\n }\n } catch (e) {\n if (!event.error) {\n event.error = createError(e);\n }\n\n if (!this.isErrorListenerHook(name)) {\n await this.trigger(HookName.ERROR, event);\n\n if (event.dispatched) {\n if (event.error) {\n event.error = undefined;\n }\n }\n }\n }\n }\n\n private triggerListener(name: HookName, event: IDispatcherEvent, listener: HookListener) {\n if (this.isErrorListenerHook(name)) {\n if (event.error) {\n return (listener as HookErrorListener)(event);\n }\n return undefined;\n }\n\n return (listener as HookDefaultListener)(event);\n }\n\n private isErrorListenerHook(input: HookName) {\n return input === HookName.ERROR;\n }\n}\n","import type { Key } from 'path-to-regexp';\nimport { pathToRegexp } from 'path-to-regexp';\nimport type { Path, PathMatcherExecResult, PathMatcherOptions } from './type.ts';\n\nfunction decodeParam(val: unknown) {\n /* istanbul ignore next */\n if (typeof val !== 'string' || val.length === 0) {\n return val;\n }\n\n try {\n return decodeURIComponent(val);\n } catch {\n return val;\n }\n}\n\nexport class PathMatcher {\n protected path: Path;\n\n protected regexp : RegExp;\n\n protected regexpKeys : Key[] = [];\n\n protected regexpOptions: PathMatcherOptions;\n\n constructor(path: Path, options?: PathMatcherOptions) {\n this.path = path;\n\n this.regexpOptions = options || {};\n const regexp = pathToRegexp(path, options);\n\n this.regexp = regexp.regexp;\n this.regexpKeys = regexp.keys;\n }\n\n test(path: string) {\n return this.regexp.test(path);\n }\n\n exec(path: string) : PathMatcherExecResult | undefined {\n if (\n this.path === '/' &&\n this.regexpOptions.end === false\n ) {\n return {\n path: '/',\n params: Object.create(null),\n };\n }\n\n const match = this.regexp.exec(path);\n\n if (!match) {\n return undefined;\n }\n\n const params : Record<string, unknown> = Object.create(null);\n\n for (let i = 1; i < match.length; i++) {\n const key = this.regexpKeys[i - 1];\n if (!key) continue;\n const prop = key.name;\n const val = decodeParam(match[i]);\n\n if (typeof val !== 'undefined') {\n params[prop] = val;\n }\n }\n\n return {\n path: match[0],\n params,\n };\n }\n}\n","import type { Path } from './type.ts';\n\nexport function isPath(input: unknown): input is Path {\n return typeof input === 'string';\n}\n","import { MethodName } from '../constants.ts';\nimport { PathMatcher } from '../path/index.ts';\nimport type { Path } from '../path/index.ts';\nimport { withLeadingSlash } from '../utils/index.ts';\n\n/**\n * Build a `PathMatcher` for a handler-side path.\n *\n * Returns `undefined` when no path is supplied. The `end` flag controls\n * whether the matcher requires a full match (`true` for method handlers\n * matching exact routes) or accepts a prefix (`false` for middleware).\n */\nexport function buildHandlerPathMatcher(\n path: Path | undefined,\n end: boolean,\n): PathMatcher | undefined {\n if (typeof path === 'undefined') {\n return undefined;\n }\n\n const normalized = typeof path === 'string' ? withLeadingSlash(path) : path;\n return new PathMatcher(normalized, { end });\n}\n\n/**\n * Match a request method against a handler's bound method.\n *\n * - When the handler has no method bound, matches every request method.\n * - Otherwise matches when the request method is the same.\n * - HEAD requests additionally match GET handlers.\n */\nexport function matchHandlerMethod(\n handlerMethod: MethodName | undefined,\n requestMethod: MethodName,\n): boolean {\n return !handlerMethod ||\n requestMethod === handlerMethod ||\n (requestMethod === MethodName.HEAD && handlerMethod === MethodName.GET);\n}\n","import { markInstanceof } from '@ebec/core';\nimport type { MethodName } from '../constants.ts';\nimport type { IDispatcher, IDispatcherEvent } from '../dispatcher/index.ts';\nimport { createError, isError } from '../error/index.ts';\nimport type { IRoutupEvent } from '../event/index.ts';\nimport { HookManager, HookName } from '../hook/index.ts';\nimport type { PathMatcher } from '../path/index.ts';\nimport { toResponse } from '../response/index.ts';\nimport type { RouterOptions } from '../router/types.ts';\nimport { toMethodName, withLeadingSlash } from '../utils/index.ts';\nimport { HandlerSymbol, HandlerType } from './constants.ts';\nimport type { HandlerOptions } from './types.ts';\nimport { buildHandlerPathMatcher } from './utils.ts';\n\nexport class Handler implements IDispatcher {\n protected config: HandlerOptions;\n\n protected hookManager: HookManager;\n\n protected pathMatcher: PathMatcher | undefined;\n\n readonly method: MethodName | undefined;\n\n // --------------------------------------------------\n\n constructor(handler: HandlerOptions) {\n this.config = handler;\n this.hookManager = new HookManager();\n\n this.mountHooks();\n\n if (typeof handler.path === 'string') {\n this.config.path = withLeadingSlash(handler.path);\n }\n\n this.pathMatcher = buildHandlerPathMatcher(this.config.path, !!this.config.method);\n this.method = this.config.method ? toMethodName(this.config.method) : undefined;\n\n markInstanceof(this, HandlerSymbol);\n }\n\n // --------------------------------------------------\n\n get type() {\n return this.config.type;\n }\n\n get path() {\n return this.config.path;\n }\n\n // --------------------------------------------------\n\n async dispatch(event: IDispatcherEvent): Promise<Response | undefined> {\n if (this.pathMatcher) {\n const pathMatch = this.pathMatcher.exec(event.path);\n if (pathMatch) {\n event.params = {\n ...event.params,\n ...pathMatch.params,\n };\n }\n }\n\n await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, event);\n if (event.dispatched) {\n return undefined;\n }\n\n let response: Response | undefined;\n\n try {\n let result: unknown;\n\n // Build a preliminary event to access routerOptions for timeout resolution\n const previewEvent = event.build();\n const effectiveTimeout = this.resolveTimeout(previewEvent.routerOptions);\n\n // When a per-handler timeout is active, create a child AbortController\n // linked to the parent signal so the handler's signal aborts on timeout\n let childController: AbortController | undefined;\n let cleanupParentListener: (() => void) | undefined;\n let handlerEvent = previewEvent;\n\n if (effectiveTimeout) {\n const parentSignal = event.signal;\n childController = new AbortController();\n\n if (parentSignal.aborted) {\n childController.abort(parentSignal.reason);\n } else {\n const onAbort = () => childController!.abort(parentSignal.reason);\n parentSignal.addEventListener('abort', onAbort, { once: true });\n cleanupParentListener = () => parentSignal.removeEventListener('abort', onAbort);\n }\n\n // Rebuild with the child signal so the handler sees it via event.signal\n handlerEvent = event.build(childController.signal);\n }\n\n try {\n if (this.config.type === HandlerType.ERROR) {\n if (event.error) {\n const { fn } = this.config;\n const { error } = event;\n result = await this.executeWithTimeout(\n () => this.resolveHandlerResult(\n fn(error, handlerEvent),\n handlerEvent,\n ),\n handlerEvent.routerOptions,\n childController,\n );\n }\n } else {\n const { fn } = this.config;\n result = await this.executeWithTimeout(\n () => this.resolveHandlerResult(\n fn(handlerEvent),\n handlerEvent,\n ),\n handlerEvent.routerOptions,\n childController,\n );\n }\n } finally {\n if (cleanupParentListener) {\n cleanupParentListener();\n }\n }\n\n response = await toResponse(result, handlerEvent);\n\n if (response) {\n event.dispatched = true;\n }\n } catch (e) {\n event.error = isError(e) ? e : createError(e);\n\n await this.hookManager.trigger(HookName.ERROR, event);\n\n if (event.dispatched) {\n event.error = undefined;\n } else {\n throw event.error;\n }\n }\n\n await this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, event);\n\n return response;\n }\n\n // --------------------------------------------------\n\n matchPath(path: string): boolean {\n if (!this.pathMatcher) {\n return true;\n }\n\n return this.pathMatcher.test(path);\n }\n\n // --------------------------------------------------\n\n /**\n * Resolve a handler's return value into the final value handed to `toResponse`.\n *\n * Contract:\n * - non-undefined value → return as-is (becomes the response)\n * - `undefined` + `event.next()` was called → forward downstream result\n * - `undefined` + `event.next()` not yet called → wait until either `next()` is\n * invoked (e.g. from an async callback) or `signal` aborts. A global or\n * per-handler timeout aborts `signal` and surfaces as 408. With no timeout\n * configured and no eventual `next()` call, the request hangs by design.\n */\n protected async resolveHandlerResult(\n invocation: unknown | Promise<unknown>,\n handlerEvent: IRoutupEvent,\n ): Promise<unknown> {\n const value = await invocation;\n if (typeof value !== 'undefined') {\n return value;\n }\n\n if (handlerEvent.nextCalled) {\n return handlerEvent.nextResult;\n }\n\n const { signal } = handlerEvent;\n\n if (signal.aborted) {\n throw createError({ status: 408, message: 'Request Timeout' });\n }\n\n return new Promise<unknown>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener('abort', onAbort);\n reject(createError({\n status: 408,\n message: 'Request Timeout',\n }));\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n handlerEvent.whenNextCalled().then(() => {\n signal.removeEventListener('abort', onAbort);\n resolve(handlerEvent.nextResult);\n });\n });\n }\n\n protected async executeWithTimeout(\n fn: () => unknown | Promise<unknown>,\n routerOptions: RouterOptions,\n controller?: AbortController,\n ): Promise<unknown> {\n const effectiveTimeout = this.resolveTimeout(routerOptions);\n\n if (!effectiveTimeout) {\n return fn();\n }\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n try {\n return await Promise.race([\n fn(),\n new Promise<never>((_, reject) => {\n timerId = setTimeout(() => {\n if (controller) {\n controller.abort();\n }\n reject(createError({\n status: 408,\n message: 'Request Timeout',\n }));\n }, effectiveTimeout);\n }),\n ]);\n } finally {\n clearTimeout(timerId);\n }\n }\n\n protected resolveTimeout(routerOptions: RouterOptions): number | undefined {\n const routerDefault = routerOptions.handlerTimeout;\n const handlerOverride = this.config.timeout;\n\n if (!routerDefault && !handlerOverride) {\n return undefined;\n }\n\n if (!routerDefault) {\n return handlerOverride;\n }\n\n if (!handlerOverride) {\n return routerDefault;\n }\n\n if (routerOptions.handlerTimeoutOverridable) {\n return handlerOverride;\n }\n\n return Math.min(routerDefault, handlerOverride);\n }\n\n protected mountHooks() {\n if (this.config.onBefore) {\n this.hookManager.addListener(HookName.CHILD_DISPATCH_BEFORE, this.config.onBefore);\n }\n\n if (this.config.onAfter) {\n this.hookManager.addListener(HookName.CHILD_DISPATCH_AFTER, this.config.onAfter);\n }\n\n if (this.config.onError) {\n this.hookManager.addListener(HookName.ERROR, this.config.onError);\n }\n }\n}\n","import { HandlerType } from '../constants.ts';\nimport { Handler } from '../module.ts';\nimport type {\n CoreHandler,\n CoreHandlerOptions,\n} from './types.ts';\n\n/**\n * Create a request handler.\n *\n * @param input - Handler function `(event) => value` or options object `{ fn, path?, method? }`\n *\n * @example\n * ```typescript\n * // Shorthand — function only\n * router.get('/', defineCoreHandler((event) => 'Hello'));\n *\n * // Verbose — with path and method\n * router.use(defineCoreHandler({\n * path: '/users/:id',\n * method: 'GET',\n * fn: (event) => ({ id: event.params.id }),\n * }));\n * ```\n */\nexport function defineCoreHandler(input: Omit<CoreHandlerOptions, | 'type'>) : Handler;\n\nexport function defineCoreHandler(input: CoreHandler) : Handler;\n\nexport function defineCoreHandler(input: any) : Handler {\n if (typeof input === 'function') {\n return new Handler({\n type: HandlerType.CORE,\n fn: input,\n });\n }\n\n return new Handler({\n type: HandlerType.CORE,\n ...input,\n });\n}\n","import { HandlerType } from '../constants.ts';\nimport { Handler } from '../module.ts';\nimport type {\n ErrorHandler,\n ErrorHandlerOptions,\n} from './types.ts';\n\n/**\n * Create an error handler.\n *\n * Error handlers receive errors thrown by preceding handlers in the pipeline.\n *\n * @param input - Handler function `(error, event) => value` or options object `{ fn, path? }`\n *\n * @example\n * ```typescript\n * router.use(defineErrorHandler((error, event) => {\n * return { message: error.message };\n * }));\n * ```\n */\nexport function defineErrorHandler(input: Omit<ErrorHandlerOptions, 'type'>) : Handler;\n\nexport function defineErrorHandler(input: ErrorHandler) : Handler;\nexport function defineErrorHandler(input: any) : Handler {\n if (typeof input === 'function') {\n return new Handler({\n type: HandlerType.ERROR,\n fn: input,\n });\n }\n\n return new Handler({\n type: HandlerType.ERROR,\n ...input,\n });\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { IRoutupEvent } from '../../../event/index.ts';\nimport { RoutupError } from '../../../error/module.ts';\nimport { defineCoreHandler } from '../../core/index.ts';\nimport type { Handler } from '../../module.ts';\nimport type { CoreHandler } from '../../core/types.ts';\nimport type { NodeHandler, NodeMiddleware } from './types.ts';\n\nconst kHandled = /* @__PURE__ */ Symbol('handled');\n\nfunction callHandler(\n handler: NodeHandler,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<typeof kHandled | void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const onClose = () => settle(kHandled);\n const onFinish = () => settle(kHandled);\n const onError = (error: Error) => fail(error);\n\n function cleanup() {\n res.removeListener('close', onClose);\n res.removeListener('finish', onFinish);\n res.removeListener('error', onError);\n }\n\n function settle(value: typeof kHandled | void) {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n }\n\n function fail(error: unknown) {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n\n res.once('close', onClose);\n res.once('finish', onFinish);\n res.once('error', onError);\n\n try {\n Promise.resolve(handler(req, res))\n .then(() => settle(kHandled))\n .catch(fail);\n } catch (error) {\n fail(error);\n }\n });\n}\n\nfunction callMiddleware(\n handler: NodeMiddleware,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<typeof kHandled | void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const onClose = () => settle(kHandled);\n const onFinish = () => settle(kHandled);\n const onError = (error: Error) => fail(error);\n\n function cleanup() {\n res.removeListener('close', onClose);\n res.removeListener('finish', onFinish);\n res.removeListener('error', onError);\n }\n\n function settle(value: typeof kHandled | void) {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n }\n\n function fail(error: unknown) {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n\n res.once('close', onClose);\n res.once('finish', onFinish);\n res.once('error', onError);\n\n try {\n Promise.resolve(\n handler(req, res, (error) => {\n if (error) {\n fail(error);\n } else {\n settle(res.writableEnded || res.destroyed ? kHandled : undefined);\n }\n }),\n ).catch(fail);\n } catch (error) {\n fail(error);\n }\n });\n}\n\nfunction createNodeBridge(handler: NodeHandler | NodeMiddleware, isMiddleware: boolean): Handler {\n if (typeof handler !== 'function') {\n throw new RoutupError('fromNodeHandler/fromNodeMiddleware expects a function.');\n }\n\n return defineCoreHandler({\n fn: (async (event: IRoutupEvent) => {\n const node = event.request.runtime?.node;\n if (!node?.req || !node?.res) {\n throw new RoutupError('fromNodeHandler/fromNodeMiddleware requires a Node.js runtime.');\n }\n\n const req = node.req as unknown as IncomingMessage;\n const res = node.res as unknown as ServerResponse;\n\n const result = isMiddleware ?\n await callMiddleware(handler as NodeMiddleware, req, res) :\n await callHandler(handler as NodeHandler, req, res);\n\n if (result === kHandled) {\n return null;\n }\n\n return event.next();\n }) as CoreHandler,\n });\n}\n\n/**\n * Wraps a Node.js `(req, res)` handler for use in the routup pipeline.\n *\n * @example\n * ```typescript\n * import { fromNodeHandler } from 'routup/node';\n *\n * router.use(fromNodeHandler((req, res) => {\n * res.end('Hello');\n * }));\n * ```\n */\nexport function fromNodeHandler(handler: NodeHandler): Handler {\n return createNodeBridge(handler, false);\n}\n\n/**\n * Wraps a Node.js `(req, res, next)` middleware for use in the routup pipeline.\n *\n * @example\n * ```typescript\n * import cors from 'cors';\n * import { fromNodeMiddleware } from 'routup/node';\n *\n * router.use(fromNodeMiddleware(cors()));\n * ```\n */\nexport function fromNodeMiddleware(handler: NodeMiddleware): Handler {\n return createNodeBridge(handler, true);\n}\n","import { isObject } from '../../../utils/index.ts';\nimport type { WebHandler, WebHandlerProvider } from './types.ts';\n\nexport function isWebHandlerProvider(input: unknown): input is WebHandlerProvider {\n return isObject(input) &&\n typeof input.fetch === 'function';\n}\n\nexport function isWebHandler(input: unknown): input is WebHandler {\n return typeof input === 'function';\n}\n","import type { IRoutupEvent } from '../../../event/index.ts';\nimport { RoutupError } from '../../../error/index.ts';\nimport { defineCoreHandler } from '../../core/index.ts';\nimport type { Handler } from '../../module.ts';\nimport { isWebHandlerProvider } from './is.ts';\nimport type { WebHandler, WebHandlerProvider } from './types.ts';\n\n/**\n * Create a handler from a Web Fetch API-compatible function or object.\n *\n * Wraps an external app (e.g. Hono, another Router) so it can be mounted\n * via `router.use()`. The original request is passed through as-is.\n *\n * @param input - Fetch function `(request) => Response` or object with a `fetch` method\n *\n * @experimental\n *\n * @example\n * ```ts\n * // Mount an object with a fetch method\n * router.use('/api', fromWebHandler(honoApp));\n *\n * // Mount a plain fetch function\n * router.use('/proxy', fromWebHandler((req) => fetch(req)));\n * ```\n */\nexport function fromWebHandler(input: WebHandler) : Handler;\n\nexport function fromWebHandler(input: WebHandlerProvider) : Handler;\n\nexport function fromWebHandler(input: any) : Handler {\n if (isWebHandlerProvider(input)) {\n return fromWebHandler(input.fetch.bind(input));\n }\n\n if (typeof input !== 'function') {\n throw new RoutupError('fromWebHandler expects a function or an object with a fetch method.');\n }\n\n return defineCoreHandler({ fn: (event: IRoutupEvent) => input(event.request) });\n}\n","import { hasInstanceof } from '@ebec/core';\nimport { isObject } from '../utils/index.ts';\nimport { HandlerSymbol } from './constants.ts';\nimport type { Handler } from './module.ts';\nimport type { HandlerOptions } from './types.ts';\n\nexport function isHandlerOptions(input: unknown) : input is HandlerOptions {\n return isObject(input) &&\n typeof input.fn === 'function' &&\n typeof input.type === 'string';\n}\n\nexport function isHandler(input: unknown): input is Handler {\n return hasInstanceof(input, HandlerSymbol);\n}\n\n","import { HeaderName } from '../../constants.ts';\n\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport function isRequestCacheable(event: IRoutupEvent, modifiedTime: string | Date) : boolean {\n const modifiedSince = event.headers.get(HeaderName.IF_MODIFIED_SINCE);\n if (!modifiedSince) {\n return false;\n }\n\n modifiedTime = typeof modifiedTime === 'string' ?\n new Date(modifiedTime) :\n modifiedTime;\n\n const sinceDate = new Date(modifiedSince);\n if (Number.isNaN(sinceDate.getTime()) || Number.isNaN(modifiedTime.getTime())) {\n return false;\n }\n\n return sinceDate >= modifiedTime;\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\nimport { useRequestNegotiator } from './negotiator.ts';\n\nexport function getRequestAcceptableCharsets(event: IRoutupEvent) : string[] {\n const negotiator = useRequestNegotiator(event);\n\n return negotiator.charsets();\n}\n\nexport function getRequestAcceptableCharset(event: IRoutupEvent, input: string | string[]) : string | undefined {\n input = input || [];\n\n const items = Array.isArray(input) ? input : [input];\n\n if (items.length === 0) {\n return getRequestAcceptableCharsets(event).shift();\n }\n\n const negotiator = useRequestNegotiator(event);\n return negotiator.charsets(items).shift() || undefined;\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\nimport { useRequestNegotiator } from './negotiator.ts';\n\nexport function getRequestAcceptableEncodings(event: IRoutupEvent) : string[] {\n const negotiator = useRequestNegotiator(event);\n return negotiator.encodings();\n}\n\nexport function getRequestAcceptableEncoding(event: IRoutupEvent, input: string | string[]) : string | undefined {\n input = input || [];\n\n const items = Array.isArray(input) ? input : [input];\n\n if (items.length === 0) {\n return getRequestAcceptableEncodings(event).shift();\n }\n\n const negotiator = useRequestNegotiator(event);\n return negotiator.encodings(items).shift() || undefined;\n}\n","import type { IRoutupEvent } from '../../event/index.ts';\nimport { useRequestNegotiator } from './negotiator.ts';\n\nexport function getRequestAcceptableLanguages(event: IRoutupEvent) : string[] {\n const negotiator = useRequestNegotiator(event);\n return negotiator.languages();\n}\n\nexport function getRequestAcceptableLanguage(event: IRoutupEvent, input?: string | string[]) : string | undefined {\n input = input || [];\n\n const items = Array.isArray(input) ? input : [input];\n\n if (items.length === 0) {\n return getRequestAcceptableLanguages(event).shift();\n }\n\n const negotiator = useRequestNegotiator(event);\n return negotiator.languages(items).shift() || undefined;\n}\n","import { HeaderName } from '../../constants.ts';\nimport { getMimeType } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\nimport { getRequestHeader } from './header.ts';\n\nexport function matchRequestContentType(event: IRoutupEvent, contentType: string) : boolean {\n const header = getRequestHeader(event, HeaderName.CONTENT_TYPE);\n if (!header) {\n return true;\n }\n\n return header.split(';')[0]!.trim() === getMimeType(contentType);\n}\n","import { HeaderName } from '../../constants.ts';\nimport type { TrustProxyFn, TrustProxyInput } from '../../utils/index.ts';\nimport { buildTrustProxyFn } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport type RequestHostNameOptions = {\n trustProxy?: TrustProxyInput,\n};\n\nexport function getRequestHostName(event: IRoutupEvent, options: RequestHostNameOptions = {}) : string | undefined {\n let trustProxy : TrustProxyFn;\n if (typeof options.trustProxy !== 'undefined') {\n trustProxy = buildTrustProxyFn(options.trustProxy);\n } else {\n trustProxy = event.routerOptions.trustProxy;\n }\n\n let hostname = event.headers.get(HeaderName.X_FORWARDED_HOST);\n if (!hostname || !event.request.ip || !trustProxy(event.request.ip, 0)) {\n hostname = event.headers.get(HeaderName.HOST);\n } else if (hostname && hostname.includes(',')) {\n hostname = hostname.substring(0, hostname.indexOf(',')).trimEnd();\n }\n\n if (!hostname) {\n return undefined;\n }\n\n // IPv6 literal support\n const offset = hostname[0] === '[' ?\n hostname.indexOf(']') + 1 :\n 0;\n const index = hostname.indexOf(':', offset);\n\n const result = index !== -1 ?\n hostname.substring(0, index) :\n hostname;\n\n // Reject hostnames with obviously invalid characters\n // eslint-disable-next-line no-control-regex\n if (/[\\x00-\\x1F\\x7F\\s/@\\\\]/.test(result)) {\n return undefined;\n }\n\n return result;\n}\n","import { HeaderName } from '../../constants.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\nimport type { TrustProxyFn, TrustProxyInput } from '../../utils/index.ts';\nimport { buildTrustProxyFn } from '../../utils/index.ts';\n\nexport type RequestIpOptions = {\n trustProxy?: TrustProxyInput,\n};\n\n/**\n * Get the client IP address from the request.\n *\n * When `trustProxy` is configured, walks the `X-Forwarded-For` chain\n * and returns the rightmost untrusted address (the actual client IP).\n * Falls back to `event.request.ip` (the direct connection IP).\n */\nexport function getRequestIP(event: IRoutupEvent, options: RequestIpOptions = {}) : string | undefined {\n let trustProxy : TrustProxyFn;\n if (typeof options.trustProxy !== 'undefined') {\n trustProxy = buildTrustProxyFn(options.trustProxy);\n } else {\n trustProxy = event.routerOptions.trustProxy;\n }\n\n const socketAddr = event.request.ip;\n if (!socketAddr) {\n return undefined;\n }\n\n // Build address list: [socket IP, ...forwarded addresses (rightmost first)]\n const forwarded = event.headers.get(HeaderName.X_FORWARDED_FOR);\n const addrs: string[] = [socketAddr];\n\n if (forwarded) {\n const parts = forwarded.split(',');\n for (let i = parts.length - 1; i >= 0; i--) {\n const addr = parts[i]!.trim();\n if (addr) {\n addrs.push(addr);\n }\n }\n }\n\n // Walk from socket (leftmost) to client (rightmost),\n // stopping at the first untrusted address\n for (let i = 0; i < addrs.length - 1; i++) {\n if (!trustProxy(addrs[i]!, i)) {\n return addrs[i];\n }\n }\n\n // All proxies trusted — return the original client (last in chain)\n return addrs[addrs.length - 1];\n}\n","import { HeaderName } from '../../constants.ts';\nimport type { TrustProxyFn, TrustProxyInput } from '../../utils/index.ts';\nimport { buildTrustProxyFn } from '../../utils/index.ts';\nimport type { IRoutupEvent } from '../../event/index.ts';\n\nexport type RequestProtocolOptions = {\n trustProxy?: TrustProxyInput,\n default?: string,\n};\n\nexport function getRequestProtocol(\n event: IRoutupEvent,\n options: RequestProtocolOptions = {},\n) : string {\n let trustProxy : TrustProxyFn;\n if (typeof options.trustProxy !== 'undefined') {\n trustProxy = buildTrustProxyFn(options.trustProxy);\n } else {\n trustProxy = event.routerOptions.trustProxy;\n }\n\n // Derive protocol from the request URL scheme\n let protocol : string;\n try {\n const url = new URL(event.request.url);\n if (url.protocol === 'https:') {\n protocol = 'https';\n } else {\n protocol = 'http';\n }\n } catch {\n protocol = options.default || 'http';\n }\n\n if (!event.request.ip || !trustProxy(event.request.ip, 0)) {\n return protocol;\n }\n\n const header = event.headers.get(HeaderName.X_FORWARDED_PROTO);\n if (!header) {\n return protocol;\n }\n\n const index = header.indexOf(',');\n\n const forwarded = index !== -1 ?\n header.substring(0, index).trim().toLowerCase() :\n header.trim().toLowerCase();\n\n if (forwarded === 'http' || forwarded === 'https') {\n return forwarded;\n }\n\n return protocol;\n}\n","export const PluginErrorCode = {\n PLUGIN: 'PLUGIN',\n NOT_INSTALLED: 'PLUGIN_NOT_INSTALLED',\n ALREADY_INSTALLED: 'PLUGIN_ALREADY_INSTALLED',\n INSTALL: 'PLUGIN_INSTALL',\n} as const;\n\nexport type PluginErrorCode = typeof PluginErrorCode[keyof typeof PluginErrorCode];\n","import { isError } from '../../error/is.ts';\nimport { PluginErrorCode } from './constants.ts';\nimport type { PluginError } from './module.ts';\n\nconst PLUGIN_ERROR_CODES = new Set<string>(Object.values(PluginErrorCode));\n\nexport function isPluginError(input: unknown): input is PluginError {\n if (!isError(input)) {\n return false;\n }\n\n return PLUGIN_ERROR_CODES.has(input.code);\n}\n","import type { HTTPErrorInput } from '@ebec/http';\nimport { RoutupError } from '../../error/module.ts';\nimport { PluginErrorCode } from './constants.ts';\n\nexport class PluginError extends RoutupError {\n constructor(input: HTTPErrorInput = {}) {\n const options = typeof input === 'string' ? { message: input } : { ...(input as object) };\n if (!('code' in options) || !(options as Record<string, unknown>).code) {\n (options as Record<string, unknown>).code = PluginErrorCode.PLUGIN;\n }\n super(options as HTTPErrorInput);\n this.name = 'PluginError';\n }\n}\n","import { PluginErrorCode } from '../constants.ts';\nimport { PluginError } from '../module.ts';\n\nexport class PluginAlreadyInstalledError extends PluginError {\n public readonly pluginName: string;\n\n constructor(pluginName: string) {\n super({\n message: `Plugin \"${pluginName}\" is already installed on this router.`,\n code: PluginErrorCode.ALREADY_INSTALLED,\n });\n this.name = 'PluginAlreadyInstalledError';\n this.pluginName = pluginName;\n }\n}\n","import { PluginErrorCode } from '../constants.ts';\nimport { PluginError } from '../module.ts';\n\nexport class PluginInstallError extends PluginError {\n public readonly pluginName: string;\n\n constructor(pluginName: string, cause?: Error) {\n super({\n message: `Failed to install plugin \"${pluginName}\".`,\n code: PluginErrorCode.INSTALL,\n cause,\n });\n this.name = 'PluginInstallError';\n this.pluginName = pluginName;\n }\n}\n","import { PluginErrorCode } from '../constants.ts';\nimport { PluginError } from '../module.ts';\n\nexport class PluginNotInstalledError extends PluginError {\n public readonly pluginName: string;\n\n public readonly helperName: string;\n\n constructor(pluginName: string, helperName: string) {\n super({\n message: `${helperName}() requires the \"${pluginName}\" plugin. ` +\n `Register it with: router.use(${pluginName}())`,\n code: PluginErrorCode.NOT_INSTALLED,\n });\n this.name = 'PluginNotInstalledError';\n this.pluginName = pluginName;\n this.helperName = helperName;\n }\n}\n","import { isObject } from '../utils/index.ts';\nimport type { Plugin } from './types.ts';\n\nexport function isPlugin(input: unknown): input is Plugin {\n if (!isObject(input)) {\n return false;\n }\n\n if (\n typeof input.name !== 'undefined' &&\n typeof input.name !== 'string'\n ) {\n return false;\n }\n\n return typeof input.install === 'function' &&\n input.install.length === 1;\n}\n","import { buildEtagFn, buildTrustProxyFn } from '../utils/index.ts';\nimport type { RouterOptions, RouterOptionsInput } from './types.ts';\n\nexport function normalizeRouterOptions(input: RouterOptionsInput): Partial<RouterOptions> {\n if (typeof input.etag !== 'undefined') {\n input.etag = buildEtagFn(input.etag);\n }\n\n if (typeof input.trustProxy !== 'undefined') {\n input.trustProxy = buildTrustProxyFn(input.trustProxy);\n }\n\n if (typeof input.timeout !== 'undefined') {\n if (\n typeof input.timeout !== 'number' ||\n !Number.isFinite(input.timeout) ||\n input.timeout <= 0\n ) {\n delete input.timeout;\n }\n }\n\n if (typeof input.handlerTimeout !== 'undefined') {\n if (\n typeof input.handlerTimeout !== 'number' ||\n !Number.isFinite(input.handlerTimeout) ||\n input.handlerTimeout <= 0\n ) {\n delete input.handlerTimeout;\n }\n }\n\n return input as Partial<RouterOptions>;\n}\n","export const RouterSymbol = Symbol.for('Router');\n\nexport const RouterPipelineStep = {\n START: 0,\n LOOKUP: 1,\n CHILD_BEFORE: 2,\n CHILD_DISPATCH: 3,\n CHILD_AFTER: 4,\n FINISH: 5,\n} as const;\n\nexport type RouterPipelineStep = typeof RouterPipelineStep[keyof typeof RouterPipelineStep];\n\nexport const RouterStackEntryType = {\n ROUTER: 'router',\n HANDLER: 'handler',\n} as const;\n\n\nexport type RouterStackEntryType = typeof RouterStackEntryType[keyof typeof RouterStackEntryType];\n","import { hasInstanceof } from '@ebec/core';\nimport type { Path } from '../path/index.ts';\nimport { PathMatcher } from '../path/index.ts';\nimport { withLeadingSlash, withoutTrailingSlash } from '../utils/index.ts';\nimport { RouterSymbol } from './constants.ts';\nimport type { Router } from './module.ts';\n\nexport function isRouterInstance(input: unknown): input is Router {\n return hasInstanceof(input, RouterSymbol);\n}\n\n/**\n * Build a non-terminal `PathMatcher` for a router mount path.\n *\n * Returns `undefined` when the path is the root (`/`) or omitted entirely —\n * a router mounted at the root has no intrinsic path filter.\n */\nexport function buildRouterPathMatcher(value?: Path): PathMatcher | undefined {\n if (value === '/' || typeof value === 'undefined') {\n return undefined;\n }\n\n return new PathMatcher(\n withLeadingSlash(withoutTrailingSlash(`${value}`)),\n { end: false },\n );\n}\n\n/**\n * Check if the request accepts JSON responses.\n * Matches application/json and +json suffixes (e.g. application/vnd.api+json).\n * Returns true if no Accept header is present (API-first default).\n */\nexport function acceptsJson(request: Request): boolean {\n const accept = request.headers.get('accept');\n if (!accept) {\n return true;\n }\n\n return accept.includes('application/json') ||\n accept.includes('+json') ||\n accept.includes('*/*');\n}\n","import { markInstanceof } from '@ebec/core';\nimport { HeaderName, MethodName } from '../constants.ts';\nimport { DispatcherEvent } from '../dispatcher/index.ts';\nimport type { IDispatcherEvent } from '../dispatcher/index.ts';\nimport type { RoutupRequest } from '../event/index.ts';\nimport { createError } from '../error/index.ts';\nimport {\n Handler,\n type HandlerOptions,\n HandlerType,\n buildHandlerPathMatcher,\n isHandler,\n isHandlerOptions,\n matchHandlerMethod,\n} from '../handler/index.ts';\nimport type {\n HookDefaultListener,\n HookErrorListener,\n HookListener,\n HookUnsubscribeFn,\n} from '../hook/index.ts';\nimport { HookManager, HookName } from '../hook/index.ts';\nimport type { Path, PathMatcher } from '../path/index.ts';\nimport { isPath } from '../path/index.ts';\nimport type { Plugin, PluginInstallContext } from '../plugin/index.ts';\nimport {\n PluginAlreadyInstalledError,\n isPlugin,\n} from '../plugin/index.ts';\nimport { normalizeRouterOptions } from './options.ts';\nimport {\n cleanDoubleSlashes,\n withLeadingSlash,\n} from '../utils/index.ts';\nimport { RouterPipelineStep, RouterStackEntryType, RouterSymbol } from './constants.ts';\nimport type {\n IRouter,\n RouterOptions,\n RouterOptionsInput,\n RouterPipelineContext,\n StackEntry,\n} from './types.ts';\nimport { acceptsJson, buildRouterPathMatcher, isRouterInstance } from './utils.ts';\n\nexport class Router implements IRouter {\n /**\n * A label for the router instance.\n */\n readonly name?: string;\n\n /**\n * Array of mounted layers, routes & routers, each tagged by kind so the\n * dispatch loop can discriminate without `isRouterInstance`/`isHandler`\n * runtime checks.\n *\n * @protected\n */\n protected stack: StackEntry[] = [];\n\n /**\n * Path matcher for the current mount path.\n *\n * @protected\n */\n protected pathMatcher: PathMatcher | undefined;\n\n /**\n * A hook manager.\n *\n * @protected\n */\n protected hookManager: HookManager;\n\n /**\n * Normalized options for this router instance.\n */\n protected _options: Partial<RouterOptions>;\n\n /**\n * Registry of installed plugins (name → version) on this router.\n *\n * @protected\n */\n protected plugins: Map<string, string | undefined> = new Map();\n\n // --------------------------------------------------\n\n constructor(input: RouterOptionsInput = {}) {\n this.name = input.name;\n\n this.hookManager = new HookManager();\n this._options = normalizeRouterOptions(input);\n this.pathMatcher = buildRouterPathMatcher(input.path);\n\n markInstanceof(this, RouterSymbol);\n }\n\n // --------------------------------------------------\n\n matchPath(path: string): boolean {\n if (this.pathMatcher) {\n return this.pathMatcher.test(path);\n }\n\n return true;\n }\n\n // --------------------------------------------------\n\n /**\n * Public entry point — creates a DispatcherEvent from the request,\n * runs the pipeline, and returns a Response (with 404/500 fallbacks).\n */\n async fetch(request: RoutupRequest): Promise<Response> {\n const event = new DispatcherEvent(request);\n\n let response: Response | undefined;\n\n try {\n const timeoutMs = this._options.timeout;\n\n if (timeoutMs) {\n const controller = new AbortController();\n event.signal = controller.signal;\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n try {\n response = await Promise.race([\n this.dispatch(event),\n new Promise<never>((_, reject) => {\n timerId = setTimeout(() => {\n controller.abort();\n reject(createError({\n status: 408,\n message: 'Request Timeout',\n }));\n }, timeoutMs);\n }),\n ]);\n } finally {\n clearTimeout(timerId);\n }\n } else {\n response = await this.dispatch(event);\n }\n } catch (e) {\n event.error = createError(e);\n }\n\n if (response) {\n return response;\n }\n\n if (event.error) {\n return this.buildFallbackResponse(\n request,\n event,\n event.error.status || 500,\n event.error.message,\n );\n }\n\n return this.buildFallbackResponse(request, event, 404, 'Not Found');\n }\n\n protected buildFallbackResponse(request: RoutupRequest, event: IDispatcherEvent, status: number, message: string): Response {\n const headers = new Headers(event.response.headers);\n\n if (acceptsJson(request)) {\n headers.set('content-type', 'application/json; charset=utf-8');\n return new Response(JSON.stringify({ status, message }), {\n status,\n headers,\n });\n }\n\n headers.set('content-type', 'text/plain; charset=utf-8');\n return new Response(message, {\n status,\n headers,\n });\n }\n\n // --------------------------------------------------\n\n protected async executePipelineStep(context: RouterPipelineContext): Promise<void> {\n while (context.step !== RouterPipelineStep.FINISH) {\n switch (context.step) {\n case RouterPipelineStep.START:\n await this.executePipelineStepStart(context); break;\n case RouterPipelineStep.LOOKUP:\n await this.executePipelineStepLookup(context); break;\n case RouterPipelineStep.CHILD_BEFORE:\n await this.executePipelineStepChildBefore(context); break;\n case RouterPipelineStep.CHILD_DISPATCH:\n await this.executePipelineStepChildDispatch(context); break;\n case RouterPipelineStep.CHILD_AFTER:\n await this.executePipelineStepChildAfter(context); break;\n default:\n context.step = RouterPipelineStep.FINISH; break;\n }\n }\n\n await this.executePipelineStepFinish(context);\n }\n\n protected async executePipelineStepStart(context: RouterPipelineContext): Promise<void> {\n await this.hookManager.trigger(HookName.REQUEST, context.event);\n\n if (context.event.dispatched) {\n context.step = RouterPipelineStep.FINISH;\n } else {\n context.step = RouterPipelineStep.LOOKUP;\n }\n }\n\n protected async executePipelineStepLookup(context: RouterPipelineContext): Promise<void> {\n while (\n !context.event.dispatched &&\n context.stackIndex < this.stack.length\n ) {\n const entry = this.stack[context.stackIndex]!;\n\n if (entry.type === RouterStackEntryType.HANDLER) {\n const handler = entry.data;\n\n if (\n (context.event.error && handler.type === HandlerType.CORE) ||\n (!context.event.error && handler.type === HandlerType.ERROR)\n ) {\n context.stackIndex++;\n continue;\n }\n\n const match = entry.pathMatcher ?\n entry.pathMatcher.test(context.event.path) :\n handler.matchPath(context.event.path);\n\n if (match) {\n const method = entry.method ?? handler.method;\n\n if (method) {\n context.event.methodsAllowed.add(method);\n }\n\n if (matchHandlerMethod(method, context.event.method as MethodName)) {\n await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);\n\n if (context.event.dispatched) {\n context.step = RouterPipelineStep.FINISH;\n } else {\n context.step = RouterPipelineStep.CHILD_BEFORE;\n }\n\n return;\n }\n }\n\n context.stackIndex++;\n continue;\n }\n\n const match = entry.pathMatcher ?\n entry.pathMatcher.test(context.event.path) :\n entry.data.matchPath(context.event.path);\n\n if (match) {\n await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);\n\n if (context.event.dispatched) {\n context.step = RouterPipelineStep.FINISH;\n } else {\n context.step = RouterPipelineStep.CHILD_BEFORE;\n }\n\n return;\n }\n\n context.stackIndex++;\n }\n\n context.step = RouterPipelineStep.FINISH;\n }\n\n protected async executePipelineStepChildBefore(context: RouterPipelineContext): Promise<void> {\n await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, context.event);\n\n if (context.event.dispatched) {\n context.step = RouterPipelineStep.FINISH;\n } else {\n context.step = RouterPipelineStep.CHILD_DISPATCH;\n }\n }\n\n protected async executePipelineStepChildAfter(context: RouterPipelineContext): Promise<void> {\n await this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, context.event);\n\n if (context.event.dispatched) {\n context.step = RouterPipelineStep.FINISH;\n } else {\n context.step = RouterPipelineStep.LOOKUP;\n }\n }\n\n protected async executePipelineStepChildDispatch(context: RouterPipelineContext): Promise<void> {\n const entry = this.stack[context.stackIndex];\n\n if (context.event.dispatched || typeof entry === 'undefined') {\n context.step = RouterPipelineStep.FINISH;\n return;\n }\n\n const { event } = context;\n\n // Snapshot routing state so we can restore it if the entry yields no\n // response. Without this, a child router that walks past its last\n // handler (e.g. its tail middleware calls next()) would leave the\n // event's path stripped of this entry's mount prefix, and subsequent\n // siblings in the parent's stack would fail to match.\n const savedPath = event.path;\n const savedMountPath = event.mountPath;\n const savedParams = event.params;\n\n if (entry.type === RouterStackEntryType.ROUTER && entry.pathMatcher) {\n // Router mount: strip the matched prefix off event.path so the\n // child router's pipeline sees a mount-relative path. The child\n // router's intrinsic pathMatcher (if any) is applied on top\n // inside its own dispatch.\n const output = entry.pathMatcher.exec(event.path);\n if (typeof output !== 'undefined') {\n event.mountPath = cleanDoubleSlashes(`${event.mountPath}/${output.path}`);\n\n if (event.path === output.path) {\n event.path = '/';\n } else {\n event.path = withLeadingSlash(event.path.substring(output.path.length));\n }\n\n event.params = {\n ...event.params,\n ...output.params,\n };\n }\n } else if (entry.type === RouterStackEntryType.HANDLER && entry.pathMatcher) {\n // Handler mount: extract route params from the mount matcher.\n // Handlers don't strip the path — they're leaves.\n const output = entry.pathMatcher.exec(event.path);\n if (typeof output !== 'undefined') {\n event.params = {\n ...event.params,\n ...output.params,\n };\n }\n }\n\n try {\n event.setNext(async (error?: Error) => {\n if (error) {\n event.error = createError(error);\n }\n\n // Continue pipeline from the next stack item\n const nextContext: RouterPipelineContext = {\n step: RouterPipelineStep.LOOKUP,\n event,\n stackIndex: context.stackIndex + 1,\n response: undefined,\n };\n\n await this.executePipelineStep(nextContext);\n\n return nextContext.response;\n });\n\n const response = await entry.data.dispatch(event);\n\n if (response) {\n context.response = response;\n event.dispatched = true;\n }\n } catch (e) {\n event.error = createError(e);\n\n await this.hookManager.trigger(HookName.ERROR, event);\n }\n\n if (!event.dispatched) {\n event.path = savedPath;\n event.mountPath = savedMountPath;\n event.params = savedParams;\n }\n\n context.stackIndex++;\n context.step = RouterPipelineStep.CHILD_AFTER;\n }\n\n protected async executePipelineStepFinish(context: RouterPipelineContext): Promise<void> {\n if (context.event.error || context.event.dispatched) {\n return this.hookManager.trigger(HookName.RESPONSE, context.event);\n }\n\n if (\n !context.event.dispatched &&\n context.event.routerPath.length === 1 &&\n context.event.method &&\n context.event.method === MethodName.OPTIONS\n ) {\n if (context.event.methodsAllowed.has(MethodName.GET)) {\n context.event.methodsAllowed.add(MethodName.HEAD);\n }\n\n const options = [...context.event.methodsAllowed]\n .map((key) => key.toUpperCase())\n .join(',');\n\n const optionsHeaders = new Headers(context.event.response.headers);\n optionsHeaders.set(HeaderName.ALLOW, options);\n context.response = new Response(options, {\n status: context.event.response.status || 200,\n headers: optionsHeaders,\n });\n\n context.event.dispatched = true;\n }\n\n return this.hookManager.trigger(HookName.RESPONSE, context.event);\n }\n\n // --------------------------------------------------\n\n async dispatch(\n event: IDispatcherEvent,\n ): Promise<Response | undefined> {\n const savedPath = event.path;\n const savedMountPath = event.mountPath;\n const savedParams = event.params;\n\n if (this.pathMatcher) {\n const output = this.pathMatcher.exec(event.path);\n if (typeof output !== 'undefined') {\n event.mountPath = cleanDoubleSlashes(`${event.mountPath}/${output.path}`);\n\n if (event.path === output.path) {\n event.path = '/';\n } else {\n event.path = withLeadingSlash(event.path.substring(output.path.length));\n }\n\n event.params = {\n ...event.params,\n ...output.params,\n };\n }\n }\n\n const context: RouterPipelineContext = {\n step: RouterPipelineStep.START,\n event,\n stackIndex: 0,\n };\n\n event.routerPath.push({ name: this.name, options: this._options });\n\n try {\n await this.executePipelineStep(context);\n } finally {\n event.routerPath.pop();\n\n // Restore routing state when this router did not produce a\n // response, so the caller's pipeline (a parent router) sees its\n // own pre-dispatch path/mountPath/params for subsequent siblings.\n if (!event.dispatched) {\n event.path = savedPath;\n event.mountPath = savedMountPath;\n event.params = savedParams;\n }\n }\n\n return context.response;\n }\n\n // --------------------------------------------------\n\n delete(...handlers: (Handler | HandlerOptions)[]): this;\n\n delete(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n delete(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.DELETE, ...input);\n\n return this;\n }\n\n get(...handlers: (Handler | HandlerOptions)[]): this;\n\n get(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n get(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.GET, ...input);\n\n return this;\n }\n\n post(...handlers: (Handler | HandlerOptions)[]): this;\n\n post(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n post(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.POST, ...input);\n\n return this;\n }\n\n put(...handlers: (Handler | HandlerOptions)[]): this;\n\n put(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n put(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.PUT, ...input);\n\n return this;\n }\n\n patch(...handlers: (Handler | HandlerOptions)[]): this;\n\n patch(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n patch(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.PATCH, ...input);\n\n return this;\n }\n\n head(...handlers: (Handler | HandlerOptions)[]): this;\n\n head(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n head(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.HEAD, ...input);\n\n return this;\n }\n\n options(...handlers: (Handler | HandlerOptions)[]): this;\n\n options(path: Path, ...handlers: (Handler | HandlerOptions)[]): this;\n\n options(...input: (Path | Handler | HandlerOptions)[]): this {\n this.useForMethod(MethodName.OPTIONS, ...input);\n\n return this;\n }\n\n // --------------------------------------------------\n\n protected useForMethod(\n method: MethodName,\n ...input: (Path | Handler | HandlerOptions)[]\n ) {\n let path: Path | undefined;\n\n for (const element of input) {\n if (isPath(element)) {\n path = element;\n continue;\n }\n\n let handler: Handler;\n if (isHandlerOptions(element)) {\n // Construct a fresh Handler from a copy of the options so the\n // user's options object is never mutated.\n handler = new Handler({\n ...element,\n method,\n path: path ?? element.path,\n });\n } else if (isHandler(element)) {\n handler = element;\n } else {\n continue;\n }\n\n this.stack.push({\n type: RouterStackEntryType.HANDLER,\n data: handler,\n method,\n pathMatcher: buildHandlerPathMatcher(path ?? handler.path, true),\n });\n }\n }\n\n // --------------------------------------------------\n\n use(router: Router): this;\n\n use(handler: Handler | HandlerOptions): this;\n\n use(plugin: Plugin): this;\n\n use(path: Path, router: Router): this;\n\n use(path: Path, handler: Handler | HandlerOptions): this;\n\n use(path: Path, plugin: Plugin): this;\n\n use(...input: unknown[]): this {\n let path: Path | undefined;\n for (const item of input) {\n if (isPath(item)) {\n path = withLeadingSlash(item);\n continue;\n }\n\n if (isRouterInstance(item)) {\n this.stack.push({\n type: RouterStackEntryType.ROUTER,\n data: item,\n pathMatcher: buildRouterPathMatcher(path),\n });\n continue;\n }\n\n if (isHandlerOptions(item)) {\n const handler = new Handler({\n ...item,\n path: path ?? item.path,\n });\n\n this.stack.push({\n type: RouterStackEntryType.HANDLER,\n data: handler,\n });\n continue;\n }\n\n if (isHandler(item)) {\n this.stack.push({\n type: RouterStackEntryType.HANDLER,\n data: item,\n pathMatcher: buildHandlerPathMatcher(path, !!item.method),\n });\n continue;\n }\n\n if (isPlugin(item)) {\n if (path) {\n this.install(item, { path });\n } else {\n this.install(item);\n }\n }\n }\n\n return this;\n }\n\n // --------------------------------------------------\n\n /**\n * Check if a plugin with the given name is installed on this router.\n */\n hasPlugin(name: string): boolean {\n return this.plugins.has(name);\n }\n\n /**\n * Get the version of an installed plugin by name on this router,\n * or `undefined` if the plugin is not installed here.\n */\n getPluginVersion(name: string): string | undefined {\n return this.plugins.get(name);\n }\n\n // --------------------------------------------------\n\n protected install(\n plugin: Plugin,\n context: PluginInstallContext = {},\n ): this {\n if (this.plugins.has(plugin.name)) {\n throw new PluginAlreadyInstalledError(plugin.name);\n }\n\n const router = new Router({ name: plugin.name });\n plugin.install(router);\n\n if (context.path) {\n this.use(context.path, router);\n } else {\n this.use(router);\n }\n\n this.plugins.set(plugin.name, plugin.version);\n\n return this;\n }\n\n //---------------------------------------------------------------------------------\n\n /**\n * Add a hook listener.\n *\n * @param name\n * @param fn\n */\n on(\n name: typeof HookName.REQUEST |\n typeof HookName.RESPONSE |\n typeof HookName.CHILD_DISPATCH_BEFORE |\n typeof HookName.CHILD_DISPATCH_AFTER,\n fn: HookDefaultListener,\n priority?: number,\n ): HookUnsubscribeFn;\n\n on(\n name: typeof HookName.CHILD_MATCH,\n fn: HookDefaultListener,\n priority?: number,\n ): HookUnsubscribeFn;\n\n on(\n name: typeof HookName.ERROR,\n fn: HookErrorListener,\n priority?: number,\n ): HookUnsubscribeFn;\n\n on(name: HookName, fn: HookListener, priority?: number): HookUnsubscribeFn {\n return this.hookManager.addListener(name, fn, priority);\n }\n\n /**\n * Remove single or all hook listeners.\n *\n * @param name\n */\n off(name: HookName): this;\n\n off(name: HookName, fn: HookListener): this;\n\n off(name: HookName, fn?: HookListener): this {\n if (typeof fn === 'undefined') {\n this.hookManager.removeListener(name);\n\n return this;\n }\n\n this.hookManager.removeListener(name, fn);\n return this;\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "routup",
3
- "version": "5.0.1",
3
+ "version": "5.1.1",
4
4
  "type": "module",
5
5
  "description": "Routup is a minimalistic http based routing framework.",
6
6
  "exports": {
@@ -100,7 +100,8 @@
100
100
  },
101
101
  "homepage": "https://github.com/routup/routup#readme",
102
102
  "dependencies": {
103
- "@ebec/http": "^4.0.0",
103
+ "@ebec/core": "^1.1.0",
104
+ "@ebec/http": "^4.1.0",
104
105
  "mime-explorer": "^1.1.0",
105
106
  "negotiator": "^1.0.0",
106
107
  "path-to-regexp": "^8.4.2",
@@ -114,13 +115,13 @@
114
115
  "@tada5hi/eslint-config": "^2.3.0",
115
116
  "@tada5hi/tsconfig": "^0.7.2",
116
117
  "@types/negotiator": "^0.6.4",
117
- "@types/node": "^25.6.0",
118
+ "@types/node": "^25.6.2",
118
119
  "@types/proxy-addr": "^2.0.3",
119
120
  "@vitest/coverage-v8": "^4.1.5",
120
121
  "eslint": "^10.3.0",
121
- "eslint-plugin-vue": "^10.9.0",
122
+ "eslint-plugin-vue": "^10.9.1",
122
123
  "husky": "^9.1.7",
123
- "tsdown": "^0.21.10",
124
+ "tsdown": "^0.22.0",
124
125
  "typescript": "^6.0.3",
125
126
  "typescript-eslint": "^8.59.2",
126
127
  "vitest": "^4.1.1"