@orieljs/http 0.1.0-alpha.1 → 0.1.0-alpha.3
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.d.ts +19 -4
- package/dist/index.js +57 -13
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpRequest, CookieJar, Session, Container, RedirectResponse, HeadersInit, Redirector, UploadedFile, Rules, OrielError, ResponseFactory, BodyInit, UrlGenerator, HttpKernel, Application, MiddlewareClass, Middleware, Next, MiddlewareConfigurator, Router, ConfigRepository, ExceptionHandler, ExceptionsConfigurator, ConsoleKernel, Route } from '@orieljs/contracts';
|
|
1
|
+
import { HttpRequest, CookieJar, Session, Container, RedirectResponse, HeadersInit, Redirector, UploadedFile, Rules, OrielError, RouteName, ResponseFactory, BodyInit, UrlGenerator, HttpKernel, Application, MiddlewareClass, Middleware, Next, MiddlewareConfigurator, Router, ConfigRepository, ExceptionHandler, ExceptionsConfigurator, ConsoleKernel, Route } from '@orieljs/contracts';
|
|
2
2
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
3
|
import { ServiceProvider } from '@orieljs/support';
|
|
4
4
|
|
|
@@ -215,8 +215,12 @@ declare function request<T = unknown>(key: string, defaultValue?: T): T;
|
|
|
215
215
|
/** response() → the ResponseFactory; response(content, status, headers) → a Response. */
|
|
216
216
|
declare function response(): ResponseFactory;
|
|
217
217
|
declare function response(content: BodyInit | null, status?: number, headers?: HeadersInit): Response;
|
|
218
|
+
/** The Redirector with its route() typed by the generated route names. */
|
|
219
|
+
type TypedRedirector = Omit<Redirector, 'route'> & {
|
|
220
|
+
route(name: RouteName, parameters?: unknown, status?: number): RedirectResponse;
|
|
221
|
+
};
|
|
218
222
|
/** redirect() → the Redirector; redirect('/path', status) → a RedirectResponse. */
|
|
219
|
-
declare function redirect():
|
|
223
|
+
declare function redirect(): TypedRedirector;
|
|
220
224
|
declare function redirect(to: string, status?: number): RedirectResponse;
|
|
221
225
|
/** Redirect to the previous URL (same argument order as Redirector.back()). */
|
|
222
226
|
declare function back(fallback?: string, status?: number): RedirectResponse;
|
|
@@ -224,7 +228,7 @@ declare function back(fallback?: string, status?: number): RedirectResponse;
|
|
|
224
228
|
declare function url(): UrlGenerator;
|
|
225
229
|
declare function url(path: string, query?: Record<string, unknown>, absolute?: boolean): string;
|
|
226
230
|
/** The URL of a named route. */
|
|
227
|
-
declare function route(name:
|
|
231
|
+
declare function route(name: RouteName, parameters?: unknown, absolute?: boolean): string;
|
|
228
232
|
/** abort(404), abort(403, 'Nope', headers), or abort(response) to send a ready response. */
|
|
229
233
|
declare function abort(status: number | Response, message?: string, headers?: Record<string, string>): never;
|
|
230
234
|
declare function abortIf(condition: unknown, status: number | Response, message?: string, headers?: Record<string, string>): void;
|
|
@@ -373,12 +377,16 @@ interface ServeOptions {
|
|
|
373
377
|
runtime?: Runtime;
|
|
374
378
|
/** Called once listening. Default: prints "Server running on [url]." */
|
|
375
379
|
onListen?: (server: RunningServer) => void;
|
|
380
|
+
/** Serve existing files from this directory before the app (Laravel's server.php). Default: app.publicPath(); false turns it off. */
|
|
381
|
+
publicPath?: string | false;
|
|
376
382
|
}
|
|
377
383
|
interface ResolvedServeOptions {
|
|
378
384
|
readonly port: number;
|
|
379
385
|
readonly hostname: string;
|
|
380
386
|
readonly signals: boolean;
|
|
381
387
|
readonly shutdownTimeout: number;
|
|
388
|
+
/** Where public files are served from, or undefined when turned off. */
|
|
389
|
+
readonly publicPath?: string;
|
|
382
390
|
}
|
|
383
391
|
interface RunningServer {
|
|
384
392
|
readonly runtime: Runtime;
|
|
@@ -421,6 +429,13 @@ declare function detectRuntime(): Runtime;
|
|
|
421
429
|
/** Boots the app and serves it with node:http or Bun.serve (public/index.ts: `await serve(app)`). */
|
|
422
430
|
declare function serve(app: Application, options?: ServeOptions): Promise<RunningServer>;
|
|
423
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Laravel's server.php for `artisan serve`: a GET or HEAD for a file that exists under public/ is answered
|
|
434
|
+
* with that file, so the built Vite assets (public/build) and other public files work without a web server.
|
|
435
|
+
* Anything else (directories, missing files, other methods) returns undefined and goes to the application.
|
|
436
|
+
*/
|
|
437
|
+
declare function servePublicFile(publicPath: string, request: Request): Promise<Response | undefined>;
|
|
438
|
+
|
|
424
439
|
interface RouteListRow {
|
|
425
440
|
/** 'GET|HEAD' */
|
|
426
441
|
readonly method: string;
|
|
@@ -477,4 +492,4 @@ declare class HttpServiceProvider extends ServiceProvider {
|
|
|
477
492
|
boot(): void;
|
|
478
493
|
}
|
|
479
494
|
|
|
480
|
-
export { API_ROUTES_STUB, ConvertEmptyStringsToNull, type ErrorClass, ErrorHandler, ExceptionsConfiguration, FormUploadedFile, type HttpCommandOptions, HttpException, HttpRedirectResponse, HttpRedirector, HttpResponseException, HttpResponseFactory, HttpServerError, HttpServiceProvider, IncomingRequest, type IncomingRequestOptions, Kernel, MiddlewareConfiguration, type RenderCallback, type ReportCallback, type ResolvedServeOptions, type RouteListFilters, type RouteListRow, type RunningServer, type Runtime, type ServeOptions, type StackFrame, TrimStrings, abort, abortIf, abortUnless, addApiRouting, applyExceptionCallbacks, applyMiddlewareCallbacks, back, bunRuntime, clientAddress, contentDisposition, currentRequest, debugPage, detectRuntime, escapeHtml, extensionFromMime, filterRouteList, formatRouteList, fromEntries, ipMatches, isBlank, mergeRecursive, mimeFromExtension, minimalPage, normalizeLists, optionalCookieJar, optionalSession, parseBracketKey, readBody, redirect, registerHttpCommands, request, requestScope, response, route, routeListRows, sanitize, serve, serveBun, serveNode, setClientAddress, stackFrames, statusFor, statusText, summarizeValidation, toWebRequest, transformLeaves, url, writeResponse };
|
|
495
|
+
export { API_ROUTES_STUB, ConvertEmptyStringsToNull, type ErrorClass, ErrorHandler, ExceptionsConfiguration, FormUploadedFile, type HttpCommandOptions, HttpException, HttpRedirectResponse, HttpRedirector, HttpResponseException, HttpResponseFactory, HttpServerError, HttpServiceProvider, IncomingRequest, type IncomingRequestOptions, Kernel, MiddlewareConfiguration, type RenderCallback, type ReportCallback, type ResolvedServeOptions, type RouteListFilters, type RouteListRow, type RunningServer, type Runtime, type ServeOptions, type StackFrame, TrimStrings, type TypedRedirector, abort, abortIf, abortUnless, addApiRouting, applyExceptionCallbacks, applyMiddlewareCallbacks, back, bunRuntime, clientAddress, contentDisposition, currentRequest, debugPage, detectRuntime, escapeHtml, extensionFromMime, filterRouteList, formatRouteList, fromEntries, ipMatches, isBlank, mergeRecursive, mimeFromExtension, minimalPage, normalizeLists, optionalCookieJar, optionalSession, parseBracketKey, readBody, redirect, registerHttpCommands, request, requestScope, response, route, routeListRows, sanitize, serve, serveBun, serveNode, servePublicFile, setClientAddress, stackFrames, statusFor, statusText, summarizeValidation, toWebRequest, transformLeaves, url, writeResponse };
|
package/dist/index.js
CHANGED
|
@@ -210,13 +210,16 @@ var TYPES = {
|
|
|
210
210
|
ico: "image/vnd.microsoft.icon",
|
|
211
211
|
jpg: "image/jpeg",
|
|
212
212
|
js: "text/javascript",
|
|
213
|
+
map: "application/json",
|
|
213
214
|
json: "application/json",
|
|
214
215
|
md: "text/markdown",
|
|
215
216
|
mp3: "audio/mpeg",
|
|
216
217
|
mp4: "video/mp4",
|
|
218
|
+
otf: "font/otf",
|
|
217
219
|
pdf: "application/pdf",
|
|
218
220
|
png: "image/png",
|
|
219
221
|
svg: "image/svg+xml",
|
|
222
|
+
ttf: "font/ttf",
|
|
220
223
|
txt: "text/plain",
|
|
221
224
|
wasm: "application/wasm",
|
|
222
225
|
webm: "video/webm",
|
|
@@ -1417,6 +1420,41 @@ function applyExceptionCallbacks(app, handler) {
|
|
|
1417
1420
|
|
|
1418
1421
|
// server/types.ts
|
|
1419
1422
|
import { HttpKernel } from "@orieljs/contracts";
|
|
1423
|
+
|
|
1424
|
+
// server/static.ts
|
|
1425
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
1426
|
+
import { stat as stat2 } from "fs/promises";
|
|
1427
|
+
import { Readable as Readable2 } from "stream";
|
|
1428
|
+
import { relative, resolve, sep } from "path";
|
|
1429
|
+
var HIDDEN_SEGMENT = /^\.|\.(ts|tsx|mts|cts)$|[. ]$/i;
|
|
1430
|
+
async function servePublicFile(publicPath, request2) {
|
|
1431
|
+
if (request2.method !== "GET" && request2.method !== "HEAD") return void 0;
|
|
1432
|
+
let pathname;
|
|
1433
|
+
try {
|
|
1434
|
+
pathname = decodeURIComponent(new URL(request2.url).pathname);
|
|
1435
|
+
} catch {
|
|
1436
|
+
return void 0;
|
|
1437
|
+
}
|
|
1438
|
+
if (pathname === "/" || pathname.includes("\0")) return void 0;
|
|
1439
|
+
const root = resolve(publicPath);
|
|
1440
|
+
const file = resolve(root, `.${pathname}`);
|
|
1441
|
+
if (!file.startsWith(root + sep)) return void 0;
|
|
1442
|
+
if (relative(root, file).split(/[\\/]/).some((segment) => HIDDEN_SEGMENT.test(segment))) return void 0;
|
|
1443
|
+
const info = await stat2(file).catch(() => void 0);
|
|
1444
|
+
if (info === void 0 || !info.isFile()) return void 0;
|
|
1445
|
+
const type = mimeFromExtension(file);
|
|
1446
|
+
const headers = new Headers({
|
|
1447
|
+
"content-type": type.startsWith("text/") || type === "application/json" ? `${type}; charset=utf-8` : type,
|
|
1448
|
+
"content-length": String(info.size),
|
|
1449
|
+
"last-modified": info.mtime.toUTCString()
|
|
1450
|
+
});
|
|
1451
|
+
if (pathname.startsWith("/build/assets/")) headers.set("cache-control", "public, max-age=31536000, immutable");
|
|
1452
|
+
if (request2.method === "HEAD") return new Response(null, { status: 200, headers });
|
|
1453
|
+
const body = Readable2.toWeb(createReadStream2(file));
|
|
1454
|
+
return new Response(body, { status: 200, headers });
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// server/types.ts
|
|
1420
1458
|
async function terminateRequest(app, request2, response2) {
|
|
1421
1459
|
try {
|
|
1422
1460
|
if (app.bound(HttpKernel)) await app.make(HttpKernel).terminate?.(request2, response2);
|
|
@@ -1424,8 +1462,12 @@ async function terminateRequest(app, request2, response2) {
|
|
|
1424
1462
|
console.error(error);
|
|
1425
1463
|
}
|
|
1426
1464
|
}
|
|
1427
|
-
async function handleSafely(app, request2) {
|
|
1465
|
+
async function handleSafely(app, request2, publicPath) {
|
|
1428
1466
|
try {
|
|
1467
|
+
if (publicPath !== void 0) {
|
|
1468
|
+
const file = await servePublicFile(publicPath, request2);
|
|
1469
|
+
if (file !== void 0) return file;
|
|
1470
|
+
}
|
|
1429
1471
|
return await app.handle(request2);
|
|
1430
1472
|
} catch (error) {
|
|
1431
1473
|
console.error(error);
|
|
@@ -1453,13 +1495,13 @@ async function serveBun(app, options) {
|
|
|
1453
1495
|
const bun = bunRuntime();
|
|
1454
1496
|
if (bun === void 0) throw new HttpServerError("Bun.serve is not available: the process is not running on Bun.");
|
|
1455
1497
|
let markClosed = () => void 0;
|
|
1456
|
-
const closed = new Promise((
|
|
1498
|
+
const closed = new Promise((resolve2) => markClosed = resolve2);
|
|
1457
1499
|
const server = bun.serve({
|
|
1458
1500
|
port: options.port,
|
|
1459
1501
|
hostname: options.hostname,
|
|
1460
1502
|
async fetch(request2, current) {
|
|
1461
1503
|
setClientAddress(request2, current.requestIP(request2)?.address);
|
|
1462
|
-
const response2 = await handleSafely(app, request2);
|
|
1504
|
+
const response2 = await handleSafely(app, request2, options.publicPath);
|
|
1463
1505
|
setTimeout(() => void terminateRequest(app, request2, response2), 0);
|
|
1464
1506
|
return response2;
|
|
1465
1507
|
},
|
|
@@ -1471,8 +1513,8 @@ async function serveBun(app, options) {
|
|
|
1471
1513
|
let closing;
|
|
1472
1514
|
const close = () => closing ??= (async () => {
|
|
1473
1515
|
let timer;
|
|
1474
|
-
const forced = new Promise((
|
|
1475
|
-
timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(
|
|
1516
|
+
const forced = new Promise((resolve2) => {
|
|
1517
|
+
timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(resolve2), options.shutdownTimeout);
|
|
1476
1518
|
});
|
|
1477
1519
|
await Promise.race([Promise.resolve(server.stop(false)), forced]);
|
|
1478
1520
|
clearTimeout(timer);
|
|
@@ -1491,7 +1533,7 @@ async function serveBun(app, options) {
|
|
|
1491
1533
|
|
|
1492
1534
|
// server/node.ts
|
|
1493
1535
|
import { createServer } from "http";
|
|
1494
|
-
import { Readable as
|
|
1536
|
+
import { Readable as Readable3 } from "stream";
|
|
1495
1537
|
import { pipeline } from "stream/promises";
|
|
1496
1538
|
function requestBody(req) {
|
|
1497
1539
|
let finished = false;
|
|
@@ -1573,7 +1615,7 @@ async function writeResponse(res, response2) {
|
|
|
1573
1615
|
res.end();
|
|
1574
1616
|
return;
|
|
1575
1617
|
}
|
|
1576
|
-
await pipeline(
|
|
1618
|
+
await pipeline(Readable3.fromWeb(response2.body), res);
|
|
1577
1619
|
}
|
|
1578
1620
|
async function serveNode(app, options) {
|
|
1579
1621
|
const fallbackHost = `${displayHost(options.hostname)}:${options.port}`;
|
|
@@ -1588,7 +1630,7 @@ async function serveNode(app, options) {
|
|
|
1588
1630
|
return;
|
|
1589
1631
|
}
|
|
1590
1632
|
setClientAddress(request2, req.socket.remoteAddress);
|
|
1591
|
-
const response2 = await handleSafely(app, request2);
|
|
1633
|
+
const response2 = await handleSafely(app, request2, options.publicPath);
|
|
1592
1634
|
try {
|
|
1593
1635
|
await writeResponse(res, response2);
|
|
1594
1636
|
} catch {
|
|
@@ -1597,18 +1639,18 @@ async function serveNode(app, options) {
|
|
|
1597
1639
|
await terminateRequest(app, request2, response2);
|
|
1598
1640
|
})();
|
|
1599
1641
|
});
|
|
1600
|
-
await new Promise((
|
|
1642
|
+
await new Promise((resolve2, reject) => {
|
|
1601
1643
|
server.once("error", reject);
|
|
1602
1644
|
server.listen(options.port, options.hostname, () => {
|
|
1603
1645
|
server.off("error", reject);
|
|
1604
|
-
|
|
1646
|
+
resolve2();
|
|
1605
1647
|
});
|
|
1606
1648
|
});
|
|
1607
1649
|
const address = server.address();
|
|
1608
|
-
const closed = new Promise((
|
|
1650
|
+
const closed = new Promise((resolve2) => server.once("close", () => resolve2()));
|
|
1609
1651
|
let closing;
|
|
1610
1652
|
const close = () => closing ??= (async () => {
|
|
1611
|
-
const done = new Promise((
|
|
1653
|
+
const done = new Promise((resolve2) => server.close(() => resolve2()));
|
|
1612
1654
|
server.closeIdleConnections();
|
|
1613
1655
|
const idle = setInterval(() => server.closeIdleConnections(), 50);
|
|
1614
1656
|
const force = setTimeout(() => server.closeAllConnections(), options.shutdownTimeout);
|
|
@@ -1636,7 +1678,8 @@ async function serve(app, options = {}) {
|
|
|
1636
1678
|
port: options.port ?? Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8e3),
|
|
1637
1679
|
hostname: options.hostname ?? "127.0.0.1",
|
|
1638
1680
|
signals: options.signals ?? true,
|
|
1639
|
-
shutdownTimeout: options.shutdownTimeout ?? 1e4
|
|
1681
|
+
shutdownTimeout: options.shutdownTimeout ?? 1e4,
|
|
1682
|
+
...options.publicPath !== false && { publicPath: options.publicPath ?? app.publicPath() }
|
|
1640
1683
|
};
|
|
1641
1684
|
await app.boot();
|
|
1642
1685
|
const runtime = options.runtime ?? detectRuntime();
|
|
@@ -1895,6 +1938,7 @@ export {
|
|
|
1895
1938
|
serve,
|
|
1896
1939
|
serveBun,
|
|
1897
1940
|
serveNode,
|
|
1941
|
+
servePublicFile,
|
|
1898
1942
|
setClientAddress,
|
|
1899
1943
|
stackFrames,
|
|
1900
1944
|
statusFor,
|
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/bun.ts","../server/node.ts","../server/serve.ts","../commands.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/** 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, RedirectResponse } from '@orieljs/contracts'\nimport { currentRequest, optionalCookieJar, optionalSession } from './context'\n\ntype ErrorsInput = Record<string, string | string[]> | { toObject(): Record<string, string[]> }\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 { toObject(): Record<string, string[]> }).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/** 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 /** Remembers where a guest was going (a GET page, else the previous URL), then redirects to `path`. */\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', 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 { Str } from '@orieljs/support'\nimport { extensionFromMime } from './mime'\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 constructor(private readonly file: Blob & { readonly name?: string }) {\n this.clientName = file.name ?? ''\n this.mimeType = file.type === '' ? 'application/octet-stream' : file.type\n this.size = file.size\n }\n\n /** Guessed from the MIME type, falling back to the client's extension (Laravel's extension()). */\n extension(): string {\n return extensionFromMime(this.mimeType) ?? this.clientExtension()\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 json: 'application/json',\n md: 'text/markdown',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n pdf: 'application/pdf',\n png: 'image/png',\n svg: 'image/svg+xml',\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 CurrentRoute,\n Session,\n ValidationFactory,\n type HttpRequest,\n type Rules,\n type UploadedFile,\n} from '@orieljs/contracts'\nimport { currentContainer, inject } from '@orieljs/container'\nimport { Arr, Str } from '@orieljs/support'\nimport { readBody } from './body'\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}\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 #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.#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 errors (413) 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 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 this.#parseForm(await new Response(bytes, { 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 #parseForm(form: FormData): 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, new FormUploadedFile(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 string(key: string, defaultValue = ''): string {\n const value = this.input<unknown>(key)\n return value === undefined || value === null ? defaultValue : String(value)\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 user<T = unknown>(guard?: string): T | undefined {\n return this.#userResolver?.(guard) as T | undefined\n }\n\n setUserResolver(resolver: (guard?: string) => unknown): void {\n this.#userResolver = resolver\n }\n\n /** Validates all() through the ValidationFactory; throws its Validation error on failure. */\n validate<T = Record<string, unknown>>(\n rules: Rules,\n messages?: Record<string, string>,\n attributes?: Record<string, string>,\n ): Promise<T> {\n return inject(ValidationFactory).make(this.all(), rules, messages, attributes).validated<T>()\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} from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException, HttpResponseException } from './errors'\n\n/** request() → the current HttpRequest; request('key', default) → its input. */\nexport function request(): HttpRequest\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/** redirect() → the Redirector; redirect('/path', status) → a RedirectResponse. */\nexport function redirect(): Redirector\nexport function redirect(to: string, status?: number): RedirectResponse\nexport function redirect(to?: string, status?: number): Redirector | 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/** The URL of a named route. */\nexport function route(name: string, parameters?: unknown, absolute?: boolean): string {\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, { trustedProxies: this.#trustedProxies(), maxBodySize: this.#maxBodySize() })\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.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\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\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 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 (http.expectsJson()) response = this.#renderJson(error)\n else response = await this.#renderHtml(http, error)\n\n const headers = (error as Partial<OrielError> | null)?.headers\n if (headers !== undefined) for (const [name, value] of Object.entries(headers)) response.headers.set(name, value)\n return response\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 (request.expectsJson()) {\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 (request.expectsJson()) 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","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 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 413: 'Content Too Large',\n 415: 'Unsupported Media Type',\n 419: 'Page Expired',\n 422: 'Unprocessable Content',\n 429: 'Too Many Requests',\n 500: 'Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n}\n\n/** Laravel's wording for the status (its error pages say \"Server Error\" and \"Page Expired\"). */\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 } 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\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'\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}\n\nexport interface ResolvedServeOptions {\n readonly port: number\n readonly hostname: string\n readonly signals: boolean\n readonly shutdownTimeout: number\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/** app.handle(), turning a crash outside the kernel into a plain 500. */\nexport async function handleSafely(app: Application, request: Request): Promise<Response> {\n try {\n return await app.handle(request)\n } catch (error) {\n console.error(error)\n return plainServerError()\n }\n}\n\n/** SIGINT/SIGTERM → close() → process.exit(0). The listeners go away when the server closes. */\nexport function exitOnSignals(close: () => Promise<void>, closed: Promise<void>): void {\n const onSignal = () => {\n void close().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 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)\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)\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)\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)\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 }\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'\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}\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\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 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 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. Run [oriel migrate] to create the personal access tokens table.')\n return 0\n })\n .purpose('Create an API routes file and prepare the application for API authentication')\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 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","request","response","request","response","Readable","url","response","Readable","request","readFile","Router","route","Router","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","../server/types.ts","../server/static.ts","../server/bun.ts","../server/node.ts","../server/serve.ts","../commands.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/** 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, RedirectResponse } from '@orieljs/contracts'\nimport { currentRequest, optionalCookieJar, optionalSession } from './context'\n\ntype ErrorsInput = Record<string, string | string[]> | { toObject(): Record<string, string[]> }\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 { toObject(): Record<string, string[]> }).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/** 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 /** Remembers where a guest was going (a GET page, else the previous URL), then redirects to `path`. */\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', 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 { Str } from '@orieljs/support'\nimport { extensionFromMime } from './mime'\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 constructor(private readonly file: Blob & { readonly name?: string }) {\n this.clientName = file.name ?? ''\n this.mimeType = file.type === '' ? 'application/octet-stream' : file.type\n this.size = file.size\n }\n\n /** Guessed from the MIME type, falling back to the client's extension (Laravel's extension()). */\n extension(): string {\n return extensionFromMime(this.mimeType) ?? this.clientExtension()\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 CurrentRoute,\n Session,\n ValidationFactory,\n type HttpRequest,\n type Rules,\n type UploadedFile,\n} from '@orieljs/contracts'\nimport { currentContainer, inject } from '@orieljs/container'\nimport { Arr, Str } from '@orieljs/support'\nimport { readBody } from './body'\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}\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 #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.#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 errors (413) 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 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 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 #parseForm(form: FormData): 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, new FormUploadedFile(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 string(key: string, defaultValue = ''): string {\n const value = this.input<unknown>(key)\n return value === undefined || value === null ? defaultValue : String(value)\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 user<T = unknown>(guard?: string): T | undefined {\n return this.#userResolver?.(guard) as T | undefined\n }\n\n setUserResolver(resolver: (guard?: string) => unknown): void {\n this.#userResolver = resolver\n }\n\n /** Validates all() through the ValidationFactory; throws its Validation error on failure. */\n validate<T = Record<string, unknown>>(\n rules: Rules,\n messages?: Record<string, string>,\n attributes?: Record<string, string>,\n ): Promise<T> {\n return inject(ValidationFactory).make(this.all(), rules, messages, attributes).validated<T>()\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 RouteName,\n} from '@orieljs/contracts'\nimport { inject } from '@orieljs/container'\nimport { HttpException, HttpResponseException } from './errors'\n\n/** request() → the current HttpRequest; request('key', default) → its input. */\nexport function request(): HttpRequest\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. */\nexport type TypedRedirector = Omit<Redirector, 'route'> & {\n route(name: RouteName, parameters?: unknown, 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/** The URL of a named route. */\nexport function route(name: RouteName, parameters?: unknown, absolute?: boolean): string {\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, { trustedProxies: this.#trustedProxies(), maxBodySize: this.#maxBodySize() })\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.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\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\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 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 (http.expectsJson()) response = this.#renderJson(error)\n else response = await this.#renderHtml(http, error)\n\n const headers = (error as Partial<OrielError> | null)?.headers\n if (headers !== undefined) for (const [name, value] of Object.entries(headers)) response.headers.set(name, value)\n return response\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 (request.expectsJson()) {\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 (request.expectsJson()) 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","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 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 413: 'Content Too Large',\n 415: 'Unsupported Media Type',\n 419: 'Page Expired',\n 422: 'Unprocessable Content',\n 429: 'Too Many Requests',\n 500: 'Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n}\n\n/** Laravel's wording for the status (its error pages say \"Server Error\" and \"Page Expired\"). */\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 } 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\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/** SIGINT/SIGTERM → close() → process.exit(0). The listeners go away when the server closes. */\nexport function exitOnSignals(close: () => Promise<void>, closed: Promise<void>): void {\n const onSignal = () => {\n void close().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)\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)\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'\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}\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\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 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 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. Run [oriel migrate] to create the personal access tokens table.')\n return 0\n })\n .purpose('Create an API routes file and prepare the application for API authentication')\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 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","readFile","Router","route","Router","readFile","ExceptionHandler","HttpKernel","Redirector","ResponseFactory","Router","HttpKernel","ExceptionHandler","ResponseFactory","Redirector","Router"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orieljs/http",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
4
|
"description": "The Oriel Http component.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
|
+
"homepage": "https://orieljs.vercel.app",
|
|
7
8
|
"sideEffects": false,
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
@@ -29,9 +30,9 @@
|
|
|
29
30
|
"NOTICE"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@orieljs/contracts": "0.1.0-alpha.
|
|
33
|
-
"@orieljs/container": "0.1.0-alpha.
|
|
34
|
-
"@orieljs/support": "0.1.0-alpha.
|
|
33
|
+
"@orieljs/contracts": "0.1.0-alpha.3",
|
|
34
|
+
"@orieljs/container": "0.1.0-alpha.3",
|
|
35
|
+
"@orieljs/support": "0.1.0-alpha.3"
|
|
35
36
|
},
|
|
36
37
|
"scripts": {
|
|
37
38
|
"build": "tsup && node ../../../scripts/copy-license.mjs"
|