@torpor/build 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/run.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { S as Site } from './Site-PxPCXGZ-.cjs';
1
+ import { S as Site } from './Site-CM2pZtq6.cjs';
2
2
  import 'vite';
3
- import './Server-B45PD5Ys.cjs';
3
+ import './Server-DhJ1nRFR.cjs';
4
4
  import 'cookie';
5
5
 
6
6
  declare function run(folder: string, mode: "dev" | "build" | "preview"): Promise<void>;
package/dist/run.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { S as Site } from './Site-Qpcmx0Xq.js';
1
+ import { S as Site } from './Site-BB6kV7wC.js';
2
2
  import 'vite';
3
- import './Server-B45PD5Ys.js';
3
+ import './Server-DhJ1nRFR.js';
4
4
  import 'cookie';
5
5
 
6
6
  declare function run(folder: string, mode: "dev" | "build" | "preview"): Promise<void>;
package/dist/run.js CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  runBuild,
4
4
  runDev,
5
5
  runPreview
6
- } from "./chunk-ZSWD4UBH.js";
6
+ } from "./chunk-4YLPLGR2.js";
7
7
  import "./chunk-VAGHGWM5.js";
8
- import "./chunk-65Z6BF2N.js";
8
+ import "./chunk-FLQZX64D.js";
9
9
  import "./chunk-T5K52YVJ.js";
