@orieljs/http 0.1.0-alpha.10 → 0.1.0-alpha.11

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../errors.ts","../body.ts","../context.ts","../HttpRedirectResponse.ts","../HttpRedirector.ts","../clientAddress.ts","../FormUploadedFile.ts","../mime.ts","../IncomingRequest.ts","../input.ts","../helpers.ts","../HttpResponseFactory.ts","../Kernel.ts","../middleware/ConvertEmptyStringsToNull.ts","../middleware/TrimStrings.ts","../MiddlewareConfiguration.ts","../ErrorHandler.ts","../errorPages.ts","../ExceptionsConfiguration.ts","../server/types.ts","../server/static.ts","../server/bun.ts","../server/node.ts","../server/serve.ts","../commands.ts","../watch/environment.ts","../watch/files.ts","../watch/port.ts","../watch/WatchedServer.ts","../HttpServiceProvider.ts"],"sourcesContent":["import type { OrielError } from '@orieljs/contracts'\n\n/** Symfony's HttpException: abort(404), abort(403, 'Nope'). An empty message renders as the status text. */\nexport class HttpException extends Error implements OrielError {\n readonly kind = 'Http' as const\n override readonly name = 'HttpException'\n constructor(\n readonly status: number,\n message = '',\n readonly headers: Record<string, string> = {},\n ) {\n super(message)\n }\n}\n\n/** Carries a ready Response out of deep code: abort(response). The handler returns it as is. */\nexport class HttpResponseException extends Error implements OrielError {\n readonly kind = 'Http' as const\n override readonly name = 'HttpResponseException'\n readonly status: number\n constructor(readonly response: Response) {\n super(`HTTP response exception (${response.status}).`)\n this.status = response.status\n }\n}\n\n/** Http's internal failures (not thrown by this package itself; used by the kernel and error rendering). */\nexport class HttpServerError extends Error implements OrielError {\n readonly kind = 'Server' as const\n readonly status = 500\n override readonly name = 'HttpServerError'\n}\n","import { HttpException } from './errors'\n\n/**\n * Whether a JSON text nests objects and arrays deeper than `maxDepth`, found by scanning (no parsing, no recursion):\n * brackets inside strings don't count. The kernel answers 400 for such bodies (http.max_json_depth) before the\n * recursive input handling (sanitizing, TrimStrings, validation) could overflow the stack.\n */\nexport function exceedsJsonDepth(text: string, maxDepth: number): boolean {\n let depth = 0\n let inString = false\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (inString) {\n if (code === 92) i++ // a backslash escapes the next character\n else if (code === 34) inString = false\n } else if (code === 34) inString = true\n else if (code === 123 || code === 91) {\n if (++depth > maxDepth) return true\n } else if (code === 125 || code === 93) depth--\n }\n return false\n}\n\n/** Reads a request body into memory, refusing more than `limit` bytes (413), like PHP's post_max_size. */\nexport async function readBody(raw: Request, limit: number | null): Promise<Uint8Array> {\n if (raw.body === null) return new Uint8Array(0)\n const declared = Number(raw.headers.get('content-length') ?? NaN)\n if (limit !== null && Number.isFinite(declared) && declared > limit) {\n await raw.body.cancel()\n throw new HttpException(413, 'Content Too Large')\n }\n const reader = raw.body.getReader()\n const chunks: Uint8Array[] = []\n let size = 0\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n size += value.byteLength\n if (limit !== null && size > limit) {\n await reader.cancel()\n throw new HttpException(413, 'Content Too Large')\n }\n chunks.push(value)\n }\n const out = new Uint8Array(size)\n let offset = 0\n for (const chunk of chunks) {\n out.set(chunk, offset)\n offset += chunk.byteLength\n }\n return out\n}\n","import { CookieJar, HttpRequest, Session, type Container } from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\n\n/** The current container, only when it is a request scope (the kernel binds HttpRequest there). */\nexport function requestScope(): Container | undefined {\n const container = currentContainer()\n return container !== undefined && container.bound(HttpRequest) ? container : undefined\n}\n\nexport function currentRequest(): HttpRequest | undefined {\n return requestScope()?.make(HttpRequest)\n}\n\n/** The request's session, or undefined outside a request or when no Session provider is registered. */\nexport function optionalSession(): Session | undefined {\n const scope = requestScope()\n return scope?.bound(Session) ? scope.make(Session) : undefined\n}\n\nexport function optionalCookieJar(): CookieJar | undefined {\n const scope = requestScope()\n return scope?.bound(CookieJar) ? scope.make(CookieJar) : undefined\n}\n","import type { Cookie, HeadersInit, MessageBag, RedirectResponse } from '@orieljs/contracts'\nimport { currentRequest, optionalCookieJar, optionalSession } from './context'\n\ntype ErrorsInput = Record<string, string | string[]> | MessageBag\n\n/** A Set-Cookie value. `minutes` 0 is a session cookie; a negative value deletes the cookie. */\nfunction serializeCookie(cookie: Cookie): string {\n const parts = [`${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`, `Path=${cookie.path}`]\n if (cookie.domain !== undefined) parts.push(`Domain=${cookie.domain}`)\n if (cookie.secure) parts.push('Secure')\n if (cookie.httpOnly) parts.push('HttpOnly')\n parts.push(`SameSite=${cookie.sameSite.charAt(0).toUpperCase()}${cookie.sameSite.slice(1)}`)\n if (cookie.minutes < 0) parts.push('Max-Age=0', 'Expires=Thu, 01 Jan 1970 00:00:00 GMT')\n else if (cookie.minutes > 0) parts.push(`Max-Age=${Math.round(cookie.minutes * 60)}`)\n return parts.join('; ')\n}\n\n/**\n * Laravel's RedirectResponse. with()/withErrors()/withInput() flash to the request's Session immediately, like\n * Laravel; without a bound Session (an API-only app) they are skipped silently.\n */\nexport class HttpRedirectResponse implements RedirectResponse {\n readonly #headers: Headers\n\n constructor(\n readonly targetUrl: string,\n readonly status = 302,\n headers?: HeadersInit,\n ) {\n this.#headers = new Headers(headers)\n }\n\n with(key: string | Record<string, unknown>, value?: unknown): this {\n const session = optionalSession()\n if (session === undefined) return this\n if (typeof key === 'string') session.flash(key, value)\n else for (const [name, item] of Object.entries(key)) session.flash(name, item)\n return this\n }\n\n /** Flashes `errors` as { [bag]: { field: string[] } }, keeping the other bags already flashed. */\n withErrors(errors: ErrorsInput, bag = 'default'): this {\n const session = optionalSession()\n if (session === undefined) return this\n const source =\n typeof (errors as { toObject?: unknown }).toObject === 'function'\n ? (errors as MessageBag).toObject()\n : (errors as Record<string, string | string[]>)\n const normalized = Object.fromEntries(\n Object.entries(source).map(([field, messages]) => [field, Array.isArray(messages) ? [...messages] : [messages]]),\n )\n const existing = session.get<Record<string, Record<string, string[]>>>('errors', {})\n session.flash('errors', { ...existing, [bag]: normalized })\n return this\n }\n\n /** Flashes `input`, or the current request's input (files are never part of input()). */\n withInput(input?: Record<string, unknown>): this {\n const session = optionalSession()\n if (session === undefined) return this\n session.flashInput(input ?? currentRequest()?.input<Record<string, unknown>>() ?? {})\n return this\n }\n\n /**\n * Always a Set-Cookie header on this response (Laravel's RedirectResponse::withCookie). A bound CookieJar only\n * supplies the defaults (path, domain, secure, same-site); queueing would lose the cookie outside the web group.\n */\n withCookie(name: string, value: string, minutes = 0): this {\n const jar = optionalCookieJar()\n const cookie: Cookie =\n jar !== undefined\n ? jar.make(name, value, minutes)\n : { name, value, minutes, path: '/', secure: false, httpOnly: true, sameSite: 'lax' }\n this.#headers.append('Set-Cookie', serializeCookie(cookie))\n return this\n }\n\n header(name: string, value: string): this {\n this.#headers.set(name, value)\n return this\n }\n\n toResponse(): Response {\n const headers = new Headers(this.#headers)\n headers.set('Location', this.targetUrl)\n return new Response(null, { status: this.status, headers })\n }\n}\n","import { UrlGenerator, type HeadersInit, type Redirector } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { currentRequest, optionalSession } from './context'\nimport { HttpRedirectResponse } from './HttpRedirectResponse'\n\n/**\n * A URL's path, query and fragment: '/dashboard?tab=1' (the intended URL is stored like this). Leading slashes\n * collapse to one, so '//evil.com/x' can never be read back as a protocol-relative URL.\n */\nfunction pathOf(url: string): string {\n let parsed: URL\n try {\n parsed = new URL(url, 'http://localhost')\n } catch {\n return '/'\n }\n return `${parsed.pathname.replace(/^\\/+/, '/')}${parsed.search}${parsed.hash}`\n}\n\n/** Laravel's Redirector. Stateless: the URL generator and session come from the current container. */\nexport class HttpRedirector implements Redirector {\n to(path: string, status = 302, headers?: HeadersInit): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).to(path), status, headers)\n }\n\n route(name: string, parameters?: unknown, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).route(name, parameters), status)\n }\n\n back(fallback?: string, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).previous(fallback), status)\n }\n\n /** Pulls url.intended from the session (put there by guest()), else goes to `fallback`. */\n intended(fallback = '/', status = 302): HttpRedirectResponse {\n const path = optionalSession()?.pull<string | undefined>('url.intended') ?? fallback\n return this.to(path, status)\n }\n\n away(url: string, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(url, status)\n }\n\n /**\n * Remembers where a guest was going (a GET page, else the previous URL), then redirects to `path`. Only the path\n * is stored, so intended() goes back on whichever host serves the app, and never to another site's Referer.\n */\n guest(path: string, status = 302): HttpRedirectResponse {\n const session = optionalSession()\n const request = currentRequest()\n if (session !== undefined) {\n const intended =\n request !== undefined && request.method() === 'GET' && !request.expectsJson()\n ? request.fullUrl()\n : inject(UrlGenerator).previous()\n session.put('url.intended', pathOf(intended))\n }\n return this.to(path, status)\n }\n\n setIntendedUrl(url: string): void {\n optionalSession()?.put('url.intended', url)\n }\n\n refresh(status = 302): HttpRedirectResponse {\n return this.to(currentRequest()?.fullUrl() ?? inject(UrlGenerator).current(), status)\n }\n}\n","/**\n * The socket address of each incoming Request, filled by the server adapters (and by test clients).\n * Kept on globalThis under a Symbol.for key, so a package that can't import @orieljs/http (Testing) can set it.\n */\nconst KEY = Symbol.for('oriel:http.client-address')\nconst store = ((globalThis as unknown as Record<symbol, WeakMap<Request, string> | undefined>)[KEY] ??= new WeakMap<Request, string>())\n\nexport function setClientAddress(request: Request, address: string | undefined): void {\n if (address !== undefined && address !== '') store.set(request, address)\n}\n\nexport function clientAddress(request: Request): string | undefined {\n return store.get(request)\n}\n","import { FilesystemManager, type UploadedFile } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { FileType, Str } from '@orieljs/support'\nimport { extensionFromMime } from './mime'\n\n/** Extensions a stored file never takes from the client's claim alone: the formats the bytes are read for, and what a browser renders or runs. */\nconst NEVER_CLAIMED: ReadonlySet<string> = new Set([\n ...FileType.BINARY_AND_MARKUP_TYPES.flatMap(({ extensions }) => extensions),\n 'jpe', 'svgz', 'xhtml', 'xht', 'shtml', 'xsl', 'xslt', 'mht', 'mhtml', 'js', 'mjs',\n 'rss', 'atom', 'rdf', 'mathml', 'mml', 'xul',\n])\n\n/** A claim is kept only as a plain extension, the same test putFile() applies to the name it writes. */\nconst PLAIN_EXTENSION = /^[a-z0-9]+$/\n\n/** An uploaded file from a multipart body. store()/storeAs() go through the FilesystemManager. */\nexport class FormUploadedFile implements UploadedFile {\n readonly clientName: string\n readonly mimeType: string\n readonly size: number\n\n /**\n * Reads the leading bytes first, so extension(), hashName() and store() name the file by its content. The request\n * builds its uploads this way.\n */\n static async fromFile(file: Blob & { readonly name?: string }): Promise<FormUploadedFile> {\n return new FormUploadedFile(file, FileType.detectFileType(new Uint8Array(await file.slice(0, FileType.SNIFF_BYTES).arrayBuffer())))\n }\n\n constructor(\n private readonly file: Blob & { readonly name?: string },\n private readonly detected?: FileType.DetectedType,\n ) {\n this.clientName = file.name ?? ''\n this.mimeType = file.type === '' ? 'application/octet-stream' : file.type\n this.size = file.size\n }\n\n /**\n * Laravel's extension(): the type the bytes show (guessExtension()), when they were read and match a known format.\n * Text and bytes no format matches keep the client's claim (its MIME type, else its file name) when it is a plain\n * extension, unless it names a format the bytes would have shown or one a browser renders or runs: otherwise 'txt'\n * for text, '' for the rest. Unread (built directly), the client's claim when it is a plain extension, else ''.\n */\n extension(): string {\n const claimed = extensionFromMime(this.mimeType) ?? this.clientExtension()\n const detected = this.detected\n if (detected === undefined) return PLAIN_EXTENSION.test(claimed) ? claimed : ''\n if (detected !== FileType.TEXT && detected.extensions.length > 0) return detected.extensions[0]!\n if (PLAIN_EXTENSION.test(claimed) && !NEVER_CLAIMED.has(claimed)) return claimed\n return detected === FileType.TEXT ? 'txt' : ''\n }\n\n clientExtension(): string {\n const dot = this.clientName.lastIndexOf('.')\n return dot === -1 ? '' : this.clientName.slice(dot + 1).toLowerCase()\n }\n\n /** A random 40-character name with the guessed extension. */\n hashName(): string {\n const extension = this.extension()\n return extension === '' ? Str.random(40) : `${Str.random(40)}.${extension}`\n }\n\n arrayBuffer(): Promise<ArrayBuffer> {\n return this.file.arrayBuffer()\n }\n\n text(): Promise<string> {\n return this.file.text()\n }\n\n stream(): ReadableStream<Uint8Array> {\n return this.file.stream() as ReadableStream<Uint8Array>\n }\n\n store(directory: string, disk?: string): Promise<string> {\n return inject(FilesystemManager).disk(disk).putFile(directory, this)\n }\n\n storeAs(directory: string, name: string, disk?: string): Promise<string> {\n return inject(FilesystemManager).disk(disk).putFileAs(directory, this, name)\n }\n}\n","/** A small extension ↔ MIME map for uploads and downloads (not exhaustive on purpose). */\nconst TYPES: Record<string, string> = {\n avif: 'image/avif',\n css: 'text/css',\n csv: 'text/csv',\n doc: 'application/msword',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n gif: 'image/gif',\n gz: 'application/gzip',\n html: 'text/html',\n ico: 'image/vnd.microsoft.icon',\n jpg: 'image/jpeg',\n js: 'text/javascript',\n map: 'application/json',\n json: 'application/json',\n md: 'text/markdown',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n otf: 'font/otf',\n pdf: 'application/pdf',\n png: 'image/png',\n svg: 'image/svg+xml',\n ttf: 'font/ttf',\n txt: 'text/plain',\n wasm: 'application/wasm',\n webm: 'video/webm',\n webp: 'image/webp',\n woff: 'font/woff',\n woff2: 'font/woff2',\n xls: 'application/vnd.ms-excel',\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n xml: 'application/xml',\n zip: 'application/zip',\n}\nconst ALIASES: Record<string, string> = { jpeg: 'jpg', htm: 'html', mjs: 'js', text: 'txt' }\nconst EXTENSIONS = Object.fromEntries(Object.entries(TYPES).map(([extension, type]) => [type, extension]))\n\n/** 'report.PDF' or 'pdf' → 'application/pdf'; unknown → 'application/octet-stream'. */\nexport function mimeFromExtension(pathOrExtension: string): string {\n const extension = pathOrExtension.slice(pathOrExtension.lastIndexOf('.') + 1).toLowerCase()\n return TYPES[ALIASES[extension] ?? extension] ?? 'application/octet-stream'\n}\n\n/** 'image/jpeg; charset=…' → 'jpg'; unknown → undefined. */\nexport function extensionFromMime(type: string): string | undefined {\n return EXTENSIONS[type.split(';')[0]!.trim().toLowerCase()]\n}\n","import {\n AuthFactory,\n CurrentRoute,\n Session,\n ValidationFactory,\n type HttpRequest,\n type InferValidatedType,\n type Rules,\n type UploadedFile,\n} from '@orieljs/contracts'\nimport { currentContainer, inject } from '@orieljs/container'\nimport { Arr, Str, type Stringable } from '@orieljs/support'\nimport { exceedsJsonDepth, readBody } from './body'\nimport { HttpException } from './errors'\nimport { clientAddress } from './clientAddress'\nimport { FormUploadedFile } from './FormUploadedFile'\nimport { fromEntries, isBlank, isPlainObject, mergeRecursive, sanitize, transformLeaves } from './input'\n\ntype Tree = Record<string, unknown>\n\nexport interface IncomingRequestOptions {\n /** Proxy addresses whose X-Forwarded-* headers are believed: exact IPs, IPv4 CIDRs, or '*'. */\n trustedProxies?: readonly string[]\n /** Largest request body in bytes before a 413 (config http.max_body_size); null is unlimited. Default 8 MB. */\n maxBodySize?: number | null\n /** Deepest nesting of objects and arrays in a JSON body before a 400 (config http.max_json_depth); null is unlimited. Default 512. */\n maxJsonDepth?: number | null\n}\n\nconst TRUE_VALUES = new Set(['1', 'true', 'on', 'yes'])\n\nconst normalizeIp = (ip: string): string => ip.trim().replace(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i, '$1')\n\nfunction ipv4ToNumber(ip: string): number | undefined {\n const parts = ip.split('.')\n if (parts.length !== 4 || parts.some((part) => !/^\\d{1,3}$/.test(part) || Number(part) > 255)) return undefined\n return parts.reduce((total, part) => total * 256 + Number(part), 0)\n}\n\n/** Exact match, IPv4 CIDR ('10.0.0.0/8') or '*'. */\nexport function ipMatches(ip: string, patterns: readonly string[]): boolean {\n const address = normalizeIp(ip)\n return patterns.some((pattern) => {\n if (pattern === '*') return true\n if (!pattern.includes('/')) return normalizeIp(pattern) === address\n const [range, bits] = pattern.split('/') as [string, string]\n const base = ipv4ToNumber(range)\n const value = ipv4ToNumber(address)\n const size = Number(bits)\n if (base === undefined || value === undefined || !(size >= 0 && size <= 32)) return false\n const mask = size === 0 ? 0 : (~0 << (32 - size)) >>> 0\n return ((base & mask) >>> 0) === ((value & mask) >>> 0)\n })\n}\n\n/**\n * The HttpRequest implementation (Laravel's Illuminate\\Http\\Request). The kernel calls load() once, before any\n * middleware, so every accessor below is synchronous.\n *\n * `http.max_body_size` applies to the bodies this class parses (JSON, urlencoded and multipart). A handler that reads\n * `request.raw` directly bypasses it and must enforce its own limit.\n */\nexport class IncomingRequest implements HttpRequest {\n readonly #url: URL\n readonly #trustedProxies: readonly string[]\n readonly #maxBodySize: number | null\n readonly #maxJsonDepth: number | null\n #query: Tree\n #body: Tree = {}\n #files: Tree = {}\n #content = ''\n #method: string\n #cookies: Record<string, string> | undefined\n #loading: Promise<this> | undefined\n #userResolver: ((guard?: string) => unknown) | undefined\n\n constructor(\n readonly raw: Request,\n options: IncomingRequestOptions = {},\n ) {\n this.#url = new URL(raw.url)\n this.#trustedProxies = options.trustedProxies ?? []\n this.#maxBodySize = options.maxBodySize === undefined ? 8 * 1024 * 1024 : options.maxBodySize\n this.#maxJsonDepth = options.maxJsonDepth === undefined ? 512 : options.maxJsonDepth\n this.#query = fromEntries(this.#url.searchParams.entries())\n this.#method = raw.method.toUpperCase()\n }\n\n /** Reads and parses the body (JSON, urlencoded or multipart) once, then applies method spoofing. */\n load(): Promise<this> {\n return (this.#loading ??= this.#load())\n }\n\n async #load(): Promise<this> {\n const method = this.raw.method.toUpperCase()\n if (method !== 'GET' && method !== 'HEAD' && this.raw.body !== null) {\n const type = (this.raw.headers.get('content-type') ?? '').toLowerCase()\n const isJson = type.includes('/json') || type.includes('+json')\n const isUrlencoded = type.startsWith('application/x-www-form-urlencoded')\n const isMultipart = type.startsWith('multipart/form-data')\n if (isJson || isUrlencoded || isMultipart) {\n // Size (413) and depth (400) errors must reach the caller; only a malformed body reads as empty input, as in Laravel.\n const bytes = await readBody(this.raw, this.#maxBodySize)\n if (isJson && this.#maxJsonDepth !== null && exceedsJsonDepth(new TextDecoder().decode(bytes), this.#maxJsonDepth)) {\n throw new HttpException(400, 'The request body is nested too deeply.')\n }\n try {\n if (isJson) {\n this.#content = new TextDecoder().decode(bytes)\n this.#body = this.#parseJson(this.#content)\n } else if (isUrlencoded) {\n this.#content = new TextDecoder().decode(bytes)\n this.#body = fromEntries(new URLSearchParams(this.#content).entries())\n } else {\n await this.#parseForm(await new Response(bytes as Uint8Array<ArrayBuffer>, { headers: { 'content-type': this.raw.headers.get('content-type') ?? '' } }).formData())\n }\n } catch {\n // A malformed body reads as empty input, as in Laravel.\n }\n }\n }\n if (method === 'POST') {\n const override =\n this.raw.headers.get('x-http-method-override') ?? this.#string(this.#body._method) ?? this.#string(this.#query._method)\n const spoofed = override?.toUpperCase()\n if (spoofed !== undefined && /^[A-Z]+$/.test(spoofed) && !['GET', 'HEAD', 'CONNECT', 'TRACE'].includes(spoofed)) {\n this.#method = spoofed\n }\n }\n return this\n }\n\n #parseJson(text: string): Tree {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n return {}\n }\n if (Array.isArray(parsed)) return sanitize({ ...parsed }) as Tree\n return isPlainObject(parsed) ? (sanitize(parsed) as Tree) : {}\n }\n\n async #parseForm(form: FormData): Promise<void> {\n const fields: Array<[string, unknown]> = []\n const files: Array<[string, unknown]> = []\n for (const [name, value] of form.entries()) {\n if (typeof value === 'string') fields.push([name, value])\n // A file input left empty arrives as filename=\"\" with no bytes (PHP's UPLOAD_ERR_NO_FILE).\n else if (!((value.name ?? '') === '' && value.size === 0)) files.push([name, await FormUploadedFile.fromFile(value)])\n }\n this.#body = fromEntries(fields)\n this.#files = fromEntries(files)\n }\n\n #string(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n }\n\n method(): string {\n return this.#method\n }\n\n isMethod(method: string): boolean {\n return this.#method === method.toUpperCase()\n }\n\n /** The scheme and host, honouring X-Forwarded-Proto/Host from trusted proxies. */\n root(): string {\n const trusted = this.#fromTrustedProxy()\n const proto = trusted ? this.raw.headers.get('x-forwarded-proto')?.split(',')[0]?.trim() : undefined\n const host = trusted ? this.raw.headers.get('x-forwarded-host')?.split(',')[0]?.trim() : undefined\n const scheme = proto === 'https' || proto === 'http' ? proto : this.#url.protocol.slice(0, -1)\n return `${scheme}://${host !== undefined && host !== '' ? host : this.#url.host}`\n }\n\n /** The URL without the query string or a trailing slash. */\n url(): string {\n return `${this.root()}${this.#url.pathname}`.replace(/\\/+$/, '')\n }\n\n fullUrl(): string {\n return this.#url.search === '' ? this.url() : `${this.url()}${this.#url.search}`\n }\n\n /** 'posts/1', or '/' for the root. */\n path(): string {\n const trimmed = this.#url.pathname.replace(/^\\/+|\\/+$/g, '')\n return trimmed === '' ? '/' : trimmed\n }\n\n decodedPath(): string {\n try {\n return decodeURIComponent(this.path())\n } catch {\n return this.path()\n }\n }\n\n secure(): boolean {\n return this.root().startsWith('https:')\n }\n\n /** request.is('admin/*'): wildcard match against the decoded path. */\n is(...patterns: string[]): boolean {\n const path = this.decodedPath()\n return patterns.some((pattern) => {\n const trimmed = pattern.replace(/^\\/+|\\/+$/g, '')\n return Str.is(trimmed === '' ? '/' : trimmed, path)\n })\n }\n\n routeIs(...names: string[]): boolean {\n const name = this.#currentRoute()?.route.getName()\n return name !== undefined && names.some((pattern) => Str.is(pattern, name))\n }\n\n header(name: string): string | undefined\n header(name: string, defaultValue: string): string\n header(name: string, defaultValue?: string): string | undefined {\n return this.raw.headers.get(name) ?? defaultValue\n }\n\n bearerToken(): string | undefined {\n const header = this.header('authorization', '')\n const position = header.toLowerCase().lastIndexOf('bearer ')\n if (position === -1) return undefined\n const token = header.slice(position + 7).split(',')[0]!.trim()\n return token === '' ? undefined : token\n }\n\n userAgent(): string | undefined {\n return this.header('user-agent')\n }\n\n /** The socket address, or the right-most untrusted X-Forwarded-For entry when the socket is a trusted proxy. */\n ip(): string | undefined {\n const socket = clientAddress(this.raw)\n if (socket === undefined) return undefined\n const address = normalizeIp(socket)\n if (!this.#fromTrustedProxy()) return address\n const chain = (this.raw.headers.get('x-forwarded-for') ?? '')\n .split(',')\n .map((entry) => normalizeIp(entry))\n .filter((entry) => entry !== '')\n for (let i = chain.length - 1; i >= 0; i--) if (!ipMatches(chain[i]!, this.#trustedProxies)) return chain[i]\n return chain[0] ?? address\n }\n\n #fromTrustedProxy(): boolean {\n const socket = clientAddress(this.raw)\n return socket !== undefined && this.#trustedProxies.length > 0 && ipMatches(socket, this.#trustedProxies)\n }\n\n ajax(): boolean {\n return this.header('x-requested-with') === 'XMLHttpRequest'\n }\n\n pjax(): boolean {\n return this.header('x-pjax') === 'true'\n }\n\n /** The first Accept type is JSON. */\n wantsJson(): boolean {\n const first = this.header('accept', '').split(',')[0]!.trim()\n return first.includes('/json') || first.includes('+json')\n }\n\n /** Laravel: (ajax and not pjax and accepts anything) or wantsJson. */\n expectsJson(): boolean {\n const first = this.header('accept', '').split(',')[0]!.split(';')[0]!.trim()\n const acceptsAny = first === '' || first === '*/*' || first === '*'\n return (this.ajax() && !this.pjax() && acceptsAny) || this.wantsJson()\n }\n\n /** The raw body text for JSON and urlencoded requests ('' otherwise; the raw stream stays unread for other types). */\n content(): string {\n return this.#content\n }\n\n query<T = unknown>(key?: string, defaultValue?: T): T {\n return Arr.get<T>(this.#query, key, defaultValue)\n }\n\n /** Body wins over the query string (PHP's $body + $query). Files are not input. */\n input<T = unknown>(key?: string, defaultValue?: T): T {\n return Arr.get<T>({ ...this.#query, ...this.#body }, key, defaultValue)\n }\n\n /** Input plus files (array_replace_recursive). */\n all(): Record<string, unknown> {\n return mergeRecursive({ ...this.#query, ...this.#body }, this.#files)\n }\n\n only(...keys: Array<string | string[]>): Record<string, unknown> {\n const all = this.all()\n const out: Tree = {}\n for (const key of keys.flat()) if (Arr.has(all, key)) Arr.set(out, key, Arr.get(all, key))\n return out\n }\n\n except(...keys: Array<string | string[]>): Record<string, unknown> {\n const all = structuredCloneInput(this.all())\n for (const key of keys.flat()) Arr.forget(all, key)\n return all\n }\n\n has(...keys: Array<string | string[]>): boolean {\n const all = this.all()\n return keys.flat().every((key) => Arr.has(all, key))\n }\n\n hasAny(...keys: Array<string | string[]>): boolean {\n const all = this.all()\n return keys.flat().some((key) => Arr.has(all, key))\n }\n\n missing(...keys: Array<string | string[]>): boolean {\n return !this.has(...keys)\n }\n\n filled(key: string): boolean {\n return !isBlank(Arr.get(this.all(), key))\n }\n\n /** Laravel's string(): the input as a Stringable (the default when it is missing or null): request().string('q').trim(). */\n string(key: string, defaultValue = ''): Stringable {\n const value = this.input<unknown>(key)\n return Str.of(value === undefined || value === null ? defaultValue : value)\n }\n\n /** Laravel's str(): string() under its short name. */\n str(key: string, defaultValue = ''): Stringable {\n return this.string(key, defaultValue)\n }\n\n /** PHP's FILTER_VALIDATE_BOOLEAN: '1', 'true', 'on', 'yes' (any case) and true are true. */\n boolean(key: string, defaultValue = false): boolean {\n const value = this.input<unknown>(key)\n if (value === undefined) return defaultValue\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value === 1\n return typeof value === 'string' && TRUE_VALUES.has(value.trim().toLowerCase())\n }\n\n /** PHP's intval: leading digits, else 0. */\n integer(key: string, defaultValue = 0): number {\n const value = this.input<unknown>(key)\n if (value === undefined) return defaultValue\n if (typeof value === 'number') return Number.isFinite(value) ? Math.trunc(value) : 0\n if (typeof value === 'boolean') return value ? 1 : 0\n const parsed = Number.parseInt(String(value).trim(), 10)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n\n /** Adds or replaces top-level body values. */\n merge(values: Record<string, unknown>): this {\n this.#body = { ...this.#body, ...(sanitize(values) as Tree) }\n return this\n }\n\n /** Rewrites every scalar in the query and the body (TrimStrings and ConvertEmptyStringsToNull use this). */\n transformInput(transform: (key: string, value: unknown) => unknown): this {\n this.#query = transformLeaves(this.#query, transform)\n this.#body = transformLeaves(this.#body, transform)\n return this\n }\n\n file(key: string): UploadedFile | undefined {\n const value = Arr.get<unknown>(this.#files, key)\n return value instanceof FormUploadedFile ? value : undefined\n }\n\n hasFile(key: string): boolean {\n const value = Arr.get<unknown>(this.#files, key)\n return value instanceof FormUploadedFile || (Array.isArray(value) && value.some((item) => item instanceof FormUploadedFile))\n }\n\n allFiles(): Record<string, unknown> {\n return { ...this.#files }\n }\n\n cookie(name: string): string | undefined {\n return this.cookies()[name]\n }\n\n cookies(): Record<string, string> {\n if (this.#cookies === undefined) {\n const cookies: Record<string, string> = {}\n for (const part of (this.raw.headers.get('cookie') ?? '').split(';')) {\n const index = part.indexOf('=')\n if (index === -1) continue\n const name = part.slice(0, index).trim()\n if (name === '' || Object.hasOwn(cookies, name)) continue\n let value = part.slice(index + 1).trim()\n if (value.startsWith('\"') && value.endsWith('\"')) value = value.slice(1, -1)\n try {\n cookies[name] = decodeURIComponent(value)\n } catch {\n cookies[name] = value\n }\n }\n this.#cookies = cookies\n }\n return { ...this.#cookies }\n }\n\n /** Replaces the parsed cookies (EncryptCookies calls this after decrypting). */\n setCookies(cookies: Record<string, string>): void {\n this.#cookies = { ...cookies }\n }\n\n /** One route parameter (after model binding), or all of them. */\n route<T = unknown>(key?: string): T {\n const parameters = this.#currentRoute()?.parameters ?? {}\n return (key === undefined ? { ...parameters } : parameters[key]) as T\n }\n\n session(): Session {\n return inject(Session)\n }\n\n /**\n * The signed-in user, through the resolver Auth sets, else the current scope's guard (the default, or `guard`).\n * The guard keeps the user it found, so it is looked up once per request. Undefined for a guest or without auth.\n */\n async user<T = unknown>(guard?: string): Promise<T | undefined> {\n if (this.#userResolver !== undefined) return (await this.#userResolver(guard)) as T | undefined\n const container = currentContainer()\n if (container === undefined || !container.bound(AuthFactory)) return undefined\n return (await container.make(AuthFactory).guard(guard).user()) as T | undefined\n }\n\n setUserResolver(resolver: (guard?: string) => unknown): void {\n this.#userResolver = resolver\n }\n\n /**\n * Validates all() through the ValidationFactory; throws its Validation error on failure. The data is typed from the\n * rules: `validate({ title: 'required|string' })` is `{ title: string }`.\n */\n validate<const R extends Rules>(\n rules: R,\n messages?: Record<string, string>,\n attributes?: Record<string, string>,\n ): Promise<InferValidatedType<R>> {\n return inject(ValidationFactory).make(this.all(), rules, messages, attributes).validated<InferValidatedType<R>>()\n }\n\n #currentRoute() {\n const container = currentContainer()\n return container?.bound(CurrentRoute) ? container.make(CurrentRoute) : undefined\n }\n}\n\n/** A copy deep enough for except() to forget nested keys without touching the request. */\nfunction structuredCloneInput(tree: Tree): Tree {\n const out: Tree = {}\n for (const [key, value] of Object.entries(tree)) {\n out[key] = isPlainObject(value) ? structuredCloneInput(value) : Array.isArray(value) ? [...value] : value\n }\n return out\n}\n","/** Helpers for request input: PHP-style bracket keys, safe cloning (no prototype pollution) and blank checks. */\n\ntype Tree = Record<string, unknown>\n\nconst FORBIDDEN = new Set(['__proto__', 'prototype', 'constructor'])\n\n/** Keys PHP treats as integers: '0', '7', '42' (not '07' or '-1'). */\nconst INTEGER_KEY = /^(?:0|[1-9]\\d*)$/\n\n// Duplicated in Routing's BaseUrlGenerator.ts on purpose: Http, Routing and Pipeline may not import each other.\nexport const isPlainObject = (value: unknown): value is Tree => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const prototype = Object.getPrototypeOf(value) as unknown\n return prototype === Object.prototype || prototype === null\n}\n\n/** 'user[name]' → ['user', 'name']; 'tags[]' → ['tags', '']; a malformed key stays whole. */\nexport function parseBracketKey(name: string): string[] {\n const open = name.indexOf('[')\n if (open <= 0 || !name.endsWith(']')) return [name]\n const segments = [name.slice(0, open)]\n const rest = name.slice(open)\n const matches = rest.match(/\\[[^[\\]]*\\]/g)\n if (matches === null || matches.join('') !== rest) return [name]\n for (const match of matches) segments.push(match.slice(1, -1))\n return segments\n}\n\n/** Objects whose keys are exactly 0..n-1 become arrays, recursively (PHP arrays → JS lists). */\nexport function normalizeLists(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(normalizeLists)\n if (!isPlainObject(value)) return value\n const keys = Object.keys(value)\n const out: Tree = {}\n for (const key of keys) out[key] = normalizeLists(value[key])\n if (keys.length > 0 && keys.every((key, index) => key === String(index))) return keys.map((key) => out[key])\n return out\n}\n\n/**\n * Builds nested input from flat form entries, PHP style: 'user[name]', 'tags[]', 'a[b][]'.\n * Keys containing __proto__/prototype/constructor are dropped.\n */\nexport function fromEntries(entries: Iterable<readonly [string, unknown]>): Tree {\n const root: Tree = {}\n // The next '[]' index per node, kept as PHP does (one past the highest integer key) so appending stays O(1).\n const nextIndex = new WeakMap<Tree, number>()\n for (const [name, value] of entries) {\n const segments = parseBracketKey(name)\n if (segments.some((segment) => FORBIDDEN.has(segment))) continue\n let node = root\n for (let i = 0; i < segments.length; i++) {\n let segment = segments[i]!\n const next = nextIndex.get(node) ?? 0\n if (segment === '') {\n segment = String(next)\n nextIndex.set(node, next + 1)\n } else if (INTEGER_KEY.test(segment) && Number(segment) >= next) {\n nextIndex.set(node, Number(segment) + 1)\n }\n if (i === segments.length - 1) {\n node[segment] = value\n break\n }\n if (!isPlainObject(node[segment])) node[segment] = {}\n node = node[segment] as Tree\n }\n }\n return normalizeLists(root) as Tree\n}\n\n/** Deep copy of parsed JSON without dangerous keys (JSON.parse creates an own \"__proto__\" property). */\nexport function sanitize(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sanitize)\n if (!isPlainObject(value)) return value\n const out: Tree = {}\n for (const [key, item] of Object.entries(value)) if (!FORBIDDEN.has(key)) out[key] = sanitize(item)\n return out\n}\n\n/** array_replace_recursive: `override` wins, nested plain objects merge. */\nexport function mergeRecursive(base: Tree, override: Tree): Tree {\n const out: Tree = { ...base }\n for (const [key, value] of Object.entries(override)) {\n if (FORBIDDEN.has(key)) continue\n const current = out[key]\n out[key] =\n (isPlainObject(current) || Array.isArray(current)) && (isPlainObject(value) || Array.isArray(value))\n ? normalizeLists(mergeRecursive({ ...current } as Tree, { ...value } as Tree))\n : value\n }\n return out\n}\n\n/** Laravel's blank(): null, undefined, whitespace-only strings, and empty arrays/objects. */\nexport function isBlank(value: unknown): boolean {\n if (value === null || value === undefined) return true\n if (typeof value === 'string') return value.trim() === ''\n if (Array.isArray(value)) return value.length === 0\n if (isPlainObject(value)) return Object.keys(value).length === 0\n return false\n}\n\n/** Applies `transform(dottedKey, value)` to every scalar leaf, inside nested objects and lists; the result replaces the leaf. */\nexport function transformLeaves(tree: Tree, transform: (key: string, value: unknown) => unknown, prefix = ''): Tree {\n const out: Tree = {}\n for (const [key, value] of Object.entries(tree)) out[key] = transformValue(`${prefix}${key}`, value, transform)\n return out\n}\n\nfunction transformValue(path: string, value: unknown, transform: (key: string, value: unknown) => unknown): unknown {\n if (Array.isArray(value)) return value.map((item, index) => transformValue(`${path}.${index}`, item, transform))\n if (isPlainObject(value)) return transformLeaves(value, transform, `${path}.`)\n return transform(path, value)\n}\n","import {\n HttpRequest,\n Redirector,\n ResponseFactory,\n UrlGenerator,\n type BodyInit,\n type HeadersInit,\n type RedirectResponse,\n type RouteArguments,\n type RouteName,\n} from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException, HttpResponseException } from './errors'\nimport type { IncomingRequest } from './IncomingRequest'\n\n/**\n * request() → the current request (Laravel's Illuminate\\Http\\Request: the HttpRequest contract plus its extras, such\n * as string()); request('key', default) → its input.\n */\nexport function request(): IncomingRequest\nexport function request<T = unknown>(key: string, defaultValue?: T): T\nexport function request(key?: string, defaultValue?: unknown): unknown {\n const current = inject(HttpRequest)\n return key === undefined ? current : current.input(key, defaultValue)\n}\n\n/** response() → the ResponseFactory; response(content, status, headers) → a Response. */\nexport function response(): ResponseFactory\nexport function response(content: BodyInit | null, status?: number, headers?: HeadersInit): Response\nexport function response(content?: BodyInit | null, status?: number, headers?: HeadersInit): ResponseFactory | Response {\n const factory = inject(ResponseFactory)\n return content === undefined ? factory : factory.make(content, status, headers)\n}\n\n/** The Redirector with its route() typed by the generated route names and their parameters. */\nexport type TypedRedirector = Omit<Redirector, 'route'> & {\n route<N extends RouteName>(name: N, ...args: RouteArguments<N, [status?: number]>): RedirectResponse\n}\n\n/** redirect() → the Redirector; redirect('/path', status) → a RedirectResponse. */\nexport function redirect(): TypedRedirector\nexport function redirect(to: string, status?: number): RedirectResponse\nexport function redirect(to?: string, status?: number): TypedRedirector | RedirectResponse {\n const redirector = inject(Redirector)\n return to === undefined ? redirector : redirector.to(to, status)\n}\n\n/** Redirect to the previous URL (same argument order as Redirector.back()). */\nexport function back(fallback?: string, status?: number): RedirectResponse {\n return inject(Redirector).back(fallback, status)\n}\n\n/** url() → the UrlGenerator; url('/path', query, absolute) → a URL. */\nexport function url(): UrlGenerator\nexport function url(path: string, query?: Record<string, unknown>, absolute?: boolean): string\nexport function url(path?: string, query?: Record<string, unknown>, absolute?: boolean): UrlGenerator | string {\n const generator = inject(UrlGenerator)\n return path === undefined ? generator : generator.to(path, query, absolute)\n}\n\n/**\n * The URL of a named route: route('posts.show', post), route('posts.show', { post, page: 2 }). Once `oriel\n * route:types` has run, the name and the route's parameters are checked.\n */\nexport function route<N extends RouteName>(name: N, ...args: RouteArguments<N>): string {\n const [parameters, absolute] = args as [parameters?: unknown, absolute?: boolean]\n return inject(UrlGenerator).route(name, parameters, absolute)\n}\n\n/** abort(404), abort(403, 'Nope', headers), or abort(response) to send a ready response. */\nexport function abort(status: number | Response, message = '', headers: Record<string, string> = {}): never {\n if (status instanceof Response) throw new HttpResponseException(status)\n throw new HttpException(status, message, headers)\n}\n\nexport function abortIf(condition: unknown, status: number | Response, message = '', headers: Record<string, string> = {}): void {\n if (condition) abort(status, message, headers)\n}\n\nexport function abortUnless(condition: unknown, status: number | Response, message = '', headers: Record<string, string> = {}): void {\n if (!condition) abort(status, message, headers)\n}\n","import { createReadStream } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { basename } from 'node:path'\nimport { Readable } from 'node:stream'\nimport { ViewFactory, type BodyInit, type HeadersInit, type ResponseFactory } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException } from './errors'\nimport { mimeFromExtension } from './mime'\n\n/** 'attachment; filename=\"report.pdf\"' plus filename* for non-ASCII names (RFC 6266). */\nexport function contentDisposition(type: 'attachment' | 'inline', name: string): string {\n const fallback = name.replace(/[^\\x20-\\x7e]/g, '_').replace(/[\"\\\\]/g, '\\\\$&')\n const header = `${type}; filename=\"${fallback}\"`\n return /^[\\x20-\\x7e]*$/.test(name) ? header : `${header}; filename*=UTF-8''${encodeURIComponent(name)}`\n}\n\n/** Laravel's ResponseFactory (the response() helper). */\nexport class HttpResponseFactory implements ResponseFactory {\n /** Strings default to text/html; charset=utf-8, as in Laravel. */\n make(content: BodyInit | null = null, status = 200, headers?: HeadersInit): Response {\n const merged = new Headers(headers)\n if (typeof content === 'string' && !merged.has('content-type')) merged.set('content-type', 'text/html; charset=utf-8')\n return new Response(content, { status, headers: merged })\n }\n\n json(data: unknown, status = 200, headers?: HeadersInit): Response {\n const merged = new Headers(headers)\n if (!merged.has('content-type')) merged.set('content-type', 'application/json')\n return new Response(JSON.stringify(data === undefined ? null : data), { status, headers: merged })\n }\n\n noContent(status = 204): Response {\n return new Response(null, { status })\n }\n\n /** Renders a view (through the ViewFactory) into an HTML response. */\n async view(name: string, data: Record<string, unknown> = {}, status = 200, headers?: HeadersInit): Promise<Response> {\n const html = await inject(ViewFactory).make(name, data).render()\n return this.make(html, status, headers)\n }\n\n /** Streams a file as an attachment. A missing file is a 404. */\n download(path: string, name = basename(path), headers?: HeadersInit): Promise<Response> {\n return this.#file(path, 'attachment', name, headers)\n }\n\n /** Streams a file for the browser to display (Laravel's response()->file()). */\n file(path: string, headers?: HeadersInit): Promise<Response> {\n return this.#file(path, 'inline', basename(path), headers)\n }\n\n stream(body: ReadableStream, status = 200, headers?: HeadersInit): Response {\n return new Response(body, { status, headers })\n }\n\n async #file(path: string, disposition: 'attachment' | 'inline', name: string, headers?: HeadersInit): Promise<Response> {\n const info = await stat(path).catch(() => undefined)\n // No file path in the message: HTTP error messages are shown to clients.\n if (info === undefined || !info.isFile()) throw new HttpException(404)\n const merged = new Headers(headers)\n if (!merged.has('content-type')) merged.set('content-type', mimeFromExtension(name))\n merged.set('content-length', String(info.size))\n merged.set('content-disposition', contentDisposition(disposition, name))\n const body = Readable.toWeb(createReadStream(path)) as ReadableStream<Uint8Array>\n return new Response(body, { status: 200, headers: merged })\n }\n}\n","import {\n ConfigRepository,\n CurrentRoute,\n ExceptionHandler,\n HttpRequest,\n PipelineFactory,\n Router,\n type Application,\n type Container,\n type HttpKernel,\n type Middleware,\n type MiddlewareClass,\n} from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\nimport { HttpServerError } from './errors'\nimport { IncomingRequest } from './IncomingRequest'\nimport { ConvertEmptyStringsToNull } from './middleware/ConvertEmptyStringsToNull'\nimport { TrimStrings } from './middleware/TrimStrings'\n\ninterface RequestState {\n readonly scope: Container\n readonly request: IncomingRequest\n readonly middleware: Middleware[]\n}\n\n/** The plain-text 500 the kernel falls back to. Exported so the server adapters can reuse it. */\nexport const plainServerError = (): Response =>\n new Response('Server Error', { status: 500, headers: { 'content-type': 'text/plain; charset=utf-8' } })\n\n/**\n * Laravel's Http Kernel: wraps the raw Request, binds it in the request scope, loads the body, then sends it through\n * the global middleware to the router. Every stage renders its own errors through the ExceptionHandler.\n */\nexport class Kernel implements HttpKernel {\n #middleware: MiddlewareClass[] = [TrimStrings, ConvertEmptyStringsToNull]\n readonly #requests = new WeakMap<Request, RequestState>()\n\n constructor(protected readonly app: Application) {}\n\n getGlobalMiddleware(): MiddlewareClass[] {\n return [...this.#middleware]\n }\n\n setGlobalMiddleware(middleware: MiddlewareClass[]): this {\n this.#middleware = [...middleware]\n return this\n }\n\n appendMiddleware(...middleware: MiddlewareClass[]): this {\n for (const cls of middleware) if (!this.#middleware.includes(cls)) this.#middleware.push(cls)\n return this\n }\n\n prependMiddleware(...middleware: MiddlewareClass[]): this {\n for (const cls of [...middleware].reverse()) if (!this.#middleware.includes(cls)) this.#middleware.unshift(cls)\n return this\n }\n\n hasMiddleware(middleware: MiddlewareClass): boolean {\n return this.#middleware.includes(middleware)\n }\n\n /** Runs in the current request scope (Application.handle() opens one); called directly, it opens its own. */\n handle(raw: Request): Promise<Response> {\n const current = currentContainer()\n const scope = current !== undefined && current !== this.app ? current : this.app.createScope()\n return scope.run(() => this.#handle(raw, scope))\n }\n\n async #handle(raw: Request, scope: Container): Promise<Response> {\n let request: IncomingRequest | undefined\n let response: Response\n try {\n request = new IncomingRequest(raw, {\n trustedProxies: this.#trustedProxies(),\n maxBodySize: this.#maxBodySize(),\n maxJsonDepth: this.#maxJsonDepth(),\n })\n scope.instance(HttpRequest, request)\n const state: RequestState = { scope, request, middleware: [] }\n this.#requests.set(raw, state)\n await request.load()\n response = await this.#sendThroughGlobal(state)\n } catch (error) {\n request ??= this.#bareRequest(scope, raw)\n if (request !== undefined) {\n response = await this.#renderLast(scope, request, error)\n } else {\n await this.#report(scope, error)\n response = plainServerError()\n }\n }\n // HEAD: same status and headers as GET, no body. Cancel the dropped body so an open file stream is released.\n if (raw.method.toUpperCase() === 'HEAD' && response.body !== null) {\n await response.body.cancel().catch(() => undefined)\n response = new Response(null, { status: response.status, statusText: response.statusText, headers: response.headers })\n }\n return response\n }\n\n /** The request without options, for rendering an error raised while the real one was being built. */\n #bareRequest(scope: Container, raw: Request): IncomingRequest | undefined {\n try {\n const request = new IncomingRequest(raw)\n scope.instance(HttpRequest, request)\n return request\n } catch {\n return undefined\n }\n }\n\n /** Runs terminate() on the global and route middleware (inside the request's scope), then Application.terminate(), inside the same scope, so terminating callbacks see the request's bindings. */\n async terminate(raw: Request, response: Response): Promise<void> {\n const state = this.#requests.get(raw)\n if (state !== undefined) {\n this.#requests.delete(raw)\n await state.scope.run(async () => {\n const route = state.scope.bound(CurrentRoute) ? state.scope.make(CurrentRoute).middleware : []\n for (const middleware of [...state.middleware, ...route]) {\n if (typeof middleware.terminate !== 'function') continue\n try {\n await middleware.terminate(state.request, response)\n } catch (error) {\n await this.#report(state.scope, error)\n }\n }\n await this.app.terminate()\n })\n return\n }\n await this.app.terminate()\n }\n\n #sendThroughGlobal(state: RequestState): Promise<Response> {\n const { scope, request } = state\n const pipes = this.#middleware.map((cls) => {\n const instance = scope.make(cls)\n state.middleware.push(instance)\n return (passable: HttpRequest, next: (passable: HttpRequest) => Promise<unknown>) =>\n this.#guard(scope, passable, () => instance.handle(passable, next as (r: HttpRequest) => Promise<Response>))\n })\n return scope\n .make(PipelineFactory)\n .make<HttpRequest>()\n .send(request)\n .through(pipes)\n .then((passable) => this.#guard(scope, passable, () => this.#dispatch(scope, passable)))\n }\n\n #dispatch(scope: Container, request: HttpRequest): Promise<Response> {\n return scope.make(Router).dispatch(request)\n }\n\n /** Converts a Responsable result, and renders a thrown error at this stage (Laravel's Routing\\Pipeline). */\n async #guard(scope: Container, request: HttpRequest, run: () => Promise<unknown>): Promise<Response> {\n try {\n const result = await run()\n if (result instanceof Response) return result\n const responsable = result as { toResponse?: (request: unknown) => Response | Promise<Response> } | null\n if (typeof responsable?.toResponse === 'function') return await responsable.toResponse(request)\n throw new HttpServerError('Middleware must return a Response.')\n } catch (error) {\n if (!scope.bound(ExceptionHandler)) throw error\n const handler = scope.make(ExceptionHandler)\n await handler.report(error)\n return handler.render(request, error)\n }\n }\n\n /** Last resort: the handler failed or isn't bound. Never throws. */\n async #renderLast(scope: Container, request: HttpRequest, error: unknown): Promise<Response> {\n if (scope.bound(ExceptionHandler)) {\n try {\n const handler = scope.make(ExceptionHandler)\n await handler.report(error)\n return await handler.render(request, error)\n } catch (renderError) {\n console.error(renderError)\n }\n } else {\n console.error(error)\n }\n return plainServerError()\n }\n\n async #report(scope: Container, error: unknown): Promise<void> {\n try {\n if (scope.bound(ExceptionHandler)) await scope.make(ExceptionHandler).report(error)\n else console.error(error)\n } catch (reportError) {\n console.error(reportError)\n }\n }\n\n /** config('http.max_body_size'): bytes, or null for no limit. Anything else is a configuration error. */\n #maxBodySize(): number | null {\n if (!this.app.bound(ConfigRepository)) return 8 * 1024 * 1024\n const value = this.app.make(ConfigRepository).get<unknown>('http.max_body_size', 8 * 1024 * 1024)\n if (value === null) return null\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value\n throw new HttpServerError(\n `Invalid http.max_body_size ${JSON.stringify(value) ?? String(value)}: use a number of bytes (0 or more), or null for no limit.`,\n )\n }\n\n /** config('http.max_json_depth'): how deep a JSON body may nest, or null for no limit. */\n #maxJsonDepth(): number | null {\n if (!this.app.bound(ConfigRepository)) return 512\n const value = this.app.make(ConfigRepository).get<unknown>('http.max_json_depth', 512)\n if (value === null) return null\n if (typeof value === 'number' && Number.isInteger(value) && value >= 1) return value\n throw new HttpServerError(\n `Invalid http.max_json_depth ${JSON.stringify(value) ?? String(value)}: use a whole number (1 or more), or null for no limit.`,\n )\n }\n\n /** config('http.trusted_proxies'): an array, or a comma-separated string such as '*' or '10.0.0.0/8,::1'. */\n #trustedProxies(): string[] {\n if (!this.app.bound(ConfigRepository)) return []\n const value = this.app.make(ConfigRepository).get<unknown>('http.trusted_proxies', [])\n if (typeof value === 'string') return value.split(',').map((entry) => entry.trim()).filter((entry) => entry !== '')\n return Array.isArray(value) ? value.map(String) : []\n }\n}\n","import type { HttpRequest, Middleware, Next } from '@orieljs/contracts'\nimport { IncomingRequest } from '../IncomingRequest'\n\n/** '' becomes null in the query and body, so `nullable` validation behaves as in Laravel. */\nexport class ConvertEmptyStringsToNull implements Middleware {\n async handle(request: HttpRequest, next: Next): Promise<Response> {\n if (request instanceof IncomingRequest) request.transformInput((_key, value) => (value === '' ? null : value))\n return next(request)\n }\n}\n","import type { HttpRequest, Middleware, Next } from '@orieljs/contracts'\nimport { IncomingRequest } from '../IncomingRequest'\n\n/** Laravel's trim: whitespace plus BOM, zero-width space and left-to-right mark. */\nconst TRIM = /^[\\s\\uFEFF\\u200B\\u200E]+|[\\s\\uFEFF\\u200B\\u200E]+$/g\n\n/** Trims every string in the query and body, except password fields (Laravel's TrimStrings). */\nexport class TrimStrings implements Middleware {\n /** Dotted input keys left untouched. Override in a subclass to change. */\n protected except: string[] = ['current_password', 'password', 'password_confirmation']\n\n async handle(request: HttpRequest, next: Next): Promise<Response> {\n if (request instanceof IncomingRequest) {\n request.transformInput((key, value) =>\n typeof value === 'string' && !this.except.includes(key) ? value.replace(TRIM, '') : value,\n )\n }\n return next(request)\n }\n}\n","import {\n ConfigRepository,\n MiddlewareCallbacks,\n Router,\n type Application,\n type HttpRequest,\n type MiddlewareClass,\n type MiddlewareConfigurator,\n type MiddlewareReference,\n} from '@orieljs/contracts'\nimport type { Kernel } from './Kernel'\n\ninterface GroupOptions {\n append?: MiddlewareClass[]\n prepend?: MiddlewareClass[]\n remove?: MiddlewareClass[]\n}\n\n/** The `m` in withMiddleware((m) => …): edits the kernel's global middleware and the router's groups and aliases. */\nexport class MiddlewareConfiguration implements MiddlewareConfigurator {\n constructor(\n private readonly kernel: Kernel,\n private readonly router: Router,\n private readonly config?: ConfigRepository,\n ) {}\n\n append(...middleware: MiddlewareClass[]): this {\n this.kernel.appendMiddleware(...middleware)\n return this\n }\n\n prepend(...middleware: MiddlewareClass[]): this {\n this.kernel.prependMiddleware(...middleware)\n return this\n }\n\n web(options: GroupOptions): this {\n return this.#modifyGroup('web', options)\n }\n\n api(options: GroupOptions): this {\n return this.#modifyGroup('api', options)\n }\n\n alias(aliases: Record<string, MiddlewareClass>): this {\n for (const [name, middleware] of Object.entries(aliases)) this.router.aliasMiddleware(name, middleware)\n return this\n }\n\n group(name: string, middleware: Array<MiddlewareClass | string>): this {\n this.router.middlewareGroup(name, middleware)\n return this\n }\n\n /** Stored in config('http.csrf_except'), which the Session component's VerifyCsrfToken reads. */\n validateCsrfTokens(options: { except: string[] }): this {\n const current = this.config?.get<string[]>('http.csrf_except', []) ?? []\n this.config?.set('http.csrf_except', [...current, ...options.except])\n return this\n }\n\n /** Stored in config('http.redirect_guests_to'), which the Auth middleware and the exception handler read. */\n redirectGuestsTo(url: string | ((request: HttpRequest) => string)): this {\n this.config?.set('http.redirect_guests_to', url)\n return this\n }\n\n /** Laravel 11's redirectUsersTo(): stored in config('http.redirect_users_to') for Auth's RedirectIfAuthenticated. */\n redirectUsersTo(url: string | ((request: HttpRequest) => string)): this {\n this.config?.set('http.redirect_users_to', url)\n return this\n }\n\n /** Laravel's order: prepends, then the group minus removals, then appends. */\n #modifyGroup(name: string, { append = [], prepend = [], remove = [] }: GroupOptions): this {\n const current: MiddlewareReference[] = this.router.getMiddlewareGroups()[name] ?? []\n const moved = new Set<MiddlewareReference>([...append, ...prepend, ...remove])\n this.router.middlewareGroup(name, [...prepend, ...current.filter((entry) => !moved.has(entry)), ...append])\n return this\n }\n}\n\n/** Runs the withMiddleware() callbacks collected by the ApplicationBuilder (HttpServiceProvider calls this once booted). */\nexport function applyMiddlewareCallbacks(app: Application, kernel: Kernel): void {\n if (!app.bound(MiddlewareCallbacks)) return\n const callbacks = app.make(MiddlewareCallbacks) as Array<(configurator: MiddlewareConfigurator) => void>\n if (callbacks.length === 0) return\n const config = app.bound(ConfigRepository) ? app.make(ConfigRepository) : undefined\n const configurator = new MiddlewareConfiguration(kernel, app.make(Router), config)\n for (const callback of callbacks) callback(configurator)\n}\n","import {\n ConfigRepository,\n LogManager,\n Redirector,\n UrlGenerator,\n ViewFactory,\n type Application,\n type AuthenticationError,\n type Container,\n type ErrorKind,\n type ExceptionHandler,\n type HttpRequest,\n type OrielError,\n type ValidationError,\n} from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\nimport { debugPage, minimalPage, stackFrames, statusText } from './errorPages'\nimport { HttpResponseException } from './errors'\nimport { IncomingRequest } from './IncomingRequest'\n\nexport type ReportCallback = (error: unknown) => void | boolean | Promise<void | boolean>\nexport type RenderCallback = (error: unknown, request: unknown) => Response | undefined | Promise<Response | undefined>\nexport type ErrorClass = abstract new (...args: never[]) => Error\nexport type JsonWhenCallback = (request: HttpRequest, error: unknown) => boolean\n\n/** Laravel's $internalDontReport: expected errors that are rendered, never logged ('Server' is not here). */\nconst NOT_REPORTED = new Set<ErrorKind>(['Http', 'ModelNotFound', 'Validation', 'Authentication', 'Authorization', 'TokenMismatch'])\n/** Kinds whose message is safe to show to users, at any status (Laravel's HttpException rendering). */\nconst HTTP_KINDS = new Set<ErrorKind>(['Http', 'ModelNotFound', 'Authorization', 'TokenMismatch'])\n\nconst kindOf = (error: unknown): ErrorKind | undefined =>\n typeof error === 'object' && error !== null && typeof (error as OrielError).kind === 'string' ? (error as OrielError).kind : undefined\n\n/** HTTP status for an error (spec §7). */\nexport function statusFor(error: unknown): number {\n const status = (error as Partial<OrielError> | null)?.status\n switch (kindOf(error)) {\n case 'Http':\n return status ?? 500\n case 'ModelNotFound':\n return 404\n case 'Authorization':\n return status ?? 403\n case 'TokenMismatch':\n return 419\n case 'Authentication':\n return 401\n case 'Validation':\n return status ?? 422\n case 'Server':\n return status ?? 500\n default:\n return 500\n }\n}\n\n/** \"The title field is required. (and 2 more errors)\" (Laravel's ValidationException::summarize). */\nexport function summarizeValidation(errors: Record<string, string[]>): string {\n const messages = Object.values(errors).flat()\n if (messages.length === 0) return 'The given data was invalid.'\n const more = messages.length - 1\n return more === 0 ? messages[0]! : `${messages[0]!} (and ${more} more ${more === 1 ? 'error' : 'errors'})`\n}\n\n/** An HTTP-like error: its message may be shown and it doesn't get the debug page. */\nconst isHttpLike = (error: unknown): boolean => {\n const kind = kindOf(error)\n return kind !== undefined && HTTP_KINDS.has(kind)\n}\n\n/** The exception handler (spec §7): report through the LogManager, render by error kind. */\nexport class ErrorHandler implements ExceptionHandler {\n /** Input keys never flashed back on a validation redirect. */\n protected dontFlash = ['current_password', 'password', 'password_confirmation']\n readonly #reportCallbacks: ReportCallback[] = []\n readonly #renderCallbacks: RenderCallback[] = []\n readonly #dontReport: ErrorClass[] = []\n readonly #reported = new WeakSet<object>()\n #jsonWhen: JsonWhenCallback | undefined\n\n constructor(protected readonly app: Application) {}\n\n reportUsing(callback: ReportCallback): void {\n this.#reportCallbacks.push(callback)\n }\n\n renderUsing(callback: RenderCallback): void {\n this.#renderCallbacks.push(callback)\n }\n\n ignore(...classes: ErrorClass[]): void {\n this.#dontReport.push(...classes)\n }\n\n /** Laravel's shouldRenderJsonWhen(): the callback decides JSON or HTML instead of the Accept header. */\n shouldRenderJsonWhen(callback: JsonWhenCallback): void {\n this.#jsonWhen = callback\n }\n\n /** Laravel's shouldReturnJson(): the shouldRenderJsonWhen() callback when set, else request.expectsJson(). */\n protected shouldReturnJson(request: HttpRequest, error: unknown): boolean {\n return this.#jsonWhen !== undefined ? this.#jsonWhen(request, error) : request.expectsJson()\n }\n\n shouldReport(error: unknown): boolean {\n const kind = kindOf(error)\n if (kind !== undefined && NOT_REPORTED.has(kind)) return false\n return !this.#dontReport.some((cls) => error instanceof cls)\n }\n\n /** Report callbacks first (returning false stops the default log), then LogManager.error(), else console.error. Once per error. */\n async report(error: unknown): Promise<void> {\n if (!this.shouldReport(error)) return\n if (typeof error === 'object' && error !== null) {\n if (this.#reported.has(error)) return\n this.#reported.add(error)\n }\n try {\n for (const callback of this.#reportCallbacks) if ((await callback(error)) === false) return\n const container = this.#container()\n if (container.bound(LogManager)) {\n const message = error instanceof Error ? error.message : String(error)\n container.make(LogManager).error(message, { exception: error })\n } else {\n console.error(error)\n }\n } catch (reportError) {\n console.error(reportError)\n }\n }\n\n async render(request: unknown, error: unknown): Promise<Response> {\n for (const callback of this.#renderCallbacks) {\n const response = await callback(error, request)\n if (response instanceof Response) return response\n }\n if (error instanceof HttpResponseException) return error.response\n const custom = await this.#renderCustom(request, error)\n if (custom !== undefined) return custom\n\n const http = this.#httpRequest(request)\n const kind = kindOf(error)\n let response: Response\n if (kind === 'Validation') response = await this.#renderValidation(http, error as ValidationError)\n else if (kind === 'Authentication') response = await this.#renderAuthentication(http, error as AuthenticationError)\n else if (this.shouldReturnJson(http, error)) response = this.#renderJson(error)\n else response = await this.#renderHtml(http, error)\n\n const headers = (error as Partial<OrielError> | null)?.headers\n return headers === undefined ? response : withHeaders(response, headers)\n }\n\n /** An error with its own render(request) or toResponse(request) (Laravel's renderable exceptions / Responsable). */\n async #renderCustom(request: unknown, error: unknown): Promise<Response | undefined> {\n if (typeof error !== 'object' || error === null) return undefined\n const candidate = error as { render?: (request: unknown) => unknown; toResponse?: (request: unknown) => unknown }\n for (const method of [candidate.render, candidate.toResponse]) {\n if (typeof method !== 'function') continue\n const response = await method.call(error, request)\n if (response instanceof Response) return response\n }\n return undefined\n }\n\n async #renderValidation(request: HttpRequest, error: ValidationError): Promise<Response> {\n if (this.shouldReturnJson(request, error)) {\n return this.#json({ message: summarizeValidation(error.errors), errors: error.errors }, statusFor(error))\n }\n const input = { ...request.input<Record<string, unknown>>() }\n for (const key of this.dontFlash) delete input[key]\n const container = this.#container()\n if (!container.bound(Redirector)) {\n return this.#redirect(error.redirectTo ?? request.header('referer') ?? '/')\n }\n const redirector = container.make(Redirector)\n const redirect = error.redirectTo !== undefined ? redirector.to(error.redirectTo) : redirector.back()\n // toResponse(request) may return a Promise per the Responsable contract; await it.\n const response = await redirect.withInput(input).withErrors(error.errors, error.errorBag).toResponse(request)\n return response\n }\n\n async #renderAuthentication(request: HttpRequest, error: AuthenticationError): Promise<Response> {\n if (this.shouldReturnJson(request, error)) return this.#json({ message: error.message || 'Unauthenticated.' }, 401)\n const target = error.redirectTo ?? this.#guestRedirect(request)\n const container = this.#container()\n if (!container.bound(Redirector)) return this.#redirect(target)\n const redirector = container.make(Redirector) as Redirector & { guest?: (path: string) => { toResponse(r: unknown): unknown } }\n const redirect = typeof redirector.guest === 'function' ? redirector.guest(target) : redirector.to(target)\n // toResponse(request) may return a Promise per the Responsable contract; await it.\n return (await redirect.toResponse(request)) as Response\n }\n\n /** config('http.redirect_guests_to'), then route('login'), then '/login'. */\n #guestRedirect(request: HttpRequest): string {\n const configured = this.#config<unknown>('http.redirect_guests_to', undefined)\n if (typeof configured === 'function') return String((configured as (request: HttpRequest) => string)(request))\n if (typeof configured === 'string' && configured !== '') return configured\n const container = this.#container()\n if (container.bound(UrlGenerator)) {\n const url = container.make(UrlGenerator)\n if (url.hasRoute('login')) return url.route('login')\n }\n return '/login'\n }\n\n #renderJson(error: unknown): Response {\n const status = statusFor(error)\n if (isHttpLike(error)) {\n const message = error instanceof Error && error.message !== '' ? error.message : statusText(status)\n return this.#json({ message }, status)\n }\n if (!this.#debug()) return this.#json({ message: 'Server Error' }, status)\n const err = error instanceof Error ? error : new Error(String(error))\n const [frame] = stackFrames(err)\n return this.#json(\n {\n message: err.message,\n exception: err.name,\n file: frame?.file,\n line: frame?.line,\n trace: stackFrames(err).map((entry) => entry.text),\n },\n status,\n )\n }\n\n async #renderHtml(request: HttpRequest, error: unknown): Promise<Response> {\n const status = statusFor(error)\n if (!isHttpLike(error) && this.#debug()) {\n return this.#html(await debugPage(error, request.method(), request.fullUrl()), status)\n }\n const message = status === 403 && error instanceof Error && error.message !== '' ? error.message : statusText(status)\n const view = await this.#errorView(status, error, message)\n return this.#html(view ?? minimalPage(status, message), status)\n }\n\n /** resources/views/errors/{status}.tsx, then errors/4xx or errors/5xx, through the ViewFactory. */\n async #errorView(status: number, error: unknown, message: string): Promise<string | undefined> {\n const container = this.#container()\n if (!container.bound(ViewFactory)) return undefined\n const views = container.make(ViewFactory)\n for (const name of [`errors.${status}`, `errors.${Math.floor(status / 100)}xx`]) {\n if (!views.exists(name)) continue\n try {\n return await views.make(name, { exception: error, status, message }).render()\n } catch (viewError) {\n await this.report(viewError)\n return undefined\n }\n }\n return undefined\n }\n\n #httpRequest(request: unknown): HttpRequest {\n if (typeof request === 'object' && request !== null && typeof (request as HttpRequest).expectsJson === 'function') {\n return request as HttpRequest\n }\n return new IncomingRequest(request instanceof Request ? request : new Request('http://localhost/'))\n }\n\n #json(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } })\n }\n\n #html(body: string, status: number): Response {\n return new Response(body, { status, headers: { 'content-type': 'text/html; charset=utf-8' } })\n }\n\n #redirect(location: string): Response {\n return new Response(null, { status: 302, headers: { Location: location } })\n }\n\n #debug(): boolean {\n return this.#config<unknown>('app.debug', false) === true\n }\n\n #config<T>(key: string, fallback: T): T {\n return this.app.bound(ConfigRepository) ? this.app.make(ConfigRepository).get<T>(key, fallback) : fallback\n }\n\n /** The request scope while handling a request (so scoped services resolve), else the application. */\n #container(): Container {\n return currentContainer() ?? this.app\n }\n}\n\n/**\n * A copy of `response` with the headers added. The rendered response's own headers may be immutable (a fetch() or\n * Response.redirect() response), so they are never set in place.\n */\nfunction withHeaders(response: Response, extra: Record<string, string>): Response {\n const headers = new Headers(response.headers)\n for (const [name, value] of Object.entries(extra)) headers.set(name, value)\n return new Response(response.body, { status: response.status, statusText: response.statusText, headers })\n}\n","import { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nconst STATUS_TEXTS: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Content Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a teapot\",\n 419: 'Page Expired',\n 421: 'Misdirected Request',\n 422: 'Unprocessable Content',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n}\n\n/**\n * The text an error page shows for a status: Laravel's own wording where it has a view (\"Server Error\", \"Page\n * Expired\"), else Symfony's `Response::$statusTexts`, which Laravel shows for the others.\n */\nexport function statusText(status: number): string {\n return STATUS_TEXTS[status] ?? (status >= 500 ? 'Server Error' : 'Error')\n}\n\nexport function escapeHtml(value: string): string {\n return value.replace(/[&<>\"']/g, (char) => `&#${char.charCodeAt(0)};`)\n}\n\n/** Laravel's minimal error page: \"404 | Not Found\". */\nexport function minimalPage(status: number, message: string): string {\n const title = escapeHtml(message)\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${title}</title>\n<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f7fafc;color:#1a202c;display:flex;align-items:center;justify-content:center;min-height:100vh}.code{padding:0 1rem;border-right:1px solid #a0aec0;font-size:1.125rem}.message{padding:0 1rem;font-size:1.125rem;text-transform:uppercase;letter-spacing:.05em}</style>\n</head>\n<body><div class=\"code\">${status}</div><div class=\"message\">${title}</div></body>\n</html>`\n}\n\nexport interface StackFrame {\n readonly file: string\n readonly line: number\n readonly column: number\n readonly text: string\n}\n\n/** Parses V8/JavaScriptCore stack lines into frames that point at files. */\nexport function stackFrames(error: Error): StackFrame[] {\n const frames: StackFrame[] = []\n for (const raw of (error.stack ?? '').split('\\n').slice(1)) {\n const text = raw.trim()\n const match = /(?:\\(|@|at )((?:file:\\/\\/)?(?:\\/|[A-Za-z]:\\\\)[^()]*?):(\\d+):(\\d+)\\)?$/.exec(text)\n if (match === null) continue\n const location = match[1]!\n const file = location.startsWith('file://') ? fileURLToPath(location) : location\n frames.push({ file, line: Number(match[2]), column: Number(match[3]), text })\n }\n return frames\n}\n\n/** Up to `radius` lines either side of the frame's line, or undefined when the file can't be read. */\nasync function excerpt(frame: StackFrame, radius = 5): Promise<string | undefined> {\n const source = await readFile(frame.file, 'utf8').catch(() => undefined)\n if (source === undefined) return undefined\n const lines = source.split('\\n')\n const start = Math.max(1, frame.line - radius)\n const end = Math.min(lines.length, frame.line + radius)\n const rows: string[] = []\n for (let number = start; number <= end; number++) {\n const current = number === frame.line ? ' class=\"current\"' : ''\n rows.push(`<tr${current}><td class=\"n\">${number}</td><td><code>${escapeHtml(lines[number - 1] ?? '')}</code></td></tr>`)\n }\n return `<table class=\"source\">${rows.join('')}</table>`\n}\n\n/** The APP_DEBUG page: class, message, request, a source excerpt of the first app frame, the stack and causes. */\nexport async function debugPage(error: unknown, method: string, url: string): Promise<string> {\n const err = error instanceof Error ? error : new Error(String(error))\n const frames = stackFrames(err)\n const appFrame = frames.find((frame) => !frame.file.includes('node_modules') && !frame.file.startsWith('node:')) ?? frames[0]\n const source = appFrame === undefined ? undefined : await excerpt(appFrame)\n const causes: string[] = []\n for (let cause = err.cause, depth = 0; cause !== undefined && depth < 5; cause = (cause as Error).cause, depth++) {\n causes.push(`<li>${escapeHtml(cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause))}</li>`)\n }\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>${escapeHtml(err.message || err.name)}</title>\n<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f3f4f6;color:#111827}main{max-width:1100px;margin:2rem auto;padding:0 1rem}header{background:#fff;border-radius:.5rem;padding:1.5rem;box-shadow:0 1px 3px #0001}.class{color:#dc2626;font-weight:600}.message{font-size:1.5rem;margin:.5rem 0}.request{color:#6b7280}section{background:#fff;border-radius:.5rem;padding:1rem;margin-top:1rem;box-shadow:0 1px 3px #0001;overflow:auto}.source td{padding:0 .5rem;white-space:pre;font-size:.85rem}.source .n{color:#9ca3af;text-align:right}.source .current{background:#fee2e2}ol{font-family:ui-monospace,monospace;font-size:.85rem}</style>\n</head>\n<body><main>\n<header><div class=\"class\">${escapeHtml(err.name)}</div><div class=\"message\">${escapeHtml(err.message)}</div><div class=\"request\">${escapeHtml(method)} ${escapeHtml(url)}</div></header>\n${appFrame === undefined ? '' : `<section><div>${escapeHtml(appFrame.file)}:${appFrame.line}</div>${source ?? ''}</section>`}\n<section><ol>${frames.map((frame) => `<li>${escapeHtml(frame.text)}</li>`).join('')}</ol></section>\n${causes.length === 0 ? '' : `<section><div>Caused by</div><ul>${causes.join('')}</ul></section>`}\n</main></body>\n</html>`\n}\n","import { ExceptionCallbacks, type Application, type ExceptionsConfigurator, type HttpRequest } from '@orieljs/contracts'\nimport type { ErrorClass, ErrorHandler, RenderCallback, ReportCallback } from './ErrorHandler'\n\n/** The `e` in withExceptions((e) => …). */\nexport class ExceptionsConfiguration implements ExceptionsConfigurator {\n constructor(private readonly handler: ErrorHandler) {}\n\n report(callback: ReportCallback): this {\n this.handler.reportUsing(callback)\n return this\n }\n\n render(callback: RenderCallback): this {\n this.handler.renderUsing(callback)\n return this\n }\n\n dontReport(...classes: ErrorClass[]): this {\n this.handler.ignore(...classes)\n return this\n }\n\n /** shouldRenderJsonWhen((request) => request.is('api/*')): JSON errors for those requests, whatever they accept. */\n shouldRenderJsonWhen(callback: (request: HttpRequest, error: unknown) => boolean): this {\n this.handler.shouldRenderJsonWhen(callback)\n return this\n }\n}\n\n/** Runs the withExceptions() callbacks against a handler (the provider does this when the handler is built). */\nexport function applyExceptionCallbacks(app: Application, handler: ErrorHandler): void {\n if (!app.bound(ExceptionCallbacks)) return\n const configurator = new ExceptionsConfiguration(handler)\n for (const callback of app.make(ExceptionCallbacks)) callback(configurator)\n}\n","import { HttpKernel, type Application } from '@orieljs/contracts'\nimport { plainServerError } from '../Kernel'\nimport { servePublicFile } from './static'\n\nexport type Runtime = 'node' | 'bun'\n\nexport interface ServeOptions {\n /** Default: PORT, then SERVER_PORT, then 8000 (Laravel's serve). 0 picks a free port. */\n port?: number\n /** Default: 127.0.0.1. */\n hostname?: string\n /** Close gracefully on SIGINT/SIGTERM, then exit. Default: true. */\n signals?: boolean\n /** How long close() waits for in-flight requests before cutting connections (ms). Default: 10000. */\n shutdownTimeout?: number\n /** Default: detected (Bun when globalThis.Bun exists). */\n runtime?: Runtime\n /** Called once listening. Default: prints \"Server running on [url].\" */\n onListen?: (server: RunningServer) => void\n /** Serve existing files from this directory before the app (Laravel's server.php). Default: app.publicPath(); false turns it off. */\n publicPath?: string | false\n}\n\nexport interface ResolvedServeOptions {\n readonly port: number\n readonly hostname: string\n readonly signals: boolean\n readonly shutdownTimeout: number\n /** Where public files are served from, or undefined when turned off. */\n readonly publicPath?: string\n}\n\nexport interface RunningServer {\n readonly runtime: Runtime\n readonly hostname: string\n readonly port: number\n /** 'http://127.0.0.1:8000' */\n readonly url: string\n /** Stops accepting connections, waits for in-flight requests (up to shutdownTimeout), then resolves. */\n close(): Promise<void>\n /** Resolves once the server has closed. */\n readonly closed: Promise<void>\n}\n\n/** HttpKernel.terminate() after the response went out (Laravel's terminable middleware). Never throws. */\nexport async function terminateRequest(app: Application, request: Request, response: Response): Promise<void> {\n try {\n if (app.bound(HttpKernel)) await app.make(HttpKernel).terminate?.(request, response)\n } catch (error) {\n console.error(error)\n }\n}\n\n/** A public file when one matches, else app.handle(), turning a crash outside the kernel into a plain 500. */\nexport async function handleSafely(app: Application, request: Request, publicPath?: string): Promise<Response> {\n try {\n if (publicPath !== undefined) {\n const file = await servePublicFile(publicPath, request)\n if (file !== undefined) return file\n }\n return await app.handle(request)\n } catch (error) {\n console.error(error)\n return plainServerError()\n }\n}\n\n/**\n * SIGINT/SIGTERM → close() → app.shutdown() (database pools, Redis clients, log files) → process.exit(0). The\n * listeners go away when the server closes.\n */\nexport function exitOnSignals(close: () => Promise<void>, closed: Promise<void>, app: Application): void {\n const onSignal = () => {\n void close()\n .then(() => app.shutdown())\n .then(() => process.exit(0))\n }\n process.once('SIGINT', onSignal)\n process.once('SIGTERM', onSignal)\n void closed.then(() => {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n })\n}\n\nexport const displayHost = (hostname: string): string => (hostname.includes(':') ? `[${hostname}]` : hostname)\n","import { createReadStream } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { Readable } from 'node:stream'\nimport { relative, resolve, sep } from 'node:path'\nimport { mimeFromExtension } from '../mime'\n\n/**\n * Source files and dotfiles in public/ are never served (public/index.ts is the entry point, not an asset).\n * Tested on every segment of the resolved path, so trailing slashes and dot segments can't hide a name.\n * Names ending in a dot or a space are refused too, since Windows strips those when it opens the file.\n */\nconst HIDDEN_SEGMENT = /^\\.|\\.(ts|tsx|mts|cts)$|[. ]$/i\n\n/**\n * Laravel's server.php for `artisan serve`: a GET or HEAD for a file that exists under public/ is answered\n * with that file, so the built Vite assets (public/build) and other public files work without a web server.\n * Anything else (directories, missing files, other methods) returns undefined and goes to the application.\n */\nexport async function servePublicFile(publicPath: string, request: Request): Promise<Response | undefined> {\n if (request.method !== 'GET' && request.method !== 'HEAD') return undefined\n let pathname: string\n try {\n pathname = decodeURIComponent(new URL(request.url).pathname)\n } catch {\n return undefined\n }\n if (pathname === '/' || pathname.includes('\\0')) return undefined\n const root = resolve(publicPath)\n const file = resolve(root, `.${pathname}`)\n if (!file.startsWith(root + sep)) return undefined\n if (relative(root, file).split(/[\\\\/]/).some((segment) => HIDDEN_SEGMENT.test(segment))) return undefined\n const info = await stat(file).catch(() => undefined)\n if (info === undefined || !info.isFile()) return undefined\n\n const type = mimeFromExtension(file)\n const headers = new Headers({\n 'content-type': type.startsWith('text/') || type === 'application/json' ? `${type}; charset=utf-8` : type,\n 'content-length': String(info.size),\n 'last-modified': info.mtime.toUTCString(),\n })\n // Vite's hashed build output never changes under the same name.\n if (pathname.startsWith('/build/assets/')) headers.set('cache-control', 'public, max-age=31536000, immutable')\n if (request.method === 'HEAD') return new Response(null, { status: 200, headers })\n const body = Readable.toWeb(createReadStream(file)) as unknown as ReadableStream<Uint8Array>\n return new Response(body, { status: 200, headers })\n}\n","import type { Application } from '@orieljs/contracts'\nimport { setClientAddress } from '../clientAddress'\nimport { HttpServerError } from '../errors'\nimport { plainServerError } from '../Kernel'\nimport {\n displayHost,\n exitOnSignals,\n handleSafely,\n terminateRequest,\n type ResolvedServeOptions,\n type RunningServer,\n} from './types'\n\n/** The slice of Bun's API used here (typed locally: there is no Bun lib in the build). */\ninterface BunServer {\n readonly port: number\n stop(closeActiveConnections?: boolean): Promise<void> | void\n requestIP(request: Request): { address: string } | null\n}\ninterface BunRuntime {\n serve(options: {\n port: number\n hostname: string\n fetch(request: Request, server: BunServer): Promise<Response>\n error(error: Error): Response\n }): BunServer\n}\n\nexport function bunRuntime(): BunRuntime | undefined {\n return (globalThis as { Bun?: BunRuntime }).Bun\n}\n\nexport async function serveBun(app: Application, options: ResolvedServeOptions): Promise<RunningServer> {\n const bun = bunRuntime()\n if (bun === undefined) throw new HttpServerError('Bun.serve is not available: the process is not running on Bun.')\n let markClosed: () => void = () => undefined\n const closed = new Promise<void>((resolve) => (markClosed = resolve))\n\n const server = bun.serve({\n port: options.port,\n hostname: options.hostname,\n async fetch(request, current) {\n setClientAddress(request, current.requestIP(request)?.address)\n const response = await handleSafely(app, request, options.publicPath)\n // Bun has no \"response sent\" hook: terminate on the next tick.\n setTimeout(() => void terminateRequest(app, request, response), 0)\n return response\n },\n error(error) {\n console.error(error)\n return plainServerError()\n },\n })\n\n let closing: Promise<void> | undefined\n const close = () =>\n (closing ??= (async () => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const forced = new Promise<void>((resolve) => {\n timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(resolve), options.shutdownTimeout)\n })\n await Promise.race([Promise.resolve(server.stop(false)), forced])\n clearTimeout(timer)\n markClosed()\n })())\n if (options.signals) exitOnSignals(close, closed, app)\n\n return {\n runtime: 'bun',\n hostname: options.hostname,\n port: server.port,\n url: `http://${displayHost(options.hostname)}:${server.port}`,\n close,\n closed,\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as NodeReadableStream } from 'node:stream/web'\nimport type { Application } from '@orieljs/contracts'\nimport { setClientAddress } from '../clientAddress'\nimport {\n displayHost,\n exitOnSignals,\n handleSafely,\n terminateRequest,\n type ResolvedServeOptions,\n type RunningServer,\n} from './types'\n\n/**\n * The request's body as a web stream that pulls from `req`. Readable.toWeb(req) is not used: cancelling it (readBody\n * does that for a declared length over the limit) closes its controller while the socket still emits data, which\n * throws out of the adapter and kills the process. Cancelling this one just stops listening; node drops the unread\n * remainder once the response finishes.\n */\nfunction requestBody(req: IncomingMessage): ReadableStream<Uint8Array> {\n let finished = false\n const detach = () => {\n finished = true\n req.off('data', onData)\n req.off('end', onEnd)\n req.off('error', onError)\n req.off('close', onClose)\n }\n let controller!: ReadableStreamDefaultController<Uint8Array>\n const onData = (chunk: Buffer) => {\n if (finished) return\n controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength))\n if ((controller.desiredSize ?? 0) <= 0) req.pause()\n }\n const onEnd = () => {\n if (finished) return\n detach()\n controller.close()\n }\n const onError = (error: Error) => {\n if (finished) return\n detach()\n controller.error(error)\n }\n const onClose = () => {\n if (!finished && !req.complete) onError(new Error('The request was aborted.'))\n }\n return new ReadableStream<Uint8Array>(\n {\n start(c) {\n controller = c\n req.on('data', onData)\n req.on('end', onEnd)\n req.on('error', onError)\n req.on('close', onClose)\n req.pause()\n },\n pull() {\n req.resume()\n },\n cancel() {\n detach()\n },\n },\n { highWaterMark: 0 },\n )\n}\n\n/** node:http IncomingMessage → web Request (the body streams; the signal aborts when the client goes away). */\nexport function toWebRequest(req: IncomingMessage, res: ServerResponse, fallbackHost: string): Request {\n // Concatenate rather than resolve: a target such as '//evil.com/x' must stay on this host, not become evil.com.\n const target = req.url ?? '/'\n const url = new URL(`http://${req.headers.host ?? fallbackHost}${target.startsWith('/') ? target : `/${target}`}`)\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i]!\n if (!name.startsWith(':')) headers.append(name, req.rawHeaders[i + 1]!)\n }\n const method = (req.method ?? 'GET').toUpperCase()\n const controller = new AbortController()\n res.once('close', () => {\n if (!res.writableFinished) controller.abort()\n })\n const init: RequestInit & { duplex?: 'half' } = { method, headers, signal: controller.signal }\n if (method !== 'GET' && method !== 'HEAD') {\n init.body = requestBody(req)\n init.duplex = 'half'\n }\n return new Request(url, init)\n}\n\n/** Web Response → ServerResponse, streaming the body with backpressure. Several Set-Cookie headers stay separate. */\nexport async function writeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status\n if (response.statusText !== '') res.statusMessage = response.statusText\n response.headers.forEach((value, name) => {\n if (name !== 'set-cookie') res.setHeader(name, value)\n })\n const cookies = response.headers.getSetCookie()\n if (cookies.length > 0) res.setHeader('set-cookie', cookies)\n if (response.body === null) {\n res.end()\n return\n }\n await pipeline(Readable.fromWeb(response.body as unknown as NodeReadableStream<Uint8Array>), res)\n}\n\nexport async function serveNode(app: Application, options: ResolvedServeOptions): Promise<RunningServer> {\n const fallbackHost = `${displayHost(options.hostname)}:${options.port}`\n const server = createServer((req, res) => {\n void (async () => {\n let request: Request\n try {\n request = toWebRequest(req, res, fallbackHost)\n } catch {\n res.statusCode = 400\n res.end('Bad Request')\n return\n }\n setClientAddress(request, req.socket.remoteAddress)\n const response = await handleSafely(app, request, options.publicPath)\n try {\n await writeResponse(res, response)\n } catch {\n // The client went away mid-response.\n res.destroy()\n }\n await terminateRequest(app, request, response)\n })()\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(options.port, options.hostname, () => {\n server.off('error', reject)\n resolve()\n })\n })\n\n const address = server.address() as AddressInfo\n const closed = new Promise<void>((resolve) => server.once('close', () => resolve()))\n let closing: Promise<void> | undefined\n const close = () =>\n (closing ??= (async () => {\n const done = new Promise<void>((resolve) => server.close(() => resolve()))\n // Keep-alive connections become idle once their request finishes; close them as that happens.\n server.closeIdleConnections()\n const idle = setInterval(() => server.closeIdleConnections(), 50)\n const force = setTimeout(() => server.closeAllConnections(), options.shutdownTimeout)\n await done\n clearInterval(idle)\n clearTimeout(force)\n })())\n if (options.signals) exitOnSignals(close, closed, app)\n\n return {\n runtime: 'node',\n hostname: options.hostname,\n port: address.port,\n url: `http://${displayHost(options.hostname)}:${address.port}`,\n close,\n closed,\n }\n}\n","import type { Application } from '@orieljs/contracts'\nimport { bunRuntime, serveBun } from './bun'\nimport { serveNode } from './node'\nimport type { ResolvedServeOptions, Runtime, RunningServer, ServeOptions } from './types'\n\nexport function detectRuntime(): Runtime {\n return bunRuntime() !== undefined ? 'bun' : 'node'\n}\n\n/** Boots the app and serves it with node:http or Bun.serve (public/index.ts: `await serve(app)`). */\nexport async function serve(app: Application, options: ServeOptions = {}): Promise<RunningServer> {\n const resolved: ResolvedServeOptions = {\n port: options.port ?? Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8000),\n hostname: options.hostname ?? '127.0.0.1',\n signals: options.signals ?? true,\n shutdownTimeout: options.shutdownTimeout ?? 10_000,\n ...(options.publicPath !== false && { publicPath: options.publicPath ?? app.publicPath() }),\n }\n await app.boot()\n const runtime = options.runtime ?? detectRuntime()\n const server = runtime === 'bun' ? await serveBun(app, resolved) : await serveNode(app, resolved)\n const onListen = options.onListen ?? ((running: RunningServer) => console.log(`Server running on [${running.url}].`))\n onListen(server)\n return server\n}\n","import { existsSync } from 'node:fs'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport {\n Router,\n type Application,\n type CommandContext,\n type ConsoleKernel,\n type MiddlewareReference,\n type Route,\n} from '@orieljs/contracts'\nimport { serve } from './server/serve'\nimport type { RunningServer, ServeOptions } from './server/types'\nimport { serverEnvironment } from './watch/environment'\nimport { watchFiles } from './watch/files'\nimport { claimPort, listenFailure } from './watch/port'\nimport { WatchedServer, type WatchedServerOptions } from './watch/WatchedServer'\n\ninterface Io {\n option(name: string): string | undefined\n flag(name: string): boolean\n info(message: string): void\n line(message: string): void\n warn(message: string): void\n error(message: string): void\n}\n\n/**\n * The closure command's `this` (the contract's CommandContext), with the options normalised: a value option that\n * is absent (undefined, null, false or '') reads as undefined, and a flag is true only when set.\n */\nfunction io(command: CommandContext): Io {\n return {\n option: (name) => {\n const value: unknown = command.option(name)\n return value === undefined || value === null || value === false || value === '' ? undefined : String(value)\n },\n flag: (name) => {\n const value: unknown = command.option(name)\n return value === true || value === 'true' || value === '1'\n },\n info: (message) => command.info(message),\n line: (message) => command.line(message),\n warn: (message) => command.warn(message),\n error: (message) => command.error(message),\n }\n}\n\nexport interface RouteListRow {\n /** 'GET|HEAD' */\n readonly method: string\n readonly uri: string\n readonly name: string | null\n /** 'PostController@show' or 'Closure' */\n readonly action: string\n readonly middleware: string[]\n}\n\ninterface ListableRoute extends Route {\n getActionName?(): string\n gatherMiddleware?(): MiddlewareReference[]\n}\n\nconst middlewareName = (reference: MiddlewareReference): string => (typeof reference === 'string' ? reference : reference.name)\n\n/** One row per route, sorted by URI (Laravel's default --sort=uri; ties keep registration order). */\nexport function routeListRows(routes: readonly Route[]): RouteListRow[] {\n const rows = routes.map((route) => {\n const listable = route as ListableRoute\n return {\n method: route.methods.join('|'),\n uri: route.uri,\n name: route.getName() ?? null,\n action: typeof listable.getActionName === 'function' ? listable.getActionName() : 'Closure',\n middleware: typeof listable.gatherMiddleware === 'function' ? listable.gatherMiddleware().map(middlewareName) : [],\n }\n })\n return rows.sort((a, b) => (a.uri < b.uri ? -1 : a.uri > b.uri ? 1 : 0))\n}\n\nexport interface RouteListFilters {\n method?: string\n name?: string\n path?: string\n /** Comma-separated. */\n exceptPath?: string\n}\n\n/** Laravel's RouteListCommand::filterRoute: substring matches, method compared uppercased. */\nexport function filterRouteList(rows: readonly RouteListRow[], filters: RouteListFilters): RouteListRow[] {\n const excluded = (filters.exceptPath ?? '').split(',').filter((path) => path !== '')\n return rows.filter((row) => {\n if (filters.name !== undefined && !(row.name ?? '').includes(filters.name)) return false\n if (filters.path !== undefined && !row.uri.includes(filters.path)) return false\n if (filters.method !== undefined && !row.method.includes(filters.method.toUpperCase())) return false\n return !excluded.some((path) => row.uri.includes(path))\n })\n}\n\n/**\n * Laravel's route:list layout: the method column padded, the URI, a dotted leader, then `name › action`\n * (closures show only the name), and a right-aligned \"Showing [n] routes\" footer.\n */\nexport function formatRouteList(rows: readonly RouteListRow[], width: number): string[] {\n const methodWidth = Math.max(...rows.map((row) => row.method.length))\n const lines = rows.map((row) => {\n const spaces = ' '.repeat(Math.max(methodWidth + 6 - row.method.length, 0))\n const action = row.action === 'Closure' ? (row.name ?? '') : row.name === null ? row.action : `${row.name} › ${row.action}`\n const used = row.method.length + spaces.length + row.uri.length + action.length + 6 + (action === '' ? 0 : 1)\n const dots = '.'.repeat(Math.max(width - used, 0))\n return ` ${row.method} ${spaces}${row.uri}${dots === '' ? '' : ` ${dots}`}${action === '' ? '' : ` ${action}`}`\n })\n const count = `Showing [${rows.length}] ${rows.length === 1 ? 'route' : 'routes'}`\n return [...lines, '', `${' '.repeat(Math.max(width - count.length - 2, 0))}${count}`]\n}\n\n/** The routes/api.ts that install:api writes (Laravel's api.stub, with the token guard). */\nexport const API_ROUTES_STUB = `import { request, Route } from '@orieljs/framework'\n\nRoute.get('/user', () => request().user()).middleware('auth:token')\n`\n\n/**\n * Adds `api: 'routes/api.ts'` to withRouting() in bootstrap/app.ts: uncomments a commented `// api:` entry,\n * else inserts it after the `web:` entry, else at the start of withRouting({, else adds a withRouting() call\n * before create(). Returns the source unchanged when api is already there, and undefined when it can't tell where.\n * (Function replacers, so a `$` in the file is never read as a replacement pattern.)\n */\nexport function addApiRouting(source: string): string | undefined {\n const code = source.replace(/^[ \\t]*\\/\\/.*$/gm, '')\n if (/withRouting\\(\\s*\\{[^}]*\\bapi\\s*:/.test(code)) return source\n const commented = /^([ \\t]*)\\/\\/\\s*(api:\\s*['\"`][^'\"`\\n]*['\"`],?)[ \\t]*$/m.exec(source)\n if (commented !== null) return source.replace(commented[0], () => `${commented[1]}${commented[2]}`)\n const web = /^([ \\t]*)web:\\s*(['\"`])[^'\"`\\n]*\\2[ \\t]*,?[ \\t]*$/m.exec(source)\n if (web !== null) {\n const line = web[0].trimEnd()\n return source.replace(web[0], () => `${line.endsWith(',') ? line : `${line},`}\\n${web[1]}api: 'routes/api.ts',`)\n }\n const inline = /withRouting\\(\\s*\\{/.exec(source)\n if (inline !== null) return source.replace(inline[0], () => `${inline[0]} api: 'routes/api.ts',`)\n const create = /^([ \\t]*)\\.create\\(\\)/m.exec(source)\n if (create !== null) return source.replace(create[0], () => `${create[1]}.withRouting({ api: 'routes/api.ts' })\\n${create[0]}`)\n return undefined\n}\n\nexport interface HttpCommandOptions {\n /** Replaces serve() (tests). */\n serve?: (app: Application, options: ServeOptions) => Promise<RunningServer>\n /** The terminal width for route:list. Default: process.stdout.columns, else 120. */\n terminalWidth?: () => number\n /** Replaces `serve --watch`'s restarting server (tests). Resolves the command's exit code. */\n watch?: (options: WatchedServerOptions) => Promise<number>\n}\n\n/**\n * `serve --watch`: claims the port once (`--port`, else PORT, SERVER_PORT, 8000; 0 picks a free one), so every\n * restart serves on the same port and a taken port fails at once, then runs `serve` on it in a child process that\n * restarts when the app's files change. The child is this runtime with its flags and script (`node oriel`,\n * `bun oriel`), in this folder, with the environment this process started with, so an edited .env applies.\n */\nasync function serveWatching(app: Application, out: Io, port: string | undefined, run: (options: WatchedServerOptions) => Promise<number>): Promise<number> {\n const hostname = out.option('host') ?? '127.0.0.1'\n const requested = port !== undefined ? Number(port) : Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8000)\n let claimed: number\n try {\n claimed = await claimPort(hostname, requested)\n } catch (error) {\n out.error(listenFailure(hostname, requested, error))\n return 1\n }\n const script = process.argv[1]\n if (script === undefined) {\n out.error(\"serve --watch can't tell which script started this process, so it can't start the server.\")\n return 1\n }\n return run({\n command: [process.execPath, ...process.execArgv, script, 'serve', `--host=${hostname}`, `--port=${claimed}`],\n cwd: process.cwd(),\n env: serverEnvironment(),\n watch: (onChange) =>\n watchFiles(app.basePath(), onChange, { onError: (folder, error) => out.warn(`Unable to watch [${folder}] for changes: ${error.message}`) }),\n info: (message) => out.info(message),\n error: (message) => out.error(message),\n })\n}\n\n/** Registers `serve`, `route:list` and `install:api` as closure commands (PC1). */\nexport function registerHttpCommands(kernel: ConsoleKernel, app: Application, options: HttpCommandOptions = {}): void {\n const serveApp = options.serve ?? serve\n const terminalWidth = options.terminalWidth ?? (() => process.stdout.columns ?? 120)\n const runWatching = options.watch ?? ((watchOptions: WatchedServerOptions) => new WatchedServer(watchOptions).run())\n\n kernel\n .command(\n 'serve {--host=127.0.0.1 : The host address to serve the application on} {--port= : The port to serve the application on} ' +\n '{--watch : Automatically restart the server when the application is modified}',\n async function (this: CommandContext) {\n const out = io(this)\n const port = out.option('port')\n if (port !== undefined && !/^\\d+$/.test(port)) {\n out.error('The --port option must be a number.')\n return 1\n }\n if (out.flag('watch')) return serveWatching(app, out, port, runWatching)\n const server = await serveApp(app, {\n hostname: out.option('host') ?? '127.0.0.1',\n ...(port !== undefined && { port: Number(port) }),\n onListen: (running) => {\n out.info(`Server running on [${running.url}].`)\n out.line('Press Ctrl+C to stop the server')\n },\n })\n await server.closed\n return 0\n },\n )\n .purpose('Serve the application on the Oriel development server')\n\n kernel\n .command(\n 'route:list {--method= : Filter the routes by method} {--name= : Filter the routes by name} ' +\n '{--path= : Only show routes matching the given path pattern} ' +\n '{--except-path= : Do not display the routes matching the given path pattern} ' +\n '{--reverse : Reverse the ordering of the routes} {--json : Output the route list as JSON}',\n function (this: CommandContext) {\n const out = io(this)\n if (!app.bound(Router)) {\n out.error('The router is not available. Is the Routing service provider registered?')\n return 1\n }\n const all = routeListRows(app.make(Router).getRoutes())\n if (all.length === 0) {\n out.error(\"Your application doesn't have any routes.\")\n return 0\n }\n const rows = filterRouteList(all, {\n ...(out.option('method') !== undefined && { method: out.option('method') }),\n ...(out.option('name') !== undefined && { name: out.option('name') }),\n ...(out.option('path') !== undefined && { path: out.option('path') }),\n ...(out.option('except-path') !== undefined && { exceptPath: out.option('except-path') }),\n })\n if (rows.length === 0) {\n out.error(\"Your application doesn't have any routes matching the given criteria.\")\n return 0\n }\n if (out.flag('reverse')) rows.reverse()\n if (out.flag('json')) {\n out.line(JSON.stringify(rows))\n return 0\n }\n for (const line of formatRouteList(rows, terminalWidth())) out.line(line)\n return 0\n },\n )\n .purpose('List all registered routes')\n\n kernel\n .command('install:api {--force : Overwrite any existing API routes file}', async function (this: CommandContext) {\n const out = io(this)\n const routesFile = app.basePath('routes/api.ts')\n if (existsSync(routesFile) && !out.flag('force')) {\n out.error('API routes file already exists.')\n } else {\n await mkdir(dirname(routesFile), { recursive: true })\n await writeFile(routesFile, API_ROUTES_STUB)\n out.info('Published API routes file.')\n }\n\n const bootstrapFile = app.bootstrapPath('app.ts')\n const source = existsSync(bootstrapFile) ? await readFile(bootstrapFile, 'utf8') : undefined\n const updated = source === undefined ? undefined : addApiRouting(source)\n if (updated === undefined) {\n out.warn(\n 'Unable to automatically add API route definition to bootstrap file. ' +\n \"Add api: 'routes/api.ts' to withRouting() in bootstrap/app.ts.\",\n )\n } else if (updated !== source) {\n await writeFile(bootstrapFile, updated)\n }\n\n out.info('API scaffolding installed.')\n return 0\n })\n .purpose('Create an API routes file and prepare the application for API authentication')\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport * as util from 'node:util'\n\n/**\n * This process's environment as it was when the framework loaded, which is before `createApplication()` reads `.env`:\n * that never overwrites a variable, so a server started with the current environment would keep every old value.\n */\nconst launchEnvironment: Readonly<NodeJS.ProcessEnv> = Object.freeze({ ...process.env })\n\n/**\n * Every file Bun may read into process.env from the working directory before any code runs, whatever the NODE_ENV:\n * `.env`, `.env.<mode>`, `.env.local` and `.env.<mode>.local`, for the modes development, production and test.\n */\nexport const BUN_ENV_FILES: readonly string[] = [\n '.env',\n '.env.development',\n '.env.production',\n '.env.test',\n '.env.local',\n '.env.development.local',\n '.env.production.local',\n '.env.test.local',\n]\n\nexport interface ServerEnvironmentOptions {\n /** Default: the environment this process started with (above). */\n launched?: NodeJS.ProcessEnv\n /** Default: whether this process runs on Bun. */\n bun?: boolean\n /** Where Bun read its env files from. Default: the working directory. */\n cwd?: string\n /** Default: `util.parseEnv`, which some supported runtimes lack (passing `undefined` stands for that). */\n parseEnv?: ((content: string) => NodeJS.Dict<string>) | undefined\n}\n\n/** `$NAME` and `${NAME}` replaced with their values, as Bun expands an env file. */\nconst expand = (value: string, env: NodeJS.ProcessEnv): string =>\n value.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}|\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, braced?: string, bare?: string) => env[braced ?? bare!] ?? '')\n\n/**\n * The environment for each server `serve --watch` starts: the one this process started with, so the server reads\n * `.env` again and an edit applies. On Bun, which loads its env files before any code runs, a variable whose value is\n * the one in such a file (as written, or expanded) is left out too, so the new process loads it again; a variable set\n * to another value (in the shell) stays.\n */\nexport function serverEnvironment(options: ServerEnvironmentOptions = {}): NodeJS.ProcessEnv {\n const launched = options.launched ?? launchEnvironment\n const env: NodeJS.ProcessEnv = { ...launched }\n if (!(options.bun ?? process.versions.bun !== undefined)) return env\n // util.parseEnv is newer than some supported runtimes (a namespace import, so its absence fails nothing at load):\n // without it the env files are not read, and the environment is the launch copy, as on Node.\n const parseEnv = 'parseEnv' in options ? options.parseEnv : (util.parseEnv as typeof util.parseEnv | undefined)\n if (typeof parseEnv !== 'function') return env\n const cwd = options.cwd ?? process.cwd()\n for (const name of BUN_ENV_FILES) {\n const file = join(cwd, name)\n if (!existsSync(file)) continue\n let values: NodeJS.Dict<string>\n try {\n values = parseEnv(readFileSync(file, 'utf8'))\n } catch {\n continue\n }\n for (const [key, raw] of Object.entries(values)) {\n const value = launched[key]\n if (raw !== undefined && value !== undefined && (value === raw || value === expand(raw, launched))) delete env[key]\n }\n }\n return env\n}\n","import { existsSync, statSync, watch as watchPath } from 'node:fs'\nimport { join } from 'node:path'\n\n/**\n * The folders `serve --watch` watches under the app's base path: the server's code, its configuration, the routes,\n * the server-rendered views and the translations. Not `resources/js` or `resources/css` (Vite's), `public`, `storage`,\n * `database` (the SQLite file changes on every write) or `tests`.\n */\nexport const WATCHED_FOLDERS: readonly string[] = ['app', 'bootstrap', 'config', 'lang', 'resources/lang', 'resources/views', 'routes']\n\n/** Files in the base path itself that restart the server, besides `.env` and `.env.*`. */\nexport const WATCHED_ROOT_FILES: readonly string[] = ['package.json', 'tsconfig.json']\n\n/** Build output inside a watched folder, ignored with everything in it: the SSR bundle (`vite build --ssr`) and caches. */\nconst IGNORED_FOLDERS = ['bootstrap/ssr', 'bootstrap/cache']\n\nconst CODE_FILE = /\\.(?:[cm]?[jt]sx?|json)$/\nconst DECLARATION_FILE = /\\.d\\.[cm]?ts$/\n/** Editor swap and backup files: Vim's `.swp` to `.swa` and `.swx`, `~` backups, JetBrains' safe-write copies. */\nconst EDITOR_FILE = /(?:\\.sw[a-px]|~|___jb_(?:tmp|old)___)$/\n\n/** `.env` and `.env.*` (`.env.local`, `.env.testing`, …), except `.env.example` and editor swap and backup files. */\nexport const isEnvironmentFile = (name: string): boolean =>\n (name === '.env' || name.startsWith('.env.')) && name !== '.env.example' && !EDITOR_FILE.test(name)\n\n/**\n * Whether a change to `path` (relative to the base path, `/`-separated) restarts the server: a TypeScript,\n * JavaScript or JSON file in a watched folder (not a `.d.ts`, nothing under a dot-folder, node_modules or the build\n * output, no editor swap or backup file), a name without an extension there (a folder that was moved or removed, but\n * not the build output's own folders), an env file, `package.json` or `tsconfig.json`.\n */\nexport function isWatchedPath(path: string): boolean {\n const segments = path.split('/')\n if (segments.length === 1) return isEnvironmentFile(path) || WATCHED_ROOT_FILES.includes(path)\n if (!WATCHED_FOLDERS.some((folder) => path.startsWith(`${folder}/`))) return false\n if (IGNORED_FOLDERS.some((folder) => path === folder || path.startsWith(`${folder}/`))) return false\n if (segments.some((segment) => segment.startsWith('.') || segment === 'node_modules')) return false\n const name = segments.at(-1)!\n if (DECLARATION_FILE.test(name)) return false\n return CODE_FILE.test(name) || !name.includes('.')\n}\n\n/** The part of a node:fs FSWatcher used here. */\nexport interface WatchHandle {\n close(): void\n on(event: 'error', listener: (error: Error) => void): unknown\n}\n\n/** node:fs watch(), replaceable in tests. */\nexport type WatchFolder = (\n path: string,\n options: { recursive: boolean },\n listener: (event: string, file: string | null) => void,\n) => WatchHandle\n\nexport interface WatchFilesOptions {\n /** Quiet time after the last change before `onChange` runs, in ms. Default 200 (Node's `--watch`). */\n debounce?: number\n /**\n * For this long after the start (ms), a change to a file last modified before the start, or to a path that doesn't\n * exist, is dropped. Default 1000: Node's watcher on macOS reports what was written just before it started, and the\n * watched folder itself under its own name (`app/app`).\n */\n settle?: number\n /** A folder (relative to the base path, `.` for the base path) that could not be watched, or stopped being. */\n onError?: (folder: string, error: Error) => void\n watch?: WatchFolder\n}\n\nexport interface FileWatcher {\n close(): void\n}\n\nconst toSlashes = (file: string): string => file.split('\\\\').join('/')\n\n/**\n * Watches the base path (not recursively: the env files, package.json, tsconfig.json) and each watched folder that\n * exists (recursively, with the runtime's fs.watch), and calls `onChange` with the changed files once no change has\n * come for `debounce` ms. A folder created later is watched from the next start; a file removed in the first second\n * (`settle`) counts only with the next change.\n */\nexport function watchFiles(basePath: string, onChange: (files: string[]) => void, options: WatchFilesOptions = {}): FileWatcher {\n const watch: WatchFolder = options.watch ?? ((path, watchOptions, listener) => watchPath(path, watchOptions, listener))\n const debounce = options.debounce ?? 200\n const onError = options.onError ?? (() => {})\n const changed = new Set<string>()\n let timer: ReturnType<typeof setTimeout> | undefined\n const settle = options.settle ?? 1000\n const startedAt = Date.now()\n /** A change reported in the settle time for something that didn't change since the start (1 ms: Date.now() is whole ms). */\n const reportedLate = (path: string): boolean => {\n if (Date.now() - startedAt >= settle) return false\n try {\n const modified = statSync(join(basePath, path), { throwIfNoEntry: false })?.mtimeMs\n return modified === undefined || modified < startedAt + 1\n } catch {\n return false\n }\n }\n\n const record = (path: string) => {\n if (!isWatchedPath(path) || reportedLate(path)) return\n changed.add(path)\n clearTimeout(timer)\n timer = setTimeout(() => {\n const files = [...changed]\n changed.clear()\n onChange(files)\n }, debounce)\n }\n\n const handles: WatchHandle[] = []\n const start = (folder: string, recursive: boolean, toPath: (file: string | null) => string | undefined) => {\n try {\n const handle = watch(folder === '.' ? basePath : join(basePath, folder), { recursive }, (_event, file) => {\n const path = toPath(file)\n if (path !== undefined) record(path)\n })\n handle.on('error', (error) => onError(folder, error))\n handles.push(handle)\n } catch (error) {\n onError(folder, error as Error)\n }\n }\n\n start('.', false, (file) => (file === null ? undefined : toSlashes(file)))\n for (const folder of WATCHED_FOLDERS) {\n if (existsSync(join(basePath, folder))) start(folder, true, (file) => `${folder}/${file === null ? '' : toSlashes(file)}`)\n }\n\n return {\n close() {\n clearTimeout(timer)\n changed.clear()\n for (const handle of handles) handle.close()\n },\n }\n}\n","import { createServer, type AddressInfo } from 'node:net'\nimport { displayHost } from '../server/types'\n\n/**\n * Listens on the port, then lets it go: the port a server can listen on (a free one for 0). Rejects as listen() does\n * (EADDRINUSE, EACCES, a port out of range). `serve --watch` calls it once, so every restart serves on the same port.\n */\nexport function claimPort(hostname: string, port: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.once('error', reject)\n try {\n server.listen({ port, host: hostname, exclusive: true }, () => {\n const { port: claimed } = server.address() as AddressInfo\n server.close(() => resolve(claimed))\n })\n } catch (error) {\n reject(error)\n }\n })\n}\n\nconst REASONS: Record<string, string> = {\n EADDRINUSE: 'Address already in use',\n EACCES: 'Permission denied',\n EADDRNOTAVAIL: \"Can't assign requested address\",\n}\n\n/** PHP's built-in server's message, which Laravel's serve shows: `Failed to listen on 127.0.0.1:8000 (reason: Address already in use)`. */\nexport function listenFailure(hostname: string, port: number, error: unknown): string {\n const { code, message } = error as NodeJS.ErrnoException\n return `Failed to listen on ${displayHost(hostname)}:${port} (reason: ${(code !== undefined && REASONS[code]) || message})`\n}\n","import { spawn as spawnProcess, type ChildProcess, type SpawnOptions } from 'node:child_process'\nimport { isEnvironmentFile, type FileWatcher } from './files'\n\n/** node:child_process's spawn(), replaceable in tests. */\nexport type SpawnServer = (command: string, args: string[], options: SpawnOptions) => ChildProcess\n\nexport interface WatchedServerOptions {\n /** The server's command line: the runtime, its flags, the CLI script, then `serve --host=… --port=…`. */\n command: readonly string[]\n cwd: string\n env: NodeJS.ProcessEnv\n /** Starts watching: calls back with the changed files (relative to the base path) once they settle. */\n watch(onChange: (files: string[]) => void): FileWatcher\n info(message: string): void\n error(message: string): void\n /** How long a server may take to stop before it is killed, in ms. Default 15000 (serve gives requests 10 s). */\n stopTimeout?: number\n /** The signals that stop it. Default SIGINT, SIGTERM and SIGHUP. */\n signals?: readonly NodeJS.Signals[]\n spawn?: SpawnServer\n}\n\ninterface Running {\n child: ChildProcess\n /** Resolves once the process has exited (or could not start). */\n exited: Promise<void>\n /** This side asked it to stop: its exit is not reported. */\n stopping: boolean\n /** Killed after stopTimeout (reported once). */\n killed: boolean\n}\n\n/**\n * `serve --watch`: runs `serve` in a child process and starts a new one after every change, on the same port. The\n * old server is stopped (SIGTERM, which serve answers by finishing its requests) and has exited before the next one\n * starts, so the port is free. Changes that come during a restart are read by the server it starts. A server that\n * exits by itself (a syntax error, a crash) is reported and the next change starts one, so this process keeps running.\n * SIGINT, SIGTERM and SIGHUP stop the server and end run(); a second one kills the server at once.\n */\nexport class WatchedServer {\n private running: Running | undefined\n private restarting = false\n private stopping = false\n private finish: (code: number) => void = () => {}\n\n constructor(private readonly options: WatchedServerOptions) {}\n\n /** Starts the server and keeps it current until stopped. Resolves 0 once the last server has exited. */\n run(): Promise<number> {\n const done = new Promise<number>((resolve) => (this.finish = resolve))\n const stopListening = this.listenForSignals()\n const watcher = this.options.watch((files) => void this.changed(files))\n this.start()\n return done.finally(() => {\n watcher.close()\n stopListening()\n })\n }\n\n /** Stops the server and ends run(); called again, kills the server at once. */\n stop(): void {\n if (this.stopping) {\n this.running?.child.kill('SIGKILL')\n return\n }\n this.stopping = true\n void this.stopServer().then(() => this.finish(0))\n }\n\n private async changed(files: string[]): Promise<void> {\n if (this.stopping || this.restarting || files.length === 0) return\n this.restarting = true\n try {\n this.options.info(\n files.some(isEnvironmentFile) ? 'Environment modified. Restarting server...' : `Application change detected in [${files[0]}]. Restarting server...`,\n )\n await this.stopServer()\n if (!this.stopping) this.start()\n } finally {\n this.restarting = false\n }\n }\n\n private start(): void {\n const [command, ...args] = this.options.command\n const child = (this.options.spawn ?? spawnProcess)(command!, args, {\n cwd: this.options.cwd,\n env: this.options.env,\n stdio: ['ignore', 'inherit', 'inherit'],\n })\n const running: Running = { child, stopping: false, killed: false, exited: Promise.resolve() }\n running.exited = new Promise<void>((resolve) => {\n let settled = false\n const settle = (report: string) => {\n if (settled) return\n settled = true\n if (this.running === running) this.running = undefined\n if (!running.stopping && !this.stopping) this.options.error(`${report}. Waiting for changes before restarting...`)\n resolve()\n }\n child.once('exit', (code, signal) => settle(signal !== null ? `The server stopped (signal ${signal})` : `The server stopped (exit code ${code})`))\n // 'error' also comes when a signal can't be sent: only a process that never started has ended with it.\n child.once('error', (error) => {\n if (child.pid === undefined) settle(`The server could not start (${error.message})`)\n })\n })\n this.running = running\n }\n\n /** Sends SIGTERM once and waits for the exit, killing the server after stopTimeout. */\n private async stopServer(): Promise<void> {\n const running = this.running\n if (running === undefined) return\n if (!running.stopping) {\n running.stopping = true\n running.child.kill('SIGTERM')\n }\n const timeout = this.options.stopTimeout ?? 15_000\n const timer = setTimeout(() => {\n if (running.killed) return\n running.killed = true\n this.options.error(`The server did not stop within ${timeout / 1000} seconds and was killed.`)\n running.child.kill('SIGKILL')\n }, timeout)\n try {\n await running.exited\n } finally {\n clearTimeout(timer)\n }\n }\n\n private listenForSignals(): () => void {\n const signals = this.options.signals ?? (['SIGINT', 'SIGTERM', 'SIGHUP'] as const)\n const handler = () => this.stop()\n for (const signal of signals) process.on(signal, handler)\n return () => {\n for (const signal of signals) process.off(signal, handler)\n }\n }\n}\n","import { ConsoleKernel, ExceptionHandler, HttpKernel, Redirector, ResponseFactory, Router } from '@orieljs/contracts'\nimport { ServiceProvider } from '@orieljs/support'\nimport { registerHttpCommands } from './commands'\nimport { ErrorHandler } from './ErrorHandler'\nimport { applyExceptionCallbacks } from './ExceptionsConfiguration'\nimport { HttpRedirector } from './HttpRedirector'\nimport { HttpResponseFactory } from './HttpResponseFactory'\nimport { Kernel } from './Kernel'\nimport { applyMiddlewareCallbacks } from './MiddlewareConfiguration'\n\n/**\n * Binds the HTTP kernel (replacing any kernel bound before, such as Foundation's ClosureKernel), the exception\n * handler, the response factory and the redirector, and merges the `http` config defaults.\n *\n * The HttpRequest is deliberately NOT bound on the application: the kernel creates one per request and puts it in\n * the request scope with scope.instance(). A root `scoped()` binding would make bound(HttpRequest) true everywhere,\n * and that check is how the URL generator, the redirects and the helpers know they are inside a request.\n */\nexport class HttpServiceProvider extends ServiceProvider {\n override register(): void {\n this.mergeConfigFrom(\n {\n trusted_proxies: [],\n max_body_size: 8 * 1024 * 1024,\n max_json_depth: 512,\n csrf_except: [],\n redirect_guests_to: undefined,\n redirect_users_to: undefined,\n },\n 'http',\n )\n this.app.singleton(HttpKernel, () => new Kernel(this.app))\n this.app.singleton(ExceptionHandler, () => {\n const handler = new ErrorHandler(this.app)\n applyExceptionCallbacks(this.app, handler)\n return handler\n })\n this.app.singleton(ResponseFactory, () => new HttpResponseFactory())\n this.app.singleton(Redirector, () => new HttpRedirector())\n }\n\n override boot(): void {\n // After every provider's boot(), so web({ remove }) and alias() overrides see the components' defaults.\n this.app.booted(() => {\n const kernel = this.app.make(HttpKernel)\n if (kernel instanceof Kernel && this.app.bound(Router)) applyMiddlewareCallbacks(this.app, kernel)\n })\n if (this.app.bound(ConsoleKernel)) registerHttpCommands(this.app.make(ConsoleKernel), this.app)\n }\n}\n"],"mappings":"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","names":["response","url","request","request","inject","inject","Session","currentContainer","inject","Str","Str","inject","Session","currentContainer","HttpRequest","UrlGenerator","inject","inject","HttpRequest","UrlGenerator","inject","inject","CurrentRoute","HttpRequest","currentContainer","request","request","currentContainer","request","response","HttpRequest","route","CurrentRoute","ConfigRepository","Router","url","ConfigRepository","Redirector","UrlGenerator","ViewFactory","currentContainer","url","request","response","Redirector","redirect","UrlGenerator","url","ViewFactory","ConfigRepository","currentContainer","createReadStream","stat","Readable","request","stat","Readable","createReadStream","request","response","resolve","request","response","Readable","url","response","Readable","request","resolve","existsSync","readFile","Router","parseEnv","existsSync","join","createServer","resolve","createServer","resolve","route","Router","existsSync","readFile","ExceptionHandler","HttpKernel","Redirector","ResponseFactory","Router","HttpKernel","ExceptionHandler","ResponseFactory","Redirector","Router"]}
1
+ {"version":3,"sources":["../errors.ts","../body.ts","../context.ts","../HttpRedirectResponse.ts","../HttpRedirector.ts","../clientAddress.ts","../FormUploadedFile.ts","../mime.ts","../IncomingRequest.ts","../input.ts","../helpers.ts","../HttpResponseFactory.ts","../Kernel.ts","../middleware/ConvertEmptyStringsToNull.ts","../middleware/TrimStrings.ts","../MiddlewareConfiguration.ts","../ErrorHandler.ts","../errorPages.ts","../ExceptionsConfiguration.ts","../export/export.ts","../server/types.ts","../server/static.ts","../export/paths.ts","../server/bun.ts","../server/node.ts","../server/serve.ts","../commands.ts","../watch/environment.ts","../watch/files.ts","../watch/port.ts","../watch/WatchedServer.ts","../HttpServiceProvider.ts"],"sourcesContent":["import type { OrielError } from '@orieljs/contracts'\n\n/** Symfony's HttpException: abort(404), abort(403, 'Nope'). An empty message renders as the status text. */\nexport class HttpException extends Error implements OrielError {\n readonly kind = 'Http' as const\n override readonly name = 'HttpException'\n constructor(\n readonly status: number,\n message = '',\n readonly headers: Record<string, string> = {},\n ) {\n super(message)\n }\n}\n\n/** Carries a ready Response out of deep code: abort(response). The handler returns it as is. */\nexport class HttpResponseException extends Error implements OrielError {\n readonly kind = 'Http' as const\n override readonly name = 'HttpResponseException'\n readonly status: number\n constructor(readonly response: Response) {\n super(`HTTP response exception (${response.status}).`)\n this.status = response.status\n }\n}\n\n/** Http's internal failures (not thrown by this package itself; used by the kernel and error rendering). */\nexport class HttpServerError extends Error implements OrielError {\n readonly kind = 'Server' as const\n readonly status = 500\n override readonly name = 'HttpServerError'\n}\n","import { HttpException } from './errors'\n\n/**\n * Whether a JSON text nests objects and arrays deeper than `maxDepth`, found by scanning (no parsing, no recursion):\n * brackets inside strings don't count. The kernel answers 400 for such bodies (http.max_json_depth) before the\n * recursive input handling (sanitizing, TrimStrings, validation) could overflow the stack.\n */\nexport function exceedsJsonDepth(text: string, maxDepth: number): boolean {\n let depth = 0\n let inString = false\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (inString) {\n if (code === 92) i++ // a backslash escapes the next character\n else if (code === 34) inString = false\n } else if (code === 34) inString = true\n else if (code === 123 || code === 91) {\n if (++depth > maxDepth) return true\n } else if (code === 125 || code === 93) depth--\n }\n return false\n}\n\n/** Reads a request body into memory, refusing more than `limit` bytes (413), like PHP's post_max_size. */\nexport async function readBody(raw: Request, limit: number | null): Promise<Uint8Array> {\n if (raw.body === null) return new Uint8Array(0)\n const declared = Number(raw.headers.get('content-length') ?? NaN)\n if (limit !== null && Number.isFinite(declared) && declared > limit) {\n await raw.body.cancel()\n throw new HttpException(413, 'Content Too Large')\n }\n const reader = raw.body.getReader()\n const chunks: Uint8Array[] = []\n let size = 0\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n size += value.byteLength\n if (limit !== null && size > limit) {\n await reader.cancel()\n throw new HttpException(413, 'Content Too Large')\n }\n chunks.push(value)\n }\n const out = new Uint8Array(size)\n let offset = 0\n for (const chunk of chunks) {\n out.set(chunk, offset)\n offset += chunk.byteLength\n }\n return out\n}\n","import { CookieJar, HttpRequest, Session, type Container } from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\n\n/** The current container, only when it is a request scope (the kernel binds HttpRequest there). */\nexport function requestScope(): Container | undefined {\n const container = currentContainer()\n return container !== undefined && container.bound(HttpRequest) ? container : undefined\n}\n\nexport function currentRequest(): HttpRequest | undefined {\n return requestScope()?.make(HttpRequest)\n}\n\n/** The request's session, or undefined outside a request or when no Session provider is registered. */\nexport function optionalSession(): Session | undefined {\n const scope = requestScope()\n return scope?.bound(Session) ? scope.make(Session) : undefined\n}\n\nexport function optionalCookieJar(): CookieJar | undefined {\n const scope = requestScope()\n return scope?.bound(CookieJar) ? scope.make(CookieJar) : undefined\n}\n","import type { Cookie, HeadersInit, MessageBag, RedirectResponse } from '@orieljs/contracts'\nimport { currentRequest, optionalCookieJar, optionalSession } from './context'\n\ntype ErrorsInput = Record<string, string | string[]> | MessageBag\n\n/** A Set-Cookie value. `minutes` 0 is a session cookie; a negative value deletes the cookie. */\nfunction serializeCookie(cookie: Cookie): string {\n const parts = [`${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`, `Path=${cookie.path}`]\n if (cookie.domain !== undefined) parts.push(`Domain=${cookie.domain}`)\n if (cookie.secure) parts.push('Secure')\n if (cookie.httpOnly) parts.push('HttpOnly')\n parts.push(`SameSite=${cookie.sameSite.charAt(0).toUpperCase()}${cookie.sameSite.slice(1)}`)\n if (cookie.minutes < 0) parts.push('Max-Age=0', 'Expires=Thu, 01 Jan 1970 00:00:00 GMT')\n else if (cookie.minutes > 0) parts.push(`Max-Age=${Math.round(cookie.minutes * 60)}`)\n return parts.join('; ')\n}\n\n/**\n * Laravel's RedirectResponse. with()/withErrors()/withInput() flash to the request's Session immediately, like\n * Laravel; without a bound Session (an API-only app) they are skipped silently.\n */\nexport class HttpRedirectResponse implements RedirectResponse {\n readonly #headers: Headers\n\n constructor(\n readonly targetUrl: string,\n readonly status = 302,\n headers?: HeadersInit,\n ) {\n this.#headers = new Headers(headers)\n }\n\n with(key: string | Record<string, unknown>, value?: unknown): this {\n const session = optionalSession()\n if (session === undefined) return this\n if (typeof key === 'string') session.flash(key, value)\n else for (const [name, item] of Object.entries(key)) session.flash(name, item)\n return this\n }\n\n /** Flashes `errors` as { [bag]: { field: string[] } }, keeping the other bags already flashed. */\n withErrors(errors: ErrorsInput, bag = 'default'): this {\n const session = optionalSession()\n if (session === undefined) return this\n const source =\n typeof (errors as { toObject?: unknown }).toObject === 'function'\n ? (errors as MessageBag).toObject()\n : (errors as Record<string, string | string[]>)\n const normalized = Object.fromEntries(\n Object.entries(source).map(([field, messages]) => [field, Array.isArray(messages) ? [...messages] : [messages]]),\n )\n const existing = session.get<Record<string, Record<string, string[]>>>('errors', {})\n session.flash('errors', { ...existing, [bag]: normalized })\n return this\n }\n\n /** Flashes `input`, or the current request's input (files are never part of input()). */\n withInput(input?: Record<string, unknown>): this {\n const session = optionalSession()\n if (session === undefined) return this\n session.flashInput(input ?? currentRequest()?.input<Record<string, unknown>>() ?? {})\n return this\n }\n\n /**\n * Always a Set-Cookie header on this response (Laravel's RedirectResponse::withCookie). A bound CookieJar only\n * supplies the defaults (path, domain, secure, same-site); queueing would lose the cookie outside the web group.\n */\n withCookie(name: string, value: string, minutes = 0): this {\n const jar = optionalCookieJar()\n const cookie: Cookie =\n jar !== undefined\n ? jar.make(name, value, minutes)\n : { name, value, minutes, path: '/', secure: false, httpOnly: true, sameSite: 'lax' }\n this.#headers.append('Set-Cookie', serializeCookie(cookie))\n return this\n }\n\n header(name: string, value: string): this {\n this.#headers.set(name, value)\n return this\n }\n\n toResponse(): Response {\n const headers = new Headers(this.#headers)\n headers.set('Location', this.targetUrl)\n return new Response(null, { status: this.status, headers })\n }\n}\n","import { UrlGenerator, type HeadersInit, type Redirector } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { currentRequest, optionalSession } from './context'\nimport { HttpRedirectResponse } from './HttpRedirectResponse'\n\n/**\n * A URL's path, query and fragment: '/dashboard?tab=1' (the intended URL is stored like this). Leading slashes\n * collapse to one, so '//evil.com/x' can never be read back as a protocol-relative URL.\n */\nfunction pathOf(url: string): string {\n let parsed: URL\n try {\n parsed = new URL(url, 'http://localhost')\n } catch {\n return '/'\n }\n return `${parsed.pathname.replace(/^\\/+/, '/')}${parsed.search}${parsed.hash}`\n}\n\n/** Laravel's Redirector. Stateless: the URL generator and session come from the current container. */\nexport class HttpRedirector implements Redirector {\n to(path: string, status = 302, headers?: HeadersInit): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).to(path), status, headers)\n }\n\n route(name: string, parameters?: unknown, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).route(name, parameters), status)\n }\n\n back(fallback?: string, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(inject(UrlGenerator).previous(fallback), status)\n }\n\n /** Pulls url.intended from the session (put there by guest()), else goes to `fallback`. */\n intended(fallback = '/', status = 302): HttpRedirectResponse {\n const path = optionalSession()?.pull<string | undefined>('url.intended') ?? fallback\n return this.to(path, status)\n }\n\n away(url: string, status = 302): HttpRedirectResponse {\n return new HttpRedirectResponse(url, status)\n }\n\n /**\n * Remembers where a guest was going (a GET page, else the previous URL), then redirects to `path`. Only the path\n * is stored, so intended() goes back on whichever host serves the app, and never to another site's Referer.\n */\n guest(path: string, status = 302): HttpRedirectResponse {\n const session = optionalSession()\n const request = currentRequest()\n if (session !== undefined) {\n const intended =\n request !== undefined && request.method() === 'GET' && !request.expectsJson()\n ? request.fullUrl()\n : inject(UrlGenerator).previous()\n session.put('url.intended', pathOf(intended))\n }\n return this.to(path, status)\n }\n\n setIntendedUrl(url: string): void {\n optionalSession()?.put('url.intended', url)\n }\n\n refresh(status = 302): HttpRedirectResponse {\n return this.to(currentRequest()?.fullUrl() ?? inject(UrlGenerator).current(), status)\n }\n}\n","/**\n * The socket address of each incoming Request, filled by the server adapters (and by test clients).\n * Kept on globalThis under a Symbol.for key, so a package that can't import @orieljs/http (Testing) can set it.\n */\nconst KEY = Symbol.for('oriel:http.client-address')\nconst store = ((globalThis as unknown as Record<symbol, WeakMap<Request, string> | undefined>)[KEY] ??= new WeakMap<Request, string>())\n\nexport function setClientAddress(request: Request, address: string | undefined): void {\n if (address !== undefined && address !== '') store.set(request, address)\n}\n\nexport function clientAddress(request: Request): string | undefined {\n return store.get(request)\n}\n","import { FilesystemManager, type UploadedFile } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { FileType, Str } from '@orieljs/support'\nimport { extensionFromMime } from './mime'\n\n/** Extensions a stored file never takes from the client's claim alone: the formats the bytes are read for, and what a browser renders or runs. */\nconst NEVER_CLAIMED: ReadonlySet<string> = new Set([\n ...FileType.BINARY_AND_MARKUP_TYPES.flatMap(({ extensions }) => extensions),\n 'jpe', 'svgz', 'xhtml', 'xht', 'shtml', 'xsl', 'xslt', 'mht', 'mhtml', 'js', 'mjs',\n 'rss', 'atom', 'rdf', 'mathml', 'mml', 'xul',\n])\n\n/** A claim is kept only as a plain extension, the same test putFile() applies to the name it writes. */\nconst PLAIN_EXTENSION = /^[a-z0-9]+$/\n\n/** An uploaded file from a multipart body. store()/storeAs() go through the FilesystemManager. */\nexport class FormUploadedFile implements UploadedFile {\n readonly clientName: string\n readonly mimeType: string\n readonly size: number\n\n /**\n * Reads the leading bytes first, so extension(), hashName() and store() name the file by its content. The request\n * builds its uploads this way.\n */\n static async fromFile(file: Blob & { readonly name?: string }): Promise<FormUploadedFile> {\n return new FormUploadedFile(file, FileType.detectFileType(new Uint8Array(await file.slice(0, FileType.SNIFF_BYTES).arrayBuffer())))\n }\n\n constructor(\n private readonly file: Blob & { readonly name?: string },\n private readonly detected?: FileType.DetectedType,\n ) {\n this.clientName = file.name ?? ''\n this.mimeType = file.type === '' ? 'application/octet-stream' : file.type\n this.size = file.size\n }\n\n /**\n * Laravel's extension(): the type the bytes show (guessExtension()), when they were read and match a known format.\n * Text and bytes no format matches keep the client's claim (its MIME type, else its file name) when it is a plain\n * extension, unless it names a format the bytes would have shown or one a browser renders or runs: otherwise 'txt'\n * for text, '' for the rest. Unread (built directly), the client's claim when it is a plain extension, else ''.\n */\n extension(): string {\n const claimed = extensionFromMime(this.mimeType) ?? this.clientExtension()\n const detected = this.detected\n if (detected === undefined) return PLAIN_EXTENSION.test(claimed) ? claimed : ''\n if (detected !== FileType.TEXT && detected.extensions.length > 0) return detected.extensions[0]!\n if (PLAIN_EXTENSION.test(claimed) && !NEVER_CLAIMED.has(claimed)) return claimed\n return detected === FileType.TEXT ? 'txt' : ''\n }\n\n clientExtension(): string {\n const dot = this.clientName.lastIndexOf('.')\n return dot === -1 ? '' : this.clientName.slice(dot + 1).toLowerCase()\n }\n\n /** A random 40-character name with the guessed extension. */\n hashName(): string {\n const extension = this.extension()\n return extension === '' ? Str.random(40) : `${Str.random(40)}.${extension}`\n }\n\n arrayBuffer(): Promise<ArrayBuffer> {\n return this.file.arrayBuffer()\n }\n\n text(): Promise<string> {\n return this.file.text()\n }\n\n stream(): ReadableStream<Uint8Array> {\n return this.file.stream() as ReadableStream<Uint8Array>\n }\n\n store(directory: string, disk?: string): Promise<string> {\n return inject(FilesystemManager).disk(disk).putFile(directory, this)\n }\n\n storeAs(directory: string, name: string, disk?: string): Promise<string> {\n return inject(FilesystemManager).disk(disk).putFileAs(directory, this, name)\n }\n}\n","/** A small extension ↔ MIME map for uploads and downloads (not exhaustive on purpose). */\nconst TYPES: Record<string, string> = {\n avif: 'image/avif',\n css: 'text/css',\n csv: 'text/csv',\n doc: 'application/msword',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n gif: 'image/gif',\n gz: 'application/gzip',\n html: 'text/html',\n ico: 'image/vnd.microsoft.icon',\n jpg: 'image/jpeg',\n js: 'text/javascript',\n map: 'application/json',\n json: 'application/json',\n md: 'text/markdown',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n otf: 'font/otf',\n pdf: 'application/pdf',\n png: 'image/png',\n svg: 'image/svg+xml',\n ttf: 'font/ttf',\n txt: 'text/plain',\n wasm: 'application/wasm',\n webm: 'video/webm',\n webp: 'image/webp',\n woff: 'font/woff',\n woff2: 'font/woff2',\n xls: 'application/vnd.ms-excel',\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n xml: 'application/xml',\n zip: 'application/zip',\n}\nconst ALIASES: Record<string, string> = { jpeg: 'jpg', htm: 'html', mjs: 'js', text: 'txt' }\nconst EXTENSIONS = Object.fromEntries(Object.entries(TYPES).map(([extension, type]) => [type, extension]))\n\n/** 'report.PDF' or 'pdf' → 'application/pdf'; unknown → 'application/octet-stream'. */\nexport function mimeFromExtension(pathOrExtension: string): string {\n const extension = pathOrExtension.slice(pathOrExtension.lastIndexOf('.') + 1).toLowerCase()\n return TYPES[ALIASES[extension] ?? extension] ?? 'application/octet-stream'\n}\n\n/** 'image/jpeg; charset=…' → 'jpg'; unknown → undefined. */\nexport function extensionFromMime(type: string): string | undefined {\n return EXTENSIONS[type.split(';')[0]!.trim().toLowerCase()]\n}\n","import {\n AuthFactory,\n CurrentRoute,\n Session,\n ValidationFactory,\n type HttpRequest,\n type InferValidatedType,\n type Rules,\n type UploadedFile,\n} from '@orieljs/contracts'\nimport { currentContainer, inject } from '@orieljs/container'\nimport { Arr, Str, type Stringable } from '@orieljs/support'\nimport { exceedsJsonDepth, readBody } from './body'\nimport { HttpException } from './errors'\nimport { clientAddress } from './clientAddress'\nimport { FormUploadedFile } from './FormUploadedFile'\nimport { fromEntries, isBlank, isPlainObject, mergeRecursive, sanitize, transformLeaves } from './input'\n\ntype Tree = Record<string, unknown>\n\nexport interface IncomingRequestOptions {\n /** Proxy addresses whose X-Forwarded-* headers are believed: exact IPs, IPv4 CIDRs, or '*'. */\n trustedProxies?: readonly string[]\n /** Largest request body in bytes before a 413 (config http.max_body_size); null is unlimited. Default 8 MB. */\n maxBodySize?: number | null\n /** Deepest nesting of objects and arrays in a JSON body before a 400 (config http.max_json_depth); null is unlimited. Default 512. */\n maxJsonDepth?: number | null\n}\n\nconst TRUE_VALUES = new Set(['1', 'true', 'on', 'yes'])\n\nconst normalizeIp = (ip: string): string => ip.trim().replace(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i, '$1')\n\nfunction ipv4ToNumber(ip: string): number | undefined {\n const parts = ip.split('.')\n if (parts.length !== 4 || parts.some((part) => !/^\\d{1,3}$/.test(part) || Number(part) > 255)) return undefined\n return parts.reduce((total, part) => total * 256 + Number(part), 0)\n}\n\n/** Exact match, IPv4 CIDR ('10.0.0.0/8') or '*'. */\nexport function ipMatches(ip: string, patterns: readonly string[]): boolean {\n const address = normalizeIp(ip)\n return patterns.some((pattern) => {\n if (pattern === '*') return true\n if (!pattern.includes('/')) return normalizeIp(pattern) === address\n const [range, bits] = pattern.split('/') as [string, string]\n const base = ipv4ToNumber(range)\n const value = ipv4ToNumber(address)\n const size = Number(bits)\n if (base === undefined || value === undefined || !(size >= 0 && size <= 32)) return false\n const mask = size === 0 ? 0 : (~0 << (32 - size)) >>> 0\n return ((base & mask) >>> 0) === ((value & mask) >>> 0)\n })\n}\n\n/**\n * The HttpRequest implementation (Laravel's Illuminate\\Http\\Request). The kernel calls load() once, before any\n * middleware, so every accessor below is synchronous.\n *\n * `http.max_body_size` applies to the bodies this class parses (JSON, urlencoded and multipart). A handler that reads\n * `request.raw` directly bypasses it and must enforce its own limit.\n */\nexport class IncomingRequest implements HttpRequest {\n readonly #url: URL\n readonly #trustedProxies: readonly string[]\n readonly #maxBodySize: number | null\n readonly #maxJsonDepth: number | null\n #query: Tree\n #body: Tree = {}\n #files: Tree = {}\n #content = ''\n #method: string\n #cookies: Record<string, string> | undefined\n #loading: Promise<this> | undefined\n #userResolver: ((guard?: string) => unknown) | undefined\n\n constructor(\n readonly raw: Request,\n options: IncomingRequestOptions = {},\n ) {\n this.#url = new URL(raw.url)\n this.#trustedProxies = options.trustedProxies ?? []\n this.#maxBodySize = options.maxBodySize === undefined ? 8 * 1024 * 1024 : options.maxBodySize\n this.#maxJsonDepth = options.maxJsonDepth === undefined ? 512 : options.maxJsonDepth\n this.#query = fromEntries(this.#url.searchParams.entries())\n this.#method = raw.method.toUpperCase()\n }\n\n /** Reads and parses the body (JSON, urlencoded or multipart) once, then applies method spoofing. */\n load(): Promise<this> {\n return (this.#loading ??= this.#load())\n }\n\n async #load(): Promise<this> {\n const method = this.raw.method.toUpperCase()\n if (method !== 'GET' && method !== 'HEAD' && this.raw.body !== null) {\n const type = (this.raw.headers.get('content-type') ?? '').toLowerCase()\n const isJson = type.includes('/json') || type.includes('+json')\n const isUrlencoded = type.startsWith('application/x-www-form-urlencoded')\n const isMultipart = type.startsWith('multipart/form-data')\n if (isJson || isUrlencoded || isMultipart) {\n // Size (413) and depth (400) errors must reach the caller; only a malformed body reads as empty input, as in Laravel.\n const bytes = await readBody(this.raw, this.#maxBodySize)\n if (isJson && this.#maxJsonDepth !== null && exceedsJsonDepth(new TextDecoder().decode(bytes), this.#maxJsonDepth)) {\n throw new HttpException(400, 'The request body is nested too deeply.')\n }\n try {\n if (isJson) {\n this.#content = new TextDecoder().decode(bytes)\n this.#body = this.#parseJson(this.#content)\n } else if (isUrlencoded) {\n this.#content = new TextDecoder().decode(bytes)\n this.#body = fromEntries(new URLSearchParams(this.#content).entries())\n } else {\n await this.#parseForm(await new Response(bytes as Uint8Array<ArrayBuffer>, { headers: { 'content-type': this.raw.headers.get('content-type') ?? '' } }).formData())\n }\n } catch {\n // A malformed body reads as empty input, as in Laravel.\n }\n }\n }\n if (method === 'POST') {\n const override =\n this.raw.headers.get('x-http-method-override') ?? this.#string(this.#body._method) ?? this.#string(this.#query._method)\n const spoofed = override?.toUpperCase()\n if (spoofed !== undefined && /^[A-Z]+$/.test(spoofed) && !['GET', 'HEAD', 'CONNECT', 'TRACE'].includes(spoofed)) {\n this.#method = spoofed\n }\n }\n return this\n }\n\n #parseJson(text: string): Tree {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n return {}\n }\n if (Array.isArray(parsed)) return sanitize({ ...parsed }) as Tree\n return isPlainObject(parsed) ? (sanitize(parsed) as Tree) : {}\n }\n\n async #parseForm(form: FormData): Promise<void> {\n const fields: Array<[string, unknown]> = []\n const files: Array<[string, unknown]> = []\n for (const [name, value] of form.entries()) {\n if (typeof value === 'string') fields.push([name, value])\n // A file input left empty arrives as filename=\"\" with no bytes (PHP's UPLOAD_ERR_NO_FILE).\n else if (!((value.name ?? '') === '' && value.size === 0)) files.push([name, await FormUploadedFile.fromFile(value)])\n }\n this.#body = fromEntries(fields)\n this.#files = fromEntries(files)\n }\n\n #string(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n }\n\n method(): string {\n return this.#method\n }\n\n isMethod(method: string): boolean {\n return this.#method === method.toUpperCase()\n }\n\n /** The scheme and host, honouring X-Forwarded-Proto/Host from trusted proxies. */\n root(): string {\n const trusted = this.#fromTrustedProxy()\n const proto = trusted ? this.raw.headers.get('x-forwarded-proto')?.split(',')[0]?.trim() : undefined\n const host = trusted ? this.raw.headers.get('x-forwarded-host')?.split(',')[0]?.trim() : undefined\n const scheme = proto === 'https' || proto === 'http' ? proto : this.#url.protocol.slice(0, -1)\n return `${scheme}://${host !== undefined && host !== '' ? host : this.#url.host}`\n }\n\n /** The URL without the query string or a trailing slash. */\n url(): string {\n return `${this.root()}${this.#url.pathname}`.replace(/\\/+$/, '')\n }\n\n fullUrl(): string {\n return this.#url.search === '' ? this.url() : `${this.url()}${this.#url.search}`\n }\n\n /** 'posts/1', or '/' for the root. */\n path(): string {\n const trimmed = this.#url.pathname.replace(/^\\/+|\\/+$/g, '')\n return trimmed === '' ? '/' : trimmed\n }\n\n decodedPath(): string {\n try {\n return decodeURIComponent(this.path())\n } catch {\n return this.path()\n }\n }\n\n secure(): boolean {\n return this.root().startsWith('https:')\n }\n\n /** request.is('admin/*'): wildcard match against the decoded path. */\n is(...patterns: string[]): boolean {\n const path = this.decodedPath()\n return patterns.some((pattern) => {\n const trimmed = pattern.replace(/^\\/+|\\/+$/g, '')\n return Str.is(trimmed === '' ? '/' : trimmed, path)\n })\n }\n\n routeIs(...names: string[]): boolean {\n const name = this.#currentRoute()?.route.getName()\n return name !== undefined && names.some((pattern) => Str.is(pattern, name))\n }\n\n header(name: string): string | undefined\n header(name: string, defaultValue: string): string\n header(name: string, defaultValue?: string): string | undefined {\n return this.raw.headers.get(name) ?? defaultValue\n }\n\n bearerToken(): string | undefined {\n const header = this.header('authorization', '')\n const position = header.toLowerCase().lastIndexOf('bearer ')\n if (position === -1) return undefined\n const token = header.slice(position + 7).split(',')[0]!.trim()\n return token === '' ? undefined : token\n }\n\n userAgent(): string | undefined {\n return this.header('user-agent')\n }\n\n /** The socket address, or the right-most untrusted X-Forwarded-For entry when the socket is a trusted proxy. */\n ip(): string | undefined {\n const socket = clientAddress(this.raw)\n if (socket === undefined) return undefined\n const address = normalizeIp(socket)\n if (!this.#fromTrustedProxy()) return address\n const chain = (this.raw.headers.get('x-forwarded-for') ?? '')\n .split(',')\n .map((entry) => normalizeIp(entry))\n .filter((entry) => entry !== '')\n for (let i = chain.length - 1; i >= 0; i--) if (!ipMatches(chain[i]!, this.#trustedProxies)) return chain[i]\n return chain[0] ?? address\n }\n\n #fromTrustedProxy(): boolean {\n const socket = clientAddress(this.raw)\n return socket !== undefined && this.#trustedProxies.length > 0 && ipMatches(socket, this.#trustedProxies)\n }\n\n ajax(): boolean {\n return this.header('x-requested-with') === 'XMLHttpRequest'\n }\n\n pjax(): boolean {\n return this.header('x-pjax') === 'true'\n }\n\n /** The first Accept type is JSON. */\n wantsJson(): boolean {\n const first = this.header('accept', '').split(',')[0]!.trim()\n return first.includes('/json') || first.includes('+json')\n }\n\n /** Laravel: (ajax and not pjax and accepts anything) or wantsJson. */\n expectsJson(): boolean {\n const first = this.header('accept', '').split(',')[0]!.split(';')[0]!.trim()\n const acceptsAny = first === '' || first === '*/*' || first === '*'\n return (this.ajax() && !this.pjax() && acceptsAny) || this.wantsJson()\n }\n\n /** The raw body text for JSON and urlencoded requests ('' otherwise; the raw stream stays unread for other types). */\n content(): string {\n return this.#content\n }\n\n query<T = unknown>(key?: string, defaultValue?: T): T {\n return Arr.get<T>(this.#query, key, defaultValue)\n }\n\n /** Body wins over the query string (PHP's $body + $query). Files are not input. */\n input<T = unknown>(key?: string, defaultValue?: T): T {\n return Arr.get<T>({ ...this.#query, ...this.#body }, key, defaultValue)\n }\n\n /** Input plus files (array_replace_recursive). */\n all(): Record<string, unknown> {\n return mergeRecursive({ ...this.#query, ...this.#body }, this.#files)\n }\n\n only(...keys: Array<string | string[]>): Record<string, unknown> {\n const all = this.all()\n const out: Tree = {}\n for (const key of keys.flat()) if (Arr.has(all, key)) Arr.set(out, key, Arr.get(all, key))\n return out\n }\n\n except(...keys: Array<string | string[]>): Record<string, unknown> {\n const all = structuredCloneInput(this.all())\n for (const key of keys.flat()) Arr.forget(all, key)\n return all\n }\n\n has(...keys: Array<string | string[]>): boolean {\n const all = this.all()\n return keys.flat().every((key) => Arr.has(all, key))\n }\n\n hasAny(...keys: Array<string | string[]>): boolean {\n const all = this.all()\n return keys.flat().some((key) => Arr.has(all, key))\n }\n\n missing(...keys: Array<string | string[]>): boolean {\n return !this.has(...keys)\n }\n\n filled(key: string): boolean {\n return !isBlank(Arr.get(this.all(), key))\n }\n\n /** Laravel's string(): the input as a Stringable (the default when it is missing or null): request().string('q').trim(). */\n string(key: string, defaultValue = ''): Stringable {\n const value = this.input<unknown>(key)\n return Str.of(value === undefined || value === null ? defaultValue : value)\n }\n\n /** Laravel's str(): string() under its short name. */\n str(key: string, defaultValue = ''): Stringable {\n return this.string(key, defaultValue)\n }\n\n /** PHP's FILTER_VALIDATE_BOOLEAN: '1', 'true', 'on', 'yes' (any case) and true are true. */\n boolean(key: string, defaultValue = false): boolean {\n const value = this.input<unknown>(key)\n if (value === undefined) return defaultValue\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value === 1\n return typeof value === 'string' && TRUE_VALUES.has(value.trim().toLowerCase())\n }\n\n /** PHP's intval: leading digits, else 0. */\n integer(key: string, defaultValue = 0): number {\n const value = this.input<unknown>(key)\n if (value === undefined) return defaultValue\n if (typeof value === 'number') return Number.isFinite(value) ? Math.trunc(value) : 0\n if (typeof value === 'boolean') return value ? 1 : 0\n const parsed = Number.parseInt(String(value).trim(), 10)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n\n /** Adds or replaces top-level body values. */\n merge(values: Record<string, unknown>): this {\n this.#body = { ...this.#body, ...(sanitize(values) as Tree) }\n return this\n }\n\n /** Rewrites every scalar in the query and the body (TrimStrings and ConvertEmptyStringsToNull use this). */\n transformInput(transform: (key: string, value: unknown) => unknown): this {\n this.#query = transformLeaves(this.#query, transform)\n this.#body = transformLeaves(this.#body, transform)\n return this\n }\n\n file(key: string): UploadedFile | undefined {\n const value = Arr.get<unknown>(this.#files, key)\n return value instanceof FormUploadedFile ? value : undefined\n }\n\n hasFile(key: string): boolean {\n const value = Arr.get<unknown>(this.#files, key)\n return value instanceof FormUploadedFile || (Array.isArray(value) && value.some((item) => item instanceof FormUploadedFile))\n }\n\n allFiles(): Record<string, unknown> {\n return { ...this.#files }\n }\n\n cookie(name: string): string | undefined {\n return this.cookies()[name]\n }\n\n cookies(): Record<string, string> {\n if (this.#cookies === undefined) {\n const cookies: Record<string, string> = {}\n for (const part of (this.raw.headers.get('cookie') ?? '').split(';')) {\n const index = part.indexOf('=')\n if (index === -1) continue\n const name = part.slice(0, index).trim()\n if (name === '' || Object.hasOwn(cookies, name)) continue\n let value = part.slice(index + 1).trim()\n if (value.startsWith('\"') && value.endsWith('\"')) value = value.slice(1, -1)\n try {\n cookies[name] = decodeURIComponent(value)\n } catch {\n cookies[name] = value\n }\n }\n this.#cookies = cookies\n }\n return { ...this.#cookies }\n }\n\n /** Replaces the parsed cookies (EncryptCookies calls this after decrypting). */\n setCookies(cookies: Record<string, string>): void {\n this.#cookies = { ...cookies }\n }\n\n /** One route parameter (after model binding), or all of them. */\n route<T = unknown>(key?: string): T {\n const parameters = this.#currentRoute()?.parameters ?? {}\n return (key === undefined ? { ...parameters } : parameters[key]) as T\n }\n\n session(): Session {\n return inject(Session)\n }\n\n /**\n * The signed-in user, through the resolver Auth sets, else the current scope's guard (the default, or `guard`).\n * The guard keeps the user it found, so it is looked up once per request. Undefined for a guest or without auth.\n */\n async user<T = unknown>(guard?: string): Promise<T | undefined> {\n if (this.#userResolver !== undefined) return (await this.#userResolver(guard)) as T | undefined\n const container = currentContainer()\n if (container === undefined || !container.bound(AuthFactory)) return undefined\n return (await container.make(AuthFactory).guard(guard).user()) as T | undefined\n }\n\n setUserResolver(resolver: (guard?: string) => unknown): void {\n this.#userResolver = resolver\n }\n\n /**\n * Validates all() through the ValidationFactory; throws its Validation error on failure. The data is typed from the\n * rules: `validate({ title: 'required|string' })` is `{ title: string }`.\n */\n validate<const R extends Rules>(\n rules: R,\n messages?: Record<string, string>,\n attributes?: Record<string, string>,\n ): Promise<InferValidatedType<R>> {\n return inject(ValidationFactory).make(this.all(), rules, messages, attributes).validated<InferValidatedType<R>>()\n }\n\n #currentRoute() {\n const container = currentContainer()\n return container?.bound(CurrentRoute) ? container.make(CurrentRoute) : undefined\n }\n}\n\n/** A copy deep enough for except() to forget nested keys without touching the request. */\nfunction structuredCloneInput(tree: Tree): Tree {\n const out: Tree = {}\n for (const [key, value] of Object.entries(tree)) {\n out[key] = isPlainObject(value) ? structuredCloneInput(value) : Array.isArray(value) ? [...value] : value\n }\n return out\n}\n","/** Helpers for request input: PHP-style bracket keys, safe cloning (no prototype pollution) and blank checks. */\n\ntype Tree = Record<string, unknown>\n\nconst FORBIDDEN = new Set(['__proto__', 'prototype', 'constructor'])\n\n/** Keys PHP treats as integers: '0', '7', '42' (not '07' or '-1'). */\nconst INTEGER_KEY = /^(?:0|[1-9]\\d*)$/\n\n// Duplicated in Routing's BaseUrlGenerator.ts on purpose: Http, Routing and Pipeline may not import each other.\nexport const isPlainObject = (value: unknown): value is Tree => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const prototype = Object.getPrototypeOf(value) as unknown\n return prototype === Object.prototype || prototype === null\n}\n\n/** 'user[name]' → ['user', 'name']; 'tags[]' → ['tags', '']; a malformed key stays whole. */\nexport function parseBracketKey(name: string): string[] {\n const open = name.indexOf('[')\n if (open <= 0 || !name.endsWith(']')) return [name]\n const segments = [name.slice(0, open)]\n const rest = name.slice(open)\n const matches = rest.match(/\\[[^[\\]]*\\]/g)\n if (matches === null || matches.join('') !== rest) return [name]\n for (const match of matches) segments.push(match.slice(1, -1))\n return segments\n}\n\n/** Objects whose keys are exactly 0..n-1 become arrays, recursively (PHP arrays → JS lists). */\nexport function normalizeLists(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(normalizeLists)\n if (!isPlainObject(value)) return value\n const keys = Object.keys(value)\n const out: Tree = {}\n for (const key of keys) out[key] = normalizeLists(value[key])\n if (keys.length > 0 && keys.every((key, index) => key === String(index))) return keys.map((key) => out[key])\n return out\n}\n\n/**\n * Builds nested input from flat form entries, PHP style: 'user[name]', 'tags[]', 'a[b][]'.\n * Keys containing __proto__/prototype/constructor are dropped.\n */\nexport function fromEntries(entries: Iterable<readonly [string, unknown]>): Tree {\n const root: Tree = {}\n // The next '[]' index per node, kept as PHP does (one past the highest integer key) so appending stays O(1).\n const nextIndex = new WeakMap<Tree, number>()\n for (const [name, value] of entries) {\n const segments = parseBracketKey(name)\n if (segments.some((segment) => FORBIDDEN.has(segment))) continue\n let node = root\n for (let i = 0; i < segments.length; i++) {\n let segment = segments[i]!\n const next = nextIndex.get(node) ?? 0\n if (segment === '') {\n segment = String(next)\n nextIndex.set(node, next + 1)\n } else if (INTEGER_KEY.test(segment) && Number(segment) >= next) {\n nextIndex.set(node, Number(segment) + 1)\n }\n if (i === segments.length - 1) {\n node[segment] = value\n break\n }\n if (!isPlainObject(node[segment])) node[segment] = {}\n node = node[segment] as Tree\n }\n }\n return normalizeLists(root) as Tree\n}\n\n/** Deep copy of parsed JSON without dangerous keys (JSON.parse creates an own \"__proto__\" property). */\nexport function sanitize(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sanitize)\n if (!isPlainObject(value)) return value\n const out: Tree = {}\n for (const [key, item] of Object.entries(value)) if (!FORBIDDEN.has(key)) out[key] = sanitize(item)\n return out\n}\n\n/** array_replace_recursive: `override` wins, nested plain objects merge. */\nexport function mergeRecursive(base: Tree, override: Tree): Tree {\n const out: Tree = { ...base }\n for (const [key, value] of Object.entries(override)) {\n if (FORBIDDEN.has(key)) continue\n const current = out[key]\n out[key] =\n (isPlainObject(current) || Array.isArray(current)) && (isPlainObject(value) || Array.isArray(value))\n ? normalizeLists(mergeRecursive({ ...current } as Tree, { ...value } as Tree))\n : value\n }\n return out\n}\n\n/** Laravel's blank(): null, undefined, whitespace-only strings, and empty arrays/objects. */\nexport function isBlank(value: unknown): boolean {\n if (value === null || value === undefined) return true\n if (typeof value === 'string') return value.trim() === ''\n if (Array.isArray(value)) return value.length === 0\n if (isPlainObject(value)) return Object.keys(value).length === 0\n return false\n}\n\n/** Applies `transform(dottedKey, value)` to every scalar leaf, inside nested objects and lists; the result replaces the leaf. */\nexport function transformLeaves(tree: Tree, transform: (key: string, value: unknown) => unknown, prefix = ''): Tree {\n const out: Tree = {}\n for (const [key, value] of Object.entries(tree)) out[key] = transformValue(`${prefix}${key}`, value, transform)\n return out\n}\n\nfunction transformValue(path: string, value: unknown, transform: (key: string, value: unknown) => unknown): unknown {\n if (Array.isArray(value)) return value.map((item, index) => transformValue(`${path}.${index}`, item, transform))\n if (isPlainObject(value)) return transformLeaves(value, transform, `${path}.`)\n return transform(path, value)\n}\n","import {\n HttpRequest,\n Redirector,\n ResponseFactory,\n UrlGenerator,\n type BodyInit,\n type HeadersInit,\n type RedirectResponse,\n type RouteArguments,\n type RouteName,\n} from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException, HttpResponseException } from './errors'\nimport type { IncomingRequest } from './IncomingRequest'\n\n/**\n * request() → the current request (Laravel's Illuminate\\Http\\Request: the HttpRequest contract plus its extras, such\n * as string()); request('key', default) → its input.\n */\nexport function request(): IncomingRequest\nexport function request<T = unknown>(key: string, defaultValue?: T): T\nexport function request(key?: string, defaultValue?: unknown): unknown {\n const current = inject(HttpRequest)\n return key === undefined ? current : current.input(key, defaultValue)\n}\n\n/** response() → the ResponseFactory; response(content, status, headers) → a Response. */\nexport function response(): ResponseFactory\nexport function response(content: BodyInit | null, status?: number, headers?: HeadersInit): Response\nexport function response(content?: BodyInit | null, status?: number, headers?: HeadersInit): ResponseFactory | Response {\n const factory = inject(ResponseFactory)\n return content === undefined ? factory : factory.make(content, status, headers)\n}\n\n/** The Redirector with its route() typed by the generated route names and their parameters. */\nexport type TypedRedirector = Omit<Redirector, 'route'> & {\n route<N extends RouteName>(name: N, ...args: RouteArguments<N, [status?: number]>): RedirectResponse\n}\n\n/** redirect() → the Redirector; redirect('/path', status) → a RedirectResponse. */\nexport function redirect(): TypedRedirector\nexport function redirect(to: string, status?: number): RedirectResponse\nexport function redirect(to?: string, status?: number): TypedRedirector | RedirectResponse {\n const redirector = inject(Redirector)\n return to === undefined ? redirector : redirector.to(to, status)\n}\n\n/** Redirect to the previous URL (same argument order as Redirector.back()). */\nexport function back(fallback?: string, status?: number): RedirectResponse {\n return inject(Redirector).back(fallback, status)\n}\n\n/** url() → the UrlGenerator; url('/path', query, absolute) → a URL. */\nexport function url(): UrlGenerator\nexport function url(path: string, query?: Record<string, unknown>, absolute?: boolean): string\nexport function url(path?: string, query?: Record<string, unknown>, absolute?: boolean): UrlGenerator | string {\n const generator = inject(UrlGenerator)\n return path === undefined ? generator : generator.to(path, query, absolute)\n}\n\n/**\n * The URL of a named route: route('posts.show', post), route('posts.show', { post, page: 2 }). Once `oriel\n * route:types` has run, the name and the route's parameters are checked.\n */\nexport function route<N extends RouteName>(name: N, ...args: RouteArguments<N>): string {\n const [parameters, absolute] = args as [parameters?: unknown, absolute?: boolean]\n return inject(UrlGenerator).route(name, parameters, absolute)\n}\n\n/** abort(404), abort(403, 'Nope', headers), or abort(response) to send a ready response. */\nexport function abort(status: number | Response, message = '', headers: Record<string, string> = {}): never {\n if (status instanceof Response) throw new HttpResponseException(status)\n throw new HttpException(status, message, headers)\n}\n\nexport function abortIf(condition: unknown, status: number | Response, message = '', headers: Record<string, string> = {}): void {\n if (condition) abort(status, message, headers)\n}\n\nexport function abortUnless(condition: unknown, status: number | Response, message = '', headers: Record<string, string> = {}): void {\n if (!condition) abort(status, message, headers)\n}\n","import { createReadStream } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { basename } from 'node:path'\nimport { Readable } from 'node:stream'\nimport { ViewFactory, type BodyInit, type HeadersInit, type ResponseFactory } from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException } from './errors'\nimport { mimeFromExtension } from './mime'\n\n/** 'attachment; filename=\"report.pdf\"' plus filename* for non-ASCII names (RFC 6266). */\nexport function contentDisposition(type: 'attachment' | 'inline', name: string): string {\n const fallback = name.replace(/[^\\x20-\\x7e]/g, '_').replace(/[\"\\\\]/g, '\\\\$&')\n const header = `${type}; filename=\"${fallback}\"`\n return /^[\\x20-\\x7e]*$/.test(name) ? header : `${header}; filename*=UTF-8''${encodeURIComponent(name)}`\n}\n\n/** Laravel's ResponseFactory (the response() helper). */\nexport class HttpResponseFactory implements ResponseFactory {\n /** Strings default to text/html; charset=utf-8, as in Laravel. */\n make(content: BodyInit | null = null, status = 200, headers?: HeadersInit): Response {\n const merged = new Headers(headers)\n if (typeof content === 'string' && !merged.has('content-type')) merged.set('content-type', 'text/html; charset=utf-8')\n return new Response(content, { status, headers: merged })\n }\n\n json(data: unknown, status = 200, headers?: HeadersInit): Response {\n const merged = new Headers(headers)\n if (!merged.has('content-type')) merged.set('content-type', 'application/json')\n return new Response(JSON.stringify(data === undefined ? null : data), { status, headers: merged })\n }\n\n noContent(status = 204): Response {\n return new Response(null, { status })\n }\n\n /** Renders a view (through the ViewFactory) into an HTML response. */\n async view(name: string, data: Record<string, unknown> = {}, status = 200, headers?: HeadersInit): Promise<Response> {\n const html = await inject(ViewFactory).make(name, data).render()\n return this.make(html, status, headers)\n }\n\n /** Streams a file as an attachment. A missing file is a 404. */\n download(path: string, name = basename(path), headers?: HeadersInit): Promise<Response> {\n return this.#file(path, 'attachment', name, headers)\n }\n\n /** Streams a file for the browser to display (Laravel's response()->file()). */\n file(path: string, headers?: HeadersInit): Promise<Response> {\n return this.#file(path, 'inline', basename(path), headers)\n }\n\n stream(body: ReadableStream, status = 200, headers?: HeadersInit): Response {\n return new Response(body, { status, headers })\n }\n\n async #file(path: string, disposition: 'attachment' | 'inline', name: string, headers?: HeadersInit): Promise<Response> {\n const info = await stat(path).catch(() => undefined)\n // No file path in the message: HTTP error messages are shown to clients.\n if (info === undefined || !info.isFile()) throw new HttpException(404)\n const merged = new Headers(headers)\n if (!merged.has('content-type')) merged.set('content-type', mimeFromExtension(name))\n merged.set('content-length', String(info.size))\n merged.set('content-disposition', contentDisposition(disposition, name))\n const body = Readable.toWeb(createReadStream(path)) as ReadableStream<Uint8Array>\n return new Response(body, { status: 200, headers: merged })\n }\n}\n","import {\n ConfigRepository,\n CurrentRoute,\n ExceptionHandler,\n HttpRequest,\n PipelineFactory,\n Router,\n type Application,\n type Container,\n type HttpKernel,\n type Middleware,\n type MiddlewareClass,\n} from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\nimport { HttpServerError } from './errors'\nimport { IncomingRequest } from './IncomingRequest'\nimport { ConvertEmptyStringsToNull } from './middleware/ConvertEmptyStringsToNull'\nimport { TrimStrings } from './middleware/TrimStrings'\n\ninterface RequestState {\n readonly scope: Container\n readonly request: IncomingRequest\n readonly middleware: Middleware[]\n}\n\n/** The plain-text 500 the kernel falls back to. Exported so the server adapters can reuse it. */\nexport const plainServerError = (): Response =>\n new Response('Server Error', { status: 500, headers: { 'content-type': 'text/plain; charset=utf-8' } })\n\n/**\n * Laravel's Http Kernel: wraps the raw Request, binds it in the request scope, loads the body, then sends it through\n * the global middleware to the router. Every stage renders its own errors through the ExceptionHandler.\n */\nexport class Kernel implements HttpKernel {\n #middleware: MiddlewareClass[] = [TrimStrings, ConvertEmptyStringsToNull]\n readonly #requests = new WeakMap<Request, RequestState>()\n\n constructor(protected readonly app: Application) {}\n\n getGlobalMiddleware(): MiddlewareClass[] {\n return [...this.#middleware]\n }\n\n setGlobalMiddleware(middleware: MiddlewareClass[]): this {\n this.#middleware = [...middleware]\n return this\n }\n\n appendMiddleware(...middleware: MiddlewareClass[]): this {\n for (const cls of middleware) if (!this.#middleware.includes(cls)) this.#middleware.push(cls)\n return this\n }\n\n prependMiddleware(...middleware: MiddlewareClass[]): this {\n for (const cls of [...middleware].reverse()) if (!this.#middleware.includes(cls)) this.#middleware.unshift(cls)\n return this\n }\n\n hasMiddleware(middleware: MiddlewareClass): boolean {\n return this.#middleware.includes(middleware)\n }\n\n /** Runs in the current request scope (Application.handle() opens one); called directly, it opens its own. */\n handle(raw: Request): Promise<Response> {\n const current = currentContainer()\n const scope = current !== undefined && current !== this.app ? current : this.app.createScope()\n return scope.run(() => this.#handle(raw, scope))\n }\n\n async #handle(raw: Request, scope: Container): Promise<Response> {\n let request: IncomingRequest | undefined\n let response: Response\n try {\n request = new IncomingRequest(raw, {\n trustedProxies: this.#trustedProxies(),\n maxBodySize: this.#maxBodySize(),\n maxJsonDepth: this.#maxJsonDepth(),\n })\n scope.instance(HttpRequest, request)\n const state: RequestState = { scope, request, middleware: [] }\n this.#requests.set(raw, state)\n await request.load()\n response = await this.#sendThroughGlobal(state)\n } catch (error) {\n request ??= this.#bareRequest(scope, raw)\n if (request !== undefined) {\n response = await this.#renderLast(scope, request, error)\n } else {\n await this.#report(scope, error)\n response = plainServerError()\n }\n }\n // HEAD: same status and headers as GET, no body. Cancel the dropped body so an open file stream is released.\n if (raw.method.toUpperCase() === 'HEAD' && response.body !== null) {\n await response.body.cancel().catch(() => undefined)\n response = new Response(null, { status: response.status, statusText: response.statusText, headers: response.headers })\n }\n return response\n }\n\n /** The request without options, for rendering an error raised while the real one was being built. */\n #bareRequest(scope: Container, raw: Request): IncomingRequest | undefined {\n try {\n const request = new IncomingRequest(raw)\n scope.instance(HttpRequest, request)\n return request\n } catch {\n return undefined\n }\n }\n\n /** Runs terminate() on the global and route middleware (inside the request's scope), then Application.terminate(), inside the same scope, so terminating callbacks see the request's bindings. */\n async terminate(raw: Request, response: Response): Promise<void> {\n const state = this.#requests.get(raw)\n if (state !== undefined) {\n this.#requests.delete(raw)\n await state.scope.run(async () => {\n const route = state.scope.bound(CurrentRoute) ? state.scope.make(CurrentRoute).middleware : []\n for (const middleware of [...state.middleware, ...route]) {\n if (typeof middleware.terminate !== 'function') continue\n try {\n await middleware.terminate(state.request, response)\n } catch (error) {\n await this.#report(state.scope, error)\n }\n }\n await this.app.terminate()\n })\n return\n }\n await this.app.terminate()\n }\n\n #sendThroughGlobal(state: RequestState): Promise<Response> {\n const { scope, request } = state\n const pipes = this.#middleware.map((cls) => {\n const instance = scope.make(cls)\n state.middleware.push(instance)\n return (passable: HttpRequest, next: (passable: HttpRequest) => Promise<unknown>) =>\n this.#guard(scope, passable, () => instance.handle(passable, next as (r: HttpRequest) => Promise<Response>))\n })\n return scope\n .make(PipelineFactory)\n .make<HttpRequest>()\n .send(request)\n .through(pipes)\n .then((passable) => this.#guard(scope, passable, () => this.#dispatch(scope, passable)))\n }\n\n #dispatch(scope: Container, request: HttpRequest): Promise<Response> {\n return scope.make(Router).dispatch(request)\n }\n\n /** Converts a Responsable result, and renders a thrown error at this stage (Laravel's Routing\\Pipeline). */\n async #guard(scope: Container, request: HttpRequest, run: () => Promise<unknown>): Promise<Response> {\n try {\n const result = await run()\n if (result instanceof Response) return result\n const responsable = result as { toResponse?: (request: unknown) => Response | Promise<Response> } | null\n if (typeof responsable?.toResponse === 'function') return await responsable.toResponse(request)\n throw new HttpServerError('Middleware must return a Response.')\n } catch (error) {\n if (!scope.bound(ExceptionHandler)) throw error\n const handler = scope.make(ExceptionHandler)\n await handler.report(error)\n return handler.render(request, error)\n }\n }\n\n /** Last resort: the handler failed or isn't bound. Never throws. */\n async #renderLast(scope: Container, request: HttpRequest, error: unknown): Promise<Response> {\n if (scope.bound(ExceptionHandler)) {\n try {\n const handler = scope.make(ExceptionHandler)\n await handler.report(error)\n return await handler.render(request, error)\n } catch (renderError) {\n console.error(renderError)\n }\n } else {\n console.error(error)\n }\n return plainServerError()\n }\n\n async #report(scope: Container, error: unknown): Promise<void> {\n try {\n if (scope.bound(ExceptionHandler)) await scope.make(ExceptionHandler).report(error)\n else console.error(error)\n } catch (reportError) {\n console.error(reportError)\n }\n }\n\n /** config('http.max_body_size'): bytes, or null for no limit. Anything else is a configuration error. */\n #maxBodySize(): number | null {\n if (!this.app.bound(ConfigRepository)) return 8 * 1024 * 1024\n const value = this.app.make(ConfigRepository).get<unknown>('http.max_body_size', 8 * 1024 * 1024)\n if (value === null) return null\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value\n throw new HttpServerError(\n `Invalid http.max_body_size ${JSON.stringify(value) ?? String(value)}: use a number of bytes (0 or more), or null for no limit.`,\n )\n }\n\n /** config('http.max_json_depth'): how deep a JSON body may nest, or null for no limit. */\n #maxJsonDepth(): number | null {\n if (!this.app.bound(ConfigRepository)) return 512\n const value = this.app.make(ConfigRepository).get<unknown>('http.max_json_depth', 512)\n if (value === null) return null\n if (typeof value === 'number' && Number.isInteger(value) && value >= 1) return value\n throw new HttpServerError(\n `Invalid http.max_json_depth ${JSON.stringify(value) ?? String(value)}: use a whole number (1 or more), or null for no limit.`,\n )\n }\n\n /** config('http.trusted_proxies'): an array, or a comma-separated string such as '*' or '10.0.0.0/8,::1'. */\n #trustedProxies(): string[] {\n if (!this.app.bound(ConfigRepository)) return []\n const value = this.app.make(ConfigRepository).get<unknown>('http.trusted_proxies', [])\n if (typeof value === 'string') return value.split(',').map((entry) => entry.trim()).filter((entry) => entry !== '')\n return Array.isArray(value) ? value.map(String) : []\n }\n}\n","import type { HttpRequest, Middleware, Next } from '@orieljs/contracts'\nimport { IncomingRequest } from '../IncomingRequest'\n\n/** '' becomes null in the query and body, so `nullable` validation behaves as in Laravel. */\nexport class ConvertEmptyStringsToNull implements Middleware {\n async handle(request: HttpRequest, next: Next): Promise<Response> {\n if (request instanceof IncomingRequest) request.transformInput((_key, value) => (value === '' ? null : value))\n return next(request)\n }\n}\n","import type { HttpRequest, Middleware, Next } from '@orieljs/contracts'\nimport { IncomingRequest } from '../IncomingRequest'\n\n/** Laravel's trim: whitespace plus BOM, zero-width space and left-to-right mark. */\nconst TRIM = /^[\\s\\uFEFF\\u200B\\u200E]+|[\\s\\uFEFF\\u200B\\u200E]+$/g\n\n/** Trims every string in the query and body, except password fields (Laravel's TrimStrings). */\nexport class TrimStrings implements Middleware {\n /** Dotted input keys left untouched. Override in a subclass to change. */\n protected except: string[] = ['current_password', 'password', 'password_confirmation']\n\n async handle(request: HttpRequest, next: Next): Promise<Response> {\n if (request instanceof IncomingRequest) {\n request.transformInput((key, value) =>\n typeof value === 'string' && !this.except.includes(key) ? value.replace(TRIM, '') : value,\n )\n }\n return next(request)\n }\n}\n","import {\n ConfigRepository,\n MiddlewareCallbacks,\n Router,\n type Application,\n type HttpRequest,\n type MiddlewareClass,\n type MiddlewareConfigurator,\n type MiddlewareReference,\n} from '@orieljs/contracts'\nimport type { Kernel } from './Kernel'\n\ninterface GroupOptions {\n append?: MiddlewareClass[]\n prepend?: MiddlewareClass[]\n remove?: MiddlewareClass[]\n}\n\n/** The `m` in withMiddleware((m) => …): edits the kernel's global middleware and the router's groups and aliases. */\nexport class MiddlewareConfiguration implements MiddlewareConfigurator {\n constructor(\n private readonly kernel: Kernel,\n private readonly router: Router,\n private readonly config?: ConfigRepository,\n ) {}\n\n append(...middleware: MiddlewareClass[]): this {\n this.kernel.appendMiddleware(...middleware)\n return this\n }\n\n prepend(...middleware: MiddlewareClass[]): this {\n this.kernel.prependMiddleware(...middleware)\n return this\n }\n\n web(options: GroupOptions): this {\n return this.#modifyGroup('web', options)\n }\n\n api(options: GroupOptions): this {\n return this.#modifyGroup('api', options)\n }\n\n alias(aliases: Record<string, MiddlewareClass>): this {\n for (const [name, middleware] of Object.entries(aliases)) this.router.aliasMiddleware(name, middleware)\n return this\n }\n\n group(name: string, middleware: Array<MiddlewareClass | string>): this {\n this.router.middlewareGroup(name, middleware)\n return this\n }\n\n /** Stored in config('http.csrf_except'), which the Session component's VerifyCsrfToken reads. */\n validateCsrfTokens(options: { except: string[] }): this {\n const current = this.config?.get<string[]>('http.csrf_except', []) ?? []\n this.config?.set('http.csrf_except', [...current, ...options.except])\n return this\n }\n\n /** Stored in config('http.redirect_guests_to'), which the Auth middleware and the exception handler read. */\n redirectGuestsTo(url: string | ((request: HttpRequest) => string)): this {\n this.config?.set('http.redirect_guests_to', url)\n return this\n }\n\n /** Laravel 11's redirectUsersTo(): stored in config('http.redirect_users_to') for Auth's RedirectIfAuthenticated. */\n redirectUsersTo(url: string | ((request: HttpRequest) => string)): this {\n this.config?.set('http.redirect_users_to', url)\n return this\n }\n\n /** Laravel's order: prepends, then the group minus removals, then appends. */\n #modifyGroup(name: string, { append = [], prepend = [], remove = [] }: GroupOptions): this {\n const current: MiddlewareReference[] = this.router.getMiddlewareGroups()[name] ?? []\n const moved = new Set<MiddlewareReference>([...append, ...prepend, ...remove])\n this.router.middlewareGroup(name, [...prepend, ...current.filter((entry) => !moved.has(entry)), ...append])\n return this\n }\n}\n\n/** Runs the withMiddleware() callbacks collected by the ApplicationBuilder (HttpServiceProvider calls this once booted). */\nexport function applyMiddlewareCallbacks(app: Application, kernel: Kernel): void {\n if (!app.bound(MiddlewareCallbacks)) return\n const callbacks = app.make(MiddlewareCallbacks) as Array<(configurator: MiddlewareConfigurator) => void>\n if (callbacks.length === 0) return\n const config = app.bound(ConfigRepository) ? app.make(ConfigRepository) : undefined\n const configurator = new MiddlewareConfiguration(kernel, app.make(Router), config)\n for (const callback of callbacks) callback(configurator)\n}\n","import {\n ConfigRepository,\n LogManager,\n Redirector,\n UrlGenerator,\n ViewFactory,\n type Application,\n type AuthenticationError,\n type Container,\n type ErrorKind,\n type ExceptionHandler,\n type HttpRequest,\n type OrielError,\n type ValidationError,\n} from '@orieljs/contracts'\nimport { currentContainer } from '@orieljs/container'\nimport { debugPage, minimalPage, stackFrames, statusText } from './errorPages'\nimport { HttpResponseException } from './errors'\nimport { IncomingRequest } from './IncomingRequest'\n\nexport type ReportCallback = (error: unknown) => void | boolean | Promise<void | boolean>\nexport type RenderCallback = (error: unknown, request: unknown) => Response | undefined | Promise<Response | undefined>\nexport type ErrorClass = abstract new (...args: never[]) => Error\nexport type JsonWhenCallback = (request: HttpRequest, error: unknown) => boolean\n\n/** Laravel's $internalDontReport: expected errors that are rendered, never logged ('Server' is not here). */\nconst NOT_REPORTED = new Set<ErrorKind>(['Http', 'ModelNotFound', 'Validation', 'Authentication', 'Authorization', 'TokenMismatch'])\n/** Kinds whose message is safe to show to users, at any status (Laravel's HttpException rendering). */\nconst HTTP_KINDS = new Set<ErrorKind>(['Http', 'ModelNotFound', 'Authorization', 'TokenMismatch'])\n\nconst kindOf = (error: unknown): ErrorKind | undefined =>\n typeof error === 'object' && error !== null && typeof (error as OrielError).kind === 'string' ? (error as OrielError).kind : undefined\n\n/** HTTP status for an error (spec §7). */\nexport function statusFor(error: unknown): number {\n const status = (error as Partial<OrielError> | null)?.status\n switch (kindOf(error)) {\n case 'Http':\n return status ?? 500\n case 'ModelNotFound':\n return 404\n case 'Authorization':\n return status ?? 403\n case 'TokenMismatch':\n return 419\n case 'Authentication':\n return 401\n case 'Validation':\n return status ?? 422\n case 'Server':\n return status ?? 500\n default:\n return 500\n }\n}\n\n/** \"The title field is required. (and 2 more errors)\" (Laravel's ValidationException::summarize). */\nexport function summarizeValidation(errors: Record<string, string[]>): string {\n const messages = Object.values(errors).flat()\n if (messages.length === 0) return 'The given data was invalid.'\n const more = messages.length - 1\n return more === 0 ? messages[0]! : `${messages[0]!} (and ${more} more ${more === 1 ? 'error' : 'errors'})`\n}\n\n/** An HTTP-like error: its message may be shown and it doesn't get the debug page. */\nconst isHttpLike = (error: unknown): boolean => {\n const kind = kindOf(error)\n return kind !== undefined && HTTP_KINDS.has(kind)\n}\n\n/** The exception handler (spec §7): report through the LogManager, render by error kind. */\nexport class ErrorHandler implements ExceptionHandler {\n /** Input keys never flashed back on a validation redirect. */\n protected dontFlash = ['current_password', 'password', 'password_confirmation']\n readonly #reportCallbacks: ReportCallback[] = []\n readonly #renderCallbacks: RenderCallback[] = []\n readonly #dontReport: ErrorClass[] = []\n readonly #reported = new WeakSet<object>()\n #jsonWhen: JsonWhenCallback | undefined\n\n constructor(protected readonly app: Application) {}\n\n reportUsing(callback: ReportCallback): void {\n this.#reportCallbacks.push(callback)\n }\n\n renderUsing(callback: RenderCallback): void {\n this.#renderCallbacks.push(callback)\n }\n\n ignore(...classes: ErrorClass[]): void {\n this.#dontReport.push(...classes)\n }\n\n /** Laravel's shouldRenderJsonWhen(): the callback decides JSON or HTML instead of the Accept header. */\n shouldRenderJsonWhen(callback: JsonWhenCallback): void {\n this.#jsonWhen = callback\n }\n\n /** Laravel's shouldReturnJson(): the shouldRenderJsonWhen() callback when set, else request.expectsJson(). */\n protected shouldReturnJson(request: HttpRequest, error: unknown): boolean {\n return this.#jsonWhen !== undefined ? this.#jsonWhen(request, error) : request.expectsJson()\n }\n\n shouldReport(error: unknown): boolean {\n const kind = kindOf(error)\n if (kind !== undefined && NOT_REPORTED.has(kind)) return false\n return !this.#dontReport.some((cls) => error instanceof cls)\n }\n\n /** Report callbacks first (returning false stops the default log), then LogManager.error(), else console.error. Once per error. */\n async report(error: unknown): Promise<void> {\n if (!this.shouldReport(error)) return\n if (typeof error === 'object' && error !== null) {\n if (this.#reported.has(error)) return\n this.#reported.add(error)\n }\n try {\n for (const callback of this.#reportCallbacks) if ((await callback(error)) === false) return\n const container = this.#container()\n if (container.bound(LogManager)) {\n const message = error instanceof Error ? error.message : String(error)\n container.make(LogManager).error(message, { exception: error })\n } else {\n console.error(error)\n }\n } catch (reportError) {\n console.error(reportError)\n }\n }\n\n async render(request: unknown, error: unknown): Promise<Response> {\n for (const callback of this.#renderCallbacks) {\n const response = await callback(error, request)\n if (response instanceof Response) return response\n }\n if (error instanceof HttpResponseException) return error.response\n const custom = await this.#renderCustom(request, error)\n if (custom !== undefined) return custom\n\n const http = this.#httpRequest(request)\n const kind = kindOf(error)\n let response: Response\n if (kind === 'Validation') response = await this.#renderValidation(http, error as ValidationError)\n else if (kind === 'Authentication') response = await this.#renderAuthentication(http, error as AuthenticationError)\n else if (this.shouldReturnJson(http, error)) response = this.#renderJson(error)\n else response = await this.#renderHtml(http, error)\n\n const headers = (error as Partial<OrielError> | null)?.headers\n return headers === undefined ? response : withHeaders(response, headers)\n }\n\n /** An error with its own render(request) or toResponse(request) (Laravel's renderable exceptions / Responsable). */\n async #renderCustom(request: unknown, error: unknown): Promise<Response | undefined> {\n if (typeof error !== 'object' || error === null) return undefined\n const candidate = error as { render?: (request: unknown) => unknown; toResponse?: (request: unknown) => unknown }\n for (const method of [candidate.render, candidate.toResponse]) {\n if (typeof method !== 'function') continue\n const response = await method.call(error, request)\n if (response instanceof Response) return response\n }\n return undefined\n }\n\n async #renderValidation(request: HttpRequest, error: ValidationError): Promise<Response> {\n if (this.shouldReturnJson(request, error)) {\n return this.#json({ message: summarizeValidation(error.errors), errors: error.errors }, statusFor(error))\n }\n const input = { ...request.input<Record<string, unknown>>() }\n for (const key of this.dontFlash) delete input[key]\n const container = this.#container()\n if (!container.bound(Redirector)) {\n return this.#redirect(error.redirectTo ?? request.header('referer') ?? '/')\n }\n const redirector = container.make(Redirector)\n const redirect = error.redirectTo !== undefined ? redirector.to(error.redirectTo) : redirector.back()\n // toResponse(request) may return a Promise per the Responsable contract; await it.\n const response = await redirect.withInput(input).withErrors(error.errors, error.errorBag).toResponse(request)\n return response\n }\n\n async #renderAuthentication(request: HttpRequest, error: AuthenticationError): Promise<Response> {\n if (this.shouldReturnJson(request, error)) return this.#json({ message: error.message || 'Unauthenticated.' }, 401)\n const target = error.redirectTo ?? this.#guestRedirect(request)\n const container = this.#container()\n if (!container.bound(Redirector)) return this.#redirect(target)\n const redirector = container.make(Redirector) as Redirector & { guest?: (path: string) => { toResponse(r: unknown): unknown } }\n const redirect = typeof redirector.guest === 'function' ? redirector.guest(target) : redirector.to(target)\n // toResponse(request) may return a Promise per the Responsable contract; await it.\n return (await redirect.toResponse(request)) as Response\n }\n\n /** config('http.redirect_guests_to'), then route('login'), then '/login'. */\n #guestRedirect(request: HttpRequest): string {\n const configured = this.#config<unknown>('http.redirect_guests_to', undefined)\n if (typeof configured === 'function') return String((configured as (request: HttpRequest) => string)(request))\n if (typeof configured === 'string' && configured !== '') return configured\n const container = this.#container()\n if (container.bound(UrlGenerator)) {\n const url = container.make(UrlGenerator)\n if (url.hasRoute('login')) return url.route('login')\n }\n return '/login'\n }\n\n #renderJson(error: unknown): Response {\n const status = statusFor(error)\n if (isHttpLike(error)) {\n const message = error instanceof Error && error.message !== '' ? error.message : statusText(status)\n return this.#json({ message }, status)\n }\n if (!this.#debug()) return this.#json({ message: 'Server Error' }, status)\n const err = error instanceof Error ? error : new Error(String(error))\n const [frame] = stackFrames(err)\n return this.#json(\n {\n message: err.message,\n exception: err.name,\n file: frame?.file,\n line: frame?.line,\n trace: stackFrames(err).map((entry) => entry.text),\n },\n status,\n )\n }\n\n async #renderHtml(request: HttpRequest, error: unknown): Promise<Response> {\n const status = statusFor(error)\n if (!isHttpLike(error) && this.#debug()) {\n return this.#html(await debugPage(error, request.method(), request.fullUrl()), status)\n }\n const message = status === 403 && error instanceof Error && error.message !== '' ? error.message : statusText(status)\n const view = await this.#errorView(status, error, message)\n return this.#html(view ?? minimalPage(status, message), status)\n }\n\n /** resources/views/errors/{status}.tsx, then errors/4xx or errors/5xx, through the ViewFactory. */\n async #errorView(status: number, error: unknown, message: string): Promise<string | undefined> {\n const container = this.#container()\n if (!container.bound(ViewFactory)) return undefined\n const views = container.make(ViewFactory)\n for (const name of [`errors.${status}`, `errors.${Math.floor(status / 100)}xx`]) {\n if (!views.exists(name)) continue\n try {\n return await views.make(name, { exception: error, status, message }).render()\n } catch (viewError) {\n await this.report(viewError)\n return undefined\n }\n }\n return undefined\n }\n\n #httpRequest(request: unknown): HttpRequest {\n if (typeof request === 'object' && request !== null && typeof (request as HttpRequest).expectsJson === 'function') {\n return request as HttpRequest\n }\n return new IncomingRequest(request instanceof Request ? request : new Request('http://localhost/'))\n }\n\n #json(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } })\n }\n\n #html(body: string, status: number): Response {\n return new Response(body, { status, headers: { 'content-type': 'text/html; charset=utf-8' } })\n }\n\n #redirect(location: string): Response {\n return new Response(null, { status: 302, headers: { Location: location } })\n }\n\n #debug(): boolean {\n return this.#config<unknown>('app.debug', false) === true\n }\n\n #config<T>(key: string, fallback: T): T {\n return this.app.bound(ConfigRepository) ? this.app.make(ConfigRepository).get<T>(key, fallback) : fallback\n }\n\n /** The request scope while handling a request (so scoped services resolve), else the application. */\n #container(): Container {\n return currentContainer() ?? this.app\n }\n}\n\n/**\n * A copy of `response` with the headers added. The rendered response's own headers may be immutable (a fetch() or\n * Response.redirect() response), so they are never set in place.\n */\nfunction withHeaders(response: Response, extra: Record<string, string>): Response {\n const headers = new Headers(response.headers)\n for (const [name, value] of Object.entries(extra)) headers.set(name, value)\n return new Response(response.body, { status: response.status, statusText: response.statusText, headers })\n}\n","import { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nconst STATUS_TEXTS: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Content Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a teapot\",\n 419: 'Page Expired',\n 421: 'Misdirected Request',\n 422: 'Unprocessable Content',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n}\n\n/**\n * The text an error page shows for a status: Laravel's own wording where it has a view (\"Server Error\", \"Page\n * Expired\"), else Symfony's `Response::$statusTexts`, which Laravel shows for the others.\n */\nexport function statusText(status: number): string {\n return STATUS_TEXTS[status] ?? (status >= 500 ? 'Server Error' : 'Error')\n}\n\nexport function escapeHtml(value: string): string {\n return value.replace(/[&<>\"']/g, (char) => `&#${char.charCodeAt(0)};`)\n}\n\n/** Laravel's minimal error page: \"404 | Not Found\". */\nexport function minimalPage(status: number, message: string): string {\n const title = escapeHtml(message)\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${title}</title>\n<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f7fafc;color:#1a202c;display:flex;align-items:center;justify-content:center;min-height:100vh}.code{padding:0 1rem;border-right:1px solid #a0aec0;font-size:1.125rem}.message{padding:0 1rem;font-size:1.125rem;text-transform:uppercase;letter-spacing:.05em}</style>\n</head>\n<body><div class=\"code\">${status}</div><div class=\"message\">${title}</div></body>\n</html>`\n}\n\nexport interface StackFrame {\n readonly file: string\n readonly line: number\n readonly column: number\n readonly text: string\n}\n\n/** Parses V8/JavaScriptCore stack lines into frames that point at files. */\nexport function stackFrames(error: Error): StackFrame[] {\n const frames: StackFrame[] = []\n for (const raw of (error.stack ?? '').split('\\n').slice(1)) {\n const text = raw.trim()\n const match = /(?:\\(|@|at )((?:file:\\/\\/)?(?:\\/|[A-Za-z]:\\\\)[^()]*?):(\\d+):(\\d+)\\)?$/.exec(text)\n if (match === null) continue\n const location = match[1]!\n const file = location.startsWith('file://') ? fileURLToPath(location) : location\n frames.push({ file, line: Number(match[2]), column: Number(match[3]), text })\n }\n return frames\n}\n\n/** Up to `radius` lines either side of the frame's line, or undefined when the file can't be read. */\nasync function excerpt(frame: StackFrame, radius = 5): Promise<string | undefined> {\n const source = await readFile(frame.file, 'utf8').catch(() => undefined)\n if (source === undefined) return undefined\n const lines = source.split('\\n')\n const start = Math.max(1, frame.line - radius)\n const end = Math.min(lines.length, frame.line + radius)\n const rows: string[] = []\n for (let number = start; number <= end; number++) {\n const current = number === frame.line ? ' class=\"current\"' : ''\n rows.push(`<tr${current}><td class=\"n\">${number}</td><td><code>${escapeHtml(lines[number - 1] ?? '')}</code></td></tr>`)\n }\n return `<table class=\"source\">${rows.join('')}</table>`\n}\n\n/** The APP_DEBUG page: class, message, request, a source excerpt of the first app frame, the stack and causes. */\nexport async function debugPage(error: unknown, method: string, url: string): Promise<string> {\n const err = error instanceof Error ? error : new Error(String(error))\n const frames = stackFrames(err)\n const appFrame = frames.find((frame) => !frame.file.includes('node_modules') && !frame.file.startsWith('node:')) ?? frames[0]\n const source = appFrame === undefined ? undefined : await excerpt(appFrame)\n const causes: string[] = []\n for (let cause = err.cause, depth = 0; cause !== undefined && depth < 5; cause = (cause as Error).cause, depth++) {\n causes.push(`<li>${escapeHtml(cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause))}</li>`)\n }\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>${escapeHtml(err.message || err.name)}</title>\n<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f3f4f6;color:#111827}main{max-width:1100px;margin:2rem auto;padding:0 1rem}header{background:#fff;border-radius:.5rem;padding:1.5rem;box-shadow:0 1px 3px #0001}.class{color:#dc2626;font-weight:600}.message{font-size:1.5rem;margin:.5rem 0}.request{color:#6b7280}section{background:#fff;border-radius:.5rem;padding:1rem;margin-top:1rem;box-shadow:0 1px 3px #0001;overflow:auto}.source td{padding:0 .5rem;white-space:pre;font-size:.85rem}.source .n{color:#9ca3af;text-align:right}.source .current{background:#fee2e2}ol{font-family:ui-monospace,monospace;font-size:.85rem}</style>\n</head>\n<body><main>\n<header><div class=\"class\">${escapeHtml(err.name)}</div><div class=\"message\">${escapeHtml(err.message)}</div><div class=\"request\">${escapeHtml(method)} ${escapeHtml(url)}</div></header>\n${appFrame === undefined ? '' : `<section><div>${escapeHtml(appFrame.file)}:${appFrame.line}</div>${source ?? ''}</section>`}\n<section><ol>${frames.map((frame) => `<li>${escapeHtml(frame.text)}</li>`).join('')}</ol></section>\n${causes.length === 0 ? '' : `<section><div>Caused by</div><ul>${causes.join('')}</ul></section>`}\n</main></body>\n</html>`\n}\n","import { ExceptionCallbacks, type Application, type ExceptionsConfigurator, type HttpRequest } from '@orieljs/contracts'\nimport type { ErrorClass, ErrorHandler, RenderCallback, ReportCallback } from './ErrorHandler'\n\n/** The `e` in withExceptions((e) => …). */\nexport class ExceptionsConfiguration implements ExceptionsConfigurator {\n constructor(private readonly handler: ErrorHandler) {}\n\n report(callback: ReportCallback): this {\n this.handler.reportUsing(callback)\n return this\n }\n\n render(callback: RenderCallback): this {\n this.handler.renderUsing(callback)\n return this\n }\n\n dontReport(...classes: ErrorClass[]): this {\n this.handler.ignore(...classes)\n return this\n }\n\n /** shouldRenderJsonWhen((request) => request.is('api/*')): JSON errors for those requests, whatever they accept. */\n shouldRenderJsonWhen(callback: (request: HttpRequest, error: unknown) => boolean): this {\n this.handler.shouldRenderJsonWhen(callback)\n return this\n }\n}\n\n/** Runs the withExceptions() callbacks against a handler (the provider does this when the handler is built). */\nexport function applyExceptionCallbacks(app: Application, handler: ErrorHandler): void {\n if (!app.bound(ExceptionCallbacks)) return\n const configurator = new ExceptionsConfiguration(handler)\n for (const callback of app.make(ExceptionCallbacks)) callback(configurator)\n}\n","import { existsSync, lstatSync, readdirSync, statSync } from 'node:fs'\nimport { cp, mkdir, mkdtemp, rename, rm, writeFile } from 'node:fs/promises'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport type { Application } from '@orieljs/contracts'\nimport { handleSafely, terminateRequest } from '../server/types'\nimport { exportFileName, sameSiteLinks, sitePath } from './paths'\n\nexport interface ExportOptions {\n /** The folder the site is written to. */\n output: string\n /** The URL the pages are requested at (the app's `app.url`); only its origin's links are followed. */\n baseUrl: string\n /** Follow every same-site link from `/` (and from `paths`). */\n crawl: boolean\n /** Paths exported besides `/` (pages nothing links to, a feed, …). */\n paths: string[]\n /** Paths left out; `*` matches anything (`/drafts/*`). */\n exclude: string[]\n /** `/docs/routing` → `docs/routing.html` (`'html'`) or `docs/routing/index.html` (`'directory'`). */\n fileNames: 'html' | 'directory'\n /** Copied into the output first (the built assets, images); false copies nothing. */\n publicPath: string | false\n}\n\nexport interface ExportResult {\n /** The paths written, in the order they were found. */\n pages: string[]\n /** Redirects met while following links: listed, not written. */\n redirects: Array<{ path: string; location: string }>\n /** Whether the app's 404 page was written as `404.html`. */\n notFoundPage: boolean\n}\n\n/** A page answered with an error: the export stops, and the last export stays as it was. */\nexport class ExportError extends Error {\n override readonly name = 'ExportError'\n\n constructor(\n readonly path: string,\n readonly status: number,\n ) {\n super(`[${path}] answered ${status}.`)\n }\n}\n\n/** The file that marks a folder as made by the export, so the next export may replace it. */\nconst MARKER = '.oriel-export'\n\n/** A path nothing routes to, for the app's 404 page. */\nconst NOT_FOUND_PATH = '/__oriel-export-not-found__'\n\n/**\n * Exports an app's pages as files: requests `/` and `paths` inside the process (as `serve` handles a request),\n * follows same-site links, and writes every page into `output`, after a copy of `publicPath`. The site is written\n * into a temporary folder beside `output` and swapped in at the end, so a failed export leaves the last one intact.\n */\nexport async function exportSite(app: Application, options: ExportOptions): Promise<ExportResult> {\n const output = resolve(options.output)\n const publicPath = options.publicPath === false ? undefined : resolve(options.publicPath)\n if (publicPath !== undefined && existsSync(join(publicPath, 'hot'))) {\n throw new Error('The Vite dev server is running (public/hot exists): stop `npm run dev`, build the assets with `npm run build`, then export.')\n }\n assertReplaceable(output)\n\n const staging = await mkdtemp(join(dirname(output), `.${basename(output)}-`))\n try {\n if (publicPath !== undefined && existsSync(publicPath)) {\n await cp(publicPath, staging, { recursive: true, filter: (source) => basename(source) !== 'hot' && !lstatSync(source).isSymbolicLink() })\n }\n const excluded = (path: string) => options.exclude.some((pattern) => wildcard(pattern).test(path))\n const isPublicFile = (path: string) => publicPath !== undefined && path !== '/' && isFile(join(publicPath, path))\n const queue = [...new Set(['/', ...options.paths.map(rooted)])].filter((path) => path === '/' || !excluded(path))\n const seen = new Set(queue)\n const pages: string[] = []\n const redirects: ExportResult['redirects'] = []\n\n while (queue.length > 0) {\n const path = queue.shift()!\n const url = new URL(path, options.baseUrl).href\n const answer = await fetchPage(app, url)\n if (answer.status >= 300 && answer.status < 400) {\n const location = new URL(answer.headers.get('location') ?? '/', url).href\n redirects.push({ path, location })\n // The page it points at is exported too, even when nothing links to it.\n const target = sitePath(location, url, options.baseUrl)\n if (target !== undefined && !seen.has(target) && !excluded(target) && !isPublicFile(target)) {\n seen.add(target)\n queue.push(target)\n }\n continue\n }\n if (answer.status >= 400) throw new ExportError(path, answer.status)\n await writeInto(staging, exportFileName(path, options.fileNames), answer.body)\n pages.push(path)\n if (!options.crawl || !isHtml(answer.headers)) continue\n for (const link of sameSiteLinks(answer.body.toString('utf8'), url, options.baseUrl)) {\n if (seen.has(link) || excluded(link) || isPublicFile(link)) continue\n seen.add(link)\n queue.push(link)\n }\n }\n\n const notFound = await fetchPage(app, new URL(NOT_FOUND_PATH, options.baseUrl).href)\n const notFoundPage = notFound.status === 404 && isHtml(notFound.headers)\n if (notFoundPage) await writeInto(staging, '404.html', notFound.body)\n\n await writeFile(join(staging, MARKER), '')\n await rm(output, { recursive: true, force: true })\n await rename(staging, output)\n return { pages, redirects, notFoundPage }\n } catch (error) {\n await rm(staging, { recursive: true, force: true })\n throw error\n }\n}\n\n/** The export only replaces a folder it made (or an empty one): `--output=.` must never delete the app. */\nfunction assertReplaceable(output: string): void {\n if (!existsSync(output)) return\n if (statSync(output).isDirectory() && (existsSync(join(output, MARKER)) || readdirSync(output).length === 0)) return\n throw new Error(`[${output}] exists and wasn't made by oriel export: remove it, or export somewhere else with --output.`)\n}\n\nasync function fetchPage(app: Application, url: string): Promise<{ status: number; headers: Headers; body: Buffer }> {\n const request = new Request(url, { headers: { accept: 'text/html' } })\n const response = await handleSafely(app, request)\n const body = Buffer.from(await response.arrayBuffer())\n await terminateRequest(app, request, response)\n return { status: response.status, headers: response.headers, body }\n}\n\nasync function writeInto(folder: string, file: string, body: Buffer): Promise<void> {\n const path = join(folder, file)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, body)\n}\n\nconst isHtml = (headers: Headers) => (headers.get('content-type') ?? '').includes('text/html')\n\nconst rooted = (path: string) => (path.startsWith('/') ? path : `/${path}`)\n\nconst isFile = (path: string) => existsSync(path) && statSync(path).isFile()\n\nconst wildcard = (pattern: string) => new RegExp(`^${rooted(pattern).replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*')}$`)\n","import { HttpKernel, type Application } from '@orieljs/contracts'\nimport { plainServerError } from '../Kernel'\nimport { servePublicFile } from './static'\n\nexport type Runtime = 'node' | 'bun'\n\nexport interface ServeOptions {\n /** Default: PORT, then SERVER_PORT, then 8000 (Laravel's serve). 0 picks a free port. */\n port?: number\n /** Default: 127.0.0.1. */\n hostname?: string\n /** Close gracefully on SIGINT/SIGTERM, then exit. Default: true. */\n signals?: boolean\n /** How long close() waits for in-flight requests before cutting connections (ms). Default: 10000. */\n shutdownTimeout?: number\n /** Default: detected (Bun when globalThis.Bun exists). */\n runtime?: Runtime\n /** Called once listening. Default: prints \"Server running on [url].\" */\n onListen?: (server: RunningServer) => void\n /** Serve existing files from this directory before the app (Laravel's server.php). Default: app.publicPath(); false turns it off. */\n publicPath?: string | false\n}\n\nexport interface ResolvedServeOptions {\n readonly port: number\n readonly hostname: string\n readonly signals: boolean\n readonly shutdownTimeout: number\n /** Where public files are served from, or undefined when turned off. */\n readonly publicPath?: string\n}\n\nexport interface RunningServer {\n readonly runtime: Runtime\n readonly hostname: string\n readonly port: number\n /** 'http://127.0.0.1:8000' */\n readonly url: string\n /** Stops accepting connections, waits for in-flight requests (up to shutdownTimeout), then resolves. */\n close(): Promise<void>\n /** Resolves once the server has closed. */\n readonly closed: Promise<void>\n}\n\n/** HttpKernel.terminate() after the response went out (Laravel's terminable middleware). Never throws. */\nexport async function terminateRequest(app: Application, request: Request, response: Response): Promise<void> {\n try {\n if (app.bound(HttpKernel)) await app.make(HttpKernel).terminate?.(request, response)\n } catch (error) {\n console.error(error)\n }\n}\n\n/** A public file when one matches, else app.handle(), turning a crash outside the kernel into a plain 500. */\nexport async function handleSafely(app: Application, request: Request, publicPath?: string): Promise<Response> {\n try {\n if (publicPath !== undefined) {\n const file = await servePublicFile(publicPath, request)\n if (file !== undefined) return file\n }\n return await app.handle(request)\n } catch (error) {\n console.error(error)\n return plainServerError()\n }\n}\n\n/**\n * SIGINT/SIGTERM → close() → app.shutdown() (database pools, Redis clients, log files) → process.exit(0). The\n * listeners go away when the server closes.\n */\nexport function exitOnSignals(close: () => Promise<void>, closed: Promise<void>, app: Application): void {\n const onSignal = () => {\n void close()\n .then(() => app.shutdown())\n .then(() => process.exit(0))\n }\n process.once('SIGINT', onSignal)\n process.once('SIGTERM', onSignal)\n void closed.then(() => {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n })\n}\n\nexport const displayHost = (hostname: string): string => (hostname.includes(':') ? `[${hostname}]` : hostname)\n","import { createReadStream } from 'node:fs'\nimport { stat } from 'node:fs/promises'\nimport { Readable } from 'node:stream'\nimport { relative, resolve, sep } from 'node:path'\nimport { mimeFromExtension } from '../mime'\n\n/**\n * Source files and dotfiles in public/ are never served (public/index.ts is the entry point, not an asset).\n * Tested on every segment of the resolved path, so trailing slashes and dot segments can't hide a name.\n * Names ending in a dot or a space are refused too, since Windows strips those when it opens the file.\n */\nconst HIDDEN_SEGMENT = /^\\.|\\.(ts|tsx|mts|cts)$|[. ]$/i\n\n/**\n * Laravel's server.php for `artisan serve`: a GET or HEAD for a file that exists under public/ is answered\n * with that file, so the built Vite assets (public/build) and other public files work without a web server.\n * Anything else (directories, missing files, other methods) returns undefined and goes to the application.\n */\nexport async function servePublicFile(publicPath: string, request: Request): Promise<Response | undefined> {\n if (request.method !== 'GET' && request.method !== 'HEAD') return undefined\n let pathname: string\n try {\n pathname = decodeURIComponent(new URL(request.url).pathname)\n } catch {\n return undefined\n }\n if (pathname === '/' || pathname.includes('\\0')) return undefined\n const root = resolve(publicPath)\n const file = resolve(root, `.${pathname}`)\n if (!file.startsWith(root + sep)) return undefined\n if (relative(root, file).split(/[\\\\/]/).some((segment) => HIDDEN_SEGMENT.test(segment))) return undefined\n const info = await stat(file).catch(() => undefined)\n if (info === undefined || !info.isFile()) return undefined\n\n const type = mimeFromExtension(file)\n const headers = new Headers({\n 'content-type': type.startsWith('text/') || type === 'application/json' ? `${type}; charset=utf-8` : type,\n 'content-length': String(info.size),\n 'last-modified': info.mtime.toUTCString(),\n })\n // Vite's hashed build output never changes under the same name.\n if (pathname.startsWith('/build/assets/')) headers.set('cache-control', 'public, max-age=31536000, immutable')\n if (request.method === 'HEAD') return new Response(null, { status: 200, headers })\n const body = Readable.toWeb(createReadStream(file)) as unknown as ReadableStream<Uint8Array>\n return new Response(body, { status: 200, headers })\n}\n","import { posix } from 'node:path'\n\n/** An `<a>` tag's href, quoted with `\"` or `'`, or unquoted. */\nconst ANCHOR = /<a\\b[^>]*?\\shref\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'>]+))/gi\n\nconst decode = (path: string): string => {\n try {\n return decodeURIComponent(path)\n } catch {\n return path\n }\n}\n\n/**\n * The file a page is written to, relative to the output folder: `/` → `index.html`, `/docs/routing` →\n * `docs/routing.html` (or `docs/routing/index.html`). A path with an extension (`/feed.xml`) keeps its name.\n */\nexport function exportFileName(path: string, style: 'html' | 'directory'): string {\n const trimmed = decode(path).replace(/^\\/+|\\/+$/g, '')\n if (trimmed === '') return 'index.html'\n if (posix.extname(trimmed) !== '') return trimmed\n return style === 'directory' ? `${trimmed}/index.html` : `${trimmed}.html`\n}\n\n/**\n * The paths a page links to on the same site (the origin of `baseUrl`): resolved against the page's URL, decoded,\n * without query, hash or a trailing slash, each once, in document order. Links to other origins, `mailto:`, `tel:`,\n * `javascript:` and to an anchor on the same page are left out.\n */\nexport function sameSiteLinks(html: string, pageUrl: string, baseUrl: string): string[] {\n const origin = new URL(baseUrl).origin\n const found: string[] = []\n const seen = new Set<string>()\n for (const match of html.matchAll(ANCHOR)) {\n const href = (match[1] ?? match[2] ?? match[3] ?? '').trim()\n if (href === '' || href.startsWith('#')) continue\n const path = sitePath(href, pageUrl, origin)\n if (path === undefined || seen.has(path)) continue\n seen.add(path)\n found.push(path)\n }\n return found\n}\n\n/**\n * The site's path a link or a redirect's location points at, without its query, hash or trailing slash, decoded; or\n * undefined for another origin or a URL that doesn't parse.\n */\nexport function sitePath(href: string, pageUrl: string, origin: string): string | undefined {\n let url: URL\n try {\n url = new URL(href, pageUrl)\n } catch {\n return undefined\n }\n if (url.origin !== new URL(origin).origin) return undefined\n return decode(url.pathname.length > 1 ? url.pathname.replace(/\\/+$/, '') : url.pathname)\n}\n","import type { Application } from '@orieljs/contracts'\nimport { setClientAddress } from '../clientAddress'\nimport { HttpServerError } from '../errors'\nimport { plainServerError } from '../Kernel'\nimport {\n displayHost,\n exitOnSignals,\n handleSafely,\n terminateRequest,\n type ResolvedServeOptions,\n type RunningServer,\n} from './types'\n\n/** The slice of Bun's API used here (typed locally: there is no Bun lib in the build). */\ninterface BunServer {\n readonly port: number\n stop(closeActiveConnections?: boolean): Promise<void> | void\n requestIP(request: Request): { address: string } | null\n}\ninterface BunRuntime {\n serve(options: {\n port: number\n hostname: string\n fetch(request: Request, server: BunServer): Promise<Response>\n error(error: Error): Response\n }): BunServer\n}\n\nexport function bunRuntime(): BunRuntime | undefined {\n return (globalThis as { Bun?: BunRuntime }).Bun\n}\n\nexport async function serveBun(app: Application, options: ResolvedServeOptions): Promise<RunningServer> {\n const bun = bunRuntime()\n if (bun === undefined) throw new HttpServerError('Bun.serve is not available: the process is not running on Bun.')\n let markClosed: () => void = () => undefined\n const closed = new Promise<void>((resolve) => (markClosed = resolve))\n\n const server = bun.serve({\n port: options.port,\n hostname: options.hostname,\n async fetch(request, current) {\n setClientAddress(request, current.requestIP(request)?.address)\n const response = await handleSafely(app, request, options.publicPath)\n // Bun has no \"response sent\" hook: terminate on the next tick.\n setTimeout(() => void terminateRequest(app, request, response), 0)\n return response\n },\n error(error) {\n console.error(error)\n return plainServerError()\n },\n })\n\n let closing: Promise<void> | undefined\n const close = () =>\n (closing ??= (async () => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const forced = new Promise<void>((resolve) => {\n timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(resolve), options.shutdownTimeout)\n })\n await Promise.race([Promise.resolve(server.stop(false)), forced])\n clearTimeout(timer)\n markClosed()\n })())\n if (options.signals) exitOnSignals(close, closed, app)\n\n return {\n runtime: 'bun',\n hostname: options.hostname,\n port: server.port,\n url: `http://${displayHost(options.hostname)}:${server.port}`,\n close,\n closed,\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as NodeReadableStream } from 'node:stream/web'\nimport type { Application } from '@orieljs/contracts'\nimport { setClientAddress } from '../clientAddress'\nimport {\n displayHost,\n exitOnSignals,\n handleSafely,\n terminateRequest,\n type ResolvedServeOptions,\n type RunningServer,\n} from './types'\n\n/**\n * The request's body as a web stream that pulls from `req`. Readable.toWeb(req) is not used: cancelling it (readBody\n * does that for a declared length over the limit) closes its controller while the socket still emits data, which\n * throws out of the adapter and kills the process. Cancelling this one just stops listening; node drops the unread\n * remainder once the response finishes.\n */\nfunction requestBody(req: IncomingMessage): ReadableStream<Uint8Array> {\n let finished = false\n const detach = () => {\n finished = true\n req.off('data', onData)\n req.off('end', onEnd)\n req.off('error', onError)\n req.off('close', onClose)\n }\n let controller!: ReadableStreamDefaultController<Uint8Array>\n const onData = (chunk: Buffer) => {\n if (finished) return\n controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength))\n if ((controller.desiredSize ?? 0) <= 0) req.pause()\n }\n const onEnd = () => {\n if (finished) return\n detach()\n controller.close()\n }\n const onError = (error: Error) => {\n if (finished) return\n detach()\n controller.error(error)\n }\n const onClose = () => {\n if (!finished && !req.complete) onError(new Error('The request was aborted.'))\n }\n return new ReadableStream<Uint8Array>(\n {\n start(c) {\n controller = c\n req.on('data', onData)\n req.on('end', onEnd)\n req.on('error', onError)\n req.on('close', onClose)\n req.pause()\n },\n pull() {\n req.resume()\n },\n cancel() {\n detach()\n },\n },\n { highWaterMark: 0 },\n )\n}\n\n/** node:http IncomingMessage → web Request (the body streams; the signal aborts when the client goes away). */\nexport function toWebRequest(req: IncomingMessage, res: ServerResponse, fallbackHost: string): Request {\n // Concatenate rather than resolve: a target such as '//evil.com/x' must stay on this host, not become evil.com.\n const target = req.url ?? '/'\n const url = new URL(`http://${req.headers.host ?? fallbackHost}${target.startsWith('/') ? target : `/${target}`}`)\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i]!\n if (!name.startsWith(':')) headers.append(name, req.rawHeaders[i + 1]!)\n }\n const method = (req.method ?? 'GET').toUpperCase()\n const controller = new AbortController()\n res.once('close', () => {\n if (!res.writableFinished) controller.abort()\n })\n const init: RequestInit & { duplex?: 'half' } = { method, headers, signal: controller.signal }\n if (method !== 'GET' && method !== 'HEAD') {\n init.body = requestBody(req)\n init.duplex = 'half'\n }\n return new Request(url, init)\n}\n\n/** Web Response → ServerResponse, streaming the body with backpressure. Several Set-Cookie headers stay separate. */\nexport async function writeResponse(res: ServerResponse, response: Response): Promise<void> {\n res.statusCode = response.status\n if (response.statusText !== '') res.statusMessage = response.statusText\n response.headers.forEach((value, name) => {\n if (name !== 'set-cookie') res.setHeader(name, value)\n })\n const cookies = response.headers.getSetCookie()\n if (cookies.length > 0) res.setHeader('set-cookie', cookies)\n if (response.body === null) {\n res.end()\n return\n }\n await pipeline(Readable.fromWeb(response.body as unknown as NodeReadableStream<Uint8Array>), res)\n}\n\n/**\n * A node:http request listener for the app: a public file when one matches, else the app's answer, then the\n * terminable middleware. `serve` uses it, and so does any host that hands Oriel Node's request and response (Vercel's\n * functions). `fallbackHost` is the Host used when a request has none.\n */\nexport function nodeRequestHandler(\n app: Application,\n options: { publicPath?: string; fallbackHost: string },\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n return async (req, res) => {\n let request: Request\n try {\n request = toWebRequest(req, res, options.fallbackHost)\n } catch {\n res.statusCode = 400\n res.end('Bad Request')\n return\n }\n setClientAddress(request, req.socket.remoteAddress)\n const response = await handleSafely(app, request, options.publicPath)\n try {\n await writeResponse(res, response)\n } catch {\n // The client went away mid-response.\n res.destroy()\n }\n await terminateRequest(app, request, response)\n }\n}\n\nexport async function serveNode(app: Application, options: ResolvedServeOptions): Promise<RunningServer> {\n const handle = nodeRequestHandler(app, {\n ...(options.publicPath !== undefined && { publicPath: options.publicPath }),\n fallbackHost: `${displayHost(options.hostname)}:${options.port}`,\n })\n const server = createServer((req, res) => void handle(req, res))\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(options.port, options.hostname, () => {\n server.off('error', reject)\n resolve()\n })\n })\n\n const address = server.address() as AddressInfo\n const closed = new Promise<void>((resolve) => server.once('close', () => resolve()))\n let closing: Promise<void> | undefined\n const close = () =>\n (closing ??= (async () => {\n const done = new Promise<void>((resolve) => server.close(() => resolve()))\n // Keep-alive connections become idle once their request finishes; close them as that happens.\n server.closeIdleConnections()\n const idle = setInterval(() => server.closeIdleConnections(), 50)\n const force = setTimeout(() => server.closeAllConnections(), options.shutdownTimeout)\n await done\n clearInterval(idle)\n clearTimeout(force)\n })())\n if (options.signals) exitOnSignals(close, closed, app)\n\n return {\n runtime: 'node',\n hostname: options.hostname,\n port: address.port,\n url: `http://${displayHost(options.hostname)}:${address.port}`,\n close,\n closed,\n }\n}\n","import type { Application } from '@orieljs/contracts'\nimport { bunRuntime, serveBun } from './bun'\nimport { serveNode } from './node'\nimport type { ResolvedServeOptions, Runtime, RunningServer, ServeOptions } from './types'\n\nexport function detectRuntime(): Runtime {\n return bunRuntime() !== undefined ? 'bun' : 'node'\n}\n\n/** Boots the app and serves it with node:http or Bun.serve (public/index.ts: `await serve(app)`). */\nexport async function serve(app: Application, options: ServeOptions = {}): Promise<RunningServer> {\n const resolved: ResolvedServeOptions = {\n port: options.port ?? Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8000),\n hostname: options.hostname ?? '127.0.0.1',\n signals: options.signals ?? true,\n shutdownTimeout: options.shutdownTimeout ?? 10_000,\n ...(options.publicPath !== false && { publicPath: options.publicPath ?? app.publicPath() }),\n }\n await app.boot()\n const runtime = options.runtime ?? detectRuntime()\n const server = runtime === 'bun' ? await serveBun(app, resolved) : await serveNode(app, resolved)\n const onListen = options.onListen ?? ((running: RunningServer) => console.log(`Server running on [${running.url}].`))\n onListen(server)\n return server\n}\n","import { existsSync } from 'node:fs'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport {\n ConfigRepository,\n Router,\n type Application,\n type CommandContext,\n type ConsoleKernel,\n type MiddlewareReference,\n type Route,\n} from '@orieljs/contracts'\nimport { ExportError, exportSite } from './export/export'\nimport { serve } from './server/serve'\nimport type { RunningServer, ServeOptions } from './server/types'\nimport { serverEnvironment } from './watch/environment'\nimport { watchFiles } from './watch/files'\nimport { claimPort, listenFailure } from './watch/port'\nimport { WatchedServer, type WatchedServerOptions } from './watch/WatchedServer'\n\ninterface Io {\n option(name: string): string | undefined\n flag(name: string): boolean\n info(message: string): void\n line(message: string): void\n warn(message: string): void\n error(message: string): void\n}\n\n/**\n * The closure command's `this` (the contract's CommandContext), with the options normalised: a value option that\n * is absent (undefined, null, false or '') reads as undefined, and a flag is true only when set.\n */\nfunction io(command: CommandContext): Io {\n return {\n option: (name) => {\n const value: unknown = command.option(name)\n return value === undefined || value === null || value === false || value === '' ? undefined : String(value)\n },\n flag: (name) => {\n const value: unknown = command.option(name)\n return value === true || value === 'true' || value === '1'\n },\n info: (message) => command.info(message),\n line: (message) => command.line(message),\n warn: (message) => command.warn(message),\n error: (message) => command.error(message),\n }\n}\n\nexport interface RouteListRow {\n /** 'GET|HEAD' */\n readonly method: string\n readonly uri: string\n readonly name: string | null\n /** 'PostController@show' or 'Closure' */\n readonly action: string\n readonly middleware: string[]\n}\n\ninterface ListableRoute extends Route {\n getActionName?(): string\n gatherMiddleware?(): MiddlewareReference[]\n}\n\nconst middlewareName = (reference: MiddlewareReference): string => (typeof reference === 'string' ? reference : reference.name)\n\n/** One row per route, sorted by URI (Laravel's default --sort=uri; ties keep registration order). */\nexport function routeListRows(routes: readonly Route[]): RouteListRow[] {\n const rows = routes.map((route) => {\n const listable = route as ListableRoute\n return {\n method: route.methods.join('|'),\n uri: route.uri,\n name: route.getName() ?? null,\n action: typeof listable.getActionName === 'function' ? listable.getActionName() : 'Closure',\n middleware: typeof listable.gatherMiddleware === 'function' ? listable.gatherMiddleware().map(middlewareName) : [],\n }\n })\n return rows.sort((a, b) => (a.uri < b.uri ? -1 : a.uri > b.uri ? 1 : 0))\n}\n\nexport interface RouteListFilters {\n method?: string\n name?: string\n path?: string\n /** Comma-separated. */\n exceptPath?: string\n}\n\n/** Laravel's RouteListCommand::filterRoute: substring matches, method compared uppercased. */\nexport function filterRouteList(rows: readonly RouteListRow[], filters: RouteListFilters): RouteListRow[] {\n const excluded = (filters.exceptPath ?? '').split(',').filter((path) => path !== '')\n return rows.filter((row) => {\n if (filters.name !== undefined && !(row.name ?? '').includes(filters.name)) return false\n if (filters.path !== undefined && !row.uri.includes(filters.path)) return false\n if (filters.method !== undefined && !row.method.includes(filters.method.toUpperCase())) return false\n return !excluded.some((path) => row.uri.includes(path))\n })\n}\n\n/**\n * Laravel's route:list layout: the method column padded, the URI, a dotted leader, then `name › action`\n * (closures show only the name), and a right-aligned \"Showing [n] routes\" footer.\n */\nexport function formatRouteList(rows: readonly RouteListRow[], width: number): string[] {\n const methodWidth = Math.max(...rows.map((row) => row.method.length))\n const lines = rows.map((row) => {\n const spaces = ' '.repeat(Math.max(methodWidth + 6 - row.method.length, 0))\n const action = row.action === 'Closure' ? (row.name ?? '') : row.name === null ? row.action : `${row.name} › ${row.action}`\n const used = row.method.length + spaces.length + row.uri.length + action.length + 6 + (action === '' ? 0 : 1)\n const dots = '.'.repeat(Math.max(width - used, 0))\n return ` ${row.method} ${spaces}${row.uri}${dots === '' ? '' : ` ${dots}`}${action === '' ? '' : ` ${action}`}`\n })\n const count = `Showing [${rows.length}] ${rows.length === 1 ? 'route' : 'routes'}`\n return [...lines, '', `${' '.repeat(Math.max(width - count.length - 2, 0))}${count}`]\n}\n\n/** The routes/api.ts that install:api writes (Laravel's api.stub, with the token guard). */\nexport const API_ROUTES_STUB = `import { request, Route } from '@orieljs/framework'\n\nRoute.get('/user', () => request().user()).middleware('auth:token')\n`\n\n/**\n * Adds `api: 'routes/api.ts'` to withRouting() in bootstrap/app.ts: uncomments a commented `// api:` entry,\n * else inserts it after the `web:` entry, else at the start of withRouting({, else adds a withRouting() call\n * before create(). Returns the source unchanged when api is already there, and undefined when it can't tell where.\n * (Function replacers, so a `$` in the file is never read as a replacement pattern.)\n */\nexport function addApiRouting(source: string): string | undefined {\n const code = source.replace(/^[ \\t]*\\/\\/.*$/gm, '')\n if (/withRouting\\(\\s*\\{[^}]*\\bapi\\s*:/.test(code)) return source\n const commented = /^([ \\t]*)\\/\\/\\s*(api:\\s*['\"`][^'\"`\\n]*['\"`],?)[ \\t]*$/m.exec(source)\n if (commented !== null) return source.replace(commented[0], () => `${commented[1]}${commented[2]}`)\n const web = /^([ \\t]*)web:\\s*(['\"`])[^'\"`\\n]*\\2[ \\t]*,?[ \\t]*$/m.exec(source)\n if (web !== null) {\n const line = web[0].trimEnd()\n return source.replace(web[0], () => `${line.endsWith(',') ? line : `${line},`}\\n${web[1]}api: 'routes/api.ts',`)\n }\n const inline = /withRouting\\(\\s*\\{/.exec(source)\n if (inline !== null) return source.replace(inline[0], () => `${inline[0]} api: 'routes/api.ts',`)\n const create = /^([ \\t]*)\\.create\\(\\)/m.exec(source)\n if (create !== null) return source.replace(create[0], () => `${create[1]}.withRouting({ api: 'routes/api.ts' })\\n${create[0]}`)\n return undefined\n}\n\nexport interface HttpCommandOptions {\n /** Replaces serve() (tests). */\n serve?: (app: Application, options: ServeOptions) => Promise<RunningServer>\n /** The terminal width for route:list. Default: process.stdout.columns, else 120. */\n terminalWidth?: () => number\n /** Replaces `serve --watch`'s restarting server (tests). Resolves the command's exit code. */\n watch?: (options: WatchedServerOptions) => Promise<number>\n}\n\n/**\n * `serve --watch`: claims the port once (`--port`, else PORT, SERVER_PORT, 8000; 0 picks a free one), so every\n * restart serves on the same port and a taken port fails at once, then runs `serve` on it in a child process that\n * restarts when the app's files change. The child is this runtime with its flags and script (`node oriel`,\n * `bun oriel`), in this folder, with the environment this process started with, so an edited .env applies.\n */\nasync function serveWatching(app: Application, out: Io, port: string | undefined, run: (options: WatchedServerOptions) => Promise<number>): Promise<number> {\n const hostname = out.option('host') ?? '127.0.0.1'\n const requested = port !== undefined ? Number(port) : Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8000)\n let claimed: number\n try {\n claimed = await claimPort(hostname, requested)\n } catch (error) {\n out.error(listenFailure(hostname, requested, error))\n return 1\n }\n const script = process.argv[1]\n if (script === undefined) {\n out.error(\"serve --watch can't tell which script started this process, so it can't start the server.\")\n return 1\n }\n return run({\n command: [process.execPath, ...process.execArgv, script, 'serve', `--host=${hostname}`, `--port=${claimed}`],\n cwd: process.cwd(),\n env: serverEnvironment(),\n watch: (onChange) =>\n watchFiles(app.basePath(), onChange, { onError: (folder, error) => out.warn(`Unable to watch [${folder}] for changes: ${error.message}`) }),\n info: (message) => out.info(message),\n error: (message) => out.error(message),\n })\n}\n\n/** `export`: the app's pages as files, set by config/export.ts (Laravel: spatie/laravel-export's export command). */\nasync function exportCommand(app: Application, out: Io): Promise<number> {\n const config = <T>(key: string, fallback: T): T => (app.bound(ConfigRepository) ? app.make(ConfigRepository).get<T>(key, fallback) : fallback)\n const fileNames = config<string>('export.file_names', 'html')\n if (fileNames !== 'html' && fileNames !== 'directory') {\n out.error(`export.file_names is \"html\" or \"directory\", not \"${fileNames}\".`)\n return 1\n }\n const output = out.option('output') ?? config<string>('export.output', 'dist')\n const baseUrl = config<string>('app.url', 'http://localhost')\n const started = performance.now()\n try {\n const result = await exportSite(app, {\n output: resolve(app.basePath(), output),\n baseUrl,\n crawl: config<boolean>('export.crawl', true),\n paths: config<string[]>('export.paths', []),\n exclude: config<string[]>('export.exclude', []),\n fileNames,\n publicPath: app.publicPath(),\n })\n const origin = new URL(baseUrl).origin\n for (const { path, location } of result.redirects) {\n out.line(`Redirect ${path} → ${location.startsWith(origin) ? location.slice(origin.length) || '/' : location}, not written.`)\n }\n const pages = result.pages.length === 1 ? '1 page' : `${result.pages.length} pages`\n out.info(`Exported ${pages} to [${output}] in ${Math.round(performance.now() - started)} ms.`)\n return 0\n } catch (error) {\n out.error(error instanceof ExportError ? error.message : error instanceof Error ? error.message : String(error))\n return 1\n }\n}\n\n/** Registers `serve`, `route:list`, `export` and `install:api` as closure commands (PC1). */\nexport function registerHttpCommands(kernel: ConsoleKernel, app: Application, options: HttpCommandOptions = {}): void {\n const serveApp = options.serve ?? serve\n const terminalWidth = options.terminalWidth ?? (() => process.stdout.columns ?? 120)\n const runWatching = options.watch ?? ((watchOptions: WatchedServerOptions) => new WatchedServer(watchOptions).run())\n\n kernel\n .command(\n 'serve {--host=127.0.0.1 : The host address to serve the application on} {--port= : The port to serve the application on} ' +\n '{--watch : Automatically restart the server when the application is modified}',\n async function (this: CommandContext) {\n const out = io(this)\n const port = out.option('port')\n if (port !== undefined && !/^\\d+$/.test(port)) {\n out.error('The --port option must be a number.')\n return 1\n }\n if (out.flag('watch')) return serveWatching(app, out, port, runWatching)\n const server = await serveApp(app, {\n hostname: out.option('host') ?? '127.0.0.1',\n ...(port !== undefined && { port: Number(port) }),\n onListen: (running) => {\n out.info(`Server running on [${running.url}].`)\n out.line('Press Ctrl+C to stop the server')\n },\n })\n await server.closed\n return 0\n },\n )\n .purpose('Serve the application on the Oriel development server')\n\n kernel\n .command(\n 'route:list {--method= : Filter the routes by method} {--name= : Filter the routes by name} ' +\n '{--path= : Only show routes matching the given path pattern} ' +\n '{--except-path= : Do not display the routes matching the given path pattern} ' +\n '{--reverse : Reverse the ordering of the routes} {--json : Output the route list as JSON}',\n function (this: CommandContext) {\n const out = io(this)\n if (!app.bound(Router)) {\n out.error('The router is not available. Is the Routing service provider registered?')\n return 1\n }\n const all = routeListRows(app.make(Router).getRoutes())\n if (all.length === 0) {\n out.error(\"Your application doesn't have any routes.\")\n return 0\n }\n const rows = filterRouteList(all, {\n ...(out.option('method') !== undefined && { method: out.option('method') }),\n ...(out.option('name') !== undefined && { name: out.option('name') }),\n ...(out.option('path') !== undefined && { path: out.option('path') }),\n ...(out.option('except-path') !== undefined && { exceptPath: out.option('except-path') }),\n })\n if (rows.length === 0) {\n out.error(\"Your application doesn't have any routes matching the given criteria.\")\n return 0\n }\n if (out.flag('reverse')) rows.reverse()\n if (out.flag('json')) {\n out.line(JSON.stringify(rows))\n return 0\n }\n for (const line of formatRouteList(rows, terminalWidth())) out.line(line)\n return 0\n },\n )\n .purpose('List all registered routes')\n\n kernel\n .command('export {--output= : The folder to write the site to (default: config export.output, else dist)}', function (this: CommandContext) {\n return exportCommand(app, io(this))\n })\n .purpose(\"Export the application's pages as static files\")\n\n kernel\n .command('install:api {--force : Overwrite any existing API routes file}', async function (this: CommandContext) {\n const out = io(this)\n const routesFile = app.basePath('routes/api.ts')\n if (existsSync(routesFile) && !out.flag('force')) {\n out.error('API routes file already exists.')\n } else {\n await mkdir(dirname(routesFile), { recursive: true })\n await writeFile(routesFile, API_ROUTES_STUB)\n out.info('Published API routes file.')\n }\n\n const bootstrapFile = app.bootstrapPath('app.ts')\n const source = existsSync(bootstrapFile) ? await readFile(bootstrapFile, 'utf8') : undefined\n const updated = source === undefined ? undefined : addApiRouting(source)\n if (updated === undefined) {\n out.warn(\n 'Unable to automatically add API route definition to bootstrap file. ' +\n \"Add api: 'routes/api.ts' to withRouting() in bootstrap/app.ts.\",\n )\n } else if (updated !== source) {\n await writeFile(bootstrapFile, updated)\n }\n\n out.info('API scaffolding installed.')\n return 0\n })\n .purpose('Create an API routes file and prepare the application for API authentication')\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport * as util from 'node:util'\n\n/**\n * This process's environment as it was when the framework loaded, which is before `createApplication()` reads `.env`:\n * that never overwrites a variable, so a server started with the current environment would keep every old value.\n */\nconst launchEnvironment: Readonly<NodeJS.ProcessEnv> = Object.freeze({ ...process.env })\n\n/**\n * Every file Bun may read into process.env from the working directory before any code runs, whatever the NODE_ENV:\n * `.env`, `.env.<mode>`, `.env.local` and `.env.<mode>.local`, for the modes development, production and test.\n */\nexport const BUN_ENV_FILES: readonly string[] = [\n '.env',\n '.env.development',\n '.env.production',\n '.env.test',\n '.env.local',\n '.env.development.local',\n '.env.production.local',\n '.env.test.local',\n]\n\nexport interface ServerEnvironmentOptions {\n /** Default: the environment this process started with (above). */\n launched?: NodeJS.ProcessEnv\n /** Default: whether this process runs on Bun. */\n bun?: boolean\n /** Where Bun read its env files from. Default: the working directory. */\n cwd?: string\n /** Default: `util.parseEnv`, which some supported runtimes lack (passing `undefined` stands for that). */\n parseEnv?: ((content: string) => NodeJS.Dict<string>) | undefined\n}\n\n/** `$NAME` and `${NAME}` replaced with their values, as Bun expands an env file. */\nconst expand = (value: string, env: NodeJS.ProcessEnv): string =>\n value.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}|\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, braced?: string, bare?: string) => env[braced ?? bare!] ?? '')\n\n/**\n * The environment for each server `serve --watch` starts: the one this process started with, so the server reads\n * `.env` again and an edit applies. On Bun, which loads its env files before any code runs, a variable whose value is\n * the one in such a file (as written, or expanded) is left out too, so the new process loads it again; a variable set\n * to another value (in the shell) stays.\n */\nexport function serverEnvironment(options: ServerEnvironmentOptions = {}): NodeJS.ProcessEnv {\n const launched = options.launched ?? launchEnvironment\n const env: NodeJS.ProcessEnv = { ...launched }\n if (!(options.bun ?? process.versions.bun !== undefined)) return env\n // util.parseEnv is newer than some supported runtimes (a namespace import, so its absence fails nothing at load):\n // without it the env files are not read, and the environment is the launch copy, as on Node.\n const parseEnv = 'parseEnv' in options ? options.parseEnv : (util.parseEnv as typeof util.parseEnv | undefined)\n if (typeof parseEnv !== 'function') return env\n const cwd = options.cwd ?? process.cwd()\n for (const name of BUN_ENV_FILES) {\n const file = join(cwd, name)\n if (!existsSync(file)) continue\n let values: NodeJS.Dict<string>\n try {\n values = parseEnv(readFileSync(file, 'utf8'))\n } catch {\n continue\n }\n for (const [key, raw] of Object.entries(values)) {\n const value = launched[key]\n if (raw !== undefined && value !== undefined && (value === raw || value === expand(raw, launched))) delete env[key]\n }\n }\n return env\n}\n","import { existsSync, statSync, watch as watchPath } from 'node:fs'\nimport { join } from 'node:path'\n\n/**\n * The folders `serve --watch` watches under the app's base path: the server's code, its configuration, the routes,\n * the server-rendered views and the translations. Not `resources/js` or `resources/css` (Vite's), `public`, `storage`,\n * `database` (the SQLite file changes on every write) or `tests`.\n */\nexport const WATCHED_FOLDERS: readonly string[] = ['app', 'bootstrap', 'config', 'lang', 'resources/lang', 'resources/views', 'routes']\n\n/** Files in the base path itself that restart the server, besides `.env` and `.env.*`. */\nexport const WATCHED_ROOT_FILES: readonly string[] = ['package.json', 'tsconfig.json']\n\n/** Build output inside a watched folder, ignored with everything in it: the SSR bundle (`vite build --ssr`) and caches. */\nconst IGNORED_FOLDERS = ['bootstrap/ssr', 'bootstrap/cache']\n\nconst CODE_FILE = /\\.(?:[cm]?[jt]sx?|json)$/\nconst DECLARATION_FILE = /\\.d\\.[cm]?ts$/\n/** Editor swap and backup files: Vim's `.swp` to `.swa` and `.swx`, `~` backups, JetBrains' safe-write copies. */\nconst EDITOR_FILE = /(?:\\.sw[a-px]|~|___jb_(?:tmp|old)___)$/\n\n/** `.env` and `.env.*` (`.env.local`, `.env.testing`, …), except `.env.example` and editor swap and backup files. */\nexport const isEnvironmentFile = (name: string): boolean =>\n (name === '.env' || name.startsWith('.env.')) && name !== '.env.example' && !EDITOR_FILE.test(name)\n\n/**\n * Whether a change to `path` (relative to the base path, `/`-separated) restarts the server: a TypeScript,\n * JavaScript or JSON file in a watched folder (not a `.d.ts`, nothing under a dot-folder, node_modules or the build\n * output, no editor swap or backup file), a name without an extension there (a folder that was moved or removed, but\n * not the build output's own folders), an env file, `package.json` or `tsconfig.json`.\n */\nexport function isWatchedPath(path: string): boolean {\n const segments = path.split('/')\n if (segments.length === 1) return isEnvironmentFile(path) || WATCHED_ROOT_FILES.includes(path)\n if (!WATCHED_FOLDERS.some((folder) => path.startsWith(`${folder}/`))) return false\n if (IGNORED_FOLDERS.some((folder) => path === folder || path.startsWith(`${folder}/`))) return false\n if (segments.some((segment) => segment.startsWith('.') || segment === 'node_modules')) return false\n const name = segments.at(-1)!\n if (DECLARATION_FILE.test(name)) return false\n return CODE_FILE.test(name) || !name.includes('.')\n}\n\n/** The part of a node:fs FSWatcher used here. */\nexport interface WatchHandle {\n close(): void\n on(event: 'error', listener: (error: Error) => void): unknown\n}\n\n/** node:fs watch(), replaceable in tests. */\nexport type WatchFolder = (\n path: string,\n options: { recursive: boolean },\n listener: (event: string, file: string | null) => void,\n) => WatchHandle\n\nexport interface WatchFilesOptions {\n /** Quiet time after the last change before `onChange` runs, in ms. Default 200 (Node's `--watch`). */\n debounce?: number\n /**\n * For this long after the start (ms), a change to a file last modified before the start, or to a path that doesn't\n * exist, is dropped. Default 1000: Node's watcher on macOS reports what was written just before it started, and the\n * watched folder itself under its own name (`app/app`).\n */\n settle?: number\n /** A folder (relative to the base path, `.` for the base path) that could not be watched, or stopped being. */\n onError?: (folder: string, error: Error) => void\n watch?: WatchFolder\n}\n\nexport interface FileWatcher {\n close(): void\n}\n\nconst toSlashes = (file: string): string => file.split('\\\\').join('/')\n\n/**\n * Watches the base path (not recursively: the env files, package.json, tsconfig.json) and each watched folder that\n * exists (recursively, with the runtime's fs.watch), and calls `onChange` with the changed files once no change has\n * come for `debounce` ms. A folder created later is watched from the next start; a file removed in the first second\n * (`settle`) counts only with the next change.\n */\nexport function watchFiles(basePath: string, onChange: (files: string[]) => void, options: WatchFilesOptions = {}): FileWatcher {\n const watch: WatchFolder = options.watch ?? ((path, watchOptions, listener) => watchPath(path, watchOptions, listener))\n const debounce = options.debounce ?? 200\n const onError = options.onError ?? (() => {})\n const changed = new Set<string>()\n let timer: ReturnType<typeof setTimeout> | undefined\n const settle = options.settle ?? 1000\n const startedAt = Date.now()\n /** A change reported in the settle time for something that didn't change since the start (1 ms: Date.now() is whole ms). */\n const reportedLate = (path: string): boolean => {\n if (Date.now() - startedAt >= settle) return false\n try {\n const modified = statSync(join(basePath, path), { throwIfNoEntry: false })?.mtimeMs\n return modified === undefined || modified < startedAt + 1\n } catch {\n return false\n }\n }\n\n const record = (path: string) => {\n if (!isWatchedPath(path) || reportedLate(path)) return\n changed.add(path)\n clearTimeout(timer)\n timer = setTimeout(() => {\n const files = [...changed]\n changed.clear()\n onChange(files)\n }, debounce)\n }\n\n const handles: WatchHandle[] = []\n const start = (folder: string, recursive: boolean, toPath: (file: string | null) => string | undefined) => {\n try {\n const handle = watch(folder === '.' ? basePath : join(basePath, folder), { recursive }, (_event, file) => {\n const path = toPath(file)\n if (path !== undefined) record(path)\n })\n handle.on('error', (error) => onError(folder, error))\n handles.push(handle)\n } catch (error) {\n onError(folder, error as Error)\n }\n }\n\n start('.', false, (file) => (file === null ? undefined : toSlashes(file)))\n for (const folder of WATCHED_FOLDERS) {\n if (existsSync(join(basePath, folder))) start(folder, true, (file) => `${folder}/${file === null ? '' : toSlashes(file)}`)\n }\n\n return {\n close() {\n clearTimeout(timer)\n changed.clear()\n for (const handle of handles) handle.close()\n },\n }\n}\n","import { createServer, type AddressInfo } from 'node:net'\nimport { displayHost } from '../server/types'\n\n/**\n * Listens on the port, then lets it go: the port a server can listen on (a free one for 0). Rejects as listen() does\n * (EADDRINUSE, EACCES, a port out of range). `serve --watch` calls it once, so every restart serves on the same port.\n */\nexport function claimPort(hostname: string, port: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.once('error', reject)\n try {\n server.listen({ port, host: hostname, exclusive: true }, () => {\n const { port: claimed } = server.address() as AddressInfo\n server.close(() => resolve(claimed))\n })\n } catch (error) {\n reject(error)\n }\n })\n}\n\nconst REASONS: Record<string, string> = {\n EADDRINUSE: 'Address already in use',\n EACCES: 'Permission denied',\n EADDRNOTAVAIL: \"Can't assign requested address\",\n}\n\n/** PHP's built-in server's message, which Laravel's serve shows: `Failed to listen on 127.0.0.1:8000 (reason: Address already in use)`. */\nexport function listenFailure(hostname: string, port: number, error: unknown): string {\n const { code, message } = error as NodeJS.ErrnoException\n return `Failed to listen on ${displayHost(hostname)}:${port} (reason: ${(code !== undefined && REASONS[code]) || message})`\n}\n","import { spawn as spawnProcess, type ChildProcess, type SpawnOptions } from 'node:child_process'\nimport { isEnvironmentFile, type FileWatcher } from './files'\n\n/** node:child_process's spawn(), replaceable in tests. */\nexport type SpawnServer = (command: string, args: string[], options: SpawnOptions) => ChildProcess\n\nexport interface WatchedServerOptions {\n /** The server's command line: the runtime, its flags, the CLI script, then `serve --host=… --port=…`. */\n command: readonly string[]\n cwd: string\n env: NodeJS.ProcessEnv\n /** Starts watching: calls back with the changed files (relative to the base path) once they settle. */\n watch(onChange: (files: string[]) => void): FileWatcher\n info(message: string): void\n error(message: string): void\n /** How long a server may take to stop before it is killed, in ms. Default 15000 (serve gives requests 10 s). */\n stopTimeout?: number\n /** The signals that stop it. Default SIGINT, SIGTERM and SIGHUP. */\n signals?: readonly NodeJS.Signals[]\n spawn?: SpawnServer\n}\n\ninterface Running {\n child: ChildProcess\n /** Resolves once the process has exited (or could not start). */\n exited: Promise<void>\n /** This side asked it to stop: its exit is not reported. */\n stopping: boolean\n /** Killed after stopTimeout (reported once). */\n killed: boolean\n}\n\n/**\n * `serve --watch`: runs `serve` in a child process and starts a new one after every change, on the same port. The\n * old server is stopped (SIGTERM, which serve answers by finishing its requests) and has exited before the next one\n * starts, so the port is free. Changes that come during a restart are read by the server it starts. A server that\n * exits by itself (a syntax error, a crash) is reported and the next change starts one, so this process keeps running.\n * SIGINT, SIGTERM and SIGHUP stop the server and end run(); a second one kills the server at once.\n */\nexport class WatchedServer {\n private running: Running | undefined\n private restarting = false\n private stopping = false\n private finish: (code: number) => void = () => {}\n\n constructor(private readonly options: WatchedServerOptions) {}\n\n /** Starts the server and keeps it current until stopped. Resolves 0 once the last server has exited. */\n run(): Promise<number> {\n const done = new Promise<number>((resolve) => (this.finish = resolve))\n const stopListening = this.listenForSignals()\n const watcher = this.options.watch((files) => void this.changed(files))\n this.start()\n return done.finally(() => {\n watcher.close()\n stopListening()\n })\n }\n\n /** Stops the server and ends run(); called again, kills the server at once. */\n stop(): void {\n if (this.stopping) {\n this.running?.child.kill('SIGKILL')\n return\n }\n this.stopping = true\n void this.stopServer().then(() => this.finish(0))\n }\n\n private async changed(files: string[]): Promise<void> {\n if (this.stopping || this.restarting || files.length === 0) return\n this.restarting = true\n try {\n this.options.info(\n files.some(isEnvironmentFile) ? 'Environment modified. Restarting server...' : `Application change detected in [${files[0]}]. Restarting server...`,\n )\n await this.stopServer()\n if (!this.stopping) this.start()\n } finally {\n this.restarting = false\n }\n }\n\n private start(): void {\n const [command, ...args] = this.options.command\n const child = (this.options.spawn ?? spawnProcess)(command!, args, {\n cwd: this.options.cwd,\n env: this.options.env,\n stdio: ['ignore', 'inherit', 'inherit'],\n })\n const running: Running = { child, stopping: false, killed: false, exited: Promise.resolve() }\n running.exited = new Promise<void>((resolve) => {\n let settled = false\n const settle = (report: string) => {\n if (settled) return\n settled = true\n if (this.running === running) this.running = undefined\n if (!running.stopping && !this.stopping) this.options.error(`${report}. Waiting for changes before restarting...`)\n resolve()\n }\n child.once('exit', (code, signal) => settle(signal !== null ? `The server stopped (signal ${signal})` : `The server stopped (exit code ${code})`))\n // 'error' also comes when a signal can't be sent: only a process that never started has ended with it.\n child.once('error', (error) => {\n if (child.pid === undefined) settle(`The server could not start (${error.message})`)\n })\n })\n this.running = running\n }\n\n /** Sends SIGTERM once and waits for the exit, killing the server after stopTimeout. */\n private async stopServer(): Promise<void> {\n const running = this.running\n if (running === undefined) return\n if (!running.stopping) {\n running.stopping = true\n running.child.kill('SIGTERM')\n }\n const timeout = this.options.stopTimeout ?? 15_000\n const timer = setTimeout(() => {\n if (running.killed) return\n running.killed = true\n this.options.error(`The server did not stop within ${timeout / 1000} seconds and was killed.`)\n running.child.kill('SIGKILL')\n }, timeout)\n try {\n await running.exited\n } finally {\n clearTimeout(timer)\n }\n }\n\n private listenForSignals(): () => void {\n const signals = this.options.signals ?? (['SIGINT', 'SIGTERM', 'SIGHUP'] as const)\n const handler = () => this.stop()\n for (const signal of signals) process.on(signal, handler)\n return () => {\n for (const signal of signals) process.off(signal, handler)\n }\n }\n}\n","import { ConsoleKernel, ExceptionHandler, HttpKernel, Redirector, ResponseFactory, Router } from '@orieljs/contracts'\nimport { ServiceProvider } from '@orieljs/support'\nimport { registerHttpCommands } from './commands'\nimport { ErrorHandler } from './ErrorHandler'\nimport { applyExceptionCallbacks } from './ExceptionsConfiguration'\nimport { HttpRedirector } from './HttpRedirector'\nimport { HttpResponseFactory } from './HttpResponseFactory'\nimport { Kernel } from './Kernel'\nimport { applyMiddlewareCallbacks } from './MiddlewareConfiguration'\n\n/**\n * Binds the HTTP kernel (replacing any kernel bound before, such as Foundation's ClosureKernel), the exception\n * handler, the response factory and the redirector, and merges the `http` config defaults.\n *\n * The HttpRequest is deliberately NOT bound on the application: the kernel creates one per request and puts it in\n * the request scope with scope.instance(). A root `scoped()` binding would make bound(HttpRequest) true everywhere,\n * and that check is how the URL generator, the redirects and the helpers know they are inside a request.\n */\nexport class HttpServiceProvider extends ServiceProvider {\n override register(): void {\n this.mergeConfigFrom(\n {\n trusted_proxies: [],\n max_body_size: 8 * 1024 * 1024,\n max_json_depth: 512,\n csrf_except: [],\n redirect_guests_to: undefined,\n redirect_users_to: undefined,\n },\n 'http',\n )\n this.app.singleton(HttpKernel, () => new Kernel(this.app))\n this.app.singleton(ExceptionHandler, () => {\n const handler = new ErrorHandler(this.app)\n applyExceptionCallbacks(this.app, handler)\n return handler\n })\n this.app.singleton(ResponseFactory, () => new HttpResponseFactory())\n this.app.singleton(Redirector, () => new HttpRedirector())\n }\n\n override boot(): void {\n // After every provider's boot(), so web({ remove }) and alias() overrides see the components' defaults.\n this.app.booted(() => {\n const kernel = this.app.make(HttpKernel)\n if (kernel instanceof Kernel && this.app.bound(Router)) applyMiddlewareCallbacks(this.app, kernel)\n })\n if (this.app.bound(ConsoleKernel)) registerHttpCommands(this.app.make(ConsoleKernel), this.app)\n }\n}\n"],"mappings":"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","names":["response","url","request","request","inject","inject","Session","currentContainer","inject","Str","Str","inject","Session","currentContainer","HttpRequest","UrlGenerator","inject","inject","HttpRequest","UrlGenerator","inject","inject","CurrentRoute","HttpRequest","currentContainer","request","request","currentContainer","request","response","HttpRequest","route","CurrentRoute","ConfigRepository","Router","url","ConfigRepository","Redirector","UrlGenerator","ViewFactory","currentContainer","url","request","response","Redirector","redirect","UrlGenerator","url","ViewFactory","ConfigRepository","currentContainer","basename","resolve","createReadStream","stat","Readable","request","stat","Readable","createReadStream","request","response","url","resolve","basename","url","request","response","resolve","request","response","Readable","url","response","Readable","request","resolve","existsSync","mkdir","readFile","writeFile","dirname","resolve","ConfigRepository","Router","existsSync","join","parseEnv","existsSync","statSync","join","createServer","resolve","createServer","resolve","route","ConfigRepository","resolve","Router","existsSync","mkdir","dirname","writeFile","readFile","ExceptionHandler","HttpKernel","Redirector","ResponseFactory","Router","HttpKernel","ExceptionHandler","ResponseFactory","Redirector","Router"]}