@torpor/build 1.1.0 → 1.2.0
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/Jsonify-Dg6gChd3.d.mts.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/nav.d.mts.map +1 -1
- package/dist/nav.mjs.map +1 -1
- package/dist/{serverEntry-LyB5pl0E.mjs → serverEntry-CUXFQ07g.mjs} +2 -2
- package/dist/{serverEntry-LyB5pl0E.mjs.map → serverEntry-CUXFQ07g.mjs.map} +1 -1
- package/dist/serverEntry.mjs +1 -1
- package/dist/{serverHandlers-DeL1qZJa.mjs → serverHandlers-fzIlmvX-.mjs} +6 -6
- package/dist/{serverHandlers-DeL1qZJa.mjs.map → serverHandlers-fzIlmvX-.mjs.map} +1 -1
- package/dist/test.mjs +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Jsonify-Dg6gChd3.d.mts","names":[],"sources":["../src/types/Jsonify.ts"],"mappings":";;;;;;KAKY,QAAQ,KAAK,6CACtB,IACA,2BAA2B,+BAE1B,UAAU,gBAET,UAAU,YAAY,QACrB,MAAM,QAAQ,SACd,
|
|
1
|
+
{"version":3,"file":"Jsonify-Dg6gChd3.d.mts","names":[],"sources":["../src/types/Jsonify.ts"],"mappings":";;;;;;KAKY,QAAQ,KAAK,6CACtB,IACA,2BAA2B,+BAE1B,UAAU,gBAET,UAAU,YAAY,QACrB,MAAM,QAAQ,SACd,sBAGE,aAAa,KAAK,EAAE,8BAA8B,+BAA+B,MAC/E,QAAQ,EAAE,WAEb"}
|
package/dist/dev.mjs
CHANGED
package/dist/nav.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav.d.mts","names":[],"sources":["../src/nav/api.ts","../src/nav/load.ts","../src/nav/reload.ts","../src/nav/route.ts"],"mappings":";;;;;;;;KASK,UAAU,WAAW,kBAAiB,sBACxC,QAAQ,WAAW,kBAAkB,oBAAoB,QACxD,OAAO;;;;;;KASN,eAAe,WAAW,kBAAiB,aAAa,iBAC1D;EAAgB,YAAY,cAAc;oBACzB,OACf,oBACA,OACD,oBACD;;KAGS,WAAW,
|
|
1
|
+
{"version":3,"file":"nav.d.mts","names":[],"sources":["../src/nav/api.ts","../src/nav/load.ts","../src/nav/reload.ts","../src/nav/route.ts"],"mappings":";;;;;;;;KASK,UAAU,WAAW,kBAAiB,sBACxC,QAAQ,WAAW,kBAAkB,oBAAoB,QACxD,OAAO;;;;;;KASN,eAAe,WAAW,kBAAiB,aAAa,iBAC1D;EAAgB,YAAY,cAAc;oBACzB,OACf,oBACA,OACD,oBACD;;KAGS,WAAW,8BAErB,yBAAyB,YAAY,YAAY,SAAS,mBAAkB,sBACzE,kBAGH,OAAO,eAAe,YAAY,SAAS,WAC3C,OAAO,gBACH,QAAQ,UAAU,YAAY,SAAS;;;;;;;;;;;;;;;;;;;iBAuBrB,QACvB,sBACA,yBACA,eAAe,iBAAiB,SAAS,iBAAiB,QAE1D,MAAM,UAGH,qBAAqB,SACpB,SAAS,gCACJ,iBAAiB,6BAErB,QAAQ,SAAS,iBAAiB,QAAQ,iBAAiB,WAC9D,WAAW;;;;;;iBCpEgB,KAAK,eAAe;;;;;;iBCApB,UAAU;;;;;;;;;;;;;;iBCQhB,MACvB,sBACA,eAAe,iBAAiB,SAAS,iBAAiB,QAE1D,MAAM,UACH,qBAAqB,SACpB,SAAS,gCACJ,iBAAiB,6BAErB,QAAQ,SAAS,iBAAiB,QAAQ,iBAAiB"}
|
package/dist/nav.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav.mjs","names":[],"sources":["../src/nav/route.ts","../src/nav/api.ts"],"sourcesContent":["import type { ExactRouteParams, ParseRouteParams } from \"../types/ParseRouteParams\";\n\n/**\n * Builds a route path in a type-safe manner, filling in dynamic segments, e.g.\n * `route(\"/posts/[id]\", { id: 5 })` returns `/posts/5`. The params object is\n * checked for exact keys: missing or unknown params error at compile time.\n *\n * NOTE: The rest args conditional must stay INLINE — routing it through a type\n * alias defeats `Params` inference, and excess keys stop being checked\n * @param path The route path\n * @param params The route params, required if the path has dynamic segments\n * @returns The path with the params filled in, URI-encoded\n */\nexport default function route<\n\tRoute extends string,\n\tParams extends ParseRouteParams<Route> = ParseRouteParams<Route>,\n>(\n\tpath: Route,\n\t...args: string extends Route\n\t\t? [params?: Record<string, string>]\n\t\t: keyof ParseRouteParams<Route> extends never\n\t\t\t? []\n\t\t\t: [params: Params & ExactRouteParams<Params, ParseRouteParams<Route>>]\n): string {\n\tconst params = ((args as unknown[])[0] ?? {}) as Record<string, string>;\n\treturn path.replace(/\\[(\\.\\.\\.)?([^\\]]+)\\]/g, (_, splat: string | undefined, name: string) => {\n\t\tconst value = params[name];\n\t\tif (value === undefined) {\n\t\t\tthrow new Error(`Missing param '${name}' for route '${path}'`);\n\t\t}\n\t\treturn splat\n\t\t\t? value\n\t\t\t\t\t.split(\"/\")\n\t\t\t\t\t.map((segment) => encodeURIComponent(segment))\n\t\t\t\t\t.join(\"/\")\n\t\t\t: encodeURIComponent(String(value));\n\t});\n}\n","import type { ExactRouteParams, ParseRouteParams } from \"../types/ParseRouteParams\";\nimport type TypedResponse from \"../response/TypedResponse\";\nimport route from \"./route\";\n\n/**\n * The value a client call resolves to: the endpoint's typed JSON body when it\n * returns a typed response, or the raw Response when the body isn't JSON.\n * Untyped endpoints resolve to `unknown`.\n */\ntype ApiResult<Handler> = Handler extends (event: any) => any\n\t? Awaited<ReturnType<Handler>> extends TypedResponse<infer Body>\n\t\t? Body | Response\n\t\t: unknown\n\t: never;\n\n/**\n * The body a client call accepts: the endpoint event's annotated JSON body\n * type (from `ServerLoadEvent<Route, Body>`), or a loose value when the\n * handler doesn't annotate one.\n */\ntype ApiRequestBody<Handler> = Handler extends (event: infer Event) => any\n\t? Event extends { json: () => Promise<infer Body> }\n\t\t? unknown extends Body\n\t\t\t? BodyInit | object\n\t\t\t: Body\n\t\t: BodyInit | object\n\t: BodyInit | object;\n\n/** The callable methods of an endpoint, one per handler it defines. */\nexport type ApiMethods<Endpoint extends object> = {\n\t[
|
|
1
|
+
{"version":3,"file":"nav.mjs","names":[],"sources":["../src/nav/route.ts","../src/nav/api.ts"],"sourcesContent":["import type { ExactRouteParams, ParseRouteParams } from \"../types/ParseRouteParams\";\n\n/**\n * Builds a route path in a type-safe manner, filling in dynamic segments, e.g.\n * `route(\"/posts/[id]\", { id: 5 })` returns `/posts/5`. The params object is\n * checked for exact keys: missing or unknown params error at compile time.\n *\n * NOTE: The rest args conditional must stay INLINE — routing it through a type\n * alias defeats `Params` inference, and excess keys stop being checked\n * @param path The route path\n * @param params The route params, required if the path has dynamic segments\n * @returns The path with the params filled in, URI-encoded\n */\nexport default function route<\n\tRoute extends string,\n\tParams extends ParseRouteParams<Route> = ParseRouteParams<Route>,\n>(\n\tpath: Route,\n\t...args: string extends Route\n\t\t? [params?: Record<string, string>]\n\t\t: keyof ParseRouteParams<Route> extends never\n\t\t\t? []\n\t\t\t: [params: Params & ExactRouteParams<Params, ParseRouteParams<Route>>]\n): string {\n\tconst params = ((args as unknown[])[0] ?? {}) as Record<string, string>;\n\treturn path.replace(/\\[(\\.\\.\\.)?([^\\]]+)\\]/g, (_, splat: string | undefined, name: string) => {\n\t\tconst value = params[name];\n\t\tif (value === undefined) {\n\t\t\tthrow new Error(`Missing param '${name}' for route '${path}'`);\n\t\t}\n\t\treturn splat\n\t\t\t? value\n\t\t\t\t\t.split(\"/\")\n\t\t\t\t\t.map((segment) => encodeURIComponent(segment))\n\t\t\t\t\t.join(\"/\")\n\t\t\t: encodeURIComponent(String(value));\n\t});\n}\n","import type { ExactRouteParams, ParseRouteParams } from \"../types/ParseRouteParams\";\nimport type TypedResponse from \"../response/TypedResponse\";\nimport route from \"./route\";\n\n/**\n * The value a client call resolves to: the endpoint's typed JSON body when it\n * returns a typed response, or the raw Response when the body isn't JSON.\n * Untyped endpoints resolve to `unknown`.\n */\ntype ApiResult<Handler> = Handler extends (event: any) => any\n\t? Awaited<ReturnType<Handler>> extends TypedResponse<infer Body>\n\t\t? Body | Response\n\t\t: unknown\n\t: never;\n\n/**\n * The body a client call accepts: the endpoint event's annotated JSON body\n * type (from `ServerLoadEvent<Route, Body>`), or a loose value when the\n * handler doesn't annotate one.\n */\ntype ApiRequestBody<Handler> = Handler extends (event: infer Event) => any\n\t? Event extends { json: () => Promise<infer Body> }\n\t\t? unknown extends Body\n\t\t\t? BodyInit | object\n\t\t\t: Body\n\t\t: BodyInit | object\n\t: BodyInit | object;\n\n/** The callable methods of an endpoint, one per handler it defines. */\nexport type ApiMethods<Endpoint extends object> = {\n\t[\n\t\tMethod in string & keyof Endpoint as NonNullable<Endpoint[Method]> extends (event: any) => any\n\t\t\t? Method\n\t\t\t: never\n\t]: (\n\t\tbody?: ApiRequestBody<NonNullable<Endpoint[Method]>>,\n\t\tinit?: RequestInit,\n\t) => Promise<ApiResult<NonNullable<Endpoint[Method]>>>;\n};\n\nconst METHODS = [\"get\", \"post\", \"patch\", \"put\", \"del\", \"options\", \"head\"] as const;\n\n/**\n * Creates typed client callers for a `+server` endpoint, e.g.\n *\n * ```ts\n * import type endpoint from \"@/routes/api/posts/[id]/+server\";\n * const post = makeApi<\"/api/posts/[id]\", typeof endpoint>(\"/api/posts/[id]\");\n * const data = await post.get(); // typed from the endpoint's responses\n * ```\n *\n * Method names match the endpoint's handlers (`del` for DELETE). Params are\n * filled in and URI-encoded from the route path, and JSON responses are\n * parsed; non-JSON responses resolve to the raw Response. Failed requests\n * (non-2xx) throw.\n *\n * @param path The endpoint's route path\n * @param params The route params, required if the path has dynamic segments\n * @returns An object with one caller per handler defined by the endpoint\n */\nexport default function makeApi<\n\tRoute extends string,\n\tEndpoint extends object,\n\tParams extends ParseRouteParams<Route> = ParseRouteParams<Route>,\n>(\n\tpath: Route,\n\t// NOTE: The rest args conditional must stay INLINE — routing it through a\n\t// type alias defeats `Params` inference, and excess keys stop being checked\n\t...args: string extends Route\n\t\t? [params?: Record<string, string>]\n\t\t: keyof ParseRouteParams<Route> extends never\n\t\t\t? []\n\t\t\t: [params: Params & ExactRouteParams<Params, ParseRouteParams<Route>>]\n): ApiMethods<Endpoint> {\n\tconst url = route(path as string, ...(args as [params?: Record<string, string>]));\n\tconst api: Record<string, (body?: unknown, init?: RequestInit) => Promise<unknown>> = {};\n\tfor (const method of METHODS) {\n\t\tapi[method] = (body, init) => request(method, url, body, init);\n\t}\n\treturn api as ApiMethods<Endpoint>;\n}\n\nasync function request(\n\tmethod: string,\n\turl: string,\n\tbody: unknown,\n\tinit?: RequestInit,\n): Promise<unknown> {\n\t// `del` is the endpoint handler name for DELETE requests\n\tconst httpMethod = method === \"del\" ? \"delete\" : method;\n\tconst options: RequestInit = { method: httpMethod.toUpperCase(), ...init };\n\tif (body !== undefined && options.body === undefined && method !== \"get\" && method !== \"head\") {\n\t\tif (typeof body === \"object\") {\n\t\t\toptions.headers ??= { \"Content-Type\": \"application/json\" };\n\t\t\toptions.body = JSON.stringify(body);\n\t\t} else {\n\t\t\toptions.body = body as BodyInit;\n\t\t}\n\t}\n\tconst response = await fetch(url, options);\n\tif (!response.ok) {\n\t\tthrow new Error(`API ${method.toUpperCase()} ${url} failed: ${response.status}`);\n\t}\n\tconst contentType = response.headers.get(\"Content-Type\") ?? \"\";\n\treturn contentType.includes(\"application/json\") ? await response.json() : response;\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAwB,MAIvB,MACA,GAAG,MAKM;CACT,MAAM,SAAW,KAAmB,MAAM,CAAC;CAC3C,OAAO,KAAK,QAAQ,2BAA2B,GAAG,OAA2B,SAAiB;EAC7F,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,GACb,MAAM,IAAI,MAAM,kBAAkB,KAAK,eAAe,KAAK,EAAE;EAE9D,OAAO,QACJ,MACC,MAAM,GAAG,CAAC,CACV,KAAK,YAAY,mBAAmB,OAAO,CAAC,CAAC,CAC7C,KAAK,GAAG,IACT,mBAAmB,OAAO,KAAK,CAAC;CACpC,CAAC;AACF;;;ACGA,MAAM,UAAU;CAAC;CAAO;CAAQ;CAAS;CAAO;CAAO;CAAW;AAAM;;;;;;;;;;;;;;;;;;;AAoBxE,SAAwB,QAKvB,MAGA,GAAG,MAKoB;CACvB,MAAM,MAAM,MAAM,MAAgB,GAAI,IAA0C;CAChF,MAAM,MAAgF,CAAC;CACvF,KAAK,MAAM,UAAU,SACpB,IAAI,WAAW,MAAM,SAAS,QAAQ,QAAQ,KAAK,MAAM,IAAI;CAE9D,OAAO;AACR;AAEA,eAAe,QACd,QACA,KACA,MACA,MACmB;CAGnB,MAAM,UAAuB;EAAE,SADZ,WAAW,QAAQ,WAAW,OAAA,CACC,YAAY;EAAG,GAAG;CAAK;CACzE,IAAI,SAAS,KAAA,KAAa,QAAQ,SAAS,KAAA,KAAa,WAAW,SAAS,WAAW,QAAQ;EAC9F,IAAI,OAAO,SAAS,UAAU;GAC7B,QAAQ,YAAY,EAAE,gBAAgB,mBAAmB;GACzD,QAAQ,OAAO,KAAK,UAAU,IAAI;EACnC,OACC,QAAQ,OAAO;CAEjB;CACA,MAAM,WAAW,MAAM,MAAM,KAAK,OAAO;CACzC,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MAAM,OAAO,OAAO,YAAY,EAAE,GAAG,IAAI,WAAW,SAAS,QAAQ;CAGhF,QADoB,SAAS,QAAQ,IAAI,cAAc,KAAK,GAAA,CACzC,SAAS,kBAAkB,IAAI,MAAM,SAAS,KAAK,IAAI;AAC3E"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as Router } from "./Router-C4ADUfhv.mjs";
|
|
2
|
-
import { t as createServerLoad } from "./serverHandlers-
|
|
2
|
+
import { t as createServerLoad } from "./serverHandlers-fzIlmvX-.mjs";
|
|
3
3
|
import manifest from "@torpor/build/manifest";
|
|
4
4
|
//#region src/site/serverEntry.ts
|
|
5
5
|
const router = new Router();
|
|
@@ -8,4 +8,4 @@ const load = createServerLoad(router);
|
|
|
8
8
|
//#endregion
|
|
9
9
|
export { load as t };
|
|
10
10
|
|
|
11
|
-
//# sourceMappingURL=serverEntry-
|
|
11
|
+
//# sourceMappingURL=serverEntry-CUXFQ07g.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverEntry-
|
|
1
|
+
{"version":3,"file":"serverEntry-CUXFQ07g.mjs","names":[],"sources":["../src/site/serverEntry.ts"],"sourcesContent":["import manifest from \"@torpor/build/manifest\";\nimport Router from \"./Router.ts\";\nimport { type ServerLoad, createServerLoad } from \"./serverHandlers.ts\";\n\n// Build the router from the Site object created by the user\nconst router = new Router();\nrouter.addPages(manifest.routes);\n\n//console.log(`routes:\\n ${router.routes.map((r) => r.path).join(\"\\n \")}`);\n\nexport const load: ServerLoad = createServerLoad(router);\n"],"mappings":";;;;AAKA,MAAM,SAAS,IAAI,OAAO;AAC1B,OAAO,SAAS,SAAS,MAAM;AAI/B,MAAa,OAAmB,iBAAiB,MAAM"}
|
package/dist/serverEntry.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as load } from "./serverEntry-
|
|
1
|
+
import { t as load } from "./serverEntry-CUXFQ07g.mjs";
|
|
2
2
|
export { load };
|
|
@@ -326,8 +326,8 @@ async function loadView(ev, url, handler, params, template, formStatus, form, fr
|
|
|
326
326
|
};
|
|
327
327
|
if (handler.layouts) {
|
|
328
328
|
let slotFunctions = [];
|
|
329
|
-
slotFunctions[handler.layouts.length] = trackSlot(handler.layouts.length, (_, $context) => {
|
|
330
|
-
let { body, head } = clientEndPoint.component($props, $context);
|
|
329
|
+
slotFunctions[handler.layouts.length] = trackSlot(handler.layouts.length, async (_, $context) => {
|
|
330
|
+
let { body, head } = await clientEndPoint.component($props, $context);
|
|
331
331
|
styles += head;
|
|
332
332
|
return body;
|
|
333
333
|
});
|
|
@@ -337,8 +337,8 @@ async function loadView(ev, url, handler, params, template, formStatus, form, fr
|
|
|
337
337
|
if (i === 0) {
|
|
338
338
|
component = layoutEndPoint.component;
|
|
339
339
|
slots = { _: slotFunctions[i + 1] };
|
|
340
|
-
} else slotFunctions[i] = trackSlot(i, (_, $context) => {
|
|
341
|
-
let { body, head } = layoutEndPoint.component($props, $context, { _: slotFunctions[i + 1] });
|
|
340
|
+
} else slotFunctions[i] = trackSlot(i, async (_, $context) => {
|
|
341
|
+
let { body, head } = await layoutEndPoint.component($props, $context, { _: slotFunctions[i + 1] });
|
|
342
342
|
styles += head;
|
|
343
343
|
return body;
|
|
344
344
|
});
|
|
@@ -347,7 +347,7 @@ async function loadView(ev, url, handler, params, template, formStatus, form, fr
|
|
|
347
347
|
}
|
|
348
348
|
let html;
|
|
349
349
|
try {
|
|
350
|
-
let { body, head } = component($props, void 0, slots);
|
|
350
|
+
let { body, head } = await component($props, void 0, slots);
|
|
351
351
|
if (form) body += `\n<input type="hidden" id="t-form-data" value='${JSON.stringify(form).replaceAll("'", "\\'")}' />`;
|
|
352
352
|
styles += head;
|
|
353
353
|
html = mergeHead(template, styles).replace("%COMPONENT_BODY%", body);
|
|
@@ -476,4 +476,4 @@ function buildServerParams(ev, url, params, values = {}) {
|
|
|
476
476
|
//#endregion
|
|
477
477
|
export { createServerLoad as t };
|
|
478
478
|
|
|
479
|
-
//# sourceMappingURL=serverHandlers-
|
|
479
|
+
//# sourceMappingURL=serverHandlers-fzIlmvX-.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverHandlers-DeL1qZJa.mjs","names":[],"sources":["../src/form/formDataToRecord.ts","../src/state/$serverPage.ts","../src/utils/searchParamsToRecord.ts","../src/validation/endpoint.ts","../src/site/layoutSlots.ts","../src/site/mergeHead.ts","../src/site/serverHandlers.ts"],"sourcesContent":["import type { FormDataRecord } from \"../types/ServerLoadEvent\";\n\n/**\n * Converts the submitted fields of a form request into a plain record: one\n * value per field, or an array when a field was submitted with multiple\n * values (e.g. a multi select). File inputs pass through as `File` values;\n * coercing them is left to the schema or the action.\n *\n * @param request The request (or FormData directly)\n * @returns The field values\n */\nexport default async function formDataToRecord(\n\trequest: Request | FormData,\n): Promise<FormDataRecord> {\n\tconst formData = request instanceof FormData ? request : await request.formData();\n\tconst result: FormDataRecord = {};\n\tfor (const key of formData.keys()) {\n\t\tif (key in result) continue;\n\t\tconst values = formData.getAll(key);\n\t\tresult[key] = values.length > 1 ? values : values[0];\n\t}\n\treturn result;\n}\n","import { $watch } from \"@torpor/view/ssr\";\nimport type PageState from \"../types/PageState\";\n\nconst PAGE_SYMBOL: unique symbol = Symbol.for(\"torp.Page\");\n\n// The server request path has no reactive subscribers, so the state is\n// stored plainly ($watch from `@torpor/view/ssr` is a no-op that returns\n// the object itself) instead of through a reactive proxy. Shares the same\n// `globalThis` slot as the client `$page`, so both variants always see the\n// same state object whichever loads first.\nconst $page: PageState =\n\t// @ts-ignore\n\t(globalThis[PAGE_SYMBOL] ??= $watch({\n\t\tstatus: 404,\n\t\turl: new URL(\"http://localhost\"),\n\t\tform: undefined,\n\t\terror: {\n\t\t\tmessage: \"\",\n\t\t},\n\t}));\n\nexport default $page;\n","import type { QueryRecord } from \"../types/ServerLoadEvent\";\n\n/**\n * Converts a URL's query string into a plain record: one string per param,\n * or an array when a param was repeated.\n *\n * @param searchParams The URL's search params\n * @returns The param values\n */\nexport default function searchParamsToRecord(searchParams: URLSearchParams): QueryRecord {\n\tconst result: QueryRecord = {};\n\tfor (const key of searchParams.keys()) {\n\t\tif (key in result) continue;\n\t\tconst values = searchParams.getAll(key);\n\t\tresult[key] = values.length > 1 ? values : values[0];\n\t}\n\treturn result;\n}\n","import type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport type ServerEndPoint from \"../types/ServerEndPoint\";\nimport type { StandardSchemaV1 } from \"../types/StandardSchema\";\nimport type ServerEvent from \"../server/ServerEvent\";\nimport searchParamsToRecord from \"../utils/searchParamsToRecord\";\nimport unprocessable from \"../response/unprocessable\";\nimport ValidationError from \"./ValidationError\";\nimport validate from \"./validate\";\n\n/**\n * Loose views of an endpoint's schema map, keyed by handler/action name (plus\n * the reserved `params` key). The type-level constraint differs per endpoint\n * type, but the runtime treats them the same.\n */\ntype Schemas = Record<string, StandardSchemaV1 | undefined>;\n\ntype EndPoint = ServerEndPoint | PageServerEndPoint;\n\n/**\n * Gets the standard schema declared for a handler or action, if any. The\n * schemas map is keyed by name; the runtime treats it as a loose record.\n */\nexport function endpointSchema(endPoint: EndPoint, name: string): StandardSchemaV1 | undefined {\n\treturn (endPoint.schema as Schemas | undefined)?.[name];\n}\n\n/**\n * Validates the route params against the endpoint's `params` schema, if it\n * declares one, returning the coerced params. Throws a ValidationError when\n * they don't match, which callers turn into a 404 (params come from the URL,\n * so a failed validation means the resource doesn't exist).\n *\n * @param endPoint The endpoint declaring the (optional) `params` schema\n * @param params The route params from the matched route\n * @returns The validated params\n */\nexport async function validateEndpointParams(\n\tendPoint: EndPoint,\n\tparams: Record<string, any>,\n): Promise<Record<string, any>> {\n\tconst schema = endpointSchema(endPoint, \"params\");\n\treturn schema ? ((await validate(schema, params)) as Record<string, any>) : params;\n}\n\n/**\n * Validates a handler's input against its schema: get/head handlers and load\n * functions validate the URL's query string, other handlers validate the JSON\n * request body. Returns the validated values (an empty object when no schema\n * is declared), which callers pass through to the handler's event.\n *\n * @param schema The handler's (optional) schema\n * @param functionName The handler name (`get`, `post`, `load`, etc)\n * @param url The request URL, for the query string\n * @param ev The server event, for the request body\n * @returns The validated values\n */\nexport async function validateHandlerInput(\n\tschema: StandardSchemaV1 | undefined,\n\tfunctionName: string,\n\turl: URL,\n\tev: ServerEvent,\n): Promise<{ json?: unknown; form?: unknown; query?: unknown }> {\n\tif (!schema) return {};\n\tif (functionName === \"get\" || functionName === \"head\" || functionName === \"load\") {\n\t\treturn { query: await validate(schema, searchParamsToRecord(url.searchParams)) };\n\t}\n\treturn { json: await validate(schema, await ev.json()) };\n}\n\n/**\n * Turns a ValidationError thrown during endpoint validation into a 422\n * response with the schema's issues. Returns undefined for any other error,\n * which callers should rethrow.\n *\n * @param error The error thrown by a handler or validation\n * @returns A 422 response, or undefined when the error isn't a validation failure\n */\nexport function validationErrorResponse(error: unknown): Response | undefined {\n\tif (error instanceof ValidationError) {\n\t\treturn unprocessable({ message: error.message, issues: error.issues });\n\t}\n\treturn undefined;\n}\n","/**\n * Layouts are composed by the layout engine passing each layout (and finally\n * the page) as the default slot of its parent — so every `_layout` component\n * must render `<slot />`, or pass the default slot down to a child component\n * it renders. A layout that doesn't drops its entire content: the server\n * renders the layout's own markup with an empty content area (no error), and\n * the first client-side navigation that reuses the layout crashes on a null\n * slot region.\n *\n * The static `checkLayoutSlots` check catches this at build/dev time; these\n * helpers report it at request time for the cases static analysis can't see\n * (e.g. a `<slot />` rendered conditionally inside `@if`). They are\n * server-side only — nothing here is imported into the client bundle.\n */\n\n/**\n * Returns the path of the outermost layout that never rendered its\n * `<slot />`, or undefined when every level rendered.\n *\n * Slot level j (1-based) is the slot render that layout j - 1 receives: the\n * root layout (layouts[0]) renders level 1, layout i renders level i + 1,\n * and level layouts.length renders the page. A broken level makes every\n * deeper level unreachable, so the first level that never ran identifies\n * the offending layout.\n */\nexport function findMissingSlotLayout(\n\tlayouts: readonly { path: string }[],\n\tinvokedLevels: ReadonlySet<number>,\n): string | undefined {\n\tfor (let level = 1; level <= layouts.length; level++) {\n\t\tif (!invokedLevels.has(level)) {\n\t\t\treturn layouts[level - 1].path;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nconst warnedLayouts = new Set<string>();\n\n/**\n * Reports a layout that dropped its slot content. The condition is a genuine\n * rendering bug (the page content is missing from the output), so it is not\n * dev-gated — but it warns only once per layout path to avoid per-request\n * noise.\n */ export function warnMissingSlotContent(layoutPath: string): void {\n\tif (warnedLayouts.has(layoutPath)) return;\n\twarnedLayouts.add(layoutPath);\n\tconsole.warn(\n\t\t`[torpor] The layout at \"${layoutPath}\" never rendered <slot />, so the page content ` +\n\t\t\t`was not included in the render. Every _layout component must render <slot /> (or ` +\n\t\t\t`pass the default slot down to a child component it renders).`,\n\t);\n}\n","const TITLE_REGEX = /<title(?:\\s[^>]*)?>[\\s\\S]*?<\\/title>/g;\nconst FIRST_TITLE_REGEX = /<title(?:\\s[^>]*)?>[\\s\\S]*?<\\/title>/;\n\n/**\n * Merges the head string rendered by a page (and its layouts) into the site\n * template. The first <title> in the head string -- the page's, since pages\n * render before the layouts around them -- wins, overriding both any later\n * component title (e.g. from a child component) and a static <title> in the\n * template itself. All other head content (styles, meta elements, etc) is\n * appended where %COMPONENT_HEAD% sits in the template, before </head>.\n */\nexport default function mergeHead(template: string, head: string): string {\n\tconst titles = head.match(TITLE_REGEX);\n\tlet html = template;\n\tlet headHtml = head;\n\tif (titles?.length) {\n\t\theadHtml = head.replace(TITLE_REGEX, \"\");\n\t\thtml = html.replace(FIRST_TITLE_REGEX, \"\");\n\t\theadHtml = titles[0] + headHtml;\n\t}\n\treturn html.replace(\"%COMPONENT_HEAD%\", headHtml);\n}\n","import { type ServerComponent, type ServerSlotRender } from \"@torpor/view/ssr\";\nimport formDataToRecord from \"../form/formDataToRecord.ts\";\nimport notFound from \"../response/notFound.ts\";\nimport ok from \"../response/ok.ts\";\nimport seeOther from \"../response/seeOther.ts\";\nimport ServerEvent from \"../server/ServerEvent.ts\";\nimport $page from \"../state/$serverPage.ts\";\nimport type PageEndPoint from \"../types/PageEndPoint.ts\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint.ts\";\nimport type RouteHandler from \"../types/RouteHandler.ts\";\nimport type ServerRequest from \"../types/ServerRequest.ts\";\nimport {\n\tERROR_ROUTE,\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport type ServerEndPoint from \"../types/ServerEndPoint.ts\";\nimport type ServerHook from \"../types/ServerHook.ts\";\nimport type ServerLoadEvent from \"../types/ServerLoadEvent.ts\";\nimport searchParamsToRecord from \"../utils/searchParamsToRecord.ts\";\nimport validate from \"../validation/validate.ts\";\nimport ValidationError from \"../validation/ValidationError.ts\";\nimport {\n\tendpointSchema,\n\tvalidateEndpointParams,\n\tvalidationErrorResponse,\n} from \"../validation/endpoint.ts\";\nimport { findMissingSlotLayout, warnMissingSlotContent } from \"./layoutSlots.ts\";\nimport mergeHead from \"./mergeHead.ts\";\nimport type Router from \"./Router.ts\";\n\n/**\n * The site's request handler, as created by `createServerLoad`.\n */\nexport type ServerLoad = (ev: ServerEvent, template?: string) => Promise<Response>;\n\n/**\n * Creates the site's request handler for the given router. This is kept\n * separate from serverEntry, which imports the virtual\n * `@torpor/build/manifest` module (it only exists when a site runs or\n * builds), so that tests can exercise the handlers with their own routes.\n *\n * @param router The router, built from the site's routes\n * @returns The request handler, which takes the site template\n */\nexport function createServerLoad(router: Router): ServerLoad {\n\treturn async function load(ev, template) {\n\t\tconst url = ev.url;\n\t\tconst path = url.pathname;\n\t\tconst query = url.searchParams;\n\n\t\t//console.log(`handling ${ev.request.method} for '${path}'${query.size ? ` with ${query}` : \"\"}`);\n\n\t\tlet route = router.match(path, query);\n\t\tif (!route) {\n\t\t\t// If the route wasn't found, the user may be posting a form to a\n\t\t\t// +page.server.ts route that doesn't have a corresponding +page.ts\n\t\t\t// route, which is allowed, so check for that as well\n\t\t\tif (ev.request.method === \"POST\" && !path.endsWith(\"/~server\")) {\n\t\t\t\tconst serverPath =\n\t\t\t\t\t(path.endsWith(\"/\") ? path.substring(0, path.length - 1) : path) + \"/~server\";\n\t\t\t\troute = router.match(serverPath, query);\n\t\t\t}\n\t\t}\n\t\tif (!route) {\n\t\t\treturn handleResponse(notFound());\n\t\t}\n\t\tconst handler = route.handler;\n\t\tconst params = route.params || {};\n\n\t\t// Update $page before building the components\n\t\t$page.url = url;\n\t\tif (path.endsWith(\"/_error\")) {\n\t\t\t$page.status = parseInt(query.get(\"status\") ?? \"404\");\n\t\t\t$page.error = { message: query.get(\"message\") ?? \"\" };\n\t\t} else {\n\t\t\t$page.status = 200;\n\t\t}\n\n\t\t// TODO: Hit the server hook out here\n\t\t// We could maybe set up data loading as middleware on a route??????\n\n\t\tswitch (handler.type) {\n\t\t\tcase PAGE_ROUTE:\n\t\t\tcase LAYOUT_ROUTE: {\n\t\t\t\t// It's a /+page.ts or /_layout.ts endpoint\n\t\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\t\treturn handleResponse(await loadView(ev, url, handler, params, template));\n\t\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\t\t// The server end point comes from the sibling /+page.server.ts, if applicable\n\t\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined =\n\t\t\t\t\t\thandler.serverEndPoint && (await handler.serverEndPoint()).default;\n\t\t\t\t\treturn handleResponse(\n\t\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase PAGE_SERVER_ROUTE:\n\t\t\tcase LAYOUT_SERVER_ROUTE: {\n\t\t\t\t// It's a /+page.server.ts or /_layout.server.ts endpoint\n\t\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\t\treturn await loadData(ev, url, handler, \"load\", params);\n\t\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined = (await resolveModule(handler))\n\t\t\t\t\t\t.default;\n\t\t\t\t\treturn handleResponse(\n\t\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SERVER_ROUTE: {\n\t\t\t\t// It's a /+server.ts endpoint\n\t\t\t\tconst functionName = ev.request.method.toLowerCase().replace(\"delete\", \"del\");\n\t\t\t\treturn await loadData(ev, url, handler, functionName, params);\n\t\t\t}\n\t\t\tcase HOOK_ROUTE:\n\t\t\tcase HOOK_SERVER_ROUTE: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ERROR_ROUTE: {\n\t\t\t\treturn await loadView(ev, url, handler, params, template);\n\t\t\t}\n\t\t}\n\n\t\treturn notFound();\n\t};\n}\n\n/**\n * Resolves the route's endpoint module, caching it on the handler so warm\n * requests don't pay for the loader promise.\n */\nasync function resolveModule(handler: RouteHandler): Promise<any> {\n\treturn (handler.resolvedModule ??= await (handler.modulePromise ??= handler.endPoint()));\n}\n\nasync function loadServerHooks(handler: RouteHandler): Promise<ServerHook[]> {\n\tif (!handler.serverHooks) return [];\n\t// Resolve each hook module once and cache the result on the handler\n\treturn (handler.resolvedHooks ??= Promise.all(\n\t\thandler.serverHooks.map(async (load) => (await load()).default),\n\t));\n}\n\nasync function handleResponse(response: Response, fromForm = false): Promise<Response> {\n\t$page.status = response.status;\n\n\t// Success codes and redirect codes are acceptable\n\tif (response.status >= 200 && response.status <= 399) {\n\t\treturn response;\n\t}\n\n\t// 4xx error codes are acceptable from form actions\n\tif (fromForm && response.status >= 400 && response.status <= 499) {\n\t\treturn response;\n\t}\n\n\t// It's an error, so redirect to the error page\n\t// We're just pushing the status and message in the URL, but maybe there's a\n\t// more sophisticated way to do this?\n\t// TODO: Should be returning loadView rather than redirecting\n\t// TODO: Should be returning the NEAREST error page to this path, including layouts\n\tlet params = new URLSearchParams();\n\tparams.append(\"status\", $page.status.toString());\n\tlet message = await response.text();\n\tif (response.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\tconst data = JSON.parse(message);\n\t\tmessage = data.message ?? message;\n\t}\n\tif (message) {\n\t\tif ($page.error) {\n\t\t\t$page.error.message = message;\n\t\t} else {\n\t\t\t$page.error = { message };\n\t\t}\n\t\tparams.append(\"message\", message);\n\t}\n\treturn seeOther(`/_error?${params.toString()}`);\n}\n\nasync function loadData(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tfunctionName: string,\n\tparams: Record<string, any>,\n) {\n\t// The endpoint module is cached on the handler, so once warm this is a\n\t// plain property read\n\tconst mod = handler.resolvedModule ?? (await resolveModule(handler));\n\tconst serverEndPoint: ServerEndPoint | undefined = mod?.default;\n\t// `functionName` is computed from the request method, so the handlers are\n\t// accessed through a loose record\n\tconst handlerFn = (\n\t\tserverEndPoint as unknown as Record<string, ServerRequest | undefined> | undefined\n\t)?.[functionName];\n\tif (!serverEndPoint || !handlerFn) {\n\t\treturn notFound();\n\t}\n\n\t// Route params come from the URL, so a failed validation means the\n\t// resource doesn't exist. Only endpoints declaring a params schema pay\n\t// for validation\n\tconst paramsSchema = endpointSchema(serverEndPoint, \"params\");\n\tif (paramsSchema) {\n\t\ttry {\n\t\t\tparams = (await validate(paramsSchema, params)) as Record<string, any>;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\ttry {\n\t\t// If the endpoint declares a schema for this handler, validate its\n\t\t// input up front and reject with 422 if it fails. get/head/load\n\t\t// schemas validate the query string; other schemas validate the json\n\t\t// body. Endpoints without a schema skip straight to the handler\n\t\tconst schema = endpointSchema(serverEndPoint, functionName);\n\t\tconst values = schema\n\t\t\t? functionName === \"get\" || functionName === \"head\" || functionName === \"load\"\n\t\t\t\t? { query: await validate(schema, searchParamsToRecord(url.searchParams)) }\n\t\t\t\t: { json: await validate(schema, await ev.json()) }\n\t\t\t: {};\n\n\t\tconst serverParams = buildServerParams(ev, url, params, values);\n\n\t\t// Hooks are resolved once per handler; routes without hooks don't\n\t\t// await anything here\n\t\tconst hooks = handler.serverHooks ? await loadServerHooks(handler) : [];\n\n\t\tlet entered = 0;\n\t\tlet enterResponse: Response | undefined = undefined;\n\t\ttry {\n\t\t\t// Hooks run from the root down; a hook's enter can return a\n\t\t\t// Response to short-circuit the request\n\t\t\tfor (; entered < hooks.length && !enterResponse; entered++) {\n\t\t\t\tconst hookResult = await hooks[entered].enter?.(serverParams);\n\t\t\t\tif (hookResult) {\n\t\t\t\t\tenterResponse = hookResult;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A hook's enter response short-circuits the request; otherwise, if\n\t\t\t// there was no response returned from load (such as errors or a\n\t\t\t// redirect), send an ok response\n\t\t\treturn enterResponse || (await handlerFn(serverParams)) || ok();\n\t\t} finally {\n\t\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\t\twhile (entered > 0) {\n\t\t\t\tentered--;\n\t\t\t\tawait hooks[entered].exit?.(serverParams);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst response = validationErrorResponse(error);\n\t\tif (response) return response;\n\t\tthrow error;\n\t}\n}\n\nasync function loadView(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tparams: Record<string, any>,\n\ttemplate: string | undefined,\n\tformStatus?: number,\n\tform?: Record<string, string | number>,\n\tfromForm?: boolean,\n) {\n\t// There must be a client endpoint with a component\n\tconst clientEndPoint: PageEndPoint | undefined = (await resolveModule(handler)).default;\n\tif (!clientEndPoint?.component) {\n\t\treturn notFound();\n\t}\n\n\t// The template comes from site.html, which endpoints-only sites don't have\n\tif (!template) {\n\t\tthrow new Error(\n\t\t\t\"Page routes require a src/site.html file, which was not found; add it, or remove page/layout routes to serve endpoints only\",\n\t\t);\n\t}\n\n\t// There may be a server endpoint\n\tconst serverEndPoint: PageServerEndPoint | undefined =\n\t\thandler.serverEndPoint && (await handler.serverEndPoint())?.default;\n\n\t// Validate the route params and the load query against the server\n\t// endpoint's schemas, if it declares any. Params come from the URL, so a\n\t// failed validation means the resource doesn't exist; a failed query goes\n\t// to the error page like any other load failure\n\tlet query: unknown;\n\tif (serverEndPoint) {\n\t\ttry {\n\t\t\tparams = await validateEndpointParams(serverEndPoint, params);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\tthrow error;\n\t\t}\n\t\tconst loadSchema = endpointSchema(serverEndPoint, \"load\");\n\t\tif (loadSchema) {\n\t\t\tconst queryRecord = searchParamsToRecord(url.searchParams);\n\t\t\ttry {\n\t\t\t\tquery = await validate(loadSchema, queryRecord);\n\t\t\t} catch (error) {\n\t\t\t\t// A form re-render's url is the POST's, and a form action can\n\t\t\t\t// drop query params that the load schema requires, so failing\n\t\t\t\t// validation here would lose the form errors. Fall back to the\n\t\t\t\t// raw query values instead and let the load make of them what\n\t\t\t\t// it can\n\t\t\t\tif (fromForm) {\n\t\t\t\t\tquery = queryRecord;\n\t\t\t\t} else {\n\t\t\t\t\tconst response = validationErrorResponse(error);\n\t\t\t\t\tif (response) return response;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Maybe hit the server hooks -- unless they already ran for this request,\n\t// which is the case when the view is re-rendered after a form action\n\tconst serverParams = buildServerParams(ev, url, params, query ? { query } : {});\n\tconst serverHooks = fromForm ? [] : await loadServerHooks(handler);\n\tlet entered = 0;\n\tlet enterResponse: Response | undefined = undefined;\n\ttry {\n\t\t// Hooks run from the root down; a hook's enter can return a Response\n\t\t// to short-circuit the request\n\t\tfor (; entered < serverHooks.length && !enterResponse; entered++) {\n\t\t\tconst hookResult = await serverHooks[entered].enter?.(serverParams);\n\t\t\tif (hookResult) {\n\t\t\t\tenterResponse = hookResult;\n\t\t\t}\n\t\t}\n\t\tif (enterResponse) {\n\t\t\treturn enterResponse;\n\t\t}\n\n\t\t// Pass the data into $props\n\t\t// TODO: Promise.all\n\t\t// NOTE: We're loading data from top to bottom, overriding as we go, and I'm\n\t\t// not sure if this is the best way to go\n\t\tlet data = {};\n\t\tif (handler.layouts) {\n\t\t\tfor (let layout of handler.layouts) {\n\t\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await layout.endPoint())?.default;\n\t\t\t\tconst layoutServerEndPoint: PageServerEndPoint | undefined =\n\t\t\t\t\tlayout.serverEndPoint && (await layout.serverEndPoint())?.default;\n\t\t\t\tconst layoutResponse = await loadClientAndServerData(\n\t\t\t\t\turl,\n\t\t\t\t\tparams,\n\t\t\t\t\tserverParams,\n\t\t\t\t\tdata,\n\t\t\t\t\tlayoutEndPoint,\n\t\t\t\t\tlayoutServerEndPoint,\n\t\t\t\t);\n\t\t\t\tif (layoutResponse?.ok === false) {\n\t\t\t\t\treturn layoutResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet endPointResponse = await loadClientAndServerData(\n\t\t\turl,\n\t\t\tparams,\n\t\t\tserverParams,\n\t\t\tdata,\n\t\t\tclientEndPoint,\n\t\t\tserverEndPoint,\n\t\t);\n\t\tif (endPointResponse?.ok === false) {\n\t\t\treturn endPointResponse;\n\t\t}\n\t\tlet $props: Record<string, any> = { data, form };\n\n\t\tlet styles = \"\";\n\n\t\t// If there are layouts, work our way upwards, pushing each component into\n\t\t// the default slot of its parent\n\t\t// TODO: Also handle layout server data\n\t\t// TODO: There's probably a nicer way to do this with reducers or something\n\t\tlet component = clientEndPoint.component as ServerComponent;\n\t\tlet slots: Record<string, ServerSlotRender> | undefined = undefined;\n\t\t// Which slot levels actually ran during the render below, so a layout\n\t\t// that never rendered its <slot /> (silently dropping the page\n\t\t// content) can be reported (see findMissingSlotLayout)\n\t\tconst invokedLevels = new Set<number>();\n\t\tconst trackSlot = (level: number, slot: ServerSlotRender): ServerSlotRender => {\n\t\t\treturn ($slot, $context) => {\n\t\t\t\tinvokedLevels.add(level);\n\t\t\t\treturn slot($slot, $context);\n\t\t\t};\n\t\t};\n\t\tif (handler.layouts) {\n\t\t\tlet slotFunctions: ServerSlotRender[] = [];\n\t\t\t// The last slot function will render the client component\n\t\t\tslotFunctions[handler.layouts.length] = trackSlot(handler.layouts.length, (_, $context) => {\n\t\t\t\tlet { body, head } = (clientEndPoint.component as ServerComponent)($props, $context);\n\t\t\t\tstyles += head;\n\t\t\t\treturn body;\n\t\t\t});\n\t\t\tfor (let i = handler.layouts.length - 1; i >= 0; i--) {\n\t\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await handler.layouts[i].endPoint())\n\t\t\t\t\t?.default;\n\t\t\t\tif (layoutEndPoint?.component) {\n\t\t\t\t\tif (i === 0) {\n\t\t\t\t\t\tcomponent = layoutEndPoint.component as ServerComponent;\n\t\t\t\t\t\tslots = { _: slotFunctions[i + 1] };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tslotFunctions[i] = trackSlot(i, (_, $context) => {\n\t\t\t\t\t\t\tlet { body, head } = (layoutEndPoint.component as ServerComponent)($props, $context, {\n\t\t\t\t\t\t\t\t_: slotFunctions[i + 1],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tstyles += head;\n\t\t\t\t\t\t\treturn body;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet html;\n\t\ttry {\n\t\t\tlet { body, head } = component($props, undefined, slots);\n\n\t\t\t// Put the form info in a hidden input so that it can be accessed on the client\n\t\t\tif (form) {\n\t\t\t\tbody += `\\n<input type=\"hidden\" id=\"t-form-data\" value='${JSON.stringify(form).replaceAll(\"'\", \"\\\\'\")}' />`;\n\t\t\t}\n\n\t\t\tstyles += head;\n\t\t\thtml = mergeHead(template, styles).replace(\"%COMPONENT_BODY%\", body);\n\t\t} catch (error) {\n\t\t\t// TODO: Show a proper Error component\n\t\t\thtml = '<span style=\"color: red\">Script syntax error</span><p>' + error + \"</p>\";\n\t\t\tconsole.log(error);\n\t\t}\n\n\t\t// A layout that never rendered <slot /> silently drops the whole page\n\t\t// content from the output; find and report the outermost one\n\t\tif (handler.layouts) {\n\t\t\tconst missingLayout = findMissingSlotLayout(handler.layouts, invokedLevels);\n\t\t\tif (missingLayout !== undefined) {\n\t\t\t\twarnMissingSlotContent(missingLayout);\n\t\t\t}\n\t\t}\n\n\t\treturn new Response(html, {\n\t\t\tstatus: formStatus ?? 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/html\",\n\t\t\t},\n\t\t});\n\t} finally {\n\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\twhile (entered > 0) {\n\t\t\tentered--;\n\t\t\tawait serverHooks[entered].exit?.(serverParams);\n\t\t}\n\t}\n}\n\nasync function runAction(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tserverEndPoint: PageServerEndPoint | undefined,\n\tparams: Record<string, any>,\n\tquery: URLSearchParams,\n\ttemplate: string | undefined,\n) {\n\t// The action name rides in the query, so look for a `?/name` key rather\n\t// than taking the first key -- the url may carry ordinary load query\n\t// params as well (e.g. `?page=3&/like`, or a default action posted to a\n\t// url that already has a query). A key that names a declared action also\n\t// matches (e.g. `?set`), and a form without an action attribute calls the\n\t// `default` action\n\tconst queryKeys = Array.from(query.keys());\n\tconst actionKey =\n\t\tqueryKeys.find((key) => key.startsWith(\"/\")) ??\n\t\tqueryKeys.find((key) => !!serverEndPoint?.actions?.[key.replace(/^\\//, \"\")]);\n\tconst actionName = (actionKey ?? \"default\").replace(/^\\//, \"\");\n\tif (serverEndPoint?.actions) {\n\t\tconst action = serverEndPoint.actions[actionName];\n\t\tif (action) {\n\t\t\tif (actionName === \"load\" || actionName === \"params\") {\n\t\t\t\t// These names are reserved in the endpoint's schema map: `load`\n\t\t\t\t// validates the query string and `params` the route params, so\n\t\t\t\t// an action with one of these names would get the wrong schema\n\t\t\t\t// applied to its form data\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The action name \"${actionName}\" is reserved. ` +\n\t\t\t\t\t\t`Rename the action (and its schema key, if any), e.g. to \"save\".`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Route params come from the URL, so a failed validation means the\n\t\t\t// resource doesn't exist\n\t\t\ttry {\n\t\t\t\tparams = await validateEndpointParams(serverEndPoint, params);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tlet result: Response | undefined | void;\n\t\t\ttry {\n\t\t\t\t// If the endpoint declares a schema for this action, validate the\n\t\t\t\t// submitted form data up front and reject with 422 if it fails\n\t\t\t\tconst schema = endpointSchema(serverEndPoint, actionName);\n\t\t\t\tconst form = schema\n\t\t\t\t\t? await validate(schema, await formDataToRecord(ev.request))\n\t\t\t\t\t: undefined;\n\n\t\t\t\tconst serverParams = buildServerParams(ev, url, params, form ? { form } : {});\n\n\t\t\t\tconst serverHooks = await loadServerHooks(handler);\n\t\t\t\tlet entered = 0;\n\t\t\t\tlet enterResponse: Response | undefined = undefined;\n\t\t\t\ttry {\n\t\t\t\t\t// Hooks run from the root down; a hook's enter can return a\n\t\t\t\t\t// Response to short-circuit the action\n\t\t\t\t\tfor (; entered < serverHooks.length && !enterResponse; entered++) {\n\t\t\t\t\t\tconst hookResult = await serverHooks[entered].enter?.(serverParams);\n\t\t\t\t\t\tif (hookResult) {\n\t\t\t\t\t\t\tenterResponse = hookResult;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult = enterResponse || (await action(serverParams));\n\t\t\t\t} finally {\n\t\t\t\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\t\t\t\twhile (entered > 0) {\n\t\t\t\t\t\tentered--;\n\t\t\t\t\t\tawait serverHooks[entered].exit?.(serverParams);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst response = validationErrorResponse(error);\n\t\t\t\tif (response) return response;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (ev.request.headers.has(\"X-Torpor-Form-Submit\")) {\n\t\t\t\t// If the form was submitted from javascript, just return the\n\t\t\t\t// response and it will be handled on the client\n\t\t\t\t// TODO: Should we make the user return a response??\n\t\t\t\tresult ??= ok();\n\n\t\t\t\t// If it's a redirect, we need to stop the browser handling it\n\t\t\t\tif (result.status >= 300 && result.status <= 399) {\n\t\t\t\t\tconst location = result.headers.get(\"Location\") ?? \"\";\n\t\t\t\t\tresult = ok();\n\t\t\t\t\tresult.headers.set(\"X-Torpor-Form-Redirect\", \"\");\n\t\t\t\t\tresult.headers.set(\"Location\", location);\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} else if (\n\t\t\t\t!result ||\n\t\t\t\t(result.status >= 200 && result.status <= 299) ||\n\t\t\t\t(result.status >= 400 && result.status <= 499)\n\t\t\t) {\n\t\t\t\t// If the form was submitted without javascript, and there was\n\t\t\t\t// no result, an ok result, or a 4xx error, re-render the view\n\t\t\t\t// with the form result. The server hook already ran around the\n\t\t\t\t// action, so it is not run again here\n\t\t\t\t// Keep the query string, so that loads validating the query see\n\t\t\t\t// the same values as the original GET. If the form action\n\t\t\t\t// dropped params that the load schema requires, loadView falls\n\t\t\t\t// back to the raw query instead of failing validation\n\t\t\t\tconst newUrl = new URL(url.pathname + url.search, url);\n\t\t\t\tconst formStatus = result?.status;\n\t\t\t\tlet formMessage = await result?.text();\n\t\t\t\tif (formMessage && result?.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t$page.form = JSON.parse(formMessage);\n\t\t\t\t\tformMessage = undefined;\n\t\t\t\t} else {\n\t\t\t\t\t$page.form = {};\n\t\t\t\t}\n\t\t\t\t// Set status and message if they haven't already been set,\n\t\t\t\t// which means that you can just return e.g. forbidden() or\n\t\t\t\t// forbidden(\"no!\") and there will be something you can work\n\t\t\t\t// with in your component, or you can set a completely custom\n\t\t\t\t// object with whatever info you need\n\t\t\t\t$page.form!.status ??= formStatus ?? 0;\n\t\t\t\t$page.form!.message ??= formMessage ?? \"\";\n\t\t\t\treturn await loadView(ev, newUrl, handler, params, template, formStatus, $page.form, true);\n\t\t\t} else {\n\t\t\t\t// If the form was submitted without javascript and there was a\n\t\t\t\t// redirect or server error, just return the result to handle it\n\t\t\t\t// as normal\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn notFound();\n}\n\nasync function loadClientAndServerData(\n\turl: URL,\n\tparams: Record<string, any>,\n\tserverParams: ServerLoadEvent,\n\tdata: Record<string, any>,\n\tclientEndPoint?: PageEndPoint,\n\tserverEndPoint?: PageServerEndPoint,\n) {\n\tif (clientEndPoint?.load) {\n\t\tconst clientParams = buildClientParams(url, params, data);\n\t\tconst clientResponse = await clientEndPoint.load(clientParams);\n\t\tif (clientResponse) {\n\t\t\tif (clientResponse.ok) {\n\t\t\t\tif (clientResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\tObject.assign(data, await clientResponse.json());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn clientResponse;\n\t\t\t}\n\t\t}\n\t}\n\tif (serverEndPoint?.load) {\n\t\tconst serverResponse = await serverEndPoint.load(serverParams);\n\t\tif (serverResponse) {\n\t\t\tif (serverResponse.ok) {\n\t\t\t\tif (serverResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\tObject.assign(data, await serverResponse.json());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn serverResponse;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction buildClientParams(url: URL, params: Record<string, any>, data: Record<string, any>) {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tdata,\n\t};\n}\n\nfunction buildServerParams(\n\tev: ServerEvent,\n\turl: URL,\n\tparams: Record<string, any>,\n\tvalues: { json?: unknown; form?: unknown; query?: unknown } = {},\n): ServerLoadEvent {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tappData: {},\n\t\trequest: ev.request,\n\t\t// The inputs may have been validated already, in which case the request\n\t\t// body has been consumed and the parsed values are returned instead.\n\t\t// Their types come from the endpoint's schemas, so they are loosely\n\t\t// typed here\n\t\tjson: (): Promise<any> =>\n\t\t\tvalues.json !== undefined ? Promise.resolve(values.json) : ev.json(),\n\t\tform: (): Promise<any> =>\n\t\t\tvalues.form !== undefined ? Promise.resolve(values.form) : formDataToRecord(ev.request),\n\t\tquery: (): Promise<any> =>\n\t\t\tvalues.query !== undefined\n\t\t\t\t? Promise.resolve(values.query)\n\t\t\t\t: Promise.resolve(searchParamsToRecord(url.searchParams)),\n\t\tcookies: ev.cookies,\n\t\theaders: ev.headers,\n\t\tadapter: ev.adapter,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serverHandlers-fzIlmvX-.mjs","names":[],"sources":["../src/form/formDataToRecord.ts","../src/state/$serverPage.ts","../src/utils/searchParamsToRecord.ts","../src/validation/endpoint.ts","../src/site/layoutSlots.ts","../src/site/mergeHead.ts","../src/site/serverHandlers.ts"],"sourcesContent":["import type { FormDataRecord } from \"../types/ServerLoadEvent\";\n\n/**\n * Converts the submitted fields of a form request into a plain record: one\n * value per field, or an array when a field was submitted with multiple\n * values (e.g. a multi select). File inputs pass through as `File` values;\n * coercing them is left to the schema or the action.\n *\n * @param request The request (or FormData directly)\n * @returns The field values\n */\nexport default async function formDataToRecord(\n\trequest: Request | FormData,\n): Promise<FormDataRecord> {\n\tconst formData = request instanceof FormData ? request : await request.formData();\n\tconst result: FormDataRecord = {};\n\tfor (const key of formData.keys()) {\n\t\tif (key in result) continue;\n\t\tconst values = formData.getAll(key);\n\t\tresult[key] = values.length > 1 ? values : values[0];\n\t}\n\treturn result;\n}\n","import { $watch } from \"@torpor/view/ssr\";\nimport type PageState from \"../types/PageState\";\n\nconst PAGE_SYMBOL: unique symbol = Symbol.for(\"torp.Page\");\n\n// The server request path has no reactive subscribers, so the state is\n// stored plainly ($watch from `@torpor/view/ssr` is a no-op that returns\n// the object itself) instead of through a reactive proxy. Shares the same\n// `globalThis` slot as the client `$page`, so both variants always see the\n// same state object whichever loads first.\nconst $page: PageState =\n\t// @ts-ignore\n\t(globalThis[PAGE_SYMBOL] ??= $watch({\n\t\tstatus: 404,\n\t\turl: new URL(\"http://localhost\"),\n\t\tform: undefined,\n\t\terror: {\n\t\t\tmessage: \"\",\n\t\t},\n\t}));\n\nexport default $page;\n","import type { QueryRecord } from \"../types/ServerLoadEvent\";\n\n/**\n * Converts a URL's query string into a plain record: one string per param,\n * or an array when a param was repeated.\n *\n * @param searchParams The URL's search params\n * @returns The param values\n */\nexport default function searchParamsToRecord(searchParams: URLSearchParams): QueryRecord {\n\tconst result: QueryRecord = {};\n\tfor (const key of searchParams.keys()) {\n\t\tif (key in result) continue;\n\t\tconst values = searchParams.getAll(key);\n\t\tresult[key] = values.length > 1 ? values : values[0];\n\t}\n\treturn result;\n}\n","import type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport type ServerEndPoint from \"../types/ServerEndPoint\";\nimport type { StandardSchemaV1 } from \"../types/StandardSchema\";\nimport type ServerEvent from \"../server/ServerEvent\";\nimport searchParamsToRecord from \"../utils/searchParamsToRecord\";\nimport unprocessable from \"../response/unprocessable\";\nimport ValidationError from \"./ValidationError\";\nimport validate from \"./validate\";\n\n/**\n * Loose views of an endpoint's schema map, keyed by handler/action name (plus\n * the reserved `params` key). The type-level constraint differs per endpoint\n * type, but the runtime treats them the same.\n */\ntype Schemas = Record<string, StandardSchemaV1 | undefined>;\n\ntype EndPoint = ServerEndPoint | PageServerEndPoint;\n\n/**\n * Gets the standard schema declared for a handler or action, if any. The\n * schemas map is keyed by name; the runtime treats it as a loose record.\n */\nexport function endpointSchema(endPoint: EndPoint, name: string): StandardSchemaV1 | undefined {\n\treturn (endPoint.schema as Schemas | undefined)?.[name];\n}\n\n/**\n * Validates the route params against the endpoint's `params` schema, if it\n * declares one, returning the coerced params. Throws a ValidationError when\n * they don't match, which callers turn into a 404 (params come from the URL,\n * so a failed validation means the resource doesn't exist).\n *\n * @param endPoint The endpoint declaring the (optional) `params` schema\n * @param params The route params from the matched route\n * @returns The validated params\n */\nexport async function validateEndpointParams(\n\tendPoint: EndPoint,\n\tparams: Record<string, any>,\n): Promise<Record<string, any>> {\n\tconst schema = endpointSchema(endPoint, \"params\");\n\treturn schema ? ((await validate(schema, params)) as Record<string, any>) : params;\n}\n\n/**\n * Validates a handler's input against its schema: get/head handlers and load\n * functions validate the URL's query string, other handlers validate the JSON\n * request body. Returns the validated values (an empty object when no schema\n * is declared), which callers pass through to the handler's event.\n *\n * @param schema The handler's (optional) schema\n * @param functionName The handler name (`get`, `post`, `load`, etc)\n * @param url The request URL, for the query string\n * @param ev The server event, for the request body\n * @returns The validated values\n */\nexport async function validateHandlerInput(\n\tschema: StandardSchemaV1 | undefined,\n\tfunctionName: string,\n\turl: URL,\n\tev: ServerEvent,\n): Promise<{ json?: unknown; form?: unknown; query?: unknown }> {\n\tif (!schema) return {};\n\tif (functionName === \"get\" || functionName === \"head\" || functionName === \"load\") {\n\t\treturn { query: await validate(schema, searchParamsToRecord(url.searchParams)) };\n\t}\n\treturn { json: await validate(schema, await ev.json()) };\n}\n\n/**\n * Turns a ValidationError thrown during endpoint validation into a 422\n * response with the schema's issues. Returns undefined for any other error,\n * which callers should rethrow.\n *\n * @param error The error thrown by a handler or validation\n * @returns A 422 response, or undefined when the error isn't a validation failure\n */\nexport function validationErrorResponse(error: unknown): Response | undefined {\n\tif (error instanceof ValidationError) {\n\t\treturn unprocessable({ message: error.message, issues: error.issues });\n\t}\n\treturn undefined;\n}\n","/**\n * Layouts are composed by the layout engine passing each layout (and finally\n * the page) as the default slot of its parent — so every `_layout` component\n * must render `<slot />`, or pass the default slot down to a child component\n * it renders. A layout that doesn't drops its entire content: the server\n * renders the layout's own markup with an empty content area (no error), and\n * the first client-side navigation that reuses the layout crashes on a null\n * slot region.\n *\n * The static `checkLayoutSlots` check catches this at build/dev time; these\n * helpers report it at request time for the cases static analysis can't see\n * (e.g. a `<slot />` rendered conditionally inside `@if`). They are\n * server-side only — nothing here is imported into the client bundle.\n */\n\n/**\n * Returns the path of the outermost layout that never rendered its\n * `<slot />`, or undefined when every level rendered.\n *\n * Slot level j (1-based) is the slot render that layout j - 1 receives: the\n * root layout (layouts[0]) renders level 1, layout i renders level i + 1,\n * and level layouts.length renders the page. A broken level makes every\n * deeper level unreachable, so the first level that never ran identifies\n * the offending layout.\n */\nexport function findMissingSlotLayout(\n\tlayouts: readonly { path: string }[],\n\tinvokedLevels: ReadonlySet<number>,\n): string | undefined {\n\tfor (let level = 1; level <= layouts.length; level++) {\n\t\tif (!invokedLevels.has(level)) {\n\t\t\treturn layouts[level - 1].path;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nconst warnedLayouts = new Set<string>();\n\n/**\n * Reports a layout that dropped its slot content. The condition is a genuine\n * rendering bug (the page content is missing from the output), so it is not\n * dev-gated — but it warns only once per layout path to avoid per-request\n * noise.\n */ export function warnMissingSlotContent(layoutPath: string): void {\n\tif (warnedLayouts.has(layoutPath)) return;\n\twarnedLayouts.add(layoutPath);\n\tconsole.warn(\n\t\t`[torpor] The layout at \"${layoutPath}\" never rendered <slot />, so the page content ` +\n\t\t\t`was not included in the render. Every _layout component must render <slot /> (or ` +\n\t\t\t`pass the default slot down to a child component it renders).`,\n\t);\n}\n","const TITLE_REGEX = /<title(?:\\s[^>]*)?>[\\s\\S]*?<\\/title>/g;\nconst FIRST_TITLE_REGEX = /<title(?:\\s[^>]*)?>[\\s\\S]*?<\\/title>/;\n\n/**\n * Merges the head string rendered by a page (and its layouts) into the site\n * template. The first <title> in the head string -- the page's, since pages\n * render before the layouts around them -- wins, overriding both any later\n * component title (e.g. from a child component) and a static <title> in the\n * template itself. All other head content (styles, meta elements, etc) is\n * appended where %COMPONENT_HEAD% sits in the template, before </head>.\n */\nexport default function mergeHead(template: string, head: string): string {\n\tconst titles = head.match(TITLE_REGEX);\n\tlet html = template;\n\tlet headHtml = head;\n\tif (titles?.length) {\n\t\theadHtml = head.replace(TITLE_REGEX, \"\");\n\t\thtml = html.replace(FIRST_TITLE_REGEX, \"\");\n\t\theadHtml = titles[0] + headHtml;\n\t}\n\treturn html.replace(\"%COMPONENT_HEAD%\", headHtml);\n}\n","import { type ServerComponent, type ServerSlotRender } from \"@torpor/view/ssr\";\nimport formDataToRecord from \"../form/formDataToRecord.ts\";\nimport notFound from \"../response/notFound.ts\";\nimport ok from \"../response/ok.ts\";\nimport seeOther from \"../response/seeOther.ts\";\nimport ServerEvent from \"../server/ServerEvent.ts\";\nimport $page from \"../state/$serverPage.ts\";\nimport type PageEndPoint from \"../types/PageEndPoint.ts\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint.ts\";\nimport type RouteHandler from \"../types/RouteHandler.ts\";\nimport type ServerRequest from \"../types/ServerRequest.ts\";\nimport {\n\tERROR_ROUTE,\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport type ServerEndPoint from \"../types/ServerEndPoint.ts\";\nimport type ServerHook from \"../types/ServerHook.ts\";\nimport type ServerLoadEvent from \"../types/ServerLoadEvent.ts\";\nimport searchParamsToRecord from \"../utils/searchParamsToRecord.ts\";\nimport validate from \"../validation/validate.ts\";\nimport ValidationError from \"../validation/ValidationError.ts\";\nimport {\n\tendpointSchema,\n\tvalidateEndpointParams,\n\tvalidationErrorResponse,\n} from \"../validation/endpoint.ts\";\nimport { findMissingSlotLayout, warnMissingSlotContent } from \"./layoutSlots.ts\";\nimport mergeHead from \"./mergeHead.ts\";\nimport type Router from \"./Router.ts\";\n\n/**\n * The site's request handler, as created by `createServerLoad`.\n */\nexport type ServerLoad = (ev: ServerEvent, template?: string) => Promise<Response>;\n\n/**\n * Creates the site's request handler for the given router. This is kept\n * separate from serverEntry, which imports the virtual\n * `@torpor/build/manifest` module (it only exists when a site runs or\n * builds), so that tests can exercise the handlers with their own routes.\n *\n * @param router The router, built from the site's routes\n * @returns The request handler, which takes the site template\n */\nexport function createServerLoad(router: Router): ServerLoad {\n\treturn async function load(ev, template) {\n\t\tconst url = ev.url;\n\t\tconst path = url.pathname;\n\t\tconst query = url.searchParams;\n\n\t\t//console.log(`handling ${ev.request.method} for '${path}'${query.size ? ` with ${query}` : \"\"}`);\n\n\t\tlet route = router.match(path, query);\n\t\tif (!route) {\n\t\t\t// If the route wasn't found, the user may be posting a form to a\n\t\t\t// +page.server.ts route that doesn't have a corresponding +page.ts\n\t\t\t// route, which is allowed, so check for that as well\n\t\t\tif (ev.request.method === \"POST\" && !path.endsWith(\"/~server\")) {\n\t\t\t\tconst serverPath =\n\t\t\t\t\t(path.endsWith(\"/\") ? path.substring(0, path.length - 1) : path) + \"/~server\";\n\t\t\t\troute = router.match(serverPath, query);\n\t\t\t}\n\t\t}\n\t\tif (!route) {\n\t\t\treturn handleResponse(notFound());\n\t\t}\n\t\tconst handler = route.handler;\n\t\tconst params = route.params || {};\n\n\t\t// Update $page before building the components\n\t\t$page.url = url;\n\t\tif (path.endsWith(\"/_error\")) {\n\t\t\t$page.status = parseInt(query.get(\"status\") ?? \"404\");\n\t\t\t$page.error = { message: query.get(\"message\") ?? \"\" };\n\t\t} else {\n\t\t\t$page.status = 200;\n\t\t}\n\n\t\t// TODO: Hit the server hook out here\n\t\t// We could maybe set up data loading as middleware on a route??????\n\n\t\tswitch (handler.type) {\n\t\t\tcase PAGE_ROUTE:\n\t\t\tcase LAYOUT_ROUTE: {\n\t\t\t\t// It's a /+page.ts or /_layout.ts endpoint\n\t\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\t\treturn handleResponse(await loadView(ev, url, handler, params, template));\n\t\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\t\t// The server end point comes from the sibling /+page.server.ts, if applicable\n\t\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined =\n\t\t\t\t\t\thandler.serverEndPoint && (await handler.serverEndPoint()).default;\n\t\t\t\t\treturn handleResponse(\n\t\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase PAGE_SERVER_ROUTE:\n\t\t\tcase LAYOUT_SERVER_ROUTE: {\n\t\t\t\t// It's a /+page.server.ts or /_layout.server.ts endpoint\n\t\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\t\treturn await loadData(ev, url, handler, \"load\", params);\n\t\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined = (await resolveModule(handler))\n\t\t\t\t\t\t.default;\n\t\t\t\t\treturn handleResponse(\n\t\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SERVER_ROUTE: {\n\t\t\t\t// It's a /+server.ts endpoint\n\t\t\t\tconst functionName = ev.request.method.toLowerCase().replace(\"delete\", \"del\");\n\t\t\t\treturn await loadData(ev, url, handler, functionName, params);\n\t\t\t}\n\t\t\tcase HOOK_ROUTE:\n\t\t\tcase HOOK_SERVER_ROUTE: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ERROR_ROUTE: {\n\t\t\t\treturn await loadView(ev, url, handler, params, template);\n\t\t\t}\n\t\t}\n\n\t\treturn notFound();\n\t};\n}\n\n/**\n * Resolves the route's endpoint module, caching it on the handler so warm\n * requests don't pay for the loader promise.\n */\nasync function resolveModule(handler: RouteHandler): Promise<any> {\n\treturn (handler.resolvedModule ??= await (handler.modulePromise ??= handler.endPoint()));\n}\n\nasync function loadServerHooks(handler: RouteHandler): Promise<ServerHook[]> {\n\tif (!handler.serverHooks) return [];\n\t// Resolve each hook module once and cache the result on the handler\n\treturn (handler.resolvedHooks ??= Promise.all(\n\t\thandler.serverHooks.map(async (load) => (await load()).default),\n\t));\n}\n\nasync function handleResponse(response: Response, fromForm = false): Promise<Response> {\n\t$page.status = response.status;\n\n\t// Success codes and redirect codes are acceptable\n\tif (response.status >= 200 && response.status <= 399) {\n\t\treturn response;\n\t}\n\n\t// 4xx error codes are acceptable from form actions\n\tif (fromForm && response.status >= 400 && response.status <= 499) {\n\t\treturn response;\n\t}\n\n\t// It's an error, so redirect to the error page\n\t// We're just pushing the status and message in the URL, but maybe there's a\n\t// more sophisticated way to do this?\n\t// TODO: Should be returning loadView rather than redirecting\n\t// TODO: Should be returning the NEAREST error page to this path, including layouts\n\tlet params = new URLSearchParams();\n\tparams.append(\"status\", $page.status.toString());\n\tlet message = await response.text();\n\tif (response.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\tconst data = JSON.parse(message);\n\t\tmessage = data.message ?? message;\n\t}\n\tif (message) {\n\t\tif ($page.error) {\n\t\t\t$page.error.message = message;\n\t\t} else {\n\t\t\t$page.error = { message };\n\t\t}\n\t\tparams.append(\"message\", message);\n\t}\n\treturn seeOther(`/_error?${params.toString()}`);\n}\n\nasync function loadData(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tfunctionName: string,\n\tparams: Record<string, any>,\n) {\n\t// The endpoint module is cached on the handler, so once warm this is a\n\t// plain property read\n\tconst mod = handler.resolvedModule ?? (await resolveModule(handler));\n\tconst serverEndPoint: ServerEndPoint | undefined = mod?.default;\n\t// `functionName` is computed from the request method, so the handlers are\n\t// accessed through a loose record\n\tconst handlerFn = (\n\t\tserverEndPoint as unknown as Record<string, ServerRequest | undefined> | undefined\n\t)?.[functionName];\n\tif (!serverEndPoint || !handlerFn) {\n\t\treturn notFound();\n\t}\n\n\t// Route params come from the URL, so a failed validation means the\n\t// resource doesn't exist. Only endpoints declaring a params schema pay\n\t// for validation\n\tconst paramsSchema = endpointSchema(serverEndPoint, \"params\");\n\tif (paramsSchema) {\n\t\ttry {\n\t\t\tparams = (await validate(paramsSchema, params)) as Record<string, any>;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\ttry {\n\t\t// If the endpoint declares a schema for this handler, validate its\n\t\t// input up front and reject with 422 if it fails. get/head/load\n\t\t// schemas validate the query string; other schemas validate the json\n\t\t// body. Endpoints without a schema skip straight to the handler\n\t\tconst schema = endpointSchema(serverEndPoint, functionName);\n\t\tconst values = schema\n\t\t\t? functionName === \"get\" || functionName === \"head\" || functionName === \"load\"\n\t\t\t\t? { query: await validate(schema, searchParamsToRecord(url.searchParams)) }\n\t\t\t\t: { json: await validate(schema, await ev.json()) }\n\t\t\t: {};\n\n\t\tconst serverParams = buildServerParams(ev, url, params, values);\n\n\t\t// Hooks are resolved once per handler; routes without hooks don't\n\t\t// await anything here\n\t\tconst hooks = handler.serverHooks ? await loadServerHooks(handler) : [];\n\n\t\tlet entered = 0;\n\t\tlet enterResponse: Response | undefined = undefined;\n\t\ttry {\n\t\t\t// Hooks run from the root down; a hook's enter can return a\n\t\t\t// Response to short-circuit the request\n\t\t\tfor (; entered < hooks.length && !enterResponse; entered++) {\n\t\t\t\tconst hookResult = await hooks[entered].enter?.(serverParams);\n\t\t\t\tif (hookResult) {\n\t\t\t\t\tenterResponse = hookResult;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A hook's enter response short-circuits the request; otherwise, if\n\t\t\t// there was no response returned from load (such as errors or a\n\t\t\t// redirect), send an ok response\n\t\t\treturn enterResponse || (await handlerFn(serverParams)) || ok();\n\t\t} finally {\n\t\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\t\twhile (entered > 0) {\n\t\t\t\tentered--;\n\t\t\t\tawait hooks[entered].exit?.(serverParams);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst response = validationErrorResponse(error);\n\t\tif (response) return response;\n\t\tthrow error;\n\t}\n}\n\nasync function loadView(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tparams: Record<string, any>,\n\ttemplate: string | undefined,\n\tformStatus?: number,\n\tform?: Record<string, string | number>,\n\tfromForm?: boolean,\n) {\n\t// There must be a client endpoint with a component\n\tconst clientEndPoint: PageEndPoint | undefined = (await resolveModule(handler)).default;\n\tif (!clientEndPoint?.component) {\n\t\treturn notFound();\n\t}\n\n\t// The template comes from site.html, which endpoints-only sites don't have\n\tif (!template) {\n\t\tthrow new Error(\n\t\t\t\"Page routes require a src/site.html file, which was not found; add it, or remove page/layout routes to serve endpoints only\",\n\t\t);\n\t}\n\n\t// There may be a server endpoint\n\tconst serverEndPoint: PageServerEndPoint | undefined =\n\t\thandler.serverEndPoint && (await handler.serverEndPoint())?.default;\n\n\t// Validate the route params and the load query against the server\n\t// endpoint's schemas, if it declares any. Params come from the URL, so a\n\t// failed validation means the resource doesn't exist; a failed query goes\n\t// to the error page like any other load failure\n\tlet query: unknown;\n\tif (serverEndPoint) {\n\t\ttry {\n\t\t\tparams = await validateEndpointParams(serverEndPoint, params);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\tthrow error;\n\t\t}\n\t\tconst loadSchema = endpointSchema(serverEndPoint, \"load\");\n\t\tif (loadSchema) {\n\t\t\tconst queryRecord = searchParamsToRecord(url.searchParams);\n\t\t\ttry {\n\t\t\t\tquery = await validate(loadSchema, queryRecord);\n\t\t\t} catch (error) {\n\t\t\t\t// A form re-render's url is the POST's, and a form action can\n\t\t\t\t// drop query params that the load schema requires, so failing\n\t\t\t\t// validation here would lose the form errors. Fall back to the\n\t\t\t\t// raw query values instead and let the load make of them what\n\t\t\t\t// it can\n\t\t\t\tif (fromForm) {\n\t\t\t\t\tquery = queryRecord;\n\t\t\t\t} else {\n\t\t\t\t\tconst response = validationErrorResponse(error);\n\t\t\t\t\tif (response) return response;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Maybe hit the server hooks -- unless they already ran for this request,\n\t// which is the case when the view is re-rendered after a form action\n\tconst serverParams = buildServerParams(ev, url, params, query ? { query } : {});\n\tconst serverHooks = fromForm ? [] : await loadServerHooks(handler);\n\tlet entered = 0;\n\tlet enterResponse: Response | undefined = undefined;\n\ttry {\n\t\t// Hooks run from the root down; a hook's enter can return a Response\n\t\t// to short-circuit the request\n\t\tfor (; entered < serverHooks.length && !enterResponse; entered++) {\n\t\t\tconst hookResult = await serverHooks[entered].enter?.(serverParams);\n\t\t\tif (hookResult) {\n\t\t\t\tenterResponse = hookResult;\n\t\t\t}\n\t\t}\n\t\tif (enterResponse) {\n\t\t\treturn enterResponse;\n\t\t}\n\n\t\t// Pass the data into $props\n\t\t// TODO: Promise.all\n\t\t// NOTE: We're loading data from top to bottom, overriding as we go, and I'm\n\t\t// not sure if this is the best way to go\n\t\tlet data = {};\n\t\tif (handler.layouts) {\n\t\t\tfor (let layout of handler.layouts) {\n\t\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await layout.endPoint())?.default;\n\t\t\t\tconst layoutServerEndPoint: PageServerEndPoint | undefined =\n\t\t\t\t\tlayout.serverEndPoint && (await layout.serverEndPoint())?.default;\n\t\t\t\tconst layoutResponse = await loadClientAndServerData(\n\t\t\t\t\turl,\n\t\t\t\t\tparams,\n\t\t\t\t\tserverParams,\n\t\t\t\t\tdata,\n\t\t\t\t\tlayoutEndPoint,\n\t\t\t\t\tlayoutServerEndPoint,\n\t\t\t\t);\n\t\t\t\tif (layoutResponse?.ok === false) {\n\t\t\t\t\treturn layoutResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet endPointResponse = await loadClientAndServerData(\n\t\t\turl,\n\t\t\tparams,\n\t\t\tserverParams,\n\t\t\tdata,\n\t\t\tclientEndPoint,\n\t\t\tserverEndPoint,\n\t\t);\n\t\tif (endPointResponse?.ok === false) {\n\t\t\treturn endPointResponse;\n\t\t}\n\t\tlet $props: Record<string, any> = { data, form };\n\n\t\tlet styles = \"\";\n\n\t\t// If there are layouts, work our way upwards, pushing each component into\n\t\t// the default slot of its parent\n\t\t// TODO: Also handle layout server data\n\t\t// TODO: There's probably a nicer way to do this with reducers or something\n\t\tlet component = clientEndPoint.component as ServerComponent;\n\t\tlet slots: Record<string, ServerSlotRender> | undefined = undefined;\n\t\t// Which slot levels actually ran during the render below, so a layout\n\t\t// that never rendered its <slot /> (silently dropping the page\n\t\t// content) can be reported (see findMissingSlotLayout)\n\t\tconst invokedLevels = new Set<number>();\n\t\tconst trackSlot = (level: number, slot: ServerSlotRender): ServerSlotRender => {\n\t\t\treturn ($slot, $context) => {\n\t\t\t\tinvokedLevels.add(level);\n\t\t\t\treturn slot($slot, $context);\n\t\t\t};\n\t\t};\n\t\tif (handler.layouts) {\n\t\t\tlet slotFunctions: ServerSlotRender[] = [];\n\t\t\t// The last slot function will render the client component\n\t\t\tslotFunctions[handler.layouts.length] = trackSlot(\n\t\t\t\thandler.layouts.length,\n\t\t\t\tasync (_, $context) => {\n\t\t\t\t\tlet { body, head } = await (clientEndPoint.component as ServerComponent)(\n\t\t\t\t\t\t$props,\n\t\t\t\t\t\t$context,\n\t\t\t\t\t);\n\t\t\t\t\tstyles += head;\n\t\t\t\t\treturn body;\n\t\t\t\t},\n\t\t\t);\n\t\t\tfor (let i = handler.layouts.length - 1; i >= 0; i--) {\n\t\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await handler.layouts[i].endPoint())\n\t\t\t\t\t?.default;\n\t\t\t\tif (layoutEndPoint?.component) {\n\t\t\t\t\tif (i === 0) {\n\t\t\t\t\t\tcomponent = layoutEndPoint.component as ServerComponent;\n\t\t\t\t\t\tslots = { _: slotFunctions[i + 1] };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tslotFunctions[i] = trackSlot(i, async (_, $context) => {\n\t\t\t\t\t\t\tlet { body, head } = await (layoutEndPoint.component as ServerComponent)(\n\t\t\t\t\t\t\t\t$props,\n\t\t\t\t\t\t\t\t$context,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t_: slotFunctions[i + 1],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tstyles += head;\n\t\t\t\t\t\t\treturn body;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet html;\n\t\ttry {\n\t\t\tlet { body, head } = await component($props, undefined, slots);\n\n\t\t\t// Put the form info in a hidden input so that it can be accessed on the client\n\t\t\tif (form) {\n\t\t\t\tbody += `\\n<input type=\"hidden\" id=\"t-form-data\" value='${JSON.stringify(form).replaceAll(\"'\", \"\\\\'\")}' />`;\n\t\t\t}\n\n\t\t\tstyles += head;\n\t\t\thtml = mergeHead(template, styles).replace(\"%COMPONENT_BODY%\", body);\n\t\t} catch (error) {\n\t\t\t// TODO: Show a proper Error component\n\t\t\thtml = '<span style=\"color: red\">Script syntax error</span><p>' + error + \"</p>\";\n\t\t\tconsole.log(error);\n\t\t}\n\n\t\t// A layout that never rendered <slot /> silently drops the whole page\n\t\t// content from the output; find and report the outermost one\n\t\tif (handler.layouts) {\n\t\t\tconst missingLayout = findMissingSlotLayout(handler.layouts, invokedLevels);\n\t\t\tif (missingLayout !== undefined) {\n\t\t\t\twarnMissingSlotContent(missingLayout);\n\t\t\t}\n\t\t}\n\n\t\treturn new Response(html, {\n\t\t\tstatus: formStatus ?? 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/html\",\n\t\t\t},\n\t\t});\n\t} finally {\n\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\twhile (entered > 0) {\n\t\t\tentered--;\n\t\t\tawait serverHooks[entered].exit?.(serverParams);\n\t\t}\n\t}\n}\n\nasync function runAction(\n\tev: ServerEvent,\n\turl: URL,\n\thandler: RouteHandler,\n\tserverEndPoint: PageServerEndPoint | undefined,\n\tparams: Record<string, any>,\n\tquery: URLSearchParams,\n\ttemplate: string | undefined,\n) {\n\t// The action name rides in the query, so look for a `?/name` key rather\n\t// than taking the first key -- the url may carry ordinary load query\n\t// params as well (e.g. `?page=3&/like`, or a default action posted to a\n\t// url that already has a query). A key that names a declared action also\n\t// matches (e.g. `?set`), and a form without an action attribute calls the\n\t// `default` action\n\tconst queryKeys = Array.from(query.keys());\n\tconst actionKey =\n\t\tqueryKeys.find((key) => key.startsWith(\"/\")) ??\n\t\tqueryKeys.find((key) => !!serverEndPoint?.actions?.[key.replace(/^\\//, \"\")]);\n\tconst actionName = (actionKey ?? \"default\").replace(/^\\//, \"\");\n\tif (serverEndPoint?.actions) {\n\t\tconst action = serverEndPoint.actions[actionName];\n\t\tif (action) {\n\t\t\tif (actionName === \"load\" || actionName === \"params\") {\n\t\t\t\t// These names are reserved in the endpoint's schema map: `load`\n\t\t\t\t// validates the query string and `params` the route params, so\n\t\t\t\t// an action with one of these names would get the wrong schema\n\t\t\t\t// applied to its form data\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The action name \"${actionName}\" is reserved. ` +\n\t\t\t\t\t\t`Rename the action (and its schema key, if any), e.g. to \"save\".`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Route params come from the URL, so a failed validation means the\n\t\t\t// resource doesn't exist\n\t\t\ttry {\n\t\t\t\tparams = await validateEndpointParams(serverEndPoint, params);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof ValidationError) return notFound();\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tlet result: Response | undefined | void;\n\t\t\ttry {\n\t\t\t\t// If the endpoint declares a schema for this action, validate the\n\t\t\t\t// submitted form data up front and reject with 422 if it fails\n\t\t\t\tconst schema = endpointSchema(serverEndPoint, actionName);\n\t\t\t\tconst form = schema\n\t\t\t\t\t? await validate(schema, await formDataToRecord(ev.request))\n\t\t\t\t\t: undefined;\n\n\t\t\t\tconst serverParams = buildServerParams(ev, url, params, form ? { form } : {});\n\n\t\t\t\tconst serverHooks = await loadServerHooks(handler);\n\t\t\t\tlet entered = 0;\n\t\t\t\tlet enterResponse: Response | undefined = undefined;\n\t\t\t\ttry {\n\t\t\t\t\t// Hooks run from the root down; a hook's enter can return a\n\t\t\t\t\t// Response to short-circuit the action\n\t\t\t\t\tfor (; entered < serverHooks.length && !enterResponse; entered++) {\n\t\t\t\t\t\tconst hookResult = await serverHooks[entered].enter?.(serverParams);\n\t\t\t\t\t\tif (hookResult) {\n\t\t\t\t\t\t\tenterResponse = hookResult;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult = enterResponse || (await action(serverParams));\n\t\t\t\t} finally {\n\t\t\t\t\t// Run exit hooks in reverse order for hooks that were entered\n\t\t\t\t\twhile (entered > 0) {\n\t\t\t\t\t\tentered--;\n\t\t\t\t\t\tawait serverHooks[entered].exit?.(serverParams);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst response = validationErrorResponse(error);\n\t\t\t\tif (response) return response;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (ev.request.headers.has(\"X-Torpor-Form-Submit\")) {\n\t\t\t\t// If the form was submitted from javascript, just return the\n\t\t\t\t// response and it will be handled on the client\n\t\t\t\t// TODO: Should we make the user return a response??\n\t\t\t\tresult ??= ok();\n\n\t\t\t\t// If it's a redirect, we need to stop the browser handling it\n\t\t\t\tif (result.status >= 300 && result.status <= 399) {\n\t\t\t\t\tconst location = result.headers.get(\"Location\") ?? \"\";\n\t\t\t\t\tresult = ok();\n\t\t\t\t\tresult.headers.set(\"X-Torpor-Form-Redirect\", \"\");\n\t\t\t\t\tresult.headers.set(\"Location\", location);\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} else if (\n\t\t\t\t!result ||\n\t\t\t\t(result.status >= 200 && result.status <= 299) ||\n\t\t\t\t(result.status >= 400 && result.status <= 499)\n\t\t\t) {\n\t\t\t\t// If the form was submitted without javascript, and there was\n\t\t\t\t// no result, an ok result, or a 4xx error, re-render the view\n\t\t\t\t// with the form result. The server hook already ran around the\n\t\t\t\t// action, so it is not run again here\n\t\t\t\t// Keep the query string, so that loads validating the query see\n\t\t\t\t// the same values as the original GET. If the form action\n\t\t\t\t// dropped params that the load schema requires, loadView falls\n\t\t\t\t// back to the raw query instead of failing validation\n\t\t\t\tconst newUrl = new URL(url.pathname + url.search, url);\n\t\t\t\tconst formStatus = result?.status;\n\t\t\t\tlet formMessage = await result?.text();\n\t\t\t\tif (formMessage && result?.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t$page.form = JSON.parse(formMessage);\n\t\t\t\t\tformMessage = undefined;\n\t\t\t\t} else {\n\t\t\t\t\t$page.form = {};\n\t\t\t\t}\n\t\t\t\t// Set status and message if they haven't already been set,\n\t\t\t\t// which means that you can just return e.g. forbidden() or\n\t\t\t\t// forbidden(\"no!\") and there will be something you can work\n\t\t\t\t// with in your component, or you can set a completely custom\n\t\t\t\t// object with whatever info you need\n\t\t\t\t$page.form!.status ??= formStatus ?? 0;\n\t\t\t\t$page.form!.message ??= formMessage ?? \"\";\n\t\t\t\treturn await loadView(ev, newUrl, handler, params, template, formStatus, $page.form, true);\n\t\t\t} else {\n\t\t\t\t// If the form was submitted without javascript and there was a\n\t\t\t\t// redirect or server error, just return the result to handle it\n\t\t\t\t// as normal\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn notFound();\n}\n\nasync function loadClientAndServerData(\n\turl: URL,\n\tparams: Record<string, any>,\n\tserverParams: ServerLoadEvent,\n\tdata: Record<string, any>,\n\tclientEndPoint?: PageEndPoint,\n\tserverEndPoint?: PageServerEndPoint,\n) {\n\tif (clientEndPoint?.load) {\n\t\tconst clientParams = buildClientParams(url, params, data);\n\t\tconst clientResponse = await clientEndPoint.load(clientParams);\n\t\tif (clientResponse) {\n\t\t\tif (clientResponse.ok) {\n\t\t\t\tif (clientResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\tObject.assign(data, await clientResponse.json());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn clientResponse;\n\t\t\t}\n\t\t}\n\t}\n\tif (serverEndPoint?.load) {\n\t\tconst serverResponse = await serverEndPoint.load(serverParams);\n\t\tif (serverResponse) {\n\t\t\tif (serverResponse.ok) {\n\t\t\t\tif (serverResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\tObject.assign(data, await serverResponse.json());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn serverResponse;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction buildClientParams(url: URL, params: Record<string, any>, data: Record<string, any>) {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tdata,\n\t};\n}\n\nfunction buildServerParams(\n\tev: ServerEvent,\n\turl: URL,\n\tparams: Record<string, any>,\n\tvalues: { json?: unknown; form?: unknown; query?: unknown } = {},\n): ServerLoadEvent {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tappData: {},\n\t\trequest: ev.request,\n\t\t// The inputs may have been validated already, in which case the request\n\t\t// body has been consumed and the parsed values are returned instead.\n\t\t// Their types come from the endpoint's schemas, so they are loosely\n\t\t// typed here\n\t\tjson: (): Promise<any> =>\n\t\t\tvalues.json !== undefined ? Promise.resolve(values.json) : ev.json(),\n\t\tform: (): Promise<any> =>\n\t\t\tvalues.form !== undefined ? Promise.resolve(values.form) : formDataToRecord(ev.request),\n\t\tquery: (): Promise<any> =>\n\t\t\tvalues.query !== undefined\n\t\t\t\t? Promise.resolve(values.query)\n\t\t\t\t: Promise.resolve(searchParamsToRecord(url.searchParams)),\n\t\tcookies: ev.cookies,\n\t\theaders: ev.headers,\n\t\tadapter: ev.adapter,\n\t};\n}\n"],"mappings":"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"}
|
package/dist/test.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Router } from "./Router-C4ADUfhv.mjs";
|
|
2
2
|
import { t as ServerEvent } from "./ServerEvent-gmOvC_Yf.mjs";
|
|
3
|
-
import { t as createServerLoad } from "./serverHandlers-
|
|
3
|
+
import { t as createServerLoad } from "./serverHandlers-fzIlmvX-.mjs";
|
|
4
4
|
import fpath from "node:path";
|
|
5
5
|
//#region src/test/runTest.ts
|
|
6
6
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@torpor/build",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A framework for building sites and apps with Torpor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
"dotenv": "^17.4.2",
|
|
72
72
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
|
|
73
73
|
"vite-plus": "0.3.0",
|
|
74
|
-
"@torpor/unplugin": "^1.0.
|
|
75
|
-
"@torpor/view": "^1.0
|
|
74
|
+
"@torpor/unplugin": "^1.0.4",
|
|
75
|
+
"@torpor/view": "^1.1.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|