10
10
  export {
11
11
  run,
package/dist/server.cjs CHANGED
@@ -92,6 +92,7 @@ var ServerEvent = class {
92
92
  response;
93
93
  // TODO: Should we cast types??
94
94
  params;
95
+ adapter;
95
96
  cookies;
96
97
  headers;
97
98
  constructor(request, params) {
@@ -99,6 +100,7 @@ var ServerEvent = class {
99
100
  this.params = params;
100
101
  this.cookies = new CookieHelper(request);
101
102
  this.headers = new HeaderHelper(request);
103
+ this.adapter = globalThis.adapter;
102
104
  }
103
105
  addHeaders() {
104
106
  if (!this.response) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts","../src/server/CookieHelper.ts","../src/server/HeaderHelper.ts","../src/site/pathToRegex.ts","../src/server/ServerEvent.ts","../src/server/Server.ts","../src/server/connect/flattenHeaders.ts","../src/server/connect/nodeMessageToNodeResponse.ts","../src/server/connect/readableToBuffer.ts","../src/server/connect/requestToNodeMessage.ts","../src/server/connect/connectMiddleware.ts"],"sourcesContent":["import CookieHelper from \"./server/CookieHelper\";\nimport HeaderHelper from \"./server/HeaderHelper\";\nimport Server from \"./server/Server\";\nimport ServerEvent from \"./server/ServerEvent\";\nimport connectMiddleware from \"./server/connect/connectMiddleware\";\n\nexport { Server, ServerEvent, CookieHelper, HeaderHelper, connectMiddleware };\n","import { SerializeOptions, parse, serialize } from \"cookie\";\n\nexport default class CookieHelper {\n\trequest: Request;\n\tcookies: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.cookies.has(name)) {\n\t\t\treturn this.cookies.get(name);\n\t\t}\n\t\t// Otherwise, return the cookie value from the `Cookie` header\n\t\tconst header = this.request.headers.get(\"cookie\");\n\t\treturn parse(header ?? \"\")[name];\n\t}\n\n\tset(name: string, value: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with some default values for security\n\t\toptions ??= {};\n\t\toptions.httpOnly ??= true;\n\t\toptions.secure ??= true;\n\t\toptions.sameSite ??= \"lax\";\n\t\tthis.cookies.set(name, serialize(name, value, options));\n\t}\n\n\tdelete(name: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with an immediate expiry date\n\t\toptions ??= {};\n\t\toptions.expires = new Date(0);\n\t\tthis.cookies.set(name, serialize(name, \"\", options));\n\t}\n}\n","export default class HeaderHelper {\n\trequest: Request;\n\theaders: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.headers.has(name)) {\n\t\t\treturn this.headers.get(name);\n\t\t}\n\t\t// Otherwise, return the value from the header\n\t\treturn this.request.headers.get(name) ?? undefined;\n\t}\n\n\tset(name: string, value: string) {\n\t\tthis.headers.set(name, value);\n\t}\n\n\tdelete(name: string) {\n\t\tthis.headers.delete(name);\n\t}\n}\n","export default function pathToRegex(path: string): RegExp {\n\tconst pattern = path\n\t\t.split(\"/\")\n\t\t.map((p) => {\n\t\t\treturn p.replace(/\\[([^\\/]+?)\\]/, \"(?<$1>[^\\\\/]+?)\");\n\t\t})\n\t\t.join(\"\\\\/\")\n\t\t.replaceAll(\"*\", \".*\");\n\treturn new RegExp(`^${pattern}$`);\n}\n","import CookieHelper from \"./CookieHelper\";\nimport HeaderHelper from \"./HeaderHelper\";\n\nexport default class ServerEvent {\n\trequest: Request;\n\tresponse?: Response;\n\t// TODO: Should we cast types??\n\tparams?: { [key: string]: string };\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\n\tconstructor(request: Request, params?: { [key: string]: string }) {\n\t\tthis.request = request;\n\t\tthis.params = params;\n\t\tthis.cookies = new CookieHelper(request);\n\t\tthis.headers = new HeaderHelper(request);\n\t}\n\n\taddHeaders() {\n\t\tif (!this.response) {\n\t\t\tthrow new Error(\"Response not created yet\");\n\t\t}\n\n\t\tfor (let cookie of this.cookies.cookies.values()) {\n\t\t\tthis.response.headers.append(\"set-cookie\", cookie);\n\t\t}\n\n\t\tfor (let header of this.headers.headers.entries()) {\n\t\t\tthis.response.headers.append(header[0], header[1]);\n\t\t}\n\t}\n}\n","import pathToRegex from \"../site/pathToRegex\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\nconst noop = () => {};\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst request = new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params);\n\n\t\tif (this.middleware.length) {\n\t\t\t// TODO: Get middleware that applies to this route only?\n\t\t\tawait this.middleware[0](ev, buildNext(this.middleware, 0));\n\t\t\tfunction buildNext(middleware: MiddlewareFunction[], i: number): () => void | Promise<void> {\n\t\t\t\tif (ev.response) {\n\t\t\t\t\treturn noop;\n\t\t\t\t}\n\n\t\t\t\tif (i < middleware.length - 1) {\n\t\t\t\t\tlet next = middleware[i + 1];\n\t\t\t\t\treturn async () => next(ev, buildNext(middleware, i + 1));\n\t\t\t\t} else {\n\t\t\t\t\treturn match\n\t\t\t\t\t\t? async () => {\n\t\t\t\t\t\t\t\tev.response = await match.fn(ev);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: noop;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tthis.routes.push(new RouteHandler(path, fn));\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string) {\n\t\tfor (let handler of this.routes) {\n\t\t\tlet match = path.match(handler.regex);\n\t\t\tif (match) {\n\t\t\t\treturn {\n\t\t\t\t\tfn: handler.fn,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tregex: RegExp;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import {\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeader,\n\ttype OutgoingHttpHeaders,\n\tServerResponse,\n} from \"node:http\";\nimport { PassThrough, Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts\n\n/**\n * Creates a custom ServerResponse object that allows for intercepting and\n * streaming the response.\n *\n * @param incomingMessage The incoming HTTP request message.\n * @returns An object containing the custom ServerResponse and a function that\n * takes a callback to invoke when the response is readable, providing an object\n * with the readable stream, headers and status code.\n */\nexport default function nodeMessageToNodeResponse(\n\tincomingMessage: IncomingMessage,\n): ServerResponseResponse {\n\tconst res = new ServerResponse(incomingMessage);\n\tconst passThrough = new PassThrough();\n\tlet handled = false;\n\n\tconst onReadable = (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => {\n\t\tconst handleReadable = () => {\n\t\t\tif (handled) return;\n\t\t\thandled = true;\n\t\t\tcb({\n\t\t\t\treadable: Readable.from(passThrough),\n\t\t\t\theaders: res.getHeaders(),\n\t\t\t\tstatus: res.statusCode,\n\t\t\t});\n\t\t};\n\n\t\tpassThrough.once(\"readable\", handleReadable);\n\t\tpassThrough.once(\"end\", handleReadable);\n\t};\n\n\tpassThrough.once(\"finish\", () => {\n\t\tres.emit(\"finish\");\n\t});\n\tpassThrough.once(\"close\", () => {\n\t\tres.destroy();\n\t\tres.emit(\"close\");\n\t});\n\tpassThrough.on(\"drain\", () => {\n\t\tres.emit(\"drain\");\n\t});\n\n\tres.write = passThrough.write.bind(passThrough);\n\tres.end = passThrough.end.bind(passThrough) as any;\n\n\tres.writeHead = function writeHead(\n\t\tstatusCode: number,\n\t\tstatusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t\theaders?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t): ServerResponse {\n\t\tres.statusCode = statusCode;\n\t\tif (typeof statusMessage === \"object\") {\n\t\t\theaders = statusMessage;\n\t\t\tstatusMessage = undefined;\n\t\t}\n\t\tif (headers) {\n\t\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t};\n\n\treturn {\n\t\tres,\n\t\tonReadable,\n\t};\n}\n\ntype ServerResponseResponse = {\n\tres: ServerResponse;\n\tonReadable: (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => void;\n};\n","import { Readable } from \"node:stream\";\n\nexport default function readableToBuffer(req: Readable): Promise<Buffer> {\n\treturn new Promise<Buffer>((resolve, reject) => {\n\t\tconst chunks: Buffer[] = [];\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tchunks.push(chunk);\n\t\t});\n\t\treq.on(\"end\", () => {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\treq.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\t});\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\nconst DUMMY_BASE_URL = \"http://localhost\";\n\n/**\n * Creates an IncomingMessage object from a web Request.\n *\n * @param {Request} request - The web Request object.\n * @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.\n */\nexport default function requestToNodeMessage(request: Request): IncomingMessage {\n\tconst parsedUrl = new URL(request.url, DUMMY_BASE_URL);\n\tconst pathAndQuery = (parsedUrl.pathname || \"\") + (parsedUrl.search || \"\");\n\t// HACK: Using Readable.fromWeb locks request.body so that the request cannot be used again\n\t// As we're only using this for Vite middlewares, it's safe to discard the body for now?\n\tconst body = /*request.body ? Readable.fromWeb(request.body as any) :*/ Readable.from([]);\n\n\treturn Object.assign(body, {\n\t\turl: pathAndQuery,\n\t\tmethod: request.method,\n\t\theaders: Object.fromEntries(request.headers),\n\t}) as IncomingMessage;\n}\n","import { IncomingMessage, ServerResponse } from \"node:http\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport flattenHeaders from \"./flattenHeaders\";\nimport nodeMessageToNodeResponse from \"./nodeMessageToNodeResponse\";\nimport readableToBuffer from \"./readableToBuffer\";\nimport requestToNodeMessage from \"./requestToNodeMessage\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\n/**\n * Converts a Connect-style middleware to a web-compatible request handler.\n *\n * @param handler - The Connect-style middleware function to be converted.\n * @returns A function that handles web requests and returns a Response or undefined.\n */\nexport default function connectMiddleware(\n\thandler: ConnectMiddleware | ConnectMiddlewareBoolean,\n): MiddlewareFunction {\n\treturn async (ev, next) => {\n\t\tconst req = requestToNodeMessage(ev.request);\n\t\tconst { res, onReadable } = nodeMessageToNodeResponse(req);\n\n\t\treturn new Promise<void>(async (resolve, reject) => {\n\t\t\tonReadable(async ({ readable, headers, status }) => {\n\t\t\t\tconst responseBody = statusCodesWithoutBody.includes(status)\n\t\t\t\t\t? null\n\t\t\t\t\t: //(Readable.toWeb(readable) as ReadableStream);\n\t\t\t\t\t\t// HACK: Chunked bodies are not being\n\t\t\t\t\t\t// read correctly somewhere...\n\t\t\t\t\t\tawait readableToBuffer(readable);\n\t\t\t\tev.response = new Response(responseBody, {\n\t\t\t\t\tstatus,\n\t\t\t\t\theaders: flattenHeaders(headers),\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tconst cnext = async (error?: unknown) => {\n\t\t\t\tif (error) {\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: Can we nest the next functions less? This is a bit weird\n\t\t\t\t\tawait next();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst handled = await handler(req, res, cnext);\n\t\t\t\tif (handled === false) {\n\t\t\t\t\tres.destroy();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tcnext(e);\n\t\t\t}\n\t\t});\n\t};\n}\n\nconst statusCodesWithoutBody = [\n\t100, // Continue\n\t101, // Switching Protocols\n\t102, // Processing (WebDAV)\n\t103, // Early Hints\n\t204, // No Content\n\t205, // Reset Content\n\t304, // Not Modified\n];\n\ntype NextFunction = (err?: unknown) => void;\ntype ConnectMiddleware<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => void | Promise<void>;\ntype ConnectMiddlewareBoolean<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => boolean | Promise<boolean>;\n"],"mappings":"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","names":["buildNext","v","import_node_stream"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/server/CookieHelper.ts","../src/server/HeaderHelper.ts","../src/site/pathToRegex.ts","../src/server/ServerEvent.ts","../src/server/Server.ts","../src/server/connect/flattenHeaders.ts","../src/server/connect/nodeMessageToNodeResponse.ts","../src/server/connect/readableToBuffer.ts","../src/server/connect/requestToNodeMessage.ts","../src/server/connect/connectMiddleware.ts"],"sourcesContent":["import CookieHelper from \"./server/CookieHelper\";\nimport HeaderHelper from \"./server/HeaderHelper\";\nimport Server from \"./server/Server\";\nimport ServerEvent from \"./server/ServerEvent\";\nimport connectMiddleware from \"./server/connect/connectMiddleware\";\n\nexport { Server, ServerEvent, CookieHelper, HeaderHelper, connectMiddleware };\n","import { SerializeOptions, parse, serialize } from \"cookie\";\n\nexport default class CookieHelper {\n\trequest: Request;\n\tcookies: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.cookies.has(name)) {\n\t\t\treturn this.cookies.get(name);\n\t\t}\n\t\t// Otherwise, return the cookie value from the `Cookie` header\n\t\tconst header = this.request.headers.get(\"cookie\");\n\t\treturn parse(header ?? \"\")[name];\n\t}\n\n\tset(name: string, value: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with some default values for security\n\t\toptions ??= {};\n\t\toptions.httpOnly ??= true;\n\t\toptions.secure ??= true;\n\t\toptions.sameSite ??= \"lax\";\n\t\tthis.cookies.set(name, serialize(name, value, options));\n\t}\n\n\tdelete(name: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with an immediate expiry date\n\t\toptions ??= {};\n\t\toptions.expires = new Date(0);\n\t\tthis.cookies.set(name, serialize(name, \"\", options));\n\t}\n}\n","export default class HeaderHelper {\n\trequest: Request;\n\theaders: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.headers.has(name)) {\n\t\t\treturn this.headers.get(name);\n\t\t}\n\t\t// Otherwise, return the value from the header\n\t\treturn this.request.headers.get(name) ?? undefined;\n\t}\n\n\tset(name: string, value: string) {\n\t\tthis.headers.set(name, value);\n\t}\n\n\tdelete(name: string) {\n\t\tthis.headers.delete(name);\n\t}\n}\n","export default function pathToRegex(path: string): RegExp {\n\tconst pattern = path\n\t\t.split(\"/\")\n\t\t.map((p) => {\n\t\t\treturn p.replace(/\\[([^\\/]+?)\\]/, \"(?<$1>[^\\\\/]+?)\");\n\t\t})\n\t\t.join(\"\\\\/\")\n\t\t.replaceAll(\"*\", \".*\");\n\treturn new RegExp(`^${pattern}$`);\n}\n","import CookieHelper from \"./CookieHelper\";\nimport HeaderHelper from \"./HeaderHelper\";\n\nexport default class ServerEvent {\n\trequest: Request;\n\tresponse?: Response;\n\t// TODO: Should we cast types??\n\tparams?: Record<string, string>;\n\n\tadapter: any;\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\n\tconstructor(request: Request, params?: Record<string, string>) {\n\t\tthis.request = request;\n\t\tthis.params = params;\n\t\tthis.cookies = new CookieHelper(request);\n\t\tthis.headers = new HeaderHelper(request);\n\n\t\t// Adapters may have added the `adapter` property to globalThis\n\t\t// @ts-ignore\n\t\tthis.adapter = globalThis.adapter;\n\t}\n\n\taddHeaders() {\n\t\tif (!this.response) {\n\t\t\tthrow new Error(\"Response not created yet\");\n\t\t}\n\n\t\tfor (let cookie of this.cookies.cookies.values()) {\n\t\t\tthis.response.headers.append(\"set-cookie\", cookie);\n\t\t}\n\n\t\tfor (let header of this.headers.headers.entries()) {\n\t\t\tthis.response.headers.append(header[0], header[1]);\n\t\t}\n\t}\n}\n","import pathToRegex from \"../site/pathToRegex\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\nconst noop = () => {};\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst request = new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params);\n\n\t\tif (this.middleware.length) {\n\t\t\t// TODO: Get middleware that applies to this route only?\n\t\t\tawait this.middleware[0](ev, buildNext(this.middleware, 0));\n\t\t\tfunction buildNext(middleware: MiddlewareFunction[], i: number): () => void | Promise<void> {\n\t\t\t\tif (ev.response) {\n\t\t\t\t\treturn noop;\n\t\t\t\t}\n\n\t\t\t\tif (i < middleware.length - 1) {\n\t\t\t\t\tlet next = middleware[i + 1];\n\t\t\t\t\treturn async () => next(ev, buildNext(middleware, i + 1));\n\t\t\t\t} else {\n\t\t\t\t\treturn match\n\t\t\t\t\t\t? async () => {\n\t\t\t\t\t\t\t\tev.response = await match.fn(ev);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: noop;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tthis.routes.push(new RouteHandler(path, fn));\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string) {\n\t\tfor (let handler of this.routes) {\n\t\t\tlet match = path.match(handler.regex);\n\t\t\tif (match) {\n\t\t\t\treturn {\n\t\t\t\t\tfn: handler.fn,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tregex: RegExp;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import {\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeader,\n\ttype OutgoingHttpHeaders,\n\tServerResponse,\n} from \"node:http\";\nimport { PassThrough, Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts\n\n/**\n * Creates a custom ServerResponse object that allows for intercepting and\n * streaming the response.\n *\n * @param incomingMessage The incoming HTTP request message.\n * @returns An object containing the custom ServerResponse and a function that\n * takes a callback to invoke when the response is readable, providing an object\n * with the readable stream, headers and status code.\n */\nexport default function nodeMessageToNodeResponse(\n\tincomingMessage: IncomingMessage,\n): ServerResponseResponse {\n\tconst res = new ServerResponse(incomingMessage);\n\tconst passThrough = new PassThrough();\n\tlet handled = false;\n\n\tconst onReadable = (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => {\n\t\tconst handleReadable = () => {\n\t\t\tif (handled) return;\n\t\t\thandled = true;\n\t\t\tcb({\n\t\t\t\treadable: Readable.from(passThrough),\n\t\t\t\theaders: res.getHeaders(),\n\t\t\t\tstatus: res.statusCode,\n\t\t\t});\n\t\t};\n\n\t\tpassThrough.once(\"readable\", handleReadable);\n\t\tpassThrough.once(\"end\", handleReadable);\n\t};\n\n\tpassThrough.once(\"finish\", () => {\n\t\tres.emit(\"finish\");\n\t});\n\tpassThrough.once(\"close\", () => {\n\t\tres.destroy();\n\t\tres.emit(\"close\");\n\t});\n\tpassThrough.on(\"drain\", () => {\n\t\tres.emit(\"drain\");\n\t});\n\n\tres.write = passThrough.write.bind(passThrough);\n\tres.end = passThrough.end.bind(passThrough) as any;\n\n\tres.writeHead = function writeHead(\n\t\tstatusCode: number,\n\t\tstatusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t\theaders?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t): ServerResponse {\n\t\tres.statusCode = statusCode;\n\t\tif (typeof statusMessage === \"object\") {\n\t\t\theaders = statusMessage;\n\t\t\tstatusMessage = undefined;\n\t\t}\n\t\tif (headers) {\n\t\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t};\n\n\treturn {\n\t\tres,\n\t\tonReadable,\n\t};\n}\n\ntype ServerResponseResponse = {\n\tres: ServerResponse;\n\tonReadable: (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => void;\n};\n","import { Readable } from \"node:stream\";\n\nexport default function readableToBuffer(req: Readable): Promise<Buffer> {\n\treturn new Promise<Buffer>((resolve, reject) => {\n\t\tconst chunks: Buffer[] = [];\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tchunks.push(chunk);\n\t\t});\n\t\treq.on(\"end\", () => {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\treq.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\t});\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\nconst DUMMY_BASE_URL = \"http://localhost\";\n\n/**\n * Creates an IncomingMessage object from a web Request.\n *\n * @param {Request} request - The web Request object.\n * @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.\n */\nexport default function requestToNodeMessage(request: Request): IncomingMessage {\n\tconst parsedUrl = new URL(request.url, DUMMY_BASE_URL);\n\tconst pathAndQuery = (parsedUrl.pathname || \"\") + (parsedUrl.search || \"\");\n\t// HACK: Using Readable.fromWeb locks request.body so that the request cannot be used again\n\t// As we're only using this for Vite middlewares, it's safe to discard the body for now?\n\tconst body = /*request.body ? Readable.fromWeb(request.body as any) :*/ Readable.from([]);\n\n\treturn Object.assign(body, {\n\t\turl: pathAndQuery,\n\t\tmethod: request.method,\n\t\theaders: Object.fromEntries(request.headers),\n\t}) as IncomingMessage;\n}\n","import { IncomingMessage, ServerResponse } from \"node:http\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport flattenHeaders from \"./flattenHeaders\";\nimport nodeMessageToNodeResponse from \"./nodeMessageToNodeResponse\";\nimport readableToBuffer from \"./readableToBuffer\";\nimport requestToNodeMessage from \"./requestToNodeMessage\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\n/**\n * Converts a Connect-style middleware to a web-compatible request handler.\n *\n * @param handler - The Connect-style middleware function to be converted.\n * @returns A function that handles web requests and returns a Response or undefined.\n */\nexport default function connectMiddleware(\n\thandler: ConnectMiddleware | ConnectMiddlewareBoolean,\n): MiddlewareFunction {\n\treturn async (ev, next) => {\n\t\tconst req = requestToNodeMessage(ev.request);\n\t\tconst { res, onReadable } = nodeMessageToNodeResponse(req);\n\n\t\treturn new Promise<void>(async (resolve, reject) => {\n\t\t\tonReadable(async ({ readable, headers, status }) => {\n\t\t\t\tconst responseBody = statusCodesWithoutBody.includes(status)\n\t\t\t\t\t? null\n\t\t\t\t\t: //(Readable.toWeb(readable) as ReadableStream);\n\t\t\t\t\t\t// HACK: Chunked bodies are not being\n\t\t\t\t\t\t// read correctly somewhere...\n\t\t\t\t\t\tawait readableToBuffer(readable);\n\t\t\t\tev.response = new Response(responseBody, {\n\t\t\t\t\tstatus,\n\t\t\t\t\theaders: flattenHeaders(headers),\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tconst cnext = async (error?: unknown) => {\n\t\t\t\tif (error) {\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: Can we nest the next functions less? This is a bit weird\n\t\t\t\t\tawait next();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst handled = await handler(req, res, cnext);\n\t\t\t\tif (handled === false) {\n\t\t\t\t\tres.destroy();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tcnext(e);\n\t\t\t}\n\t\t});\n\t};\n}\n\nconst statusCodesWithoutBody = [\n\t100, // Continue\n\t101, // Switching Protocols\n\t102, // Processing (WebDAV)\n\t103, // Early Hints\n\t204, // No Content\n\t205, // Reset Content\n\t304, // Not Modified\n];\n\ntype NextFunction = (err?: unknown) => void;\ntype ConnectMiddleware<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => void | Promise<void>;\ntype ConnectMiddlewareBoolean<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => boolean | Promise<boolean>;\n"],"mappings":"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","names":["buildNext","v","import_node_stream"]}
package/dist/server.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MiddlewareFunction } from './Server-B45PD5Ys.cjs';
2
- export { C as CookieHelper, H as HeaderHelper, S as Server, a as ServerEvent } from './Server-B45PD5Ys.cjs';
1
+ import { M as MiddlewareFunction } from './Server-DhJ1nRFR.cjs';
2
+ export { C as CookieHelper, H as HeaderHelper, S as Server, a as ServerEvent } from './Server-DhJ1nRFR.cjs';
3
3
  import { IncomingMessage, ServerResponse } from 'node:http';
4
4
  import 'cookie';
5
5
 
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MiddlewareFunction } from './Server-B45PD5Ys.js';
2
- export { C as CookieHelper, H as HeaderHelper, S as Server, a as ServerEvent } from './Server-B45PD5Ys.js';
1
+ import { M as MiddlewareFunction } from './Server-DhJ1nRFR.js';
2
+ export { C as CookieHelper, H as HeaderHelper, S as Server, a as ServerEvent } from './Server-DhJ1nRFR.js';
3
3
  import { IncomingMessage, ServerResponse } from 'node:http';
