ingenium 0.0.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.
- package/LICENSE +21 -0
- package/README.md +943 -0
- package/dist/index.cjs +7078 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4262 -0
- package/dist/index.d.ts +4262 -0
- package/dist/index.js +6963 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
- package/src/api-key/middleware.ts +157 -0
- package/src/api-key/types.ts +37 -0
- package/src/app/scope.ts +392 -0
- package/src/app.ts +1752 -0
- package/src/body/limit.ts +21 -0
- package/src/body/middleware.ts +30 -0
- package/src/body/multipart-types.ts +40 -0
- package/src/body/multipart.ts +254 -0
- package/src/context/body.ts +324 -0
- package/src/context/context.ts +650 -0
- package/src/context/cookies.ts +282 -0
- package/src/context/pool.ts +32 -0
- package/src/cors/middleware.ts +182 -0
- package/src/cors/types.ts +79 -0
- package/src/cron/parser.ts +311 -0
- package/src/cron/registry.ts +49 -0
- package/src/cron/scheduler.ts +153 -0
- package/src/csrf/middleware.ts +224 -0
- package/src/csrf/types.ts +65 -0
- package/src/errors.ts +148 -0
- package/src/idempotency/middleware.ts +197 -0
- package/src/idempotency/store.ts +70 -0
- package/src/idempotency/types.ts +87 -0
- package/src/index.ts +328 -0
- package/src/jobs/queue.ts +306 -0
- package/src/jobs/registry.ts +82 -0
- package/src/jobs/store-memory.ts +113 -0
- package/src/jobs/types.ts +135 -0
- package/src/jwt/jwks.ts +143 -0
- package/src/jwt/middleware.ts +313 -0
- package/src/jwt/types.ts +137 -0
- package/src/jwt/verify.ts +370 -0
- package/src/middleware/compose.ts +94 -0
- package/src/middleware/types.ts +37 -0
- package/src/negotiation/accept.ts +159 -0
- package/src/negotiation/etag.ts +30 -0
- package/src/negotiation/format.ts +88 -0
- package/src/negotiation/fresh.ts +89 -0
- package/src/negotiation/json-etag.ts +122 -0
- package/src/negotiation/negotiate.ts +97 -0
- package/src/openapi/describe.ts +79 -0
- package/src/openapi/extract-params.ts +62 -0
- package/src/openapi/generate.ts +251 -0
- package/src/openapi/handler.ts +73 -0
- package/src/openapi/types.ts +145 -0
- package/src/plugin/decorators.ts +100 -0
- package/src/plugin/hooks.ts +114 -0
- package/src/plugin/types.ts +189 -0
- package/src/problem/middleware.ts +55 -0
- package/src/problem/serialize.ts +121 -0
- package/src/problem/types.ts +68 -0
- package/src/proxy/trust.ts +247 -0
- package/src/rate-limit/middleware.ts +72 -0
- package/src/rate-limit/store.ts +129 -0
- package/src/rate-limit/types.ts +60 -0
- package/src/response/reflect.ts +93 -0
- package/src/router/router.ts +284 -0
- package/src/router/trie.ts +309 -0
- package/src/router/types.ts +54 -0
- package/src/schema/standard.ts +67 -0
- package/src/session/middleware.ts +379 -0
- package/src/session/store-memory.ts +79 -0
- package/src/session/types.ts +95 -0
- package/src/sinatra/filters.ts +129 -0
- package/src/sinatra/top-level.ts +151 -0
- package/src/sse/keep-alive.ts +52 -0
- package/src/sse/sse.ts +115 -0
- package/src/static/middleware.ts +254 -0
- package/src/static/types.ts +31 -0
- package/src/transport/http2-helpers.ts +242 -0
- package/src/transport/http2.ts +316 -0
- package/src/transport/node.ts +261 -0
- package/src/transport/shutdown.ts +86 -0
- package/src/transport/types.ts +72 -0
- package/src/util/safe-json.ts +66 -0
- package/src/ws/index.ts +164 -0
- package/src/ws/middleware.ts +178 -0
- package/src/ws/types.ts +52 -0
- package/src/ws/ws-node-adapter.ts +162 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/body/limit.ts","../src/body/multipart.ts","../src/schema/standard.ts","../src/context/body.ts","../src/context/cookies.ts","../src/proxy/trust.ts","../src/negotiation/accept.ts","../src/negotiation/negotiate.ts","../src/negotiation/format.ts","../src/negotiation/fresh.ts","../src/negotiation/etag.ts","../src/negotiation/json-etag.ts","../src/context/context.ts","../src/context/pool.ts","../src/response/reflect.ts","../src/middleware/compose.ts","../src/plugin/decorators.ts","../src/plugin/hooks.ts","../src/router/router.ts","../src/sinatra/filters.ts","../src/app/scope.ts","../src/router/trie.ts","../src/transport/node.ts","../src/openapi/describe.ts","../src/jobs/store-memory.ts","../src/jobs/queue.ts","../src/jobs/registry.ts","../src/cron/parser.ts","../src/cron/scheduler.ts","../src/cron/registry.ts","../src/app.ts","../src/body/middleware.ts","../src/static/middleware.ts","../src/cors/middleware.ts","../src/sse/sse.ts","../src/rate-limit/store.ts","../src/rate-limit/middleware.ts","../src/csrf/middleware.ts","../src/problem/serialize.ts","../src/problem/middleware.ts","../src/idempotency/store.ts","../src/idempotency/middleware.ts","../src/jwt/verify.ts","../src/jwt/jwks.ts","../src/jwt/middleware.ts","../src/api-key/middleware.ts","../src/openapi/extract-params.ts","../src/openapi/generate.ts","../src/openapi/handler.ts","../src/router/types.ts","../src/util/safe-json.ts","../src/transport/http2-helpers.ts","../src/transport/http2.ts","../src/transport/shutdown.ts","../src/sse/keep-alive.ts","../src/session/store-memory.ts","../src/session/middleware.ts","../src/ws/middleware.ts","../src/ws/ws-node-adapter.ts","../src/ws/index.ts","../src/sinatra/top-level.ts","../src/index.ts"],"names":["Buffer","path","resolve","head","result","normalizeEtag","IS_DEV","normalizePrefix","normalizePath","remaining","EMPTY_PARAMS","options","Readable","after","createHmac","timingSafeEqual","token","appendSetCookie","problem","instance","DEFAULT_METHODS","readHeader","cryptoVerify","cryptoConstants","createPublicKey","cache","h2","createH2Server","createH2cServer","MemoryStore","parseCookieHeader","verifySigned","randomBytes","createServer","handleRequest","populateContext","writeResponse"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error class for all framework-emitted errors. Errors that extend\n * `IngeniumError` are caught by the global error boundary and serialized to the\n * client according to their `statusCode` and `code`.\n */\nexport class IngeniumError extends Error {\n /**\n * @param statusCode HTTP status code to send to the client.\n * @param code Machine-readable error code (UPPER_SNAKE_CASE convention).\n * @param message Human-readable error message.\n * @param cause Optional underlying error.\n */\n constructor(\n public readonly statusCode: number,\n public readonly code: string,\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = new.target.name\n }\n}\n\n/** 404 — no route matched. */\nexport class IngeniumNotFoundError extends IngeniumError {\n constructor(message = 'Not Found') {\n super(404, 'NOT_FOUND', message)\n }\n}\n\n/** 401 — authentication required or invalid. */\nexport class IngeniumUnauthorizedError extends IngeniumError {\n constructor(message = 'Unauthorized') {\n super(401, 'UNAUTHORIZED', message)\n }\n}\n\n/**\n * 405 — path matched but method did not. Includes the list of allowed methods,\n * which the framework writes into the `Allow` response header automatically.\n */\nexport class IngeniumMethodNotAllowedError extends IngeniumError {\n constructor(public readonly allowed: readonly string[], message = 'Method Not Allowed') {\n super(405, 'METHOD_NOT_ALLOWED', message)\n }\n}\n\n/** 413 — request body exceeded the configured `maxBytes` limit. */\nexport class IngeniumPayloadTooLargeError extends IngeniumError {\n constructor(message = 'Payload Too Large') {\n super(413, 'PAYLOAD_TOO_LARGE', message)\n }\n}\n\n/**\n * 422 — request body parsed successfully but failed validation. The `fields`\n * map is serialized into the response body so clients can render field-level\n * error messages.\n */\nexport class IngeniumValidationError extends IngeniumError {\n constructor(public readonly fields: Record<string, string>, message = 'Validation Failed') {\n super(422, 'VALIDATION_FAILED', message)\n }\n}\n\n/** 400 — request was malformed (bad JSON, invalid content-type, etc). */\nexport class IngeniumBadRequestError extends IngeniumError {\n constructor(message = 'Bad Request', cause?: unknown) {\n super(400, 'BAD_REQUEST', message, cause)\n }\n}\n\n/**\n * 500 — caller attempted to write a header name or value containing CR or\n * LF. Node would eventually reject these at the wire level, but the late\n * throw produces a useless stack — we fail fast at the call site so the\n * offending header (and the route that set it) shows up in the trace.\n */\nexport class IngeniumHeaderInjectionError extends IngeniumError {\n constructor(message = 'Header value contains CR/LF (possible header injection)') {\n super(500, 'HEADER_INJECTION', message)\n }\n}\n\n/**\n * 500 — `ctx.json` (or `respondJsonWithEtag`) was handed a value that\n * `JSON.stringify` cannot serialize: a circular structure, a `BigInt`, or\n * any other unsupported shape. The original `TypeError` is attached as\n * `cause` and emitted via `process.emitWarning` for diagnostics.\n */\nexport class IngeniumUnserializableError extends IngeniumError {\n constructor(message: string, cause?: unknown) {\n super(500, 'UNSERIALIZABLE_RESPONSE', message, cause)\n }\n}\n\n/**\n * Sinatra-style `halt` short-circuit. Thrown by `ctx.halt(status, body?)`;\n * caught by the default error boundary and serialized according to `bodyShape`:\n *\n * - `'none'` → boundary uses default `{ error, code: 'HALT' }` JSON shape.\n * - `'text'` → boundary writes `body` as `text/plain` verbatim.\n * - `'json'` → boundary writes `body` as `application/json`.\n *\n * The body shape is decided at the call site (string ⇒ text, object ⇒ json,\n * undefined ⇒ none) so the boundary can branch without re-inspecting types.\n * Custom `app.onError` handlers still receive the error and can override it\n * (e.g. add a header, reshape the body) by writing the response themselves.\n */\nexport class IngeniumHaltError extends IngeniumError {\n /** What the default error boundary should do with `body`. */\n readonly bodyShape: 'none' | 'text' | 'json'\n /** The body argument from `ctx.halt(status, body?)`. */\n readonly body: string | Record<string, unknown> | undefined\n\n constructor(statusCode: number, body?: string | Record<string, unknown>) {\n let shape: 'none' | 'text' | 'json'\n let message: string\n if (body === undefined) {\n shape = 'none'\n message = `Halted with status ${statusCode}`\n } else if (typeof body === 'string') {\n shape = 'text'\n message = body\n } else {\n shape = 'json'\n // Best-effort message for ctx.error / logging; the JSON body is the\n // wire-level payload regardless.\n message = typeof body['error'] === 'string' ? (body['error'] as string) : 'HALT'\n }\n super(statusCode, 'HALT', message)\n this.bodyShape = shape\n this.body = body\n }\n}\n\n/**\n * 503 — handler exceeded the configured `requestTimeoutMs` ceiling. The\n * orphaned handler is NOT cancelled (JavaScript can't safely cancel a\n * Promise); the framework just stops waiting for it. Late writes from the\n * orphaned handler are guarded by the per-request epoch counter on the\n * context and discarded with a `process.emitWarning`.\n */\nexport class IngeniumTimeoutError extends IngeniumError {\n constructor(timeoutMs: number, message?: string) {\n super(503, 'REQUEST_TIMEOUT', message ?? `Request exceeded ${timeoutMs}ms`)\n }\n}\n","import { Transform, type TransformCallback } from 'node:stream'\nimport { IngeniumPayloadTooLargeError } from '../errors.ts'\n\n/**\n * A `Transform` stream that aborts with `IngeniumPayloadTooLargeError` as soon as\n * cumulative throughput exceeds `maxBytes`. The check happens before the\n * chunk is emitted downstream, so consumers never see bytes past the limit.\n */\nexport function createByteLimit(maxBytes: number): Transform {\n let total = 0\n return new Transform({\n transform(chunk: Buffer, _encoding: BufferEncoding, callback: TransformCallback) {\n total += chunk.length\n if (total > maxBytes) {\n callback(new IngeniumPayloadTooLargeError(`Request body exceeded ${maxBytes} bytes`))\n return\n }\n callback(null, chunk)\n },\n })\n}\n","import { Buffer } from 'node:buffer'\nimport { IngeniumBadRequestError, IngeniumPayloadTooLargeError } from '../errors.ts'\nimport type { MultipartFile, MultipartOptions, MultipartResult } from './multipart-types.ts'\n\n/** Default per-file cap: 10 MiB. */\nconst DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024\n/** Default file-count cap. */\nconst DEFAULT_MAX_FILES = 20\n/** Default field-count cap. */\nconst DEFAULT_MAX_FIELDS = 100\n\nconst CRLF = Buffer.from('\\r\\n')\nconst DOUBLE_CRLF = Buffer.from('\\r\\n\\r\\n')\nconst DASH_DASH = Buffer.from('--')\n\n/**\n * Extract the `boundary` parameter from a `Content-Type` header.\n * Per RFC 7578 / RFC 2046 the boundary is required and case-insensitive\n * parameter name; the value may be quoted.\n */\nfunction extractBoundary(contentType: string | undefined): string {\n if (!contentType) {\n throw new IngeniumBadRequestError('Content-Type header missing')\n }\n // The mime type itself is case-insensitive.\n const lower = contentType.toLowerCase()\n if (!lower.startsWith('multipart/form-data')) {\n throw new IngeniumBadRequestError('Content-Type is not multipart/form-data')\n }\n // Walk parameters: split on `;` but only after the type. We don't bother with\n // RFC 2231 continuations — boundaries are restricted to a 70-char ASCII subset.\n const params = contentType.slice(contentType.indexOf(';') + 1).split(';')\n for (const raw of params) {\n const eq = raw.indexOf('=')\n if (eq === -1) continue\n const name = raw.slice(0, eq).trim().toLowerCase()\n if (name !== 'boundary') continue\n let value = raw.slice(eq + 1).trim()\n if (value.startsWith('\"') && value.endsWith('\"')) {\n value = value.slice(1, -1)\n }\n if (value.length === 0) {\n throw new IngeniumBadRequestError('multipart boundary is empty')\n }\n return value\n }\n throw new IngeniumBadRequestError('multipart boundary missing')\n}\n\ninterface PartHeaders {\n /** form-data field name (`Content-Disposition: ...; name=\"...\"`). */\n name: string\n /** filename, if present. Presence marks the part as a file. */\n filename: string | undefined\n /** Content-Type header, if present. */\n contentType: string | undefined\n}\n\n/**\n * Parse the headers of a single part from a header-block string (already\n * split off at the `\\r\\n\\r\\n` boundary). Header names are case-insensitive.\n */\nfunction parsePartHeaders(block: string): PartHeaders {\n const lines = block.split('\\r\\n')\n let name: string | undefined\n let filename: string | undefined\n let contentType: string | undefined\n\n for (const line of lines) {\n if (line.length === 0) continue\n const colon = line.indexOf(':')\n if (colon === -1) {\n throw new IngeniumBadRequestError('Malformed multipart body: invalid header line')\n }\n const headerName = line.slice(0, colon).trim().toLowerCase()\n const headerValue = line.slice(colon + 1).trim()\n\n if (headerName === 'content-disposition') {\n // form-data; name=\"x\"; filename=\"y\"\n const params = headerValue.split(';')\n // First token is the disposition (`form-data`); we only accept that.\n const disposition = params[0]?.trim().toLowerCase()\n if (disposition !== 'form-data') {\n throw new IngeniumBadRequestError('Malformed multipart body: unsupported Content-Disposition')\n }\n for (let i = 1; i < params.length; i++) {\n const p = params[i]!\n const eq = p.indexOf('=')\n if (eq === -1) continue\n const k = p.slice(0, eq).trim().toLowerCase()\n let v = p.slice(eq + 1).trim()\n if (v.startsWith('\"') && v.endsWith('\"')) v = v.slice(1, -1)\n // Decode common escapes (\\\" and \\\\) — RFC 7578 references RFC 2183.\n v = v.replace(/\\\\(.)/g, '$1')\n if (k === 'name') name = v\n else if (k === 'filename') filename = v\n }\n } else if (headerName === 'content-type') {\n contentType = headerValue\n }\n // Other headers (Content-Transfer-Encoding etc.) are ignored.\n }\n\n if (name === undefined) {\n throw new IngeniumBadRequestError('Malformed multipart body: missing form-data name')\n }\n return { name, filename, contentType }\n}\n\n/**\n * Stash a parsed field into `fields` / `files`, collapsing repeated names\n * into arrays in arrival order. Mixing field+file under one name follows\n * arrival order too (rare; not specifically supported).\n */\nfunction appendField(\n result: MultipartResult,\n headers: PartHeaders,\n body: Buffer,\n): void {\n if (headers.filename !== undefined) {\n const file: MultipartFile = {\n filename: headers.filename,\n mimeType: headers.contentType ?? 'application/octet-stream',\n size: body.length,\n data: body,\n }\n const existing = result.files[headers.name]\n if (existing === undefined) {\n result.files[headers.name] = file\n } else if (Array.isArray(existing)) {\n existing.push(file)\n } else {\n result.files[headers.name] = [existing, file]\n }\n } else {\n const value = body.toString('utf8')\n const existing = result.fields[headers.name]\n if (existing === undefined) {\n result.fields[headers.name] = value\n } else if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n result.fields[headers.name] = [existing, value]\n }\n }\n}\n\n/**\n * Parse a `multipart/form-data` request body. Operates on raw bytes — boundary\n * sequences can legally appear inside binary file payloads, so we never\n * convert the payload to a string before splitting.\n *\n * @param buffer Full body bytes (already buffered & length-checked by caller).\n * @param contentType Raw `Content-Type` header — boundary is extracted from it.\n * @param opts Limits and filters.\n */\nexport function parseMultipart(\n buffer: Buffer,\n contentType: string | undefined,\n opts: MultipartOptions = {},\n): MultipartResult {\n const maxFileSize = opts.maxFileSize ?? DEFAULT_MAX_FILE_SIZE\n const maxFiles = opts.maxFiles ?? DEFAULT_MAX_FILES\n const maxFields = opts.maxFields ?? DEFAULT_MAX_FIELDS\n const allowed = opts.allowedMimePrefixes\n\n const boundary = extractBoundary(contentType)\n const result: MultipartResult = { fields: {}, files: {} }\n\n // Empty body → empty result. (No boundary delimiter at all.)\n if (buffer.length === 0) return result\n\n // RFC 7578: each part is preceded by `--<boundary>`. The first occurrence\n // may not be at byte 0 (a \"preamble\" is permitted but must be ignored).\n const dashBoundary = Buffer.concat([DASH_DASH, Buffer.from(boundary)])\n\n let cursor = buffer.indexOf(dashBoundary)\n if (cursor === -1) {\n throw new IngeniumBadRequestError('Malformed multipart body: opening boundary not found')\n }\n cursor += dashBoundary.length\n\n let fileCount = 0\n let fieldCount = 0\n\n // Loop over parts. After each `--<boundary>` we expect either:\n // `--` → final close delimiter (end of stream)\n // `\\r\\n` → start of a part (headers follow)\n // anything else is malformed.\n for (;;) {\n if (cursor + 2 > buffer.length) {\n throw new IngeniumBadRequestError('Malformed multipart body: truncated after boundary')\n }\n // Final delimiter: `--<boundary>--`\n if (buffer[cursor] === 0x2d && buffer[cursor + 1] === 0x2d) {\n // Close delimiter — done. We deliberately accept any trailing epilogue.\n return result\n }\n // Otherwise expect CRLF before headers.\n if (buffer[cursor] !== 0x0d || buffer[cursor + 1] !== 0x0a) {\n throw new IngeniumBadRequestError('Malformed multipart body: expected CRLF after boundary')\n }\n cursor += 2\n\n // Header block ends at the first `\\r\\n\\r\\n`.\n const headerEnd = buffer.indexOf(DOUBLE_CRLF, cursor)\n if (headerEnd === -1) {\n throw new IngeniumBadRequestError('Malformed multipart body: missing header terminator')\n }\n const headerBlock = buffer.slice(cursor, headerEnd).toString('utf8')\n const headers = parsePartHeaders(headerBlock)\n cursor = headerEnd + DOUBLE_CRLF.length\n\n // Body bytes run until the next `\\r\\n--<boundary>`. Boundaries may appear\n // inside binary payloads so we MUST scan bytes, not strings.\n const delimiter = Buffer.concat([CRLF, dashBoundary])\n const partEnd = buffer.indexOf(delimiter, cursor)\n if (partEnd === -1) {\n throw new IngeniumBadRequestError('Malformed multipart body: missing closing boundary')\n }\n\n const partBody = buffer.slice(cursor, partEnd)\n\n if (headers.filename !== undefined) {\n // File part — apply size + count + mime checks.\n if (partBody.length > maxFileSize) {\n throw new IngeniumPayloadTooLargeError(\n `File \"${headers.filename}\" exceeded ${maxFileSize} bytes`,\n )\n }\n if (allowed && allowed.length > 0) {\n const mime = (headers.contentType ?? 'application/octet-stream').toLowerCase()\n const ok = allowed.some((prefix) => mime.startsWith(prefix.toLowerCase()))\n if (!ok) {\n throw new IngeniumBadRequestError('Disallowed mime type')\n }\n }\n fileCount++\n if (fileCount > maxFiles) {\n throw new IngeniumBadRequestError('Too many files')\n }\n } else {\n fieldCount++\n if (fieldCount > maxFields) {\n throw new IngeniumBadRequestError('Too many fields')\n }\n }\n\n appendField(result, headers, partBody)\n\n cursor = partEnd + delimiter.length\n // Next iteration will check for `--` (close) or `\\r\\n` (next part).\n }\n}\n","/**\n * Local, zero-dependency type definitions for the\n * [Standard Schema](https://standardschema.dev) v1 spec.\n *\n * Ingenium detects schemas implementing this contract on\n * `IngeniumBody.json(schema)` and runs their `validate` function, mapping\n * `issues` into a `IngeniumValidationError` with field-level messages.\n *\n * We intentionally do NOT import `@standard-schema/spec` to keep the\n * core dependency-free. These types mirror the spec exactly.\n */\n\n/** A successful validation result: parsed/transformed value. */\nexport interface StandardSuccessResult<TOut> {\n readonly value: TOut\n readonly issues?: undefined\n}\n\n/** A single issue describing why validation failed at a particular path. */\nexport interface StandardIssue {\n readonly message: string\n readonly path?: ReadonlyArray<PropertyKey | StandardPathSegment> | undefined\n}\n\n/** A path segment may be a bare key OR an object with a `key` property. */\nexport interface StandardPathSegment {\n readonly key: PropertyKey\n}\n\n/** A failed validation result: one or more issues. */\nexport interface StandardFailureResult {\n readonly issues: ReadonlyArray<StandardIssue>\n readonly value?: undefined\n}\n\n/** Standard Schema validation result: success XOR failure. */\nexport type StandardResult<TOut> = StandardSuccessResult<TOut> | StandardFailureResult\n\n/** The properties living under the `~standard` key. */\nexport interface StandardSchemaV1Props<TIn = unknown, TOut = TIn> {\n readonly version: 1\n readonly vendor: string\n readonly validate: (input: unknown) => StandardResult<TOut> | Promise<StandardResult<TOut>>\n readonly types?: {\n readonly input: TIn\n readonly output: TOut\n } | undefined\n}\n\n/** The Standard Schema v1 interface — anything with a `~standard` property. */\nexport interface StandardSchemaV1<TIn = unknown, TOut = TIn> {\n readonly '~standard': StandardSchemaV1Props<TIn, TOut>\n}\n\n/**\n * Type guard: is `x` a Standard Schema v1?\n *\n * Checks for the `~standard` property and that its `version` is `1` and\n * `validate` is a function. Cheap enough to call on every body.json() call.\n */\nexport function isStandardSchema(x: unknown): x is StandardSchemaV1 {\n if (x === null || (typeof x !== 'object' && typeof x !== 'function')) return false\n const std = (x as { '~standard'?: unknown })['~standard']\n if (std === null || typeof std !== 'object') return false\n const props = std as { version?: unknown; validate?: unknown }\n return props.version === 1 && typeof props.validate === 'function'\n}\n","import type { Readable } from 'node:stream'\nimport { Buffer } from 'node:buffer'\nimport { IngeniumBadRequestError, IngeniumPayloadTooLargeError, IngeniumValidationError } from '../errors.ts'\nimport { createByteLimit } from '../body/limit.ts'\nimport { parseMultipart } from '../body/multipart.ts'\nimport type { MultipartOptions, MultipartResult } from '../body/multipart-types.ts'\nimport {\n isStandardSchema,\n type StandardIssue,\n type StandardSchemaV1,\n} from '../schema/standard.ts'\n\n/** Minimal duck-type for any validation library that accepts unknown and returns a typed value. */\nexport interface ParseSchema<T> {\n parse(input: unknown): T\n}\n\n/** Optional Zod-like schema: success/failure object output (used internally for friendlier errors). */\nexport interface SafeParseSchema<T> {\n safeParse(input: unknown): { success: true; data: T } | { success: false; error: { issues: ZodLikeIssue[] } }\n}\n\ninterface ZodLikeIssue {\n path: ReadonlyArray<string | number>\n message: string\n}\n\n/** Normalize a Standard Schema issue path into a dot-joined field key. */\nfunction standardPathToField(path: StandardIssue['path']): string {\n if (!path || path.length === 0) return '_'\n const parts: string[] = []\n for (const seg of path) {\n if (seg !== null && typeof seg === 'object' && 'key' in seg) {\n parts.push(String(seg.key))\n } else {\n parts.push(String(seg))\n }\n }\n return parts.join('.') || '_'\n}\n\n/**\n * Default body size limit for `IngeniumBody.json/text/urlencoded/buffer`.\n * 100,000 bytes matches Express's `body-parser` default (`'100kb'`),\n * which is the convention every Express app implicitly relies on. Override\n * per-call (`ctx.body.json(undefined, 5_000_000)`) or set a different\n * default by configuring your `ingenium.json({ limit })` middleware (the\n * middleware is currently a stub — see `body/middleware.ts`).\n */\nconst DEFAULT_MAX_BYTES = 100_000\n\n/**\n * Lazy body accessor. Bytes are not read until one of the consume methods\n * (`json`, `text`, `urlencoded`, `buffer`, `stream`) is called.\n *\n * One instance is allocated per `IngeniumContext` (pool-bound), so per-request\n * cost is just a `reset()`.\n */\nexport class IngeniumBody {\n /** @internal */ _source: Readable | null = null\n /** @internal */ _consumed = false\n /** @internal */ _contentType: string | undefined = undefined\n /** @internal */ _contentLength: number | undefined = undefined\n /**\n * @internal\n * Parse cache. Stores the raw body bytes after the first successful\n * `buffer()` (or `text()` / `json()` / `urlencoded()`, which all go\n * through `buffer()`). Subsequent buffer-producing consumers reuse\n * these bytes instead of throwing \"already consumed\".\n *\n * Caches the RAW Buffer (not parsed objects) so different callers can\n * apply different schemas / decoders against the same bytes — a\n * common pattern when an audit middleware reads the body before the\n * handler does. Re-parsing JSON from a cached buffer is cheap; mixing\n * schemas against a cached parsed object would be incorrect.\n *\n * `stream()` opts out (it hands the caller ownership of the raw\n * Readable) and `multipart()` opts out (its result is bespoke and\n * re-parsing with different options would be ambiguous).\n *\n * Checked with `!== null` rather than truthiness so an empty body\n * (`Buffer.alloc(0)`) still hits the cache on subsequent reads.\n */\n /** @internal */ _cached: Buffer | null = null\n\n /** @internal Adapter calls this on each request before dispatch. */\n _attach(source: Readable | null, contentType: string | undefined, contentLength: number | undefined): void {\n this._source = source\n this._consumed = false\n this._contentType = contentType\n this._contentLength = contentLength\n this._cached = null\n }\n\n /** @internal Pool reset. */\n _reset(): void {\n this._source = null\n this._consumed = false\n this._contentType = undefined\n this._contentLength = undefined\n this._cached = null\n }\n\n /**\n * Returns the raw request body stream. Throws if already consumed OR\n * if the body has already been buffered (cached) — once we hold the\n * bytes, we can't hand the caller back a fresh Readable to own.\n */\n stream(): Readable {\n if (this._cached !== null) throw new IngeniumBadRequestError('Request body already consumed')\n if (this._consumed) throw new IngeniumBadRequestError('Request body already consumed')\n if (!this._source) throw new IngeniumBadRequestError('Request has no body')\n this._consumed = true\n return this._source\n }\n\n /**\n * Buffers the entire body into a `Buffer`. Honors `maxBytes` (default 100KB).\n *\n * If the body has already been buffered once (by any prior `buffer()`,\n * `text()`, `json()`, or `urlencoded()` call), returns the cached bytes\n * — `maxBytes` is still enforced against `cached.length`, so a caller\n * passing a tighter cap than the original still gets a 413.\n */\n async buffer(maxBytes: number = DEFAULT_MAX_BYTES): Promise<Buffer> {\n // Cached path: reuse bytes, but honor the caller's ceiling.\n if (this._cached !== null) {\n if (this._cached.length > maxBytes) {\n throw new IngeniumPayloadTooLargeError(\n `Request body exceeded ${maxBytes} bytes`,\n )\n }\n return this._cached\n }\n if (this._consumed) throw new IngeniumBadRequestError('Request body already consumed')\n if (!this._source) {\n // Empty body — cache the empty buffer so subsequent consumers\n // also hit the cached path (consistent semantics).\n this._cached = Buffer.alloc(0)\n return this._cached\n }\n this._consumed = true\n\n const cl = this._contentLength\n if (cl !== undefined && cl > maxBytes) {\n // Drain source so the connection can be reused.\n this._source.resume()\n throw new IngeniumPayloadTooLargeError(\n `Request body exceeded ${maxBytes} bytes`,\n )\n }\n\n const source = this._source\n\n // Fast path: Content-Length is known and within cap. Pre-allocate exactly\n // one Buffer and copy chunks directly into it — eliminates the chunks[]\n // array, the per-chunk push, and the final Buffer.concat copy. Same\n // observable behavior, ~2-3 fewer allocations per request, and a single\n // contiguous write instead of a copy-then-walk.\n //\n // The transport-layer Transform may already be installed; that's fine —\n // it just no-ops for in-bounds bodies. We do not install a second one\n // here when we know the length (the transport already enforced).\n if (cl !== undefined && cl >= 0) {\n const buf = Buffer.allocUnsafe(cl)\n let offset = 0\n return new Promise<Buffer>((resolve, reject) => {\n source.on('data', (chunk: Buffer) => {\n // Defensive: clamp to declared length so a misbehaving stream\n // can't write past our pre-allocated buffer. (`node:http` itself\n // already enforces Content-Length, so this is belt + suspenders.)\n const remaining = cl - offset\n if (remaining <= 0) return\n const n = chunk.length <= remaining ? chunk.length : remaining\n chunk.copy(buf, offset, 0, n)\n offset += n\n })\n source.on('end', () => {\n // If the client truncated, return the partial buffer (matches the\n // chunks-then-concat path's behavior pre-optimization).\n const result = offset === cl ? buf : buf.subarray(0, offset)\n // Cache before resolving so a follow-up consumer that awaits this\n // same promise can read `_cached` immediately after.\n this._cached = result\n resolve(result)\n })\n source.on('error', reject)\n })\n }\n\n // Unknown length (chunked encoding, no Content-Length) — fall back to\n // the chunks + Buffer.concat path with the byte-limit Transform on top.\n const limited = source.pipe(createByteLimit(maxBytes))\n const chunks: Buffer[] = []\n return new Promise<Buffer>((resolve, reject) => {\n limited.on('data', (chunk: Buffer) => chunks.push(chunk))\n limited.on('end', () => {\n const result = Buffer.concat(chunks)\n this._cached = result\n resolve(result)\n })\n limited.on('error', reject)\n })\n }\n\n /** Buffers the body and decodes as UTF-8 text. */\n async text(maxBytes?: number): Promise<string> {\n const buf = await this.buffer(maxBytes)\n return buf.length === 0 ? '' : buf.toString('utf8')\n }\n\n /**\n * Parses the body as JSON. If a schema is provided, the parsed value is\n * validated. Detection order:\n *\n * 1. Standard Schema v1 (`[\"~standard\"]`) — async-aware, multi-issue\n * 2. Zod-like `safeParse(input)` — multi-issue\n * 3. Plain `parse(input): T` — throws on failure\n *\n * Validation failures are normalized into `IngeniumValidationError` with a\n * field-level `fields` map (dot-joined paths; empty path → `_`).\n */\n async json<T = unknown>(\n schema?: StandardSchemaV1<unknown, T> | SafeParseSchema<T> | ParseSchema<T>,\n maxBytes?: number,\n ): Promise<T> {\n // Inline `text()` to skip one async indirection (one microtask saved\n // per ctx.body.json() call). Same observable behavior.\n const buf = await this.buffer(maxBytes)\n const text = buf.length === 0 ? '' : buf.toString('utf8')\n let parsed: unknown\n try {\n parsed = text.length === 0 ? null : JSON.parse(text)\n } catch (err) {\n throw new IngeniumBadRequestError('Invalid JSON', err)\n }\n if (schema) {\n // 1. Standard Schema v1 — most modern, takes precedence.\n if (isStandardSchema(schema)) {\n const maybe = schema['~standard'].validate(parsed)\n const result = maybe instanceof Promise ? await maybe : maybe\n if (result.issues) {\n const fields: Record<string, string> = {}\n for (const issue of result.issues) {\n fields[standardPathToField(issue.path)] = issue.message\n }\n throw new IngeniumValidationError(fields)\n }\n return result.value as T\n }\n // 2. Zod-like safeParse.\n if ('safeParse' in schema && typeof (schema as SafeParseSchema<T>).safeParse === 'function') {\n const result = (schema as SafeParseSchema<T>).safeParse(parsed)\n if (!result.success) {\n const fields: Record<string, string> = {}\n for (const issue of result.error.issues) {\n fields[issue.path.join('.') || '_'] = issue.message\n }\n throw new IngeniumValidationError(fields)\n }\n return result.data\n }\n // 3. Plain parse.\n try {\n return (schema as ParseSchema<T>).parse(parsed)\n } catch (err) {\n throw new IngeniumValidationError({ _: (err as Error).message ?? 'validation failed' })\n }\n }\n return parsed as T\n }\n\n /** Parses the body as `application/x-www-form-urlencoded`. */\n async urlencoded(maxBytes?: number): Promise<Record<string, string>> {\n const text = await this.text(maxBytes)\n const params = new URLSearchParams(text)\n const out: Record<string, string> = {}\n for (const [k, v] of params) out[k] = v\n return out\n }\n\n /**\n * Parses the body as `multipart/form-data` (RFC 7578).\n *\n * Returns plain-text fields and fully buffered file parts. For very large\n * uploads prefer `stream()` and parse manually — this method holds every\n * file in memory.\n *\n * Failure modes:\n * - Body exceeds `maxBytes` → `IngeniumPayloadTooLargeError`\n * - Single file exceeds `maxFileSize` → `IngeniumPayloadTooLargeError`\n * - Too many files / fields → `IngeniumBadRequestError`\n * - Disallowed mime type → `IngeniumBadRequestError`\n * - Content-Type isn't `multipart/form-data` or boundary missing → `IngeniumBadRequestError`\n * - Malformed body → `IngeniumBadRequestError`\n */\n async multipart(opts: MultipartOptions = {}): Promise<MultipartResult> {\n // Multipart opts out of the buffer cache. Unlike json/text/urlencoded —\n // which all return idempotent decodings of the same bytes — multipart's\n // result is bespoke (file parts, field limits, mime allow-lists), and\n // re-parsing the same bytes under different `opts` would silently return\n // a different shape. Safer to treat multipart as a terminal consumer:\n // it runs once, then any further body access throws.\n //\n // To enforce that, we either consume the live stream (first call) or\n // read the cached buffer (someone called .text()/.json() first), then\n // immediately invalidate both — clearing `_cached` and setting\n // `_consumed = true` so subsequent .json()/.text()/.multipart()/.stream()\n // calls throw \"already consumed\".\n const contentType = this._contentType\n const buf = await this.buffer(opts.maxBytes ?? DEFAULT_MAX_BYTES)\n this._cached = null\n this._consumed = true\n try {\n return parseMultipart(buf, contentType, opts)\n } catch (err) {\n // Preserve framework errors (415/413/400) as-is.\n if (err instanceof IngeniumPayloadTooLargeError || err instanceof IngeniumBadRequestError) {\n throw err\n }\n throw new IngeniumBadRequestError('Malformed multipart body', err)\n }\n }\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto'\nimport { Buffer } from 'node:buffer'\nimport type { IngeniumContext } from './context.ts'\nimport { IngeniumError } from '../errors.ts'\n\n/**\n * Options accepted by {@link IngeniumCookies.set}. Maps 1:1 to RFC 6265 cookie\n * attributes plus a few modern extensions (`Priority`, `Partitioned`).\n *\n * `sameSite: true` is normalized to `'strict'` (Express compatibility);\n * `sameSite: false` omits the attribute entirely so the browser falls back\n * to its default policy.\n */\nexport interface CookieSetOptions {\n /** `Domain=` attribute. Omitted when undefined. */\n domain?: string\n /** `Path=` attribute. Defaults to `'/'`. */\n path?: string\n /** `Expires=` attribute. Serialized via `Date.toUTCString()`. */\n expires?: Date\n /** `Max-Age=` (seconds). Floored to an integer. */\n maxAge?: number\n /** `HttpOnly` flag. */\n httpOnly?: boolean\n /** `Secure` flag. */\n secure?: boolean\n /** `SameSite=` attribute. `true` → `'strict'`; `false`/omitted → no attr. */\n sameSite?: 'strict' | 'lax' | 'none' | true | false\n /** `Priority=` attribute (CHIPS / RFC 9220). Capitalized on the wire. */\n priority?: 'low' | 'medium' | 'high'\n /** `Partitioned` flag (CHIPS). */\n partitioned?: boolean\n /**\n * When `true`, the cookie value is HMAC-SHA-256 signed with the app's\n * `cookieSecrets[0]`. On the wire: `name=value.signature`. Throws\n * `IngeniumError(500, 'COOKIE_SECRET_MISSING')` if no secrets are configured.\n */\n signed?: boolean\n}\n\n/** Options accepted by {@link IngeniumCookies.get}. */\nexport interface CookieGetOptions {\n /**\n * When `true`, the cookie value is treated as `value.signature` and the\n * HMAC is verified against every configured secret (rotation-safe).\n * Returns `null` on tamper, missing signature, or no configured secrets.\n */\n signed?: boolean\n}\n\n/**\n * First-class cookie API exposed via `ctx.cookies`. Pool-bound and lazy —\n * the holder is allocated on first access and dropped to `null` on context\n * reset, so routes that never touch cookies pay zero overhead.\n *\n * Read side parses `ctx.headers.cookie` once and caches the resulting record.\n * Write side appends to the response `set-cookie` header, preserving prior\n * values (a single response may carry multiple `Set-Cookie` headers).\n */\nexport interface IngeniumCookies {\n /**\n * Read a cookie by name. With `{ signed: true }`, verifies the HMAC\n * suffix and returns `null` on mismatch. Returns `null` when the cookie\n * is absent.\n */\n get(name: string, opts?: CookieGetOptions): string | null\n /**\n * Snapshot of all parsed cookies. Signed cookies appear with their raw\n * `value.signature` suffix — call `.get(name, { signed: true })` to verify.\n */\n all(): Record<string, string>\n /**\n * Write a `Set-Cookie` header. Multiple calls accumulate (the response\n * carries one `Set-Cookie` header per call). With `{ signed: true }`,\n * the value is HMAC-SHA-256 signed.\n */\n set(name: string, value: string, opts?: CookieSetOptions): void\n /**\n * Expire a cookie. Emits `Max-Age=0` plus an `Expires` in the past, and\n * mirrors `path` / `domain` so the browser actually removes the right\n * cookie (a `Set-Cookie` only matches the existing cookie on those attrs).\n */\n clear(name: string, opts?: Pick<CookieSetOptions, 'domain' | 'path'>): void\n}\n\n// ───── Parser (RFC 6265 §5.2, defensive) ────────────────────────────────────\n\n/**\n * Parse a `Cookie` request header into a name → value map. Mirrors the\n * `parseCookieHeader` helper in `session/middleware.ts` but kept inline here\n * so the cookie holder has no cross-module dependency on the session module.\n *\n * - First occurrence wins (RFC 6265 §5.4 typical browser behavior).\n * - Quoted values: surrounding `\"` are stripped.\n * - Percent-encoded values are decoded via `decodeURIComponent`; bad encodings\n * fall back to the raw value rather than throwing — this parser is exposed\n * to attacker-controlled input and must never crash dispatch.\n */\nfunction parseCookieHeader(header: string | undefined): Record<string, string> {\n const out: Record<string, string> = Object.create(null) as Record<string, string>\n if (!header) return out\n\n const parts = header.split(';')\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!\n const eq = part.indexOf('=')\n if (eq < 0) continue\n const name = part.slice(0, eq).trim()\n if (!name || name in out) continue\n let value = part.slice(eq + 1).trim()\n if (\n value.length >= 2 &&\n value.charCodeAt(0) === 0x22 &&\n value.charCodeAt(value.length - 1) === 0x22\n ) {\n value = value.slice(1, -1)\n }\n try {\n out[name] = decodeURIComponent(value)\n } catch {\n out[name] = value\n }\n }\n return out\n}\n\n// ───── Serializer ───────────────────────────────────────────────────────────\n\n/** Capitalize the first character; the rest stays as-is. */\nfunction cap(s: string): string {\n return s.length === 0 ? s : s[0]!.toUpperCase() + s.slice(1)\n}\n\n/**\n * Serialize a single `Set-Cookie` value per RFC 6265 §4.1.1. The value is\n * `encodeURIComponent`-escaped so semicolons, whitespace, and control chars\n * cannot break the header (the read side mirrors this with `decodeURIComponent`).\n */\nfunction serializeSetCookie(name: string, value: string, opts: CookieSetOptions): string {\n const segments: string[] = [`${name}=${encodeURIComponent(value)}`]\n if (opts.domain) segments.push(`Domain=${opts.domain}`)\n segments.push(`Path=${opts.path ?? '/'}`)\n\n if (opts.expires) {\n segments.push(`Expires=${opts.expires.toUTCString()}`)\n }\n if (typeof opts.maxAge === 'number') {\n // Max-Age must be an integer; floor to match RFC behaviour.\n segments.push(`Max-Age=${Math.floor(opts.maxAge)}`)\n }\n if (opts.httpOnly) segments.push('HttpOnly')\n if (opts.secure) segments.push('Secure')\n\n if (opts.sameSite !== undefined && opts.sameSite !== false) {\n // `true` → 'strict' for Express compat. Otherwise lowercase → Capitalized.\n const ss = opts.sameSite === true ? 'strict' : opts.sameSite\n segments.push(`SameSite=${cap(ss)}`)\n }\n if (opts.priority) segments.push(`Priority=${cap(opts.priority)}`)\n if (opts.partitioned) segments.push('Partitioned')\n\n return segments.join('; ')\n}\n\n/**\n * Append a `Set-Cookie` value to the response, preserving any existing\n * values. The header bag normalizes to an array on the second `.set()` so\n * the transport writes multiple `Set-Cookie` lines (per RFC 7230 §3.2.2,\n * `Set-Cookie` is the canonical exception to header-folding rules).\n */\nfunction appendSetCookie(ctx: IngeniumContext<unknown>, value: string): void {\n const existing = ctx.getHeader('set-cookie')\n if (!existing) {\n ctx.set('set-cookie', value)\n } else if (Array.isArray(existing)) {\n ctx.set('set-cookie', [...existing, value])\n } else {\n ctx.set('set-cookie', [existing, value])\n }\n}\n\n// ───── HMAC sign / verify ───────────────────────────────────────────────────\n\n/** HMAC-SHA-256(secret, value), base64url-encoded. */\nfunction sign(value: string, secret: string): string {\n return createHmac('sha256', secret).update(value).digest('base64url')\n}\n\n/**\n * Verify a `value.signature` cookie against any of the provided secrets.\n * Returns the un-signed value or `null`. Uses {@link timingSafeEqual} to\n * defeat byte-wise timing oracles. Splits on the LAST `.` so the underlying\n * value may itself contain dots.\n */\nfunction verifySigned(raw: string, secrets: readonly string[]): string | null {\n const dot = raw.lastIndexOf('.')\n if (dot <= 0 || dot >= raw.length - 1) return null\n const value = raw.slice(0, dot)\n const sig = raw.slice(dot + 1)\n const sigBuf = Buffer.from(sig, 'base64url')\n if (sigBuf.length === 0) return null\n\n for (let i = 0; i < secrets.length; i++) {\n const expected = Buffer.from(sign(value, secrets[i]!), 'base64url')\n if (expected.length !== sigBuf.length) continue\n if (timingSafeEqual(expected, sigBuf)) return value\n }\n return null\n}\n\n// ───── Factory ──────────────────────────────────────────────────────────────\n\n/**\n * Build the lazy cookie holder bound to `ctx`. The parsed-cookies cache is\n * populated on first read; the closed-over `parsed` reference is local to\n * the holder so a context that's reset and re-acquired gets a fresh holder\n * (because `ctx._cookies` is nulled on `reset()`).\n *\n * Secrets are read from `ctx._cookieSecrets`, which the app stamps at\n * dispatch entry when configured — same pattern as `_trustProxy`. The read\n * happens at sign/verify time (NOT at holder construction) so an app that\n * registers secrets after the holder is allocated still picks them up.\n */\nexport function makeIngeniumCookies<Params>(ctx: IngeniumContext<Params>): IngeniumCookies {\n let parsed: Record<string, string> | null = null\n\n const requireSecrets = (): readonly string[] => {\n const secrets = ctx._cookieSecrets\n if (!secrets || secrets.length === 0) {\n throw new IngeniumError(\n 500,\n 'COOKIE_SECRET_MISSING',\n 'Signed cookies require `cookieSecrets` to be configured on the app.',\n )\n }\n return secrets\n }\n\n return {\n get(name, opts) {\n if (!parsed) parsed = parseCookieHeader(ctx.headers.cookie as string | undefined)\n const raw = parsed[name]\n if (raw === undefined) return null\n if (opts?.signed) {\n // Verify uses ALL secrets so rotation (new key first, old keys kept)\n // doesn't lock existing clients out mid-deploy.\n const secrets = requireSecrets()\n return verifySigned(raw, secrets)\n }\n return raw\n },\n all() {\n if (!parsed) parsed = parseCookieHeader(ctx.headers.cookie as string | undefined)\n return parsed\n },\n set(name, value, opts) {\n let wireValue = value\n if (opts?.signed) {\n // First secret signs; remaining secrets are verify-only (rotation).\n const secrets = requireSecrets()\n wireValue = `${value}.${sign(value, secrets[0]!)}`\n }\n appendSetCookie(ctx, serializeSetCookie(name, wireValue, opts ?? {}))\n },\n clear(name, opts) {\n // Max-Age=0 + an Expires in the distant past. Browsers only match on\n // (name, domain, path) when expiring, so mirror those from the caller.\n appendSetCookie(\n ctx,\n serializeSetCookie(name, '', {\n // exactOptionalPropertyTypes: only include `domain` when the caller\n // actually supplied one — an explicit `undefined` isn't assignable to\n // the optional `domain?: string` field.\n ...(opts?.domain !== undefined ? { domain: opts.domain } : {}),\n path: opts?.path ?? '/',\n maxAge: 0,\n expires: new Date(0),\n }),\n )\n },\n }\n}\n","/**\n * Trust-proxy resolution for `X-Forwarded-*` headers.\n *\n * Mirrors Express's `app.set('trust proxy', ...)` semantics:\n * - `false` (default): never trust XFF — `ctx.ip` always reflects the immediate\n * socket peer.\n * - `true`: trust the entire `X-Forwarded-For` chain — last entry wins.\n * - `number n`: trust `n` upstream hops — return chain entry `n` from the right.\n * - `string` (single CIDR/IP/keyword) or `string[]` (list): trust connections\n * from these addresses; walk the chain skipping trusted IPs.\n * - `(ip, hopIdx) => boolean`: custom predicate, called per chain entry.\n *\n * Supported keywords: `'loopback'` (127.0.0.0/8, ::1), `'linklocal'`\n * (169.254.0.0/16, fe80::/10), `'uniquelocal'` (10/8, 172.16/12, 192.168/16,\n * fc00::/7). CIDRs accepted in IPv4 dotted (`10.0.0.0/8`) and IPv6\n * (`fc00::/7`) form. Single addresses without `/` match exactly.\n */\n\nexport type TrustProxy =\n | boolean\n | number\n | string\n | string[]\n | ((ip: string, hopIdx: number) => boolean)\n\nexport interface ForwardedInfo {\n /** The resolved client IP after walking the trusted hop chain. */\n ip: string\n /** Full forwarded chain, left-to-right (closest to client first), plus the immediate peer at the end. */\n ips: readonly string[]\n /** Best-effort protocol: `http` or `https`. */\n protocol: 'http' | 'https'\n /** Best-effort hostname (no port). */\n hostname: string\n}\n\n/**\n * Resolve forwarded info from raw headers + the immediate socket peer.\n *\n * @param trust The `trustProxy` configuration.\n * @param remoteAddress The socket-level peer address (always present).\n * @param headers Lowercased request headers (Node convention).\n * @param defaultProtocol The protocol of the underlying transport (`http` for `node:http`,\n * `https` for TLS, `http` for h2c, `https` for h2/TLS).\n */\nexport function resolveForwarded(\n trust: TrustProxy,\n remoteAddress: string,\n headers: Readonly<Record<string, string | string[] | undefined>>,\n defaultProtocol: 'http' | 'https' = 'http',\n): ForwardedInfo {\n if (trust === false || trust === 0 || trust === undefined || trust === null) {\n return {\n ip: remoteAddress,\n ips: [remoteAddress],\n protocol: defaultProtocol,\n hostname: parseHost(headers, false),\n }\n }\n\n const xffHeader = headers['x-forwarded-for']\n const xff = parseHeaderList(xffHeader)\n // Append the immediate peer at the end so the chain is complete.\n const fullChain: string[] = [...xff, remoteAddress]\n\n let trustedIp = remoteAddress\n if (typeof trust === 'boolean' && trust === true) {\n trustedIp = fullChain[0] ?? remoteAddress\n } else if (typeof trust === 'number') {\n // Skip `trust` hops from the right (the rightmost is the immediate peer).\n const idx = Math.max(0, fullChain.length - 1 - trust)\n trustedIp = fullChain[idx] ?? remoteAddress\n } else if (typeof trust === 'function') {\n trustedIp = walkChainPredicate(fullChain, trust)\n } else {\n const matchers = typeof trust === 'string' ? [trust] : trust\n const compiled = matchers.map(compileTrustEntry)\n const predicate = (ip: string): boolean => compiled.some((m) => m(ip))\n trustedIp = walkChainPredicate(fullChain, (ip) => predicate(ip))\n }\n\n const protoHeader = headers['x-forwarded-proto']\n const proto = parseHeaderList(protoHeader)[0]?.toLowerCase()\n const protocol: 'http' | 'https' = proto === 'https' ? 'https' : proto === 'http' ? 'http' : defaultProtocol\n\n const hostHeader = headers['x-forwarded-host']\n const xfhFirst = parseHeaderList(hostHeader)[0]\n const hostname = xfhFirst ? stripPort(xfhFirst) : parseHost(headers, false)\n\n return { ip: trustedIp, ips: fullChain, protocol, hostname }\n}\n\n/**\n * Walk the chain right-to-left while the predicate keeps trusting the\n * current hop. Return the first untrusted address encountered (the real\n * client). If the predicate trusts every hop, return the leftmost entry.\n */\nfunction walkChainPredicate(\n chain: readonly string[],\n isTrusted: (ip: string, hopIdx: number) => boolean,\n): string {\n for (let i = chain.length - 1, hop = 0; i >= 0; i--, hop++) {\n const ip = chain[i]!\n if (!isTrusted(ip, hop)) return ip\n }\n return chain[0] ?? ''\n}\n\n/** Parse a comma-separated header (or array) into a trimmed list. */\nfunction parseHeaderList(value: string | string[] | undefined): string[] {\n if (!value) return []\n const flat = Array.isArray(value) ? value.join(',') : value\n return flat\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction parseHost(\n headers: Readonly<Record<string, string | string[] | undefined>>,\n trustForwarded: boolean,\n): string {\n if (trustForwarded) {\n const xfh = parseHeaderList(headers['x-forwarded-host'])[0]\n if (xfh) return stripPort(xfh)\n }\n const host = headers['host']\n const flat = Array.isArray(host) ? host[0] : host\n if (!flat) return 'localhost'\n return stripPort(flat)\n}\n\nfunction stripPort(host: string): string {\n // IPv6 literals are bracketed: [::1]:8080\n if (host[0] === '[') {\n const end = host.indexOf(']')\n return end >= 0 ? host.slice(1, end) : host\n }\n const idx = host.lastIndexOf(':')\n return idx > 0 ? host.slice(0, idx) : host\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// CIDR / keyword matchers\n// ───────────────────────────────────────────────────────────────────────────\n\ntype IpMatcher = (ip: string) => boolean\n\nconst KEYWORDS: Record<string, string[]> = {\n loopback: ['127.0.0.0/8', '::1/128'],\n linklocal: ['169.254.0.0/16', 'fe80::/10'],\n uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'],\n}\n\nfunction compileTrustEntry(entry: string): IpMatcher {\n const expanded = KEYWORDS[entry] ?? [entry]\n const matchers = expanded.map(compileSingle)\n return (ip) => matchers.some((m) => m(ip))\n}\n\nfunction compileSingle(entry: string): IpMatcher {\n if (entry.includes('/')) return compileCidr(entry)\n return (ip) => ip === entry\n}\n\nfunction compileCidr(cidr: string): IpMatcher {\n const slash = cidr.indexOf('/')\n const network = cidr.slice(0, slash)\n const prefix = Number(cidr.slice(slash + 1))\n if (network.includes(':')) return compileCidrV6(network, prefix)\n return compileCidrV4(network, prefix)\n}\n\nfunction compileCidrV4(network: string, prefix: number): IpMatcher {\n const netBits = ipV4ToInt(network)\n if (netBits === null) return () => false\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0\n const target = (netBits & mask) >>> 0\n return (ip) => {\n const bits = ipV4ToInt(stripIpv6Wrap(ip))\n if (bits === null) return false\n return ((bits & mask) >>> 0) === target\n }\n}\n\nfunction compileCidrV6(network: string, prefix: number): IpMatcher {\n const netBytes = ipV6ToBytes(network)\n if (!netBytes) return () => false\n return (ip) => {\n const bytes = ipV6ToBytes(ip)\n if (!bytes) return false\n return cmpPrefix(netBytes, bytes, prefix)\n }\n}\n\nfunction cmpPrefix(a: Uint8Array, b: Uint8Array, prefix: number): boolean {\n const fullBytes = prefix >>> 3\n for (let i = 0; i < fullBytes; i++) if (a[i] !== b[i]) return false\n const rem = prefix & 7\n if (rem === 0) return true\n const shift = 8 - rem\n return (a[fullBytes]! >> shift) === (b[fullBytes]! >> shift)\n}\n\nfunction ipV4ToInt(ip: string): number | null {\n const parts = ip.split('.')\n if (parts.length !== 4) return null\n let n = 0\n for (const p of parts) {\n const v = Number(p)\n if (!Number.isInteger(v) || v < 0 || v > 255) return null\n n = (n << 8) | v\n }\n return n >>> 0\n}\n\n/** ::ffff:1.2.3.4 → 1.2.3.4 (so v4 matchers work on v4-mapped addresses). */\nfunction stripIpv6Wrap(ip: string): string {\n if (ip.startsWith('::ffff:')) return ip.slice(7)\n return ip\n}\n\nfunction ipV6ToBytes(ip: string): Uint8Array | null {\n // Very small implementation: handles standard `a:b:...:h` and `::` shorthand.\n const cleaned = stripIpv6Wrap(ip)\n if (cleaned.includes('.')) return null // v4-mapped already stripped above; bare v4 not v6\n const out = new Uint8Array(16)\n let parts: string[]\n if (ip.includes('::')) {\n const [head, tail] = ip.split('::')\n const headParts = head ? head.split(':') : []\n const tailParts = tail ? tail.split(':') : []\n const fillCount = 8 - (headParts.length + tailParts.length)\n if (fillCount < 0) return null\n parts = [...headParts, ...new Array<string>(fillCount).fill('0'), ...tailParts]\n } else {\n parts = ip.split(':')\n }\n if (parts.length !== 8) return null\n for (let i = 0; i < 8; i++) {\n const v = parseInt(parts[i]!, 16)\n if (!Number.isInteger(v) || v < 0 || v > 0xffff) return null\n out[i * 2] = (v >> 8) & 0xff\n out[i * 2 + 1] = v & 0xff\n }\n return out\n}\n","/**\n * Pure parsers and matchers for HTTP `Accept`-family headers.\n *\n * Implemented from scratch — no `negotiator` / `accepts` runtime dep.\n * Used by `negotiate.ts`, `format.ts`, and downstream context helpers.\n *\n * Spec references:\n * - RFC 9110 §12.5.1 (Accept), §12.5.2 (Accept-Charset),\n * §12.5.4 (Accept-Encoding), §12.5.5 (Accept-Language).\n */\n\n/** A single parsed media-range entry from an `Accept` header. */\nexport interface ParsedAccept {\n /** The full media-range string (lowercased), e.g. `text/html`, `text/\\*`, `\\*\\/\\*`. */\n type: string\n /** Quality factor from `;q=N`, default `1`. Out-of-range values are clamped. */\n quality: number\n /** Any other extension parameters (e.g. `level=1`). */\n params: Record<string, string>\n}\n\n/**\n * Express `accepts`-style shorthand → canonical media type.\n * Kept intentionally tiny — covers the 99% case for body responses.\n */\nconst SHORTHAND: Readonly<Record<string, string>> = {\n json: 'application/json',\n html: 'text/html',\n text: 'text/plain',\n xml: 'application/xml',\n form: 'application/x-www-form-urlencoded',\n multipart: 'multipart/form-data',\n csv: 'text/csv',\n 'octet-stream': 'application/octet-stream',\n}\n\n/** Resolve a shorthand (`'json'`) to its canonical mime, or pass through. */\nexport function expandShorthand(token: string): string {\n const lower = token.toLowerCase()\n return SHORTHAND[lower] ?? lower\n}\n\n/**\n * Parse a comma-separated `Accept`-family header into a list of entries.\n * Empty / undefined input returns an empty array. Malformed entries are\n * silently dropped (lenient parsing — same as Express).\n *\n * Result is **not** sorted; pass to `sortByPreference` if you need ordering.\n */\nexport function parseAcceptHeader(header: string | undefined): ParsedAccept[] {\n if (!header) return []\n const out: ParsedAccept[] = []\n // Split on commas. Header values don't allow quoted commas in this set,\n // so a plain split is safe.\n const parts = header.split(',')\n for (const raw of parts) {\n const trimmed = raw.trim()\n if (trimmed.length === 0) continue\n const segments = trimmed.split(';')\n const typeSeg = segments[0]?.trim().toLowerCase()\n if (!typeSeg) continue\n let quality = 1\n const params: Record<string, string> = {}\n for (let i = 1; i < segments.length; i++) {\n const seg = segments[i]?.trim()\n if (!seg) continue\n const eq = seg.indexOf('=')\n if (eq === -1) continue\n const key = seg.slice(0, eq).trim().toLowerCase()\n let value = seg.slice(eq + 1).trim()\n // Strip surrounding quotes if present.\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n value = value.slice(1, value.length - 1)\n }\n if (key === 'q') {\n const q = Number(value)\n quality = Number.isFinite(q) ? Math.max(0, Math.min(1, q)) : 0\n } else {\n params[key] = value\n }\n }\n out.push({ type: typeSeg, quality, params })\n }\n return out\n}\n\n/**\n * Specificity score for a media-range. Higher is more specific.\n * `*/*` → 0\n * `type/*` → 1\n * `type/sub` → 2 (+ #params for tie-breaking)\n */\nfunction specificity(entry: ParsedAccept): number {\n if (entry.type === '*/*' || entry.type === '*') return 0\n if (entry.type.endsWith('/*')) return 1\n return 2 + Object.keys(entry.params).length\n}\n\n/**\n * Stable sort by RFC preference: highest q first, then most-specific first.\n * Returns a NEW array; does not mutate input.\n */\nexport function sortByPreference(entries: readonly ParsedAccept[]): ParsedAccept[] {\n return [...entries]\n .map((e, i) => ({ e, i }))\n .sort((a, b) => {\n if (b.e.quality !== a.e.quality) return b.e.quality - a.e.quality\n const sb = specificity(b.e)\n const sa = specificity(a.e)\n if (sb !== sa) return sb - sa\n return a.i - b.i // stable\n })\n .map((x) => x.e)\n}\n\n/** Does an offered concrete type match a parsed Accept entry (incl. wildcards)? */\nfunction entryMatches(entry: ParsedAccept, offered: string): boolean {\n const offeredLower = offered.toLowerCase()\n if (entry.type === '*/*' || entry.type === '*') return true\n if (entry.type === offeredLower) return true\n if (entry.type.endsWith('/*')) {\n const prefix = entry.type.slice(0, -1) // keep trailing slash\n return offeredLower.startsWith(prefix)\n }\n return false\n}\n\n/**\n * Return the best match for `offered` against `acceptHeader`, or `false`.\n *\n * Matching algorithm:\n * 1. If `acceptHeader` is missing/empty → first offered wins (Express behavior).\n * 2. Walk parsed entries sorted by quality + specificity.\n * 3. For each entry (in preference order), pick the first offered that matches.\n * Among ties at the same Accept entry, the offered's listed order wins.\n * 4. Entries with `q=0` reject — never match.\n */\nexport function selectBest(\n acceptHeader: string | undefined,\n offered: readonly string[],\n): string | false {\n if (offered.length === 0) return false\n const expanded = offered.map(expandShorthand)\n if (!acceptHeader || acceptHeader.trim() === '') {\n return offered[0] ?? false\n }\n const sorted = sortByPreference(parseAcceptHeader(acceptHeader))\n if (sorted.length === 0) return offered[0] ?? false\n\n for (const entry of sorted) {\n if (entry.quality === 0) continue\n for (let i = 0; i < expanded.length; i++) {\n if (entryMatches(entry, expanded[i] as string)) {\n return offered[i] as string\n }\n }\n }\n return false\n}\n","/**\n * Higher-level `accepts*` helpers, parameterized over a context-like object\n * with a `headers` map. Kept context-agnostic so they're trivially testable\n * with a plain `{ headers: {...} }` stub.\n */\n\nimport type { IncomingHttpHeaders } from 'node:http'\nimport { parseAcceptHeader, selectBest, expandShorthand } from './accept.ts'\n\n/** Minimal shape we depend on — `IngeniumContext` satisfies it. */\nexport interface NegotiableCtx {\n headers: IncomingHttpHeaders\n}\n\nfunction readHeader(ctx: NegotiableCtx, name: string): string | undefined {\n const v = ctx.headers[name]\n if (Array.isArray(v)) return v.join(',')\n return v\n}\n\n/**\n * `accepts(ctx)` → list of accepted media types in preference order\n * (after expanding shorthand inputs is a no-op here — it returns the raw\n * mime strings the client sent).\n *\n * `accepts(ctx, ...types)` → best matching offered type, or `false`.\n * Each `type` may be a shorthand (`'json'`, `'html'`) or full mime\n * (`'application/json'`).\n */\nexport function accepts(ctx: NegotiableCtx): string[]\nexport function accepts(ctx: NegotiableCtx, ...types: string[]): string | false\nexport function accepts(ctx: NegotiableCtx, ...types: string[]): string | false | string[] {\n const header = readHeader(ctx, 'accept')\n if (types.length === 0) {\n return parseAcceptHeader(header).map((e) => e.type)\n }\n const best = selectBest(header, types.map(expandShorthand))\n if (best === false) return false\n // Map the canonical match back to the caller's original token (preserves shorthand).\n for (const t of types) {\n if (expandShorthand(t) === best) return t\n }\n return best\n}\n\n/**\n * `acceptsCharsets(ctx)` → all charsets in preference order.\n * `acceptsCharsets(ctx, ...charsets)` → best match or `false`.\n */\nexport function acceptsCharsets(ctx: NegotiableCtx): string[]\nexport function acceptsCharsets(ctx: NegotiableCtx, ...charsets: string[]): string | false\nexport function acceptsCharsets(\n ctx: NegotiableCtx,\n ...charsets: string[]\n): string | false | string[] {\n const header = readHeader(ctx, 'accept-charset')\n if (charsets.length === 0) return parseAcceptHeader(header).map((e) => e.type)\n return selectBest(header, charsets)\n}\n\n/**\n * `acceptsLanguages(ctx)` → all languages in preference order.\n * `acceptsLanguages(ctx, ...langs)` → best match or `false`.\n *\n * Language matching is treated like opaque tokens with `*` as wildcard;\n * partial-tag matching (e.g. `en` matching `en-US`) is **not** performed —\n * use exact tags for predictable behavior, mirroring Express's default.\n */\nexport function acceptsLanguages(ctx: NegotiableCtx): string[]\nexport function acceptsLanguages(ctx: NegotiableCtx, ...langs: string[]): string | false\nexport function acceptsLanguages(\n ctx: NegotiableCtx,\n ...langs: string[]\n): string | false | string[] {\n const header = readHeader(ctx, 'accept-language')\n if (langs.length === 0) return parseAcceptHeader(header).map((e) => e.type)\n return selectBest(header, langs)\n}\n\n/**\n * `acceptsEncodings(ctx)` → all encodings in preference order.\n * `acceptsEncodings(ctx, ...encodings)` → best match or `false`.\n *\n * Per RFC 9110 §12.5.4, when `Accept-Encoding` is absent, the server\n * MAY assume the client accepts any encoding — we follow Express and\n * return the first offered.\n */\nexport function acceptsEncodings(ctx: NegotiableCtx): string[]\nexport function acceptsEncodings(ctx: NegotiableCtx, ...encodings: string[]): string | false\nexport function acceptsEncodings(\n ctx: NegotiableCtx,\n ...encodings: string[]\n): string | false | string[] {\n const header = readHeader(ctx, 'accept-encoding')\n if (encodings.length === 0) return parseAcceptHeader(header).map((e) => e.type)\n return selectBest(header, encodings)\n}\n","/**\n * `formatResponse(ctx, handlers)` — Express's `res.format` for Ingenium.\n *\n * Picks the best handler key against the request `Accept` header, runs it,\n * sets `Content-Type` to the matched key, and writes the result as the\n * response body. If no handler matches and no `default` key is provided,\n * throws a `IngeniumError(406, 'NOT_ACCEPTABLE')`.\n *\n * Handlers may be sync or async — `formatResponse` always awaits.\n */\n\nimport { Buffer } from 'node:buffer'\nimport { selectBest } from './accept.ts'\nimport type { NegotiableCtx } from './negotiate.ts'\nimport { IngeniumError } from '../errors.ts'\n\n/** Minimal context shape required by `formatResponse` — narrower than full `IngeniumContext`. */\nexport interface FormattableCtx extends NegotiableCtx {\n set(name: string, value: string | string[]): unknown\n json(body: unknown, status?: number): void\n send(body: Buffer | string, status?: number): void\n}\n\n/** Map of `mime → handler`. The reserved key `default` is the no-match fallback. */\nexport type FormatHandlers = Record<string, () => unknown | Promise<unknown>>\n\n/**\n * Pick the best handler key for `Accept` and run it.\n *\n * - JSON-shaped result objects are written via `ctx.json`.\n * - String / Buffer results are written via `ctx.send` with the matched\n * content-type preserved (instead of `send`'s default text/plain inference).\n * - `default` handler is used when no explicit key matches.\n * - No match + no default → throws `IngeniumError(406, 'NOT_ACCEPTABLE')`.\n */\nexport async function formatResponse(\n ctx: FormattableCtx,\n handlers: FormatHandlers,\n): Promise<void> {\n const keys = Object.keys(handlers).filter((k) => k !== 'default')\n const acceptHeader = (() => {\n const v = ctx.headers['accept']\n return Array.isArray(v) ? v.join(',') : v\n })()\n\n let chosenKey: string | false = selectBest(acceptHeader, keys)\n\n // No explicit match — fall back to `default`, else 406.\n if (chosenKey === false) {\n if ('default' in handlers) {\n const result = await handlers['default']!()\n writeResult(ctx, result, undefined)\n return\n }\n throw new IngeniumError(\n 406,\n 'NOT_ACCEPTABLE',\n `None of the offered types [${keys.join(', ')}] satisfy Accept: ${acceptHeader ?? '*/*'}`,\n )\n }\n\n const handler = handlers[chosenKey]\n if (!handler) {\n // Defensive — shouldn't happen since selectBest only returns offered keys.\n throw new IngeniumError(406, 'NOT_ACCEPTABLE', 'Internal: matched handler missing')\n }\n const result = await handler()\n writeResult(ctx, result, chosenKey)\n}\n\nfunction writeResult(ctx: FormattableCtx, result: unknown, contentType: string | undefined): void {\n if (contentType) ctx.set('content-type', contentType)\n if (result === undefined || result === null) {\n // Treat as empty body — caller handles 204 elsewhere.\n ctx.send('', undefined)\n return\n }\n if (typeof result === 'string') {\n ctx.send(result, undefined)\n return\n }\n if (Buffer.isBuffer(result) || result instanceof Uint8Array) {\n ctx.send(Buffer.isBuffer(result) ? result : Buffer.from(result))\n return\n }\n // Object → JSON.\n ctx.json(result)\n}\n","/**\n * `isFresh(reqHeaders, resHeaders)` — RFC 7232 conditional-request evaluator.\n *\n * Returns `true` when the response can be considered fresh relative to the\n * client's cached copy, i.e. a `304 Not Modified` is appropriate. This is\n * the engine behind `ctx.fresh` / `ctx.stale`.\n *\n * Decision matrix:\n * - `If-None-Match` present → compare against response `ETag`. Wildcard\n * `*` matches any current representation. Strong/weak prefixes are\n * normalized away (per RFC 7232 §2.3.2 weak-comparison rules).\n * - Else if `If-Modified-Since` present → compare against response\n * `Last-Modified` (or fall back to `Date`). Fresh when the resource has\n * not been modified since.\n * - Otherwise → not fresh (no precondition to evaluate).\n *\n * Methods other than GET/HEAD are not handled here — callers should gate\n * on method themselves (Express does the same in `req.fresh`).\n */\n\n/** Header bag shape — accepts both incoming-request and stored-response styles. */\nexport type HeaderBag = Record<string, string | string[] | undefined>\n\nfunction getHeader(bag: HeaderBag, name: string): string | undefined {\n const lower = name.toLowerCase()\n const v = bag[lower]\n if (v === undefined) {\n // Try original-case key as fallback.\n const alt = bag[name]\n if (alt === undefined) return undefined\n return Array.isArray(alt) ? alt.join(',') : alt\n }\n return Array.isArray(v) ? v.join(',') : v\n}\n\n/** Strip a leading `W/` weak prefix and surrounding double-quotes. */\nfunction normalizeEtag(tag: string): string {\n let t = tag.trim()\n if (t.startsWith('W/') || t.startsWith('w/')) t = t.slice(2)\n if (t.length >= 2 && t.startsWith('\"') && t.endsWith('\"')) t = t.slice(1, t.length - 1)\n return t\n}\n\n/** Split an `If-None-Match` header value into individual ETag tokens. */\nfunction splitInm(header: string): string[] {\n return header.split(',').map((s) => s.trim()).filter((s) => s.length > 0)\n}\n\n/**\n * Returns `true` when the response is fresh w.r.t. the client's preconditions.\n */\nexport function isFresh(reqHeaders: HeaderBag, resHeaders: HeaderBag): boolean {\n const ifNoneMatch = getHeader(reqHeaders, 'if-none-match')\n const ifModifiedSince = getHeader(reqHeaders, 'if-modified-since')\n\n // No conditional headers → cannot be fresh.\n if (!ifNoneMatch && !ifModifiedSince) return false\n\n // Cache-Control: no-cache on the request explicitly disables 304.\n const reqCacheControl = getHeader(reqHeaders, 'cache-control')\n if (reqCacheControl && /(?:^|,)\\s*no-cache\\s*(?:,|$)/i.test(reqCacheControl)) {\n return false\n }\n\n // ───── If-None-Match takes precedence ─────\n if (ifNoneMatch) {\n if (ifNoneMatch.trim() === '*') return true\n const etag = getHeader(resHeaders, 'etag')\n if (!etag) return false\n const target = normalizeEtag(etag)\n for (const candidate of splitInm(ifNoneMatch)) {\n if (normalizeEtag(candidate) === target) return true\n }\n return false\n }\n\n // ───── Fallback: If-Modified-Since ─────\n if (ifModifiedSince) {\n const lastModified = getHeader(resHeaders, 'last-modified') ?? getHeader(resHeaders, 'date')\n if (!lastModified) return false\n const sinceMs = Date.parse(ifModifiedSince)\n const lastMs = Date.parse(lastModified)\n if (!Number.isFinite(sinceMs) || !Number.isFinite(lastMs)) return false\n // Fresh when resource hasn't changed since the client's copy.\n return lastMs <= sinceMs\n }\n\n return false\n}\n","/**\n * `computeEtag(body, weak?)` — sha1-based entity tag for response bodies.\n *\n * Format: `W/\"<sha1-base64-without-padding>\"` (weak) or `\"<sha1-base64-without-padding>\"`.\n * Weak is the default — fine for JSON where serialization may legitimately vary\n * (key order, whitespace) without representing a different resource.\n *\n * The empty-body ETag is special-cased to a fixed constant so two empty\n * bodies always compare equal without pumping through the hash.\n */\n\nimport { createHash } from 'node:crypto'\nimport { Buffer } from 'node:buffer'\n\n/** Pre-computed sha1(\"\") base64 → `2jmj7l5rSw0yVb/vlWAYkK/YBwk=`. */\nconst EMPTY_HASH = '2jmj7l5rSw0yVb/vlWAYkK/YBwk='\n\n/**\n * Compute an ETag for the given body. Strings are treated as UTF-8.\n * @param body Response body — usually `JSON.stringify(...)` or a `Buffer`.\n * @param weak Prefix the tag with `W/`. Defaults to `true` for JSON safety.\n */\nexport function computeEtag(body: string | Buffer, weak = true): string {\n const len = typeof body === 'string' ? Buffer.byteLength(body, 'utf8') : body.length\n if (len === 0) return weak ? `W/\"${EMPTY_HASH}\"` : `\"${EMPTY_HASH}\"`\n const hash = createHash('sha1').update(body as Buffer | string).digest('base64')\n // Trim trailing `=` padding for compactness — keeps tag URL-safe-ish and shorter.\n const trimmed = hash.replace(/=+$/g, '')\n return weak ? `W/\"${trimmed}\"` : `\"${trimmed}\"`\n}\n","/**\n * `respondJsonWithEtag(ctx, body, opts)` — JSON response with auto ETag and\n * 304 short-circuit when `If-None-Match` matches.\n *\n * Behavior:\n * 1. Stringify `body` to JSON exactly once.\n * 2. Compute weak ETag (default) over the stringified bytes.\n * 3. If `If-None-Match` (after weak normalization) matches → set 304,\n * clear body, mark written. Skip writing the JSON.\n * 4. Otherwise: set `ETag` + `Content-Type` headers, write the body via\n * the same internal shape `ctx.json` uses, and mark written.\n *\n * Uses the lower-level shape from `IngeniumContext` directly (rather than\n * calling `ctx.json`) so the JSON.stringify result can be reused without\n * a second pass.\n */\n\nimport type { IncomingHttpHeaders } from 'node:http'\nimport { computeEtag } from './etag.ts'\nimport type { ResponseBody } from '../context/context.ts'\nimport { IngeniumUnserializableError } from '../errors.ts'\n\n/**\n * Strict `JSON.stringify` wrapper mirroring the one in `context.ts`. Kept\n * inline rather than shared to avoid a circular import between\n * `negotiation/` and `context/` (and so this helper stays consumable as a\n * standalone with the lightweight `JsonEtagCtx` shape).\n */\nfunction strictStringifyForEtag(body: unknown): string {\n try {\n return JSON.stringify(body) as string\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n let reason: string\n if (/circular/i.test(msg)) reason = `circular structure (${msg})`\n else if (/BigInt/i.test(msg)) reason = `BigInt value (${msg})`\n else reason = msg\n try {\n process.emitWarning(\n `IngeniumUnserializableError: ${reason}`,\n { type: 'IngeniumUnserializableError' },\n )\n } catch {\n // emitWarning unavailable — swallow.\n }\n throw new IngeniumUnserializableError(\n `Response body cannot be serialized: ${reason}`,\n err,\n )\n }\n}\n\n/** Options for `respondJsonWithEtag`. */\nexport interface JsonEtagOptions {\n /** Prefix the ETag with `W/`. Defaults to `true`. */\n weak?: boolean\n /** HTTP status to use for the success path. Defaults to `200`. */\n status?: number\n}\n\n/**\n * Minimal context shape required by `respondJsonWithEtag` — keeps the\n * helper testable with a plain stub and avoids a hard import cycle on\n * the full `IngeniumContext` class.\n */\nexport interface JsonEtagCtx {\n headers: IncomingHttpHeaders\n _statusCode: number\n _headers: Record<string, string | string[]>\n _body: ResponseBody\n _written: boolean\n}\n\n/** Strip `W/` and quotes for weak-comparison equality. */\nfunction normalizeEtag(tag: string): string {\n let t = tag.trim()\n if (t.startsWith('W/') || t.startsWith('w/')) t = t.slice(2)\n if (t.length >= 2 && t.startsWith('\"') && t.endsWith('\"')) t = t.slice(1, t.length - 1)\n return t\n}\n\nfunction ifNoneMatchHas(header: string, target: string): boolean {\n if (header.trim() === '*') return true\n const want = normalizeEtag(target)\n for (const part of header.split(',')) {\n const candidate = part.trim()\n if (candidate.length === 0) continue\n if (normalizeEtag(candidate) === want) return true\n }\n return false\n}\n\nexport function respondJsonWithEtag(\n ctx: JsonEtagCtx,\n body: unknown,\n opts: JsonEtagOptions = {},\n): void {\n const weak = opts.weak ?? true\n const status = opts.status ?? 200\n const serialized = strictStringifyForEtag(body)\n const etag = computeEtag(serialized, weak)\n\n const inm = ctx.headers['if-none-match']\n const inmStr = Array.isArray(inm) ? inm.join(',') : inm\n if (typeof inmStr === 'string' && inmStr.length > 0 && ifNoneMatchHas(inmStr, etag)) {\n // Short-circuit: cache hit.\n ctx._statusCode = 304\n ctx._headers['etag'] = etag\n // 304 must not carry a body.\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n\n ctx._statusCode = status\n ctx._headers['etag'] = etag\n if (!ctx._headers['content-type']) {\n ctx._headers['content-type'] = 'application/json; charset=utf-8'\n }\n ctx._body = { kind: 'string', data: serialized }\n ctx._written = true\n}\n","import type { IncomingHttpHeaders } from 'node:http'\nimport type { Readable } from 'node:stream'\nimport { Buffer } from 'node:buffer'\nimport { IngeniumBody, type ParseSchema, type SafeParseSchema } from './body.ts'\nimport { makeIngeniumCookies, type IngeniumCookies } from './cookies.ts'\nimport { isStandardSchema, type StandardIssue, type StandardSchemaV1 } from '../schema/standard.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport { resolveForwarded, type ForwardedInfo, type TrustProxy } from '../proxy/trust.ts'\nimport {\n accepts as acceptsFn,\n acceptsCharsets as acceptsCharsetsFn,\n acceptsLanguages as acceptsLanguagesFn,\n acceptsEncodings as acceptsEncodingsFn,\n} from '../negotiation/negotiate.ts'\nimport { formatResponse, type FormatHandlers } from '../negotiation/format.ts'\nimport { isFresh } from '../negotiation/fresh.ts'\nimport { respondJsonWithEtag, type JsonEtagOptions } from '../negotiation/json-etag.ts'\nimport {\n IngeniumHaltError,\n IngeniumHeaderInjectionError,\n IngeniumUnserializableError,\n IngeniumValidationError,\n} from '../errors.ts'\n\n/**\n * Dev-mode gate. Captured ONCE at module load; in production V8 dead-code-\n * eliminates the branch bodies behind `if (IS_DEV)`. Every dev diagnostic\n * MUST check this first so it pays nothing on the hot path.\n */\nconst IS_DEV = process.env.NODE_ENV !== 'production'\n\n/**\n * @internal Test-only flag for the trust-proxy / XFF mismatch warning. Once\n * per process — read-once UX. Exposed via `_resetFootgunWarnings()` for tests.\n */\nlet _trustProxyWarned = false\n\n/**\n * @internal Test-only reset hook. Clears all module-scoped once-flags used by\n * the dev footgun warnings. Not part of the public API.\n */\nexport function _resetFootgunWarnings(): void {\n _trustProxyWarned = false\n}\n\n/** CR/LF detector for header-injection guard. Tested against names + values. */\nconst CRLF_RE = /[\\r\\n]/\n\n/**\n * Reject header NAMES containing CR or LF. Empty/undefined names are\n * allowed through — the underlying header bag's own type system rejects\n * those naturally.\n */\nfunction assertHeaderNameSafe(name: string): void {\n if (CRLF_RE.test(name)) {\n throw new IngeniumHeaderInjectionError(\n `Header name contains CR/LF (possible header injection): ${JSON.stringify(name)}`,\n )\n }\n}\n\n/**\n * Reject header VALUES containing CR or LF. Accepts a single string or an\n * array — the array form checks each element. `undefined` is allowed (some\n * call sites pass through optionals); empty string is allowed (legitimate).\n */\nfunction assertHeaderValueSafe(name: string, value: string | string[]): void {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const v = value[i]\n if (typeof v === 'string' && CRLF_RE.test(v)) {\n throw new IngeniumHeaderInjectionError(\n `Header value contains CR/LF (possible header injection): ${name}[${i}]`,\n )\n }\n }\n return\n }\n if (typeof value === 'string' && CRLF_RE.test(value)) {\n throw new IngeniumHeaderInjectionError(\n `Header value contains CR/LF (possible header injection): ${name}`,\n )\n }\n}\n\n/**\n * Strict `JSON.stringify` wrapper used by the response helpers. Surfaces\n * `BigInt` / circular / other serialization failures as a\n * `IngeniumUnserializableError` so the framework error boundary can render\n * a clean 500 instead of a deep `TypeError` from V8.\n */\nfunction strictStringify(body: unknown): string {\n try {\n return JSON.stringify(body) as string\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n let reason: string\n if (/circular/i.test(msg)) {\n reason = `circular structure (${msg})`\n } else if (/BigInt/i.test(msg)) {\n reason = `BigInt value (${msg})`\n } else {\n reason = msg\n }\n try {\n process.emitWarning(\n `IngeniumUnserializableError: ${reason}`,\n { type: 'IngeniumUnserializableError' },\n )\n } catch {\n // process.emitWarning can throw in unusual runtimes (workers); swallow.\n }\n throw new IngeniumUnserializableError(\n `Response body cannot be serialized: ${reason}`,\n err,\n )\n }\n}\n\n/** Sentinel for routes with no params — frozen, so `ctx.params.foo` is safe. */\nconst EMPTY_PARAMS = Object.freeze(Object.create(null) as Record<string, string>)\n\n/**\n * `URLSearchParams` augmented with a `parse(schema)` method that runs the\n * query through the same schema-detection pipeline as `ctx.body.json(schema)`.\n *\n * The shape passed to the schema is a **shallow array-aware** object:\n *\n * `?id=42&tag=a&tag=b&active=true`\n * → `{ id: '42', tag: ['a','b'], active: 'true' }`\n *\n * Single-occurrence keys → `string`. Repeated keys → `string[]`. Everything is\n * a string on the wire, so the user's schema is responsible for coercing\n * numbers/booleans (Zod: use `z.coerce.number()`; ArkType: use `'string.numeric.parse'`).\n *\n * Rationale for picking THIS coercion over alternatives:\n * - \"raw strings only\" loses repeated-key fidelity (qs/Express-style arrays)\n * - \"pre-coerced booleans/numbers\" surprises users when \"12foo\" silently\n * becomes a string or \"true\" becomes a boolean against their schema\n * - Shallow-array matches `Object.fromEntries` semantics PLUS the most\n * common ergonomic ask (tag=a&tag=b → tag: string[])\n */\nexport interface IngeniumQuery extends URLSearchParams {\n parse<T = unknown>(\n schema: StandardSchemaV1<unknown, T> | SafeParseSchema<T> | ParseSchema<T>,\n ): T\n}\n\n/** Normalize a Standard Schema issue path into a dot-joined field key. */\nfunction queryPathToField(path: StandardIssue['path']): string {\n if (!path || path.length === 0) return '_'\n const parts: string[] = []\n for (const seg of path) {\n if (seg !== null && typeof seg === 'object' && 'key' in seg) {\n parts.push(String(seg.key))\n } else {\n parts.push(String(seg))\n }\n }\n return parts.join('.') || '_'\n}\n\n/**\n * Build the `{ key: string | string[] }` input that gets fed to the schema.\n * Walks the URLSearchParams once; collisions promote a scalar to an array.\n *\n * Allocated lazily on `parse()` only — never paid by handlers that just read\n * `ctx.query.get(...)`. Iteration of URLSearchParams is iteration-order stable\n * and yields decoded values, so no manual percent-decoding here.\n */\nfunction toShallowArrayObject(usp: URLSearchParams): Record<string, string | string[]> {\n const out: Record<string, string | string[]> = Object.create(null)\n for (const [k, v] of usp) {\n const existing = out[k]\n if (existing === undefined) {\n out[k] = v\n } else if (Array.isArray(existing)) {\n existing.push(v)\n } else {\n out[k] = [existing, v]\n }\n }\n return out\n}\n\nfunction makeIngeniumQuery(raw: string): IngeniumQuery {\n const usp = new URLSearchParams(raw) as IngeniumQuery\n Object.defineProperty(usp, 'parse', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: function parse<T>(\n this: URLSearchParams,\n schema: StandardSchemaV1<unknown, T> | SafeParseSchema<T> | ParseSchema<T>,\n ): T {\n const input = toShallowArrayObject(this)\n // 1. Standard Schema v1 takes precedence.\n if (isStandardSchema(schema)) {\n const maybe = schema['~standard'].validate(input)\n // Query parsing is synchronous — async validators are still accepted\n // but throw a clearer error than awaiting at the wire would.\n if (maybe instanceof Promise) {\n throw new IngeniumValidationError({\n _: 'async Standard Schema validators are not supported on ctx.query.parse (use ctx.body.json for async)',\n })\n }\n if (maybe.issues) {\n const fields: Record<string, string> = {}\n for (const issue of maybe.issues) {\n fields[queryPathToField(issue.path)] = issue.message\n }\n throw new IngeniumValidationError(fields)\n }\n return maybe.value as T\n }\n // 2. Zod-like safeParse.\n if (\n 'safeParse' in schema &&\n typeof (schema as SafeParseSchema<T>).safeParse === 'function'\n ) {\n const result = (schema as SafeParseSchema<T>).safeParse(input)\n if (!result.success) {\n const fields: Record<string, string> = {}\n for (const issue of result.error.issues) {\n fields[issue.path.join('.') || '_'] = issue.message\n }\n throw new IngeniumValidationError(fields)\n }\n return result.data\n }\n // 3. Plain parse.\n try {\n return (schema as ParseSchema<T>).parse(input)\n } catch (err) {\n throw new IngeniumValidationError({ _: (err as Error).message ?? 'validation failed' })\n }\n },\n })\n return usp\n}\n\n/** Internal response body shape — adapter writes one of these to the wire. */\nexport type ResponseBody =\n | { kind: 'none' }\n | { kind: 'buffer'; data: Buffer }\n | { kind: 'string'; data: string }\n | { kind: 'stream'; data: Readable }\n\n/**\n * Per-request context. Pool-bound: one instance per pool slot, reused\n * across thousands of requests. All mutable fields are reset between uses.\n *\n * The `Params` generic is a phantom — it narrows `ctx.params` for typed\n * route handlers but is `Record<string, string>` at runtime.\n */\nexport class IngeniumContext<Params = Record<string, string>> {\n // ───── Request ─────────────────────────────────────────────────────────\n /** HTTP method, uppercase. */\n method: HttpMethod = 'GET'\n /** Full request URL including query string (e.g. `/users/42?expand=posts`). */\n url = '/'\n /** Path portion of the URL (no query string). Set by the adapter. */\n path = '/'\n /** Raw query string (no leading `?`). Use `query` for parsed access. */\n rawQuery = ''\n /** Route params, written at trie-match time. */\n params: Params = EMPTY_PARAMS as unknown as Params\n /** Lowercased request headers (Node convention). */\n headers: IncomingHttpHeaders = {}\n /** Lazy body accessor. */\n readonly body: IngeniumBody = new IngeniumBody()\n /** Free-form per-request state for plugins/middleware (e.g. `ctx.user = ...`). */\n state: Record<string, unknown> = Object.create(null) as Record<string, unknown>\n\n /**\n * Per-request handle to enqueue background jobs onto a registered queue.\n * Wired by `IngeniumApp` as a lazy decorator (declared with `!` because the\n * runtime value is installed by the decorator registry, not the class\n * initializer). Throws if the named queue isn't registered.\n *\n * @example\n * await ctx.queue<{ to: string }>('emails').add({ to: 'a@b.com' })\n */\n queue!: <TData = unknown>(name: string) => import('../jobs/types.ts').JobHandle<TData>\n\n /** Lazy-parsed query. First access caches the URLSearchParams. */\n private _query: IngeniumQuery | null = null\n get query(): IngeniumQuery {\n if (!this._query) this._query = makeIngeniumQuery(this.rawQuery)\n return this._query\n }\n\n /**\n * @internal Lazy cookie holder. `null` until first read of `ctx.cookies`.\n * Reset to `null` in `reset()` so a context returned to the pool drops the\n * parsed-cookie cache (and any closed-over write state — though writes go\n * straight to `_headers`, which is itself reset by reassignment).\n */\n _cookies: IngeniumCookies | null = null\n /**\n * First-class cookie API. Lazy: the holder is allocated on first access so\n * apps that never touch cookies pay zero per-request overhead. See\n * `cookies.ts` for the read/write contract and signing rules.\n *\n * @example\n * const sid = ctx.cookies.get('sid', { signed: true })\n * ctx.cookies.set('theme', 'dark', { httpOnly: true, sameSite: 'lax' })\n * ctx.cookies.clear('legacy')\n */\n get cookies(): IngeniumCookies {\n if (!this._cookies) this._cookies = makeIngeniumCookies(this)\n return this._cookies\n }\n\n /**\n * @internal App-wide cookie-signing secrets. Stamped by `IngeniumApp.handle`\n * on dispatch entry when configured (mirrors `_trustProxy`). First secret\n * signs new cookies; all entries verify reads (supports rotation). Empty\n * means signed cookies will throw `IngeniumError(500, 'COOKIE_SECRET_MISSING')`.\n *\n * NOT cleared in `reset()` — this is app-wide config, not per-request state,\n * and the cost of re-stamping every request is wasteful when the value is\n * stable across the app's lifetime. The first call to `handle()` after a\n * compose sets it; subsequent requests reuse the same array reference.\n */\n _cookieSecrets: readonly string[] = []\n\n // ───── Network info (trust-proxy aware) ────────────────────────────────\n /** Immediate socket peer address — populated by the adapter. */\n remoteAddress = '127.0.0.1'\n /** Underlying transport protocol — populated by the adapter (http for node:http, https for TLS). */\n baseProtocol: 'http' | 'https' = 'http'\n /** @internal `trustProxy` config carried in from the app. */ _trustProxy: TrustProxy = false\n /** @internal Cached forwarded resolution; computed lazily from headers. */\n private _forwarded: ForwardedInfo | null = null\n\n private resolveForwarded(): ForwardedInfo {\n if (!this._forwarded) {\n this._forwarded = resolveForwarded(\n this._trustProxy,\n this.remoteAddress,\n this.headers as Record<string, string | string[] | undefined>,\n this.baseProtocol,\n )\n // Dev-only — warn once per process when the user reads forwarded info\n // with trustProxy disabled BUT the request carries X-Forwarded-For.\n // Almost always means the user is behind a proxy and forgot to enable\n // trustProxy, so `ctx.ip` is silently returning the proxy's address.\n if (IS_DEV && !_trustProxyWarned && this._trustProxy === false) {\n if (this.headers['x-forwarded-for'] !== undefined) {\n _trustProxyWarned = true\n try {\n process.emitWarning(\n \"Read ctx.ip with trustProxy disabled, but request has X-Forwarded-For. Set 'trustProxy' on the app if behind a reverse proxy.\",\n { type: 'IngeniumTrustProxyWarning' },\n )\n } catch {\n // process.emitWarning can throw in unusual runtimes (workers); swallow.\n }\n }\n }\n }\n return this._forwarded\n }\n\n /**\n * Best-effort client IP. With `trustProxy: false` this is the immediate\n * socket peer; with trust-proxy enabled the X-Forwarded-For chain is\n * walked according to the configured trust policy.\n */\n get ip(): string { return this.resolveForwarded().ip }\n /** Full forwarded chain (left-to-right, immediate peer last). */\n get ips(): readonly string[] { return this.resolveForwarded().ips }\n /** Best-effort protocol — honors `X-Forwarded-Proto` when trust-proxy is enabled. */\n get protocol(): 'http' | 'https' { return this.resolveForwarded().protocol }\n /** Convenience: `protocol === 'https'`. */\n get secure(): boolean { return this.protocol === 'https' }\n /** Best-effort hostname (no port) — honors `X-Forwarded-Host` when trust-proxy is enabled. */\n get hostname(): string { return this.resolveForwarded().hostname }\n\n // ───── Response ────────────────────────────────────────────────────────\n /** @internal */ _statusCode = 200\n /** @internal */ _headers: Record<string, string | string[]> = Object.create(null) as Record<string, string | string[]>\n /** @internal */ _body: ResponseBody = { kind: 'none' }\n /** @internal Whether a response helper has been called. */\n _written = false\n\n /**\n * @internal Per-request generation counter. Incremented every time the\n * pool resets this context (and also bumped by `IngeniumApp.handle` when a\n * request times out, so writes from the orphaned handler can be detected\n * as stale). Compared against `_dispatchEpoch` by every response writer.\n */\n _epoch = 0\n\n /**\n * @internal Last `_epoch` value captured by `IngeniumApp.withEpochGuard`.\n * Set on dispatch entry; the per-dispatch wrappers installed around the\n * response writers close over this value to detect late writes from an\n * orphaned (timed-out) handler. The wrappers compare `_epoch` against\n * the captured value at call time — mismatch ⇒ orphan ⇒ swallow.\n *\n * `0` means no guard is active (no `requestTimeoutMs` configured, or\n * the dispatch already resolved naturally).\n */\n _dispatchEpoch = 0\n\n // ───── Response helpers ────────────────────────────────────────────────\n\n /**\n * @internal Dev-only — emit `IngeniumDoubleWriteWarning` when a writer is\n * called after `_written` is already true. No-op in production: V8\n * eliminates the branch body behind the `IS_DEV` gate.\n */\n private _warnDoubleWrite(method: string): void {\n if (!IS_DEV) return\n if (!this._written) return\n try {\n process.emitWarning(\n `ctx.${method}() called after response was already written. Second call overrides the first; use 'return' to short-circuit.`,\n { type: 'IngeniumDoubleWriteWarning' },\n )\n } catch {\n // process.emitWarning can throw in unusual runtimes (workers); swallow.\n }\n }\n\n /** Set the HTTP status code. Returns `this` for chaining. */\n status(code: number): this {\n this._statusCode = code\n return this\n }\n\n /**\n * Set a response header (case-insensitive). Returns `this` for chaining.\n *\n * Throws `IngeniumHeaderInjectionError` if `name` or `value` contains CR\n * or LF — these would otherwise enable header-injection / response-\n * splitting attacks if a caller forwards untrusted user input directly.\n */\n set(name: string, value: string | string[]): this {\n assertHeaderNameSafe(name)\n assertHeaderValueSafe(name, value)\n this._headers[name.toLowerCase()] = value\n return this\n }\n /** Alias for `set` — matches Express's `res.setHeader`. */\n setHeader(name: string, value: string | string[]): this {\n return this.set(name, value)\n }\n\n /** Get a previously-set response header (lowercase lookup). */\n getHeader(name: string): string | string[] | undefined {\n return this._headers[name.toLowerCase()]\n }\n\n /**\n * Send a JSON response.\n *\n * Throws `IngeniumUnserializableError` if `body` cannot be encoded\n * (circular structure, `BigInt`, etc.) — surfaces a clean 500 from the\n * framework error boundary instead of a deep `TypeError`.\n */\n json(body: unknown, status?: number): void {\n this._warnDoubleWrite('json')\n const data = strictStringify(body)\n if (status !== undefined) this._statusCode = status\n if (!this._headers['content-type']) this._headers['content-type'] = 'application/json; charset=utf-8'\n this._body = { kind: 'string', data }\n this._written = true\n }\n\n /** Send a `text/plain` response. */\n text(body: string, status?: number): void {\n this._warnDoubleWrite('text')\n if (status !== undefined) this._statusCode = status\n if (!this._headers['content-type']) this._headers['content-type'] = 'text/plain; charset=utf-8'\n this._body = { kind: 'string', data: body }\n this._written = true\n }\n\n /** Send a `text/html` response. */\n html(body: string, status?: number): void {\n this._warnDoubleWrite('html')\n if (status !== undefined) this._statusCode = status\n if (!this._headers['content-type']) this._headers['content-type'] = 'text/html; charset=utf-8'\n this._body = { kind: 'string', data: body }\n this._written = true\n }\n\n /** Send a redirect (default 302). */\n redirect(location: string, status = 302): void {\n this._warnDoubleWrite('redirect')\n this._statusCode = status\n this._headers.location = location\n this._body = { kind: 'none' }\n this._written = true\n }\n\n /** Stream a `Readable` to the client. Sets content-type if not already set. */\n stream(readable: Readable, contentType?: string): void {\n this._warnDoubleWrite('stream')\n if (contentType && !this._headers['content-type']) this._headers['content-type'] = contentType\n this._body = { kind: 'stream', data: readable }\n this._written = true\n }\n\n /**\n * Sinatra-style short-circuit. Throws `IngeniumHaltError(status, body?)`\n * — the framework error boundary catches it and serializes per `bodyShape`:\n *\n * - `ctx.halt(401)` → 401 with default JSON `{ error, code: 'HALT' }`.\n * - `ctx.halt(404, 'Not Found')` → 404 `text/plain` body verbatim.\n * - `ctx.halt(422, { fields })` → 422 `application/json` body verbatim.\n *\n * The TypeScript `never` return type lets `if (!found) ctx.halt(404)`\n * narrow the rest of the function — code after the call is unreachable.\n *\n * To bypass the error boundary entirely (write the response without\n * throwing) call `ctx.json(body, status)` and `return` from the handler.\n *\n * @example\n * if (!authorized(ctx)) ctx.halt(401, 'Unauthorized')\n * if (!user) ctx.halt(404, { error: 'Not Found', id })\n */\n halt(status: number, body?: string | Record<string, unknown>): never {\n throw new IngeniumHaltError(status, body)\n }\n\n /** Send a `Buffer` body verbatim. */\n send(body: Buffer | string, status?: number): void {\n this._warnDoubleWrite('send')\n if (status !== undefined) this._statusCode = status\n if (typeof body === 'string') {\n if (!this._headers['content-type']) this._headers['content-type'] = 'text/plain; charset=utf-8'\n this._body = { kind: 'string', data: body }\n } else {\n if (!this._headers['content-type']) this._headers['content-type'] = 'application/octet-stream'\n this._body = { kind: 'buffer', data: body }\n }\n this._written = true\n }\n\n // ───── Content negotiation (request side) ──────────────────────────────\n\n /**\n * Return the best mime type the client accepts from the offered list, or\n * `false` if none are acceptable. With no arguments, returns the parsed\n * preference-ordered list of accepted types from `Accept`.\n *\n * Each `type` may be a shorthand (`'json'`, `'html'`, `'csv'`, …) or a full\n * mime (`'application/json'`). Quality factors are honored.\n *\n * @example\n * if (ctx.accepts('json')) ctx.json({ ok: true })\n * else ctx.status(406).text('Not Acceptable')\n */\n accepts(): string[]\n accepts(...types: string[]): string | false\n accepts(...types: string[]): string | false | string[] {\n return types.length === 0 ? acceptsFn(this) : acceptsFn(this, ...types)\n }\n\n /** Best matching charset from the offered list against `Accept-Charset`. */\n acceptsCharsets(): string[]\n acceptsCharsets(...charsets: string[]): string | false\n acceptsCharsets(...charsets: string[]): string | false | string[] {\n return charsets.length === 0 ? acceptsCharsetsFn(this) : acceptsCharsetsFn(this, ...charsets)\n }\n\n /** Best matching language against `Accept-Language` (exact-tag match only). */\n acceptsLanguages(): string[]\n acceptsLanguages(...langs: string[]): string | false\n acceptsLanguages(...langs: string[]): string | false | string[] {\n return langs.length === 0 ? acceptsLanguagesFn(this) : acceptsLanguagesFn(this, ...langs)\n }\n\n /** Best matching encoding against `Accept-Encoding` (first offered when header absent). */\n acceptsEncodings(): string[]\n acceptsEncodings(...encodings: string[]): string | false\n acceptsEncodings(...encodings: string[]): string | false | string[] {\n return encodings.length === 0 ? acceptsEncodingsFn(this) : acceptsEncodingsFn(this, ...encodings)\n }\n\n // ───── Content negotiation (response side) ─────────────────────────────\n\n /**\n * Run the handler whose key best matches the request `Accept` header. The\n * matched key is set as `Content-Type`. If no key matches and no `default`\n * handler is provided, throws `IngeniumError(406, 'NOT_ACCEPTABLE')`.\n */\n format(handlers: FormatHandlers): Promise<void> {\n return formatResponse(this, handlers)\n }\n\n /**\n * `true` when the client's `If-None-Match` matches the response `ETag`,\n * or `If-Modified-Since` is at-or-after the response `Last-Modified`.\n * Reads from `_headers` so handlers can set ETag / Last-Modified before checking.\n */\n get fresh(): boolean {\n return isFresh(\n this.headers as Record<string, string | string[] | undefined>,\n this._headers as Record<string, string | string[] | undefined>,\n )\n }\n\n /** `!fresh`. */\n get stale(): boolean {\n return !this.fresh\n }\n\n /**\n * Send a JSON body with an auto-computed weak ETag. If the request's\n * `If-None-Match` matches the computed tag, short-circuits to 304.\n */\n jsonWithEtag(body: unknown, opts?: JsonEtagOptions): void {\n respondJsonWithEtag(this, body, opts)\n }\n\n // ───── Pool lifecycle ──────────────────────────────────────────────────\n\n /**\n * Reset all per-request state. Called by the pool before returning the\n * context to the free list. Reassignments preserve the V8 hidden class\n * so subsequent allocations stay monomorphic.\n */\n reset(): void {\n this.method = 'GET'\n this.url = '/'\n this.path = '/'\n this.rawQuery = ''\n this.params = EMPTY_PARAMS as unknown as Params\n this.headers = {}\n this._query = null\n this._cookies = null\n this.state = Object.create(null) as Record<string, unknown>\n this.remoteAddress = '127.0.0.1'\n this.baseProtocol = 'http'\n this._trustProxy = false\n this._forwarded = null\n this._statusCode = 200\n this._headers = Object.create(null) as Record<string, string | string[]>\n this._body = { kind: 'none' }\n this._written = false\n this._dispatchEpoch = 0\n this._epoch++\n this.body._reset()\n }\n}\n","import { IngeniumContext } from './context.ts'\n\n/**\n * A bounded free-list of `IngeniumContext` objects. Acquire on each request,\n * release back when the response has been written. If the pool is empty,\n * a fresh context is allocated; if the pool is full on release, the\n * context is discarded (GC handles it). Never blocks.\n */\nexport class IngeniumContextPool {\n private readonly pool: IngeniumContext[] = []\n private readonly max: number\n\n constructor(maxSize = 1024) {\n this.max = maxSize\n }\n\n /** Acquire a context. Caller must call `release()` when done. */\n acquire(): IngeniumContext {\n return this.pool.pop() ?? new IngeniumContext()\n }\n\n /** Reset and return the context to the free list (or discard if full). */\n release(ctx: IngeniumContext): void {\n ctx.reset()\n if (this.pool.length < this.max) this.pool.push(ctx)\n }\n\n /** Current free-list size. Useful for tests and metrics. */\n get size(): number {\n return this.pool.length\n }\n}\n","import { Buffer } from 'node:buffer'\nimport { Readable } from 'node:stream'\nimport type { IngeniumContext } from '../context/context.ts'\n\n/**\n * Dev-mode gate. Captured ONCE at module load; in production V8 dead-code-\n * eliminates the branch bodies behind `if (IS_DEV)`. Every dev diagnostic\n * MUST check this first so it pays nothing on the hot path.\n */\nconst IS_DEV = process.env.NODE_ENV !== 'production'\n\n/**\n * @internal Once-per-process flag for the fetch-style `Response` warning.\n * Exposed via `_resetReflectFootgunWarnings()` for tests.\n */\nlet _responseObjectWarned = false\n\n/** @internal Test-only — clear the once-flag for the fetch-Response warning. */\nexport function _resetReflectFootgunWarnings(): void {\n _responseObjectWarned = false\n}\n\n/**\n * Reflect a handler's return value to the response per the contract:\n *\n * | return type | wire output |\n * |------------------------|-----------------------------------|\n * | `undefined` / `null` | 204 (unless ctx wrote) |\n * | string starting w/ `<` | 200 text/html |\n * | other string | 200 text/plain |\n * | `Buffer` / `Uint8Array`| 200 application/octet-stream |\n * | `Readable` | 200 streamed |\n * | any object/array | 200 application/json |\n *\n * If a `ctx.json/text/html/stream/redirect/send` helper has already been\n * called, the return value is ignored.\n */\nexport function reflectReturn(ctx: IngeniumContext, value: unknown): void {\n if (ctx._written) return\n\n if (value === undefined || value === null) {\n ctx.status(204)\n return\n }\n\n // Dev-only — catch the common mistake of returning a fetch-style `Response`\n // object (e.g. `return new Response('hi')`). Ingenium handlers return plain\n // values; interop with the Fetch Response shape is intentionally not\n // supported. Warn once, then fall through to the 204 path so the framework\n // doesn't accidentally JSON-serialize the Response object's enumerable bag.\n if (IS_DEV && typeof Response !== 'undefined' && value instanceof Response) {\n if (!_responseObjectWarned) {\n _responseObjectWarned = true\n try {\n process.emitWarning(\n 'Handler returned a fetch-style Response object. Ingenium handlers return plain values or call ctx.json/text/etc. The Response was ignored.',\n { type: 'IngeniumResponseObjectWarning' },\n )\n } catch {\n // process.emitWarning can throw in unusual runtimes (workers); swallow.\n }\n }\n ctx.status(204)\n return\n }\n\n if (typeof value === 'string') {\n if (value.length > 0 && value.charCodeAt(0) === 60 /* '<' */) {\n ctx.html(value)\n } else {\n ctx.text(value)\n }\n return\n }\n\n if (Buffer.isBuffer(value)) {\n ctx.send(value)\n return\n }\n\n if (value instanceof Uint8Array) {\n ctx.send(Buffer.from(value))\n return\n }\n\n if (value instanceof Readable) {\n ctx.stream(value)\n return\n }\n\n // Default: JSON-serialize anything else (objects, arrays, numbers, booleans).\n ctx.json(value)\n}\n","import type { IngeniumContext } from '../context/context.ts'\nimport { reflectReturn } from '../response/reflect.ts'\nimport type { ComposedHandler, IngeniumMiddleware } from './types.ts'\n\nconst NOOP: ComposedHandler = async () => {}\n\n/**\n * Compose an array of middleware into a single async function. Composition\n * runs ONCE at registration / first-request time; the returned function has\n * no per-request `bind`, no index variable, and no `stack[n]` lookups.\n *\n * The dispatcher chain is pre-built bottom-up: `dispatchers[i]` runs\n * `stack[i]` with a `next` that invokes `dispatchers[i + 1]`. Each\n * middleware-level invocation still allocates one closure to capture `ctx`\n * (unavoidable without dropping concurrency safety).\n *\n * Double-`next()` calls are detected only when `process.env.REX_DEBUG` is\n * truthy, to keep the production hot path free of per-call guard variables.\n */\nexport function compose(stack: readonly IngeniumMiddleware[]): ComposedHandler {\n const len = stack.length\n if (len === 0) return NOOP\n\n const debug = !!process.env.REX_DEBUG\n\n // dispatchers[i] runs middleware[i] and threads control through middleware[i+1..]\n // dispatchers[len] is the terminal noop.\n const dispatchers: ComposedHandler[] = new Array(len + 1)\n dispatchers[len] = NOOP\n\n for (let i = len - 1; i >= 0; i--) {\n const fn = stack[i]!\n const nextDispatcher = dispatchers[i + 1]!\n if (debug) {\n dispatchers[i] = async (ctx) => {\n let called = false\n await fn(ctx, () => {\n if (called) {\n throw new Error(`next() called multiple times in middleware at index ${i}`)\n }\n called = true\n return nextDispatcher(ctx)\n })\n }\n } else {\n dispatchers[i] = async (ctx) => {\n await fn(ctx, () => nextDispatcher(ctx))\n }\n }\n }\n\n return dispatchers[0] ?? NOOP\n}\n\n/**\n * Compose middleware then append a terminal handler that does not receive a\n * `next` (so a route handler can be the leaf of the chain). The handler's\n * return value is reflected to the response per the contract in\n * `response/reflect.ts` — unless the handler called a `ctx.json/...` helper,\n * in which case the return value is ignored.\n *\n * Hot-path optimization: when there are no middleware, we skip the\n * dispatcher chain entirely and return a thin wrapper that calls the\n * handler directly. We also detect synchronous handler return values\n * (non-thenable) and avoid the `await` microtask in that case — measurable\n * on JSON-returning routes that don't touch the body.\n */\nexport function composeWithHandler(\n middleware: readonly IngeniumMiddleware[],\n handler: (ctx: IngeniumContext) => unknown | Promise<unknown>,\n): ComposedHandler {\n if (middleware.length === 0) {\n return makeFastTerminal(handler)\n }\n const terminal: IngeniumMiddleware = async (ctx) => {\n const result = await handler(ctx)\n reflectReturn(ctx, result)\n }\n return compose([...middleware, terminal])\n}\n\n/** No-middleware fast path: skip compose, skip await when handler is sync. */\nfunction makeFastTerminal(\n handler: (ctx: IngeniumContext) => unknown | Promise<unknown>,\n): ComposedHandler {\n return async (ctx) => {\n const r = handler(ctx)\n if (r !== null && typeof r === 'object' && typeof (r as Promise<unknown>).then === 'function') {\n reflectReturn(ctx, await r)\n } else {\n reflectReturn(ctx, r)\n }\n }\n}\n","import type { IngeniumContext } from '../context/context.ts'\nimport type { Decorator, EagerDecorator, LazyDecorator } from './types.ts'\n\ninterface LazyEntry {\n name: string\n factory: LazyDecorator\n}\n\ninterface EagerEntry {\n name: string\n factory: EagerDecorator\n}\n\n/**\n * Per-app registry of decorators. Decorators are NOT installed onto\n * `IngeniumContext.prototype` — that would mutate a shared class and leak across\n * apps in the same process. Instead, `applyTo(ctx)` writes them onto each\n * pooled context instance at request start.\n *\n * # Lazy vs eager — perf trade-off\n *\n * - **Lazy** (`decorate`): installed via `Object.defineProperty` with a\n * getter. The getter computes on first access, then redefines itself as\n * a plain data property holding the resolved value (define-self pattern).\n * Subsequent reads cost a normal property access — no getter call. Use\n * this for values that may not be needed (e.g. `ctx.user` on public\n * routes), and for values whose computation is non-trivial (DB lookups,\n * token decoding).\n *\n * - **Eager** (`decorateRequest`): factory is invoked at request start,\n * value assigned directly. Use this for cheap values that virtually every\n * handler will read (e.g. `ctx.startedAt = Date.now()`). Avoids the\n * per-property getter-redefinition overhead.\n *\n * # Pool reuse\n *\n * Pooled contexts are reset between requests; the `IngeniumContext.reset()`\n * method does not know about decorator names, so each request re-applies\n * via `applyTo(ctx)`. Lazy `defineProperty` overwrites the previous slot\n * configuration cleanly; eager assignment overwrites the previous value.\n * No leakage between requests.\n */\nexport class DecoratorRegistry {\n private readonly lazy: LazyEntry[] = []\n private readonly eager: EagerEntry[] = []\n\n /** Register a lazy decorator. Computed on first access; cached thereafter. */\n decorate<T>(name: string, factory: LazyDecorator<T>): void {\n this.lazy.push({ name, factory: factory as Decorator })\n }\n\n /** Register an eager decorator. Factory runs at the start of every request. */\n decorateRequest<T>(name: string, factory: EagerDecorator<T>): void {\n this.eager.push({ name, factory: factory as Decorator })\n }\n\n /** True when any decorator is registered (lets the hot path skip work). */\n hasAny(): boolean {\n return this.lazy.length > 0 || this.eager.length > 0\n }\n\n /**\n * Install all registered decorators onto a single context instance.\n * Called by `app.handle` after `onRequest` hooks and before dispatch.\n */\n applyTo(ctx: IngeniumContext): void {\n // Eager: simple assignment.\n for (let i = 0; i < this.eager.length; i++) {\n const entry = this.eager[i]!\n ;(ctx as unknown as Record<string, unknown>)[entry.name] = entry.factory(ctx)\n }\n // Lazy: define-self getter.\n for (let i = 0; i < this.lazy.length; i++) {\n const entry = this.lazy[i]!\n defineLazy(ctx, entry.name, entry.factory)\n }\n }\n}\n\n/**\n * Install a getter that computes once, then replaces itself with a plain\n * data property holding the resolved value. After first access, reads are\n * free of any getter overhead.\n */\nfunction defineLazy(ctx: IngeniumContext, name: string, factory: LazyDecorator): void {\n Object.defineProperty(ctx, name, {\n configurable: true,\n enumerable: true,\n get() {\n const value = factory(ctx)\n Object.defineProperty(ctx, name, {\n configurable: true,\n enumerable: true,\n writable: true,\n value,\n })\n return value\n },\n })\n}\n","import type { IngeniumContext } from '../context/context.ts'\nimport type {\n Hooks,\n OnComposeHook,\n OnErrorHook,\n OnRequestHook,\n OnResponseHook,\n OnRouteHook,\n RegistrationEvent,\n} from './types.ts'\n\n/**\n * Registry for the framework's lifecycle hooks. Implements the `Hooks`\n * interface that plugins call into via `app.hooks`.\n *\n * # Execution model\n *\n * `runOn*` methods invoke listeners **sequentially** in registration order,\n * awaiting each one before invoking the next. This is intentional:\n *\n * - Predictable ordering: a hook registered first ALWAYS observes state\n * before a hook registered later. Plugins can rely on this.\n * - Backpressure: an async hook (e.g. fetching a session) blocks\n * subsequent hooks, ensuring downstream hooks see decorated state.\n * - Errors short-circuit `runOnRequest`/`runOnResponse`/`runOnCompose` —\n * they propagate to the caller (the request enters the error boundary).\n *\n * `runOnError` is the exception: it wraps each listener in a try/catch and\n * swallows throws, because observers must not mask the original error.\n *\n * # Reading order\n *\n * Within a single `run*` call, listeners run in the order they were added.\n * Across hook types within one request, the order is fixed by `app.handle`:\n *\n * onRequest -> (decorators applied) -> dispatch -> onResponse\n * \\-> onError (on throw)\n *\n * # Hot-path note\n *\n * Each `runOn*` returns immediately if no listeners are registered. Callers\n * should additionally check `hasAny()` (or the per-hook `has*()` helpers) to\n * skip the `await` entirely on the zero-plugin path.\n */\nexport class HooksRegistry implements Hooks {\n private readonly _onRoute: OnRouteHook[] = []\n private readonly _onCompose: OnComposeHook[] = []\n private readonly _onRequest: OnRequestHook[] = []\n private readonly _onResponse: OnResponseHook[] = []\n private readonly _onError: OnErrorHook[] = []\n\n // ───── Registration (Hooks interface) ──────────────────────────────────\n\n onRoute(fn: OnRouteHook): void { this._onRoute.push(fn) }\n onCompose(fn: OnComposeHook): void { this._onCompose.push(fn) }\n onRequest(fn: OnRequestHook): void { this._onRequest.push(fn) }\n onResponse(fn: OnResponseHook): void { this._onResponse.push(fn) }\n onError(fn: OnErrorHook): void { this._onError.push(fn) }\n\n // ───── Hot-path checks ─────────────────────────────────────────────────\n\n /** True when any request-time hook is registered. */\n hasAny(): boolean {\n return (\n this._onRequest.length > 0 ||\n this._onResponse.length > 0 ||\n this._onError.length > 0\n )\n }\n\n hasOnRequest(): boolean { return this._onRequest.length > 0 }\n hasOnResponse(): boolean { return this._onResponse.length > 0 }\n hasOnError(): boolean { return this._onError.length > 0 }\n hasOnRoute(): boolean { return this._onRoute.length > 0 }\n hasOnCompose(): boolean { return this._onCompose.length > 0 }\n\n // ───── Run (sequential, registration order) ────────────────────────────\n\n /** Synchronous — `onRoute` is invoked during composition for each route. */\n runOnRoute(event: RegistrationEvent): void {\n for (let i = 0; i < this._onRoute.length; i++) {\n this._onRoute[i]!(event)\n }\n }\n\n async runOnCompose(): Promise<void> {\n for (let i = 0; i < this._onCompose.length; i++) {\n await this._onCompose[i]!()\n }\n }\n\n async runOnRequest(ctx: IngeniumContext): Promise<void> {\n for (let i = 0; i < this._onRequest.length; i++) {\n await this._onRequest[i]!(ctx)\n }\n }\n\n async runOnResponse(ctx: IngeniumContext): Promise<void> {\n for (let i = 0; i < this._onResponse.length; i++) {\n await this._onResponse[i]!(ctx)\n }\n }\n\n /** Observation only. Throws inside listeners are swallowed. */\n async runOnError(err: unknown, ctx: IngeniumContext): Promise<void> {\n for (let i = 0; i < this._onError.length; i++) {\n try {\n await this._onError[i]!(err, ctx)\n } catch {\n // Swallow — observers must not mask the original error.\n }\n }\n }\n}\n","import type { IngeniumHandler, IngeniumMiddleware } from '../middleware/types.ts'\nimport type { ExtractParams, HttpMethod } from './types.ts'\n\n/** A journal entry — replayed against the trie when the app composes. */\nexport type Registration =\n | { kind: 'use-global'; mw: IngeniumMiddleware }\n | { kind: 'use-prefix'; prefix: string; mw: IngeniumMiddleware }\n | { kind: 'use-router'; prefix: string; router: Router }\n | {\n kind: 'route'\n method: HttpMethod\n path: string\n handler: IngeniumHandler\n /**\n * Inline middleware passed positionally to `app.get(path, mw1, mw2, handler)`\n * (and the equivalent declarative-options form on `IngeniumApp`). Spliced into\n * the composed chain AFTER global + scoped middleware AND BEFORE the handler.\n * `undefined` for the back-compat single-arg form.\n */\n inlineMiddleware?: IngeniumMiddleware[]\n }\n\n/**\n * Variadic route-arg shape: zero or more middleware followed by exactly one\n * handler at the tail. The TypeScript trick `[...IngeniumMiddleware[], IngeniumHandler]`\n * forces the tail position to be the handler while everything before it is\n * middleware — preserves Express's `app.get(path, ...mw, handler)` ergonomics.\n */\nexport type RouteArgs<P = Record<string, string>> =\n | [IngeniumHandler<P>]\n | [...IngeniumMiddleware[], IngeniumHandler<P>]\n\n/**\n * A mountable router. Registrations are journaled, not eagerly composed —\n * mounting via `app.use('/api', router)` replays this journal into the\n * parent's trie with the prefix prepended.\n */\nexport class Router {\n /** @internal */ readonly journal: Registration[] = []\n\n /** Add middleware that runs for every request below this router. */\n use(mw: IngeniumMiddleware): this\n /** Mount middleware or a sub-router at a path prefix. */\n use(prefix: string, mw: IngeniumMiddleware | Router): this\n use(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware | Router): this {\n if (typeof arg1 === 'string') {\n const prefix = normalizePrefix(arg1)\n if (arg2 instanceof Router) {\n this.journal.push({ kind: 'use-router', prefix, router: arg2 })\n } else if (typeof arg2 === 'function') {\n this.journal.push({ kind: 'use-prefix', prefix, mw: arg2 })\n } else {\n throw new TypeError(`Router.use(prefix, value): value must be a middleware function or a Router`)\n }\n } else if (typeof arg1 === 'function') {\n this.journal.push({ kind: 'use-global', mw: arg1 })\n } else {\n throw new TypeError(`Router.use(): first argument must be a path string or middleware function`)\n }\n return this\n }\n\n // ───── Verb registration ──────────────────────────────────────────────\n // Each verb supports the back-compat `(path, handler)` shape AND the\n // variadic `(path, ...inlineMiddleware, handler)` shape Express uses. The\n // overloads keep TypeScript happy with the \"handler is always last\" rule.\n\n get<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n get<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n get<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('GET', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n post<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n post<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n post<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('POST', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n put<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n put<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n put<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('PUT', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n patch<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n patch<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n patch<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('PATCH', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n delete<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n delete<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n delete<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('DELETE', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n head<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n head<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n head<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('HEAD', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n options<P extends string>(path: P, handler: IngeniumHandler<ExtractParams<P>>): this\n options<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n options<P extends string>(path: P, ...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this {\n return this.method('OPTIONS', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n /**\n * Chainable per-path registration. Returns a builder that holds the path\n * and lets you stack verbs on it without retyping:\n *\n * @example\n * router\n * .route('/users/:id')\n * .get((ctx) => loadUser(ctx.params.id))\n * .put(requireAdmin, (ctx) => updateUser(ctx))\n * .delete(requireAdmin, (ctx) => deleteUser(ctx))\n *\n * Pure registration sugar — every call delegates to `router.method(...)`,\n * so all features (inline middleware, declarative options, typed params\n * via `ExtractParams<P>`) work identically.\n */\n route<P extends string>(path: P): RouteBuilder<P> {\n return new RouteBuilder<P>((method, args) =>\n (this.method as (m: HttpMethod, p: string, ...a: unknown[]) => unknown)(method, path, ...args),\n )\n }\n\n /**\n * Internal — register a route under any HTTP method. Accepts the variadic\n * `(...inlineMiddleware, handler)` tail; the LAST positional arg is always\n * the handler.\n */\n method(method: HttpMethod, path: string, handler: IngeniumHandler): this\n method(method: HttpMethod, path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n method(method: HttpMethod, path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this {\n if (args.length === 0) {\n throw new TypeError(`Router.${method.toLowerCase()}('${path}'): handler is required`)\n }\n const handler = args[args.length - 1] as IngeniumHandler\n if (typeof handler !== 'function') {\n throw new TypeError(\n `Router.${method.toLowerCase()}('${path}'): last argument must be a handler function`,\n )\n }\n const inline = args.slice(0, -1) as IngeniumMiddleware[]\n for (let i = 0; i < inline.length; i++) {\n if (typeof inline[i] !== 'function') {\n throw new TypeError(\n `Router.${method.toLowerCase()}('${path}'): inline middleware at position ${i} is not a function`,\n )\n }\n }\n const entry: Registration = {\n kind: 'route',\n method,\n path: normalizePath(path),\n handler,\n }\n if (inline.length > 0) entry.inlineMiddleware = inline\n this.journal.push(entry)\n return this\n }\n}\n\n/**\n * Per-path chainable builder returned by `app.route(path)` and\n * `router.route(path)`. Holds the path and an \"emit\" callback that registers\n * a route on the underlying host (an `IngeniumApp` or a `Router`); the\n * builder itself is just sugar — no per-request cost, no separate dispatch\n * path. The host's verb method does all the validation, dirty-bit flipping,\n * and journal writes.\n *\n * The generic `P` flows `ExtractParams<P>` into every handler signature so\n * `app.route('/users/:id').get(ctx => ctx.params.id)` narrows `ctx.params`\n * exactly like the bare verb form does.\n */\nexport class RouteBuilder<P extends string> {\n constructor(private readonly emit: (method: HttpMethod, args: unknown[]) => void) {}\n\n get(handler: IngeniumHandler<ExtractParams<P>>): this\n get(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n get(...args: unknown[]): this { this.emit('GET', args); return this }\n\n post(handler: IngeniumHandler<ExtractParams<P>>): this\n post(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n post(...args: unknown[]): this { this.emit('POST', args); return this }\n\n put(handler: IngeniumHandler<ExtractParams<P>>): this\n put(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n put(...args: unknown[]): this { this.emit('PUT', args); return this }\n\n patch(handler: IngeniumHandler<ExtractParams<P>>): this\n patch(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n patch(...args: unknown[]): this { this.emit('PATCH', args); return this }\n\n delete(handler: IngeniumHandler<ExtractParams<P>>): this\n delete(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n delete(...args: unknown[]): this { this.emit('DELETE', args); return this }\n\n head(handler: IngeniumHandler<ExtractParams<P>>): this\n head(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n head(...args: unknown[]): this { this.emit('HEAD', args); return this }\n\n options(handler: IngeniumHandler<ExtractParams<P>>): this\n options(...args: [...IngeniumMiddleware[], IngeniumHandler<ExtractParams<P>>]): this\n options(...args: unknown[]): this { this.emit('OPTIONS', args); return this }\n\n /** Register the same handler for all common HTTP methods (GET, POST, PUT, PATCH, DELETE). */\n all(handler: IngeniumHandler<ExtractParams<P>>): this {\n for (const m of ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as const) this.emit(m, [handler])\n return this\n }\n}\n\n/** Strip trailing slash; ensure leading slash. Empty string is allowed (means \"no prefix\"). */\nfunction normalizePrefix(p: string): string {\n if (p === '' || p === '/') return ''\n let out = p\n if (out[0] !== '/') out = '/' + out\n if (out.length > 1 && out[out.length - 1] === '/') out = out.slice(0, -1)\n return out\n}\n\nfunction normalizePath(p: string): string {\n if (!p) return '/'\n if (p[0] !== '/') return '/' + p\n return p\n}\n\n/**\n * Flatten a router's journal into resolved registrations against the parent,\n * applying the given prefix and inheriting any router-scoped middleware.\n *\n * Returns:\n * - global middleware to apply to ALL routes inside the prefix\n * - prefix-scoped middleware (with its own sub-prefix relative to root)\n * - routes with their final composed paths\n *\n * Used by the App at compose time.\n */\nexport interface FlatRegistrations {\n globalMiddleware: IngeniumMiddleware[] // unscoped (matches every request)\n scopedMiddleware: { prefix: string; mw: IngeniumMiddleware }[]\n routes: {\n method: HttpMethod\n path: string\n handler: IngeniumHandler\n /** Inline middleware survives the flatten so app.compose() can splice it in. */\n inlineMiddleware?: IngeniumMiddleware[]\n }[]\n}\n\nexport function flattenRouter(router: Router, prefix: string = ''): FlatRegistrations {\n const out: FlatRegistrations = { globalMiddleware: [], scopedMiddleware: [], routes: [] }\n flattenInto(router, prefix, out)\n return out\n}\n\nfunction flattenInto(router: Router, prefix: string, out: FlatRegistrations): void {\n for (const entry of router.journal) {\n switch (entry.kind) {\n case 'use-global':\n // A \"global\" registration inside a mounted router is actually scoped to the mount prefix.\n if (prefix === '') out.globalMiddleware.push(entry.mw)\n else out.scopedMiddleware.push({ prefix, mw: entry.mw })\n break\n case 'use-prefix':\n out.scopedMiddleware.push({ prefix: prefix + entry.prefix, mw: entry.mw })\n break\n case 'use-router':\n flattenInto(entry.router, prefix + entry.prefix, out)\n break\n case 'route': {\n const route: FlatRegistrations['routes'][number] = {\n method: entry.method,\n path: prefix + entry.path,\n handler: entry.handler,\n }\n if (entry.inlineMiddleware && entry.inlineMiddleware.length > 0) {\n route.inlineMiddleware = entry.inlineMiddleware\n }\n out.routes.push(route)\n break\n }\n }\n }\n}\n","/**\n * Sinatra-style `before` / `after` filters.\n *\n * `before(pattern?, handler)` runs BEFORE the route handler. Equivalent to\n * app.use(prefix, mw) // when pattern is given\n * app.use(mw) // when pattern is omitted\n * The user writes only the body of the filter — the wrapper invokes\n * `await next()` automatically. If the filter calls a response writer\n * (`ctx.json`, `ctx.text`, ...) the chain short-circuits because `next()`\n * is never called, so the route handler does not run.\n *\n * `after(pattern?, handler)` runs AFTER the route handler resolves but\n * BEFORE the adapter writes to the wire. The wrapper calls `await next()`\n * first and then runs the user filter, so the filter can observe the final\n * response state on `ctx`.\n *\n * Pattern semantics in v0.0.1:\n * - Simple boundary-respecting prefix match (reuses the same\n * `pathStartsWith` rule the app uses for scoped middleware).\n * - `'/admin/*'` and `'/admin'` both match `/admin` and `/admin/users`\n * but neither matches `/administrator`. The trailing `/*` is sugar\n * and is stripped before matching.\n * - Regex patterns and trailing-slash flexibility are out of scope.\n */\n\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumApp } from '../app.ts'\n\n/**\n * Strip the Sinatra-style trailing `/*` (or bare `*`) from a prefix so that\n * `/admin/*` and `/admin` both reduce to `/admin` for prefix matching.\n * A bare `*` (or `/*`) means \"every path\" → empty prefix.\n */\nfunction normalizeFilterPattern(pattern: string): string {\n if (pattern === '*' || pattern === '/*' || pattern === '/') return ''\n if (pattern.endsWith('/*')) return pattern.slice(0, -2)\n if (pattern.endsWith('*')) return pattern.slice(0, -1)\n return pattern\n}\n\n/**\n * Wrap a user `before` filter so it auto-calls `next()` after its body runs.\n * If the filter throws, the error propagates to the framework error boundary.\n * If the filter writes a response (and never calls `next()`), it\n * short-circuits — but since the wrapper IS the one that calls `next()`, we\n * detect short-circuit by checking `ctx._written` after the user filter\n * resolves and skip the downstream chain in that case.\n */\nfunction wrapBefore(handler: IngeniumMiddleware): IngeniumMiddleware {\n return async (ctx, next) => {\n // The handler may receive a no-op `next` of its own — but for ergonomic\n // Sinatra parity we want it to look handler-shaped (just `(ctx) => ...`).\n // We pass a `noopNext` and inspect ctx._written afterward to decide\n // whether to invoke the real downstream chain.\n const noopNext = async (): Promise<void> => {}\n await handler(ctx, noopNext)\n // Short-circuit if the filter wrote a response — don't run the route.\n if ((ctx as unknown as { _written?: boolean })._written) return\n await next()\n }\n}\n\n/**\n * Wrap a user `after` filter so it runs only AFTER the downstream chain\n * resolves. The filter sees the final response state on `ctx` (status code,\n * headers, body buffer). Errors thrown by the filter propagate to the\n * framework error boundary just like errors from any other middleware.\n */\nfunction wrapAfter(handler: IngeniumMiddleware): IngeniumMiddleware {\n return async (ctx, next) => {\n await next()\n const noopNext = async (): Promise<void> => {}\n await handler(ctx, noopNext)\n }\n}\n\n/**\n * Register a `before` filter on `app`. If `pattern` is omitted, the filter\n * is registered as a global middleware (runs for every request). Otherwise\n * the pattern is normalized and registered as a path-scoped middleware.\n */\nexport function registerBefore(\n app: IngeniumApp,\n patternOrHandler: string | IngeniumMiddleware,\n maybeHandler?: IngeniumMiddleware,\n): IngeniumApp {\n if (typeof patternOrHandler === 'function') {\n app.use(wrapBefore(patternOrHandler))\n return app\n }\n if (typeof maybeHandler !== 'function') {\n throw new TypeError('before(pattern, handler): handler must be a function')\n }\n const prefix = normalizeFilterPattern(patternOrHandler)\n if (prefix === '') {\n app.use(wrapBefore(maybeHandler))\n } else {\n app.use(prefix, wrapBefore(maybeHandler))\n }\n return app\n}\n\n/**\n * Register an `after` filter on `app`. Same pattern semantics as\n * `registerBefore`, but the user body runs after the downstream chain.\n */\nexport function registerAfter(\n app: IngeniumApp,\n patternOrHandler: string | IngeniumMiddleware,\n maybeHandler?: IngeniumMiddleware,\n): IngeniumApp {\n if (typeof patternOrHandler === 'function') {\n app.use(wrapAfter(patternOrHandler))\n return app\n }\n if (typeof maybeHandler !== 'function') {\n throw new TypeError('after(pattern, handler): handler must be a function')\n }\n const prefix = normalizeFilterPattern(patternOrHandler)\n if (prefix === '') {\n app.use(wrapAfter(maybeHandler))\n } else {\n app.use(prefix, wrapAfter(maybeHandler))\n }\n return app\n}\n\n/** @internal Exposed for tests. */\nexport const _internal_normalizeFilterPattern = normalizeFilterPattern\n","/**\n * `ScopedApp` — registration facade returned to the callback of\n * `app.scope(prefix, registrar)`. Translates every registration call into a\n * prefix-qualified registration on the underlying `IngeniumApp`, leveraging\n * the existing Router scoping primitives (`use-prefix`, prefix-prepended\n * paths) so the COMPOSE-TIME machinery does all the heavy lifting and the\n * per-request hot path stays untouched.\n *\n * # Design\n *\n * - Holds a reference to the root `IngeniumApp` plus the ABSOLUTE prefix\n * (already includes any outer scope prefix). Nested scopes just construct\n * a new `ScopedApp` with `parent.prefix + sub`.\n * - `scope.use(mw)` becomes `app.use(absolutePrefix, mw)` — the existing\n * `Router.use(prefix, mw)` plumbing produces a `use-prefix` registration,\n * and `flattenRouter` emits a `scopedMiddleware` entry that `app.compose()`\n * intersects against route paths via `pathStartsWith`.\n * - `scope.get(path, handler)` becomes `app.method('GET', absolutePrefix + path, handler)`.\n * - `scope.register(plugin, opts)` invokes the plugin with `this` as the\n * target. Any `target.use(...)` inside the plugin body is therefore\n * scope-prefixed; the plugin can't accidentally leak global middleware.\n * - `scope.scope(sub, fn)` constructs a child `ScopedApp` and runs `fn`\n * against it.\n *\n * # Out of scope for V1 (documented footguns)\n *\n * - **Decorators**: `scope.decorate(...)` / `scope.decorateRequest(...)`\n * forward to the root app and decorate EVERY request, not just requests\n * under the scope's prefix. The reason is structural: decorators install\n * onto pooled `IngeniumContext` instances at request start, BEFORE the\n * route is matched — there's no path information available at that point\n * without re-shaping the dispatch path. Per-scope decorators would require\n * either (a) a runtime path check on every property access, or (b) a\n * separate decorator registry per scope keyed by matched route — both of\n * which move work onto the hot path and complicate the pool. For V1 we\n * accept the footgun and emit a one-shot `process.emitWarning` in\n * non-production environments to surface it.\n * - **Hooks**: `scope.hooks` returns the SAME registry the root app uses.\n * Hook registration is global. A plugin that wants scope-aware hook\n * behavior should inspect `ctx.path` inside the hook body.\n */\n\nimport type { IngeniumApp } from '../app.ts'\nimport type { IngeniumHandler, IngeniumMiddleware } from '../middleware/types.ts'\nimport { RouteBuilder, type Router } from '../router/router.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport type {\n EagerDecorator,\n Hooks,\n IngeniumPlugin,\n LazyDecorator,\n PluginTarget,\n} from '../plugin/types.ts'\nimport { registerAfter, registerBefore } from '../sinatra/filters.ts'\n\n/**\n * @internal Friend-access surface a `ScopedApp` needs from its parent\n * `IngeniumApp`. Kept narrow so refactors don't accidentally widen the\n * coupling. The methods are implemented on `IngeniumApp` itself.\n */\nexport interface ScopeHost {\n use(mw: IngeniumMiddleware): IngeniumApp\n use(prefix: string, mw: IngeniumMiddleware | Router): IngeniumApp\n method(method: HttpMethod, path: string, handler: IngeniumHandler): IngeniumApp\n method(\n method: HttpMethod,\n path: string,\n ...args: [...IngeniumMiddleware[], IngeniumHandler]\n ): IngeniumApp\n decorate<T>(name: string, factory: LazyDecorator<T>): IngeniumApp\n decorateRequest<T>(name: string, factory: EagerDecorator<T>): IngeniumApp\n readonly hooks: Hooks\n /** @internal Marks the app's compose-cache dirty. */\n _markDirty(): void\n}\n\n/**\n * Normalize an absolute-or-relative prefix piece so concatenation is clean.\n * Drops the trailing slash, ensures a leading slash. Empty string and `'/'`\n * collapse to `''` (no prefix).\n */\nfunction normalizePrefix(p: string): string {\n if (p === '' || p === '/') return ''\n let out = p\n if (out[0] !== '/') out = '/' + out\n if (out.length > 1 && out[out.length - 1] === '/') out = out.slice(0, -1)\n return out\n}\n\n/**\n * Normalize a route path so `'users'` and `'/users'` both end up `/users` and\n * `''` resolves to `'/'`. Mirrors `Router.normalizePath`.\n */\nfunction normalizePath(p: string): string {\n if (!p) return '/'\n if (p[0] !== '/') return '/' + p\n return p\n}\n\n/**\n * Join the scope's absolute prefix with a relative path. The result is what\n * goes onto the underlying `Router` (so it's the absolute path inside the\n * trie at compose time).\n */\nfunction joinScopePath(prefix: string, path: string): string {\n const np = normalizePath(path)\n if (prefix === '') return np\n if (np === '/') return prefix\n return prefix + np\n}\n\n/**\n * Process-wide flag — true once we've emitted the \"decorators are global\"\n * warning. Gated on `NODE_ENV !== 'production'` so production deploys aren't\n * spammed. We accept the once-per-process granularity (rather than once per\n * scope) because the message is the same regardless of which scope tripped it.\n */\nlet _decoratorWarningEmitted = false\n\nfunction maybeEmitDecoratorWarning(name: string): void {\n if (_decoratorWarningEmitted) return\n if (typeof process === 'undefined') return\n if (process.env?.NODE_ENV === 'production') return\n _decoratorWarningEmitted = true\n try {\n process.emitWarning(\n `ingenium: scope.decorate('${name}', ...) is GLOBAL — decorators apply to every request regardless of scope prefix. ` +\n `Make the decorator's resolver path-aware (read ctx.path) if you want scoped behavior. ` +\n `This warning fires once per process.`,\n { type: 'IngeniumScopedDecoratorWarning' },\n )\n } catch {\n // process.emitWarning may throw in unusual runtimes (workers); swallow.\n }\n}\n\n/** @internal Test-only — reset the one-shot decorator warning latch. */\nexport function _resetDecoratorWarningLatch(): void {\n _decoratorWarningEmitted = false\n}\n\n/**\n * A `ScopedApp` is the registration target passed to the `app.scope(prefix, registrar)`\n * callback. It exposes the registration surface a plugin needs (`use`, verbs,\n * `register`, `decorate`, `before`/`after`, nested `scope`) but NOT the\n * dispatch surface (`compose`, `handle`, `listen`) — those still belong to\n * the root app.\n *\n * Instances are cheap: a couple of fields and method-call forwarding. Do not\n * cache them across recompose boundaries — they hold a reference to the\n * `IngeniumApp` and rely on its mutable router journal.\n */\nexport class ScopedApp implements PluginTarget {\n /** @internal The root app this scope translates registrations onto. */\n private readonly _app: ScopeHost\n /** @internal Absolute prefix (already includes any outer scope's prefix). */\n private readonly _prefix: string\n\n /** @internal Construct via `app.scope(...)`; not meant to be `new`'d directly. */\n constructor(app: ScopeHost, prefix: string) {\n this._app = app\n this._prefix = normalizePrefix(prefix)\n }\n\n /** Absolute prefix this scope rewrites against (for debugging / introspection). */\n get prefix(): string {\n return this._prefix\n }\n\n /** Lifecycle hooks. SHARED with the root app — hooks are global by design. */\n get hooks(): Hooks {\n return this._app.hooks\n }\n\n // ───── Middleware ──────────────────────────────────────────────────────\n\n use(mw: IngeniumMiddleware): this\n use(subPrefix: string, mw: IngeniumMiddleware | Router): this\n use(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware | Router): this {\n if (typeof arg1 === 'string') {\n // Subprefix is relative to this scope's prefix.\n const joined = this._prefix + normalizePrefix(arg1)\n // If both prefix and subPrefix were empty, fall through to global.\n if (joined === '') {\n this._app.use(arg2 as IngeniumMiddleware)\n } else {\n this._app.use(joined, arg2 as IngeniumMiddleware | Router)\n }\n } else {\n // No prefix arg — scope.use(mw) means \"scoped to this scope's prefix\".\n if (this._prefix === '') {\n this._app.use(arg1)\n } else {\n this._app.use(this._prefix, arg1)\n }\n }\n this._app._markDirty()\n return this\n }\n\n // ───── Verbs ───────────────────────────────────────────────────────────\n\n get(path: string, handler: IngeniumHandler): this\n get(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n get(path: string, ...args: unknown[]): this {\n return this.method('GET', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n post(path: string, handler: IngeniumHandler): this\n post(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n post(path: string, ...args: unknown[]): this {\n return this.method('POST', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n put(path: string, handler: IngeniumHandler): this\n put(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n put(path: string, ...args: unknown[]): this {\n return this.method('PUT', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n patch(path: string, handler: IngeniumHandler): this\n patch(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n patch(path: string, ...args: unknown[]): this {\n return this.method('PATCH', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n delete(path: string, handler: IngeniumHandler): this\n delete(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n delete(path: string, ...args: unknown[]): this {\n return this.method('DELETE', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n head(path: string, handler: IngeniumHandler): this\n head(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n head(path: string, ...args: unknown[]): this {\n return this.method('HEAD', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n options(path: string, handler: IngeniumHandler): this\n options(path: string, ...args: [...IngeniumMiddleware[], IngeniumHandler]): this\n options(path: string, ...args: unknown[]): this {\n return this.method('OPTIONS', path, ...(args as [...IngeniumMiddleware[], IngeniumHandler]))\n }\n\n method(method: HttpMethod, path: string, handler: IngeniumHandler): this\n method(\n method: HttpMethod,\n path: string,\n ...args: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n method(method: HttpMethod, path: string, ...args: unknown[]): this {\n const absolute = joinScopePath(this._prefix, path)\n // Delegate to the underlying app — which already validates handler-is-\n // function and middleware-is-function (via Router), and sets dirty.\n ;(this._app.method as (m: HttpMethod, p: string, ...a: unknown[]) => IngeniumApp)(\n method,\n absolute,\n ...args,\n )\n return this\n }\n\n /**\n * Chainable per-path builder. The builder closes over `this.method`, which\n * already does the scope-prefix join — so the same builder works identically\n * on the root app and inside a scope. Typed params via `ExtractParams<P>`\n * narrow against the RELATIVE path the user wrote, matching what the bare\n * verb form does.\n */\n route<P extends string>(path: P): RouteBuilder<P> {\n return new RouteBuilder<P>((method, args) =>\n (this.method as (m: HttpMethod, p: string, ...a: unknown[]) => unknown)(method, path, ...args),\n )\n }\n\n // ───── Decorators (GLOBAL — see file header) ───────────────────────────\n\n /**\n * Register a lazy decorator. **WARNING:** decorators are GLOBAL even when\n * registered inside a scope — they apply to every request regardless of\n * the scope's prefix. The first call from inside any scope in a process\n * emits a `process.emitWarning` (non-production only). See file header.\n */\n decorate<T>(name: string, factory: LazyDecorator<T>): this {\n maybeEmitDecoratorWarning(name)\n this._app.decorate(name, factory)\n // Decorators don't affect routing, but they DO affect the per-request\n // dispatch flags (`_hasDecorators`), which are cached at compose time.\n // Mark dirty so a recompose picks up the new decorator if registration\n // happens after the first request.\n this._app._markDirty()\n return this\n }\n\n /**\n * Register an eager decorator. **WARNING:** see {@link ScopedApp.decorate}.\n */\n decorateRequest<T>(name: string, factory: EagerDecorator<T>): this {\n maybeEmitDecoratorWarning(name)\n this._app.decorateRequest(name, factory)\n this._app._markDirty()\n return this\n }\n\n // ───── Plugin registration ─────────────────────────────────────────────\n\n /**\n * Register a plugin against THIS scope. The plugin receives the `ScopedApp`\n * as its `target`, so any `target.use(...)` inside the plugin body is\n * automatically prefix-scoped.\n */\n register<O>(plugin: IngeniumPlugin<O>, opts: O): Promise<this>\n register(plugin: IngeniumPlugin<void>): Promise<this>\n async register<O>(plugin: IngeniumPlugin<O>, opts?: O): Promise<this> {\n await plugin(this, opts as O)\n this._app._markDirty()\n return this\n }\n\n // ───── Nested scope ────────────────────────────────────────────────────\n\n /**\n * Open a nested scope. `subPrefix` is relative to this scope's prefix.\n * The registrar may be async; the call returns a Promise that resolves\n * once the registrar finishes if it returned one, otherwise resolves\n * synchronously to `this`. We type-erase to `this` to match the\n * `PluginTarget` interface, which can't express the sync-or-async return\n * without polluting every caller.\n */\n scope(\n subPrefix: string,\n registrar: (scope: PluginTarget) => void,\n ): this {\n const child = new ScopedApp(this._app, this._prefix + normalizePrefix(subPrefix))\n const ret: unknown = registrar(child)\n if (ret && typeof (ret as Promise<void>).then === 'function') {\n // Best-effort: surface async failures via the returned promise. We can't\n // wait synchronously, so we annotate the chain to mark dirty after the\n // registrar settles. Tests should `await app.scope(..., async (s) => {})`\n // by chaining via the parent app or by awaiting the registrar themselves.\n ;(ret as Promise<void>).then(() => this._app._markDirty())\n } else {\n this._app._markDirty()\n }\n return this\n }\n\n // ───── Sinatra filters ─────────────────────────────────────────────────\n\n /**\n * Register a `before` filter scoped to this scope's prefix. If a pattern\n * is given it's appended to the scope's prefix (so `scope('/api').before('/users', h)`\n * matches `/api/users` and below). If omitted, the filter applies to the\n * scope's full subtree.\n */\n before(handler: IngeniumMiddleware): this\n before(pattern: string, handler: IngeniumMiddleware): this\n before(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware): this {\n // We delegate to the existing Sinatra filter implementation, but with the\n // scope's prefix folded in. `registerBefore` takes `(app, pattern, fn)`\n // and uses `app.use(prefix, wrapped)` under the hood — so passing the\n // root app + a prefixed pattern yields exactly the desired scoping.\n const root = this._app as unknown as IngeniumApp\n if (typeof arg1 === 'function') {\n if (this._prefix === '') registerBefore(root, arg1)\n else registerBefore(root, this._prefix, arg1)\n } else {\n const joined = this._prefix + normalizePrefix(arg1)\n if (joined === '') registerBefore(root, arg2 as IngeniumMiddleware)\n else registerBefore(root, joined, arg2 as IngeniumMiddleware)\n }\n this._app._markDirty()\n return this\n }\n\n /** Register an `after` filter scoped to this scope's prefix. See {@link ScopedApp.before}. */\n after(handler: IngeniumMiddleware): this\n after(pattern: string, handler: IngeniumMiddleware): this\n after(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware): this {\n const root = this._app as unknown as IngeniumApp\n if (typeof arg1 === 'function') {\n if (this._prefix === '') registerAfter(root, arg1)\n else registerAfter(root, this._prefix, arg1)\n } else {\n const joined = this._prefix + normalizePrefix(arg1)\n if (joined === '') registerAfter(root, arg2 as IngeniumMiddleware)\n else registerAfter(root, joined, arg2 as IngeniumMiddleware)\n }\n this._app._markDirty()\n return this\n }\n}\n","import type { ComposedHandler } from '../middleware/types.ts'\nimport type { HttpMethod } from './types.ts'\n\n/**\n * One node in the radix trie. Static segments win over `:param`, which wins\n * over `*wild`. Method-specific composed handlers live at the leaf.\n */\nexport class TrieNode {\n staticChildren: Map<string, TrieNode> = new Map()\n paramChild: TrieNode | null = null\n paramName: string | null = null\n wildcardChild: TrieNode | null = null\n wildcardName: string | null = null\n\n /**\n * Compiled inline constraint for this node *as a param child*, or `null`\n * when the param is unconstrained. Set at insert time when the registered\n * segment carries a `(regex)` group (e.g. `:id(\\d+)`). The `find()` hot\n * path loads this field and only runs `.test()` when it is non-null, so\n * unconstrained routes pay zero extra cost. Lives on the param node itself\n * (the child) so the matcher can test it the instant it descends.\n */\n paramConstraint: RegExp | null = null\n\n /** Per-method composed handlers, populated by `RouteRegistry` after compose. */\n handlers: Partial<Record<HttpMethod, ComposedHandler>> = {}\n\n /**\n * Param names accumulated from root → this node, in order. Cached so\n * matching can fill the params object in O(k) without re-walking parents.\n */\n paramNames: readonly string[] = []\n}\n\n/** Result of a trie lookup. `params` may be empty if the route had none. */\nexport interface MatchResult {\n handler: ComposedHandler\n params: Record<string, string>\n /** Methods registered at this leaf — used to populate `Allow` on 405. */\n allowed: readonly HttpMethod[]\n}\n\n/** Why a lookup failed. */\nexport type MatchMiss =\n | { kind: 'not-found' }\n | { kind: 'method-not-allowed'; allowed: readonly HttpMethod[] }\n\n/**\n * Radix trie router. `insert()` is called at registration; `find()` runs on\n * every request and is the single hottest piece of code in the framework.\n */\nexport class RouterTrie {\n readonly root = new TrieNode()\n\n /**\n * Walks/creates trie nodes for the path. Returns the leaf where handlers\n * should be attached. Path must start with `/`.\n */\n insert(path: string): TrieNode {\n if (path.length === 0 || path[0] !== '/') {\n throw new Error(`Route path must start with '/': ${path}`)\n }\n const segments = splitPath(path)\n let node = this.root\n const paramNames: string[] = []\n\n for (const seg of segments) {\n if (seg.length === 0) continue\n\n if (seg[0] === ':') {\n const { name, constraint } = parseParamSegment(seg)\n if (!node.paramChild) {\n node.paramChild = new TrieNode()\n node.paramName = name\n node.paramChild.paramConstraint = constraint\n } else {\n if (node.paramName !== name) {\n throw new Error(\n `Conflicting param names at the same trie level: ':${node.paramName}' vs ':${name}'`,\n )\n }\n // Same name, but the constraint may differ. Rule: a constraint is a\n // promise about the shape of matched segments; two registrations of\n // the same param must agree on that promise. We require the *source*\n // of the compiled regex to match (or both to be unconstrained).\n // Last-writer-wins would silently let one route's `:id(\\d+)` weaken\n // another's, which is a footgun, so we throw instead — same style as\n // the param-name conflict above.\n const existing = node.paramChild.paramConstraint\n const incoming = constraint\n const existingSrc = existing ? existing.source : ''\n const incomingSrc = incoming ? incoming.source : ''\n if (existingSrc !== incomingSrc) {\n const fmt = (n: string, c: RegExp | null) => (c ? `:${n}(...)` : `:${n}`)\n throw new Error(\n `Conflicting param constraints at the same trie level: ` +\n `'${fmt(name, existing)}' vs '${fmt(name, incoming)}' for param ':${name}'`,\n )\n }\n }\n paramNames.push(name)\n node = node.paramChild\n } else if (seg[0] === '*') {\n const name = seg.slice(1) || 'wildcard'\n if (!node.wildcardChild) {\n node.wildcardChild = new TrieNode()\n node.wildcardName = name\n }\n paramNames.push(name)\n node = node.wildcardChild\n // Wildcards consume the rest of the path; later segments are ignored\n // by the matcher anyway, but we don't allow more registration past *.\n break\n } else {\n let child = node.staticChildren.get(seg)\n if (!child) {\n child = new TrieNode()\n node.staticChildren.set(seg, child)\n }\n node = child\n }\n }\n\n node.paramNames = paramNames\n return node\n }\n\n /**\n * Look up a route. Iterative with single-level wildcard backtrack — if the\n * static/param walk dead-ends and an ancestor had a `*wildcard` child, we\n * retry from the wildcard with the remaining segments. Backtrack frames\n * are tracked in a small stack (one per wildcard ancestor encountered).\n */\n find(method: HttpMethod, path: string): MatchResult | MatchMiss {\n const segments = splitPath(path)\n\n // Stack of wildcard fallback points. `paramCount` is paramValues.length\n // captured at the moment the fallback was recorded — used to truncate\n // any params collected past that point if we have to backtrack.\n type Fallback = { node: TrieNode; segIdx: number; paramCount: number }\n const fallbacks: Fallback[] = []\n\n let node: TrieNode = this.root\n const paramValues: string[] = []\n let consumedWildcard = false\n\n let i = 0\n walk: while (i < segments.length) {\n const seg = segments[i]!\n if (seg.length === 0) {\n i++\n continue\n }\n\n // Record a wildcard fallback at this level *before* descending, so a\n // later miss can rewind and consume from `i` greedily via the wildcard.\n if (node.wildcardChild) {\n fallbacks.push({ node: node.wildcardChild, segIdx: i, paramCount: paramValues.length })\n }\n\n const staticChild = node.staticChildren.get(seg)\n if (staticChild) {\n node = staticChild\n i++\n continue\n }\n\n if (node.paramChild) {\n // Hot-path gate: only constrained params (a tiny minority of routes)\n // run a regex. The field load + `!== null` is one branch; unconstrained\n // routes never touch `.test()`, so they pay zero extra cost. Constrained\n // routes pay one anchored `.test()` against the raw segment — justified\n // because the alternative (matching, then 404ing in user code) is both\n // slower and wrong (a sibling `*wild` could legitimately catch it).\n const constraint = node.paramChild.paramConstraint\n if (constraint === null || constraint.test(seg)) {\n paramValues.push(decodeParam(seg))\n node = node.paramChild\n i++\n continue\n }\n // Constraint miss: this param branch is dead. Fall through to the\n // wildcard child / backtrack stack exactly as a structural dead-end\n // would, so a sibling `*wild` can still catch the segment, else 404.\n }\n\n if (node.wildcardChild) {\n const remaining = segments.slice(i).join('/')\n paramValues.push(decodeParam(remaining))\n node = node.wildcardChild\n consumedWildcard = true\n break walk\n }\n\n // Dead end — try the most recent wildcard fallback.\n const fb = fallbacks.pop()\n if (!fb) return { kind: 'not-found' }\n const remaining = segments.slice(fb.segIdx).join('/')\n paramValues.length = fb.paramCount\n paramValues.push(decodeParam(remaining))\n node = fb.node\n consumedWildcard = true\n break walk\n }\n\n if (!consumedWildcard && !node.handlers[method] && fallbacks.length > 0) {\n // Walked to the end via static/param but no handler at this leaf —\n // try the most recent wildcard fallback.\n const fb = fallbacks.pop()!\n const remaining = segments.slice(fb.segIdx).join('/')\n paramValues.length = fb.paramCount\n paramValues.push(decodeParam(remaining))\n node = fb.node\n }\n\n const handler = node.handlers[method]\n if (!handler) {\n const allowed = Object.keys(node.handlers) as HttpMethod[]\n if (allowed.length === 0) return { kind: 'not-found' }\n return { kind: 'method-not-allowed', allowed }\n }\n\n // Build params object — one allocation per match. Stable key insertion\n // order (driven by paramNames recorded at insert time) → V8 monomorphic\n // hidden class per route.\n let params: Record<string, string>\n if (node.paramNames.length === 0) {\n params = EMPTY_PARAMS\n } else {\n params = {}\n for (let j = 0; j < node.paramNames.length; j++) {\n params[node.paramNames[j]!] = paramValues[j]!\n }\n }\n\n return {\n handler,\n params,\n allowed: Object.keys(node.handlers) as HttpMethod[],\n }\n }\n}\n\n/** Shared frozen empty-params sentinel — exported so the dispatcher can identity-compare. */\nexport const EMPTY_PARAMS: Record<string, string> = Object.freeze({}) as Record<string, string>\n\n/**\n * Split `/users/42/posts` into `['users', '42', 'posts']`. Reused by both\n * insert and lookup, so the implementation is hot — manual scan beats\n * `String.prototype.split` only marginally; we use split for clarity.\n */\nfunction splitPath(path: string): string[] {\n // Strip leading and trailing slash for a stable segment count.\n let start = 0\n let end = path.length\n if (start < end && path[start] === '/') start++\n if (end > start && path[end - 1] === '/') end--\n if (start >= end) return []\n return path.slice(start, end).split('/')\n}\n\n/**\n * Parse a `:param` segment into its clean name and an optional compiled\n * constraint. Runs at *insert* time only (never on the request hot path), so\n * the regex compile cost is paid once per route.\n *\n * Grammar handled:\n * `:name` → { name: 'name', constraint: null }\n * `:name?` → { name: 'name', constraint: null }\n * `:name(regex)` → { name: 'name', constraint: /^(?:regex)$/ }\n * `:name(regex)?` → { name: 'name', constraint: /^(?:regex)$/ }\n *\n * The constraint is anchored with `^(?:...)$` so it must match the *entire*\n * segment — a partial match (e.g. `\\d+` against `12a`) does NOT slip through.\n * The `(?:...)` wrapper keeps the user's alternations (`a|b`) from binding\n * past the anchors.\n */\nfunction parseParamSegment(seg: string): { name: string; constraint: RegExp | null } {\n // Strip the leading ':'.\n let body = seg.slice(1)\n\n // Strip a trailing optional marker first; it sits *after* the constraint\n // group in the documented grammar (`:id(\\d+)?`).\n if (body.length > 0 && body[body.length - 1] === '?') {\n body = body.slice(0, -1)\n }\n\n // Detect a constraint group: `name(regex)`. The regex body is everything\n // between the first '(' and the final ')'.\n const open = body.indexOf('(')\n if (open !== -1 && body[body.length - 1] === ')') {\n const name = body.slice(0, open)\n const pattern = body.slice(open + 1, -1)\n // Anchor fully so the constraint governs the whole segment.\n return { name, constraint: new RegExp(`^(?:${pattern})$`) }\n }\n\n return { name: body, constraint: null }\n}\n\nfunction decodeParam(raw: string): string {\n // Hot path: skip decode if no '%' present.\n if (raw.indexOf('%') === -1) return raw\n try {\n return decodeURIComponent(raw)\n } catch {\n return raw\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { Socket } from 'node:net'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport { createByteLimit } from '../body/limit.ts'\nimport type { CloseOptions, ListeningServer, Transport, TransportHooks } from './types.ts'\n\n/**\n * Node.js `node:http` transport. Owns a single `http.Server`; on each\n * request, populates a pooled `IngeniumContext` directly from the\n * `IncomingMessage` (no WinterCG translation), awaits dispatch, then writes\n * the context's response state to the `ServerResponse`.\n */\nexport class NodeAdapter implements Transport {\n private hooks: TransportHooks | null = null\n\n attach(hooks: TransportHooks): void {\n this.hooks = hooks\n }\n\n async listen(port: number, host = '127.0.0.1'): Promise<ListeningServer> {\n if (!this.hooks) throw new Error('NodeAdapter.listen() called before attach()')\n const hooks = this.hooks\n\n const server = createServer((req, res) => {\n handleRequest(req, res, hooks).catch((err) => {\n // Last-resort safety net — the dispatch loop should have caught everything.\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('content-type', 'application/json; charset=utf-8')\n res.end(JSON.stringify({ error: 'Internal Server Error', code: 'INTERNAL_ERROR' }))\n } else {\n res.end()\n }\n process.emitWarning(`ingenium: dispatch leaked: ${(err as Error).message ?? String(err)}`)\n })\n })\n\n // Track every open socket so close() can drain (and, if asked, force-kill)\n // idle keep-alive connections that `server.close()` alone would leave open.\n const sockets = new Set<Socket>()\n server.on('connection', (socket) => {\n sockets.add(socket)\n socket.on('close', () => sockets.delete(socket))\n })\n\n return new Promise<ListeningServer>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to determine bound address'))\n return\n }\n resolve({\n port: addr.port,\n host: addr.address,\n close: (opts?: CloseOptions) =>\n new Promise<void>((res, rej) => {\n let settled = false\n let timer: NodeJS.Timeout | null = null\n\n server.close((err) => {\n if (timer) clearTimeout(timer)\n if (settled) return\n settled = true\n err ? rej(err) : res()\n })\n\n const timeoutMs = opts?.gracefulTimeoutMs\n if (typeof timeoutMs === 'number' && Number.isFinite(timeoutMs)) {\n timer = setTimeout(() => {\n // Force-close any sockets still hanging around (idle\n // keep-alives or slow handlers). server.close()'s callback\n // will fire once they're destroyed.\n for (const socket of sockets) socket.destroy()\n }, Math.max(0, timeoutMs))\n // Don't keep the event loop alive just for the force-close timer.\n if (typeof timer.unref === 'function') timer.unref()\n }\n }),\n })\n })\n })\n }\n}\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse, hooks: TransportHooks): Promise<void> {\n // Normalize once: TransportHooks types maxRequestBytes as optional for\n // backward-compat; framework dispatch always sets it. Older fixtures may\n // not — treat undefined as \"no cap\" (Infinity).\n const maxBytes = hooks.maxRequestBytes ?? Number.POSITIVE_INFINITY\n\n // Content-Length pre-check: if the client declares a body larger than the\n // ceiling, reject IMMEDIATELY without acquiring a context or buffering\n // anything. Chunked requests (no Content-Length) and Content-Length: 0\n // fall through to the byte-limit Transform below, which catches\n // mid-stream overruns.\n if (rejectIfContentLengthTooBig(req, res, maxBytes)) return\n\n const ctx = hooks.acquire()\n try {\n populateContext(ctx, req, maxBytes)\n await hooks.dispatch(ctx)\n writeResponse(ctx, res)\n } finally {\n hooks.release(ctx)\n }\n}\n\n/**\n * Returns `true` (and writes a 413 response) if the request advertises a\n * Content-Length greater than `maxRequestBytes`. Returns `false` for missing,\n * invalid, or in-range Content-Length values — those cases are handled by\n * the byte-limit Transform downstream.\n */\nfunction rejectIfContentLengthTooBig(\n req: IncomingMessage,\n res: ServerResponse,\n maxRequestBytes: number,\n): boolean {\n if (!Number.isFinite(maxRequestBytes)) return false\n const raw = req.headers['content-length']\n if (typeof raw !== 'string' || raw.length === 0) return false\n const n = Number(raw)\n if (!Number.isFinite(n)) return false\n if (n <= maxRequestBytes) return false\n\n res.statusCode = 413\n res.setHeader('content-type', 'application/json; charset=utf-8')\n res.setHeader('connection', 'close')\n res.end(\n JSON.stringify({\n error: `Request body exceeded ${maxRequestBytes} bytes`,\n code: 'PAYLOAD_TOO_LARGE',\n }),\n )\n // Hint the kernel to drop any pending body bytes; we never read them.\n req.socket?.destroy()\n return true\n}\n\nfunction populateContext(ctx: IngeniumContext, req: IncomingMessage, maxRequestBytes: number): void {\n ctx.method = (req.method ?? 'GET') as HttpMethod\n ctx.url = req.url ?? '/'\n // Split path / query without allocating a URL object.\n const url = ctx.url\n const qIdx = url.indexOf('?')\n if (qIdx >= 0) {\n ctx.path = url.slice(0, qIdx)\n ctx.rawQuery = url.slice(qIdx + 1)\n } else {\n ctx.path = url\n ctx.rawQuery = ''\n }\n ctx.headers = req.headers\n ctx.remoteAddress = req.socket?.remoteAddress ?? '127.0.0.1'\n // Detect TLS via the socket's `encrypted` flag (set by tls.TLSSocket).\n ctx.baseProtocol = (req.socket as { encrypted?: boolean })?.encrypted ? 'https' : 'http'\n\n // Wire body lazily — the source stream is only consumed if a body method is called.\n const cl = req.headers['content-length']\n const contentLength = cl ? Number(cl) : undefined\n const ct = req.headers['content-type']\n // Wrap the raw IncomingMessage in a transport-level byte-limit so the cap\n // applies to EVERY consumer, including `ctx.body.stream()`. We skip the\n // wrap in three provably-safe cases:\n //\n // 1. The request is structurally body-less (GET/HEAD/OPTIONS or\n // Content-Length: 0). No body to cap.\n // 2. The cap is disabled (Number.POSITIVE_INFINITY).\n // 3. Content-Length is declared AND ≤ cap. The pre-check\n // (`rejectIfContentLengthTooBig`) already verified this; node:http\n // itself enforces the declared length and stops reading at the\n // byte count, so the body cannot exceed the cap. The Transform\n // would be redundant defense in this path.\n //\n // Chunked encoding (no Content-Length) keeps the Transform — that's\n // where the cap actually matters, because the client controls the\n // stream length without any prior declaration.\n const noBody =\n contentLength === 0 ||\n ctx.method === 'GET' ||\n ctx.method === 'HEAD' ||\n ctx.method === 'OPTIONS'\n const knownSafe =\n contentLength !== undefined &&\n Number.isFinite(contentLength) &&\n contentLength <= maxRequestBytes\n if (noBody || !Number.isFinite(maxRequestBytes) || knownSafe) {\n ctx.body._attach(req, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n return\n }\n\n // Cap unknown-length (chunked) bodies with a byte-limit Transform. `pipe()`\n // does NOT forward `'error'` events, so when the chunked path in\n // `IngeniumBody.buffer` re-pipes this Transform into a SECOND limiter and only\n // listens on the downstream pipe, the cap error here would (a) be an\n // unhandled-error crash and (b) never reach that downstream — so the\n // consumer's promise would hang. Attach a guard `'error'` listener and\n // forward the error to every stream this Transform was piped into. We leave\n // `req`/its socket alone so the response (413) can still flush.\n const limited = createByteLimit(maxRequestBytes)\n const downstream = new Set<{ destroy(err?: Error): void; destroyed: boolean }>()\n const origPipe = limited.pipe.bind(limited) as typeof limited.pipe\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n limited.pipe = function pipe(dest: any, ...rest: any[]) {\n downstream.add(dest)\n return origPipe(dest, ...rest)\n } as typeof limited.pipe\n limited.on('error', (err: Error) => {\n for (const dest of downstream) {\n if (!dest.destroyed) dest.destroy(err)\n }\n // Discard the rest of the inbound body so the socket can be reused/closed.\n req.unpipe(limited)\n req.on('error', () => {})\n req.resume()\n })\n req.pipe(limited)\n ctx.body._attach(limited, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n}\n\nfunction writeResponse(ctx: IngeniumContext, res: ServerResponse): void {\n const body = ctx._body\n const headers = ctx._headers\n\n // Compute content-length where we know it. Mutating ctx._headers is safe\n // because the context is being released to the pool right after this call.\n switch (body.kind) {\n case 'string':\n if (headers['content-length'] === undefined) {\n headers['content-length'] = String(Buffer.byteLength(body.data))\n }\n break\n case 'buffer':\n if (headers['content-length'] === undefined) {\n headers['content-length'] = String(body.data.length)\n }\n break\n case 'none':\n case 'stream':\n break\n }\n\n // Single writeHead call instead of `statusCode = ...; setHeader × N`.\n // node:http has a fast path that flushes status line + headers in one\n // serialization pass — measurably faster than the per-header setHeader\n // sequence on hot endpoints.\n if (body.kind === 'stream') {\n res.writeHead(ctx._statusCode, headers)\n body.data.pipe(res)\n return\n }\n res.writeHead(ctx._statusCode, headers)\n if (body.kind === 'none') {\n res.end()\n } else {\n res.end(body.data)\n }\n}\n","import type { HttpMethod } from '../router/types.ts'\nimport type {\n Operation,\n Parameter,\n RequestBody,\n Response,\n SecurityRequirement,\n} from './types.ts'\n\n/**\n * Per-route metadata supplied via `app.describe('METHOD', '/path', meta)`.\n * Merged into the generated Operation by `generateOpenApi`.\n *\n * Anything you put here ends up on the operation object verbatim, except:\n * - `hidden: true` skips the route entirely (won't appear in the spec).\n * - `parameters` are *appended* to the path-param parameters extracted from\n * the route syntax, so you typically only put `query`, `header`, or\n * `cookie` parameters here.\n */\nexport interface RouteDescriptor {\n summary?: string\n description?: string\n operationId?: string\n tags?: string[]\n deprecated?: boolean\n hidden?: boolean\n parameters?: Parameter[]\n requestBody?: RequestBody\n responses?: Record<string | number, Response>\n security?: SecurityRequirement[]\n /** Extension passthrough — anything starting with `x-` is preserved. */\n [extension: `x-${string}`]: unknown\n}\n\n/** Stable lookup key used by the descriptor map. */\nexport function descriptorKey(method: HttpMethod, path: string): string {\n return `${method} ${path}`\n}\n\n/**\n * Merge a `RouteDescriptor` onto a base `Operation` (which already carries\n * the path parameters extracted from the route syntax). Mutates and returns\n * the base operation for caller convenience.\n *\n * Order rules:\n * - `parameters` are concatenated (path params first, descriptor params after).\n * - `responses` map keys are normalized to strings (200 → '200').\n * - Extensions (`x-*`) are copied verbatim.\n */\nexport function mergeDescriptor(\n base: Operation,\n desc: RouteDescriptor | undefined,\n): Operation {\n if (!desc) return base\n if (desc.summary !== undefined) base.summary = desc.summary\n if (desc.description !== undefined) base.description = desc.description\n if (desc.operationId !== undefined) base.operationId = desc.operationId\n if (desc.tags !== undefined) base.tags = [...desc.tags]\n if (desc.deprecated !== undefined) base.deprecated = desc.deprecated\n if (desc.security !== undefined) base.security = desc.security\n if (desc.requestBody !== undefined) base.requestBody = desc.requestBody\n if (desc.parameters && desc.parameters.length > 0) {\n base.parameters = [...(base.parameters ?? []), ...desc.parameters]\n }\n if (desc.responses) {\n const out: Record<string, Response> = {}\n for (const k of Object.keys(desc.responses)) {\n out[String(k)] = desc.responses[k as keyof typeof desc.responses] as Response\n }\n base.responses = out\n }\n // Copy x-* extensions verbatim.\n for (const k of Object.keys(desc)) {\n if (k.startsWith('x-')) {\n ;(base as Record<string, unknown>)[k] = (desc as Record<string, unknown>)[k]\n }\n }\n return base\n}\n","import type { QueueStore } from './types.ts'\n\ninterface PendingEntry<TData> {\n id: string\n data: TData\n attempt: number\n /** When `> Date.now()`, the job is delayed (used by retries). */\n notBefore: number\n}\n\ninterface InFlightEntry<TData> {\n id: string\n data: TData\n attempt: number\n}\n\n/**\n * In-process FIFO queue store. Backs {@link IngeniumQueue} when no custom\n * store is supplied. Suitable for single-instance deployments and tests.\n *\n * Layout:\n * - `pending`: ordered list of jobs ready to be picked up. Delayed jobs\n * (post-retry backoff) sit here too — `next()` skips entries whose\n * `notBefore` hasn't elapsed yet, so callers should poll on a timer.\n * - `inFlight`: jobs that have been `next()`-ed but not yet `ack`/`retry`/`fail`-ed.\n * - `failed`: dead-letter list. Persists until `clearFailed()` is called.\n *\n * No background timers — purely event-driven via the queue worker pool.\n */\nexport class MemoryQueueStore<TData> implements QueueStore<TData> {\n private readonly pending: PendingEntry<TData>[] = []\n private readonly inFlight: Map<string, InFlightEntry<TData>> = new Map()\n private readonly failed: { id: string; data: TData; attempt: number }[] = []\n private nextId = 1\n\n enqueue(data: TData): Promise<{ id: string }> {\n const id = String(this.nextId++)\n this.pending.push({ id, data, attempt: 1, notBefore: 0 })\n return Promise.resolve({ id })\n }\n\n next(): Promise<{ id: string; data: TData; attempt: number } | null> {\n const now = Date.now()\n // Find the first pending entry whose delay has elapsed.\n for (let i = 0; i < this.pending.length; i++) {\n const entry = this.pending[i]!\n if (entry.notBefore <= now) {\n this.pending.splice(i, 1)\n const inflight: InFlightEntry<TData> = {\n id: entry.id,\n data: entry.data,\n attempt: entry.attempt,\n }\n this.inFlight.set(entry.id, inflight)\n return Promise.resolve({ id: entry.id, data: entry.data, attempt: entry.attempt })\n }\n }\n return Promise.resolve(null)\n }\n\n ack(id: string): Promise<void> {\n this.inFlight.delete(id)\n return Promise.resolve()\n }\n\n retry(id: string, delayMs: number): Promise<void> {\n const entry = this.inFlight.get(id)\n if (!entry) return Promise.resolve()\n this.inFlight.delete(id)\n this.pending.push({\n id: entry.id,\n data: entry.data,\n attempt: entry.attempt + 1,\n notBefore: Date.now() + Math.max(0, delayMs),\n })\n return Promise.resolve()\n }\n\n fail(id: string): Promise<void> {\n const entry = this.inFlight.get(id)\n if (!entry) return Promise.resolve()\n this.inFlight.delete(id)\n this.failed.push({ id: entry.id, data: entry.data, attempt: entry.attempt })\n return Promise.resolve()\n }\n\n size(): Promise<number> {\n return Promise.resolve(this.pending.length)\n }\n\n failedCount(): Promise<number> {\n return Promise.resolve(this.failed.length)\n }\n\n /** @internal Used by `IngeniumQueue.clearFailed()`. */\n clearFailed(): void {\n this.failed.length = 0\n }\n\n /** @internal Used by `IngeniumQueue.drain()` to know if work is outstanding. */\n inFlightCount(): number {\n return this.inFlight.size\n }\n\n /** @internal Earliest `notBefore` of any pending entry, or `null` if none. */\n earliestPendingAt(): number | null {\n let min: number | null = null\n for (const e of this.pending) {\n if (min === null || e.notBefore < min) min = e.notBefore\n }\n return min\n }\n}\n","import { MemoryQueueStore } from './store-memory.ts'\nimport type {\n FailedJob,\n QueueOptions,\n QueueStore,\n QueueWorker,\n RetryPolicy,\n} from './types.ts'\n\n/** Default exponential backoff: 100ms, 400ms, 1.6s, 6.4s, ... (4^(n-1) * 100). */\nconst DEFAULT_RETRIES: RetryPolicy = {\n attempts: 3,\n backoffMs: (attempt: number) => 100 * Math.pow(4, attempt - 1),\n}\n\nfunction normalizeRetries(retries: number | RetryPolicy | undefined): RetryPolicy {\n if (retries === undefined) return DEFAULT_RETRIES\n if (typeof retries === 'number') {\n return { attempts: Math.max(1, retries), backoffMs: DEFAULT_RETRIES.backoffMs }\n }\n return retries\n}\n\n/**\n * A single named background queue. Wraps a {@link QueueStore} with a worker\n * pool, retry/backoff logic, pause/resume controls, and a `drain()` for\n * graceful shutdown.\n *\n * The pool is event-driven: when a slot frees up, the queue immediately\n * tries to pull another job; if none is ready (empty or all delayed), the\n * pool sleeps until either:\n * - a new `add()` call wakes it, or\n * - the earliest delayed job's `notBefore` elapses (timer-based wake).\n *\n * All timers are `unref()`'d so the queue alone never keeps the event loop alive.\n */\nexport class IngeniumQueue<TData = unknown> {\n readonly name: string\n private readonly store: QueueStore<TData>\n private readonly worker: QueueWorker<TData>\n private readonly retries: RetryPolicy\n private readonly concurrency: number\n private readonly onFailed: ((job: FailedJob<TData>) => void | Promise<void>) | undefined\n\n /** Active worker slot count. When `< concurrency`, pull more work. */\n private active = 0\n /** Whether `pause()` has been called and `resume()` not yet. */\n private paused = false\n /** Whether `drain()`/close has been called. No new jobs accepted. */\n private closed = false\n /** Timer for waking the pool when a delayed retry becomes due. */\n private wakeTimer: NodeJS.Timeout | null = null\n /** Resolvers waiting for `active` to hit 0 (used by `drain()`). */\n private idleWaiters: (() => void)[] = []\n /** Set when the pool is started — protects against double-start. */\n private started = false\n\n constructor(name: string, opts: QueueOptions<TData>, worker: QueueWorker<TData>) {\n this.name = name\n this.store = opts.store ?? new MemoryQueueStore<TData>()\n this.worker = worker\n this.retries = normalizeRetries(opts.retries)\n this.concurrency = Math.max(1, opts.concurrency ?? 1)\n this.onFailed = opts.onFailed\n }\n\n /**\n * Start the worker pool. Idempotent — safe to call multiple times. The\n * pool is also implicitly started by the first `add()` call so direct\n * invocation is optional.\n */\n start(): void {\n if (this.started) return\n this.started = true\n this.pump()\n }\n\n /** Enqueue a job. Returns the assigned id. */\n async add(data: TData): Promise<{ id: string }> {\n if (this.closed) {\n throw new Error(`ingenium: queue \"${this.name}\" is closed (no new jobs accepted)`)\n }\n const handle = await this.store.enqueue(data)\n // Lazy-start: first add() triggers worker pool boot if `start()` wasn't called.\n if (!this.started) this.start()\n else this.pump()\n return handle\n }\n\n /** Approximate number of pending jobs. */\n size(): Promise<number> {\n return this.store.size()\n }\n\n /** Number of jobs in the dead-letter list. */\n failedCount(): Promise<number> {\n return this.store.failedCount()\n }\n\n /**\n * Empty the dead-letter list. Only effective when the underlying store\n * is the default {@link MemoryQueueStore}; custom stores should provide\n * their own clearing surface.\n */\n clearFailed(): void {\n if (this.store instanceof MemoryQueueStore) this.store.clearFailed()\n }\n\n /**\n * Stop pulling new jobs from the store. In-flight jobs continue to run\n * until they complete. Idempotent.\n */\n pause(): void {\n this.paused = true\n }\n\n /** Resume pulling jobs. Wakes the pool. */\n resume(): void {\n if (!this.paused) return\n this.paused = false\n this.pump()\n }\n\n /**\n * Wait for all in-flight jobs to complete, then stop accepting new ones.\n * If `timeoutMs` elapses first, resolve anyway — the orphaned jobs keep\n * running until they naturally finish (JS can't cancel a Promise), but\n * the framework stops waiting.\n *\n * Returns `true` if the queue drained cleanly; `false` on timeout.\n */\n async drain(timeoutMs?: number): Promise<boolean> {\n this.closed = true\n this.paused = true // stop pulling new work even if currently active\n if (this.active === 0) {\n this.clearWakeTimer()\n return true\n }\n return new Promise<boolean>((resolve) => {\n let settled = false\n const onIdle = (): void => {\n if (settled) return\n settled = true\n if (timer) clearTimeout(timer)\n this.clearWakeTimer()\n resolve(true)\n }\n this.idleWaiters.push(onIdle)\n const timer = timeoutMs !== undefined\n ? setTimeout(() => {\n if (settled) return\n settled = true\n // Drop our waiter so the pool doesn't re-resolve us.\n const idx = this.idleWaiters.indexOf(onIdle)\n if (idx >= 0) this.idleWaiters.splice(idx, 1)\n this.clearWakeTimer()\n resolve(false)\n }, timeoutMs)\n : null\n timer?.unref?.()\n })\n }\n\n /**\n * Pump the pool: while we have free slots and we're not paused, pull jobs\n * and dispatch them. No-op when paused / saturated. Re-entrant: every\n * job completion calls `pump()` again to fill the slot.\n */\n private pump(): void {\n if (this.paused) {\n this.checkIdle()\n return\n }\n while (this.active < this.concurrency) {\n // Synchronously check store state via a microtask. The store API is\n // async (so a Redis adapter works), so each pull is a Promise we don't\n // await inline — we just kick it off and let `runOne` increment/decrement\n // `active` around the actual worker invocation.\n const slotOpen = this.tryFillSlot()\n if (!slotOpen) break\n }\n this.checkIdle()\n }\n\n /**\n * Attempts to take one job from the store and run it. Returns `false` if\n * the store is empty (or all-delayed) so the caller stops looping.\n *\n * NOTE: we increment `active` BEFORE the async `next()` resolves so a\n * burst of synchronous `pump()` calls doesn't over-subscribe the pool.\n * We decrement on the `null` path.\n */\n private tryFillSlot(): boolean {\n this.active++\n void this.runOne().catch(() => {\n // runOne handles all errors internally; this catch is a defensive\n // backstop so an unexpected bug doesn't unhandle a rejection.\n })\n return true\n }\n\n private async runOne(): Promise<void> {\n let job: { id: string; data: TData; attempt: number } | null = null\n try {\n job = await this.store.next()\n } catch {\n // Store failure pulling the next job — release slot and back off.\n this.active--\n this.checkIdle()\n return\n }\n if (job === null) {\n // Empty (or all delayed). Release the speculative slot, schedule a\n // wake for the earliest delayed job (if any), and stop pulling.\n this.active--\n this.scheduleDelayedWake()\n this.checkIdle()\n return\n }\n\n let lastError: unknown = undefined\n try {\n await this.worker({ id: job.id, data: job.data, attempt: job.attempt })\n await this.store.ack(job.id)\n } catch (err) {\n lastError = err\n const attempt = job.attempt\n if (attempt < this.retries.attempts) {\n const delay = Math.max(0, this.retries.backoffMs(attempt))\n try {\n await this.store.retry(job.id, delay)\n } catch {\n // If retry bookkeeping fails, fall back to fail() so the job\n // doesn't get stuck in-flight forever.\n await this.safeFail(job, lastError)\n }\n } else {\n await this.safeFail(job, lastError)\n }\n } finally {\n this.active--\n // Refill the freed slot on the next macrotask, not synchronously. A\n // synchronous refill would chain pickup of the *next* job into the same\n // microtask run as this job's completion, so the pool would never be\n // observably idle between jobs (active would dip and immediately rise\n // within one turn). Deferring to setImmediate yields a macrotask\n // boundary where `active` reflects only genuinely-running jobs.\n const t = setImmediate(() => this.pump())\n t.unref?.()\n }\n }\n\n private async safeFail(\n job: { id: string; data: TData; attempt: number },\n lastError: unknown,\n ): Promise<void> {\n try {\n await this.store.fail(job.id)\n } catch {\n // If even fail() throws, we've done what we can — the job stays\n // in-flight in the store, which is at-least-once-correct.\n return\n }\n if (this.onFailed) {\n try {\n await this.onFailed({ id: job.id, data: job.data, attempt: job.attempt, lastError })\n } catch {\n // onFailed errors are observation-only; swallow.\n }\n }\n }\n\n /**\n * If the store has only delayed entries (e.g. just-retried jobs whose\n * backoff hasn't elapsed), schedule a one-shot wake when the earliest\n * delay fires so we don't spin or sleep forever.\n *\n * Only the default in-memory store exposes `earliestPendingAt`; for\n * custom stores we don't poll — we rely on the next `add()` to wake us.\n */\n private scheduleDelayedWake(): void {\n if (!(this.store instanceof MemoryQueueStore)) return\n const earliest = this.store.earliestPendingAt()\n if (earliest === null) return\n const delay = Math.max(1, earliest - Date.now())\n this.clearWakeTimer()\n this.wakeTimer = setTimeout(() => {\n this.wakeTimer = null\n this.pump()\n }, delay)\n this.wakeTimer.unref?.()\n }\n\n private clearWakeTimer(): void {\n if (this.wakeTimer) {\n clearTimeout(this.wakeTimer)\n this.wakeTimer = null\n }\n }\n\n private checkIdle(): void {\n if (this.active !== 0 || this.idleWaiters.length === 0) return\n const waiters = this.idleWaiters.splice(0, this.idleWaiters.length)\n for (const w of waiters) w()\n }\n}\n","import { IngeniumQueue } from './queue.ts'\nimport type { QueueOptions, QueueWorker } from './types.ts'\n\n/**\n * Maps queue names → {@link IngeniumQueue} instances. Held by `IngeniumApp`,\n * mirroring the shape of {@link CronRegistry}.\n *\n * Lookup is O(1). Names must be unique within an app — re-registering the\n * same name throws (mirrors how `app.get('/users')` would conflict if you\n * registered the same path twice with the same method).\n */\nexport class QueueRegistry {\n private readonly queues: Map<string, IngeniumQueue<unknown>> = new Map()\n\n /**\n * Register a new queue. Returns the created instance. Throws if a queue\n * with `name` is already registered.\n */\n register<TData>(\n name: string,\n opts: QueueOptions<TData>,\n worker: QueueWorker<TData>,\n ): IngeniumQueue<TData> {\n if (this.queues.has(name)) {\n throw new Error(`ingenium: queue \"${name}\" is already registered`)\n }\n const queue = new IngeniumQueue<TData>(name, opts, worker)\n this.queues.set(name, queue as unknown as IngeniumQueue<unknown>)\n return queue\n }\n\n /** Look up a queue. Throws if not registered (typos surface immediately). */\n get<TData = unknown>(name: string): IngeniumQueue<TData> {\n const queue = this.queues.get(name)\n if (!queue) {\n throw new Error(\n `ingenium: queue \"${name}\" is not registered (call app.queue(\"${name}\", ...) first)`,\n )\n }\n return queue as unknown as IngeniumQueue<TData>\n }\n\n /** Has a queue with this name been registered? */\n has(name: string): boolean {\n return this.queues.has(name)\n }\n\n /** Number of registered queues. */\n count(): number {\n return this.queues.size\n }\n\n /** All registered queue names (insertion order). */\n names(): string[] {\n return [...this.queues.keys()]\n }\n\n /**\n * Start the worker pool of every registered queue. Called by the app's\n * composition step so workers don't process jobs before the app is ready.\n */\n startAll(): void {\n for (const q of this.queues.values()) q.start()\n }\n\n /**\n * Drain every queue concurrently. Resolves when all queues either finish\n * their in-flight work or hit `timeoutMs`. The returned object reports\n * which queues drained cleanly vs timed out — useful for shutdown logs.\n */\n async drainAll(timeoutMs?: number): Promise<{ clean: string[]; timedOut: string[] }> {\n const entries = [...this.queues.entries()]\n const results = await Promise.all(entries.map(([, q]) => q.drain(timeoutMs)))\n const clean: string[] = []\n const timedOut: string[] = []\n entries.forEach(([name], i) => {\n if (results[i]) clean.push(name)\n else timedOut.push(name)\n })\n return { clean, timedOut }\n }\n}\n","/**\n * 5-field crontab parser + \"next fire time\" calculator.\n *\n * Grammar (per field):\n * - `*` every value\n * - `N` literal\n * - `N-M` inclusive range\n * - `* / S` or `N-M / S` step\n * - `A,B,C` list (each entry can be any of the above)\n *\n * Supported field ranges:\n * minute 0-59\n * hour 0-23\n * dom 1-31\n * month 1-12, or 3-letter names jan|feb|...|dec\n * dow 0-6 (sunday=0), or 3-letter names sun|mon|...|sat\n *\n * Explicitly NOT supported (would need a different parser):\n * - 6-field syntax with seconds\n * - L (last day-of-month), W (weekday), # (nth-of-month)\n * - Predefined macros (@hourly, @daily, ...)\n *\n * Day-of-month vs day-of-week conflict resolution: when BOTH `dom` and\n * `dow` are restricted (i.e. neither is `*`), the cron fires when EITHER\n * matches (this is the historical Vixie-cron behavior). When only one is\n * restricted, only that one matters. This is what every other production\n * cron implementation does and what users expect.\n */\n\nconst MONTH_NAMES: Record<string, number> = {\n jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6,\n jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12,\n}\n\nconst DOW_NAMES: Record<string, number> = {\n sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6,\n}\n\ninterface FieldSpec {\n min: number\n max: number\n /** Optional name → number map (months, weekdays). */\n names?: Record<string, number>\n}\n\nconst FIELDS: { minute: FieldSpec; hour: FieldSpec; dom: FieldSpec; month: FieldSpec; dow: FieldSpec } = {\n minute: { min: 0, max: 59 },\n hour: { min: 0, max: 23 },\n dom: { min: 1, max: 31 },\n month: { min: 1, max: 12, names: MONTH_NAMES },\n dow: { min: 0, max: 6, names: DOW_NAMES },\n}\n\n/** Parsed match-set. `Set<number>` of all valid integers per field. */\nexport interface CronMatch {\n minute: Set<number>\n hour: Set<number>\n dom: Set<number>\n month: Set<number>\n dow: Set<number>\n /** Was the original `dom` field `*`? Used for dom/dow conflict resolution. */\n domIsWild: boolean\n /** Was the original `dow` field `*`? */\n dowIsWild: boolean\n}\n\n/**\n * Parse a 5-field crontab spec into a {@link CronMatch}. Throws on any\n * malformed input — out-of-range, wrong field count, garbage characters.\n */\nexport function parseCronSpec(spec: string): CronMatch {\n if (typeof spec !== 'string') {\n throw new Error(`ingenium: cron spec must be a string (got ${typeof spec})`)\n }\n const trimmed = spec.trim()\n if (trimmed === '') throw new Error('ingenium: cron spec is empty')\n\n const fields = trimmed.split(/\\s+/)\n if (fields.length !== 5) {\n throw new Error(\n `ingenium: cron spec must have exactly 5 fields (got ${fields.length}: \"${spec}\"). ` +\n `Six-field specs with seconds are not supported in v0.0.1.`,\n )\n }\n\n const [minuteF, hourF, domF, monthF, dowF] = fields as [string, string, string, string, string]\n return {\n minute: parseField(minuteF, FIELDS.minute, 'minute'),\n hour: parseField(hourF, FIELDS.hour, 'hour'),\n dom: parseField(domF, FIELDS.dom, 'day-of-month'),\n month: parseField(monthF, FIELDS.month, 'month'),\n dow: parseField(dowF, FIELDS.dow, 'day-of-week'),\n domIsWild: domF === '*',\n dowIsWild: dowF === '*',\n }\n}\n\nfunction parseField(field: string, spec: FieldSpec, label: string): Set<number> {\n const out = new Set<number>()\n for (const part of field.split(',')) {\n expandPart(part, spec, label, out)\n }\n if (out.size === 0) {\n throw new Error(`ingenium: cron field \"${label}\" produced no matches (\"${field}\")`)\n }\n return out\n}\n\nfunction expandPart(part: string, spec: FieldSpec, label: string, out: Set<number>): void {\n if (part === '') throw new Error(`ingenium: empty cron sub-expression in \"${label}\"`)\n\n // Step: optional. Either `*/N`, `A-B/N`, or `A/N` (treated as `A-max/N`).\n let step = 1\n let body = part\n const slashIdx = part.indexOf('/')\n if (slashIdx >= 0) {\n body = part.slice(0, slashIdx)\n const stepStr = part.slice(slashIdx + 1)\n if (!/^\\d+$/.test(stepStr)) {\n throw new Error(`ingenium: cron step in \"${label}\" must be a positive integer (\"${part}\")`)\n }\n step = parseInt(stepStr, 10)\n if (step <= 0) {\n throw new Error(`ingenium: cron step in \"${label}\" must be > 0 (\"${part}\")`)\n }\n }\n\n let lo: number\n let hi: number\n if (body === '*') {\n lo = spec.min\n hi = spec.max\n } else if (body.includes('-')) {\n const [aStr, bStr] = body.split('-')\n const a = parseAtom(aStr ?? '', spec, label)\n const b = parseAtom(bStr ?? '', spec, label)\n if (a > b) {\n throw new Error(`ingenium: cron range \"${body}\" in \"${label}\" is reversed (${a} > ${b})`)\n }\n lo = a\n hi = b\n } else {\n const v = parseAtom(body, spec, label)\n if (slashIdx >= 0) {\n // `N/S` form → `N-max/S`\n lo = v\n hi = spec.max\n } else {\n lo = hi = v\n }\n }\n\n if (lo < spec.min || hi > spec.max) {\n throw new Error(\n `ingenium: cron value out of range in \"${label}\" — got ${lo}..${hi}, allowed ${spec.min}..${spec.max}`,\n )\n }\n\n for (let i = lo; i <= hi; i += step) out.add(i)\n}\n\nfunction parseAtom(atom: string, spec: FieldSpec, label: string): number {\n if (atom === '') throw new Error(`ingenium: empty cron atom in \"${label}\"`)\n if (/^-?\\d+$/.test(atom)) {\n const n = parseInt(atom, 10)\n if (n < 0) {\n throw new Error(`ingenium: cron value in \"${label}\" must be non-negative (\"${atom}\")`)\n }\n return n\n }\n if (spec.names) {\n const lower = atom.toLowerCase()\n if (lower in spec.names) return spec.names[lower]!\n }\n throw new Error(`ingenium: cron atom \"${atom}\" in \"${label}\" is not a number or known name`)\n}\n\n// ─── Next-fire calculation ──────────────────────────────────────────────────\n\n/**\n * Given a parsed {@link CronMatch}, find the next moment >= `from` that\n * matches the spec, in the given IANA timezone. Returns `null` if none\n * within ~5 years (defensive against pathological specs).\n *\n * Algorithm: walk forward minute-by-minute with smart skipping. We start\n * one minute past `from` (cron fires at the START of each minute and we\n * never want to re-fire the same slot back-to-back).\n *\n * Timezone handling:\n * - For `'UTC'` we use direct UTC accessors — fast path.\n * - For other zones we call `Intl.DateTimeFormat` to get the wall-clock\n * fields in that zone for each candidate. This relies on Node's bundled\n * ICU data; full-icu Node ships with a complete tz database.\n *\n * DST: by walking minute-by-minute on the UTC timeline and reading the\n * wall-clock fields per-step, we naturally skip the \"spring forward\" gap\n * (those minutes simply don't exist in the local clock so they can't match\n * the user's local-time spec) and double-fire on \"fall back\" (the wall\n * clock visits 1:30am twice; we fire each time). The latter matches Vixie\n * cron's documented behavior — users wanting strict once-per-day semantics\n * should pin their spec to UTC.\n */\nexport function nextFireFrom(match: CronMatch, from: Date, timezone = 'UTC'): Date | null {\n // Start at the next whole minute strictly after `from`.\n const start = new Date(from.getTime() + 1)\n start.setUTCSeconds(0, 0)\n // If the rounding above happened to put us at-or-before `from`, bump.\n if (start.getTime() <= from.getTime()) {\n start.setTime(start.getTime() + 60_000)\n start.setUTCSeconds(0, 0)\n }\n\n // Cap the search to ~5 years in case the spec matches nothing reachable.\n const maxIterations = 5 * 366 * 24 * 60\n const candidate = start\n const reader = timezone === 'UTC' ? readUtc : makeIntlReader(timezone)\n\n for (let i = 0; i < maxIterations; i++) {\n const wall = reader(candidate)\n if (matchesWall(match, wall)) return new Date(candidate.getTime())\n // Step forward one minute.\n candidate.setTime(candidate.getTime() + 60_000)\n }\n return null\n}\n\ninterface WallClock {\n minute: number\n hour: number\n dom: number\n month: number // 1-12\n dow: number // 0=sunday\n}\n\nfunction matchesWall(m: CronMatch, w: WallClock): boolean {\n if (!m.minute.has(w.minute)) return false\n if (!m.hour.has(w.hour)) return false\n if (!m.month.has(w.month)) return false\n // Vixie-cron dom/dow OR semantics: if BOTH are restricted, either match\n // is sufficient. If only one is restricted, only it matters.\n const domOk = m.dom.has(w.dom)\n const dowOk = m.dow.has(w.dow)\n if (m.domIsWild && m.dowIsWild) {\n // Both wild → both sets are full → both ok (above) → fall through to true.\n if (!domOk || !dowOk) return false\n } else if (m.domIsWild) {\n if (!dowOk) return false\n } else if (m.dowIsWild) {\n if (!domOk) return false\n } else {\n if (!domOk && !dowOk) return false\n }\n return true\n}\n\nfunction readUtc(d: Date): WallClock {\n return {\n minute: d.getUTCMinutes(),\n hour: d.getUTCHours(),\n dom: d.getUTCDate(),\n month: d.getUTCMonth() + 1,\n dow: d.getUTCDay(),\n }\n}\n\n/**\n * Build a wall-clock reader for a non-UTC timezone using `Intl.DateTimeFormat`.\n * The reader is reusable (we cache the formatter).\n */\nfunction makeIntlReader(timezone: string): (d: Date) => WallClock {\n let fmt: Intl.DateTimeFormat\n try {\n fmt = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n hour12: false,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n weekday: 'short',\n })\n } catch {\n throw new Error(\n `ingenium: invalid cron timezone \"${timezone}\". ` +\n `Use a valid IANA zone (e.g. \"America/Los_Angeles\") or \"UTC\".`,\n )\n }\n const dowMap: Record<string, number> = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }\n\n return (d: Date): WallClock => {\n const parts = fmt.formatToParts(d)\n let minute = 0, hour = 0, dom = 1, month = 1, dow = 0\n for (const p of parts) {\n switch (p.type) {\n case 'minute': minute = parseInt(p.value, 10); break\n case 'hour': {\n // Intl returns \"24\" at midnight in en-US hour12:false on some Node versions; normalize.\n const h = parseInt(p.value, 10)\n hour = h === 24 ? 0 : h\n break\n }\n case 'day': dom = parseInt(p.value, 10); break\n case 'month': month = parseInt(p.value, 10); break\n case 'weekday': dow = dowMap[p.value] ?? 0; break\n }\n }\n return { minute, hour, dom, month, dow }\n }\n}\n","import { nextFireFrom, parseCronSpec, type CronMatch } from './parser.ts'\n\n/**\n * Handler signature for `app.cron(...)` jobs. Receives the scheduled fire\n * time AND a fresh `now` so handlers can detect drift / late starts.\n */\nexport type CronHandler = (ctx: { now: Date; firedAt: Date }) => unknown | Promise<unknown>\n\n/** Options for {@link IngeniumCronJob}. */\nexport interface CronOptions {\n /** IANA timezone for the spec. Default `'UTC'`. */\n timezone?: string\n /**\n * If `true`, fire once at `start()` BEFORE waiting for the next scheduled\n * slot. The synthetic `firedAt` for this immediate run is `now`. Default `false`.\n */\n runOnStart?: boolean\n /**\n * Behavior when a previous run is still in flight at the next fire time.\n * - `'skip'` → drop the new tick (default).\n * - `'queue'` → queue ONE pending run; subsequent ticks during the same\n * pile-up still drop. (We don't do unbounded queuing; that's an\n * anti-pattern that hides bugs.)\n */\n overlap?: 'skip' | 'queue'\n /** Optional name for logs / introspection. Defaults to the original spec. */\n name?: string\n}\n\n/**\n * A single scheduled cron job. Owns its parsed spec, a `setTimeout`-based\n * one-shot rescheduler, and bookkeeping for in-flight runs.\n *\n * Lifecycle: `start()` arms the first timer; `stop()` cancels it. The\n * timer is `unref()`'d so a registered cron alone never keeps the event\n * loop alive — production apps that have an HTTP listener will keep\n * running normally; standalone scripts will exit when other work finishes.\n */\nexport class IngeniumCronJob {\n readonly name: string\n readonly spec: string\n readonly timezone: string\n readonly overlap: 'skip' | 'queue'\n private readonly match: CronMatch\n private readonly handler: CronHandler\n private readonly runOnStart: boolean\n\n private timer: NodeJS.Timeout | null = null\n private inFlight = 0\n private queuedRun: { firedAt: Date } | null = null\n private nextAt: Date | null = null\n private started = false\n private stopped = false\n\n constructor(spec: string, opts: CronOptions, handler: CronHandler) {\n this.spec = spec\n this.match = parseCronSpec(spec)\n this.timezone = opts.timezone ?? 'UTC'\n this.overlap = opts.overlap ?? 'skip'\n this.runOnStart = opts.runOnStart ?? false\n this.name = opts.name ?? spec\n this.handler = handler\n }\n\n /** Arm the scheduler. Idempotent. */\n start(): void {\n if (this.started || this.stopped) return\n this.started = true\n if (this.runOnStart) {\n // Fire immediately (synthetic `firedAt = now`), then schedule.\n this.dispatch(new Date())\n }\n this.scheduleNext()\n }\n\n /** Cancel the scheduler. In-flight runs continue until they naturally finish. */\n stop(): void {\n this.stopped = true\n this.started = false\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n this.queuedRun = null\n this.nextAt = null\n }\n\n /** Next scheduled fire time, or `null` if not started / stopped. */\n nextRunAt(): Date | null {\n return this.nextAt\n }\n\n /** Are there currently any in-flight invocations of the handler? */\n isRunning(): boolean {\n return this.inFlight > 0\n }\n\n /** @internal Test helper — does this job have its wake timer armed? */\n hasArmedTimer(): boolean {\n return this.timer !== null\n }\n\n private scheduleNext(): void {\n if (this.stopped) return\n const now = new Date()\n const next = nextFireFrom(this.match, now, this.timezone)\n if (!next) {\n // Spec matches nothing reachable — give up silently rather than spin.\n this.nextAt = null\n return\n }\n this.nextAt = next\n const delay = Math.max(1, next.getTime() - now.getTime())\n this.timer = setTimeout(() => {\n this.timer = null\n const firedAt = next\n this.dispatch(firedAt)\n this.scheduleNext()\n }, delay)\n this.timer.unref?.()\n }\n\n private dispatch(firedAt: Date): void {\n if (this.inFlight > 0) {\n // Overlap path. `'skip'` drops; `'queue'` records ONE pending run.\n if (this.overlap === 'queue' && this.queuedRun === null) {\n this.queuedRun = { firedAt }\n }\n return\n }\n this.runOnce(firedAt)\n }\n\n private runOnce(firedAt: Date): void {\n this.inFlight++\n void Promise.resolve()\n .then(() => this.handler({ now: new Date(), firedAt }))\n .catch(() => {\n // Cron handler errors are observation-only here; framework-level\n // logging belongs in the registry layer (or a user-supplied\n // `onError` if/when we add one). Do not crash the scheduler.\n })\n .finally(() => {\n this.inFlight--\n // If a queued run is waiting, drain it now.\n if (this.queuedRun !== null && this.inFlight === 0 && !this.stopped) {\n const pending = this.queuedRun\n this.queuedRun = null\n this.runOnce(pending.firedAt)\n }\n })\n }\n}\n","import { IngeniumCronJob, type CronHandler, type CronOptions } from './scheduler.ts'\n\n/**\n * Holds every registered {@link IngeniumCronJob} for an app. Mirrors the shape\n * of `QueueRegistry` so the integration in `IngeniumApp` is symmetric.\n *\n * Cron jobs are NOT auto-started on registration — `startAll()` runs at\n * compose time so handlers don't fire before the app is ready (e.g. before\n * `app.decorate()` plugins have wired up `ctx`-style state the handler may\n * inspect via the registry from another code path).\n */\nexport class CronRegistry {\n private readonly jobs: IngeniumCronJob[] = []\n private started = false\n\n /** Register a new cron job. Returns the job for advanced introspection. */\n register(spec: string, opts: CronOptions, handler: CronHandler): IngeniumCronJob {\n const job = new IngeniumCronJob(spec, opts, handler)\n this.jobs.push(job)\n // If the registry has already been started (e.g. plugin registered a\n // cron after compose), start the new job immediately to match what\n // happened to all earlier-registered jobs.\n if (this.started) job.start()\n return job\n }\n\n /** Number of registered jobs. */\n count(): number {\n return this.jobs.length\n }\n\n /** All registered job names (insertion order). */\n names(): string[] {\n return this.jobs.map((j) => j.name)\n }\n\n /** Start every registered job. Idempotent. */\n startAll(): void {\n if (this.started) return\n this.started = true\n for (const j of this.jobs) j.start()\n }\n\n /** Stop every registered job. In-flight handlers continue until they finish. */\n stopAll(): void {\n this.started = false\n for (const j of this.jobs) j.stop()\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport { Buffer } from 'node:buffer'\nimport { Readable } from 'node:stream'\nimport { IngeniumContext } from './context/context.ts'\nimport { IngeniumContextPool } from './context/pool.ts'\nimport {\n IngeniumError,\n IngeniumHaltError,\n IngeniumMethodNotAllowedError,\n IngeniumNotFoundError,\n IngeniumTimeoutError,\n} from './errors.ts'\nimport { composeWithHandler } from './middleware/compose.ts'\nimport type { IngeniumHandler, IngeniumMiddleware } from './middleware/types.ts'\nimport { DecoratorRegistry } from './plugin/decorators.ts'\nimport { HooksRegistry } from './plugin/hooks.ts'\nimport type {\n EagerDecorator,\n Hooks,\n LazyDecorator,\n IngeniumPlugin,\n PluginTarget,\n} from './plugin/types.ts'\nimport { RouteBuilder, Router, flattenRouter } from './router/router.ts'\nimport { ScopedApp } from './app/scope.ts'\nimport { registerAfter, registerBefore } from './sinatra/filters.ts'\nimport { EMPTY_PARAMS, RouterTrie, type MatchMiss } from './router/trie.ts'\nimport type { HttpMethod } from './router/types.ts'\nimport { NodeAdapter } from './transport/node.ts'\nimport type { ListeningServer, Transport } from './transport/types.ts'\nimport { descriptorKey, type RouteDescriptor } from './openapi/describe.ts'\nimport { isStandardSchema } from './schema/standard.ts'\nimport type { RequestBody, Response, Schema } from './openapi/types.ts'\nimport { QueueRegistry } from './jobs/registry.ts'\nimport type { JobHandle, QueueOptions, QueueWorker } from './jobs/types.ts'\nimport { CronRegistry } from './cron/registry.ts'\nimport type { CronHandler, CronOptions } from './cron/scheduler.ts'\n\n/** Options accepted by `ingenium(...)` and `new IngeniumApp(...)`. */\nexport interface IngeniumAppOptions {\n /** Max number of pooled `IngeniumContext` instances kept in the free list. Default 1024. */\n poolSize?: number\n /** Inject a custom transport (e.g. for tests). Default: `NodeAdapter`. */\n transport?: Transport\n /**\n * Trust-proxy configuration — controls whether `X-Forwarded-For`,\n * `X-Forwarded-Proto`, `X-Forwarded-Host` are honored when computing\n * `ctx.ip`, `ctx.protocol`, `ctx.hostname`. Mirrors Express's\n * `app.set('trust proxy', ...)` semantics. Default `false` (never trust).\n * See `proxy/trust.ts` for the full type. Set to `true` only when running\n * behind a reverse proxy you control.\n */\n trustProxy?: import('./proxy/trust.ts').TrustProxy\n /**\n * Maximum wall-clock time (ms) for a single request to complete from\n * dispatch to response. When exceeded, throws `IngeniumTimeoutError(503)`\n * and the response becomes 503 Service Unavailable.\n *\n * The handler that timed out is NOT cancelled — JavaScript can't safely\n * cancel a Promise. The framework just stops waiting for it; the in-flight\n * work continues until it naturally completes or the process exits. This\n * means a slow handler can still leak compute (but not connections or\n * pool slots, since the response is sent and the context is released).\n *\n * Scoped to HTTP request handling only — does NOT apply to upgraded\n * connections (WebSocket, SSE) which are explicitly long-lived.\n *\n * Default: undefined (no timeout). Production deploys SHOULD set this.\n */\n requestTimeoutMs?: number\n /**\n * Hard ceiling (bytes) on the total request body, enforced at the\n * transport layer — applies regardless of which `ctx.body.*` consumer\n * reads the body, including `ctx.body.stream()`. Defaults to **2 MiB**\n * (2_097_152) — high enough for typical JSON / form payloads,\n * low enough that an unauthenticated attacker can't exhaust memory.\n *\n * Per-call limits on `ctx.body.json(schema, maxBytes)` etc. are still\n * honored and apply WITHIN this ceiling. To allow larger uploads on a\n * specific route, raise this AND use `ctx.body.stream()` with your own\n * size accounting.\n *\n * Set to `Infinity` to disable (NOT recommended outside controlled deploys).\n */\n maxRequestBytes?: number\n\n /**\n * Default queue-drain timeout (ms) used when the listener closes. Per-queue\n * timeouts can also be passed to `app.queues.drainAll(timeoutMs)`. Default\n * `10_000`ms — matches `gracefulShutdown`'s default `gracefulTimeoutMs`.\n */\n queueDrainTimeoutMs?: number\n\n /**\n * Secret(s) used to HMAC-sign cookies written via\n * `ctx.cookies.set(name, value, { signed: true })`.\n *\n * Accepts a single string or an array — the FIRST entry signs new cookies,\n * ALL entries verify reads (so rotating a secret is: prepend the new key,\n * keep the old key, deploy; remove the old key on the next deploy once all\n * outstanding signed cookies have expired).\n *\n * If omitted, calling `ctx.cookies.set(..., { signed: true })` or\n * `ctx.cookies.get(..., { signed: true })` throws\n * `IngeniumError(500, 'COOKIE_SECRET_MISSING')`. The unsigned cookie API\n * still works without any secrets configured.\n */\n cookieSecrets?: string | string[]\n}\n\n/** Default transport-layer body ceiling — see {@link IngeniumAppOptions.maxRequestBytes}. */\nconst DEFAULT_MAX_REQUEST_BYTES = 2_097_152\n\n/** A user-supplied error handler. Return a non-error or call a `ctx` writer to recover. */\nexport type IngeniumErrorHandler = (err: unknown, ctx: IngeniumContext) => unknown | Promise<unknown>\n\n/**\n * Options for {@link IngeniumApp.inject} — the in-process test client. Mirrors\n * the shape a real request would carry, minus a socket. `url` is the only\n * required field; everything else defaults to a bare GET.\n */\nexport interface InjectRequest {\n /** HTTP method. Defaults to `GET`. */\n method?: HttpMethod\n /** Request URL including any query string (e.g. `/users/42?expand=posts`). */\n url: string\n /**\n * Request headers. Names are lowercased before they reach the handler so\n * `ctx.headers['x-custom']` works regardless of the casing passed here\n * (matching node:http's lowercasing of inbound headers).\n */\n headers?: Record<string, string | string[]>\n /**\n * Request body. A `string` / `Buffer` / `Uint8Array` is sent verbatim; a\n * plain object is JSON-serialized and (unless the caller set a\n * `content-type`) tagged `application/json`.\n */\n body?: string | Buffer | Uint8Array | Record<string, unknown> | unknown[]\n /** Socket peer address surfaced as `ctx.remoteAddress`. Defaults to `127.0.0.1`. */\n remoteAddress?: string\n}\n\n/**\n * Result of {@link IngeniumApp.inject}. A fully-materialized snapshot of the\n * response — captured BEFORE the pooled context is released, so reading any\n * field is safe even though the underlying context has been recycled.\n */\nexport interface InjectResponse {\n /** Final HTTP status code. */\n status: number\n /**\n * Response headers, lowercased. A deep-ish copy of the context's header bag\n * (the array values are cloned) so sequential `inject()` calls never share\n * or bleed header state.\n */\n headers: Record<string, string | string[]>\n /**\n * Response body decoded as a UTF-8 string. Stream responses are drained to\n * completion first; a bodyless response (`{ kind: 'none' }`) yields `''`.\n */\n body: string\n /** Parse {@link InjectResponse.body} as JSON. Throws on invalid JSON, like `JSON.parse`. */\n json<T = unknown>(): T\n}\n\n/**\n * Per-route options object accepted as the second positional arg to a verb\n * registration (`app.get(path, { auth: ['admin'] }, handler)`). Each key must\n * match a registered declarator (see `app.declare(...)`); the value is passed\n * to the declarator's factory at REGISTRATION time and the resulting\n * middleware is prepended to the route's chain.\n */\nexport type RouteOptions = Record<string, unknown>\n\n/**\n * Well-known route-options keys handled natively by the framework. Mixed with\n * user-defined declarator keys in the same options object — the framework\n * peels off the well-known ones at REGISTRATION time, hands them straight to\n * `app.describe(method, path, ...)`, and forwards everything else to\n * `translateRouteOptions()` for declarator resolution. Built-in keys never\n * trigger the \"unknown declarator\" error because they're removed from the\n * forwarded options before declarator lookup runs.\n *\n * Inline schema values for `response` / `requestBody` accept ONLY raw OpenAPI\n * Schema objects today. Passing a Standard Schema or Zod validator throws at\n * registration time — converting validators to JSON Schema is the OpenAPI\n * generator's job and isn't wired through this seam yet. Use\n * `app.describe(method, path, ...)` with a precomputed schema if you need\n * that today.\n */\nconst BUILTIN_ROUTE_OPTION_KEYS: ReadonlySet<string> = new Set([\n 'response',\n 'requestBody',\n 'tags',\n 'summary',\n 'description',\n 'parameters',\n 'deprecated',\n 'operationId',\n 'security',\n])\n\n/**\n * Variadic arg shape accepted by `app.get/post/...` and `app.method(...)` after\n * the leading `(method?, path)`. The tail is always one handler; everything\n * before it is either positional middleware or the (optional) leading options\n * object. We type it as `unknown[]` at the implementation seam because TS\n * tuple-rest narrowing fights with the overload's union return type — the\n * runtime validates structure (handler-is-function tail, plain-object head\n * detection, function middleware) and the public overloads enforce the shape\n * the caller actually sees.\n */\nexport type VerbArgs = unknown[]\n\n/**\n * The Ingenium application. Combines a `Router` (registration journal),\n * a `RouterTrie` (matched at request time), a context pool, and a\n * transport. Composition is lazy: the trie's composed handlers are built\n * on first request (or when `compose()` is called explicitly), and a dirty\n * bit triggers recomposition if registrations are added later.\n */\nexport class IngeniumApp implements PluginTarget {\n private readonly pool: IngeniumContextPool\n private readonly transport: Transport\n private readonly router: Router = new Router()\n private trie: RouterTrie = new RouterTrie()\n private dirty = true\n private errorHandler: IngeniumErrorHandler | null = null\n private readonly _hooks: HooksRegistry = new HooksRegistry()\n private readonly _decorators: DecoratorRegistry = new DecoratorRegistry()\n /** @internal Per-route OpenAPI metadata. Keyed by `${method} ${path}`. */\n private readonly _routeDescriptors: Map<string, RouteDescriptor> = new Map()\n /** @internal Bumped on every `describe()` call so the OpenAPI handler's cache invalidates. */\n private _routeDescriptorVersion = 0\n /** @internal Carried onto each `IngeniumContext` so its `ip`/`protocol`/`hostname` getters can resolve. */\n private readonly _trustProxy: import('./proxy/trust.ts').TrustProxy\n /** @internal Wall-clock per-request ceiling. `undefined` disables the race entirely. */\n private readonly _requestTimeoutMs: number | undefined\n /**\n * @internal Hard transport-layer ceiling on request body bytes. Passed to\n * the transport via `TransportHooks.maxRequestBytes`. `Infinity` disables.\n */\n private readonly _maxRequestBytes: number\n /** @internal Background job registry. Workers start at compose() / first request. */\n private readonly _queues: QueueRegistry = new QueueRegistry()\n /** @internal Cron job registry. Timers start at compose() / first request. */\n private readonly _crons: CronRegistry = new CronRegistry()\n /** @internal Default queue-drain timeout used when the listener closes. */\n private readonly _queueDrainTimeoutMs: number\n /**\n * @internal Frozen list of cookie-signing secrets, normalized from the\n * scalar/array input. Empty array when not configured. Stamped onto each\n * dispatched context only when non-empty (per-request field write avoided\n * for the common case of \"no cookie secrets configured\").\n */\n private readonly _cookieSecrets: readonly string[]\n /** @internal Whether `cookieSecrets` was configured — caches the truthy check. */\n private readonly _hasCookieSecrets: boolean\n\n /**\n * @internal Per-request dispatch booleans, recomputed at every `compose()`.\n * Cached because their underlying `.hasAny()` / `.hasOnXxx()` calls walk\n * arrays and we don't want to pay that on every request — the registries\n * are frozen between composes.\n *\n * `_handleFast` is the hot-path closure: when ALL of these are off\n * (`!_hasHooks && !_hasDecorators && !_hasTimeout && !_hasTrustProxy`)\n * we route through a stripped dispatch that skips every conditional.\n */\n private _hasHooks = false\n private _hasOnRequest = false\n private _hasOnResponse = false\n private _hasOnError = false\n private _hasDecorators = false\n private readonly _hasTimeout: boolean\n private readonly _hasTrustProxy: boolean\n private _useFastPath = false\n\n /**\n * @internal Whether `listen()` has bound a server that hasn't been closed\n * yet. Guards against the double-listen footgun: a second `listen()` on the\n * same app would silently bind a second server (two ports dispatching to one\n * pool), almost always a copy-paste mistake. Cleared when the returned\n * handle's `close()` resolves, so re-listening after a clean shutdown works.\n */\n private _listening = false\n\n constructor(options: IngeniumAppOptions = {}) {\n this.pool = new IngeniumContextPool(options.poolSize ?? 1024)\n this.transport = options.transport ?? new NodeAdapter()\n this._trustProxy = options.trustProxy ?? false\n this._requestTimeoutMs = options.requestTimeoutMs\n this._maxRequestBytes = options.maxRequestBytes ?? DEFAULT_MAX_REQUEST_BYTES\n this._queueDrainTimeoutMs = options.queueDrainTimeoutMs ?? 10_000\n // Normalize scalar/array secret input into a frozen list. Frozen because\n // the array reference is shared across every request — accidental mutation\n // anywhere would silently change the verify set for the whole app.\n const rawSecrets = options.cookieSecrets\n this._cookieSecrets = Object.freeze(\n rawSecrets === undefined\n ? []\n : Array.isArray(rawSecrets)\n ? rawSecrets.slice()\n : [rawSecrets],\n )\n this._hasCookieSecrets = this._cookieSecrets.length > 0\n // These two are stable for the lifetime of the app.\n this._hasTimeout = options.requestTimeoutMs !== undefined\n this._hasTrustProxy = (options.trustProxy ?? false) !== false\n\n // Wire `ctx.queue(name)` as a lazy decorator. Returns a per-call handle\n // that delegates straight to the registry. Lazy = zero overhead for\n // routes that don't enqueue background work.\n this._decorators.decorate('queue', (_ctx) => {\n return <TData = unknown>(name: string): JobHandle<TData> => {\n const q = this._queues.get<TData>(name)\n return { add: (data: TData) => q.add(data) }\n }\n })\n }\n\n /**\n * @internal Recompute the cached dispatch booleans. Called at the end of\n * `compose()` (and `composeAsync()`) so per-request reads are O(1) field\n * loads instead of `.hasAny()` array scans.\n *\n * The fast path is taken when an app uses zero opt-in features beyond the\n * router itself: no plugins, no decorators, no request timeout, no\n * trust-proxy. That's the typical \"Sinatra-shape\" / \"Express-shape\"\n * register-routes-and-go app — the case we want to be the absolute fastest.\n * Note `ctx.queue` registers a decorator at construction, so any app that\n * uses background jobs is OFF the fast path. That's the correct semantics:\n * if you want the queue ergonomic, you accept the per-request decorator\n * apply cost.\n */\n private _recomputeDispatchFlags(): void {\n this._hasHooks = this._hooks.hasAny()\n this._hasOnRequest = this._hasHooks && this._hooks.hasOnRequest()\n this._hasOnResponse = this._hasHooks && this._hooks.hasOnResponse()\n this._hasOnError = this._hasHooks && this._hooks.hasOnError()\n this._hasDecorators = this._decorators.hasAny()\n this._useFastPath =\n !this._hasHooks &&\n !this._hasDecorators &&\n !this._hasTimeout &&\n !this._hasTrustProxy\n }\n\n // ───── Plugin system ────────────────────────────────────────────────────\n\n /** Lifecycle hooks API — plugins call `app.hooks.onRequest(...)` etc. */\n get hooks(): Hooks { return this._hooks }\n\n /**\n * Register a plugin. Plugins are invoked immediately and may be async;\n * callers should `await app.register(...)` if the plugin returns a Promise.\n * Plugins must be registered BEFORE `compose()` runs (i.e. before the\n * first request); registering a plugin sets the dirty bit so the next\n * request will recompose.\n */\n register<O>(plugin: IngeniumPlugin<O>, opts: O): Promise<this>\n register(plugin: IngeniumPlugin<void>): Promise<this>\n async register<O>(plugin: IngeniumPlugin<O>, opts?: O): Promise<this> {\n await plugin(this, opts as O)\n this.dirty = true\n return this\n }\n\n /**\n * Open a registration scope rooted at `prefix`. Routes, middleware, and\n * sub-plugins registered through the `scope` parameter inside `registrar`\n * are automatically prefix-qualified, so a plugin's `use(mw)` only applies\n * to requests under `prefix` — not the whole app.\n *\n * This is the killer feature for sub-app affinity: today, plugins registered\n * via `app.register(...)` decorate the WHOLE app (their `app.use(mw)` calls\n * become global). Wrapping a `register(...)` call inside `app.scope(...)`\n * confines the plugin's middleware to the scope's subtree, without forcing\n * the user to manually prefix every route.\n *\n * The actual prefix-matching happens at compose time: scope translates\n * `s.use(mw)` into `app.use(prefix, mw)` on the underlying router, which\n * the existing `flattenRouter` / `RouterTrie` machinery already handles.\n * Per-request dispatch sees no new work.\n *\n * @example\n * app.scope('/api/v2', (s) => {\n * s.use(authPlugin) // only runs for /api/v2/*\n * s.get('/users', listUsers) // registers at /api/v2/users\n * })\n *\n * Nested scopes compose:\n *\n * @example\n * app.scope('/api', (s) => {\n * s.scope('/v2', (s2) => {\n * s2.get('/users', listUsers) // /api/v2/users\n * })\n * })\n *\n * # Caveat — decorators (V1)\n *\n * `scope.decorate(...)` decorates EVERY request, not just requests under\n * `prefix`. Decorators install onto the pooled context at request start,\n * before the route is matched. The first call from inside any scope emits\n * a `process.emitWarning` in non-production environments to surface this.\n * See `ScopedApp` for details.\n *\n * @returns `this` for chaining. If `registrar` is async, the returned\n * promise is NOT awaited — callers who need async plugin registration\n * inside a scope should await the `registrar` themselves (or use\n * `scope.register(asyncPlugin)`, which returns a Promise).\n */\n scope(\n prefix: string,\n registrar: (scope: PluginTarget) => void,\n ): this {\n const scoped = new ScopedApp(this, prefix)\n // Return is typed `void` so concise chainable arrows (`s => s.get(...)`)\n // and async registrars both satisfy the signature; we still thenable-check\n // the actual value to re-mark dirty if it resolves later.\n const ret: unknown = registrar(scoped as unknown as PluginTarget)\n // If the registrar is async, it's the caller's responsibility to await it\n // (e.g. by awaiting `scope.register(asyncPlugin)` inside the body). We\n // still mark dirty eagerly so synchronous registrations recompose next.\n // Async paths additionally re-mark dirty when they resolve, just in case.\n if (ret && typeof (ret as Promise<void>).then === 'function') {\n ;(ret as Promise<void>).then(() => {\n this.dirty = true\n })\n }\n this.dirty = true\n return this\n }\n\n /**\n * @internal Mark the compose-cache dirty. Used by `ScopedApp` to invalidate\n * after registering routes/middleware/plugins inside a scope. External\n * callers should not depend on this — it's a friend-access seam for the\n * scope facade.\n */\n _markDirty(): void {\n this.dirty = true\n }\n\n /**\n * Add a lazy decorator. The factory is invoked the first time `ctx[name]`\n * is read; the result is cached on the context for the rest of the request.\n *\n * @example\n * app.decorate('user', async (ctx) => loadUser(ctx.headers.authorization))\n */\n decorate<T>(name: string, factory: LazyDecorator<T>): this {\n this._decorators.decorate(name, factory)\n return this\n }\n\n /**\n * Add an eager decorator. The factory runs at the start of every request,\n * and the value is assigned directly to the context.\n *\n * @example\n * app.decorateRequest('startedAt', () => Date.now())\n */\n decorateRequest<T>(name: string, factory: EagerDecorator<T>): this {\n this._decorators.decorateRequest(name, factory)\n return this\n }\n\n // ───── Registration (delegates to the inner Router) ─────────────────────\n\n use(mw: IngeniumMiddleware): this\n use(prefix: string, mw: IngeniumMiddleware | Router): this\n use(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware | Router): this {\n if (typeof arg1 === 'string') {\n // Overload preserved by passing both args verbatim.\n this.router.use(arg1, arg2 as IngeniumMiddleware | Router)\n } else {\n this.router.use(arg1)\n }\n this.dirty = true\n return this\n }\n\n // ───── Verb registration ──────────────────────────────────────────────\n // Three accepted shapes per verb:\n // 1. (path, handler) — back-compat single arg\n // 2. (path, ...inlineMiddleware, handler) — Express positional mw\n // 3. (path, optionsObject, ...inlineMw, handler) — declarative middleware\n // (see app.declare())\n // Detection of shape (3) is by `isPlainOptionsObject(args[0])` — see the\n // helper for the exact prototype-check rule. Translation from declarative\n // options → middleware happens at REGISTRATION time, not request time, so\n // the per-request hot path has zero declarative-middleware overhead.\n\n get(path: string, handler: IngeniumHandler): this\n get(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n get(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('GET', path, ...args)\n }\n\n post(path: string, handler: IngeniumHandler): this\n post(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n post(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('POST', path, ...args)\n }\n\n put(path: string, handler: IngeniumHandler): this\n put(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n put(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('PUT', path, ...args)\n }\n\n patch(path: string, handler: IngeniumHandler): this\n patch(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n patch(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('PATCH', path, ...args)\n }\n\n delete(path: string, handler: IngeniumHandler): this\n delete(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n delete(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('DELETE', path, ...args)\n }\n\n head(path: string, handler: IngeniumHandler): this\n head(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n head(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('HEAD', path, ...args)\n }\n\n options(path: string, handler: IngeniumHandler): this\n options(\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n options(path: string, ...args: VerbArgs): this {\n return (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)('OPTIONS', path, ...args)\n }\n\n /**\n * Chainable per-path registration. Returns a `RouteBuilder` that stacks\n * verb registrations on the same path without retyping it:\n *\n * @example\n * app\n * .route('/users/:id')\n * .get((ctx) => loadUser(ctx.params.id))\n * .put(requireAdmin, (ctx) => updateUser(ctx))\n * .delete(requireAdmin, (ctx) => deleteUser(ctx))\n *\n * Pure registration sugar — every call delegates to `app.method(...)`, so\n * declarative options, inline middleware, and typed params via\n * `ExtractParams<P>` work exactly as they do on the bare verb form.\n */\n route<P extends string>(path: P): RouteBuilder<P> {\n return new RouteBuilder<P>((method, args) =>\n (this.method as (m: HttpMethod, p: string, ...a: VerbArgs) => this)(method, path, ...(args as VerbArgs)),\n )\n }\n\n /**\n * Register a route under any HTTP method. Accepts the variadic shape with\n * an optional declarative-options object as the first arg (after `path`).\n */\n method(method: HttpMethod, path: string, handler: IngeniumHandler): this\n method(\n method: HttpMethod,\n path: string,\n optsOrFirst: RouteOptions | IngeniumMiddleware,\n ...rest: [...IngeniumMiddleware[], IngeniumHandler]\n ): this\n method(method: HttpMethod, path: string, ...args: VerbArgs): this {\n if (args.length === 0) {\n throw new TypeError(`IngeniumApp.${method.toLowerCase()}('${path}'): handler is required`)\n }\n // Translate the optional declarative-options object (when present in\n // position 0) into prepended middleware. The remaining args are passed\n // through to the inner Router as plain positional middleware + handler.\n let translatedHead: IngeniumMiddleware[] = []\n let tail: unknown[] = args\n if (isPlainOptionsObject(args[0])) {\n const opts = args[0] as RouteOptions\n // Peel off well-known OpenAPI keys → describe() at registration time.\n // Forward everything else through the declarator pipeline. Splitting\n // the bag in two means a single options object can legally mix\n // built-in keys (`tags`, `summary`, ...) with user declarator keys\n // (`auth`, `rateLimit`, ...) without the latter tripping over the\n // former or vice versa.\n const builtins: Record<string, unknown> = {}\n const userOpts: RouteOptions = {}\n let hasBuiltins = false\n let hasUser = false\n for (const key of Object.keys(opts)) {\n if (BUILTIN_ROUTE_OPTION_KEYS.has(key)) {\n builtins[key] = opts[key]\n hasBuiltins = true\n } else {\n userOpts[key] = opts[key]\n hasUser = true\n }\n }\n if (hasBuiltins) {\n const descriptor = buildDescriptorFromBuiltins(method, path, builtins)\n this.describe(method, path, descriptor)\n }\n if (hasUser) {\n translatedHead = this.translateRouteOptions(method, path, userOpts)\n }\n tail = args.slice(1)\n }\n if (tail.length === 0) {\n throw new TypeError(`IngeniumApp.${method.toLowerCase()}('${path}'): handler is required`)\n }\n // Pass through to Router. The Router validates handler-is-function and\n // each inline middleware-is-function — we don't duplicate those checks.\n this.router.method(\n method,\n path,\n ...(translatedHead.concat(tail as IngeniumMiddleware[]) as [...IngeniumMiddleware[], IngeniumHandler]),\n )\n this.dirty = true\n return this\n }\n\n // ───── Declarative middleware (per-route via options object) ───────────\n\n /**\n * @internal Registry of declarators. Looked up at REGISTRATION time, not\n * request time — so unknown-declarator errors fire eagerly and the per-\n * request hot path stays clean.\n */\n private readonly _declarators: Map<string, (opts: unknown) => IngeniumMiddleware> = new Map()\n\n /**\n * Register a declarator: a name → middleware-factory mapping. When a route\n * registration includes an options object with that name as a key, the value\n * is passed to the factory and the resulting middleware is composed into\n * the route's chain (in the same position as positional inline middleware,\n * but BEFORE any positional middleware on the same call).\n *\n * Declarators are global to the app and survive across all subsequent route\n * registrations until overridden by a second `declare(name, ...)` call.\n * Lookup is REGISTRATION-time: a route registered before the matching\n * `declare(...)` call throws at registration with a clear hint, not at\n * request time. This trades flexibility for debuggability — the error is\n * caught at boot, not under load.\n *\n * @example\n * app.declare('auth', (roles: string[]) => requireRoles(roles))\n * app.declare('rateLimit', (spec: string) => parseRateLimitSpec(spec))\n * app.get('/admin', { auth: ['admin'], rateLimit: '10/min' }, handler)\n */\n declare<O>(name: string, factory: (opts: O) => IngeniumMiddleware): this {\n this._declarators.set(name, factory as (opts: unknown) => IngeniumMiddleware)\n return this\n }\n\n /**\n * @internal Resolve a route's options object into a list of middleware by\n * looking up each key in the declarator registry. Iterates keys in object\n * insertion order (ES2015+ guarantee for string keys). Throws at REG TIME\n * with a contextual message when a key has no registered declarator.\n */\n private translateRouteOptions(\n method: HttpMethod,\n path: string,\n opts: RouteOptions,\n ): IngeniumMiddleware[] {\n const out: IngeniumMiddleware[] = []\n for (const key of Object.keys(opts)) {\n const factory = this._declarators.get(key)\n if (!factory) {\n throw new Error(\n `app.${method.toLowerCase()}('${path}', { ${key}: ... }, ...): unknown declarator '${key}'. ` +\n `Did you forget to call app.declare('${key}', ...)?`,\n )\n }\n out.push(factory(opts[key]))\n }\n return out\n }\n\n /** Register a global error handler. Re-throw to delegate to the default boundary. */\n onError(handler: IngeniumErrorHandler): this {\n this.errorHandler = handler\n return this\n }\n\n // ───── Sinatra-style filters ───────────────────────────────────────────────\n\n /**\n * Register a `before` filter — runs BEFORE the route handler resolves.\n * The user writes only the body; `await next()` is called automatically\n * after it returns. If the body writes a response (e.g. `ctx.json(...)`)\n * the chain short-circuits and the route handler does not run.\n *\n * - `before(handler)` — runs for every request (global).\n * - `before(pattern, handler)` — boundary-respecting prefix match\n * (`/admin/*` and `/admin` both match `/admin` and `/admin/x`, neither\n * matches `/administrator`). See `sinatra/filters.ts` for details.\n */\n before(handler: IngeniumMiddleware): this\n before(pattern: string, handler: IngeniumMiddleware): this\n before(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware): this {\n if (typeof arg1 === 'string') registerBefore(this, arg1, arg2 as IngeniumMiddleware)\n else registerBefore(this, arg1)\n return this\n }\n\n /**\n * Register an `after` filter — runs AFTER the route handler resolves but\n * BEFORE the adapter writes the response to the wire. The filter sees the\n * final ctx state (status, headers, body buffer) and may inspect or\n * augment it. Errors thrown by the filter propagate to the error boundary.\n *\n * - `after(handler)` — runs for every request (global).\n * - `after(pattern, handler)` — same prefix semantics as `before`.\n */\n after(handler: IngeniumMiddleware): this\n after(pattern: string, handler: IngeniumMiddleware): this\n after(arg1: string | IngeniumMiddleware, arg2?: IngeniumMiddleware): this {\n if (typeof arg1 === 'string') registerAfter(this, arg1, arg2 as IngeniumMiddleware)\n else registerAfter(this, arg1)\n return this\n }\n\n /**\n * Attach OpenAPI metadata to a route. The route must be registered separately\n * via `app.get/post/...`. Multiple calls MERGE shallowly onto the existing\n * descriptor for the same `(method, path)` pair — later keys overwrite\n * earlier ones, but keys absent from `meta` are preserved. This is what lets\n * the inline-options form (`app.get(p, { tags: [...] }, h)`) coexist with a\n * later explicit `app.describe(method, p, { summary })` without one wiping\n * the other. Reads via `generateOpenApi(app)`.\n */\n describe(method: HttpMethod, path: string, meta: RouteDescriptor): this {\n const key = descriptorKey(method, path)\n const existing = this._routeDescriptors.get(key)\n const merged: RouteDescriptor = existing ? { ...existing, ...meta } : meta\n this._routeDescriptors.set(key, merged)\n this._routeDescriptorVersion++\n return this\n }\n\n /** @internal Read-only view of route descriptors — used by the OpenAPI generator. */\n get routeDescriptors(): ReadonlyMap<string, RouteDescriptor> {\n return this._routeDescriptors\n }\n\n /** @internal Bumps on every `describe()` call so the OpenAPI handler can cache-bust. */\n get routeDescriptorVersion(): number {\n return this._routeDescriptorVersion\n }\n\n /** @internal Read-only view of the registration journal — used by the OpenAPI generator. */\n get routerJournal(): Router {\n return this.router\n }\n\n // ───── Background jobs + cron ───────────────────────────────────────────\n\n /**\n * Register a background queue with a worker. The worker pool starts when\n * the app is composed (first request, `app.compose()`, or `app.listen()`).\n *\n * @example\n * app.queue<{ to: string; body: string }>('emails',\n * { concurrency: 4, retries: 5 },\n * async (job) => sendEmail(job.data),\n * )\n *\n * // From a route handler:\n * app.post('/signup', async (ctx) => {\n * const u = await createUser(await ctx.body.json())\n * await ctx.queue('emails').add({ to: u.email, body: 'Welcome!' })\n * return { ok: true }\n * })\n */\n queue<TData>(name: string, opts: QueueOptions<TData>, worker: QueueWorker<TData>): this\n queue<TData>(name: string, worker: QueueWorker<TData>): this\n queue<TData>(\n name: string,\n optsOrWorker: QueueOptions<TData> | QueueWorker<TData>,\n maybeWorker?: QueueWorker<TData>,\n ): this {\n const opts: QueueOptions<TData> = typeof optsOrWorker === 'function' ? {} : optsOrWorker\n const worker: QueueWorker<TData> =\n typeof optsOrWorker === 'function' ? optsOrWorker : (maybeWorker as QueueWorker<TData>)\n if (typeof worker !== 'function') {\n throw new TypeError(`ingenium: app.queue(\"${name}\", ...) requires a worker function`)\n }\n this._queues.register<TData>(name, opts, worker)\n this.dirty = true\n return this\n }\n\n /**\n * Register a cron job. Spec is a 5-field crontab string. See\n * `src/cron/parser.ts` for the supported grammar.\n *\n * @example\n * app.cron('0 *\\/15 * * *', () => refreshCaches()) // every 15 min\n * app.cron('0 0 * * 0', { timezone: 'America/Los_Angeles' }, weeklyReport)\n */\n cron(spec: string, handler: CronHandler): this\n cron(spec: string, opts: CronOptions, handler: CronHandler): this\n cron(\n spec: string,\n optsOrHandler: CronOptions | CronHandler,\n maybeHandler?: CronHandler,\n ): this {\n const opts: CronOptions = typeof optsOrHandler === 'function' ? {} : optsOrHandler\n const handler: CronHandler =\n typeof optsOrHandler === 'function' ? optsOrHandler : (maybeHandler as CronHandler)\n if (typeof handler !== 'function') {\n throw new TypeError('ingenium: app.cron(spec, ..., handler) requires a handler function')\n }\n this._crons.register(spec, opts, handler)\n this.dirty = true\n return this\n }\n\n /** @internal Read-only access to the queue registry for ops/test introspection. */\n get queues(): QueueRegistry { return this._queues }\n /** @internal Read-only access to the cron registry for ops/test introspection. */\n get crons(): CronRegistry { return this._crons }\n\n // ───── Composition ───────────────────────────────────────────────────────\n\n /**\n * Walk the registration journal and rebuild the trie with composed\n * handlers at every leaf. Auto-runs on first request; safe to call\n * explicitly to pre-warm.\n */\n /** Cached flat registrations — used to build the on-miss fallback chain. */\n private _flat: ReturnType<typeof flattenRouter> | null = null\n\n compose(): void {\n // Note: this entry is synchronous. Async `onCompose` hooks are awaited\n // by `composeAsync()` (the path used by `handle()` and `listen()`).\n // Calling `compose()` directly skips `onCompose` — pre-warm only.\n const flat = flattenRouter(this.router)\n const trie = new RouterTrie()\n const hasOnRoute = this._hooks.hasOnRoute()\n\n for (const route of flat.routes) {\n const node = trie.insert(route.path)\n\n // Determine which middleware applies to this route's path.\n const applicable: IngeniumMiddleware[] = [...flat.globalMiddleware]\n for (const scoped of flat.scopedMiddleware) {\n if (pathStartsWith(route.path, scoped.prefix)) {\n applicable.push(scoped.mw)\n }\n }\n\n // Splice inline middleware (positional + declarative-translated) AFTER\n // global + scoped middleware AND BEFORE the terminal handler. This\n // matches Express's positional-mw semantics and is the foundation\n // `app.declare()` builds on.\n if (route.inlineMiddleware && route.inlineMiddleware.length > 0) {\n for (const mw of route.inlineMiddleware) applicable.push(mw)\n }\n\n const composed = composeWithHandler(applicable, route.handler)\n node.handlers[route.method] = composed\n\n if (hasOnRoute) {\n this._hooks.runOnRoute({ method: route.method, path: route.path })\n }\n }\n\n this.trie = trie\n this._flat = flat\n this.dirty = false\n\n // Start cron timers + queue worker pools at compose time so they don't\n // process work before the app is wired up. Both `startAll` calls are\n // idempotent — safe to run on every recompose triggered by the dirty bit.\n this._crons.startAll()\n this._queues.startAll()\n\n // Cache dispatch booleans so handle() can branch on field reads instead\n // of `.hasAny()` calls. Re-runs on every recompose because plugins can\n // be `register()`'d after listen().\n this._recomputeDispatchFlags()\n }\n\n /**\n * Async composition entry — runs `onCompose` hooks first, then composes.\n * Used by `handle()` and `listen()` when there are async pre-compose\n * listeners. Sync-only composition still works via `compose()` above.\n */\n private async composeAsync(): Promise<void> {\n if (this._hooks.hasOnCompose()) {\n await this._hooks.runOnCompose()\n }\n this.compose()\n }\n\n // ───── Dispatch entry point (used by transports and tests) ───────────────\n\n /**\n * Dispatch a single context through the framework. Handles route lookup,\n * 404/405 generation, and the error boundary. The transport is responsible\n * for populating the request side of the context and writing the response\n * side after this resolves.\n */\n async handle(ctx: IngeniumContext): Promise<void> {\n if (this.dirty) await this.composeAsync()\n\n // Back-reference so app-aware handlers (e.g. openapiHandler) can reach\n // the app from inside a route handler. ctx.state is reset per request\n // by the pool, so this doesn't leak between requests.\n ctx.state._ingeniumApp = this\n\n // Stamp cookie secrets ONLY when configured. Same pattern as `_trustProxy`:\n // apps that don't use signed cookies pay zero (the field load on the ctx\n // returns the default empty-array initialised at class-field stamp time).\n // We don't reset this between requests because it's app-wide config — the\n // reassignment is idempotent against the same frozen array reference.\n if (this._hasCookieSecrets) ctx._cookieSecrets = this._cookieSecrets\n\n // ───── Fast path ─────────────────────────────────────────────────────\n // Apps with no plugins, no decorators, no timeout, and no trust-proxy\n // skip the entire branch ladder below. This is the typical Sinatra-shape\n // app — register routes, listen, done. Bench impact: meaningfully better\n // hello-rps because we don't pay for features the app doesn't use.\n if (this._useFastPath) {\n try {\n const match = this.trie.find(ctx.method, ctx.path)\n if ('handler' in match) {\n if (match.params !== EMPTY_PARAMS) ctx.params = match.params as never\n await match.handler(ctx)\n return\n }\n await this.runFallback(ctx, missToError(match))\n } catch (err) {\n await this.handleError(err, ctx)\n }\n return\n }\n\n // ───── Full path (plugins / decorators / timeout / trust-proxy on) ──\n // Stamp trust-proxy config so ctx.ip/protocol/hostname resolve correctly.\n if (this._hasTrustProxy) ctx._trustProxy = this._trustProxy\n\n // All booleans below are pre-computed at compose() time — no per-request\n // `.hasAny()` array scans. See `_recomputeDispatchFlags`.\n const hooks = this._hooks\n const decorators = this._decorators\n\n try {\n if (this._hasOnRequest) {\n await hooks.runOnRequest(ctx)\n }\n if (this._hasDecorators) {\n decorators.applyTo(ctx)\n }\n\n const match = this.trie.find(ctx.method, ctx.path)\n if ('handler' in match) {\n // Only assign params when the route actually has them — otherwise\n // ctx.params already points at the frozen empty sentinel from reset.\n if (match.params !== EMPTY_PARAMS) {\n ctx.params = match.params as never\n }\n // Wrap the dispatch in a wall-clock race AND a closure-bound\n // late-write guard on the response writers. The race is HTTP-\n // request-scoped only — WS / SSE upgrades bypass this path because\n // they're dispatched through their own adapters and never resolve\n // back to a normal HTTP response. See `withEpochGuard` for the\n // mechanism that prevents orphaned handlers from corrupting the\n // next request bound to this same pooled context instance.\n if (this._hasTimeout) {\n await withEpochGuard(ctx, this._requestTimeoutMs as number, () => match.handler(ctx))\n } else {\n await match.handler(ctx)\n }\n\n if (this._hasOnResponse) {\n await hooks.runOnResponse(ctx)\n }\n return\n }\n // Miss — but middleware that mounts a path-handler (e.g. `ingenium.static()`)\n // expects to run on requests that don't match a registered route. Build a\n // fall-through chain from any global + mount-prefix-matching middleware\n // and let it have a shot. If it writes the response, we're done; if it\n // calls next() or doesn't write, we surface the original 404/405.\n await this.runFallback(ctx, missToError(match))\n if (this._hasOnResponse) {\n await hooks.runOnResponse(ctx)\n }\n } catch (err) {\n // Observation hook fires BEFORE the error boundary writes a response.\n // The boundary still owns the actual response — these hooks cannot\n // swallow or replace the error.\n if (this._hasOnError) {\n await hooks.runOnError(err, ctx)\n }\n await this.handleError(err, ctx)\n }\n }\n\n /**\n * Run global + path-matching scoped middleware as a fallback chain when the\n * trie has no matching route. The terminal handler re-throws the original\n * trie miss so the error boundary still produces 404/405 if no middleware\n * wrote the response. Composed per-request — misses are exceptional.\n */\n private async runFallback(ctx: IngeniumContext, miss: IngeniumError): Promise<void> {\n const flat = this._flat\n if (!flat) {\n throw miss\n }\n const applicable: IngeniumMiddleware[] = [...flat.globalMiddleware]\n for (const scoped of flat.scopedMiddleware) {\n if (pathStartsWith(ctx.path, scoped.prefix)) applicable.push(scoped.mw)\n }\n if (applicable.length === 0) {\n throw miss\n }\n // No-op terminal — let middleware finish completely (including post-next\n // hooks). If nothing wrote a response, surface the trie miss as a 404/405.\n const chain = composeWithHandler(applicable, () => {})\n await chain(ctx)\n if (!ctx._written) throw miss\n }\n\n private async handleError(err: unknown, ctx: IngeniumContext): Promise<void> {\n // Reset response state in case a partial helper had been called.\n if (this.errorHandler) {\n try {\n await this.errorHandler(err, ctx)\n return\n } catch (rethrow) {\n err = rethrow\n }\n }\n writeDefaultError(err, ctx)\n }\n\n // ───── In-process test client ──────────────────────────────────────────\n\n /**\n * Dispatch a synthetic request through the SAME path as the wire — no\n * socket, no transport. Acquires a pooled context, populates it exactly as\n * the Node adapter would from an `IncomingMessage`, runs `handle()` (so\n * routing, 404/405, middleware, hooks, and the error boundary all behave\n * identically), then materializes the response into a plain {@link InjectResponse}.\n *\n * Crucially the context is extracted FULLY and only THEN released back to\n * the pool: releasing bumps `_epoch` and reassigns `_headers`/`_body`, so\n * reading them after release would surface the next request's state (or\n * empty). The returned object holds copies, so it survives the recycle and\n * sequential `inject()` calls never bleed header/body state into each other.\n *\n * @example\n * const res = await app.inject({ method: 'POST', url: '/users', body: { name: 'a' } })\n * expect(res.status).toBe(201)\n * expect(res.json<{ id: string }>().id).toBeDefined()\n */\n async inject(opts: InjectRequest): Promise<InjectResponse> {\n if (this.dirty) await this.composeAsync()\n\n const ctx = this.pool.acquire()\n try {\n populateInjectContext(ctx, opts)\n await this.handle(ctx)\n // Extract EVERYTHING before release — see the doc comment above.\n return await extractInjectResponse(ctx)\n } finally {\n this.pool.release(ctx)\n }\n }\n\n // ───── Transport ─────────────────────────────────────────────────────────\n\n /** Bind a port and accept requests. Returns a handle for graceful shutdown. */\n async listen(port: number, host?: string): Promise<ListeningServer> {\n // Double-listen guard. Binding a second server to the same app means two\n // ports feeding one context pool — almost always a copy-paste bug. Throw a\n // clear TypeError instead of silently double-binding. Re-listening after a\n // clean `close()` is allowed (the flag is cleared there).\n if (this._listening) {\n throw new TypeError(\n 'ingenium: app.listen() called while already listening. Call close() on the ' +\n 'returned server handle before listening again, or create a separate app.',\n )\n }\n if (this.dirty) await this.composeAsync()\n this.transport.attach({\n acquire: () => this.pool.acquire(),\n release: (ctx) => this.pool.release(ctx),\n dispatch: (ctx) => this.handle(ctx),\n maxRequestBytes: this._maxRequestBytes,\n })\n const handle = host !== undefined\n ? await this.transport.listen(port, host)\n : await this.transport.listen(port)\n\n // Mark listening only AFTER the bind succeeds — a failed bind (e.g. port\n // in use) leaves the app re-listenable.\n this._listening = true\n\n // Wrap the underlying close so cron timers + queue worker pools are torn\n // down as part of graceful shutdown. Sockets and queues drain in parallel\n // (wall-clock bounded by max(socket-drain, queue-drain), not their sum).\n const drainTimeout = this._queueDrainTimeoutMs\n const queues = this._queues\n const crons = this._crons\n const wrappedClose: ListeningServer['close'] = async (closeOpts) => {\n // Allow a fresh listen() once shutdown begins. Cleared before the await\n // so a re-listen racing the drain still binds (the old server is already\n // refusing new connections via server.close()).\n this._listening = false\n // Stop cron tickers FIRST so they don't enqueue new work mid-shutdown.\n crons.stopAll()\n const queueDrain = queues.drainAll(drainTimeout)\n const socketClose = handle.close(closeOpts)\n const [, drainResult] = await Promise.all([socketClose, queueDrain])\n if (drainResult.timedOut.length > 0) {\n try {\n process.emitWarning(\n `ingenium: queues did not drain within ${drainTimeout}ms: ${drainResult.timedOut.join(', ')}`,\n { type: 'IngeniumQueueDrainWarning' },\n )\n } catch {\n /* worker contexts may throw on emitWarning */\n }\n }\n }\n return { ...handle, close: wrappedClose }\n }\n}\n\nfunction missToError(miss: MatchMiss): IngeniumError {\n if (miss.kind === 'not-found') return new IngeniumNotFoundError()\n return new IngeniumMethodNotAllowedError(miss.allowed)\n}\n\nfunction writeDefaultError(err: unknown, ctx: IngeniumContext): void {\n if (err instanceof IngeniumHaltError) {\n // Halt body shape was decided at the call site (`ctx.halt`):\n // - 'text' → body is a string, write as text/plain verbatim\n // - 'json' → body is an object, write as application/json verbatim\n // - 'none' → no body provided, fall through to default JSON shape\n if (err.bodyShape === 'text') {\n ctx.text(err.body as string, err.statusCode)\n return\n }\n if (err.bodyShape === 'json') {\n ctx.json(err.body as Record<string, unknown>, err.statusCode)\n return\n }\n ctx.json({ error: err.message, code: err.code }, err.statusCode)\n return\n }\n if (err instanceof IngeniumError) {\n if (err instanceof IngeniumMethodNotAllowedError) {\n ctx.set('allow', err.allowed.join(', '))\n }\n const payload: Record<string, unknown> = { error: err.message, code: err.code }\n if ('fields' in err && err.fields) payload.fields = err.fields\n ctx.json(payload, err.statusCode)\n return\n }\n // Unknown error → 500\n const message = (err as Error)?.message ?? 'Internal Server Error'\n ctx.json({ error: message, code: 'INTERNAL_ERROR' }, 500)\n}\n\n/**\n * Populate a pooled context from {@link InjectRequest}, mirroring the Node\n * adapter's `populateContext`. Splits path / query, lowercases header names,\n * normalizes the body into a `Readable` (so `ctx.body.*` consumers behave\n * exactly as they do on the wire), and tags JSON bodies with a content-type\n * unless the caller set one.\n */\nfunction populateInjectContext(ctx: IngeniumContext, opts: InjectRequest): void {\n ctx.method = opts.method ?? 'GET'\n ctx.url = opts.url\n const qIdx = opts.url.indexOf('?')\n if (qIdx >= 0) {\n ctx.path = opts.url.slice(0, qIdx)\n ctx.rawQuery = opts.url.slice(qIdx + 1)\n } else {\n ctx.path = opts.url\n ctx.rawQuery = ''\n }\n\n // Lowercase header names (node:http convention). Collect into the bag the\n // handler reads via ctx.headers[...].\n const headers: Record<string, string | string[]> = {}\n if (opts.headers) {\n for (const name of Object.keys(opts.headers)) {\n headers[name.toLowerCase()] = opts.headers[name] as string | string[]\n }\n }\n\n ctx.remoteAddress = opts.remoteAddress ?? '127.0.0.1'\n ctx.baseProtocol = 'http'\n\n // Normalize the body into raw bytes. Objects → JSON (+ default content-type\n // unless the caller already set one). Strings/Buffers/Uint8Arrays pass\n // through verbatim. `undefined` → no body.\n let bodyBuf: Buffer | null = null\n const body = opts.body\n if (body !== undefined) {\n if (typeof body === 'string') {\n bodyBuf = Buffer.from(body, 'utf8')\n } else if (Buffer.isBuffer(body)) {\n bodyBuf = body\n } else if (body instanceof Uint8Array) {\n bodyBuf = Buffer.from(body)\n } else {\n // Plain object / array → JSON. Auto-tag content-type unless explicit.\n bodyBuf = Buffer.from(JSON.stringify(body), 'utf8')\n if (headers['content-type'] === undefined) {\n headers['content-type'] = 'application/json'\n }\n }\n }\n\n ctx.headers = headers\n\n if (bodyBuf !== null) {\n const ct = headers['content-type']\n ctx.body._attach(\n Readable.from(bodyBuf),\n Array.isArray(ct) ? ct[0] : ct,\n bodyBuf.length,\n )\n } else {\n ctx.body._attach(null, undefined, undefined)\n }\n}\n\n/**\n * Materialize a dispatched context's response into a plain {@link InjectResponse}.\n * Clones the header bag (array values copied) so callers never alias the\n * pooled context's `_headers`, and drains a stream body to a UTF-8 string.\n * MUST be called before the context is released back to the pool.\n */\nasync function extractInjectResponse(ctx: IngeniumContext): Promise<InjectResponse> {\n const status = ctx._statusCode\n\n // Deep-ish copy of headers — array values cloned so a later inject() can't\n // mutate this snapshot (and vice versa).\n const headers: Record<string, string | string[]> = {}\n for (const key of Object.keys(ctx._headers)) {\n const v = ctx._headers[key]\n if (v === undefined) continue\n headers[key] = Array.isArray(v) ? v.slice() : v\n }\n\n let body = ''\n const rb = ctx._body\n switch (rb.kind) {\n case 'string':\n body = rb.data\n break\n case 'buffer':\n body = rb.data.toString('utf8')\n break\n case 'stream': {\n const chunks: Buffer[] = []\n for await (const chunk of rb.data) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : (chunk as Buffer))\n }\n body = Buffer.concat(chunks).toString('utf8')\n break\n }\n case 'none':\n body = ''\n break\n }\n\n return {\n status,\n headers,\n body,\n json<T = unknown>(): T {\n return JSON.parse(body) as T\n },\n }\n}\n\n/**\n * Detect whether a value is a \"plain options object\" — i.e. the declarative\n * route-options shape (`{ auth: [...], rateLimit: '...' }`) — vs anything\n * else that might be in argument-position 0 (a middleware function, a\n * handler function, a class instance, a Buffer, an Array, etc).\n *\n * Rule: must be non-null, `typeof === 'object'`, NOT a function, NOT an\n * Array, and `Object.getPrototypeOf(v)` is either `Object.prototype` or\n * `null` (covers `Object.create(null)` bags). Class instances have a\n * non-Object prototype and are correctly rejected. This is a stricter check\n * than `typeof === 'object'` alone — we want false positives to be near-\n * impossible because misclassifying a middleware as options would bury the\n * mistake under \"unknown declarator\" errors.\n */\nfunction isPlainOptionsObject(v: unknown): v is RouteOptions {\n if (v === null || typeof v !== 'object') return false\n if (typeof v === 'function') return false\n if (Array.isArray(v)) return false\n const proto = Object.getPrototypeOf(v) as object | null\n return proto === null || proto === Object.prototype\n}\n\n/**\n * Translate the peeled-off built-in slice of a route-options object into the\n * shape `app.describe()` expects. Pass-through for plain OpenAPI keys\n * (`summary`, `description`, `operationId`, `tags`, `deprecated`, `security`,\n * `parameters`); normalization for `response` / `requestBody` which the user\n * may write in compact form (a bare Schema). See `normalizeResponse` /\n * `normalizeRequestBody` for the rules. Throws at REGISTRATION time on any\n * inline value that looks like a live validator (Standard Schema or Zod-style\n * `safeParse`) — we don't try to convert validators to JSON Schema from this\n * code path; callers can precompute and use `app.describe()` directly.\n */\nfunction buildDescriptorFromBuiltins(\n method: HttpMethod,\n path: string,\n builtins: Record<string, unknown>,\n): RouteDescriptor {\n const desc: RouteDescriptor = {}\n if ('summary' in builtins) desc.summary = builtins.summary as string\n if ('description' in builtins) desc.description = builtins.description as string\n if ('operationId' in builtins) desc.operationId = builtins.operationId as string\n if ('tags' in builtins) desc.tags = builtins.tags as string[]\n if ('deprecated' in builtins) desc.deprecated = builtins.deprecated as boolean\n if ('security' in builtins) desc.security = builtins.security as NonNullable<RouteDescriptor['security']>\n if ('parameters' in builtins) desc.parameters = builtins.parameters as NonNullable<RouteDescriptor['parameters']>\n if ('response' in builtins) {\n desc.responses = normalizeResponse(method, path, builtins.response)\n }\n if ('requestBody' in builtins) {\n desc.requestBody = normalizeRequestBody(method, path, builtins.requestBody)\n }\n return desc\n}\n\n/**\n * Reject inline schema values that need conversion we don't perform at this\n * seam. We accept ONLY raw OpenAPI Schema objects (plain JSON Schema literals,\n * including the wrappers Zod 3.24+/ArkType/Effect emit when the caller has\n * already called `.toJsonSchema()`). Anything that still carries a live\n * `~standard` or `safeParse` is a precondition violation: it's the caller's\n * job to convert. The OpenAPI generator's runtime conversion path handles\n * validators passed through the long-form `app.describe()` API; this inline\n * convenience form intentionally stays conversion-free so the failure mode\n * is at registration, not at spec-generation time inside a healthcheck.\n */\nfunction validateInlineSchema(\n method: HttpMethod,\n path: string,\n location: 'response' | 'requestBody',\n value: unknown,\n): void {\n if (value === null || typeof value !== 'object') return\n if (isStandardSchema(value)) {\n throw new TypeError(\n `app.${method.toLowerCase()}('${path}', { ${location}: ... }, handler): inline schema conversion isn't supported yet. ` +\n `Pass a plain OpenAPI Schema object, or use app.describe() with a precomputed schema.`,\n )\n }\n const maybeZod = value as { safeParse?: unknown }\n if (typeof maybeZod.safeParse === 'function') {\n throw new TypeError(\n `app.${method.toLowerCase()}('${path}', { ${location}: ... }, handler): inline schema conversion isn't supported yet. ` +\n `Pass a plain OpenAPI Schema object, or use app.describe() with a precomputed schema.`,\n )\n }\n}\n\n/**\n * Three-digit status-code key heuristic — `200`, `404`, `4XX` are all\n * accepted. Used to distinguish \"status-keyed response map\" from \"bare\n * schema with `200`-shaped property names.\" Keys longer than 3 chars, with\n * non-digit/non-X content, or starting with `0` are NOT status codes.\n */\nfunction isStatusKey(k: string): boolean {\n if (k.length !== 3) return false\n if (k[0] === '0') return false\n for (let i = 0; i < 3; i++) {\n const c = k.charCodeAt(i)\n // 0-9 or X / x\n if (!((c >= 48 && c <= 57) || c === 88 || c === 120)) return false\n }\n return true\n}\n\n/**\n * Heuristic: does this look like a JSON Schema literal? Detects the common\n * top-level keywords. Used to choose between `{ response: SchemaLiteral }`\n * (wrap as 200) and `{ response: { '200': {...}, '404': {...} } }`\n * (status-keyed map). The two shapes are unambiguous in practice because a\n * status-keyed map's keys are all 3-char digits and JSON Schema keywords\n * never are.\n */\nfunction looksLikeSchemaLiteral(v: object): boolean {\n const obj = v as Record<string, unknown>\n return (\n 'type' in obj ||\n 'properties' in obj ||\n '$ref' in obj ||\n 'oneOf' in obj ||\n 'anyOf' in obj ||\n 'allOf' in obj ||\n 'enum' in obj ||\n 'const' in obj ||\n 'items' in obj\n )\n}\n\n/**\n * Normalize the inline `response` option into the descriptor's `responses`\n * map. Three accepted shapes:\n * 1. A bare OpenAPI Schema → wrapped as `200 application/json` content.\n * 2. A status-keyed map (`{ '200': {...}, '404': {...} }`) where each entry\n * is either a full `Response` object or a bare Schema.\n * 3. An already-shaped `Response` (has `description` and/or `content`) for\n * the 200 slot.\n *\n * Picks (1) vs (2) by inspecting the object's keys: if any key is a 3-digit\n * status code (`200`, `4XX`), it's (2); if the object looks like a JSON\n * Schema literal (`type`/`properties`/`$ref`/...), it's (1); otherwise we\n * fall back to (3) — wrap the value as the 200 Response.\n */\nfunction normalizeResponse(\n method: HttpMethod,\n path: string,\n value: unknown,\n): Record<string, Response> {\n validateInlineSchema(method, path, 'response', value)\n if (value === null || typeof value !== 'object') {\n // A non-object is not a meaningful response shape. Wrap as an opaque\n // 200 schema so the caller at least sees something in the spec.\n return {\n '200': {\n description: 'OK',\n content: { 'application/json': { schema: value as Schema } },\n },\n }\n }\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj)\n const allStatus = keys.length > 0 && keys.every(isStatusKey)\n\n if (allStatus) {\n const out: Record<string, Response> = {}\n for (const k of keys) {\n out[k] = coerceResponseEntry(method, path, obj[k])\n }\n return out\n }\n\n // Single 200 entry. If it already looks like a Response (has description\n // and/or content), pass it through; otherwise wrap as JSON content.\n if ('content' in obj || ('description' in obj && !looksLikeSchemaLiteral(obj))) {\n return { '200': obj as unknown as Response }\n }\n return {\n '200': {\n description: 'OK',\n content: { 'application/json': { schema: obj as Schema } },\n },\n }\n}\n\n/**\n * Coerce a single value from a status-keyed `response` map into a `Response`.\n * Accepts either a full `Response` (passed through) or a bare schema (wrapped\n * as `application/json` content with a default description).\n */\nfunction coerceResponseEntry(method: HttpMethod, path: string, value: unknown): Response {\n validateInlineSchema(method, path, 'response', value)\n if (value === null || typeof value !== 'object') {\n return {\n description: 'Response',\n content: { 'application/json': { schema: value as Schema } },\n }\n }\n const obj = value as Record<string, unknown>\n if ('content' in obj || ('description' in obj && !looksLikeSchemaLiteral(obj))) {\n return obj as unknown as Response\n }\n return {\n description: 'Response',\n content: { 'application/json': { schema: obj as Schema } },\n }\n}\n\n/**\n * Normalize the inline `requestBody` option into a full `RequestBody` shape.\n * If the value already has a `content` field (an OpenAPI RequestBody),\n * pass it through; otherwise wrap as `application/json` content.\n */\nfunction normalizeRequestBody(\n method: HttpMethod,\n path: string,\n value: unknown,\n): RequestBody {\n validateInlineSchema(method, path, 'requestBody', value)\n if (value === null || typeof value !== 'object') {\n return { content: { 'application/json': { schema: value as Schema } } }\n }\n const obj = value as Record<string, unknown>\n if ('content' in obj) return obj as unknown as RequestBody\n return { content: { 'application/json': { schema: obj as Schema } } }\n}\n\n/**\n * Race a dispatched handler against a wall-clock deadline. Resolves when\n * the handler does, or rejects with `IngeniumTimeoutError` if the deadline\n * fires first. The handler promise is NOT cancelled (JS can't) — it's just\n * orphaned. We bump `ctx._epoch` at timeout so any subsequent writes from\n * the orphaned handler hit the epoch-guard installed around the dispatch\n * and get swallowed instead of corrupting the next request.\n *\n * The timer is `unref`'d so a fast handler that resolves naturally doesn't\n * keep the event loop alive waiting for the timeout to fire.\n */\nfunction raceWithTimeout(\n dispatch: Promise<unknown> | unknown,\n timeoutMs: number,\n ctx: IngeniumContext,\n capturedEpoch: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n // Bump the epoch so the orphaned handler's late writes are detected\n // by the guard wrappers as stale and discarded. This is what\n // prevents cross-request response corruption when the ctx is\n // recycled and rebound to a new request.\n if (ctx._epoch === capturedEpoch) ctx._epoch++\n reject(new IngeniumTimeoutError(timeoutMs))\n }, timeoutMs)\n // Crucially, never keep the event loop alive. A handler that resolves\n // in 5ms with a 30s timeout configured should not block process exit.\n timer.unref?.()\n Promise.resolve(dispatch).then(\n (v) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n resolve(v as void)\n },\n (err) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n reject(err)\n },\n )\n })\n}\n\n/**\n * Per-dispatch async-context store. Carries the epoch captured at dispatch\n * entry through every `await` in the handler chain. The orphaned handler\n * of a timed-out dispatch keeps running inside its OWN ALS frame even\n * after `Promise.race` rejects in `handle()`, so its `als.getStore()`\n * still returns the original captured epoch. The next request runs in a\n * different ALS frame (because `als.run(...)` was called fresh), so its\n * store is its own captured epoch. This is the ONLY reliable way to\n * distinguish \"the orphan calling `ctx.json`\" from \"the legitimate next\n * request calling `ctx.json`\" — ctx state alone cannot.\n */\nconst dispatchEpochStore: AsyncLocalStorage<number> = new AsyncLocalStorage()\n\n/**\n * Run `fn()` under both the wall-clock race AND a per-dispatch late-write\n * guard. The guard installs closure-bound wrappers around `ctx`'s response\n * writers; each wrapper checks `dispatchEpochStore.getStore()` (carried by\n * `AsyncLocalStorage` through every `await` in the handler chain) against\n * the epoch captured at dispatch entry. When they diverge — because the\n * timeout path bumped `ctx._epoch` and we're now executing inside a stale\n * orphan continuation — the wrapper swallows the write and emits a single\n * `IngeniumLateWriteWarning` so leaks remain observable in production.\n *\n * Behavior:\n * - Dispatch resolves naturally → restore originals (no orphan possible).\n * - Dispatch times out → bump `_epoch` (so any check against the captured\n * value fails), `Promise.race` rejects with `IngeniumTimeoutError`, the\n * error boundary writes the 503. The orphaned handler keeps running in\n * its own ALS frame; its eventual `ctx.json(...)` is detected as stale\n * either by (a) the still-installed wrapper (if no new request has\n * re-wrapped) — store mismatch → swallow; or (b) the next request's\n * wrapper, which compares the orphan's ALS-store epoch against its own\n * captured value → mismatch → swallow.\n *\n * The error boundary itself runs OUTSIDE the orphan's ALS frame (it\n * executes synchronously after the `await` in `handle()`), so its\n * `als.getStore()` returns `undefined`, which the wrapper treats as \"no\n * guard active for this caller\" and lets through.\n *\n * The timer is `unref`'d so a fast handler that resolves naturally doesn't\n * keep the event loop alive waiting for the timeout to fire.\n */\nasync function withEpochGuard(\n ctx: IngeniumContext,\n timeoutMs: number,\n fn: () => Promise<unknown> | unknown,\n): Promise<void> {\n const capturedEpoch = ctx._epoch\n ctx._dispatchEpoch = capturedEpoch\n\n // Snapshot originals — un-wrapped methods we restore on dispatch end.\n const originals = {\n json: ctx.json,\n text: ctx.text,\n html: ctx.html,\n send: ctx.send,\n redirect: ctx.redirect,\n stream: ctx.stream,\n }\n\n // The closure + ALS combined check. `capturedEpoch` is the per-dispatch\n // identity. We swallow ONLY when this wrapper's own orphan is calling:\n // the ALS store still says \"you're inside dispatch N\" (because the\n // orphan kept running its async chain past the timeout) BUT the live\n // `_epoch` has moved on (because the timeout path bumped it). For every\n // other caller — the legitimate handler under THIS dispatch, the error\n // boundary (no store), the next dispatch's handler (different store) —\n // we pass through to the underlying writer. With wrappers stacked\n // across recycled contexts, each layer detects only its own orphan and\n // forwards everything else; the deepest layer is the original writer.\n const guarded = (orig: (...args: never[]) => unknown) =>\n function guardedWriter(this: IngeniumContext, ...args: unknown[]): unknown {\n const callerEpoch = dispatchEpochStore.getStore()\n // Only my-own-orphan path swallows: caller is in the same ALS frame\n // I installed, but the live epoch has been bumped past my captured\n // value (timeout fired or the ctx was recycled).\n if (callerEpoch === capturedEpoch && ctx._epoch !== capturedEpoch) {\n try {\n process.emitWarning(\n 'Late response write after timeout — handler may be leaking',\n { type: 'IngeniumLateWriteWarning' },\n )\n } catch {\n // process.emitWarning can throw in unusual runtimes (workers); swallow.\n }\n return undefined\n }\n return (orig as (...a: unknown[]) => unknown).apply(ctx, args)\n }\n\n ctx.json = guarded(originals.json) as typeof ctx.json\n ctx.text = guarded(originals.text) as typeof ctx.text\n ctx.html = guarded(originals.html) as typeof ctx.html\n ctx.send = guarded(originals.send) as typeof ctx.send\n ctx.redirect = guarded(originals.redirect) as typeof ctx.redirect\n ctx.stream = guarded(originals.stream) as typeof ctx.stream\n\n const restore = (): void => {\n ctx.json = originals.json\n ctx.text = originals.text\n ctx.html = originals.html\n ctx.send = originals.send\n ctx.redirect = originals.redirect\n ctx.stream = originals.stream\n ctx._dispatchEpoch = 0\n }\n\n try {\n await dispatchEpochStore.run(capturedEpoch, () =>\n raceWithTimeout(fn(), timeoutMs, ctx, capturedEpoch),\n )\n // Success path: no orphan can exist. Restore originals so we don't\n // accumulate dead wrappers on the pooled context across thousands of\n // successful requests.\n restore()\n } catch (err) {\n // Failure path. If it's a timeout, the orphaned handler is still alive\n // and may eventually call ctx.json/text/...; we KEEP the wrapper\n // installed so its ALS-store check can detect and swallow those late\n // writes. The error boundary itself runs outside the orphan's ALS\n // frame, so its writes pass through (no store ⇒ no swallow).\n //\n // For non-timeout errors (handler threw synchronously, etc.) there's\n // no orphan to defend against, so restore for hygiene.\n if (err instanceof IngeniumTimeoutError) {\n ctx._dispatchEpoch = 0 // Stop advertising \"active dispatch\"; wrapper still inspects ALS store.\n } else {\n restore()\n }\n throw err\n }\n}\n\nfunction pathStartsWith(path: string, prefix: string): boolean {\n if (prefix === '') return true\n if (!path.startsWith(prefix)) return false\n // Boundary check: '/api' must not match '/apiary'.\n const after = path.charCodeAt(prefix.length)\n return Number.isNaN(after) || after === 47 // '/'\n}\n\n/**\n * Factory function. Mirrors the `express()` ergonomics — `ingenium(...)` returns\n * a new app, and the function carries the body-parser middleware factories\n * plus a `Router` constructor as static properties.\n */\nexport interface IngeniumFactory {\n (options?: IngeniumAppOptions): IngeniumApp\n Router: () => Router\n}\n\n/** Match: `void` for error-handler that delegates. (Used by the type tests.) */\nexport type IngeniumErrorReturn = unknown | Promise<unknown>\n\n/** Function-with-properties factory created and exported by `index.ts`. */\nexport function makeIngeniumFactory(): IngeniumFactory {\n const fn = ((options?: IngeniumAppOptions) => new IngeniumApp(options)) as IngeniumFactory\n fn.Router = () => new Router()\n return fn\n}\n\n/** Match path-with-prefix exported for tests. */\nexport const _internal_pathStartsWith = pathStartsWith\n","import type { IngeniumMiddleware } from '../middleware/types.ts'\n\n/**\n * Express compatibility shim. In Ingenium, body parsing is lazy via\n * `ctx.body.json()` / `ctx.body.urlencoded()` / `ctx.body.text()` — there is\n * no parse-on-every-request middleware to register. This factory exists so\n * existing `app.use(express.json())` migration patterns keep compiling and\n * reading naturally; the returned middleware is a zero-cost no-op.\n *\n * If you need to enforce a default `maxBytes` across all body access, set it\n * via the `limit` option here and read it inside your handlers when calling\n * `ctx.body.json({ limit })` — Ingenium doesn't store it implicitly.\n *\n * @returns a no-op middleware\n */\nexport function jsonMiddleware(_opts?: { limit?: number }): IngeniumMiddleware {\n return async (_ctx, next) => {\n await next()\n }\n}\n\n/**\n * See `jsonMiddleware` — same rationale. URL-encoded parsing is lazy via\n * `ctx.body.urlencoded()`.\n */\nexport function urlencodedMiddleware(_opts?: { limit?: number }): IngeniumMiddleware {\n return async (_ctx, next) => {\n await next()\n }\n}\n","import { createReadStream } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport * as path from 'node:path'\nimport type { Stats } from 'node:fs'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { StaticOptions } from './types.ts'\n\n/**\n * Minimal MIME table — extension (lowercase, without dot) → content-type.\n * Unknown extensions fall back to `application/octet-stream`.\n */\nconst MIME_TYPES: Readonly<Record<string, string>> = {\n html: 'text/html; charset=utf-8',\n css: 'text/css; charset=utf-8',\n js: 'application/javascript; charset=utf-8',\n mjs: 'application/javascript; charset=utf-8',\n json: 'application/json; charset=utf-8',\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n ico: 'image/x-icon',\n txt: 'text/plain; charset=utf-8',\n woff: 'font/woff',\n woff2: 'font/woff2',\n}\n\nconst DEFAULT_INDEX = 'index.html'\n\nfunction mimeFor(file: string): string {\n const ext = path.extname(file).slice(1).toLowerCase()\n return MIME_TYPES[ext] ?? 'application/octet-stream'\n}\n\nfunction makeEtag(stats: Stats): string {\n // Express-style weak etag: W/\"<size>-<mtimeMs-as-hex>\"\n return `W/\"${stats.size.toString(16)}-${Math.floor(stats.mtimeMs).toString(16)}\"`\n}\n\n/**\n * Parse a `Range: bytes=N-M` header against a known total size.\n * Returns `{ start, end }` (inclusive), `'invalid'` if the header is malformed\n * or unsatisfiable (caller should respond 416), or `null` if no/multi range\n * (caller should serve the full body).\n */\nfunction parseRange(\n header: string | undefined,\n size: number,\n): { start: number; end: number } | 'invalid' | null {\n if (!header) return null\n if (!header.startsWith('bytes=')) return null\n const spec = header.slice(6)\n // Multiple ranges: not supported — fall back to full body.\n if (spec.includes(',')) return null\n const dash = spec.indexOf('-')\n if (dash === -1) return 'invalid'\n const startStr = spec.slice(0, dash)\n const endStr = spec.slice(dash + 1)\n let start: number\n let end: number\n if (startStr === '') {\n // Suffix range: bytes=-N → last N bytes\n const suffix = Number(endStr)\n if (!Number.isFinite(suffix) || suffix <= 0) return 'invalid'\n start = Math.max(0, size - suffix)\n end = size - 1\n } else {\n start = Number(startStr)\n end = endStr === '' ? size - 1 : Number(endStr)\n if (!Number.isFinite(start) || !Number.isFinite(end)) return 'invalid'\n if (start < 0 || end < start) return 'invalid'\n if (start >= size) return 'invalid'\n if (end >= size) end = size - 1\n }\n return { start, end }\n}\n\n/**\n * Static-file middleware. Serves files from `root`, supporting directory\n * indexes, weak ETags, `If-None-Match`, byte-range requests, and basic\n * dotfile policy. Misses (file not found) call `next()` — they do NOT\n * write 404 themselves, so downstream routes still get a chance.\n *\n * @example\n * app.use(ingenium.static('./public', { maxAge: 60_000 }))\n */\nexport function staticMiddleware(root: string, opts: StaticOptions = {}): IngeniumMiddleware {\n const absRoot = path.resolve(root)\n const indexFile = opts.index === undefined ? DEFAULT_INDEX : opts.index\n const maxAgeMs = opts.maxAge ?? 0\n const cacheControl = `public, max-age=${Math.floor(maxAgeMs / 1000)}`\n const extensions = opts.extensions ?? []\n const dotfiles = opts.dotfiles ?? 'ignore'\n\n return async (ctx, next) => {\n // Only GET / HEAD make sense for static.\n if (ctx.method !== 'GET' && ctx.method !== 'HEAD') {\n return next()\n }\n\n // Decode percent-escapes; reject malformed URLs.\n let urlPath: string\n try {\n urlPath = decodeURIComponent(ctx.path)\n } catch {\n ctx.status(400).text('Bad Request')\n return\n }\n\n // Path-traversal protection: resolve, then ensure it stays under root.\n const joined = path.join(absRoot, urlPath)\n const resolved = path.resolve(joined)\n const isUnderRoot =\n resolved === absRoot ||\n resolved.startsWith(absRoot + path.sep)\n if (!isUnderRoot) {\n ctx.status(403).text('Forbidden')\n return\n }\n\n // Dotfile policy: check every segment of the path BELOW root.\n const rel = path.relative(absRoot, resolved)\n const segments = rel.length === 0 ? [] : rel.split(/[/\\\\]/)\n const hasDot = segments.some((s) => s.length > 0 && s.startsWith('.'))\n if (hasDot) {\n if (dotfiles === 'deny') {\n ctx.status(403).text('Forbidden')\n return\n }\n if (dotfiles === 'ignore') {\n return next()\n }\n // 'allow' falls through.\n }\n\n // Try to stat the resolved path. Fall through on ENOENT / not-a-file.\n let target = resolved\n let stats: Stats | null = null\n try {\n stats = await stat(target)\n } catch {\n stats = null\n }\n\n // Try `extensions` if the bare path didn't exist.\n if (!stats && extensions.length > 0) {\n for (const ext of extensions) {\n const withExt = `${target}.${ext.replace(/^\\./, '')}`\n try {\n const s = await stat(withExt)\n if (s.isFile()) {\n target = withExt\n stats = s\n break\n }\n } catch {\n // try next\n }\n }\n }\n\n // Directory → optional index file.\n if (stats && stats.isDirectory()) {\n if (!indexFile) return next()\n const idx = path.join(target, indexFile)\n try {\n const s = await stat(idx)\n if (s.isFile()) {\n target = idx\n stats = s\n } else {\n return next()\n }\n } catch {\n return next()\n }\n }\n\n if (!stats || !stats.isFile()) {\n return next()\n }\n\n // ───── Cacheable response headers ─────\n const etag = makeEtag(stats)\n const lastModified = new Date(stats.mtimeMs).toUTCString()\n ctx.set('etag', etag)\n ctx.set('last-modified', lastModified)\n ctx.set('cache-control', cacheControl)\n ctx.set('content-type', mimeFor(target))\n ctx.set('accept-ranges', 'bytes')\n\n // Conditional GET via If-None-Match (preferred) or If-Modified-Since\n // (fallback per RFC 7232 §6). If-None-Match wins when both are present.\n const ifNoneMatch = ctx.headers['if-none-match']\n let notModified = typeof ifNoneMatch === 'string' && ifNoneMatch === etag\n\n if (!notModified && !ifNoneMatch) {\n const ifModifiedSince = ctx.headers['if-modified-since']\n if (typeof ifModifiedSince === 'string') {\n const sinceMs = Date.parse(ifModifiedSince)\n // mtime is compared at second-resolution because HTTP-dates have no\n // sub-second precision — Math.floor matches both sides.\n const lastMs = Math.floor(stats.mtimeMs / 1000) * 1000\n if (Number.isFinite(sinceMs) && lastMs <= sinceMs) notModified = true\n }\n }\n\n if (notModified) {\n ctx.status(304)\n // 304 must not have a body.\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n\n const size = stats.size\n const rangeHeader = ctx.headers.range\n const range = parseRange(typeof rangeHeader === 'string' ? rangeHeader : undefined, size)\n\n if (range === 'invalid') {\n ctx.status(416)\n ctx.set('content-range', `bytes */${size}`)\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n\n if (range) {\n const { start, end } = range\n const chunk = end - start + 1\n ctx.status(206)\n ctx.set('content-range', `bytes ${start}-${end}/${size}`)\n ctx.set('content-length', String(chunk))\n if (ctx.method === 'HEAD') {\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n ctx.stream(createReadStream(target, { start, end }))\n return\n }\n\n // Full body.\n ctx.set('content-length', String(size))\n if (ctx.method === 'HEAD') {\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n ctx.stream(createReadStream(target))\n }\n}\n","import type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { CorsOptions, CorsOrigin } from './types.ts'\n\nconst DEFAULT_METHODS: readonly string[] = [\n 'GET',\n 'HEAD',\n 'PUT',\n 'PATCH',\n 'POST',\n 'DELETE',\n]\n\n/**\n * Append a value to the `Vary` response header, de-duplicating field names\n * (case-insensitive).\n */\nfunction appendVary(ctx: IngeniumContext, field: string): void {\n const existing = ctx.getHeader('vary')\n if (!existing) {\n ctx.set('vary', field)\n return\n }\n const cur = Array.isArray(existing) ? existing.join(', ') : existing\n const seen = cur\n .split(',')\n .map((s) => s.trim().toLowerCase())\n .filter((s) => s.length > 0)\n if (seen.includes(field.toLowerCase())) return\n ctx.set('vary', cur.length > 0 ? `${cur}, ${field}` : field)\n}\n\n/**\n * Resolve the `origin` option against the request's `Origin` header.\n * Returns the literal value to put on `Access-Control-Allow-Origin`, or\n * `null` to omit the header (request is denied / had no `Origin`).\n *\n * Also returns `reflected` — `true` when the value mirrors the request's\n * `Origin`, so the caller knows to add `Vary: Origin`.\n */\nasync function resolveOrigin(\n spec: CorsOrigin,\n reqOrigin: string | undefined,\n ctx: IngeniumContext,\n): Promise<{ value: string | null; reflected: boolean }> {\n // Static wildcard: never depends on the request, never reflects.\n if (spec === '*') return { value: '*', reflected: false }\n if (spec === false) return { value: null, reflected: false }\n\n // Anything below requires an Origin header on the request.\n if (typeof reqOrigin !== 'string' || reqOrigin.length === 0) {\n return { value: null, reflected: false }\n }\n\n if (spec === true) return { value: reqOrigin, reflected: true }\n\n if (typeof spec === 'string') {\n return spec === reqOrigin\n ? { value: reqOrigin, reflected: true }\n : { value: null, reflected: true }\n }\n\n if (Array.isArray(spec)) {\n return spec.includes(reqOrigin)\n ? { value: reqOrigin, reflected: true }\n : { value: null, reflected: true }\n }\n\n if (spec instanceof RegExp) {\n return spec.test(reqOrigin)\n ? { value: reqOrigin, reflected: true }\n : { value: null, reflected: true }\n }\n\n if (typeof spec === 'function') {\n const result = await spec(reqOrigin, ctx)\n if (result === true) return { value: reqOrigin, reflected: true }\n if (result === false) return { value: null, reflected: true }\n if (typeof result === 'string') {\n // Custom string — not a literal reflection; only Vary if it's not '*'.\n return { value: result, reflected: result !== '*' }\n }\n return { value: null, reflected: true }\n }\n\n return { value: null, reflected: false }\n}\n\n/**\n * CORS middleware. Implements the standard CORS protocol (Fetch spec\n * §3.2.4) for both simple requests and preflight (`OPTIONS` +\n * `Access-Control-Request-Method`).\n *\n * @example\n * app.use(ingenium.cors())\n * app.use(ingenium.cors({ origin: ['https://app.example.com'], credentials: true }))\n */\nexport function corsMiddleware(opts: CorsOptions = {}): IngeniumMiddleware {\n const origin: CorsOrigin = opts.origin ?? '*'\n const methods = opts.methods ?? DEFAULT_METHODS\n const allowedHeaders = opts.allowedHeaders\n const exposedHeaders = opts.exposedHeaders\n const credentials = opts.credentials ?? false\n const maxAge = opts.maxAge\n const optionsSuccessStatus = opts.optionsSuccessStatus ?? 204\n\n // Construction-time validation: `credentials: true` + wildcard origin is\n // forbidden by the CORS spec — browsers reject the response.\n if (credentials && origin === '*') {\n throw new Error(\n \"ingenium.cors: `credentials: true` is incompatible with `origin: '*'`. \" +\n 'Specify an explicit origin (string, array, regex, or function) instead.',\n )\n }\n\n const methodsHeader = methods.join(',')\n const exposedHeader = exposedHeaders && exposedHeaders.length > 0\n ? exposedHeaders.join(',')\n : undefined\n const allowedHeader = allowedHeaders && allowedHeaders.length > 0\n ? allowedHeaders.join(',')\n : undefined\n const maxAgeHeader = typeof maxAge === 'number' ? String(maxAge) : undefined\n\n return async (ctx, next) => {\n const reqOrigin = ctx.headers.origin\n const reqOriginStr = typeof reqOrigin === 'string' ? reqOrigin : undefined\n\n const { value: allowOrigin, reflected } = await resolveOrigin(\n origin,\n reqOriginStr,\n ctx,\n )\n\n if (reflected) appendVary(ctx, 'Origin')\n\n if (allowOrigin !== null) {\n ctx.set('access-control-allow-origin', allowOrigin)\n if (credentials) {\n ctx.set('access-control-allow-credentials', 'true')\n }\n }\n\n // Detect preflight: OPTIONS + Access-Control-Request-Method header.\n const acrm = ctx.headers['access-control-request-method']\n const isPreflight =\n ctx.method === 'OPTIONS' && typeof acrm === 'string' && acrm.length > 0\n\n if (isPreflight) {\n ctx.set('access-control-allow-methods', methodsHeader)\n\n if (allowedHeader !== undefined) {\n ctx.set('access-control-allow-headers', allowedHeader)\n } else {\n const acrh = ctx.headers['access-control-request-headers']\n if (typeof acrh === 'string' && acrh.length > 0) {\n ctx.set('access-control-allow-headers', acrh)\n // The reflected headers vary with the request, so signal it.\n appendVary(ctx, 'Access-Control-Request-Headers')\n }\n }\n\n if (maxAgeHeader !== undefined) {\n ctx.set('access-control-max-age', maxAgeHeader)\n }\n\n // Preflight terminates here — no body, no downstream handlers.\n ctx.status(optionsSuccessStatus)\n ctx.set('content-length', '0')\n ctx._body = { kind: 'none' }\n ctx._written = true\n return\n }\n\n // Simple / actual request: expose headers, then continue the chain.\n if (exposedHeader !== undefined) {\n ctx.set('access-control-expose-headers', exposedHeader)\n }\n\n return next()\n }\n}\n","import { PassThrough } from 'node:stream'\nimport type { IngeniumContext } from '../context/context.ts'\n\n/**\n * A single Server-Sent Event. The `data` field is required; if you pass an\n * object, it's `JSON.stringify`'d before being written. All other fields are\n * optional and serialized per the EventSource specification.\n *\n * @see https://html.spec.whatwg.org/multipage/server-sent-events.html\n */\nexport interface SseEvent {\n /** Payload. Strings are written verbatim; objects are JSON-encoded. */\n data: string | object\n /** Optional event name — populates `event:` field. */\n event?: string\n /** Optional event id — populates `id:` field. */\n id?: string\n /** Optional retry hint in milliseconds — populates `retry:` field. */\n retry?: number\n}\n\n/**\n * Handle for an open SSE connection. Returned by {@link sse}. Use `send()`\n * to push events, `comment()` for keep-alive frames, and `close()` to end\n * the response stream cleanly.\n */\nexport interface SseStream {\n /**\n * Send a single event. A bare string is treated as `{ data: <string> }`.\n */\n send(event: SseEvent | string): void\n /** Write a comment line (`: <text>`). Useful for heartbeats / keep-alive. */\n comment(text: string): void\n /** End the response stream. Subsequent calls are no-ops. */\n close(): void\n /** Whether the underlying stream has been closed (locally or by the client). */\n readonly closed: boolean\n}\n\n/**\n * Open a Server-Sent Events response on the given context. Sets the\n * appropriate headers (`Content-Type: text/event-stream`, no caching, no\n * proxy buffering) and wires a `PassThrough` into `ctx.stream()`.\n *\n * @example\n * app.get('/events', (ctx) => {\n * const stream = sse(ctx)\n * stream.send({ event: 'hello', data: { msg: 'world' } })\n * setTimeout(() => stream.close(), 1000)\n * })\n */\nexport function sse(ctx: IngeniumContext): SseStream {\n const passthrough = new PassThrough()\n\n // SSE headers — set BEFORE ctx.stream() so the adapter can flush them.\n ctx.set('cache-control', 'no-cache')\n ctx.set('connection', 'keep-alive')\n // Disable proxy buffering (nginx-specific but harmless elsewhere).\n ctx.set('x-accel-buffering', 'no')\n\n ctx.stream(passthrough, 'text/event-stream; charset=utf-8')\n\n let closed = false\n passthrough.on('close', () => {\n closed = true\n })\n\n function write(chunk: string): void {\n if (closed) return\n if (!passthrough.writable) {\n closed = true\n return\n }\n passthrough.write(chunk)\n }\n\n return {\n get closed(): boolean {\n return closed\n },\n\n send(eventOrString: SseEvent | string): void {\n if (closed) return\n const evt: SseEvent =\n typeof eventOrString === 'string' ? { data: eventOrString } : eventOrString\n\n let frame = ''\n if (evt.event !== undefined) frame += `event: ${evt.event}\\n`\n if (evt.id !== undefined) frame += `id: ${evt.id}\\n`\n if (evt.retry !== undefined) frame += `retry: ${evt.retry}\\n`\n\n const dataStr =\n typeof evt.data === 'string' ? evt.data : JSON.stringify(evt.data)\n // Spec: split on newlines, emit one `data:` line per chunk.\n const lines = dataStr.split('\\n')\n for (const line of lines) {\n frame += `data: ${line}\\n`\n }\n frame += '\\n'\n write(frame)\n },\n\n comment(text: string): void {\n if (closed) return\n // Comment lines start with ':'. Use \\n\\n terminator to flush.\n write(`: ${text}\\n\\n`)\n },\n\n close(): void {\n if (closed) return\n closed = true\n passthrough.end()\n },\n }\n}\n","import type { RateLimitStore } from './types.ts'\n\ninterface Entry {\n count: number\n resetAt: number\n}\n\n/** Default cap on the number of distinct keys held in the in-memory store. */\nconst DEFAULT_MAX_ENTRIES = 100_000\n\nexport interface MemoryStoreOptions {\n /**\n * Hard ceiling on the number of distinct keys retained. When exceeded, the\n * **least-recently-touched** entry is evicted to make room. Default\n * `100_000`.\n *\n * The cap exists to bound memory under adversarial conditions: an attacker\n * generating one request per unique IP would otherwise grow the map without\n * bound. With the cap, the worst case is a fixed memory footprint and\n * attackers' counters get evicted (which means they bypass rate-limiting\n * for the exact endpoint they're hammering — a real trade-off, but better\n * than OOM).\n *\n * For genuinely high-cardinality production workloads (millions of distinct\n * users), prefer a Redis-backed store so eviction isn't required.\n */\n maxEntries?: number\n}\n\n/**\n * In-process fixed-window counter store. Suitable for single-replica\n * deployments and tests; swap for a Redis-backed store when running\n * multiple replicas behind a load balancer.\n *\n * A periodic sweep removes expired entries every `windowMs` so long-lived\n * processes don't leak memory across forgotten keys. The sweep timer is\n * `.unref()`'d, so it never keeps the Node event loop alive.\n *\n * The `Map` itself is bounded by `maxEntries` (default 100k). When the cap\n * is reached, the least-recently-touched entry is evicted before the new\n * entry is inserted. We rely on the JS `Map` insertion-order guarantee:\n * delete-then-set on an existing key moves it to the end, so the first\n * iteration step always returns the genuine LRU. **This is intentional\n * defense against scanner attacks that would otherwise OOM the process by\n * generating unique keys.**\n */\nexport class MemoryStore implements RateLimitStore {\n private readonly map: Map<string, Entry> = new Map()\n private sweeper: NodeJS.Timeout | null = null\n private sweepIntervalMs = 0\n private readonly maxEntries: number\n\n constructor(opts: MemoryStoreOptions = {}) {\n this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES\n if (!Number.isInteger(this.maxEntries) || this.maxEntries < 1) {\n throw new RangeError(\n `MemoryStore: maxEntries must be a positive integer, got ${String(opts.maxEntries)}`,\n )\n }\n }\n\n hit(key: string, windowMs: number): Promise<{ count: number; resetAt: number }> {\n const now = Date.now()\n const existing = this.map.get(key)\n\n let entry: Entry\n if (!existing || now >= existing.resetAt) {\n // New (or expired) key — may need to evict before inserting.\n if (!existing && this.map.size >= this.maxEntries) {\n // Evict the LRU: Map preserves insertion order, so the first key in\n // iteration is the oldest-touched (touch = delete+set on every hit).\n const oldestKey = this.map.keys().next().value\n if (oldestKey !== undefined) this.map.delete(oldestKey)\n }\n entry = { count: 1, resetAt: now + windowMs }\n // Re-insert order: existing-but-expired keys also need delete+set so\n // their order moves to the end (preserves LRU semantics).\n if (existing) this.map.delete(key)\n this.map.set(key, entry)\n } else {\n // Touch — move to end of insertion order so it's NOT the LRU candidate.\n existing.count += 1\n entry = existing\n this.map.delete(key)\n this.map.set(key, entry)\n }\n\n this.ensureSweeper(windowMs)\n return Promise.resolve({ count: entry.count, resetAt: entry.resetAt })\n }\n\n reset(key: string): Promise<void> {\n this.map.delete(key)\n return Promise.resolve()\n }\n\n /**\n * Stop the cleanup interval. Safe to call multiple times. Mostly useful\n * in tests; production usage doesn't need this because the timer is\n * already unref'd.\n */\n destroy(): void {\n if (this.sweeper) {\n clearInterval(this.sweeper)\n this.sweeper = null\n }\n this.map.clear()\n }\n\n /** @internal Current entry count — exposed for ops/tests. */\n get size(): number {\n return this.map.size\n }\n\n private ensureSweeper(windowMs: number): void {\n if (this.sweeper && this.sweepIntervalMs === windowMs) return\n if (this.sweeper) clearInterval(this.sweeper)\n this.sweepIntervalMs = windowMs\n this.sweeper = setInterval(() => this.sweep(), windowMs)\n if (typeof this.sweeper.unref === 'function') this.sweeper.unref()\n }\n\n private sweep(): void {\n const now = Date.now()\n for (const [key, entry] of this.map) {\n if (now >= entry.resetAt) this.map.delete(key)\n }\n }\n}\n","import type { IngeniumContext } from '../context/context.ts'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport { MemoryStore } from './store.ts'\nimport type { RateLimitOptions } from './types.ts'\n\n/** Default key generator — see RateLimitOptions.keyGenerator JSDoc. */\nfunction defaultKeyGenerator(ctx: IngeniumContext): string {\n const xff = ctx.headers['x-forwarded-for']\n if (typeof xff === 'string' && xff.length > 0) {\n const first = xff.split(',')[0]\n const trimmed = first?.trim()\n if (trimmed && trimmed.length > 0) return trimmed\n }\n const xri = ctx.headers['x-real-ip']\n if (typeof xri === 'string' && xri.length > 0) return xri\n return 'unknown'\n}\n\n/**\n * Fixed-window rate-limiting middleware. Each key is allowed at most `max`\n * requests per `windowMs`. Over-limit requests get a `429 Too Many\n * Requests` response with `Retry-After` and a JSON body.\n *\n * Every passing response carries `X-RateLimit-Limit`,\n * `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (unix seconds).\n *\n * @example\n * app.use(rateLimit({ max: 100, windowMs: 60_000 }))\n * app.use('/auth', rateLimit({ max: 5, windowMs: 60_000 }))\n */\nexport function rateLimit(opts: RateLimitOptions = {}): IngeniumMiddleware {\n const windowMs = opts.windowMs ?? 60_000\n const max = opts.max ?? 100\n const keyGenerator = opts.keyGenerator ?? defaultKeyGenerator\n const skip = opts.skip\n const store = opts.store ?? new MemoryStore()\n\n if (windowMs <= 0) throw new Error('rateLimit: windowMs must be > 0')\n if (max <= 0) throw new Error('rateLimit: max must be > 0')\n\n return async (ctx, next) => {\n if (skip && skip(ctx)) {\n return next()\n }\n\n const key = keyGenerator(ctx)\n const { count, resetAt } = await store.hit(key, windowMs)\n\n const remaining = Math.max(0, max - count)\n const resetSeconds = Math.ceil(resetAt / 1000)\n\n ctx.set('x-ratelimit-limit', String(max))\n ctx.set('x-ratelimit-remaining', String(remaining))\n ctx.set('x-ratelimit-reset', String(resetSeconds))\n\n if (count > max) {\n const retryAfter = Math.max(1, Math.ceil((resetAt - Date.now()) / 1000))\n ctx.set('retry-after', String(retryAfter))\n ctx.json(\n {\n error: 'Too Many Requests',\n code: 'RATE_LIMITED',\n retryAfter,\n },\n 429,\n )\n return\n }\n\n return next()\n }\n}\n","import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto'\nimport { Buffer } from 'node:buffer'\nimport { IngeniumError } from '../errors.ts'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { CsrfCookieOptions, CsrfOptions, CsrfValueReader } from './types.ts'\n\n/** 403 Forbidden — CSRF token missing or mismatched. */\nexport class IngeniumCsrfError extends IngeniumError {\n constructor(message = 'CSRF token validation failed') {\n super(403, 'CSRF_FAILED', message)\n }\n}\n\nconst TOKEN_BYTES = 18\nconst SAFE_METHODS_DEFAULT: readonly string[] = ['GET', 'HEAD', 'OPTIONS', 'TRACE']\nconst COOKIE_NAME_DEFAULT = 'ingenium.csrf'\nconst HEADER_NAMES_DEFAULT: readonly string[] = ['x-csrf-token', 'x-xsrf-token']\n\ninterface ResolvedOptions {\n secrets: string[] // first signs, all verify (rotation)\n storage: 'cookie' | 'session'\n cookie: Required<CsrfCookieOptions>\n ignoreMethods: Set<string>\n value: CsrfValueReader\n skip: ((ctx: IngeniumContext) => boolean | Promise<boolean>) | null\n}\n\n/**\n * CSRF protection middleware. Two modes:\n *\n * - `storage: 'cookie'` (default) — double-submit cookie pattern. A\n * randomly-generated token is HMAC-signed, written to a non-HttpOnly\n * cookie on safe requests, and the client must echo the cookie value\n * back in a header (`X-CSRF-Token`) on unsafe requests. The signature\n * prevents client-side forgery; the same-origin policy prevents\n * cross-origin sites from reading the cookie.\n *\n * - `storage: 'session'` — synchronizer pattern. The token is stored on\n * `ctx.session` and matched against the submitted token. Requires\n * `sessionMiddleware` to run before this middleware.\n *\n * Use `ctx.state.csrfToken` (or call `(ctx as IngeniumContext & { csrfToken(): string }).csrfToken()`)\n * to read the current token to embed in HTML forms or send to a JS client.\n */\nexport function csrfMiddleware(opts: CsrfOptions = {}): IngeniumMiddleware {\n const resolved = resolveOptions(opts)\n if (resolved.storage === 'cookie' && resolved.secrets.length === 0) {\n throw new Error(\"csrfMiddleware: `secret` is required when storage is 'cookie'\")\n }\n\n return async (ctx, next) => {\n if (resolved.skip && (await resolved.skip(ctx))) {\n await next()\n return\n }\n\n // Resolve / mint the expected token for this request.\n let expected = readExpectedToken(ctx, resolved)\n let mintedThisRequest = false\n if (!expected) {\n expected = mintToken(resolved)\n mintedThisRequest = true\n }\n\n // Expose token to handlers via ctx.state.csrfToken AND a method.\n ctx.state.csrfToken = expected\n ;(ctx as IngeniumContext & { csrfToken: () => string }).csrfToken = () => expected as string\n\n const isUnsafe = !resolved.ignoreMethods.has(ctx.method)\n if (isUnsafe) {\n const submitted = await resolved.value(ctx)\n if (!submitted || !tokenMatches(submitted, expected)) {\n throw new IngeniumCsrfError()\n }\n }\n\n await next()\n\n // Issue (or refresh) the cookie on cookie-storage mode.\n if (resolved.storage === 'cookie' && (mintedThisRequest || isUnsafe)) {\n writeCookie(ctx, expected, resolved.cookie)\n } else if (resolved.storage === 'session' && mintedThisRequest) {\n writeSession(ctx, expected)\n }\n }\n}\n\n// ───── Token mint / verify ─────────────────────────────────────────────────\n\nfunction mintToken(opts: ResolvedOptions): string {\n const raw = randomBytes(TOKEN_BYTES).toString('base64url')\n if (opts.storage === 'session' || opts.secrets.length === 0) return raw\n // Signed for double-submit so a forged cookie value can't pass verification.\n const sig = signToken(raw, opts.secrets[0]!)\n return `${raw}.${sig}`\n}\n\nfunction signToken(raw: string, secret: string): string {\n return createHmac('sha256', secret).update(raw).digest('base64url')\n}\n\nfunction tokenMatches(submitted: string, expected: string): boolean {\n const a = Buffer.from(submitted)\n const b = Buffer.from(expected)\n // Length-mismatch already rules out a match; timingSafeEqual requires equal length.\n if (a.length !== b.length) return false\n return timingSafeEqual(a, b)\n}\n\nfunction verifySignedToken(token: string, secrets: readonly string[]): boolean {\n const dot = token.lastIndexOf('.')\n if (dot <= 0) return false\n const raw = token.slice(0, dot)\n const sig = token.slice(dot + 1)\n for (const secret of secrets) {\n const expected = signToken(raw, secret)\n if (expected.length !== sig.length) continue\n if (timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) return true\n }\n return false\n}\n\n// ───── Storage ─────────────────────────────────────────────────────────────\n\nfunction readExpectedToken(ctx: IngeniumContext, opts: ResolvedOptions): string | null {\n if (opts.storage === 'cookie') {\n const cookies = parseCookies(ctx.headers['cookie'])\n const token = cookies[opts.cookie.name]\n if (!token) return null\n if (opts.secrets.length > 0 && !verifySignedToken(token, opts.secrets)) return null\n return token\n }\n // Session storage\n const session = (ctx as IngeniumContext & { session?: { get: (k: string) => unknown } }).session\n if (!session) {\n throw new Error(\"csrfMiddleware: storage='session' requires sessionMiddleware to run first\")\n }\n const token = session.get('csrfToken')\n return typeof token === 'string' && token.length > 0 ? token : null\n}\n\n// TODO: migrate to ctx.cookies — kept inline because csrf uses the\n// double-submit pattern with a non-HttpOnly cookie + HMAC value, which the\n// generic cookie API doesn't model directly.\nfunction writeCookie(ctx: IngeniumContext, token: string, cookie: Required<CsrfCookieOptions>): void {\n const parts: string[] = [`${cookie.name}=${encodeURIComponent(token)}`]\n parts.push(`Path=${cookie.path}`)\n if (cookie.domain) parts.push(`Domain=${cookie.domain}`)\n parts.push(`Max-Age=${cookie.maxAgeSeconds}`)\n parts.push(`SameSite=${cookie.sameSite[0]!.toUpperCase() + cookie.sameSite.slice(1)}`)\n if (cookie.secure) parts.push('Secure')\n if (cookie.httpOnly) parts.push('HttpOnly')\n appendSetCookie(ctx, parts.join('; '))\n}\n\nfunction writeSession(ctx: IngeniumContext, token: string): void {\n const session = (ctx as IngeniumContext & { session?: { set: (k: string, v: unknown) => void } }).session\n if (!session) return\n session.set('csrfToken', token)\n}\n\nfunction appendSetCookie(ctx: IngeniumContext, value: string): void {\n const existing = ctx._headers['set-cookie']\n if (!existing) {\n ctx._headers['set-cookie'] = [value]\n } else if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n ctx._headers['set-cookie'] = [existing, value]\n }\n}\n\nfunction parseCookies(header: string | string[] | undefined): Record<string, string> {\n const out: Record<string, string> = {}\n if (!header) return out\n const flat = Array.isArray(header) ? header.join('; ') : header\n for (const piece of flat.split(';')) {\n const eq = piece.indexOf('=')\n if (eq < 0) continue\n const k = piece.slice(0, eq).trim()\n const v = piece.slice(eq + 1).trim()\n if (!k || k in out) continue // first occurrence wins\n try {\n out[k] = decodeURIComponent(v)\n } catch {\n out[k] = v\n }\n }\n return out\n}\n\n// ───── Options resolution ──────────────────────────────────────────────────\n\nfunction resolveOptions(opts: CsrfOptions): ResolvedOptions {\n const secrets =\n typeof opts.secret === 'string'\n ? [opts.secret]\n : Array.isArray(opts.secret)\n ? [...opts.secret]\n : []\n const storage = opts.storage ?? 'cookie'\n const cookie: Required<CsrfCookieOptions> = {\n name: opts.cookie?.name ?? COOKIE_NAME_DEFAULT,\n path: opts.cookie?.path ?? '/',\n domain: opts.cookie?.domain ?? '',\n sameSite: opts.cookie?.sameSite ?? 'lax',\n secure: opts.cookie?.secure ?? false,\n httpOnly: opts.cookie?.httpOnly ?? false,\n maxAgeSeconds: opts.cookie?.maxAgeSeconds ?? 7 * 24 * 60 * 60,\n }\n const ignoreMethods = new Set((opts.ignoreMethods ?? SAFE_METHODS_DEFAULT).map((m) => m.toUpperCase()))\n const value = opts.value ?? defaultValueReader\n return { secrets, storage, cookie, ignoreMethods, value, skip: opts.skip ?? null }\n}\n\nconst defaultValueReader: CsrfValueReader = (ctx) => {\n for (const name of HEADER_NAMES_DEFAULT) {\n const v = ctx.headers[name]\n if (v) return Array.isArray(v) ? v[0] : v\n }\n const q = ctx.query.get('_csrf')\n return q ?? undefined\n}\n","import type { IngeniumContext } from '../context/context.ts'\nimport {\n IngeniumError,\n IngeniumMethodNotAllowedError,\n IngeniumValidationError,\n} from '../errors.ts'\nimport type { ProblemDetails, ResolvedProblemDetailsOptions } from './types.ts'\n\n/**\n * Maps known framework error codes to short, human-readable titles. Falls\n * back to the standard HTTP reason phrase, then to the error's own message.\n */\nconst TITLES: Readonly<Record<string, string>> = Object.freeze({\n NOT_FOUND: 'Not Found',\n UNAUTHORIZED: 'Unauthorized',\n METHOD_NOT_ALLOWED: 'Method Not Allowed',\n PAYLOAD_TOO_LARGE: 'Payload Too Large',\n VALIDATION_FAILED: 'Validation Failed',\n BAD_REQUEST: 'Bad Request',\n RATE_LIMITED: 'Too Many Requests',\n INTERNAL_ERROR: 'Internal Server Error',\n})\n\n/** Generic HTTP status reason phrases for common codes (fallback for unknown errors). */\nconst STATUS_REASON: Readonly<Record<number, string>> = Object.freeze({\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 409: 'Conflict',\n 413: 'Payload Too Large',\n 415: 'Unsupported Media Type',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n})\n\n/** UPPER_SNAKE_CASE → kebab-case path segment for `type` URIs. */\nfunction codeToSlug(code: string): string {\n return code.toLowerCase().replace(/_/g, '-')\n}\n\n/**\n * Build the `type` field. Returns `'about:blank'` (RFC 7807 default) when\n * no `typeBaseUrl` is configured, otherwise prefixes the slugified code.\n */\nfunction buildType(code: string, baseUrl: string): string {\n if (baseUrl === 'about:blank' || baseUrl === '') return 'about:blank'\n // Avoid double-slash when caller forgot the trailing slash.\n return baseUrl.endsWith('/')\n ? `${baseUrl}${codeToSlug(code)}`\n : `${baseUrl}/${codeToSlug(code)}`\n}\n\n/**\n * Convert a thrown value into an RFC 7807 ProblemDetails object. Handles\n * `IngeniumError` and its subclasses with rich extensions; unknown errors are\n * reported as a generic 500 with `type: 'about:blank'`.\n *\n * Side effect: for `IngeniumMethodNotAllowedError`, the `Allow` header is set\n * on the response so it matches the framework's default boundary behavior.\n */\nexport function toProblemDetails(\n err: unknown,\n opts: ResolvedProblemDetailsOptions,\n ctx: IngeniumContext,\n): ProblemDetails {\n if (err instanceof IngeniumError) {\n const title = TITLES[err.code] ?? STATUS_REASON[err.statusCode] ?? err.message\n const problem: ProblemDetails = {\n type: buildType(err.code, opts.typeBaseUrl),\n title,\n status: err.statusCode,\n detail: err.message,\n }\n\n const instance = opts.instance(ctx)\n if (instance !== undefined) problem.instance = instance\n\n // Carry the framework error code as a non-standard extension so clients\n // can program against it without parsing the `type` URI.\n problem.code = err.code\n\n if (err instanceof IngeniumValidationError) {\n problem.fields = err.fields\n }\n\n if (err instanceof IngeniumMethodNotAllowedError) {\n problem.allowed = err.allowed\n ctx.set('allow', err.allowed.join(', '))\n }\n\n if (opts.includeStack && typeof err.stack === 'string') {\n problem.stack = err.stack\n }\n\n return problem\n }\n\n // Unknown error — generic 500.\n const message = (err as Error)?.message\n const problem: ProblemDetails = {\n type: 'about:blank',\n title: STATUS_REASON[500]!,\n status: 500,\n detail: typeof message === 'string' && message.length > 0 ? message : 'Internal Server Error',\n }\n\n const instance = opts.instance(ctx)\n if (instance !== undefined) problem.instance = instance\n\n if (opts.includeStack && err instanceof Error && typeof err.stack === 'string') {\n problem.stack = err.stack\n }\n\n return problem\n}\n","import type { IngeniumMiddleware } from '../middleware/types.ts'\nimport { toProblemDetails } from './serialize.ts'\nimport type {\n ProblemDetailsOptions,\n ResolvedProblemDetailsOptions,\n} from './types.ts'\n\nconst PROBLEM_CONTENT_TYPE = 'application/problem+json; charset=utf-8'\n\n/**\n * RFC 7807 Problem Details middleware. Wraps downstream handlers in a\n * try/catch and serializes any `IngeniumError` (or unknown error) as\n * `application/problem+json` instead of the framework's default\n * `{ error, code, fields? }` shape.\n *\n * Composition notes:\n * - This sits as a regular middleware in front of user handlers, NOT in\n * place of `app.onError`. If `app.onError` is configured AND it re-throws\n * (or the user handler throws past the onError), this middleware catches\n * the error before it reaches the default boundary.\n * - Composes cleanly with other middleware (e.g. idempotency) — the\n * try/catch is the only thing it does on the way out.\n *\n * @example\n * app.use(ingenium.problemDetails({\n * typeBaseUrl: 'https://api.example.com/errors/',\n * includeStack: process.env.NODE_ENV !== 'production',\n * }))\n */\nexport function problemDetailsMiddleware(opts: ProblemDetailsOptions = {}): IngeniumMiddleware {\n const resolved: ResolvedProblemDetailsOptions = {\n typeBaseUrl: opts.typeBaseUrl ?? 'about:blank',\n includeStack: opts.includeStack ?? false,\n instance: opts.instance ?? ((ctx) => ctx.path),\n }\n\n return async (ctx, next) => {\n try {\n await next()\n } catch (err) {\n // If something downstream already wrote a response (e.g. handler\n // partially wrote then threw), don't clobber it.\n if (ctx._written) throw err\n\n const problem = toProblemDetails(err, resolved, ctx)\n\n // Force the problem+json content-type even if a handler pre-set\n // application/json on the context.\n ctx.set('content-type', PROBLEM_CONTENT_TYPE)\n ctx._statusCode = problem.status\n ctx._body = { kind: 'string', data: JSON.stringify(problem) }\n ctx._written = true\n }\n }\n}\n","import type { CachedResponse, IdempotencyStore } from './types.ts'\n\ninterface Entry {\n value: CachedResponse\n expiresAt: number\n}\n\n/**\n * In-process idempotency cache. Suitable for single-replica deployments and\n * tests; back with Redis when running multiple replicas behind a load\n * balancer (responses cached on one replica won't replay on another).\n *\n * A periodic sweep removes expired entries so long-lived processes don't\n * leak memory across forgotten keys. The sweep timer is `.unref()`'d, so\n * it never keeps the Node event loop alive.\n */\nexport class IdempotencyMemoryStore implements IdempotencyStore {\n private readonly map: Map<string, Entry> = new Map()\n private sweeper: NodeJS.Timeout | null = null\n private sweepIntervalMs = 0\n\n get(key: string): Promise<CachedResponse | null> {\n const entry = this.map.get(key)\n if (!entry) return Promise.resolve(null)\n if (Date.now() >= entry.expiresAt) {\n this.map.delete(key)\n return Promise.resolve(null)\n }\n return Promise.resolve(entry.value)\n }\n\n set(key: string, value: CachedResponse, ttlMs: number): Promise<void> {\n this.map.set(key, { value, expiresAt: Date.now() + ttlMs })\n this.ensureSweeper(ttlMs)\n return Promise.resolve()\n }\n\n delete(key: string): Promise<void> {\n this.map.delete(key)\n return Promise.resolve()\n }\n\n /**\n * Stop the cleanup interval. Safe to call multiple times. Mostly useful\n * in tests; production usage doesn't need this because the timer is\n * already unref'd.\n */\n destroy(): void {\n if (this.sweeper) {\n clearInterval(this.sweeper)\n this.sweeper = null\n }\n this.map.clear()\n }\n\n private ensureSweeper(ttlMs: number): void {\n if (this.sweeper && this.sweepIntervalMs === ttlMs) return\n if (this.sweeper) clearInterval(this.sweeper)\n this.sweepIntervalMs = ttlMs\n this.sweeper = setInterval(() => this.sweep(), ttlMs)\n if (typeof this.sweeper.unref === 'function') this.sweeper.unref()\n }\n\n private sweep(): void {\n const now = Date.now()\n for (const [key, entry] of this.map) {\n if (now >= entry.expiresAt) this.map.delete(key)\n }\n }\n}\n","import { Buffer } from 'node:buffer'\nimport type { IngeniumContext, ResponseBody } from '../context/context.ts'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport { IdempotencyMemoryStore } from './store.ts'\nimport type {\n CachedResponse,\n IdempotencyOptions,\n ResolvedIdempotencyOptions,\n} from './types.ts'\n\nconst DEFAULT_METHODS: readonly HttpMethod[] = ['POST', 'PATCH', 'DELETE']\n\n/**\n * Default cacheable predicate: cache 2xx/3xx/4xx, NOT 5xx. Stripe\n * convention — a transient 500 must not be replayed forever.\n */\nconst DEFAULT_CACHEABLE = (status: number): boolean => status >= 200 && status < 500\n\n/** Authorization-header-derived scope; falls back to `'anon'`. */\nfunction defaultScope(ctx: IngeniumContext): string {\n const auth = ctx.headers['authorization']\n if (typeof auth === 'string' && auth.length > 0) return auth\n if (Array.isArray(auth) && auth.length > 0 && typeof auth[0] === 'string') return auth[0]\n return 'anon'\n}\n\n/** Pull a header value as a single string (first element if it came as an array). */\nfunction readHeader(ctx: IngeniumContext, lowerName: string): string | undefined {\n const v = ctx.headers[lowerName]\n if (typeof v === 'string') return v\n if (Array.isArray(v)) return typeof v[0] === 'string' ? v[0] : undefined\n return undefined\n}\n\n/**\n * Snapshot whatever the handler wrote to `ctx`. Streams are NOT cached —\n * we cannot rewind a `Readable`, so a streamed response makes the request\n * non-idempotent (the second call will run the handler again).\n *\n * Returns `null` to signal \"do not cache\" (stream / nothing written).\n */\nfunction snapshot(ctx: IngeniumContext): CachedResponse | null {\n if (!ctx._written) return null\n const body = ctx._body\n let serialized: string | Buffer | null\n switch (body.kind) {\n case 'none':\n serialized = null\n break\n case 'string':\n serialized = body.data\n break\n case 'buffer':\n // Copy the buffer — caller may reuse the underlying memory.\n serialized = Buffer.from(body.data)\n break\n case 'stream':\n return null\n }\n // Shallow-copy headers; values are strings or string[] (immutable in practice).\n const headersCopy: Record<string, string | string[]> = Object.create(null)\n for (const k of Object.keys(ctx._headers)) {\n const v = ctx._headers[k]\n if (v === undefined) continue\n headersCopy[k] = Array.isArray(v) ? [...v] : v\n }\n return { statusCode: ctx._statusCode, headers: headersCopy, body: serialized }\n}\n\n/** Replay a cached response onto a fresh `ctx`. */\nfunction replay(ctx: IngeniumContext, cached: CachedResponse): void {\n ctx._statusCode = cached.statusCode\n // Replace, not merge — replayed response is authoritative.\n ctx._headers = Object.create(null) as Record<string, string | string[]>\n for (const k of Object.keys(cached.headers)) {\n const v = cached.headers[k]\n if (v === undefined) continue\n ctx._headers[k] = Array.isArray(v) ? [...v] : v\n }\n ctx._headers['idempotent-replayed'] = 'true'\n let nextBody: ResponseBody\n if (cached.body === null) {\n nextBody = { kind: 'none' }\n } else if (typeof cached.body === 'string') {\n nextBody = { kind: 'string', data: cached.body }\n } else {\n nextBody = { kind: 'buffer', data: Buffer.from(cached.body) }\n }\n ctx._body = nextBody\n ctx._written = true\n}\n\n/**\n * Idempotency-Key middleware (per Stripe / IETF idempotency-key draft).\n *\n * Behavior:\n * - Non-mutating method or missing header → pass through.\n * - Mutating method WITH header:\n * 1. Build cache key: `<scope>:<method>:<path>:<idempotency-key>`.\n * 2. Cache hit → replay the cached (status, headers, body) and set\n * `Idempotent-Replayed: true`. Handler does NOT run.\n * 3. Cache miss → run handler. If the response is cacheable (i.e. not a\n * stream and something was written), persist it under the key with\n * the configured TTL.\n * 4. Concurrent in-flight requests for the same key are coordinated via\n * an in-process Promise map: the second request awaits the first and\n * replays its result.\n *\n * Note: the cache key intentionally does NOT include the request body —\n * the spec assumes the client guarantees byte-for-byte identical retries,\n * and reading the body at middleware-entry time would defeat lazy parsing.\n *\n * @example\n * app.use(ingenium.idempotency({\n * store: new IdempotencyMemoryStore(),\n * ttlSeconds: 86_400,\n * }))\n */\nexport function idempotencyMiddleware(opts: IdempotencyOptions = {}): IngeniumMiddleware {\n const resolved: ResolvedIdempotencyOptions = {\n header: (opts.header ?? 'Idempotency-Key').toLowerCase(),\n store: opts.store ?? new IdempotencyMemoryStore(),\n ttlMs: (opts.ttlSeconds ?? 86_400) * 1000,\n scope: opts.scope ?? defaultScope,\n methodSet: new Set(opts.methods ?? DEFAULT_METHODS),\n cacheable: opts.cacheable ?? DEFAULT_CACHEABLE,\n }\n\n if (resolved.ttlMs <= 0) {\n throw new Error('idempotency: ttlSeconds must be > 0')\n }\n\n // Per-key in-flight map. The promise resolves once the first handler\n // finishes and its response has been snapshotted (or with `null` if the\n // response wasn't cacheable — second request then runs the handler).\n const inflight: Map<string, Promise<CachedResponse | null>> = new Map()\n\n return async (ctx, next) => {\n if (!resolved.methodSet.has(ctx.method)) {\n return next()\n }\n\n const headerValue = readHeader(ctx, resolved.header)\n if (!headerValue || headerValue.length === 0) {\n return next()\n }\n\n const scope = resolved.scope(ctx)\n const cacheKey = `${scope}:${ctx.method}:${ctx.path}:${headerValue}`\n\n // 1. Persisted cache hit?\n const existing = await resolved.store.get(cacheKey)\n if (existing) {\n replay(ctx, existing)\n return\n }\n\n // 2. In-flight from a concurrent request?\n const pending = inflight.get(cacheKey)\n if (pending) {\n const result = await pending\n if (result) {\n replay(ctx, result)\n return\n }\n // First request wasn't cacheable — fall through and run the handler.\n }\n\n // 3. Cache miss + no in-flight: take ownership.\n let resolveInflight!: (value: CachedResponse | null) => void\n const ownPromise = new Promise<CachedResponse | null>((res) => { resolveInflight = res })\n inflight.set(cacheKey, ownPromise)\n\n try {\n await next()\n const captured = snapshot(ctx)\n // Honor the `cacheable` predicate — by default 5xx is NOT cached so a\n // transient failure can't poison the key for the entire TTL. When\n // skipped, resolve the in-flight promise with `null` so any waiter\n // re-runs the handler instead of replaying a stale failure.\n if (captured && resolved.cacheable(captured.statusCode)) {\n await resolved.store.set(cacheKey, captured, resolved.ttlMs)\n resolveInflight(captured)\n } else {\n resolveInflight(null)\n }\n } catch (err) {\n // Don't cache failures — clear the in-flight slot so retries can run\n // the handler fresh, and let the error propagate.\n resolveInflight(null)\n throw err\n } finally {\n inflight.delete(cacheKey)\n }\n }\n}\n","import {\n constants as cryptoConstants,\n createHmac,\n createPublicKey,\n verify as cryptoVerify,\n timingSafeEqual,\n type KeyObject,\n} from 'node:crypto'\nimport { Buffer } from 'node:buffer'\nimport type {\n JwtAlgorithm,\n JwtHeader,\n JwtVerified,\n JwtVerifyError,\n} from './types.ts'\n\n/**\n * Per-algorithm wire descriptor.\n *\n * `family` selects the verifier branch; the digest / openssl-name fields are\n * only consulted by the matching family.\n */\ninterface AlgSpec {\n family: 'hmac' | 'rsa' | 'rsa-pss' | 'ecdsa'\n /** node:crypto digest name (`sha256`, `sha384`, `sha512`). HMAC + asymmetric both use it. */\n digest: string\n /** Expected raw signature length for ECDSA (r||s, two equal-sized halves). */\n ecSigLen?: number\n}\n\nconst ALG_SPEC: Readonly<Record<JwtAlgorithm, AlgSpec>> = {\n HS256: { family: 'hmac', digest: 'sha256' },\n HS384: { family: 'hmac', digest: 'sha384' },\n HS512: { family: 'hmac', digest: 'sha512' },\n RS256: { family: 'rsa', digest: 'sha256' },\n RS384: { family: 'rsa', digest: 'sha384' },\n RS512: { family: 'rsa', digest: 'sha512' },\n PS256: { family: 'rsa-pss', digest: 'sha256' },\n PS384: { family: 'rsa-pss', digest: 'sha384' },\n PS512: { family: 'rsa-pss', digest: 'sha512' },\n // ECDSA: r||s lengths come from the curve order — 32B for P-256,\n // 48B for P-384, 66B for P-521 (the curve is 521 bits, padded to 528 = 66B).\n ES256: { family: 'ecdsa', digest: 'sha256', ecSigLen: 64 },\n ES384: { family: 'ecdsa', digest: 'sha384', ecSigLen: 96 },\n ES512: { family: 'ecdsa', digest: 'sha512', ecSigLen: 132 },\n}\n\n/**\n * A verification key as supplied by the caller (post-resolution).\n * - `string` / `Buffer` for HMAC secrets and PEM blobs.\n * - `KeyObject` for pre-built node:crypto keys (and JWKS-derived keys).\n */\nexport type VerifyKeyMaterial = string | Buffer | KeyObject\n\n/** Optional kid-tagged variant — what middleware passes after kid resolution. */\nexport interface KidTaggedKey {\n kid?: string\n key: VerifyKeyMaterial\n}\n\n/** Options accepted by {@link verifyJwt}. Mirrors the relevant subset of `JwtOptions`. */\nexport interface VerifyOptions {\n algorithms: readonly JwtAlgorithm[]\n audience?: string | readonly string[]\n issuer?: string | readonly string[]\n maxAgeSeconds?: number\n clockSkewSeconds?: number\n /** Override \"now\" for deterministic tests. Returns seconds since epoch. */\n nowSeconds?: () => number\n}\n\n/**\n * Decode a base64url-encoded JSON segment. Returns `null` on malformed input\n * (so callers can fold it into the generic `'malformed'` failure mode).\n */\nfunction decodeJsonSegment<T = unknown>(segment: string): T | null {\n if (!segment) return null\n try {\n const buf = Buffer.from(segment, 'base64url')\n if (buf.length === 0) return null\n const parsed = JSON.parse(buf.toString('utf8')) as unknown\n if (parsed === null || typeof parsed !== 'object') return null\n return parsed as T\n } catch {\n return null\n }\n}\n\n/**\n * Constant-time HMAC verification.\n *\n * `timingSafeEqual` requires equal-length buffers — feeding mismatched lengths\n * would itself leak length info via the throw. So we compare `signingInput`'s\n * computed signature against the supplied one only after the explicit length\n * check; both branches return `false` in O(constant) time relative to the\n * caller's view (the throw path never executes).\n */\nfunction hmacVerifies(\n digest: string,\n secret: VerifyKeyMaterial,\n signingInput: string,\n sig: Buffer,\n): boolean {\n // HMAC accepts string or Buffer; KeyObject would be unusual but handle it.\n const secretInput: string | Buffer =\n typeof secret === 'string' || Buffer.isBuffer(secret)\n ? secret\n : secret.export({ format: 'buffer' } as never)\n const expected = createHmac(digest, secretInput).update(signingInput).digest()\n if (sig.length !== expected.length) return false\n return timingSafeEqual(sig, expected)\n}\n\n/**\n * Asymmetric verification via OpenSSL. The key may be a PEM (string/Buffer)\n * or a pre-built `KeyObject`; we normalise via `createPublicKey` once. RSA\n * algorithms (RSxxx) use PKCS1-v1_5; PS* uses PSS (with MGF1 + salt = digest);\n * ECDSA decodes from raw r||s (per JOSE) rather than DER.\n *\n * `crypto.verify` from OpenSSL is constant-time relative to the key — we\n * don't add an extra timing shield ourselves.\n */\nfunction asymmetricVerifies(\n spec: AlgSpec,\n keyMaterial: VerifyKeyMaterial,\n signingInput: string,\n sig: Buffer,\n): boolean {\n let key: KeyObject\n try {\n key =\n typeof keyMaterial === 'string' || Buffer.isBuffer(keyMaterial)\n ? createPublicKey(keyMaterial)\n : keyMaterial\n } catch {\n return false\n }\n\n // ECDSA: spec mandates raw r||s (concatenation of two fixed-length integers).\n // node:crypto's default DSA encoding is DER; we have to set 'ieee-p1363' to\n // get the JOSE wire format. Length-check up front so a malformed sig never\n // hits openssl with garbage.\n if (spec.family === 'ecdsa') {\n if (typeof spec.ecSigLen === 'number' && sig.length !== spec.ecSigLen) return false\n try {\n return cryptoVerify(spec.digest, Buffer.from(signingInput, 'utf8'), {\n key,\n dsaEncoding: 'ieee-p1363',\n }, sig)\n } catch {\n return false\n }\n }\n\n if (spec.family === 'rsa-pss') {\n try {\n return cryptoVerify(spec.digest, Buffer.from(signingInput, 'utf8'), {\n key,\n padding: cryptoConstants.RSA_PKCS1_PSS_PADDING,\n // RFC 7518 §3.5: salt length equals the digest output length.\n saltLength: cryptoConstants.RSA_PSS_SALTLEN_DIGEST,\n }, sig)\n } catch {\n return false\n }\n }\n\n // Plain RSA-PKCS1-v1_5.\n try {\n return cryptoVerify(spec.digest, Buffer.from(signingInput, 'utf8'), key, sig)\n } catch {\n return false\n }\n}\n\n/** Allowed claim resolution — both single value and array forms are common in spec. */\nfunction audienceMatches(claim: unknown, expected: string | readonly string[]): boolean {\n const wanted = typeof expected === 'string' ? [expected] : expected\n if (typeof claim === 'string') return wanted.includes(claim)\n if (Array.isArray(claim)) {\n for (const c of claim) {\n if (typeof c === 'string' && wanted.includes(c)) return true\n }\n }\n return false\n}\n\nfunction issuerMatches(claim: unknown, expected: string | readonly string[]): boolean {\n if (typeof claim !== 'string') return false\n return typeof expected === 'string' ? expected === claim : expected.includes(claim)\n}\n\n/**\n * Pure JWT verifier. No I/O, no logging — returns either a `JwtVerified` or\n * a tagged failure object. The middleware layer is responsible for collapsing\n * every failure into the same `IngeniumUnauthorizedError('Invalid token')` so\n * the wire never reveals which check tripped.\n *\n * `keys` is a flat array because key-resolution (rotation, kid-lookup, JWKS)\n * is the caller's responsibility; this function just tries them in order.\n * Each entry may carry an optional `kid` — when present AND `header.kid` is\n * set, only matching entries are considered. Without a `header.kid`, every\n * entry is tried.\n *\n * `alg: 'none'` is rejected unconditionally, even if for some reason the\n * allowlist were extended to include it. Defence in depth.\n */\nexport function verifyJwt<T = Record<string, unknown>>(\n token: string,\n keys: readonly (VerifyKeyMaterial | KidTaggedKey)[],\n opts: VerifyOptions,\n): JwtVerified<T> | JwtVerifyError {\n if (typeof token !== 'string' || token.length === 0) return { error: 'malformed' }\n\n // Compact serialization: header.payload.signature\n const firstDot = token.indexOf('.')\n if (firstDot <= 0) return { error: 'malformed' }\n const secondDot = token.indexOf('.', firstDot + 1)\n if (secondDot <= firstDot + 1) return { error: 'malformed' }\n if (token.indexOf('.', secondDot + 1) !== -1) return { error: 'malformed' }\n // The signature segment may legally be empty only for 'alg: none', which\n // we reject anyway. Treat empty as malformed.\n if (secondDot === token.length - 1) return { error: 'malformed' }\n\n const headerB64 = token.slice(0, firstDot)\n const payloadB64 = token.slice(firstDot + 1, secondDot)\n const sigB64 = token.slice(secondDot + 1)\n\n const header = decodeJsonSegment<JwtHeader>(headerB64)\n if (!header || typeof header.alg !== 'string') return { error: 'malformed' }\n\n // Hard-reject 'none' BEFORE the allowlist check — even if a buggy caller\n // somehow lets it through. This is the canonical JWT-library footgun.\n if (header.alg === 'none' || header.alg.toLowerCase() === 'none') {\n return { error: 'unsupported_alg' }\n }\n\n const alg = header.alg as JwtAlgorithm\n if (!opts.algorithms.includes(alg)) return { error: 'unsupported_alg' }\n const spec = ALG_SPEC[alg]\n if (!spec) return { error: 'unsupported_alg' }\n\n const payload = decodeJsonSegment<T & Record<string, unknown>>(payloadB64)\n if (!payload) return { error: 'malformed' }\n\n const signingInput = `${headerB64}.${payloadB64}`\n\n // Decode signature once.\n let sig: Buffer\n try {\n sig = Buffer.from(sigB64, 'base64url')\n } catch {\n return { error: 'malformed' }\n }\n if (sig.length === 0) return { error: 'malformed' }\n\n // Filter keys by kid when both sides advertise one. This both narrows the\n // candidate set (perf) and is required for JWKS — the resolver may have\n // returned the entire keyset.\n const headerKid = typeof header.kid === 'string' ? header.kid : null\n const candidates = selectCandidates(keys, headerKid)\n if (candidates.length === 0) {\n // If the caller supplied kid-tagged keys but none matched, we know\n // nothing will verify — surface this as a distinct (internal) reason\n // so the logger can be precise. The wire still gets 'Invalid token'.\n return { error: headerKid ? 'kid_unknown' : 'bad_signature' }\n }\n\n let signatureOk = false\n for (const candidate of candidates) {\n if (spec.family === 'hmac') {\n if (hmacVerifies(spec.digest, candidate, signingInput, sig)) {\n signatureOk = true\n break\n }\n } else {\n if (asymmetricVerifies(spec, candidate, signingInput, sig)) {\n signatureOk = true\n break\n }\n }\n }\n if (!signatureOk) return { error: 'bad_signature' }\n\n // Temporal claims.\n const now = (opts.nowSeconds ?? (() => Math.floor(Date.now() / 1000)))()\n const skew = opts.clockSkewSeconds ?? 5\n const claims = payload as Record<string, unknown>\n\n if (typeof claims.exp === 'number') {\n if (claims.exp <= now - skew) return { error: 'expired' }\n }\n if (typeof claims.nbf === 'number') {\n if (claims.nbf > now + skew) return { error: 'not_yet_valid' }\n }\n if (typeof opts.maxAgeSeconds === 'number') {\n if (typeof claims.iat !== 'number') return { error: 'too_old' }\n if (claims.iat + opts.maxAgeSeconds <= now - skew) return { error: 'too_old' }\n }\n if (opts.audience !== undefined) {\n if (!audienceMatches(claims.aud, opts.audience)) return { error: 'aud_mismatch' }\n }\n if (opts.issuer !== undefined) {\n if (!issuerMatches(claims.iss, opts.issuer)) return { error: 'iss_mismatch' }\n }\n\n return { header, payload, raw: token }\n}\n\n/**\n * Reduce the supplied key array to the set worth trying:\n * - If `header.kid` is set, prefer entries whose `kid` matches. If at least\n * one tagged key matches, ONLY those are tried (no fallback to untagged\n * keys — an attacker shouldn't be able to coerce a kid-tagged JWKS into\n * trying an unrelated rotation key).\n * - If `header.kid` is set but no tagged key matches, AND the array contains\n * untagged keys, try the untagged ones (legacy / single-key callers).\n * - If `header.kid` is absent, try every entry's `key`.\n */\nfunction selectCandidates(\n keys: readonly (VerifyKeyMaterial | KidTaggedKey)[],\n headerKid: string | null,\n): VerifyKeyMaterial[] {\n if (headerKid) {\n const matched: VerifyKeyMaterial[] = []\n let sawAnyTagged = false\n const untagged: VerifyKeyMaterial[] = []\n for (const k of keys) {\n if (isKidTagged(k)) {\n sawAnyTagged = true\n if (k.kid === headerKid) matched.push(k.key)\n } else {\n untagged.push(k)\n }\n }\n if (matched.length > 0) return matched\n // No tag match — fall back to untagged only when nothing was tagged at\n // all (caller didn't intend kid routing). If they tagged some but the\n // header.kid matches none, refuse.\n if (sawAnyTagged) return []\n return untagged\n }\n\n const out: VerifyKeyMaterial[] = []\n for (const k of keys) {\n if (isKidTagged(k)) out.push(k.key)\n else out.push(k)\n }\n return out\n}\n\nfunction isKidTagged(k: VerifyKeyMaterial | KidTaggedKey): k is KidTaggedKey {\n return (\n typeof k === 'object' &&\n k !== null &&\n !Buffer.isBuffer(k) &&\n 'key' in (k as object) &&\n 'kid' in (k as object)\n )\n}\n\n/** Internal helper — exported for tests that want a stable digest map. */\nexport function digestFor(alg: JwtAlgorithm): string {\n return ALG_SPEC[alg].digest\n}\n\n/** Internal helper — surface the alg family for tests / introspection. */\nexport function familyFor(alg: JwtAlgorithm): AlgSpec['family'] {\n return ALG_SPEC[alg].family\n}\n","import { createPublicKey, type KeyObject } from 'node:crypto'\n\n/**\n * In-memory JWKS cache.\n *\n * One entry per URL. Each entry holds the parsed `Map<kid, KeyObject>` and\n * the absolute timestamp at which it expires. A `pending` promise is stored\n * alongside so concurrent callers for the same URL share a single in-flight\n * fetch — we never stampede the upstream IdP.\n */\ninterface CacheEntry {\n keys: Map<string, KeyObject>\n expiresAt: number\n pending: Promise<Map<string, KeyObject>> | null\n}\n\nconst cache = new Map<string, CacheEntry>()\n\n/** JWK shape we accept. We tolerate extra fields and ignore unsupported `kty`. */\ninterface Jwk {\n kty?: string\n kid?: string\n use?: string\n alg?: string\n n?: string\n e?: string\n crv?: string\n x?: string\n y?: string\n // RSA private parts / EC `d` are intentionally ignored — verifier-only.\n [k: string]: unknown\n}\n\ninterface JwksResponse {\n keys?: Jwk[]\n}\n\n/**\n * Fetch + cache a JWKS. Returns a `Map<kid, KeyObject>`.\n *\n * Concurrency: if a fetch is already in flight for `url` we await the same\n * promise, ensuring a thundering-herd of requests collapses to one upstream\n * call. After the fetch resolves, all waiters get the same keys.\n *\n * Failure mode: any thrown error (network, JSON parse, malformed JWK, empty\n * keyset) bubbles as a generic `Error('jwks_fetch_failed')` — the caller is\n * responsible for translating to a wire-safe `IngeniumUnauthorizedError`. We\n * deliberately do NOT serve a stale cache on failure: stale public keys can\n * mean accepting tokens that the IdP has rotated away from.\n */\nexport async function fetchJwks(url: string, ttlMs: number): Promise<Map<string, KeyObject>> {\n const now = Date.now()\n const entry = cache.get(url)\n\n // Fresh cache hit — return synchronously-resolved map.\n if (entry && entry.expiresAt > now && !entry.pending) {\n return entry.keys\n }\n\n // In-flight coalescing: another caller already triggered the fetch.\n if (entry?.pending) {\n return entry.pending\n }\n\n const pending = doFetch(url).then(\n (keys) => {\n cache.set(url, { keys, expiresAt: Date.now() + ttlMs, pending: null })\n return keys\n },\n (err) => {\n // Drop the failed entry so the next caller retries (instead of being\n // pinned to a rejected promise forever).\n cache.delete(url)\n throw err\n },\n )\n\n // Park the in-flight promise so concurrent callers within this tick share it.\n // Preserve the existing `keys` map so reads during refresh have something\n // to fall back on if needed (currently unused — we always await `pending`).\n cache.set(url, {\n keys: entry?.keys ?? new Map(),\n expiresAt: entry?.expiresAt ?? 0,\n pending,\n })\n\n return pending\n}\n\n/** Reset the in-process cache. Tests use this; production code shouldn't need it. */\nexport function clearJwksCache(): void {\n cache.clear()\n}\n\nasync function doFetch(url: string): Promise<Map<string, KeyObject>> {\n let res: Response\n try {\n res = await fetch(url)\n } catch {\n throw new Error('jwks_fetch_failed')\n }\n if (!res.ok) throw new Error('jwks_fetch_failed')\n\n let body: unknown\n try {\n body = await res.json()\n } catch {\n throw new Error('jwks_fetch_failed')\n }\n\n if (!body || typeof body !== 'object') throw new Error('jwks_fetch_failed')\n const jwks = body as JwksResponse\n if (!Array.isArray(jwks.keys) || jwks.keys.length === 0) {\n throw new Error('jwks_fetch_failed')\n }\n\n const out = new Map<string, KeyObject>()\n for (const jwk of jwks.keys) {\n if (!jwk || typeof jwk !== 'object') continue\n if (typeof jwk.kid !== 'string' || jwk.kid.length === 0) continue\n if (jwk.kty !== 'RSA' && jwk.kty !== 'EC') continue\n // EC: only accept the JWT-spec curves. P-521 (note: 521, not 512) is\n // the curve name JOSE uses for ES512 — yes, the off-by-one is in the spec.\n if (jwk.kty === 'EC' && jwk.crv !== 'P-256' && jwk.crv !== 'P-384' && jwk.crv !== 'P-521') {\n continue\n }\n try {\n // node:crypto accepts JWK directly when format is 'jwk'. For RSA it\n // needs `n` + `e`; for EC it needs `crv` + `x` + `y`. Private fields\n // are ignored when we createPublicKey.\n const key = createPublicKey({ key: jwk as never, format: 'jwk' })\n out.set(jwk.kid, key)\n } catch {\n // Skip individual bad keys rather than failing the whole keyset —\n // an IdP rolling a new (broken) key shouldn't blow up verification of\n // tokens signed with the still-valid old keys.\n continue\n }\n }\n\n if (out.size === 0) throw new Error('jwks_fetch_failed')\n return out\n}\n","import { Buffer } from 'node:buffer'\nimport type { KeyObject } from 'node:crypto'\nimport { IngeniumUnauthorizedError } from '../errors.ts'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type {\n JwtAlgorithm,\n JwtHeader,\n JwtKey,\n JwtOptions,\n JwtSecret,\n JwtSecretResolver,\n JwtTokenReader,\n JwtVerified,\n} from './types.ts'\nimport { verifyJwt, type KidTaggedKey, type VerifyKeyMaterial } from './verify.ts'\nimport { fetchJwks } from './jwks.ts'\n\nconst DEFAULT_ALGORITHMS: readonly JwtAlgorithm[] = ['HS256']\nconst DEFAULT_JWKS_TTL_MS = 10 * 60 * 1000\nconst SUPPORTED: ReadonlySet<JwtAlgorithm> = new Set([\n 'HS256', 'HS384', 'HS512',\n 'RS256', 'RS384', 'RS512',\n 'PS256', 'PS384', 'PS512',\n 'ES256', 'ES384', 'ES512',\n])\n\n/** Default token reader — `Authorization: Bearer <token>`. */\nconst defaultGetToken: JwtTokenReader = (ctx) => {\n const raw = ctx.headers['authorization']\n if (!raw) return undefined\n const value = Array.isArray(raw) ? raw[0] : raw\n if (!value) return undefined\n // Bearer scheme is case-insensitive per RFC 6750 §2.1.\n const space = value.indexOf(' ')\n if (space < 0) return undefined\n const scheme = value.slice(0, space)\n if (scheme.toLowerCase() !== 'bearer') return undefined\n const token = value.slice(space + 1).trim()\n return token.length > 0 ? token : undefined\n}\n\n/**\n * Bearer-token JWT verification middleware.\n *\n * Attaches the verified token at `ctx.jwt`. Callers should module-augment\n * `IngeniumContext` for typed access (the framework purposely doesn't ship a\n * baked-in `jwt` field — payload shape is application-specific).\n *\n * @example\n * ```ts\n * declare module 'ingenium' {\n * interface IngeniumContext {\n * jwt?: import('ingenium').JwtVerified<{ sub: string; roles: string[] }>\n * }\n * }\n *\n * import { ingenium } from 'ingenium'\n * const app = ingenium()\n * // HMAC\n * app.use(ingenium.jwt({ secret: process.env.JWT_SECRET! }))\n * // RSA via JWKS (Auth0, Okta, Cognito, Clerk, Supabase, ...)\n * app.use(ingenium.jwt({\n * secret: [],\n * algorithms: ['RS256'],\n * jwksUrl: 'https://example.auth0.com/.well-known/jwks.json',\n * issuer: 'https://example.auth0.com/',\n * audience: 'https://api.example.com',\n * }))\n * ```\n *\n * Security choices:\n * - Default leeway (`clockSkewSeconds`) is **5 seconds** — enough for typical\n * multi-host clock drift, small enough that an expired token does not stay\n * usable for long.\n * - HMAC signature comparison uses `crypto.timingSafeEqual` after an explicit\n * length check inside {@link verifyJwt}; asymmetric verification uses\n * `crypto.verify` (constant-time within OpenSSL).\n * - The algorithm allowlist is enforced at verify time. Even if an attacker\n * crafts `alg: 'RS256'` and we have a matching JWKS key, verification fails\n * unless `RS256` appears in `algorithms`. This is the canonical defence\n * against algorithm-confusion attacks.\n * - `'none'` is rejected unconditionally, regardless of the allowlist.\n * - The wire-facing error is always `IngeniumUnauthorizedError('Invalid token')`\n * regardless of which check failed (signature vs exp vs aud) — this avoids\n * handing attackers an oracle. Detailed reasons go to `opts.logger` (or\n * `process.emitWarning` if no logger is supplied).\n */\nexport function jwtMiddleware<T = Record<string, unknown>>(\n opts: JwtOptions<T>,\n): IngeniumMiddleware {\n // ── Construction-time validation ─────────────────────────────────────────\n if (opts == null) {\n throw new Error('jwtMiddleware: options object is required')\n }\n // `secret` may be an empty array when the caller is leaning entirely on\n // `jwksUrl` for key material — treat that as a valid configuration.\n const hasJwks = typeof opts.jwksUrl === 'string' && opts.jwksUrl.length > 0\n if ((opts.secret as unknown) === undefined || opts.secret === null) {\n if (!hasJwks) {\n throw new Error('jwtMiddleware: `secret` (or `jwksUrl`) is required')\n }\n }\n\n const algorithms = (opts.algorithms ?? DEFAULT_ALGORITHMS).slice() as JwtAlgorithm[]\n if (algorithms.length === 0) {\n throw new Error('jwtMiddleware: `algorithms` must contain at least one algorithm')\n }\n for (const alg of algorithms) {\n // 'none' is never permitted, even if a caller adds it to the allowlist.\n if ((alg as unknown as string) === 'none') {\n throw new Error('jwtMiddleware: `alg: \"none\"` is forbidden')\n }\n if (!SUPPORTED.has(alg)) {\n throw new Error(`jwtMiddleware: unsupported algorithm ${String(alg)}`)\n }\n }\n\n const required = opts.required ?? true\n const clockSkewSeconds = opts.clockSkewSeconds ?? 5\n const jwksCacheMs = opts.jwksCacheMs ?? DEFAULT_JWKS_TTL_MS\n const jwksUrl = hasJwks ? opts.jwksUrl! : null\n const getToken = opts.getToken ?? defaultGetToken\n const logger = opts.logger ?? ((event) => {\n process.emitWarning(`jwt verification failed: ${event.reason}`, 'IngeniumJwtWarning')\n })\n\n const staticKeys = opts.secret != null && typeof opts.secret !== 'function'\n ? normaliseStaticKeys(opts.secret as JwtKey | JwtKey[])\n : []\n const keyResolver =\n typeof opts.secret === 'function'\n ? (opts.secret as JwtSecretResolver<T>)\n : null\n\n return async (ctx, next) => {\n const token = await getToken(ctx)\n if (!token) {\n if (required) {\n // Missing token IS allowed to leak (no secret material involved).\n throw new IngeniumUnauthorizedError('Missing token')\n }\n await next()\n return\n }\n\n // Peek the header so resolvers / JWKS can route by `kid`. Malformed\n // tokens still reach the verifier so they get the canonical error.\n const peeked = peekHeader(token)\n\n // Build the candidate key list for this request.\n let keys: (VerifyKeyMaterial | KidTaggedKey)[]\n try {\n keys = await collectKeys({\n peeked,\n staticKeys,\n keyResolver,\n jwksUrl,\n jwksCacheMs,\n })\n } catch (err) {\n if (err instanceof IngeniumUnauthorizedError) throw err\n const reason = err instanceof Error ? err.message : 'key_resolution_failed'\n logger({ reason })\n throw new IngeniumUnauthorizedError('Invalid token')\n }\n\n if (keys.length === 0) {\n logger({ reason: 'no_keys_available' })\n throw new IngeniumUnauthorizedError('Invalid token')\n }\n\n // Build VerifyOptions without spreading undefined keys (exactOptionalPropertyTypes).\n const verifyOpts: Parameters<typeof verifyJwt>[2] = { algorithms, clockSkewSeconds }\n if (opts.audience !== undefined) verifyOpts.audience = opts.audience\n if (opts.issuer !== undefined) verifyOpts.issuer = opts.issuer\n if (opts.maxAgeSeconds !== undefined) verifyOpts.maxAgeSeconds = opts.maxAgeSeconds\n const result = verifyJwt<T>(token, keys, verifyOpts)\n\n if ('error' in result) {\n logger({ reason: result.error })\n throw new IngeniumUnauthorizedError('Invalid token')\n }\n\n ;(ctx as IngeniumContext & { jwt?: JwtVerified<T> }).jwt = result\n await next()\n }\n}\n\n/**\n * Normalise the static `secret` option to a flat array of either raw key\n * material or kid-tagged entries that `verifyJwt` understands.\n *\n * Accepts string / Buffer / KeyObject and the `{ kid, key }` wrapper.\n */\nfunction normaliseStaticKeys(secret: JwtKey | JwtKey[]): (VerifyKeyMaterial | KidTaggedKey)[] {\n const list = Array.isArray(secret) ? secret : [secret]\n if (list.length === 0) {\n // An empty literal array IS allowed when paired with jwksUrl; the\n // top-level construction-time check already validated that constraint.\n return []\n }\n const out: (VerifyKeyMaterial | KidTaggedKey)[] = []\n for (const k of list) {\n out.push(coerceJwtKey(k))\n }\n return out\n}\n\nfunction coerceJwtKey(k: JwtKey): VerifyKeyMaterial | KidTaggedKey {\n if (typeof k === 'string') {\n if (k.length === 0) {\n throw new Error('jwtMiddleware: secret string must not be empty')\n }\n return k\n }\n if (Buffer.isBuffer(k)) return k\n if (isKeyObject(k)) return k\n if (typeof k === 'object' && k !== null && 'kid' in k && 'key' in k) {\n if (typeof k.kid !== 'string' || k.kid.length === 0) {\n throw new Error('jwtMiddleware: keyed entry requires a non-empty `kid`')\n }\n const key = k.key\n if (typeof key === 'string') {\n if (key.length === 0) throw new Error('jwtMiddleware: keyed entry `key` must not be empty')\n return { kid: k.kid, key }\n }\n if (Buffer.isBuffer(key) || isKeyObject(key)) return { kid: k.kid, key }\n }\n throw new Error('jwtMiddleware: invalid `secret` entry — expected string, Buffer, KeyObject, or { kid, key }')\n}\n\nfunction isKeyObject(v: unknown): v is KeyObject {\n // Avoid a hard import-time check; KeyObjects from node:crypto carry a\n // distinctive `asymmetricKeyType` getter or `type` property of\n // 'public' | 'private' | 'secret'.\n if (typeof v !== 'object' || v === null) return false\n const t = (v as { type?: unknown }).type\n return t === 'public' || t === 'private' || t === 'secret'\n}\n\ninterface CollectKeysCtx<T> {\n peeked: JwtHeader | null\n staticKeys: (VerifyKeyMaterial | KidTaggedKey)[]\n keyResolver: JwtSecretResolver<T> | null\n jwksUrl: string | null\n jwksCacheMs: number\n}\n\nasync function collectKeys<T>(ctx: CollectKeysCtx<T>): Promise<(VerifyKeyMaterial | KidTaggedKey)[]> {\n const out: (VerifyKeyMaterial | KidTaggedKey)[] = ctx.staticKeys.slice()\n\n if (ctx.keyResolver) {\n const resolved = await ctx.keyResolver(ctx.peeked ?? ({ alg: '' } as JwtHeader))\n if (resolved == null) {\n throw new Error('secret_resolver_returned_empty')\n }\n if (typeof resolved === 'string') {\n if (resolved.length === 0) throw new Error('secret_resolver_returned_empty')\n out.push(resolved)\n } else {\n out.push(coerceJwtKey(resolved as JwtKey))\n }\n }\n\n if (ctx.jwksUrl) {\n let jwks: Map<string, KeyObject>\n try {\n jwks = await fetchJwks(ctx.jwksUrl, ctx.jwksCacheMs)\n } catch {\n // Don't leak upstream details to clients OR to the logger reason —\n // a single canonical reason is enough for ops.\n throw new IngeniumUnauthorizedError('Token key fetch failed')\n }\n const headerKid = ctx.peeked && typeof ctx.peeked.kid === 'string' ? ctx.peeked.kid : null\n if (headerKid) {\n const match = jwks.get(headerKid)\n if (match) out.push({ kid: headerKid, key: match })\n // No-match isn't fatal here; verifier returns kid_unknown if the\n // entire candidate set is empty after key selection.\n } else {\n // No kid on the token — try every key in the JWKS as a tagged entry.\n for (const [kid, key] of jwks) {\n out.push({ kid, key })\n }\n // Also expose them untagged so the verifier's `selectCandidates` will\n // try them when the header lacks `kid`.\n for (const [, key] of jwks) {\n out.push(key)\n }\n }\n }\n\n return out\n}\n\n/** Best-effort header peek for resolver routing. Returns null on malformed tokens. */\nfunction peekHeader(token: string): JwtHeader | null {\n const dot = token.indexOf('.')\n if (dot <= 0) return null\n try {\n const buf = Buffer.from(token.slice(0, dot), 'base64url')\n if (buf.length === 0) return null\n const parsed = JSON.parse(buf.toString('utf8')) as unknown\n if (parsed === null || typeof parsed !== 'object') return null\n return parsed as JwtHeader\n } catch {\n return null\n }\n}\n\n// Backwards-compat re-exports for downstream code that imported these names.\nexport type { JwtSecret, JwtSecretResolver }\n","import { timingSafeEqual } from 'node:crypto'\nimport { Buffer } from 'node:buffer'\nimport { IngeniumUnauthorizedError } from '../errors.ts'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { ApiKeyLogger, ApiKeyOptions, ApiKeyValidator } from './types.ts'\n\n/**\n * API-key authentication middleware.\n *\n * Attaches the validated key string at `ctx.apiKey`. Callers should\n * module-augment `IngeniumContext` for typed access:\n *\n * @example\n * ```ts\n * declare module 'ingenium' {\n * interface IngeniumContext { apiKey?: string }\n * }\n *\n * import { ingenium } from 'ingenium'\n * const app = ingenium()\n * app.use(ingenium.apiKey({\n * keys: process.env.API_KEYS!.split(','),\n * scheme: 'ApiKey',\n * query: 'api_key',\n * }))\n * ```\n *\n * Security choices:\n * - Allow-list comparisons go through `crypto.timingSafeEqual` after an\n * explicit length check, so neither equality nor length leaks via timing.\n * - The wire-facing error is always `IngeniumUnauthorizedError('Invalid API key')`\n * regardless of which lookup failed (header vs scheme vs query) — no\n * oracle for which transport surface the legit key uses.\n * - Custom validators get the candidate key + ctx; their boolean result is\n * trusted as-is. Validators should be constant-time when comparing keys.\n */\nexport function apiKeyMiddleware(opts: ApiKeyOptions): IngeniumMiddleware {\n // ── Construction-time validation ─────────────────────────────────────────\n if (opts == null || opts.keys === undefined || opts.keys === null) {\n throw new Error('apiKeyMiddleware: `keys` is required')\n }\n const validator = resolveValidator(opts.keys)\n const headerName = (opts.header ?? 'x-api-key').toLowerCase()\n const queryParam = opts.query ?? null\n const scheme = opts.scheme ?? null\n const schemeLower = scheme ? scheme.toLowerCase() : null\n const required = opts.required ?? true\n const logger: ApiKeyLogger =\n opts.logger ?? ((event) => process.emitWarning(`api-key auth failed: ${event.reason}`, 'IngeniumApiKeyWarning'))\n\n return async (ctx, next) => {\n const key = readKey(ctx, headerName, schemeLower, queryParam)\n if (!key) {\n if (required) {\n // Missing-key surface is not an oracle — there is no secret material\n // to compare against, so we use a distinct message.\n throw new IngeniumUnauthorizedError('Missing API key')\n }\n await next()\n return\n }\n\n let ok = false\n try {\n ok = await validator(key, ctx)\n } catch (err) {\n logger({ reason: 'validator_threw' })\n throw new IngeniumUnauthorizedError('Invalid API key')\n }\n if (!ok) {\n logger({ reason: 'no_match' })\n throw new IngeniumUnauthorizedError('Invalid API key')\n }\n\n ;(ctx as IngeniumContext & { apiKey?: string }).apiKey = key\n await next()\n }\n}\n\n/** Build a validator from either an allow-list or a user-supplied function. */\nfunction resolveValidator(keys: readonly string[] | ApiKeyValidator): ApiKeyValidator {\n if (typeof keys === 'function') return keys\n if (!Array.isArray(keys)) {\n throw new Error('apiKeyMiddleware: `keys` must be a string[] or a validator function')\n }\n if (keys.length === 0) {\n throw new Error('apiKeyMiddleware: `keys` array must contain at least one key')\n }\n // Pre-encode the allow-list once, at construction, so the per-request path\n // does no allocation work beyond hashing the candidate buffer.\n const allow: Buffer[] = []\n for (const k of keys) {\n if (typeof k !== 'string' || k.length === 0) {\n throw new Error('apiKeyMiddleware: every key in the array must be a non-empty string')\n }\n allow.push(Buffer.from(k, 'utf8'))\n }\n return (candidate) => {\n const cand = Buffer.from(candidate, 'utf8')\n // We deliberately walk the entire list even after a match — a length-\n // dependent early-out would let an attacker probe how many keys exist\n // by measuring response time against length-classes. The list is small\n // and bounded by the user.\n let matched = false\n for (const a of allow) {\n if (a.length !== cand.length) continue\n if (timingSafeEqual(a, cand)) matched = true\n }\n return matched\n }\n}\n\n/**\n * Read the candidate key from the request, in priority order:\n * 1. The configured header (default `x-api-key`).\n * 2. The configured `Authorization` scheme, if any.\n * 3. The configured query parameter, if any.\n *\n * Returns `null` when no surface produced a non-empty key.\n */\nfunction readKey(\n ctx: IngeniumContext,\n headerName: string,\n schemeLower: string | null,\n queryParam: string | null,\n): string | null {\n const headerVal = ctx.headers[headerName]\n if (headerVal) {\n const v = Array.isArray(headerVal) ? headerVal[0] : headerVal\n if (v && v.length > 0) return v\n }\n\n if (schemeLower) {\n const auth = ctx.headers['authorization']\n if (auth) {\n const v = Array.isArray(auth) ? auth[0] : auth\n if (v) {\n const space = v.indexOf(' ')\n if (space > 0) {\n const s = v.slice(0, space).toLowerCase()\n if (s === schemeLower) {\n const tail = v.slice(space + 1).trim()\n if (tail.length > 0) return tail\n }\n }\n }\n }\n }\n\n if (queryParam) {\n const q = ctx.query.get(queryParam)\n if (q && q.length > 0) return q\n }\n\n return null\n}\n","import type { Parameter } from './types.ts'\n\n/**\n * Extract OpenAPI `path` parameter descriptors from a Ingenium route\n * pattern. Mirrors the path syntax documented in `API.md`:\n *\n * - `/users/:id` → required string param `id`\n * - `/users/:id?` → optional string param `id`\n * - `/files/*path` → required string param `path` (greedy tail)\n *\n * All extracted params get `schema: { type: 'string' }` since Ingenium\n * preserves URL segments as raw strings; consumers can override the schema\n * via `app.describe()` if they want a tighter type (e.g. integer ids).\n *\n * Pure function: deterministic, no allocations beyond the result array.\n *\n * @example\n * extractPathParams('/users/:id/posts/:slug?')\n * // [\n * // { name: 'id', in: 'path', required: true, schema: { type: 'string' } },\n * // { name: 'slug', in: 'path', required: false, schema: { type: 'string' } },\n * // ]\n */\nexport function extractPathParams(path: string): Parameter[] {\n if (!path) return []\n const params: Parameter[] = []\n const segments = path.split('/')\n\n for (const seg of segments) {\n if (!seg) continue\n if (seg[0] === ':') {\n // Trim a single trailing `?` to detect optionality.\n const isOptional = seg.endsWith('?')\n const name = isOptional ? seg.slice(1, -1) : seg.slice(1)\n if (!name) continue\n params.push({\n name,\n in: 'path',\n // OpenAPI 3.1: path parameters MUST be required: true. If the route\n // declares an optional segment, the server actually accepts two\n // distinct paths (with and without the segment). For correctness in\n // generated specs, we still emit required: true and surface the\n // optionality via an `x-rift-optional` extension; tools that need it\n // can split the path themselves.\n required: !isOptional,\n schema: { type: 'string' },\n ...(isOptional ? { 'x-rift-optional': true } : {}),\n })\n } else if (seg[0] === '*') {\n const name = seg.slice(1) || 'wildcard'\n params.push({\n name,\n in: 'path',\n required: true,\n schema: { type: 'string' },\n 'x-rift-wildcard': true,\n })\n }\n }\n\n return params\n}\n","import type { IngeniumApp } from '../app.ts'\nimport { isStandardSchema } from '../schema/standard.ts'\nimport { Router, flattenRouter } from '../router/router.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport { descriptorKey, mergeDescriptor, type RouteDescriptor } from './describe.ts'\nimport { extractPathParams } from './extract-params.ts'\nimport type {\n Components,\n Info,\n MediaType,\n OpenApiSpec,\n Operation,\n PathItem,\n RequestBody,\n Response,\n Schema,\n SecurityRequirement,\n SecurityScheme,\n Server,\n Tag,\n} from './types.ts'\n\n/** Public options for `generateOpenApi(app, opts)`. */\nexport interface GenerateOpenApiOptions {\n info: Info\n servers?: Server[]\n tags?: Tag[]\n security?: SecurityRequirement[]\n /**\n * Auto-tag generated operations by path prefix. The longest matching\n * prefix wins. Routes that already have `tags` in their descriptor are\n * left alone.\n *\n * @example { '/users': 'users', '/auth': 'auth' }\n */\n tagsByPrefix?: Record<string, string>\n /**\n * Hide routes whose path matches any entry. Strings match exactly,\n * RegExps are tested against the full path.\n */\n excludePaths?: (string | RegExp)[]\n /** Pass-through `components.securitySchemes`. */\n securitySchemes?: Record<string, SecurityScheme>\n /**\n * Optional additional schemas to merge into `components.schemas`. Useful\n * when you reference shared models via `$ref: '#/components/schemas/X'`.\n */\n componentSchemas?: Record<string, Schema>\n}\n\n/**\n * Generate an OpenAPI 3.1 spec from a composed (or uncomposed) IngeniumApp.\n * Walks the registration journal — does not require `compose()` to have run.\n *\n * Schema-conversion strategy (in priority order):\n * 1. If a request/response schema has a `toJsonSchema()` method (Zod 3.24+,\n * ArkType, Effect Schema, etc.), call it.\n * 2. If it looks like a Standard Schema (has `~standard`), emit `{}` plus\n * `x-schema-source: '<vendor>-untranslated'` as a TODO marker.\n * 3. Otherwise, pass the value through unchanged (assumed JSON Schema).\n */\nexport function generateOpenApi(\n app: IngeniumApp,\n opts: GenerateOpenApiOptions,\n): OpenApiSpec {\n const router = getRouter(app)\n const descriptors = getDescriptors(app)\n const flat = flattenRouter(router)\n\n const paths: Record<string, PathItem> = {}\n const tagsByPrefix = sortedTagsByPrefix(opts.tagsByPrefix)\n const exclude = opts.excludePaths ?? []\n\n for (const route of flat.routes) {\n if (isExcluded(route.path, exclude)) continue\n\n const desc = descriptors.get(descriptorKey(route.method, route.path))\n if (desc?.hidden) continue\n\n const oasPath = toOpenApiPath(route.path)\n const item: PathItem = paths[oasPath] ?? (paths[oasPath] = {})\n\n const op: Operation = {\n parameters: extractPathParams(route.path),\n responses: { default: { description: 'Default response' } },\n }\n\n // Auto-tag by prefix if no descriptor tags were provided.\n if (!desc?.tags) {\n const tag = matchTag(route.path, tagsByPrefix)\n if (tag) op.tags = [tag]\n }\n\n mergeDescriptor(op, desc)\n\n // Convert any Standard/Zod-style schemas inside requestBody.content.\n if (op.requestBody) {\n op.requestBody = convertRequestBodySchemas(op.requestBody)\n }\n if (op.responses) {\n const r: Record<string, Response> = {}\n for (const k of Object.keys(op.responses)) {\n r[k] = convertResponseSchemas(op.responses[k]!)\n }\n op.responses = r\n }\n\n // PathItem's method keys are typed as Operation but `keyof PathItem` widens\n // to include `parameters` / `summary` / `description`. Cast the slot.\n ;(item as Record<string, Operation>)[methodKey(route.method)] = op\n }\n\n const components: Components = {}\n if (opts.securitySchemes) components.securitySchemes = opts.securitySchemes\n if (opts.componentSchemas) components.schemas = opts.componentSchemas\n\n const spec: OpenApiSpec = {\n openapi: '3.1.0',\n info: opts.info,\n paths,\n }\n if (opts.servers) spec.servers = opts.servers\n if (opts.tags) spec.tags = opts.tags\n if (opts.security) spec.security = opts.security\n if (Object.keys(components).length > 0) spec.components = components\n\n return spec\n}\n\n// ───── helpers ──────────────────────────────────────────────────────────────\n\n/** Reach into the app's private `router` field — public surface intentionally narrow. */\nfunction getRouter(app: IngeniumApp): Router {\n const r = (app as unknown as { router?: Router })['router']\n if (!(r instanceof Router)) {\n throw new TypeError(\n 'generateOpenApi: app.router is not a Router instance — pass the value returned by `ingenium()`.',\n )\n }\n return r\n}\n\n/** Reach into the descriptor map (set up by the integration in app.ts). */\nfunction getDescriptors(app: IngeniumApp): Map<string, RouteDescriptor> {\n const m = (app as unknown as { _routeDescriptors?: Map<string, RouteDescriptor> })['_routeDescriptors']\n return m instanceof Map ? m : new Map()\n}\n\n/** Convert Ingenium path syntax to OpenAPI: `:id` → `{id}`, `*path` → `{path}`. */\nfunction toOpenApiPath(path: string): string {\n if (!path) return '/'\n const out = path\n .split('/')\n .map((seg) => {\n if (!seg) return seg\n if (seg[0] === ':') {\n const isOpt = seg.endsWith('?')\n const name = isOpt ? seg.slice(1, -1) : seg.slice(1)\n return `{${name}}`\n }\n if (seg[0] === '*') {\n const name = seg.slice(1) || 'wildcard'\n return `{${name}}`\n }\n return seg\n })\n .join('/')\n return out || '/'\n}\n\nfunction methodKey(m: HttpMethod): keyof PathItem {\n return m.toLowerCase() as keyof PathItem\n}\n\nfunction isExcluded(path: string, excludes: (string | RegExp)[]): boolean {\n for (const ex of excludes) {\n if (typeof ex === 'string') {\n if (ex === path) return true\n } else if (ex.test(path)) {\n return true\n }\n }\n return false\n}\n\nfunction sortedTagsByPrefix(map: Record<string, string> | undefined): [string, string][] {\n if (!map) return []\n return Object.entries(map).sort((a, b) => b[0].length - a[0].length)\n}\n\nfunction matchTag(path: string, tagsByPrefix: [string, string][]): string | undefined {\n for (const [prefix, tag] of tagsByPrefix) {\n if (path === prefix || path.startsWith(prefix + '/') || path.startsWith(prefix)) {\n return tag\n }\n }\n return undefined\n}\n\nfunction convertRequestBodySchemas(rb: RequestBody): RequestBody {\n const out: RequestBody = { ...rb, content: {} }\n for (const [type, media] of Object.entries(rb.content)) {\n out.content[type] = convertMediaSchema(media)\n }\n return out\n}\n\nfunction convertResponseSchemas(res: Response): Response {\n if (!res.content) return res\n const next: Response = { ...res, content: {} }\n for (const [type, media] of Object.entries(res.content)) {\n next.content![type] = convertMediaSchema(media)\n }\n return next\n}\n\nfunction convertMediaSchema(media: MediaType): MediaType {\n if (!media.schema) return media\n const converted = toJsonSchema(media.schema)\n if (converted === media.schema) return media\n return { ...media, schema: converted }\n}\n\n/**\n * Best-effort schema conversion. Returns the input unchanged if it's already\n * a plain JSON Schema; otherwise tries known conversion paths.\n */\nfunction toJsonSchema(schema: unknown): Schema {\n if (schema === null || typeof schema !== 'object') return schema as Schema\n\n // 1. Native `toJsonSchema()` (Zod 3.24+, ArkType, Effect Schema, etc.)\n const maybe = schema as { toJsonSchema?: () => unknown }\n if (typeof maybe.toJsonSchema === 'function') {\n try {\n const out = maybe.toJsonSchema()\n if (out && typeof out === 'object') return out as Schema\n } catch {\n // fall through to placeholder\n }\n }\n\n // 2. Standard Schema fallback — emit a marker so users know to add a\n // converter. We can't introspect the validator without running it.\n if (isStandardSchema(schema)) {\n const vendor = schema['~standard'].vendor || 'unknown'\n return { 'x-schema-source': `${vendor}-untranslated` }\n }\n\n // 3. Pass through (assumed JSON Schema literal).\n return schema as Schema\n}\n","import type { IngeniumApp } from '../app.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { IngeniumHandler } from '../middleware/types.ts'\nimport { generateOpenApi, type GenerateOpenApiOptions } from './generate.ts'\nimport type { OpenApiSpec } from './types.ts'\n\n/**\n * Build a route handler that serves the generated OpenAPI spec as JSON.\n *\n * The spec is generated lazily on the first request that hits this handler\n * and cached on the app under a private symbol. The cache invalidates when\n * the registration journal length changes — i.e. when new routes are added —\n * so live-registered routes are reflected on the next request.\n *\n * @example\n * app.get('/openapi.json', ingenium.openapiHandler({\n * info: { title: 'My API', version: '1.0.0' },\n * }))\n */\nexport function openapiHandler(opts: GenerateOpenApiOptions): IngeniumHandler {\n type Cache = { journalLen: number; descriptorVer: number; spec: OpenApiSpec }\n let cache: Cache | null = null\n\n return (ctx: IngeniumContext): void => {\n const app = resolveApp(ctx)\n if (!app) {\n // The integration shim stamps `ctx.state._ingeniumApp` for us; if it's\n // missing the user is on an older app build that hasn't applied the\n // shim. Surface a clear error rather than silently emitting an empty\n // spec.\n ctx.json(\n {\n error: 'openapiHandler: ctx.state._ingeniumApp is missing — apply the integration shim from src/_pending-context-additions/openapi.ts',\n },\n 500,\n )\n return\n }\n\n const journalLen = readJournalLen(app)\n const descriptorVer = readDescriptorVersion(app)\n\n if (\n cache === null\n || cache.journalLen !== journalLen\n || cache.descriptorVer !== descriptorVer\n ) {\n cache = { journalLen, descriptorVer, spec: generateOpenApi(app, opts) }\n }\n ctx.json(cache.spec)\n }\n}\n\n/**\n * Pull the owning IngeniumApp off the context. We stash a reference under\n * `ctx.state._ingeniumApp` from the integration shim in app.ts; if it's\n * missing (older app, no integration), fall back to `ctx.state.app`.\n */\nfunction resolveApp(ctx: IngeniumContext): IngeniumApp | null {\n const fromState = (ctx.state as Record<string, unknown>)._ingeniumApp\n ?? (ctx.state as Record<string, unknown>).app\n return (fromState as IngeniumApp | undefined) ?? null\n}\n\nfunction readJournalLen(app: IngeniumApp): number {\n const router = (app as unknown as { router?: { journal: unknown[] } }).router\n return router?.journal?.length ?? 0\n}\n\nfunction readDescriptorVersion(app: IngeniumApp): number {\n // Bumped by `app.describe()` so descriptor edits invalidate the cache too.\n return (app as unknown as { _routeDescriptorVersion?: number })._routeDescriptorVersion ?? 0\n}\n","/** HTTP methods supported by the router. */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport const HTTP_METHODS: readonly HttpMethod[] = [\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'HEAD',\n 'OPTIONS',\n] as const\n\n/**\n * Recursively extracts named params from a path string at the type level.\n *\n * - `:name` → required string\n * - `:name?` → optional string (becomes `string | undefined`)\n * - `:name(regex)` → required string. The regex is type-stripped here, but\n * the constraint IS enforced at runtime by the trie\n * (`RouterTrie.find` tests the segment against the\n * compiled, fully-anchored pattern), so the `string`\n * type is honest about the matched shape.\n * Note: number-narrowing (typing `:id(\\d+)` as `number`)\n * remains deferred — constrained params stay `string`.\n * - `*name` → required string (greedy wildcard tail)\n *\n * @example\n * type P = ExtractParams<'/users/:id(\\\\d+)/posts/:slug?'>\n * // { id: string; slug?: string | undefined }\n */\nexport type ExtractParams<Path extends string> = Path extends `${string}:${infer Param}/${infer Rest}`\n ? ParamRecord<Param> & ExtractParams<`/${Rest}`>\n : Path extends `${string}:${infer Param}`\n ? ParamRecord<Param>\n : Path extends `${string}*${infer Wild}`\n ? { [K in Wild]: string }\n : EmptyParams\n\ntype EmptyParams = Record<string, never>\n\n/**\n * Drop a single parenthesized constraint group from a param name.\n * `id(\\\\d+)` → `id`\n * `id(\\\\d+)?` → `id?` (optionality marker preserved for ParamRecord)\n * `id` → `id` (no-op when no constraint present)\n */\ntype StripConstraint<P extends string> = P extends `${infer Head}(${string})${infer Tail}`\n ? `${Head}${Tail}`\n : P\n\ntype ParamRecord<P extends string> = StripConstraint<P> extends `${infer Name}?`\n ? { [K in Name]?: string }\n : { [K in StripConstraint<P>]: string }\n","/**\n * `safeJsonStringify(value, opts?)` — a lenient `JSON.stringify` that never\n * throws on circular references or `BigInt` values.\n *\n * Behavior:\n * - Circular references → replaced with the string `'[Circular]'`.\n * - `BigInt` values → serialized as a JSON string (e.g. `1n` → `\"1\"`).\n * This preserves precision and is reversible by the caller; if you need a\n * different convention, pass your own `replacer`.\n * - Symbol values → omitted (matches `JSON.stringify` default).\n * - Functions → omitted (matches `JSON.stringify` default).\n *\n * Intended for opt-in use by callers who want lenient behavior — the\n * default `ctx.json()` path remains strict and surfaces a\n * `IngeniumUnserializableError` so the bug is visible.\n *\n * @example\n * import { safeJsonStringify } from 'ingenium'\n * ctx.send(safeJsonStringify(value), 200)\n * ctx.set('content-type', 'application/json; charset=utf-8')\n */\n\n/** Options for `safeJsonStringify`. */\nexport interface SafeJsonStringifyOptions {\n /**\n * Pass-through to `JSON.stringify`'s third argument — number of spaces or\n * indent string for pretty-printing. Defaults to no indentation.\n */\n space?: string | number\n /**\n * Optional user replacer applied AFTER the cycle/BigInt sanitization. If\n * provided, behaves like `JSON.stringify`'s second argument.\n */\n replacer?: (key: string, value: unknown) => unknown\n}\n\n/**\n * Stringify `value` without throwing on circular structures or `BigInt`s.\n * See module doc for the exact substitution rules.\n */\nexport function safeJsonStringify(\n value: unknown,\n opts: SafeJsonStringifyOptions = {},\n): string {\n const seen = new WeakSet<object>()\n const userReplacer = opts.replacer\n\n const replacer = (key: string, val: unknown): unknown => {\n let v: unknown = val\n if (typeof v === 'bigint') {\n // Preserve precision by emitting as a JSON string.\n v = v.toString()\n } else if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]'\n seen.add(v as object)\n }\n if (userReplacer) v = userReplacer(key, v)\n return v\n }\n\n // `JSON.stringify` returns `undefined` for top-level `undefined`,\n // functions, and symbols — normalize to the literal string 'undefined'\n // so the return type contract (`string`) holds.\n const out = JSON.stringify(value, replacer, opts.space)\n return out === undefined ? 'undefined' : out\n}\n","import type { ServerHttp2Stream, IncomingHttpHeaders as Http2IncomingHeaders } from 'node:http2'\nimport { constants as h2 } from 'node:http2'\nimport type { IncomingHttpHeaders } from 'node:http'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport { createByteLimit } from '../body/limit.ts'\n\n/**\n * HTTP/2 pseudo-headers (RFC 7540 §8.1.2.1). These appear as keys on the\n * `headers` object when reading an inbound stream and must NOT be passed to\n * any setHeader-style API on outbound responses (Node throws). Strip them\n * from `ctx.headers` so user middleware sees a Node-http-compatible shape.\n */\nconst PSEUDO_HEADERS = new Set<string>([':method', ':path', ':scheme', ':authority', ':status'])\n\n/**\n * Some HTTP/1 hop-by-hop headers are forbidden in HTTP/2 (RFC 7540 §8.1.2.2).\n * Strip these from outbound responses if a handler set them — `Transfer-Encoding`\n * is the most common offender (Express habit) and `connection` is implicit.\n */\nconst FORBIDDEN_RESPONSE_HEADERS = new Set<string>([\n 'transfer-encoding',\n 'connection',\n 'keep-alive',\n 'proxy-connection',\n 'upgrade',\n])\n\n/**\n * Populate a pooled `IngeniumContext` from an inbound HTTP/2 stream + headers map.\n * Mirrors `node.ts`'s `populateContext` but unpacks pseudo-headers and\n * uppercases the method (HTTP/2 sends it lowercase per node:http2 convention).\n */\nexport function populateFromH2(\n ctx: IngeniumContext,\n stream: ServerHttp2Stream,\n headers: Http2IncomingHeaders,\n maxRequestBytes: number,\n): void {\n const rawMethod = headers[h2.HTTP2_HEADER_METHOD]\n ctx.method = (typeof rawMethod === 'string' ? rawMethod.toUpperCase() : 'GET') as HttpMethod\n\n const rawPath = headers[h2.HTTP2_HEADER_PATH]\n const url = typeof rawPath === 'string' ? rawPath : '/'\n ctx.url = url\n\n // Split path / query without allocating a URL object — same trick as NodeAdapter.\n const qIdx = url.indexOf('?')\n if (qIdx >= 0) {\n ctx.path = url.slice(0, qIdx)\n ctx.rawQuery = url.slice(qIdx + 1)\n } else {\n ctx.path = url\n ctx.rawQuery = ''\n }\n\n // Filter pseudo-headers out of the user-visible `ctx.headers` so middleware\n // sees an `IncomingHttpHeaders`-compatible bag.\n const userHeaders: Record<string, string | string[] | undefined> = Object.create(null)\n for (const name in headers) {\n if (PSEUDO_HEADERS.has(name)) continue\n userHeaders[name] = headers[name]\n }\n ctx.headers = userHeaders as IncomingHttpHeaders\n\n const cl = userHeaders['content-length']\n const contentLength = typeof cl === 'string' ? Number(cl) : undefined\n const ct = typeof userHeaders['content-type'] === 'string' ? (userHeaders['content-type'] as string) : undefined\n\n // The `ServerHttp2Stream` IS a Duplex with a Readable side — wrap it in the\n // byte-limit Transform so the cap applies to EVERY consumer, including\n // `ctx.body.stream()`. Three provably-safe skip conditions (mirror NodeAdapter):\n // 1. Body-less method or Content-Length: 0\n // 2. Cap disabled (Infinity)\n // 3. Content-Length declared and ≤ cap (pre-check enforced; protocol\n // bounds the actual byte count to the declared length)\n const noBody =\n contentLength === 0 ||\n ctx.method === 'GET' ||\n ctx.method === 'HEAD' ||\n ctx.method === 'OPTIONS'\n const knownSafe =\n contentLength !== undefined &&\n Number.isFinite(contentLength) &&\n contentLength <= maxRequestBytes\n if (noBody || !Number.isFinite(maxRequestBytes) || knownSafe) {\n ctx.body._attach(stream, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n return\n }\n\n // Cap unknown-length (chunked) bodies with a byte-limit Transform that\n // becomes `ctx.body`'s source. Two failure modes have to be defended here,\n // both rooted in `Stream.prototype.pipe` NOT forwarding `'error'` events:\n //\n // 1. Unhandled-error crash. When the cap trips, the Transform emits\n // `'error'`. The `body.stream()` consumer attaches its own listener, but\n // the chunked path in `IngeniumBody.buffer` re-pipes THIS Transform into\n // a second limiter and only listens on the DOWNSTREAM pipe — so this\n // Transform's `'error'` has no listener and becomes a process-killing\n // unhandled error (h2c has no socket-level teardown to swallow it).\n //\n // 2. Hung request. Because `pipe()` drops errors, that re-piped downstream\n // limiter never sees the overrun: it stops receiving data but never\n // `end`s or `error`s, so `body.buffer()`'s promise never settles and the\n // request hangs until the test/client timeout.\n //\n // Fix both by (a) attaching a guard `'error'` listener so the event is always\n // handled, and (b) forwarding the cap error to every stream this Transform\n // was piped into, so re-piping consumers reject promptly. We deliberately do\n // NOT touch the underlying h2 `stream` here: the 413 is produced by the body\n // consumer's `IngeniumPayloadTooLargeError`, which the error boundary\n // serializes and `writeH2Response` must flush on the still-open stream.\n const limited = createByteLimit(maxRequestBytes)\n const downstream = new Set<{ destroy(err?: Error): void; destroyed: boolean }>()\n const origPipe = limited.pipe.bind(limited) as typeof limited.pipe\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n limited.pipe = function pipe(dest: any, ...rest: any[]) {\n downstream.add(dest)\n return origPipe(dest, ...rest)\n } as typeof limited.pipe\n limited.on('error', (err: Error) => {\n for (const dest of downstream) {\n if (!dest.destroyed) dest.destroy(err)\n }\n // Drain whatever inbound bytes the client is still sending. We stopped\n // reading at the cap, so the raw h2 stream's readable side is left with\n // unconsumed (and incoming) DATA frames. The response (413) flushes on the\n // WRITABLE side, but a half-closed stream whose readable side never ends\n // keeps the h2 SESSION's stream count > 0 — so a later graceful\n // `client.close()` / `server.close()` hangs waiting for it. Unpipe the dead\n // Transform and resume the raw stream to discard the rest, letting it reach\n // `end` and the session close cleanly. `stream.on('error')` below absorbs\n // any RST that arrives while draining.\n stream.unpipe(limited)\n stream.on('error', () => {})\n stream.resume()\n })\n stream.pipe(limited)\n ctx.body._attach(limited, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n}\n\n/**\n * Returns `true` (and writes a 413 response) if the inbound h2 stream's\n * Content-Length exceeds the cap. Mirrors the Node adapter pre-check —\n * called BEFORE `populateFromH2` so we don't even acquire a context for\n * a request we're going to reject. Missing / invalid Content-Length →\n * `false` (chunked-style framing, where the byte-limit catches the overrun).\n */\nexport function rejectH2IfContentLengthTooBig(\n stream: ServerHttp2Stream,\n headers: Http2IncomingHeaders,\n maxRequestBytes: number,\n): boolean {\n if (!Number.isFinite(maxRequestBytes)) return false\n const raw = headers['content-length']\n const cl = typeof raw === 'string' ? raw : Array.isArray(raw) ? raw[0] : undefined\n if (typeof cl !== 'string' || cl.length === 0) return false\n const n = Number(cl)\n if (!Number.isFinite(n)) return false\n if (n <= maxRequestBytes) return false\n\n if (stream.destroyed || stream.closed) return true\n\n // A client that declared an oversized Content-Length is, by definition,\n // about to send (or has half-sent) body frames we will never read. When we\n // respond + end early, the peer's continued DATA — or its own Content-Length\n // bookkeeping if it later sends fewer bytes than declared — makes node:http2\n // emit `ERR_HTTP2_STREAM_ERROR` on this stream. With no listener that is an\n // unhandled-error crash. Absorb it: the 413 has already been delivered (or\n // the stream is being torn down anyway), so there is nothing left to do.\n stream.on('error', () => {\n /* absorb late RST/protocol error from the rejected, never-read body */\n })\n\n try {\n stream.respond({\n [h2.HTTP2_HEADER_STATUS]: 413,\n 'content-type': 'application/json; charset=utf-8',\n })\n stream.end(\n JSON.stringify({\n error: `Request body exceeded ${maxRequestBytes} bytes`,\n code: 'PAYLOAD_TOO_LARGE',\n }),\n )\n } catch {\n try {\n stream.close(h2.NGHTTP2_INTERNAL_ERROR)\n } catch {\n stream.destroy()\n }\n }\n return true\n}\n\n/**\n * Write the `IngeniumContext` response state to an HTTP/2 stream. Handles all four\n * `_body.kind` variants. HTTP/2 has no `Transfer-Encoding: chunked` (framing\n * is implicit) and no hop-by-hop headers, so we strip those before responding.\n */\nexport function writeH2Response(ctx: IngeniumContext, stream: ServerHttp2Stream): void {\n if (stream.destroyed || stream.closed) return\n\n const responseHeaders: Record<string, string | string[] | number> = Object.create(null)\n responseHeaders[h2.HTTP2_HEADER_STATUS] = ctx._statusCode\n\n for (const name in ctx._headers) {\n const lc = name.toLowerCase()\n if (FORBIDDEN_RESPONSE_HEADERS.has(lc)) continue\n if (PSEUDO_HEADERS.has(lc)) continue // defensive — shouldn't ever happen\n const value = ctx._headers[name]\n if (value !== undefined) responseHeaders[lc] = value\n }\n\n const body = ctx._body\n switch (body.kind) {\n case 'none':\n stream.respond(responseHeaders, { endStream: true })\n return\n case 'string': {\n if (responseHeaders['content-length'] === undefined) {\n responseHeaders['content-length'] = Buffer.byteLength(body.data)\n }\n stream.respond(responseHeaders)\n stream.end(body.data)\n return\n }\n case 'buffer': {\n if (responseHeaders['content-length'] === undefined) {\n responseHeaders['content-length'] = body.data.length\n }\n stream.respond(responseHeaders)\n stream.end(body.data)\n return\n }\n case 'stream': {\n stream.respond(responseHeaders)\n body.data.pipe(stream)\n return\n }\n }\n}\n","import {\n createServer as createH2cServer,\n createSecureServer as createH2Server,\n constants as h2,\n type Http2SecureServer,\n type Http2Server,\n type ServerHttp2Stream,\n type IncomingHttpHeaders as Http2IncomingHeaders,\n type Http2ServerRequest,\n type Http2ServerResponse,\n} from 'node:http2'\nimport type { Socket } from 'node:net'\nimport type { TLSSocket } from 'node:tls'\nimport type { IncomingHttpHeaders } from 'node:http'\nimport type { HttpMethod } from '../router/types.ts'\nimport type {\n CloseOptions,\n ListeningServer,\n Transport,\n TransportHooks,\n} from './types.ts'\nimport { populateFromH2, rejectH2IfContentLengthTooBig, writeH2Response } from './http2-helpers.ts'\nimport { createByteLimit } from '../body/limit.ts'\n\n/** TLS options accepted by the h2 (secure) adapter. */\nexport interface Http2AdapterOptions {\n /** TLS certificate (PEM). */\n cert: Buffer | string\n /** TLS private key (PEM). */\n key: Buffer | string\n /**\n * If true, the secure server also accepts HTTP/1.1 connections via ALPN\n * fallback. Inbound HTTP/1 requests are dispatched through the same path\n * used by `NodeAdapter`. Default: false (HTTP/2 only).\n */\n allowHttp1?: boolean\n}\n\n/**\n * HTTP/2-over-TLS (`h2`) transport. Uses Node's built-in `http2.createSecureServer`.\n * Browsers REQUIRE TLS for HTTP/2 — there is no cleartext HTTP/2 negotiation\n * over the open web. For local testing without certs, use {@link Http2cAdapter}.\n *\n * Per-request: on `'stream'`, populates a pooled `IngeniumContext` from pseudo-headers,\n * awaits dispatch, then writes the response via `stream.respond()` + `stream.end()`\n * (or pipes for `Readable` bodies).\n */\nexport class Http2Adapter implements Transport {\n private hooks: TransportHooks | null = null\n\n constructor(private readonly options: Http2AdapterOptions) {}\n\n attach(hooks: TransportHooks): void {\n this.hooks = hooks\n }\n\n async listen(port: number, host = '127.0.0.1'): Promise<ListeningServer> {\n if (!this.hooks) throw new Error('Http2Adapter.listen() called before attach()')\n const hooks = this.hooks\n\n const server: Http2SecureServer = createH2Server({\n cert: this.options.cert,\n key: this.options.key,\n allowHTTP1: this.options.allowHttp1 === true,\n })\n\n server.on('stream', (stream, headers) => {\n handleStream(stream, headers, hooks).catch((err) => emergencyAbort(stream, err))\n })\n\n if (this.options.allowHttp1 === true) {\n // ALPN fallback: HTTP/1.1 clients land here, NOT on `'stream'`.\n server.on('request', (req, res) => {\n handleHttp1Fallback(req, res, hooks).catch((err) => {\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('content-type', 'application/json; charset=utf-8')\n res.end(JSON.stringify({ error: 'Internal Server Error', code: 'INTERNAL_ERROR' }))\n } else {\n res.end()\n }\n process.emitWarning(`ingenium(h2/http1): dispatch leaked: ${(err as Error).message ?? String(err)}`)\n })\n })\n }\n\n return startServer(server, port, host)\n }\n}\n\n/**\n * HTTP/2 cleartext (`h2c`) transport. Uses Node's `http2.createServer` — no TLS,\n * so this is intended for local development, internal service-to-service calls\n * behind an L7 proxy that handles TLS termination, or test suites. Browsers do\n * not speak h2c; use {@link Http2Adapter} for browser traffic.\n *\n * Constructor takes no required arguments.\n */\nexport class Http2cAdapter implements Transport {\n private hooks: TransportHooks | null = null\n\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n constructor(_options: {} = {}) {\n // Reserved for future tuning knobs (settings frame, max concurrent streams, …).\n }\n\n attach(hooks: TransportHooks): void {\n this.hooks = hooks\n }\n\n async listen(port: number, host = '127.0.0.1'): Promise<ListeningServer> {\n if (!this.hooks) throw new Error('Http2cAdapter.listen() called before attach()')\n const hooks = this.hooks\n\n const server: Http2Server = createH2cServer()\n\n server.on('stream', (stream, headers) => {\n handleStream(stream, headers, hooks).catch((err) => emergencyAbort(stream, err))\n })\n\n return startServer(server, port, host)\n }\n}\n\n// ───── shared internals ─────────────────────────────────────────────────────\n\nasync function handleStream(\n stream: ServerHttp2Stream,\n headers: Http2IncomingHeaders,\n hooks: TransportHooks,\n): Promise<void> {\n // Normalize the optional hook field — older fixtures may not set it.\n const maxBytes = hooks.maxRequestBytes ?? Number.POSITIVE_INFINITY\n // Reject oversized Content-Length BEFORE we acquire a context — the request\n // is dead on arrival. Chunked / unknown-length bodies fall through to the\n // byte-limit Transform installed by `populateFromH2`.\n if (rejectH2IfContentLengthTooBig(stream, headers, maxBytes)) return\n\n const ctx = hooks.acquire()\n try {\n populateFromH2(ctx, stream, headers, maxBytes)\n await hooks.dispatch(ctx)\n writeH2Response(ctx, stream)\n } finally {\n hooks.release(ctx)\n }\n}\n\n/**\n * HTTP/1.1 fallback path used when `allowHttp1` is set on `Http2Adapter`.\n * Mirrors `NodeAdapter.populateContext` + `writeResponse`. We can't reuse\n * `node.ts` directly because the framework should not import from a sibling\n * adapter, and `Http2ServerRequest`/`Response` are subclasses of the http\n * primitives but with the same surface — so we duplicate the small populate +\n * write loop here.\n */\nasync function handleHttp1Fallback(\n req: Http2ServerRequest,\n res: Http2ServerResponse,\n hooks: TransportHooks,\n): Promise<void> {\n // Same Content-Length pre-check as the pure-h1 NodeAdapter path.\n const maxBytes = hooks.maxRequestBytes ?? Number.POSITIVE_INFINITY\n if (Number.isFinite(maxBytes)) {\n const raw = req.headers['content-length']\n if (typeof raw === 'string' && raw.length > 0) {\n const n = Number(raw)\n if (Number.isFinite(n) && n > maxBytes) {\n res.statusCode = 413\n res.setHeader('content-type', 'application/json; charset=utf-8')\n res.setHeader('connection', 'close')\n res.end(\n JSON.stringify({\n error: `Request body exceeded ${maxBytes} bytes`,\n code: 'PAYLOAD_TOO_LARGE',\n }),\n )\n return\n }\n }\n }\n\n const ctx = hooks.acquire()\n try {\n ctx.method = (req.method ?? 'GET') as HttpMethod\n const url = req.url ?? '/'\n ctx.url = url\n const qIdx = url.indexOf('?')\n if (qIdx >= 0) {\n ctx.path = url.slice(0, qIdx)\n ctx.rawQuery = url.slice(qIdx + 1)\n } else {\n ctx.path = url\n ctx.rawQuery = ''\n }\n ctx.headers = req.headers as unknown as IncomingHttpHeaders\n\n const cl = req.headers['content-length']\n const contentLength = typeof cl === 'string' ? Number(cl) : undefined\n const ct = typeof req.headers['content-type'] === 'string' ? (req.headers['content-type'] as string) : undefined\n const source = Number.isFinite(maxBytes) ? req.pipe(createByteLimit(maxBytes)) : req\n ctx.body._attach(source, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n\n await hooks.dispatch(ctx)\n\n res.statusCode = ctx._statusCode\n for (const name in ctx._headers) {\n const value = ctx._headers[name]\n if (value !== undefined) res.setHeader(name, value)\n }\n const body = ctx._body\n switch (body.kind) {\n case 'none':\n res.end()\n break\n case 'string':\n if (!res.hasHeader('content-length')) {\n res.setHeader('content-length', Buffer.byteLength(body.data))\n }\n res.end(body.data)\n break\n case 'buffer':\n if (!res.hasHeader('content-length')) {\n res.setHeader('content-length', body.data.length)\n }\n res.end(body.data)\n break\n case 'stream':\n body.data.pipe(res)\n break\n }\n } finally {\n hooks.release(ctx)\n }\n}\n\nfunction emergencyAbort(stream: ServerHttp2Stream, err: unknown): void {\n // Last-resort safety net — the dispatch loop should have caught everything.\n if (!stream.headersSent && !stream.destroyed) {\n try {\n stream.respond(\n { [h2.HTTP2_HEADER_STATUS]: 500, 'content-type': 'application/json; charset=utf-8' },\n )\n stream.end(JSON.stringify({ error: 'Internal Server Error', code: 'INTERNAL_ERROR' }))\n } catch {\n // fall through to destroy\n }\n }\n if (!stream.destroyed) {\n try {\n stream.close(h2.NGHTTP2_INTERNAL_ERROR)\n } catch {\n stream.destroy()\n }\n }\n process.emitWarning(`ingenium(h2): dispatch leaked: ${(err as Error).message ?? String(err)}`)\n}\n\n/**\n * Bind the underlying server and return a {@link ListeningServer} handle.\n * Same socket-tracking pattern as `NodeAdapter` so `close({ gracefulTimeoutMs })`\n * can force-kill idle connections.\n */\nfunction startServer(\n server: Http2Server | Http2SecureServer,\n port: number,\n host: string,\n): Promise<ListeningServer> {\n const sockets = new Set<Socket | TLSSocket>()\n server.on('connection', (socket: Socket) => {\n sockets.add(socket)\n socket.on('close', () => sockets.delete(socket))\n })\n server.on('secureConnection', (socket: TLSSocket) => {\n sockets.add(socket)\n socket.on('close', () => sockets.delete(socket))\n })\n\n return new Promise<ListeningServer>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to determine bound address'))\n return\n }\n resolve({\n port: addr.port,\n host: addr.address,\n close: (opts?: CloseOptions): Promise<void> =>\n new Promise<void>((res, rej) => {\n let settled = false\n let timer: NodeJS.Timeout | null = null\n\n server.close((err) => {\n if (timer) clearTimeout(timer)\n if (settled) return\n settled = true\n err ? rej(err) : res()\n })\n\n const timeoutMs = opts?.gracefulTimeoutMs\n if (typeof timeoutMs === 'number' && Number.isFinite(timeoutMs)) {\n timer = setTimeout(() => {\n for (const socket of sockets) socket.destroy()\n }, Math.max(0, timeoutMs))\n if (typeof timer.unref === 'function') timer.unref()\n }\n }),\n })\n })\n })\n}\n\n// Re-export types for downstream consumers who need to type adapter options.\nexport type { Http2AdapterOptions as Http2Options }\n","/**\n * Graceful shutdown helper. Wires POSIX signal handlers to drain a\n * {@link ListeningServer}, run a user cleanup hook, then exit.\n *\n * Most production deployments (Kubernetes, systemd, PM2, ECS, Fly, …) send\n * SIGTERM when they want a process to stop. By default Node simply dies on\n * SIGTERM, which kills in-flight requests and leaves keep-alive sockets\n * dangling. Calling {@link gracefulShutdown} after `app.listen()` opts the\n * process into a clean drain instead.\n */\n\nimport type { ListeningServer } from './types.ts'\n\n/** Options for {@link gracefulShutdown}. */\nexport interface ShutdownOptions {\n /**\n * Maximum time (ms) to wait for sockets to drain before they are forcibly\n * destroyed. Defaults to `10_000` (10s) — matches Kubernetes' default\n * `terminationGracePeriodSeconds` headroom.\n */\n gracefulTimeoutMs?: number\n\n /**\n * Signals to listen for. Defaults to `['SIGTERM', 'SIGINT']`.\n */\n signals?: NodeJS.Signals[]\n\n /**\n * User cleanup hook — runs AFTER the server stops accepting new\n * connections but BEFORE the process exits. Use for closing DB pools,\n * flushing logs, etc. Awaited; throwing exits with code 1.\n */\n onShutdown?: () => void | Promise<void>\n\n /** Logger used to announce shutdown lifecycle events. Defaults to `console.log`. */\n logger?: (msg: string) => void\n}\n\n/**\n * Wire signal handlers that gracefully shut down `server` on SIGTERM/SIGINT\n * (or whichever signals you pass). Returns an unsubscribe function that\n * removes the listeners — mostly useful for tests.\n *\n * @example\n * const server = await app.listen(3000)\n * gracefulShutdown(server, { onShutdown: async () => db.close() })\n */\nexport function gracefulShutdown(\n server: ListeningServer,\n opts: ShutdownOptions = {},\n): () => void {\n const gracefulTimeoutMs = opts.gracefulTimeoutMs ?? 10_000\n const signals: NodeJS.Signals[] = opts.signals ?? ['SIGTERM', 'SIGINT']\n const log = opts.logger ?? ((msg: string) => console.log(msg))\n\n let shuttingDown = false\n\n const handler = (signal: NodeJS.Signals): void => {\n if (shuttingDown) {\n // Second signal during an in-progress drain → bail immediately.\n log(`ingenium: received ${signal} during shutdown — forcing exit`)\n process.exit(1)\n return\n }\n shuttingDown = true\n log(`ingenium: received ${signal}, shutting down (timeout ${gracefulTimeoutMs}ms)`)\n\n void (async () => {\n try {\n if (opts.onShutdown) await opts.onShutdown()\n await server.close({ gracefulTimeoutMs })\n log('ingenium: shutdown complete')\n process.exit(0)\n } catch (err) {\n log(`ingenium: shutdown failed: ${(err as Error)?.message ?? String(err)}`)\n process.exit(1)\n }\n })()\n }\n\n for (const signal of signals) process.on(signal, handler)\n\n return (): void => {\n for (const signal of signals) process.off(signal, handler)\n }\n}\n","import type { SseStream } from './sse.ts'\n\n/**\n * Send a `:keepalive` comment to the given SSE stream every `intervalMs`\n * milliseconds. Returns a cancellation function.\n *\n * The interval is automatically cancelled when the stream closes — but\n * callers should still hold onto the cancel function for explicit cleanup\n * (e.g. on a separate teardown signal).\n *\n * The internal timer is `unref()`'d so it won't keep the Node event loop\n * alive on its own.\n *\n * @example\n * const stream = sse(ctx)\n * const cancel = startKeepAlive(stream, 15_000)\n * ctx.req.on('close', cancel) // optional\n */\nexport function startKeepAlive(\n stream: SseStream,\n intervalMs = 15_000,\n): () => void {\n let cancelled = false\n\n const timer = setInterval(() => {\n if (cancelled || stream.closed) {\n clearInterval(timer)\n return\n }\n stream.comment('keepalive')\n }, intervalMs)\n\n if (typeof timer.unref === 'function') timer.unref()\n\n // Best-effort: clear the interval as soon as we observe the stream closing.\n // The interval also self-clears via the closed-check above, but this\n // shortens the window before the next tick fires.\n const watcher = setInterval(() => {\n if (stream.closed) {\n clearInterval(timer)\n clearInterval(watcher)\n }\n }, Math.max(50, Math.min(intervalMs, 1000)))\n if (typeof watcher.unref === 'function') watcher.unref()\n\n return () => {\n if (cancelled) return\n cancelled = true\n clearInterval(timer)\n clearInterval(watcher)\n }\n}\n","import type { SessionStore } from './types.ts'\n\ninterface Entry {\n data: Record<string, unknown>\n expiresAt: number\n}\n\n/**\n * In-process session store backed by a `Map`. Suitable for development and\n * single-instance deployments. NOT shared across workers/replicas.\n *\n * Expired entries are evicted lazily on access AND periodically by a\n * background sweep. The sweep timer is `unref()`'d so it never keeps the\n * Node process alive on its own.\n */\nexport class MemoryStore implements SessionStore {\n private readonly map = new Map<string, Entry>()\n private readonly sweep: NodeJS.Timeout | null\n\n /**\n * @param sweepIntervalMs How often to scan the map for expired entries.\n * Defaults to 60s. Pass `0` to disable the timer entirely (tests).\n */\n constructor(sweepIntervalMs = 60_000) {\n if (sweepIntervalMs > 0) {\n this.sweep = setInterval(() => this.purge(), sweepIntervalMs)\n // Don't keep the event loop alive just for the sweep.\n this.sweep.unref?.()\n } else {\n this.sweep = null\n }\n }\n\n async get(id: string): Promise<Record<string, unknown> | null> {\n const entry = this.map.get(id)\n if (!entry) return null\n if (entry.expiresAt <= Date.now()) {\n this.map.delete(id)\n return null\n }\n return entry.data\n }\n\n async set(id: string, data: Record<string, unknown>, ttlSeconds: number): Promise<void> {\n this.map.set(id, { data, expiresAt: Date.now() + ttlSeconds * 1000 })\n }\n\n async destroy(id: string): Promise<void> {\n this.map.delete(id)\n }\n\n async touch(id: string, ttlSeconds: number): Promise<void> {\n const entry = this.map.get(id)\n if (!entry) return\n entry.expiresAt = Date.now() + ttlSeconds * 1000\n }\n\n /**\n * Stop the background sweep timer. Useful in tests / graceful shutdown.\n * After this call the store still works but expired entries are only\n * evicted on access.\n */\n stop(): void {\n if (this.sweep) clearInterval(this.sweep)\n }\n\n /** @internal Test helper: number of live (non-expired) entries. */\n size(): number {\n this.purge()\n return this.map.size\n }\n\n private purge(): void {\n const now = Date.now()\n for (const [id, entry] of this.map) {\n if (entry.expiresAt <= now) this.map.delete(id)\n }\n }\n}\n","import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto'\nimport { Buffer } from 'node:buffer'\nimport type { IngeniumMiddleware } from '../middleware/types.ts'\nimport type { IngeniumContext } from '../context/context.ts'\nimport { MemoryStore } from './store-memory.ts'\nimport type { Session, SessionCookieOptions, SessionOptions, SessionStore } from './types.ts'\n\n// ───── Constants ────────────────────────────────────────────────────────────\n\nconst DEFAULT_COOKIE_NAME = 'ingenium.sid'\nconst DEFAULT_MAX_AGE_SECONDS = 60 * 60 * 24 * 7 // 7 days\n/** ID byte length — 18 bytes → 24 base64url chars, ~144 bits of entropy. */\nconst ID_BYTES = 18\n\n// ───── Cookie helpers ───────────────────────────────────────────────────────\n// TODO: migrate to ctx.cookies — kept inline for now because session has\n// specific behaviours (rolling, secret-rotation re-signing, destroy-on-commit)\n// that don't map 1:1 onto the generic cookie API.\n\n/**\n * Parse a `Cookie` request header into a name→value map. Handles:\n * - Multiple cookies separated by `;` (with optional whitespace)\n * - Quoted values: `name=\"quoted value\"`\n * - Percent-encoded characters via `decodeURIComponent`\n * - Duplicate names: first occurrence wins (matches RFC 6265 §5.4 typical behaviour)\n *\n * Malformed pairs are skipped silently — this is a defensive parser that\n * never throws on user input.\n */\nexport function parseCookieHeader(header: string | undefined): Record<string, string> {\n const out: Record<string, string> = Object.create(null) as Record<string, string>\n if (!header) return out\n\n const parts = header.split(';')\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!\n const eq = part.indexOf('=')\n if (eq < 0) continue\n const name = part.slice(0, eq).trim()\n if (!name || name in out) continue\n let value = part.slice(eq + 1).trim()\n // Strip surrounding double quotes.\n if (value.length >= 2 && value.charCodeAt(0) === 0x22 && value.charCodeAt(value.length - 1) === 0x22) {\n value = value.slice(1, -1)\n }\n try {\n out[name] = decodeURIComponent(value)\n } catch {\n // Bad percent-encoding — keep raw value rather than throwing.\n out[name] = value\n }\n }\n return out\n}\n\n/**\n * Serialize a single `Set-Cookie` value. We implement this inline to avoid\n * pulling in `cookie` as a dependency.\n *\n * `maxAge` is in seconds; when supplied we also emit an absolute `Expires`\n * for older clients that ignore `Max-Age`.\n */\nexport function serializeCookie(\n name: string,\n value: string,\n opts: SessionCookieOptions & { maxAge?: number } = {},\n): string {\n // Encode the value so semicolons / whitespace cannot break the header.\n const segments: string[] = [`${name}=${encodeURIComponent(value)}`]\n if (opts.domain) segments.push(`Domain=${opts.domain}`)\n segments.push(`Path=${opts.path ?? '/'}`)\n\n if (typeof opts.maxAge === 'number') {\n // Floor — Max-Age must be an integer.\n const ma = Math.floor(opts.maxAge)\n segments.push(`Max-Age=${ma}`)\n const expires = new Date(Date.now() + ma * 1000)\n segments.push(`Expires=${expires.toUTCString()}`)\n }\n\n if (opts.httpOnly !== false) segments.push('HttpOnly')\n if (opts.secure) segments.push('Secure')\n const sameSite = opts.sameSite ?? 'lax'\n segments.push(`SameSite=${sameSite[0]!.toUpperCase()}${sameSite.slice(1)}`)\n\n return segments.join('; ')\n}\n\n/**\n * Append a `Set-Cookie` value to the response, preserving any existing\n * `Set-Cookie` header(s) from earlier middleware.\n */\nfunction appendSetCookie(ctx: IngeniumContext, value: string): void {\n const existing = ctx.getHeader('set-cookie')\n if (!existing) {\n ctx.set('set-cookie', value)\n } else if (Array.isArray(existing)) {\n ctx.set('set-cookie', [...existing, value])\n } else {\n ctx.set('set-cookie', [existing, value])\n }\n}\n\n// ───── Signing ──────────────────────────────────────────────────────────────\n\n/** HMAC-SHA-256 the id with `secret`, base64url-encoded. */\nfunction signId(id: string, secret: string): string {\n return createHmac('sha256', secret).update(id).digest('base64url')\n}\n\n/**\n * Verify `cookieValue` (`<id>.<sig>`) against any of the supplied secrets.\n * Returns the id and the index of the matching secret, or `null`.\n *\n * Uses {@link timingSafeEqual} to defeat byte-wise timing oracles.\n */\nfunction verifySigned(\n cookieValue: string,\n secrets: readonly string[],\n): { id: string; secretIndex: number } | null {\n const dot = cookieValue.lastIndexOf('.')\n if (dot <= 0 || dot >= cookieValue.length - 1) return null\n const id = cookieValue.slice(0, dot)\n const sig = cookieValue.slice(dot + 1)\n const sigBuf = Buffer.from(sig, 'base64url')\n if (sigBuf.length === 0) return null\n\n for (let i = 0; i < secrets.length; i++) {\n const expected = Buffer.from(signId(id, secrets[i]!), 'base64url')\n if (expected.length !== sigBuf.length) continue\n if (timingSafeEqual(expected, sigBuf)) return { id, secretIndex: i }\n }\n return null\n}\n\n/** Generate a fresh, opaque session id. */\nfunction newId(): string {\n return randomBytes(ID_BYTES).toString('base64url')\n}\n\n// ───── Session implementation ───────────────────────────────────────────────\n\n/**\n * @internal Mutable-by-design implementation of {@link Session}. The public\n * `data` field is exposed via `Object.freeze` to keep callers from mutating\n * around the dirty-tracking surface.\n */\nclass SessionImpl implements Session {\n /** Tracks whether the session needs to be persisted on response. */\n dirty: boolean\n /** True when no record existed in the store at request start. */\n readonly isNew: boolean\n /** True after `destroy()` — middleware will clear cookie + store. */\n destroyed = false\n\n private _id: string\n private _data: Record<string, unknown>\n\n constructor(\n id: string,\n data: Record<string, unknown>,\n isNew: boolean,\n private readonly store: SessionStore,\n /** Set to `true` when secret rotation requires re-signing on response. */\n public needsResign: boolean,\n ) {\n this._id = id\n this._data = data\n this.isNew = isNew\n // A brand-new session with no data is NOT dirty — we don't want to\n // create empty rows or cookies for every anonymous request.\n this.dirty = false\n }\n\n get id(): string {\n return this._id\n }\n\n get data(): Readonly<Record<string, unknown>> {\n return Object.freeze({ ...this._data })\n }\n\n get<T = unknown>(key: string): T | undefined {\n return this._data[key] as T | undefined\n }\n\n set(key: string, value: unknown): void {\n this._data[key] = value\n this.dirty = true\n }\n\n delete(key: string): void {\n if (key in this._data) {\n delete this._data[key]\n this.dirty = true\n }\n }\n\n async destroy(): Promise<void> {\n await this.store.destroy(this._id)\n this._data = Object.create(null) as Record<string, unknown>\n this.destroyed = true\n this.dirty = false\n }\n\n async regenerate(): Promise<void> {\n const oldId = this._id\n this._id = newId()\n // Old id must die so a stolen cookie cannot resurrect the session.\n await this.store.destroy(oldId)\n this.dirty = true\n this.needsResign = true\n }\n\n /** @internal Snapshot for persistence; cheap shallow clone. */\n snapshot(): Record<string, unknown> {\n return { ...this._data }\n }\n}\n\n// ───── Middleware factory ───────────────────────────────────────────────────\n\n/**\n * Cookie-backed session middleware.\n *\n * The middleware attaches a {@link Session} instance at `ctx.session`. To\n * make this typesafe in user code, augment the `IngeniumContext` interface in\n * your own project:\n *\n * @example\n * ```ts\n * declare module 'ingenium' {\n * interface IngeniumContext { session: import('ingenium').Session }\n * }\n *\n * import { ingenium, sessionMiddleware } from 'ingenium'\n * const app = ingenium()\n * app.use(sessionMiddleware({ secret: process.env.SESSION_SECRET! }))\n *\n * app.get('/me', (ctx) => ({ user: ctx.session.get('user') }))\n * app.post('/login', async (ctx) => {\n * ctx.session.set('user', { id: 1 })\n * await ctx.session.regenerate() // mitigate session fixation\n * })\n * ```\n *\n * Security choices:\n * - HMAC-SHA-256 over the session id, base64url-encoded; verified with\n * `timingSafeEqual`.\n * - 144-bit (18-byte) random ids.\n * - Defaults: `HttpOnly`, `SameSite=Lax`, `Path=/`. Set `secure: true`\n * behind TLS to enable `Secure`.\n * - Tampered or unknown cookies silently issue a fresh session — never an\n * error response, since this is an attacker-influenced surface.\n */\nexport function sessionMiddleware(opts: SessionOptions): IngeniumMiddleware {\n // ── Construction-time validation ─────────────────────────────────────────\n const secrets: readonly string[] = Array.isArray(opts.secret)\n ? opts.secret.slice()\n : [opts.secret]\n if (secrets.length === 0 || secrets.some((s) => typeof s !== 'string' || s.length === 0)) {\n throw new Error('sessionMiddleware: `secret` must be a non-empty string or non-empty string[]')\n }\n\n const cookieName = opts.cookieName ?? DEFAULT_COOKIE_NAME\n const maxAgeSeconds = opts.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS\n const rolling = opts.rolling ?? false\n const cookieOpts: SessionCookieOptions = opts.cookie ?? {}\n const store: SessionStore = opts.store ?? new MemoryStore()\n\n return async (ctx, next) => {\n const cookies = parseCookieHeader(ctx.headers.cookie as string | undefined)\n const raw = cookies[cookieName]\n\n let id: string\n let data: Record<string, unknown>\n let isNew: boolean\n let needsResign = false\n\n if (raw) {\n const verified = verifySigned(raw, secrets)\n if (verified) {\n const loaded = await store.get(verified.id)\n if (loaded) {\n id = verified.id\n data = { ...loaded }\n isNew = false\n // If verified by anything other than the active key, re-sign.\n if (verified.secretIndex !== 0) needsResign = true\n } else {\n // Cookie validly signed but store has nothing — treat as new.\n id = newId()\n data = Object.create(null) as Record<string, unknown>\n isNew = true\n }\n } else {\n // Bad signature → silently issue a new session.\n id = newId()\n data = Object.create(null) as Record<string, unknown>\n isNew = true\n }\n } else {\n id = newId()\n data = Object.create(null) as Record<string, unknown>\n isNew = true\n }\n\n const session = new SessionImpl(id, data, isNew, store, needsResign)\n // Decorator-by-assignment. Type augmentation (see JSDoc above) keeps\n // this typesafe in user code without polluting the shared prototype.\n ;(ctx as unknown as { session: Session }).session = session\n\n try {\n await next()\n } finally {\n await commit(ctx, session, secrets[0]!, cookieName, maxAgeSeconds, rolling, cookieOpts, store)\n }\n }\n}\n\n/**\n * Persist session changes and write the appropriate `Set-Cookie` header.\n * Runs in `finally` so we still clean up after handler errors.\n */\nasync function commit(\n ctx: IngeniumContext,\n session: SessionImpl,\n signingSecret: string,\n cookieName: string,\n maxAgeSeconds: number,\n rolling: boolean,\n cookieOpts: SessionCookieOptions,\n store: SessionStore,\n): Promise<void> {\n if (session.destroyed) {\n // Clear cookie. Max-Age=0 is the cross-browser way to expire immediately.\n appendSetCookie(\n ctx,\n serializeCookie(cookieName, '', { ...cookieOpts, maxAge: 0 }),\n )\n return\n }\n\n // Spec: persist + cookie when session is dirty OR new. Persisting empty\n // new sessions is intentional — it lets handlers rely on a stable id\n // across requests for anon flows (CSRF tokens, A/B buckets, etc.).\n const shouldPersist = session.dirty || session.isNew\n\n if (shouldPersist) {\n await store.set(session.id, session.snapshot(), maxAgeSeconds)\n const signed = `${session.id}.${signId(session.id, signingSecret)}`\n appendSetCookie(\n ctx,\n serializeCookie(cookieName, signed, { ...cookieOpts, maxAge: maxAgeSeconds }),\n )\n return\n }\n\n // Re-sign without re-persisting (e.g. secret rotation on a clean read).\n if (session.needsResign && !session.isNew) {\n const signed = `${session.id}.${signId(session.id, signingSecret)}`\n appendSetCookie(\n ctx,\n serializeCookie(cookieName, signed, { ...cookieOpts, maxAge: maxAgeSeconds }),\n )\n if (rolling && store.touch) await store.touch(session.id, maxAgeSeconds)\n return\n }\n\n // Rolling: refresh TTL + cookie even when nothing changed.\n if (rolling && !session.isNew) {\n if (store.touch) await store.touch(session.id, maxAgeSeconds)\n const signed = `${session.id}.${signId(session.id, signingSecret)}`\n appendSetCookie(\n ctx,\n serializeCookie(cookieName, signed, { ...cookieOpts, maxAge: maxAgeSeconds }),\n )\n }\n}\n","/**\n * WebSocket registrar — the small piece of state that holds path → handler\n * mappings and knows how to wire `'upgrade'` on a Node `http.Server`.\n *\n * Design: the `ws` package is loaded lazily via dynamic `import('ws')` so\n * apps that never use WebSockets pay no cost (no module load, no peer-dep\n * requirement). The first call to `attach()` resolves the import.\n */\n\nimport type { Server as HttpServer, IncomingMessage } from 'node:http'\nimport type { Socket } from 'node:net'\nimport { IngeniumContext } from '../context/context.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport type {\n WebSocketHandler,\n WebSocketHandlerOptions,\n WsRegistrar,\n WsRoute,\n} from './types.ts'\n\n/**\n * Attempt to detect whether `ws` is installed. Used by the test suite to\n * `describe.skipIf` the WS suite when the optional peer dep is missing.\n */\nexport async function peerHasWs(): Promise<boolean> {\n try {\n await import('ws')\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Build a registrar bound to an app. The registrar is intentionally\n * decoupled from `IngeniumApp` — the app calls `add()` from `app.ws()`, and\n * `enableWebSockets()` (or the app's `listen()` integration) calls `attach()`\n * once the underlying `http.Server` is created.\n */\nexport function createWebSocketRegistrar(): WsRegistrar {\n const routes: Map<string, WsRoute> = new Map()\n let attachedServer: HttpServer | null = null\n // The `ws` `WebSocketServer` instance, lazy-initialized on first upgrade.\n // We use one server per registered path so per-handler options apply.\n const wssByPath: Map<string, unknown> = new Map()\n // We keep a reference to the `ws` module after the first dynamic import.\n let wsModule: typeof import('ws') | null = null\n\n // Single shared upgrade listener — installed exactly once.\n let upgradeListener: ((req: IncomingMessage, socket: Socket, head: Buffer) => void) | null = null\n\n function add(path: string, handler: WebSocketHandler, options: WebSocketHandlerOptions = {}): void {\n if (routes.has(path)) {\n throw new Error(`ingenium.ws: path \"${path}\" already has a WebSocket handler`)\n }\n routes.set(path, { path, handler, options })\n }\n\n function attach(httpServer: HttpServer): void {\n if (attachedServer === httpServer) return // idempotent\n if (attachedServer !== null) {\n throw new Error('ingenium.ws: registrar already attached to a different http.Server')\n }\n attachedServer = httpServer\n\n upgradeListener = (req, socket, head) => {\n // Parse the path from the upgrade request URL. We only look at the\n // pathname — query strings are exposed via `ctx.rawQuery` for handlers\n // that care.\n const url = req.url ?? '/'\n const qIdx = url.indexOf('?')\n const path = qIdx >= 0 ? url.slice(0, qIdx) : url\n\n const route = routes.get(path)\n if (!route) {\n // No handler for this path — close the socket cleanly. The\n // 404-equivalent for WebSockets is just refusing the upgrade.\n socket.destroy()\n return\n }\n\n // Lazy-load `ws`. On the first upgrade, dynamically import. If `ws`\n // isn't installed, give a clear actionable error and tear the socket\n // down — apps that wired `app.ws(...)` without installing the peer\n // dep should learn about it the moment a client tries to connect.\n void (async () => {\n try {\n if (wsModule === null) wsModule = await import('ws')\n } catch (err) {\n process.emitWarning(\n 'ingenium: app.ws() was called but the `ws` package is not installed. ' +\n 'Install it with `npm install ws` (and `@types/ws` for TypeScript).',\n )\n socket.destroy()\n return\n }\n\n let wss = wssByPath.get(route.path) as\n | InstanceType<typeof import('ws').WebSocketServer>\n | undefined\n if (!wss) {\n wss = new wsModule.WebSocketServer({\n noServer: true,\n maxPayload: route.options.maxPayload,\n perMessageDeflate: route.options.perMessageDeflate ?? false,\n })\n wssByPath.set(route.path, wss)\n }\n\n wss.handleUpgrade(req, socket, head, (ws) => {\n const ctx = buildMinimalContext(req, path)\n try {\n const ret = route.handler(ws, ctx)\n if (ret && typeof (ret as Promise<unknown>).then === 'function') {\n ;(ret as Promise<unknown>).catch((err) => {\n process.emitWarning(\n `ingenium.ws: handler for ${path} rejected: ${(err as Error)?.message ?? String(err)}`,\n )\n try { ws.close(1011, 'handler error') } catch { /* socket may already be dead */ }\n })\n }\n } catch (err) {\n process.emitWarning(\n `ingenium.ws: handler for ${path} threw: ${(err as Error)?.message ?? String(err)}`,\n )\n try { ws.close(1011, 'handler error') } catch { /* ignore */ }\n }\n })\n })()\n }\n\n httpServer.on('upgrade', upgradeListener)\n }\n\n async function close(): Promise<void> {\n // Detach the upgrade listener so a re-listen on the same server doesn't\n // double-up handlers.\n if (attachedServer && upgradeListener) {\n attachedServer.off('upgrade', upgradeListener)\n }\n upgradeListener = null\n attachedServer = null\n\n // Close every per-path WebSocketServer. `ws.WebSocketServer.close(cb)`\n // fires once all clients have disconnected; we await each in parallel.\n const closes: Promise<void>[] = []\n for (const wss of wssByPath.values()) {\n const server = wss as InstanceType<typeof import('ws').WebSocketServer>\n // Forcibly terminate any still-open clients so close() resolves\n // promptly during test teardown.\n for (const client of server.clients) {\n try { client.terminate() } catch { /* ignore */ }\n }\n closes.push(new Promise<void>((resolve) => server.close(() => resolve())))\n }\n wssByPath.clear()\n await Promise.all(closes)\n }\n\n return { add, attach, close }\n}\n\n/**\n * Build a minimal `IngeniumContext` for a WebSocket handler. We don't run the\n * full request pipeline (no middleware, no decorators) because the upgrade\n * has already taken place — the handler owns the socket from here.\n */\nfunction buildMinimalContext(req: IncomingMessage, path: string): IngeniumContext {\n const ctx = new IngeniumContext()\n ctx.method = (req.method ?? 'GET') as HttpMethod\n ctx.url = req.url ?? '/'\n ctx.path = path\n const url = ctx.url\n const qIdx = url.indexOf('?')\n ctx.rawQuery = qIdx >= 0 ? url.slice(qIdx + 1) : ''\n ctx.headers = req.headers\n return ctx\n}\n","/**\n * WebSocket-aware variant of `NodeAdapter`. Mirrors the behavior of\n * `transport/node.ts` (request handling, socket tracking, graceful close)\n * but exposes the underlying `http.Server` via an `onServerReady` callback\n * so the WS registrar can `.on('upgrade', …)` it.\n *\n * We did not modify the core `NodeAdapter` because the core has no awareness\n * of WebSockets; this adapter is opt-in via `enableWebSockets()`.\n */\n\nimport { createServer, type IncomingMessage, type Server as HttpServer, type ServerResponse } from 'node:http'\nimport type { Socket } from 'node:net'\nimport { Buffer } from 'node:buffer'\nimport type { IngeniumContext } from '../context/context.ts'\nimport type { HttpMethod } from '../router/types.ts'\nimport type {\n CloseOptions,\n ListeningServer,\n Transport,\n TransportHooks,\n} from '../transport/types.ts'\n\nexport type OnServerReady = (httpServer: HttpServer) => void\n\nexport class WsNodeAdapter implements Transport {\n private hooks: TransportHooks | null = null\n private readonly onServerReady: OnServerReady\n\n constructor(onServerReady: OnServerReady) {\n this.onServerReady = onServerReady\n }\n\n attach(hooks: TransportHooks): void {\n this.hooks = hooks\n }\n\n async listen(port: number, host = '127.0.0.1'): Promise<ListeningServer> {\n if (!this.hooks) throw new Error('WsNodeAdapter.listen() called before attach()')\n const hooks = this.hooks\n\n const server = createServer((req, res) => {\n handleRequest(req, res, hooks).catch((err) => {\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('content-type', 'application/json; charset=utf-8')\n res.end(JSON.stringify({ error: 'Internal Server Error', code: 'INTERNAL_ERROR' }))\n } else {\n res.end()\n }\n process.emitWarning(`ingenium: dispatch leaked: ${(err as Error).message ?? String(err)}`)\n })\n })\n\n // Hand the http.Server to the WS registrar BEFORE listen() resolves —\n // this guarantees upgrade listeners are wired before any client can\n // connect.\n this.onServerReady(server)\n\n const sockets = new Set<Socket>()\n server.on('connection', (socket) => {\n sockets.add(socket)\n socket.on('close', () => sockets.delete(socket))\n })\n\n return new Promise<ListeningServer>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to determine bound address'))\n return\n }\n resolve({\n port: addr.port,\n host: addr.address,\n close: (opts?: CloseOptions) =>\n new Promise<void>((res, rej) => {\n let settled = false\n let timer: NodeJS.Timeout | null = null\n\n server.close((err) => {\n if (timer) clearTimeout(timer)\n if (settled) return\n settled = true\n err ? rej(err) : res()\n })\n\n const timeoutMs = opts?.gracefulTimeoutMs\n if (typeof timeoutMs === 'number' && Number.isFinite(timeoutMs)) {\n timer = setTimeout(() => {\n for (const socket of sockets) socket.destroy()\n }, Math.max(0, timeoutMs))\n if (typeof timer.unref === 'function') timer.unref()\n }\n }),\n })\n })\n })\n }\n}\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse, hooks: TransportHooks): Promise<void> {\n const ctx = hooks.acquire()\n try {\n populateContext(ctx, req)\n await hooks.dispatch(ctx)\n writeResponse(ctx, res)\n } finally {\n hooks.release(ctx)\n }\n}\n\nfunction populateContext(ctx: IngeniumContext, req: IncomingMessage): void {\n ctx.method = (req.method ?? 'GET') as HttpMethod\n ctx.url = req.url ?? '/'\n const url = ctx.url\n const qIdx = url.indexOf('?')\n if (qIdx >= 0) {\n ctx.path = url.slice(0, qIdx)\n ctx.rawQuery = url.slice(qIdx + 1)\n } else {\n ctx.path = url\n ctx.rawQuery = ''\n }\n ctx.headers = req.headers\n\n const cl = req.headers['content-length']\n const contentLength = cl ? Number(cl) : undefined\n const ct = req.headers['content-type']\n ctx.body._attach(req, ct, Number.isFinite(contentLength) ? contentLength : undefined)\n}\n\nfunction writeResponse(ctx: IngeniumContext, res: ServerResponse): void {\n res.statusCode = ctx._statusCode\n\n for (const name in ctx._headers) {\n const value = ctx._headers[name]\n if (value !== undefined) res.setHeader(name, value)\n }\n\n const body = ctx._body\n switch (body.kind) {\n case 'none':\n res.end()\n break\n case 'string':\n if (!res.hasHeader('content-length')) {\n res.setHeader('content-length', Buffer.byteLength(body.data))\n }\n res.end(body.data)\n break\n case 'buffer':\n if (!res.hasHeader('content-length')) {\n res.setHeader('content-length', body.data.length)\n }\n res.end(body.data)\n break\n case 'stream':\n body.data.pipe(res)\n break\n }\n}\n","/**\n * WebSocket adapter for Ingenium (optional `ws` peer dependency).\n *\n * # Usage\n * ```ts\n * import { ingenium } from 'ingenium'\n * import { enableWebSockets } from 'ingenium/ws'\n *\n * const app = ingenium()\n * enableWebSockets(app)\n * app.ws('/echo', (sock) => {\n * sock.on('message', (m) => sock.send(m))\n * })\n * await app.listen(3000)\n * ```\n *\n * # Why a monkey-patch?\n * `enableWebSockets(app)` augments the app instance with `app.ws()` and\n * wraps `app.listen()` so the registrar gets attached to the underlying\n * `http.Server` once it's bound. We chose this over extending `IngeniumApp` to\n * avoid pulling `./ws/middleware.ts` into the core import graph (which would\n * create a soft dep on `ws` types from every `app.ts` consumer). This is a\n * known pattern in WS-extending frameworks (e.g. `express-ws`).\n *\n * The trade-off: TypeScript can't statically see `app.ws` unless the\n * augmentation below is loaded. Importing this module both registers the\n * runtime patch AND adds the type augmentation to the global `IngeniumApp`.\n */\n\nimport type { IngeniumApp } from '../app.ts'\nimport type { ListeningServer, Transport } from '../transport/types.ts'\nimport { createWebSocketRegistrar, peerHasWs } from './middleware.ts'\nimport { WsNodeAdapter } from './ws-node-adapter.ts'\nimport type {\n WebSocketHandler,\n WebSocketHandlerOptions,\n WsIntegrator,\n WsRegistrar,\n} from './types.ts'\n\nexport type {\n WebSocketHandler,\n WebSocketHandlerOptions,\n WsIntegrator,\n WsRegistrar,\n WebSocket,\n} from './types.ts'\nexport { createWebSocketRegistrar, peerHasWs } from './middleware.ts'\n\n// ───── Type augmentation ────────────────────────────────────────────────────\n// Declared on IngeniumApp so `app.ws(...)` and `app.upgradeWith(...)` typecheck\n// for any consumer that imports from 'ingenium/ws'.\ndeclare module '../app.ts' {\n interface IngeniumApp {\n ws(path: string, handler: WebSocketHandler, options?: WebSocketHandlerOptions): IngeniumApp\n upgradeWith(integrator: WsIntegrator): IngeniumApp\n }\n}\n\n/** Per-app state attached by `enableWebSockets`. Internal. */\ninterface WsAppState {\n registrar: WsRegistrar\n integrators: WsIntegrator[]\n enabled: true\n}\n\nconst APP_STATE: WeakMap<IngeniumApp, WsAppState> = new WeakMap()\n\n/** Options for `enableWebSockets`. Reserved for future use. */\nexport interface EnableWebSocketsOptions {\n /**\n * When `true`, eagerly probes for the `ws` peer dependency at install\n * time and prints a warning if it is missing. Default: `false` (we wait\n * until the first upgrade attempt).\n */\n warnOnMissingPeer?: boolean\n}\n\n/**\n * Augment a `IngeniumApp` with WebSocket support. Idempotent — calling more than\n * once on the same app is a no-op.\n */\nexport function enableWebSockets(app: IngeniumApp, opts: EnableWebSocketsOptions = {}): void {\n if (APP_STATE.has(app)) return\n\n const registrar = createWebSocketRegistrar()\n const state: WsAppState = { registrar, integrators: [], enabled: true }\n APP_STATE.set(app, state)\n\n if (opts.warnOnMissingPeer) {\n void peerHasWs().then((ok) => {\n if (!ok) {\n process.emitWarning(\n 'ingenium: enableWebSockets() called but `ws` is not installed. ' +\n 'Install it with `npm install ws`.',\n )\n }\n })\n }\n\n // Attach the new methods. We assign with a cast because the augmentation\n // above only exists at the type layer.\n ;(app as unknown as { ws: IngeniumApp['ws'] }).ws = function (\n path: string,\n handler: WebSocketHandler,\n options?: WebSocketHandlerOptions,\n ): IngeniumApp {\n state.registrar.add(path, handler, options)\n return app\n }\n\n ;(app as unknown as { upgradeWith: IngeniumApp['upgradeWith'] }).upgradeWith = function (\n integrator: WsIntegrator,\n ): IngeniumApp {\n state.integrators.push(integrator)\n return app\n }\n\n // Swap in a WebSocket-aware Node transport. We do this via bracket-access\n // because `IngeniumApp#transport` is `private` (TypeScript-only — `private`\n // doesn't actually hide the field at runtime). If the user injected a\n // custom transport via `IngeniumAppOptions.transport`, we leave it alone and\n // log a warning — they're responsible for calling `registrar.attach()`\n // themselves via `app.upgradeWith(...)`.\n const appAny = app as unknown as { transport: Transport }\n const existing = appAny.transport\n const isDefault = existing.constructor?.name === 'NodeAdapter'\n\n if (isDefault) {\n appAny.transport = new WsNodeAdapter((httpServer) => {\n state.registrar.attach(httpServer)\n for (const integrator of state.integrators) integrator(httpServer)\n })\n } else {\n process.emitWarning(\n 'ingenium.ws: a custom Transport is in use — WebSockets will only be wired ' +\n 'if you call `app.upgradeWith((httpServer) => registrar.attach(httpServer))` from your transport.',\n )\n }\n\n // Wrap close() of the eventual ListeningServer so the registrar tears\n // down its WebSocketServers first — otherwise `server.close()` hangs\n // forever waiting on the open WS sockets.\n const originalListen = app.listen.bind(app)\n ;(app as unknown as { listen: IngeniumApp['listen'] }).listen = async function (\n port: number,\n host?: string,\n ): Promise<ListeningServer> {\n const server = await originalListen(port, host)\n const originalClose = server.close.bind(server)\n return {\n port: server.port,\n host: server.host,\n close: async (closeOpts) => {\n await state.registrar.close()\n await originalClose(closeOpts)\n },\n }\n }\n}\n\n// Re-export the WS-aware Node transport for advanced users who want to\n// construct it manually (e.g. when wiring a custom Transport stack).\nexport { WsNodeAdapter } from './ws-node-adapter.ts'\n","/**\n * Sinatra-style top-level shorthand.\n *\n * Lets users skip the app object entirely:\n *\n * ```ts\n * import { get, post, listen } from 'ingenium'\n *\n * get('/', () => 'hi')\n * get('/users/:id', (ctx) => ({ id: ctx.params.id }))\n * post('/echo', async (ctx) => ctx.body.json())\n *\n * await listen(3000)\n * ```\n *\n * All exported verbs route to a lazy singleton `IngeniumApp` created on first\n * call. The instance is retained for the lifetime of the process; tests can\n * call `_resetDefaultApp()` to drop it (this throws in production).\n */\n\nimport { IngeniumApp, type IngeniumErrorHandler } from '../app.ts'\nimport type { IngeniumHandler, IngeniumMiddleware } from '../middleware/types.ts'\nimport { Router } from '../router/router.ts'\nimport type { ListeningServer } from '../transport/types.ts'\n\nlet _defaultApp: IngeniumApp | null = null\n\n/**\n * Get the lazy default app. Created on first call, retained for the\n * lifetime of the process (or until `_resetDefaultApp()` is invoked).\n *\n * The same instance is returned on every subsequent call, so all\n * top-level verb functions and `listen()` operate on a single coherent\n * registration journal.\n */\nexport function defaultApp(): IngeniumApp {\n if (!_defaultApp) _defaultApp = new IngeniumApp()\n return _defaultApp\n}\n\n/**\n * Reset the default app — for tests only. The next call to any top-level\n * function will lazily create a fresh `IngeniumApp`. Throws when\n * `NODE_ENV === 'production'` so accidental production calls are loud.\n */\nexport function _resetDefaultApp(): void {\n if (process.env.NODE_ENV === 'production') {\n throw new Error('_resetDefaultApp is a test-only API')\n }\n _defaultApp = null\n}\n\n// ───── HTTP verb shorthand ──────────────────────────────────────────────────\n//\n// Signatures mirror `IngeniumApp.get/post/...` exactly (`(path, handler)`),\n// so the typed-ctx story (e.g. `IngeniumHandler<{ id: string }>`) is preserved\n// for users who import these as drop-in replacements for `app.get(...)`.\n\nexport function get(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().get(path, handler)\n}\n\nexport function post(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().post(path, handler)\n}\n\nexport function put(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().put(path, handler)\n}\n\nexport function patch(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().patch(path, handler)\n}\n\n/**\n * Default-app shorthand for `app.delete(path, handler)`.\n * Exported as `del` because `delete` is a reserved word in JavaScript and\n * cannot be used as a top-level identifier. `index.ts` re-exports this as\n * `{ del as delete }` so the public name is `delete`.\n */\nexport function del(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().delete(path, handler)\n}\n\nexport function head(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().head(path, handler)\n}\n\nexport function options(path: string, handler: IngeniumHandler): IngeniumApp {\n return defaultApp().options(path, handler)\n}\n\n// ───── use / onError / listen ───────────────────────────────────────────────\n\n/**\n * Mount middleware on the default app. Same overload set as `app.use`:\n * - `use(mw)` — global\n * - `use(prefix, mw | Router)` — prefix-scoped\n */\nexport function use(mw: IngeniumMiddleware): IngeniumApp\nexport function use(prefix: string, mw: IngeniumMiddleware | Router): IngeniumApp\nexport function use(\n arg1: string | IngeniumMiddleware,\n arg2?: IngeniumMiddleware | Router,\n): IngeniumApp {\n const app = defaultApp()\n if (typeof arg1 === 'string') {\n return app.use(arg1, arg2 as IngeniumMiddleware | Router)\n }\n return app.use(arg1)\n}\n\n/** Default-app shorthand for `app.onError(handler)`. */\nexport function onError(handler: IngeniumErrorHandler): IngeniumApp {\n return defaultApp().onError(handler)\n}\n\n/**\n * Bind the default app to a port. Returns a `ListeningServer` whose\n * `.close()` shuts down the underlying transport. Pass `0` for an\n * ephemeral port (useful in tests).\n */\nexport function listen(port: number, host?: string): Promise<ListeningServer> {\n return host !== undefined ? defaultApp().listen(port, host) : defaultApp().listen(port)\n}\n\n// ───── Sinatra-style filter shorthand ───────────────────────────────────────\n//\n// Mirrors `IngeniumApp.before/after` overloads exactly.\n\nexport function before(handler: IngeniumMiddleware): IngeniumApp\nexport function before(pattern: string, handler: IngeniumMiddleware): IngeniumApp\nexport function before(\n arg1: string | IngeniumMiddleware,\n arg2?: IngeniumMiddleware,\n): IngeniumApp {\n const app = defaultApp()\n if (typeof arg1 === 'string') return app.before(arg1, arg2 as IngeniumMiddleware)\n return app.before(arg1)\n}\n\nexport function after(handler: IngeniumMiddleware): IngeniumApp\nexport function after(pattern: string, handler: IngeniumMiddleware): IngeniumApp\nexport function after(\n arg1: string | IngeniumMiddleware,\n arg2?: IngeniumMiddleware,\n): IngeniumApp {\n const app = defaultApp()\n if (typeof arg1 === 'string') return app.after(arg1, arg2 as IngeniumMiddleware)\n return app.after(arg1)\n}\n","/**\n * Ingenium — Express DX, Hono/Fastify throughput.\n *\n * @packageDocumentation\n */\n\nimport { makeIngeniumFactory, type IngeniumFactory } from './app.ts'\nimport { jsonMiddleware, urlencodedMiddleware } from './body/middleware.ts'\nimport { staticMiddleware } from './static/middleware.ts'\nimport { corsMiddleware } from './cors/middleware.ts'\nimport { sse } from './sse/sse.ts'\nimport { rateLimit } from './rate-limit/middleware.ts'\nimport { csrfMiddleware } from './csrf/middleware.ts'\nimport { problemDetailsMiddleware } from './problem/middleware.ts'\nimport { idempotencyMiddleware } from './idempotency/middleware.ts'\nimport { jwtMiddleware } from './jwt/middleware.ts'\nimport { apiKeyMiddleware } from './api-key/middleware.ts'\nimport { openapiHandler } from './openapi/handler.ts'\n\n// ───── App + Router ────────────────────────────────────────────────────────\nexport {\n IngeniumApp,\n type IngeniumAppOptions,\n type IngeniumErrorHandler,\n type RouteOptions,\n type InjectRequest,\n type InjectResponse,\n} from './app.ts'\nexport { Router, RouteBuilder } from './router/router.ts'\n\n// ───── Context + Body ──────────────────────────────────────────────────────\nexport { IngeniumContext, type ResponseBody, type IngeniumQuery } from './context/context.ts'\nexport type {\n IngeniumCookies,\n CookieSetOptions,\n CookieGetOptions,\n} from './context/cookies.ts'\nexport { IngeniumBody, type ParseSchema, type SafeParseSchema } from './context/body.ts'\nexport { IngeniumContextPool } from './context/pool.ts'\nexport type {\n MultipartFile,\n MultipartOptions,\n MultipartResult,\n} from './body/multipart-types.ts'\n\n// ───── Standard Schema (https://standardschema.dev) ────────────────────────\nexport {\n isStandardSchema,\n type StandardSchemaV1,\n type StandardResult,\n type StandardIssue,\n type StandardPathSegment,\n type StandardSuccessResult,\n type StandardFailureResult,\n type StandardSchemaV1Props,\n} from './schema/standard.ts'\n\n// ───── Middleware + Handler types ──────────────────────────────────────────\nexport type { IngeniumMiddleware, IngeniumHandler, ComposedHandler } from './middleware/types.ts'\nexport { compose, composeWithHandler } from './middleware/compose.ts'\n\n// ───── Router types ────────────────────────────────────────────────────────\nexport type { HttpMethod, ExtractParams } from './router/types.ts'\nexport { HTTP_METHODS } from './router/types.ts'\nexport { RouterTrie, TrieNode, type MatchResult, type MatchMiss } from './router/trie.ts'\n\n// ───── Static-file middleware ──────────────────────────────────────────────\nexport { staticMiddleware as static_ } from './static/middleware.ts'\nexport type { StaticOptions } from './static/types.ts'\n\n// ───── CORS middleware ─────────────────────────────────────────────────────\nexport { corsMiddleware as cors_ } from './cors/middleware.ts'\nexport type { CorsOptions, CorsOrigin, CorsOriginFn } from './cors/types.ts'\n\n// ───── Errors ──────────────────────────────────────────────────────────────\nexport {\n IngeniumError,\n IngeniumNotFoundError,\n IngeniumUnauthorizedError,\n IngeniumMethodNotAllowedError,\n IngeniumPayloadTooLargeError,\n IngeniumValidationError,\n IngeniumBadRequestError,\n IngeniumHeaderInjectionError,\n IngeniumUnserializableError,\n IngeniumTimeoutError,\n IngeniumHaltError,\n} from './errors.ts'\n\n// ───── JSON serialization helpers ──────────────────────────────────────────\nexport { safeJsonStringify, type SafeJsonStringifyOptions } from './util/safe-json.ts'\n\n// ───── Transport (mainly for advanced users / tests) ───────────────────────\nexport type { Transport, TransportHooks, ListeningServer, CloseOptions } from './transport/types.ts'\nexport { NodeAdapter } from './transport/node.ts'\nexport { Http2Adapter, Http2cAdapter, type Http2AdapterOptions } from './transport/http2.ts'\nexport { gracefulShutdown, type ShutdownOptions } from './transport/shutdown.ts'\n\n// ───── Trust-proxy ─────────────────────────────────────────────────────────\nexport { resolveForwarded, type TrustProxy, type ForwardedInfo } from './proxy/trust.ts'\n\n// ───── Server-Sent Events helper ───────────────────────────────────────────\nexport { sse, type SseStream, type SseEvent } from './sse/sse.ts'\nexport { startKeepAlive } from './sse/keep-alive.ts'\n\n// ───── Rate-limit middleware ───────────────────────────────────────────────\nexport { rateLimit } from './rate-limit/middleware.ts'\nexport { MemoryStore as RateLimitMemoryStore } from './rate-limit/store.ts'\nexport type { RateLimitOptions, RateLimitStore } from './rate-limit/types.ts'\n\n// ───── CSRF middleware ─────────────────────────────────────────────────────\nexport { csrfMiddleware, IngeniumCsrfError } from './csrf/middleware.ts'\nexport type { CsrfOptions, CsrfStorage, CsrfCookieOptions, CsrfValueReader } from './csrf/types.ts'\n\n// ───── Content negotiation ─────────────────────────────────────────────────\nexport {\n parseAcceptHeader,\n selectBest,\n expandShorthand,\n sortByPreference,\n type ParsedAccept,\n} from './negotiation/accept.ts'\nexport {\n accepts,\n acceptsCharsets,\n acceptsLanguages,\n acceptsEncodings,\n type NegotiableCtx,\n} from './negotiation/negotiate.ts'\nexport {\n formatResponse,\n type FormatHandlers,\n type FormattableCtx,\n} from './negotiation/format.ts'\nexport { isFresh, type HeaderBag } from './negotiation/fresh.ts'\nexport { computeEtag } from './negotiation/etag.ts'\nexport {\n respondJsonWithEtag,\n type JsonEtagOptions,\n type JsonEtagCtx,\n} from './negotiation/json-etag.ts'\n\n// ───── RFC 7807 Problem Details middleware ─────────────────────────────────\nexport { problemDetailsMiddleware } from './problem/middleware.ts'\nexport { toProblemDetails } from './problem/serialize.ts'\nexport type { ProblemDetails, ProblemDetailsOptions } from './problem/types.ts'\n\n// ───── Idempotency-Key middleware ──────────────────────────────────────────\nexport { idempotencyMiddleware } from './idempotency/middleware.ts'\nexport { IdempotencyMemoryStore } from './idempotency/store.ts'\nexport type {\n CachedResponse,\n IdempotencyOptions,\n IdempotencyStore,\n} from './idempotency/types.ts'\n\n// ───── JWT middleware ──────────────────────────────────────────────────────\nexport { jwtMiddleware } from './jwt/middleware.ts'\nexport { verifyJwt } from './jwt/verify.ts'\nexport { fetchJwks, clearJwksCache } from './jwt/jwks.ts'\nexport type {\n JwtAlgorithm,\n JwtHeader,\n JwtKey,\n JwtOptions,\n JwtSecret,\n JwtSecretResolver,\n JwtTokenReader,\n JwtVerified,\n JwtLogger,\n} from './jwt/types.ts'\n\n// ───── API-key middleware ──────────────────────────────────────────────────\nexport { apiKeyMiddleware } from './api-key/middleware.ts'\nexport type { ApiKeyOptions, ApiKeyValidator, ApiKeyLogger } from './api-key/types.ts'\n\n// ───── OpenAPI 3.1 spec generation ─────────────────────────────────────────\nexport { generateOpenApi } from './openapi/generate.ts'\nexport type { GenerateOpenApiOptions } from './openapi/generate.ts'\nexport { openapiHandler } from './openapi/handler.ts'\nexport type { RouteDescriptor } from './openapi/describe.ts'\nexport type {\n OpenApiSpec,\n PathItem,\n Operation,\n Parameter,\n RequestBody,\n Response as OpenApiResponse,\n Schema as OpenApiSchema,\n Info as OpenApiInfo,\n Server as OpenApiServer,\n Tag as OpenApiTag,\n Components as OpenApiComponents,\n SecurityScheme as OpenApiSecurityScheme,\n SecurityRequirement as OpenApiSecurityRequirement,\n} from './openapi/types.ts'\n\n// ───── Background jobs ─────────────────────────────────────────────────────\nexport { IngeniumQueue } from './jobs/queue.ts'\nexport { QueueRegistry } from './jobs/registry.ts'\nexport { MemoryQueueStore } from './jobs/store-memory.ts'\nexport type {\n QueueOptions,\n QueueWorker,\n QueueStore,\n RetryPolicy,\n FailedJob,\n JobHandle,\n RegisteredQueue,\n} from './jobs/types.ts'\n\n// ───── Cron scheduling ─────────────────────────────────────────────────────\nexport { IngeniumCronJob } from './cron/scheduler.ts'\nexport type { CronHandler, CronOptions } from './cron/scheduler.ts'\nexport { CronRegistry } from './cron/registry.ts'\nexport { parseCronSpec, nextFireFrom } from './cron/parser.ts'\nexport type { CronMatch } from './cron/parser.ts'\n\n// ───── Session middleware ──────────────────────────────────────────────────\nexport { sessionMiddleware } from './session/middleware.ts'\nexport { MemoryStore as SessionMemoryStore } from './session/store-memory.ts'\nexport type {\n Session,\n SessionOptions,\n SessionStore,\n SessionCookieOptions,\n} from './session/types.ts'\n\n// ───── WebSocket adapter (optional `ws` peer dep) ──────────────────────────\nexport {\n enableWebSockets,\n createWebSocketRegistrar,\n peerHasWs,\n WsNodeAdapter,\n type EnableWebSocketsOptions,\n type WebSocketHandler,\n type WebSocketHandlerOptions,\n type WsIntegrator,\n type WsRegistrar,\n type WebSocket,\n} from './ws/index.ts'\n\n// ───── Plugin system ───────────────────────────────────────────────────────\nexport type {\n IngeniumPlugin,\n PluginTarget,\n Hooks,\n RegistrationEvent,\n Decorator,\n LazyDecorator,\n EagerDecorator,\n OnRouteHook,\n OnComposeHook,\n OnRequestHook,\n OnResponseHook,\n OnErrorHook,\n} from './plugin/types.ts'\nexport { HooksRegistry } from './plugin/hooks.ts'\nexport { DecoratorRegistry } from './plugin/decorators.ts'\nexport { ScopedApp } from './app/scope.ts'\n\n// ───── Default factory + body parsers ──────────────────────────────────────\n\n/**\n * Create a new Ingenium application.\n *\n * @example\n * import { ingenium } from 'ingenium'\n *\n * const app = ingenium()\n * app.get('/', (ctx) => ({ hello: 'world' }))\n * await app.listen(3000)\n */\nconst ingeniumCore: IngeniumFactory = makeIngeniumFactory()\n\n/**\n * The `ingenium` export is callable AND has static helpers attached:\n *\n * - `ingenium(opts?)` — create an app\n * - `ingenium.Router()` — create a mountable router\n * - `ingenium.json(opts?)` — Express-compat body-parser shim (no-op; parsing is lazy)\n * - `ingenium.urlencoded(opts?)` — same, for `application/x-www-form-urlencoded`\n * - `ingenium.static(root, opts?)` — serve files from a directory\n * - `ingenium.cors(opts?)` — CORS middleware (simple + preflight)\n */\n// ───── Sinatra-style top-level ──────────────────────────────────────────────\n//\n// Lets users skip the app object entirely:\n//\n// import { get, listen } from 'ingenium'\n// get('/', () => 'hi')\n// await listen(3000)\n//\n// Every verb routes to a lazy singleton `IngeniumApp` (see `defaultApp()`).\n// `_resetDefaultApp` is test-only and throws under NODE_ENV=production.\nexport {\n defaultApp,\n _resetDefaultApp,\n get,\n post,\n put,\n patch,\n del as delete,\n head,\n options,\n use,\n onError,\n listen,\n before,\n after,\n} from './sinatra/top-level.ts'\n\nexport const ingenium = Object.assign(ingeniumCore, {\n json: jsonMiddleware,\n urlencoded: urlencodedMiddleware,\n static: staticMiddleware,\n cors: corsMiddleware,\n csrf: csrfMiddleware,\n sse,\n rateLimit,\n problemDetails: problemDetailsMiddleware,\n idempotency: idempotencyMiddleware,\n jwt: jwtMiddleware,\n apiKey: apiKeyMiddleware,\n openapiHandler,\n})\n\nexport default ingenium\n"]}
|