4
4
  import 'cookie';
5
5
 
package/dist/server.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  Server,
5
5
  ServerEvent,
6
6
  connectMiddleware
7
- } from "./chunk-65Z6BF2N.js";
7
+ } from "./chunk-FLQZX64D.js";
8
8
  import "./chunk-T5K52YVJ.js";
9
9
  export {
10
10
  CookieHelper,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torpor/build",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "A framework for building sites and apps with Torpor",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -50,8 +50,8 @@
50
50
  "dotenv": "^16.5.0",
51
51
  "vite": "^6.2.6",
52
52
  "vite-tsconfig-paths": "^5.1.4",
53
- "@torpor/view": "^0.0.10",
54
- "@torpor/unplugin": "^0.1.4"
53
+ "@torpor/view": "^0.0.11",
54
+ "@torpor/unplugin": "^0.1.5"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
@@ -5,16 +5,22 @@ export default class ServerEvent {
5
5
  request: Request;
6
6
  response?: Response;
7
7
  // TODO: Should we cast types??
8
- params?: { [key: string]: string };
8
+ params?: Record<string, string>;
9
+
10
+ adapter: any;
9
11
 
10
12
  cookies: CookieHelper;
11
13
  headers: HeaderHelper;
12
14
 
13
- constructor(request: Request, params?: { [key: string]: string }) {
15
+ constructor(request: Request, params?: Record<string, string>) {
14
16
  this.request = request;
15
17
  this.params = params;
16
18
  this.cookies = new CookieHelper(request);
17
19
  this.headers = new HeaderHelper(request);
20
+
21
+ // Adapters may have added the `adapter` property to globalThis
22
+ // @ts-ignore
23
+ this.adapter = globalThis.adapter;
18
24
  }
19
25
 
20
26
  addHeaders() {
@@ -294,5 +294,6 @@ function buildServerParams(
294
294
  request: ev.request,
295
295
  cookies: ev.cookies,
296
296
  headers: ev.headers,
297
+ adapter: ev.adapter,
297
298
  };
298
299
  }
@@ -30,6 +30,10 @@ type ServerLoadEvent = {
30
30
  * A helper for getting and setting headers.
31
31
  */
32
32
  headers: HeaderHelper;
33
+ /**
34
+ * An optional adapter object, containing adapter-specific functionality.
35
+ */
36
+ adapter: Record<PropertyKey, any>;
33
37
  };
34
38
 
35
39
  export default ServerLoadEvent;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/CookieHelper.ts","../src/server/HeaderHelper.ts","../src/server/ServerEvent.ts","../src/server/Server.ts","../src/server/connect/flattenHeaders.ts","../src/server/connect/nodeMessageToNodeResponse.ts","../src/server/connect/readableToBuffer.ts","../src/server/connect/requestToNodeMessage.ts","../src/server/connect/connectMiddleware.ts"],"sourcesContent":["import { SerializeOptions, parse, serialize } from \"cookie\";\n\nexport default class CookieHelper {\n\trequest: Request;\n\tcookies: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.cookies.has(name)) {\n\t\t\treturn this.cookies.get(name);\n\t\t}\n\t\t// Otherwise, return the cookie value from the `Cookie` header\n\t\tconst header = this.request.headers.get(\"cookie\");\n\t\treturn parse(header ?? \"\")[name];\n\t}\n\n\tset(name: string, value: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with some default values for security\n\t\toptions ??= {};\n\t\toptions.httpOnly ??= true;\n\t\toptions.secure ??= true;\n\t\toptions.sameSite ??= \"lax\";\n\t\tthis.cookies.set(name, serialize(name, value, options));\n\t}\n\n\tdelete(name: string, options?: SerializeOptions) {\n\t\t// Set a cookie header with an immediate expiry date\n\t\toptions ??= {};\n\t\toptions.expires = new Date(0);\n\t\tthis.cookies.set(name, serialize(name, \"\", options));\n\t}\n}\n","export default class HeaderHelper {\n\trequest: Request;\n\theaders: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.headers.has(name)) {\n\t\t\treturn this.headers.get(name);\n\t\t}\n\t\t// Otherwise, return the value from the header\n\t\treturn this.request.headers.get(name) ?? undefined;\n\t}\n\n\tset(name: string, value: string) {\n\t\tthis.headers.set(name, value);\n\t}\n\n\tdelete(name: string) {\n\t\tthis.headers.delete(name);\n\t}\n}\n","import CookieHelper from \"./CookieHelper\";\nimport HeaderHelper from \"./HeaderHelper\";\n\nexport default class ServerEvent {\n\trequest: Request;\n\tresponse?: Response;\n\t// TODO: Should we cast types??\n\tparams?: { [key: string]: string };\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\n\tconstructor(request: Request, params?: { [key: string]: string }) {\n\t\tthis.request = request;\n\t\tthis.params = params;\n\t\tthis.cookies = new CookieHelper(request);\n\t\tthis.headers = new HeaderHelper(request);\n\t}\n\n\taddHeaders() {\n\t\tif (!this.response) {\n\t\t\tthrow new Error(\"Response not created yet\");\n\t\t}\n\n\t\tfor (let cookie of this.cookies.cookies.values()) {\n\t\t\tthis.response.headers.append(\"set-cookie\", cookie);\n\t\t}\n\n\t\tfor (let header of this.headers.headers.entries()) {\n\t\t\tthis.response.headers.append(header[0], header[1]);\n\t\t}\n\t}\n}\n","import pathToRegex from \"../site/pathToRegex\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\nconst noop = () => {};\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst request = new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params);\n\n\t\tif (this.middleware.length) {\n\t\t\t// TODO: Get middleware that applies to this route only?\n\t\t\tawait this.middleware[0](ev, buildNext(this.middleware, 0));\n\t\t\tfunction buildNext(middleware: MiddlewareFunction[], i: number): () => void | Promise<void> {\n\t\t\t\tif (ev.response) {\n\t\t\t\t\treturn noop;\n\t\t\t\t}\n\n\t\t\t\tif (i < middleware.length - 1) {\n\t\t\t\t\tlet next = middleware[i + 1];\n\t\t\t\t\treturn async () => next(ev, buildNext(middleware, i + 1));\n\t\t\t\t} else {\n\t\t\t\t\treturn match\n\t\t\t\t\t\t? async () => {\n\t\t\t\t\t\t\t\tev.response = await match.fn(ev);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: noop;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tthis.routes.push(new RouteHandler(path, fn));\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string) {\n\t\tfor (let handler of this.routes) {\n\t\t\tlet match = path.match(handler.regex);\n\t\t\tif (match) {\n\t\t\t\treturn {\n\t\t\t\t\tfn: handler.fn,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tregex: RegExp;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import {\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeader,\n\ttype OutgoingHttpHeaders,\n\tServerResponse,\n} from \"node:http\";\nimport { PassThrough, Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts\n\n/**\n * Creates a custom ServerResponse object that allows for intercepting and\n * streaming the response.\n *\n * @param incomingMessage The incoming HTTP request message.\n * @returns An object containing the custom ServerResponse and a function that\n * takes a callback to invoke when the response is readable, providing an object\n * with the readable stream, headers and status code.\n */\nexport default function nodeMessageToNodeResponse(\n\tincomingMessage: IncomingMessage,\n): ServerResponseResponse {\n\tconst res = new ServerResponse(incomingMessage);\n\tconst passThrough = new PassThrough();\n\tlet handled = false;\n\n\tconst onReadable = (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => {\n\t\tconst handleReadable = () => {\n\t\t\tif (handled) return;\n\t\t\thandled = true;\n\t\t\tcb({\n\t\t\t\treadable: Readable.from(passThrough),\n\t\t\t\theaders: res.getHeaders(),\n\t\t\t\tstatus: res.statusCode,\n\t\t\t});\n\t\t};\n\n\t\tpassThrough.once(\"readable\", handleReadable);\n\t\tpassThrough.once(\"end\", handleReadable);\n\t};\n\n\tpassThrough.once(\"finish\", () => {\n\t\tres.emit(\"finish\");\n\t});\n\tpassThrough.once(\"close\", () => {\n\t\tres.destroy();\n\t\tres.emit(\"close\");\n\t});\n\tpassThrough.on(\"drain\", () => {\n\t\tres.emit(\"drain\");\n\t});\n\n\tres.write = passThrough.write.bind(passThrough);\n\tres.end = passThrough.end.bind(passThrough) as any;\n\n\tres.writeHead = function writeHead(\n\t\tstatusCode: number,\n\t\tstatusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t\theaders?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t): ServerResponse {\n\t\tres.statusCode = statusCode;\n\t\tif (typeof statusMessage === \"object\") {\n\t\t\theaders = statusMessage;\n\t\t\tstatusMessage = undefined;\n\t\t}\n\t\tif (headers) {\n\t\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t};\n\n\treturn {\n\t\tres,\n\t\tonReadable,\n\t};\n}\n\ntype ServerResponseResponse = {\n\tres: ServerResponse;\n\tonReadable: (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => void;\n};\n","import { Readable } from \"node:stream\";\n\nexport default function readableToBuffer(req: Readable): Promise<Buffer> {\n\treturn new Promise<Buffer>((resolve, reject) => {\n\t\tconst chunks: Buffer[] = [];\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tchunks.push(chunk);\n\t\t});\n\t\treq.on(\"end\", () => {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\treq.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\t});\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\nconst DUMMY_BASE_URL = \"http://localhost\";\n\n/**\n * Creates an IncomingMessage object from a web Request.\n *\n * @param {Request} request - The web Request object.\n * @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.\n */\nexport default function requestToNodeMessage(request: Request): IncomingMessage {\n\tconst parsedUrl = new URL(request.url, DUMMY_BASE_URL);\n\tconst pathAndQuery = (parsedUrl.pathname || \"\") + (parsedUrl.search || \"\");\n\t// HACK: Using Readable.fromWeb locks request.body so that the request cannot be used again\n\t// As we're only using this for Vite middlewares, it's safe to discard the body for now?\n\tconst body = /*request.body ? Readable.fromWeb(request.body as any) :*/ Readable.from([]);\n\n\treturn Object.assign(body, {\n\t\turl: pathAndQuery,\n\t\tmethod: request.method,\n\t\theaders: Object.fromEntries(request.headers),\n\t}) as IncomingMessage;\n}\n","import { IncomingMessage, ServerResponse } from \"node:http\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport flattenHeaders from \"./flattenHeaders\";\nimport nodeMessageToNodeResponse from \"./nodeMessageToNodeResponse\";\nimport readableToBuffer from \"./readableToBuffer\";\nimport requestToNodeMessage from \"./requestToNodeMessage\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\n/**\n * Converts a Connect-style middleware to a web-compatible request handler.\n *\n * @param handler - The Connect-style middleware function to be converted.\n * @returns A function that handles web requests and returns a Response or undefined.\n */\nexport default function connectMiddleware(\n\thandler: ConnectMiddleware | ConnectMiddlewareBoolean,\n): MiddlewareFunction {\n\treturn async (ev, next) => {\n\t\tconst req = requestToNodeMessage(ev.request);\n\t\tconst { res, onReadable } = nodeMessageToNodeResponse(req);\n\n\t\treturn new Promise<void>(async (resolve, reject) => {\n\t\t\tonReadable(async ({ readable, headers, status }) => {\n\t\t\t\tconst responseBody = statusCodesWithoutBody.includes(status)\n\t\t\t\t\t? null\n\t\t\t\t\t: //(Readable.toWeb(readable) as ReadableStream);\n\t\t\t\t\t\t// HACK: Chunked bodies are not being\n\t\t\t\t\t\t// read correctly somewhere...\n\t\t\t\t\t\tawait readableToBuffer(readable);\n\t\t\t\tev.response = new Response(responseBody, {\n\t\t\t\t\tstatus,\n\t\t\t\t\theaders: flattenHeaders(headers),\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tconst cnext = async (error?: unknown) => {\n\t\t\t\tif (error) {\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: Can we nest the next functions less? This is a bit weird\n\t\t\t\t\tawait next();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst handled = await handler(req, res, cnext);\n\t\t\t\tif (handled === false) {\n\t\t\t\t\tres.destroy();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tcnext(e);\n\t\t\t}\n\t\t});\n\t};\n}\n\nconst statusCodesWithoutBody = [\n\t100, // Continue\n\t101, // Switching Protocols\n\t102, // Processing (WebDAV)\n\t103, // Early Hints\n\t204, // No Content\n\t205, // Reset Content\n\t304, // Not Modified\n];\n\ntype NextFunction = (err?: unknown) => void;\ntype ConnectMiddleware<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => void | Promise<void>;\ntype ConnectMiddlewareBoolean<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => boolean | Promise<boolean>;\n"],"mappings":"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","names":["buildNext","v","Readable"]}