@torpor/build 0.4.14 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/Jsonify-Dg6gChd3.d.mts +10 -0
- package/dist/Jsonify-Dg6gChd3.d.mts.map +1 -0
- package/dist/ParseRouteParams-DBmqlmLh.d.mts +42 -0
- package/dist/ParseRouteParams-DBmqlmLh.d.mts.map +1 -0
- package/dist/{RouteType-B6BMOyYw.mjs → Router-C4ADUfhv.mjs} +30 -42
- package/dist/Router-C4ADUfhv.mjs.map +1 -0
- package/dist/Server-BnjLJleZ.mjs +104 -0
- package/dist/Server-BnjLJleZ.mjs.map +1 -0
- package/dist/Server-Cler2w5O.d.mts +61 -0
- package/dist/Server-Cler2w5O.d.mts.map +1 -0
- package/dist/ServerEvent-CTx3Q-hk.d.mts +48 -0
- package/dist/ServerEvent-CTx3Q-hk.d.mts.map +1 -0
- package/dist/{ServerEvent-CxPwA4lH.mjs → ServerEvent-Dljn5i7A.mjs} +37 -11
- package/dist/ServerEvent-Dljn5i7A.mjs.map +1 -0
- package/dist/Site-CE0_o5Ci.d.mts +566 -0
- package/dist/Site-CE0_o5Ci.d.mts.map +1 -0
- package/dist/StandardSchema-D28L8_zZ.d.mts +100 -0
- package/dist/StandardSchema-D28L8_zZ.d.mts.map +1 -0
- package/dist/TypedResponse-6lznqN4U.d.mts +22 -0
- package/dist/TypedResponse-6lznqN4U.d.mts.map +1 -0
- package/dist/{_page-BQs4WvCO.mjs → _page-4cQKs_Dn.mjs} +3 -5
- package/dist/_page-4cQKs_Dn.mjs.map +1 -0
- package/dist/bin/index.d.mts +1 -1
- package/dist/bin/index.js +15 -11
- package/dist/bin/index.js.map +1 -1
- package/dist/clientEntry.d.mts +1 -0
- package/dist/clientEntry.mjs +59 -0
- package/dist/clientEntry.mjs.map +1 -0
- package/dist/clientEntryDev.d.mts +1 -0
- package/dist/clientEntryDev.mjs +7 -0
- package/dist/clientEntryDev.mjs.map +1 -0
- package/dist/dev.d.mts +3 -0
- package/dist/dev.mjs +3 -0
- package/dist/endpoint-EULRGCKA.mjs +108 -0
- package/dist/endpoint-EULRGCKA.mjs.map +1 -0
- package/dist/flattenHeaders-DM5qsSqO.mjs +13 -0
- package/dist/flattenHeaders-DM5qsSqO.mjs.map +1 -0
- package/dist/form.d.mts +35 -0
- package/dist/form.d.mts.map +1 -0
- package/dist/form.mjs +48 -0
- package/dist/form.mjs.map +1 -0
- package/dist/index.d.mts +72 -156
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +158 -26
- package/dist/index.mjs.map +1 -1
- package/dist/load-BntzvmwL.mjs +228 -0
- package/dist/load-BntzvmwL.mjs.map +1 -0
- package/dist/nav.d.mts +58 -5
- package/dist/nav.d.mts.map +1 -1
- package/dist/nav.mjs +63 -209
- package/dist/nav.mjs.map +1 -1
- package/dist/openapi.d.mts +144 -0
- package/dist/openapi.d.mts.map +1 -0
- package/dist/openapi.mjs +2 -0
- package/dist/pathTrie-D4Ax2Mu9.mjs +160 -0
- package/dist/pathTrie-D4Ax2Mu9.mjs.map +1 -0
- package/dist/plugin-D8Www11B.mjs +202 -0
- package/dist/plugin-D8Www11B.mjs.map +1 -0
- package/dist/{response-C5TtAsh1.mjs → response-Bg4w2S1q.mjs} +16 -39
- package/dist/response-Bg4w2S1q.mjs.map +1 -0
- package/dist/response.d.mts +309 -289
- package/dist/response.d.mts.map +1 -1
- package/dist/response.mjs +3 -4
- package/dist/run.d.mts +11 -4
- package/dist/run.d.mts.map +1 -1
- package/dist/run.mjs +2 -8
- package/dist/runOpenApi-DlOgF2Il.mjs +1419 -0
- package/dist/runOpenApi-DlOgF2Il.mjs.map +1 -0
- package/dist/schema.d.mts +32 -0
- package/dist/schema.d.mts.map +1 -0
- package/dist/schema.mjs +2 -0
- package/dist/server/Server.d.mts +2 -0
- package/dist/server/Server.mjs +2 -0
- package/dist/server.d.mts +11 -8
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +133 -4
- package/dist/server.mjs.map +1 -0
- package/dist/serverEntry-1qY3wZig.mjs +351 -0
- package/dist/serverEntry-1qY3wZig.mjs.map +1 -0
- package/dist/serverEntry-BAO8m03V.d.mts +6 -0
- package/dist/serverEntry-BAO8m03V.d.mts.map +1 -0
- package/dist/serverEntry.d.mts +2 -0
- package/dist/serverEntry.mjs +2 -0
- package/dist/state.d.mts.map +1 -1
- package/dist/state.mjs +2 -3
- package/dist/test.d.mts +8 -10
- package/dist/test.d.mts.map +1 -1
- package/dist/test.mjs +181 -79
- package/dist/test.mjs.map +1 -1
- package/dist/{seeOther-B4Yhu9iq.mjs → unprocessable-DAZbrDeR.mjs} +34 -13
- package/dist/unprocessable-DAZbrDeR.mjs.map +1 -0
- package/dist/validate-Ok4krlkX.mjs +40 -0
- package/dist/validate-Ok4krlkX.mjs.map +1 -0
- package/package.json +30 -18
- package/dist/RouteType-B6BMOyYw.mjs.map +0 -1
- package/dist/Server-CF5wDJp6.d.mts +0 -78
- package/dist/Server-CF5wDJp6.d.mts.map +0 -1
- package/dist/ServerEvent-CxPwA4lH.mjs.map +0 -1
- package/dist/Site-DgC6WWn1.d.mts +0 -78
- package/dist/Site-DgC6WWn1.d.mts.map +0 -1
- package/dist/_page-BQs4WvCO.mjs.map +0 -1
- package/dist/connectMiddleware-D7nehjj3.mjs +0 -252
- package/dist/connectMiddleware-D7nehjj3.mjs.map +0 -1
- package/dist/pathToRegex-TUAMc3zS.mjs +0 -11
- package/dist/pathToRegex-TUAMc3zS.mjs.map +0 -1
- package/dist/response-C5TtAsh1.mjs.map +0 -1
- package/dist/run-BPFtSYA3.mjs +0 -332
- package/dist/run-BPFtSYA3.mjs.map +0 -1
- package/dist/seeOther-B4Yhu9iq.mjs.map +0 -1
- package/src/bin/index.ts +0 -11
- package/src/index.ts +0 -30
- package/src/nav/formSubmit.ts +0 -56
- package/src/nav/load.ts +0 -9
- package/src/nav/loadData.ts +0 -134
- package/src/nav/navigate.ts +0 -164
- package/src/nav/reload.ts +0 -9
- package/src/nav.ts +0 -4
- package/src/response/badRequest.ts +0 -19
- package/src/response/created.ts +0 -20
- package/src/response/forbidden.ts +0 -21
- package/src/response/found.ts +0 -30
- package/src/response/methodNotAllowed.ts +0 -18
- package/src/response/movedPermanently.ts +0 -25
- package/src/response/notFound.ts +0 -24
- package/src/response/notModified.ts +0 -34
- package/src/response/ok.ts +0 -29
- package/src/response/permanentRedirect.ts +0 -30
- package/src/response/response.ts +0 -22
- package/src/response/seeOther.ts +0 -19
- package/src/response/serverError.ts +0 -24
- package/src/response/temporaryRedirect.ts +0 -31
- package/src/response/transfer.ts +0 -14
- package/src/response/unauthorized.ts +0 -21
- package/src/response/unprocessable.ts +0 -18
- package/src/response.ts +0 -37
- package/src/run/prepareTemplate.ts +0 -39
- package/src/run/run.ts +0 -62
- package/src/run/runBuild.ts +0 -77
- package/src/run/runDev.ts +0 -89
- package/src/run/runPreview.ts +0 -93
- package/src/run.ts +0 -6
- package/src/server/CookieHelper.ts +0 -36
- package/src/server/HeaderHelper.ts +0 -25
- package/src/server/Routerx.ts +0 -72
- package/src/server/Server.ts +0 -144
- package/src/server/ServerEvent.ts +0 -39
- package/src/server/connect/bufferToArrayBuffer.ts +0 -8
- package/src/server/connect/connectMiddleware.ts +0 -81
- package/src/server/connect/flattenHeaders.ts +0 -44
- package/src/server/connect/nodeMessageToNodeResponse.ts +0 -89
- package/src/server/connect/readableToBuffer.ts +0 -16
- package/src/server/connect/requestToNodeMessage.ts +0 -26
- package/src/server/contentType.ts +0 -85
- package/src/server/types/HttpMethod.ts +0 -12
- package/src/server/types/MiddlewareFunction.ts +0 -8
- package/src/server/types/ServerFunction.ts +0 -7
- package/src/server.ts +0 -7
- package/src/site/Router.ts +0 -164
- package/src/site/Site.ts +0 -214
- package/src/site/clientEntry.ts +0 -108
- package/src/site/clientEntryDev.ts +0 -3
- package/src/site/defaultAdapter.ts +0 -11
- package/src/site/manifest.ts +0 -54
- package/src/site/serverEntry.ts +0 -439
- package/src/state/$page.ts +0 -24
- package/src/state/client.ts +0 -15
- package/src/state.ts +0 -3
- package/src/test/runTest.ts +0 -350
- package/src/test.ts +0 -3
- package/src/types/Adapter.ts +0 -8
- package/src/types/ClientState.ts +0 -8
- package/src/types/InternalState.ts +0 -7
- package/src/types/LayoutHandler.ts +0 -5
- package/src/types/LayoutPath.ts +0 -10
- package/src/types/ManifestRoute.ts +0 -6
- package/src/types/PageEndPoint.ts +0 -39
- package/src/types/PageLoadEvent.ts +0 -14
- package/src/types/PageServerAction.ts +0 -7
- package/src/types/PageServerEndPoint.ts +0 -16
- package/src/types/PageServerLoad.ts +0 -7
- package/src/types/PageState.ts +0 -8
- package/src/types/Route.ts +0 -11
- package/src/types/RouteHandler.ts +0 -16
- package/src/types/RouteLayoutHandler.ts +0 -5
- package/src/types/RouteMatchResult.ts +0 -7
- package/src/types/RouteType.ts +0 -19
- package/src/types/ServerEndPoint.ts +0 -37
- package/src/types/ServerHook.ts +0 -11
- package/src/types/ServerLoadEvent.ts +0 -37
- package/src/types/ServerRequest.ts +0 -7
- package/src/utils/pathToRegex.ts +0 -15
- package/src/vite-env.d.ts +0 -2
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { t as Router } from "./Router-C4ADUfhv.mjs";
|
|
2
|
+
import { i as notFound, n as seeOther, r as ok } from "./unprocessable-DAZbrDeR.mjs";
|
|
3
|
+
import { n as ValidationError, t as validate } from "./validate-Ok4krlkX.mjs";
|
|
4
|
+
import { a as searchParamsToRecord, i as validationErrorResponse, n as validateEndpointParams, o as $page, s as formDataToRecord, t as endpointSchema } from "./endpoint-EULRGCKA.mjs";
|
|
5
|
+
import manifest from "@torpor/build/manifest";
|
|
6
|
+
//#region src/site/layoutSlots.ts
|
|
7
|
+
/**
|
|
8
|
+
* Layouts are composed by the layout engine passing each layout (and finally
|
|
9
|
+
* the page) as the default slot of its parent — so every `_layout` component
|
|
10
|
+
* must render `<slot />`, or pass the default slot down to a child component
|
|
11
|
+
* it renders. A layout that doesn't drops its entire content: the server
|
|
12
|
+
* renders the layout's own markup with an empty content area (no error), and
|
|
13
|
+
* the first client-side navigation that reuses the layout crashes on a null
|
|
14
|
+
* slot region.
|
|
15
|
+
*
|
|
16
|
+
* The static `checkLayoutSlots` check catches this at build/dev time; these
|
|
17
|
+
* helpers report it at request time for the cases static analysis can't see
|
|
18
|
+
* (e.g. a `<slot />` rendered conditionally inside `@if`). They are
|
|
19
|
+
* server-side only — nothing here is imported into the client bundle.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Returns the path of the outermost layout that never rendered its
|
|
23
|
+
* `<slot />`, or undefined when every level rendered.
|
|
24
|
+
*
|
|
25
|
+
* Slot level j (1-based) is the slot render that layout j - 1 receives: the
|
|
26
|
+
* root layout (layouts[0]) renders level 1, layout i renders level i + 1,
|
|
27
|
+
* and level layouts.length renders the page. A broken level makes every
|
|
28
|
+
* deeper level unreachable, so the first level that never ran identifies
|
|
29
|
+
* the offending layout.
|
|
30
|
+
*/
|
|
31
|
+
function findMissingSlotLayout(layouts, invokedLevels) {
|
|
32
|
+
for (let level = 1; level <= layouts.length; level++) if (!invokedLevels.has(level)) return layouts[level - 1].path;
|
|
33
|
+
}
|
|
34
|
+
const warnedLayouts = /* @__PURE__ */ new Set();
|
|
35
|
+
/**
|
|
36
|
+
* Reports a layout that dropped its slot content. The condition is a genuine
|
|
37
|
+
* rendering bug (the page content is missing from the output), so it is not
|
|
38
|
+
* dev-gated — but it warns only once per layout path to avoid per-request
|
|
39
|
+
* noise.
|
|
40
|
+
*/ function warnMissingSlotContent(layoutPath) {
|
|
41
|
+
if (warnedLayouts.has(layoutPath)) return;
|
|
42
|
+
warnedLayouts.add(layoutPath);
|
|
43
|
+
console.warn(`[torpor] The layout at "${layoutPath}" never rendered <slot />, so the page content was not included in the render. Every _layout component must render <slot /> (or pass the default slot down to a child component it renders).`);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/site/serverEntry.ts
|
|
47
|
+
const router = new Router();
|
|
48
|
+
router.addPages(manifest.routes);
|
|
49
|
+
async function load(ev, template) {
|
|
50
|
+
const url = ev.url;
|
|
51
|
+
const path = url.pathname;
|
|
52
|
+
const query = url.searchParams;
|
|
53
|
+
let route = router.match(path, query);
|
|
54
|
+
if (!route) {
|
|
55
|
+
if (ev.request.method === "POST" && !path.endsWith("/~server")) {
|
|
56
|
+
const serverPath = (path.endsWith("/") ? path.substring(0, path.length - 1) : path) + "/~server";
|
|
57
|
+
route = router.match(serverPath, query);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!route) return handleResponse(notFound());
|
|
61
|
+
const handler = route.handler;
|
|
62
|
+
const params = route.params || {};
|
|
63
|
+
$page.url = url;
|
|
64
|
+
if (path.endsWith("/_error")) {
|
|
65
|
+
$page.status = parseInt(query.get("status") ?? "404");
|
|
66
|
+
$page.error = { message: query.get("message") ?? "" };
|
|
67
|
+
} else $page.status = 200;
|
|
68
|
+
switch (handler.type) {
|
|
69
|
+
case 0:
|
|
70
|
+
case 4:
|
|
71
|
+
if (ev.request.method === "GET") return handleResponse(await loadView(ev, url, handler, params, template));
|
|
72
|
+
else if (ev.request.method === "POST") return handleResponse(await runAction(ev, url, handler, handler.serverEndPoint && (await handler.serverEndPoint()).default, params, query, template), true);
|
|
73
|
+
break;
|
|
74
|
+
case 1:
|
|
75
|
+
case 5:
|
|
76
|
+
if (ev.request.method === "GET") return await loadData(ev, url, handler, "load", params);
|
|
77
|
+
else if (ev.request.method === "POST") {
|
|
78
|
+
const serverEndPoint = (await resolveModule(handler)).default;
|
|
79
|
+
return handleResponse(await runAction(ev, url, handler, serverEndPoint, params, query, template), true);
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case 3: return await loadData(ev, url, handler, ev.request.method.toLowerCase().replace("delete", "del"), params);
|
|
83
|
+
case 6:
|
|
84
|
+
case 7: break;
|
|
85
|
+
case 8: return await loadView(ev, url, handler, params, template);
|
|
86
|
+
}
|
|
87
|
+
return notFound();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolves the route's endpoint module, caching it on the handler so warm
|
|
91
|
+
* requests don't pay for the loader promise.
|
|
92
|
+
*/
|
|
93
|
+
async function resolveModule(handler) {
|
|
94
|
+
return handler.resolvedModule ??= await (handler.modulePromise ??= handler.endPoint());
|
|
95
|
+
}
|
|
96
|
+
async function loadServerHooks(handler) {
|
|
97
|
+
if (!handler.serverHooks) return [];
|
|
98
|
+
return handler.resolvedHooks ??= Promise.all(handler.serverHooks.map(async (load) => (await load()).default));
|
|
99
|
+
}
|
|
100
|
+
async function handleResponse(response, fromForm = false) {
|
|
101
|
+
$page.status = response.status;
|
|
102
|
+
if (response.status >= 200 && response.status <= 399) return response;
|
|
103
|
+
if (fromForm && response.status >= 400 && response.status <= 499) return response;
|
|
104
|
+
let params = new URLSearchParams();
|
|
105
|
+
params.append("status", $page.status.toString());
|
|
106
|
+
let message = await response.text();
|
|
107
|
+
if (response.headers.get("Content-Type")?.includes("application/json")) message = JSON.parse(message).message ?? message;
|
|
108
|
+
if (message) {
|
|
109
|
+
if ($page.error) $page.error.message = message;
|
|
110
|
+
else $page.error = { message };
|
|
111
|
+
params.append("message", message);
|
|
112
|
+
}
|
|
113
|
+
return seeOther(`/_error?${params.toString()}`);
|
|
114
|
+
}
|
|
115
|
+
async function loadData(ev, url, handler, functionName, params) {
|
|
116
|
+
const serverEndPoint = (handler.resolvedModule ?? await resolveModule(handler))?.default;
|
|
117
|
+
const handlerFn = serverEndPoint?.[functionName];
|
|
118
|
+
if (!serverEndPoint || !handlerFn) return notFound();
|
|
119
|
+
const paramsSchema = endpointSchema(serverEndPoint, "params");
|
|
120
|
+
if (paramsSchema) try {
|
|
121
|
+
params = await validate(paramsSchema, params);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
if (error instanceof ValidationError) return notFound();
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const schema = endpointSchema(serverEndPoint, functionName);
|
|
128
|
+
const values = schema ? functionName === "get" || functionName === "head" || functionName === "load" ? { query: await validate(schema, searchParamsToRecord(url.searchParams)) } : { json: await validate(schema, await ev.json()) } : {};
|
|
129
|
+
const serverParams = buildServerParams(ev, url, params, values);
|
|
130
|
+
const hooks = handler.serverHooks ? await loadServerHooks(handler) : [];
|
|
131
|
+
let entered = 0;
|
|
132
|
+
let enterResponse = void 0;
|
|
133
|
+
try {
|
|
134
|
+
for (; entered < hooks.length && !enterResponse; entered++) {
|
|
135
|
+
const hookResult = await hooks[entered].enter?.(serverParams);
|
|
136
|
+
if (hookResult) enterResponse = hookResult;
|
|
137
|
+
}
|
|
138
|
+
return await handlerFn(serverParams) || ok();
|
|
139
|
+
} finally {
|
|
140
|
+
while (entered > 0) {
|
|
141
|
+
entered--;
|
|
142
|
+
await hooks[entered].exit?.(serverParams);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
const response = validationErrorResponse(error);
|
|
147
|
+
if (response) return response;
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function loadView(ev, url, handler, params, template, formStatus, form, skipHook) {
|
|
152
|
+
const clientEndPoint = (await resolveModule(handler)).default;
|
|
153
|
+
if (!clientEndPoint?.component) return notFound();
|
|
154
|
+
if (!template) throw new Error("Page routes require a src/site.html file, which was not found; add it, or remove page/layout routes to serve endpoints only");
|
|
155
|
+
const serverEndPoint = handler.serverEndPoint && (await handler.serverEndPoint())?.default;
|
|
156
|
+
let query;
|
|
157
|
+
if (serverEndPoint) {
|
|
158
|
+
try {
|
|
159
|
+
params = await validateEndpointParams(serverEndPoint, params);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (error instanceof ValidationError) return notFound();
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
const loadSchema = endpointSchema(serverEndPoint, "load");
|
|
165
|
+
if (loadSchema) try {
|
|
166
|
+
query = await validate(loadSchema, searchParamsToRecord(url.searchParams));
|
|
167
|
+
} catch (error) {
|
|
168
|
+
const response = validationErrorResponse(error);
|
|
169
|
+
if (response) return response;
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const serverParams = buildServerParams(ev, url, params, query ? { query } : {});
|
|
174
|
+
const serverHooks = skipHook ? [] : await loadServerHooks(handler);
|
|
175
|
+
let entered = 0;
|
|
176
|
+
let enterResponse = void 0;
|
|
177
|
+
try {
|
|
178
|
+
for (; entered < serverHooks.length && !enterResponse; entered++) {
|
|
179
|
+
const hookResult = await serverHooks[entered].enter?.(serverParams);
|
|
180
|
+
if (hookResult) enterResponse = hookResult;
|
|
181
|
+
}
|
|
182
|
+
if (enterResponse) return enterResponse;
|
|
183
|
+
let data = {};
|
|
184
|
+
if (handler.layouts) for (let layout of handler.layouts) {
|
|
185
|
+
const layoutEndPoint = (await layout.endPoint())?.default;
|
|
186
|
+
const layoutServerEndPoint = layout.serverEndPoint && (await layout.serverEndPoint())?.default;
|
|
187
|
+
const layoutResponse = await loadClientAndServerData(url, params, serverParams, data, layoutEndPoint, layoutServerEndPoint);
|
|
188
|
+
if (layoutResponse?.ok === false) return layoutResponse;
|
|
189
|
+
}
|
|
190
|
+
let endPointResponse = await loadClientAndServerData(url, params, serverParams, data, clientEndPoint, serverEndPoint);
|
|
191
|
+
if (endPointResponse?.ok === false) return endPointResponse;
|
|
192
|
+
let $props = {
|
|
193
|
+
data,
|
|
194
|
+
form
|
|
195
|
+
};
|
|
196
|
+
let styles = "";
|
|
197
|
+
let component = clientEndPoint.component;
|
|
198
|
+
let slots = void 0;
|
|
199
|
+
const invokedLevels = /* @__PURE__ */ new Set();
|
|
200
|
+
const trackSlot = (level, slot) => {
|
|
201
|
+
return ($slot, $context) => {
|
|
202
|
+
invokedLevels.add(level);
|
|
203
|
+
return slot($slot, $context);
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
if (handler.layouts) {
|
|
207
|
+
let slotFunctions = [];
|
|
208
|
+
slotFunctions[handler.layouts.length] = trackSlot(handler.layouts.length, (_, $context) => {
|
|
209
|
+
let { body, head } = clientEndPoint.component($props, $context);
|
|
210
|
+
styles += head;
|
|
211
|
+
return body;
|
|
212
|
+
});
|
|
213
|
+
for (let i = handler.layouts.length - 1; i >= 0; i--) {
|
|
214
|
+
const layoutEndPoint = (await handler.layouts[i].endPoint())?.default;
|
|
215
|
+
if (layoutEndPoint?.component) if (i === 0) {
|
|
216
|
+
component = layoutEndPoint.component;
|
|
217
|
+
slots = { _: slotFunctions[i + 1] };
|
|
218
|
+
} else slotFunctions[i] = trackSlot(i, (_, $context) => {
|
|
219
|
+
let { body, head } = layoutEndPoint.component($props, $context, { _: slotFunctions[i + 1] });
|
|
220
|
+
styles += head;
|
|
221
|
+
return body;
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
let html;
|
|
226
|
+
try {
|
|
227
|
+
let { body, head } = component($props, void 0, slots);
|
|
228
|
+
if (form) body += `\n<input type="hidden" id="t-form-data" value='${JSON.stringify(form).replaceAll("'", "\\'")}' />`;
|
|
229
|
+
styles += head;
|
|
230
|
+
html = template.replace("%COMPONENT_BODY%", body).replace("%COMPONENT_HEAD%", styles);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
html = "<span style=\"color: red\">Script syntax error</span><p>" + error + "</p>";
|
|
233
|
+
console.log(error);
|
|
234
|
+
}
|
|
235
|
+
if (handler.layouts) {
|
|
236
|
+
const missingLayout = findMissingSlotLayout(handler.layouts, invokedLevels);
|
|
237
|
+
if (missingLayout !== void 0) warnMissingSlotContent(missingLayout);
|
|
238
|
+
}
|
|
239
|
+
return new Response(html, {
|
|
240
|
+
status: formStatus ?? 200,
|
|
241
|
+
headers: { "Content-Type": "text/html" }
|
|
242
|
+
});
|
|
243
|
+
} finally {
|
|
244
|
+
while (entered > 0) {
|
|
245
|
+
entered--;
|
|
246
|
+
await serverHooks[entered].exit?.(serverParams);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async function runAction(ev, url, handler, serverEndPoint, params, query, template) {
|
|
251
|
+
const actionName = (Array.from(query.keys())[0] || "default").replace(/^\//, "");
|
|
252
|
+
if (serverEndPoint?.actions) {
|
|
253
|
+
const action = serverEndPoint.actions[actionName];
|
|
254
|
+
if (action) {
|
|
255
|
+
if (actionName === "load" || actionName === "params") throw new Error(`The action name "${actionName}" is reserved. Rename the action (and its schema key, if any), e.g. to "save".`);
|
|
256
|
+
try {
|
|
257
|
+
params = await validateEndpointParams(serverEndPoint, params);
|
|
258
|
+
} catch (error) {
|
|
259
|
+
if (error instanceof ValidationError) return notFound();
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
let result;
|
|
263
|
+
try {
|
|
264
|
+
const schema = endpointSchema(serverEndPoint, actionName);
|
|
265
|
+
const form = schema ? await validate(schema, await formDataToRecord(ev.request)) : void 0;
|
|
266
|
+
const serverParams = buildServerParams(ev, url, params, form ? { form } : {});
|
|
267
|
+
const serverHooks = await loadServerHooks(handler);
|
|
268
|
+
let entered = 0;
|
|
269
|
+
let enterResponse = void 0;
|
|
270
|
+
try {
|
|
271
|
+
for (; entered < serverHooks.length && !enterResponse; entered++) {
|
|
272
|
+
const hookResult = await serverHooks[entered].enter?.(serverParams);
|
|
273
|
+
if (hookResult) enterResponse = hookResult;
|
|
274
|
+
}
|
|
275
|
+
result = enterResponse || await action(serverParams);
|
|
276
|
+
} finally {
|
|
277
|
+
while (entered > 0) {
|
|
278
|
+
entered--;
|
|
279
|
+
await serverHooks[entered].exit?.(serverParams);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
const response = validationErrorResponse(error);
|
|
284
|
+
if (response) return response;
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
if (ev.request.headers.has("X-Torpor-Form-Submit")) {
|
|
288
|
+
result ??= ok();
|
|
289
|
+
if (result.status >= 300 && result.status <= 399) {
|
|
290
|
+
const location = result.headers.get("Location") ?? "";
|
|
291
|
+
result = ok();
|
|
292
|
+
result.headers.set("X-Torpor-Form-Redirect", "");
|
|
293
|
+
result.headers.set("Location", location);
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
} else if (!result || result.status >= 200 && result.status <= 299 || result.status >= 400 && result.status <= 499) {
|
|
297
|
+
const newUrl = new URL(url.pathname + url.search, url);
|
|
298
|
+
const formStatus = result?.status;
|
|
299
|
+
let formMessage = await result?.text();
|
|
300
|
+
if (formMessage && result?.headers.get("Content-Type")?.includes("application/json")) {
|
|
301
|
+
$page.form = JSON.parse(formMessage);
|
|
302
|
+
formMessage = void 0;
|
|
303
|
+
} else $page.form = {};
|
|
304
|
+
$page.form.status ??= formStatus ?? 0;
|
|
305
|
+
$page.form.message ??= formMessage ?? "";
|
|
306
|
+
return await loadView(ev, newUrl, handler, params, template, formStatus, $page.form, true);
|
|
307
|
+
} else return result;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return notFound();
|
|
311
|
+
}
|
|
312
|
+
async function loadClientAndServerData(url, params, serverParams, data, clientEndPoint, serverEndPoint) {
|
|
313
|
+
if (clientEndPoint?.load) {
|
|
314
|
+
const clientParams = buildClientParams(url, params, data);
|
|
315
|
+
const clientResponse = await clientEndPoint.load(clientParams);
|
|
316
|
+
if (clientResponse) if (clientResponse.ok) {
|
|
317
|
+
if (clientResponse.headers.get("Content-Type")?.includes("application/json")) Object.assign(data, await clientResponse.json());
|
|
318
|
+
} else return clientResponse;
|
|
319
|
+
}
|
|
320
|
+
if (serverEndPoint?.load) {
|
|
321
|
+
const serverResponse = await serverEndPoint.load(serverParams);
|
|
322
|
+
if (serverResponse) if (serverResponse.ok) {
|
|
323
|
+
if (serverResponse.headers.get("Content-Type")?.includes("application/json")) Object.assign(data, await serverResponse.json());
|
|
324
|
+
} else return serverResponse;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function buildClientParams(url, params, data) {
|
|
328
|
+
return {
|
|
329
|
+
url,
|
|
330
|
+
params,
|
|
331
|
+
data
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function buildServerParams(ev, url, params, values = {}) {
|
|
335
|
+
return {
|
|
336
|
+
url,
|
|
337
|
+
params,
|
|
338
|
+
appData: {},
|
|
339
|
+
request: ev.request,
|
|
340
|
+
json: () => values.json !== void 0 ? Promise.resolve(values.json) : ev.json(),
|
|
341
|
+
form: () => values.form !== void 0 ? Promise.resolve(values.form) : formDataToRecord(ev.request),
|
|
342
|
+
query: () => values.query !== void 0 ? Promise.resolve(values.query) : Promise.resolve(searchParamsToRecord(url.searchParams)),
|
|
343
|
+
cookies: ev.cookies,
|
|
344
|
+
headers: ev.headers,
|
|
345
|
+
adapter: ev.adapter
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
//#endregion
|
|
349
|
+
export { load as t };
|
|
350
|
+
|
|
351
|
+
//# sourceMappingURL=serverEntry-1qY3wZig.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverEntry-1qY3wZig.mjs","names":[],"sources":["../src/site/layoutSlots.ts","../src/site/serverEntry.ts"],"sourcesContent":["/**\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","import manifest from \"@torpor/build/manifest\";\nimport { 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 Router from \"./Router.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 async function load(ev: ServerEvent, template?: string): Promise<Response> {\n\tconst url = ev.url;\n\tconst path = url.pathname;\n\tconst query = url.searchParams;\n\n\t//console.log(`handling ${ev.request.method} for '${path}'${query.size ? ` with ${query}` : \"\"}`);\n\n\tlet route = router.match(path, query);\n\tif (!route) {\n\t\t// If the route wasn't found, the user may be posting a form to a\n\t\t// +page.server.ts route that doesn't have a corresponding +page.ts\n\t\t// route, which is allowed, so check for that as well\n\t\tif (ev.request.method === \"POST\" && !path.endsWith(\"/~server\")) {\n\t\t\tconst serverPath =\n\t\t\t\t(path.endsWith(\"/\") ? path.substring(0, path.length - 1) : path) + \"/~server\";\n\t\t\troute = router.match(serverPath, query);\n\t\t}\n\t}\n\tif (!route) {\n\t\treturn handleResponse(notFound());\n\t}\n\tconst handler = route.handler;\n\tconst params = route.params || {};\n\n\t// Update $page before building the components\n\t$page.url = url;\n\tif (path.endsWith(\"/_error\")) {\n\t\t$page.status = parseInt(query.get(\"status\") ?? \"404\");\n\t\t$page.error = { message: query.get(\"message\") ?? \"\" };\n\t} else {\n\t\t$page.status = 200;\n\t}\n\n\t// TODO: Hit the server hook out here\n\t// We could maybe set data loading up as middleware on a route??????\n\n\tswitch (handler.type) {\n\t\tcase PAGE_ROUTE:\n\t\tcase LAYOUT_ROUTE: {\n\t\t\t// It's a /+page.ts or /_layout.ts endpoint\n\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\treturn handleResponse(await loadView(ev, url, handler, params, template));\n\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\t// The server end point comes from the sibling /+page.server.ts, if applicable\n\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined =\n\t\t\t\t\thandler.serverEndPoint && (await handler.serverEndPoint()).default;\n\t\t\t\treturn handleResponse(\n\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase PAGE_SERVER_ROUTE:\n\t\tcase LAYOUT_SERVER_ROUTE: {\n\t\t\t// It's a /+page.server.ts or /_layout.server.ts endpoint\n\t\t\tif (ev.request.method === \"GET\") {\n\t\t\t\treturn await loadData(ev, url, handler, \"load\", params);\n\t\t\t} else if (ev.request.method === \"POST\") {\n\t\t\t\tconst serverEndPoint: PageServerEndPoint | undefined = (await resolveModule(handler))\n\t\t\t\t\t.default;\n\t\t\t\treturn handleResponse(\n\t\t\t\t\tawait runAction(ev, url, handler, serverEndPoint, params, query, template),\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase SERVER_ROUTE: {\n\t\t\t// It's a /+server.ts endpoint\n\t\t\tconst functionName = ev.request.method.toLowerCase().replace(\"delete\", \"del\");\n\t\t\treturn await loadData(ev, url, handler, functionName, params);\n\t\t}\n\t\tcase HOOK_ROUTE:\n\t\tcase HOOK_SERVER_ROUTE: {\n\t\t\tbreak;\n\t\t}\n\t\tcase ERROR_ROUTE: {\n\t\t\treturn await loadView(ev, url, handler, params, template);\n\t\t}\n\t}\n\n\treturn notFound();\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// If 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 (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\tskipHook?: 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\ttry {\n\t\t\t\tquery = await validate(loadSchema, searchParamsToRecord(url.searchParams));\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\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 = skipHook ? [] : 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 = template.replace(\"%COMPONENT_BODY%\", body).replace(\"%COMPONENT_HEAD%\", styles);\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\tconst actionName = (Array.from(query.keys())[0] || \"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\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,sBACf,SACA,eACqB;CACrB,KAAK,IAAI,QAAQ,GAAG,SAAS,QAAQ,QAAQ,SAC5C,IAAI,CAAC,cAAc,IAAI,KAAK,GAC3B,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAI7B;AAEA,MAAM,gCAAgB,IAAI,IAAY;;;;;;GAOlC,SAAgB,uBAAuB,YAA0B;CACpE,IAAI,cAAc,IAAI,UAAU,GAAG;CACnC,cAAc,IAAI,UAAU;CAC5B,QAAQ,KACP,2BAA2B,WAAW,6LAGvC;AACD;;;ACfA,MAAM,SAAS,IAAI,OAAO;AAC1B,OAAO,SAAS,SAAS,MAAM;AAI/B,eAAsB,KAAK,IAAiB,UAAsC;CACjF,MAAM,MAAM,GAAG;CACf,MAAM,OAAO,IAAI;CACjB,MAAM,QAAQ,IAAI;CAIlB,IAAI,QAAQ,OAAO,MAAM,MAAM,KAAK;CACpC,IAAI,CAAC,OAIA;MAAA,GAAG,QAAQ,WAAW,UAAU,CAAC,KAAK,SAAS,UAAU,GAAG;GAC/D,MAAM,cACJ,KAAK,SAAS,GAAG,IAAI,KAAK,UAAU,GAAG,KAAK,SAAS,CAAC,IAAI,QAAQ;GACpE,QAAQ,OAAO,MAAM,YAAY,KAAK;EACvC;;CAED,IAAI,CAAC,OACJ,OAAO,eAAe,SAAS,CAAC;CAEjC,MAAM,UAAU,MAAM;CACtB,MAAM,SAAS,MAAM,UAAU,CAAC;CAGhC,MAAM,MAAM;CACZ,IAAI,KAAK,SAAS,SAAS,GAAG;EAC7B,MAAM,SAAS,SAAS,MAAM,IAAI,QAAQ,KAAK,KAAK;EACpD,MAAM,QAAQ,EAAE,SAAS,MAAM,IAAI,SAAS,KAAK,GAAG;CACrD,OACC,MAAM,SAAS;CAMhB,QAAQ,QAAQ,MAAhB;EACC,KAAA;EACA,KAAA;GAEC,IAAI,GAAG,QAAQ,WAAW,OACzB,OAAO,eAAe,MAAM,SAAS,IAAI,KAAK,SAAS,QAAQ,QAAQ,CAAC;QAClE,IAAI,GAAG,QAAQ,WAAW,QAIhC,OAAO,eACN,MAAM,UAAU,IAAI,KAAK,SAFzB,QAAQ,mBAAmB,MAAM,QAAQ,eAAe,EAAA,CAAG,SAET,QAAQ,OAAO,QAAQ,GACzE,IACD;GAED;EAED,KAAA;EACA,KAAA;GAEC,IAAI,GAAG,QAAQ,WAAW,OACzB,OAAO,MAAM,SAAS,IAAI,KAAK,SAAS,QAAQ,MAAM;QAChD,IAAI,GAAG,QAAQ,WAAW,QAAQ;IACxC,MAAM,kBAAkD,MAAM,cAAc,OAAO,EAAA,CACjF;IACF,OAAO,eACN,MAAM,UAAU,IAAI,KAAK,SAAS,gBAAgB,QAAQ,OAAO,QAAQ,GACzE,IACD;GACD;GACA;EAED,KAAA,GAGC,OAAO,MAAM,SAAS,IAAI,KAAK,SADV,GAAG,QAAQ,OAAO,YAAY,CAAC,CAAC,QAAQ,UAAU,KACpB,GAAG,MAAM;EAE7D,KAAA;EACA,KAAA,GACC;EAED,KAAA,GACC,OAAO,MAAM,SAAS,IAAI,KAAK,SAAS,QAAQ,QAAQ;CAE1D;CAEA,OAAO,SAAS;AACjB;;;;;AAMA,eAAe,cAAc,SAAqC;CACjE,OAAQ,QAAQ,mBAAmB,OAAO,QAAQ,kBAAkB,QAAQ,SAAS;AACtF;AAEA,eAAe,gBAAgB,SAA8C;CAC5E,IAAI,CAAC,QAAQ,aAAa,OAAO,CAAC;CAElC,OAAQ,QAAQ,kBAAkB,QAAQ,IACzC,QAAQ,YAAY,IAAI,OAAO,UAAU,MAAM,KAAK,EAAA,CAAG,OAAO,CAC/D;AACD;AAEA,eAAe,eAAe,UAAoB,WAAW,OAA0B;CACtF,MAAM,SAAS,SAAS;CAGxB,IAAI,SAAS,UAAU,OAAO,SAAS,UAAU,KAChD,OAAO;CAIR,IAAI,YAAY,SAAS,UAAU,OAAO,SAAS,UAAU,KAC5D,OAAO;CAQR,IAAI,SAAS,IAAI,gBAAgB;CACjC,OAAO,OAAO,UAAU,MAAM,OAAO,SAAS,CAAC;CAC/C,IAAI,UAAU,MAAM,SAAS,KAAK;CAClC,IAAI,SAAS,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,kBAAkB,GAEpE,UADa,KAAK,MAAM,OACX,CAAC,CAAC,WAAW;CAE3B,IAAI,SAAS;EACZ,IAAI,MAAM,OACT,MAAM,MAAM,UAAU;OAEtB,MAAM,QAAQ,EAAE,QAAQ;EAEzB,OAAO,OAAO,WAAW,OAAO;CACjC;CACA,OAAO,SAAS,WAAW,OAAO,SAAS,GAAG;AAC/C;AAEA,eAAe,SACd,IACA,KACA,SACA,cACA,QACC;CAID,MAAM,kBADM,QAAQ,kBAAmB,MAAM,cAAc,OAAO,EAAA,EACV;CAGxD,MAAM,YACL,iBACG;CACJ,IAAI,CAAC,kBAAkB,CAAC,WACvB,OAAO,SAAS;CAMjB,MAAM,eAAe,eAAe,gBAAgB,QAAQ;CAC5D,IAAI,cACH,IAAI;EACH,SAAU,MAAM,SAAS,cAAc,MAAM;CAC9C,SAAS,OAAO;EACf,IAAI,iBAAiB,iBAAiB,OAAO,SAAS;EACtD,MAAM;CACP;CAGD,IAAI;EAKH,MAAM,SAAS,eAAe,gBAAgB,YAAY;EAC1D,MAAM,SAAS,SACZ,iBAAiB,SAAS,iBAAiB,UAAU,iBAAiB,SACrE,EAAE,OAAO,MAAM,SAAS,QAAQ,qBAAqB,IAAI,YAAY,CAAC,EAAE,IACxE,EAAE,MAAM,MAAM,SAAS,QAAQ,MAAM,GAAG,KAAK,CAAC,EAAE,IACjD,CAAC;EAEJ,MAAM,eAAe,kBAAkB,IAAI,KAAK,QAAQ,MAAM;EAI9D,MAAM,QAAQ,QAAQ,cAAc,MAAM,gBAAgB,OAAO,IAAI,CAAC;EAEtE,IAAI,UAAU;EACd,IAAI,gBAAsC,KAAA;EAC1C,IAAI;GAGH,OAAO,UAAU,MAAM,UAAU,CAAC,eAAe,WAAW;IAC3D,MAAM,aAAa,MAAM,MAAM,QAAQ,CAAC,QAAQ,YAAY;IAC5D,IAAI,YACH,gBAAgB;GAElB;GAIA,OAAQ,MAAM,UAAU,YAAY,KAAM,GAAG;EAC9C,UAAU;GAET,OAAO,UAAU,GAAG;IACnB;IACA,MAAM,MAAM,QAAQ,CAAC,OAAO,YAAY;GACzC;EACD;CACD,SAAS,OAAO;EACf,MAAM,WAAW,wBAAwB,KAAK;EAC9C,IAAI,UAAU,OAAO;EACrB,MAAM;CACP;AACD;AAEA,eAAe,SACd,IACA,KACA,SACA,QACA,UACA,YACA,MACA,UACC;CAED,MAAM,kBAA4C,MAAM,cAAc,OAAO,EAAA,CAAG;CAChF,IAAI,CAAC,gBAAgB,WACpB,OAAO,SAAS;CAIjB,IAAI,CAAC,UACJ,MAAM,IAAI,MACT,6HACD;CAID,MAAM,iBACL,QAAQ,mBAAmB,MAAM,QAAQ,eAAe,EAAA,EAAI;CAM7D,IAAI;CACJ,IAAI,gBAAgB;EACnB,IAAI;GACH,SAAS,MAAM,uBAAuB,gBAAgB,MAAM;EAC7D,SAAS,OAAO;GACf,IAAI,iBAAiB,iBAAiB,OAAO,SAAS;GACtD,MAAM;EACP;EACA,MAAM,aAAa,eAAe,gBAAgB,MAAM;EACxD,IAAI,YACH,IAAI;GACH,QAAQ,MAAM,SAAS,YAAY,qBAAqB,IAAI,YAAY,CAAC;EAC1E,SAAS,OAAO;GACf,MAAM,WAAW,wBAAwB,KAAK;GAC9C,IAAI,UAAU,OAAO;GACrB,MAAM;EACP;CAEF;CAIA,MAAM,eAAe,kBAAkB,IAAI,KAAK,QAAQ,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;CAC9E,MAAM,cAAc,WAAW,CAAC,IAAI,MAAM,gBAAgB,OAAO;CACjE,IAAI,UAAU;CACd,IAAI,gBAAsC,KAAA;CAC1C,IAAI;EAGH,OAAO,UAAU,YAAY,UAAU,CAAC,eAAe,WAAW;GACjE,MAAM,aAAa,MAAM,YAAY,QAAQ,CAAC,QAAQ,YAAY;GAClE,IAAI,YACH,gBAAgB;EAElB;EACA,IAAI,eACH,OAAO;EAOR,IAAI,OAAO,CAAC;EACZ,IAAI,QAAQ,SACX,KAAK,IAAI,UAAU,QAAQ,SAAS;GACnC,MAAM,kBAA4C,MAAM,OAAO,SAAS,EAAA,EAAI;GAC5E,MAAM,uBACL,OAAO,mBAAmB,MAAM,OAAO,eAAe,EAAA,EAAI;GAC3D,MAAM,iBAAiB,MAAM,wBAC5B,KACA,QACA,cACA,MACA,gBACA,oBACD;GACA,IAAI,gBAAgB,OAAO,OAC1B,OAAO;EAET;EAED,IAAI,mBAAmB,MAAM,wBAC5B,KACA,QACA,cACA,MACA,gBACA,cACD;EACA,IAAI,kBAAkB,OAAO,OAC5B,OAAO;EAER,IAAI,SAA8B;GAAE;GAAM;EAAK;EAE/C,IAAI,SAAS;EAMb,IAAI,YAAY,eAAe;EAC/B,IAAI,QAAsD,KAAA;EAI1D,MAAM,gCAAgB,IAAI,IAAY;EACtC,MAAM,aAAa,OAAe,SAA6C;GAC9E,QAAQ,OAAO,aAAa;IAC3B,cAAc,IAAI,KAAK;IACvB,OAAO,KAAK,OAAO,QAAQ;GAC5B;EACD;EACA,IAAI,QAAQ,SAAS;GACpB,IAAI,gBAAoC,CAAC;GAEzC,cAAc,QAAQ,QAAQ,UAAU,UAAU,QAAQ,QAAQ,SAAS,GAAG,aAAa;IAC1F,IAAI,EAAE,MAAM,SAAU,eAAe,UAA8B,QAAQ,QAAQ;IACnF,UAAU;IACV,OAAO;GACR,CAAC;GACD,KAAK,IAAI,IAAI,QAAQ,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;IACrD,MAAM,kBAA4C,MAAM,QAAQ,QAAQ,EAAE,CAAC,SAAS,EAAA,EACjF;IACH,IAAI,gBAAgB,WACnB,IAAI,MAAM,GAAG;KACZ,YAAY,eAAe;KAC3B,QAAQ,EAAE,GAAG,cAAc,IAAI,GAAG;IACnC,OACC,cAAc,KAAK,UAAU,IAAI,GAAG,aAAa;KAChD,IAAI,EAAE,MAAM,SAAU,eAAe,UAA8B,QAAQ,UAAU,EACpF,GAAG,cAAc,IAAI,GACtB,CAAC;KACD,UAAU;KACV,OAAO;IACR,CAAC;GAGJ;EACD;EAEA,IAAI;EACJ,IAAI;GACH,IAAI,EAAE,MAAM,SAAS,UAAU,QAAQ,KAAA,GAAW,KAAK;GAGvD,IAAI,MACH,QAAQ,kDAAkD,KAAK,UAAU,IAAI,CAAC,CAAC,WAAW,KAAK,KAAK,EAAE;GAGvG,UAAU;GACV,OAAO,SAAS,QAAQ,oBAAoB,IAAI,CAAC,CAAC,QAAQ,oBAAoB,MAAM;EACrF,SAAS,OAAO;GAEf,OAAO,6DAA2D,QAAQ;GAC1E,QAAQ,IAAI,KAAK;EAClB;EAIA,IAAI,QAAQ,SAAS;GACpB,MAAM,gBAAgB,sBAAsB,QAAQ,SAAS,aAAa;GAC1E,IAAI,kBAAkB,KAAA,GACrB,uBAAuB,aAAa;EAEtC;EAEA,OAAO,IAAI,SAAS,MAAM;GACzB,QAAQ,cAAc;GACtB,SAAS,EACR,gBAAgB,YACjB;EACD,CAAC;CACF,UAAU;EAET,OAAO,UAAU,GAAG;GACnB;GACA,MAAM,YAAY,QAAQ,CAAC,OAAO,YAAY;EAC/C;CACD;AACD;AAEA,eAAe,UACd,IACA,KACA,SACA,gBACA,QACA,OACA,UACC;CACD,MAAM,cAAc,MAAM,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,UAAA,CAAW,QAAQ,OAAO,EAAE;CAC/E,IAAI,gBAAgB,SAAS;EAC5B,MAAM,SAAS,eAAe,QAAQ;EACtC,IAAI,QAAQ;GACX,IAAI,eAAe,UAAU,eAAe,UAK3C,MAAM,IAAI,MACT,oBAAoB,WAAW,+EAEhC;GAID,IAAI;IACH,SAAS,MAAM,uBAAuB,gBAAgB,MAAM;GAC7D,SAAS,OAAO;IACf,IAAI,iBAAiB,iBAAiB,OAAO,SAAS;IACtD,MAAM;GACP;GAEA,IAAI;GACJ,IAAI;IAGH,MAAM,SAAS,eAAe,gBAAgB,UAAU;IACxD,MAAM,OAAO,SACV,MAAM,SAAS,QAAQ,MAAM,iBAAiB,GAAG,OAAO,CAAC,IACzD,KAAA;IAEH,MAAM,eAAe,kBAAkB,IAAI,KAAK,QAAQ,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;IAE5E,MAAM,cAAc,MAAM,gBAAgB,OAAO;IACjD,IAAI,UAAU;IACd,IAAI,gBAAsC,KAAA;IAC1C,IAAI;KAGH,OAAO,UAAU,YAAY,UAAU,CAAC,eAAe,WAAW;MACjE,MAAM,aAAa,MAAM,YAAY,QAAQ,CAAC,QAAQ,YAAY;MAClE,IAAI,YACH,gBAAgB;KAElB;KAEA,SAAS,iBAAkB,MAAM,OAAO,YAAY;IACrD,UAAU;KAET,OAAO,UAAU,GAAG;MACnB;MACA,MAAM,YAAY,QAAQ,CAAC,OAAO,YAAY;KAC/C;IACD;GACD,SAAS,OAAO;IACf,MAAM,WAAW,wBAAwB,KAAK;IAC9C,IAAI,UAAU,OAAO;IACrB,MAAM;GACP;GAEA,IAAI,GAAG,QAAQ,QAAQ,IAAI,sBAAsB,GAAG;IAInD,WAAW,GAAG;IAGd,IAAI,OAAO,UAAU,OAAO,OAAO,UAAU,KAAK;KACjD,MAAM,WAAW,OAAO,QAAQ,IAAI,UAAU,KAAK;KACnD,SAAS,GAAG;KACZ,OAAO,QAAQ,IAAI,0BAA0B,EAAE;KAC/C,OAAO,QAAQ,IAAI,YAAY,QAAQ;IACxC;IAEA,OAAO;GACR,OAAO,IACN,CAAC,UACA,OAAO,UAAU,OAAO,OAAO,UAAU,OACzC,OAAO,UAAU,OAAO,OAAO,UAAU,KACzC;IAOD,MAAM,SAAS,IAAI,IAAI,IAAI,WAAW,IAAI,QAAQ,GAAG;IACrD,MAAM,aAAa,QAAQ;IAC3B,IAAI,cAAc,MAAM,QAAQ,KAAK;IACrC,IAAI,eAAe,QAAQ,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,kBAAkB,GAAG;KACrF,MAAM,OAAO,KAAK,MAAM,WAAW;KACnC,cAAc,KAAA;IACf,OACC,MAAM,OAAO,CAAC;IAOf,MAAM,KAAM,WAAW,cAAc;IACrC,MAAM,KAAM,YAAY,eAAe;IACvC,OAAO,MAAM,SAAS,IAAI,QAAQ,SAAS,QAAQ,UAAU,YAAY,MAAM,MAAM,IAAI;GAC1F,OAIC,OAAO;EAET;CACD;CAEA,OAAO,SAAS;AACjB;AAEA,eAAe,wBACd,KACA,QACA,cACA,MACA,gBACA,gBACC;CACD,IAAI,gBAAgB,MAAM;EACzB,MAAM,eAAe,kBAAkB,KAAK,QAAQ,IAAI;EACxD,MAAM,iBAAiB,MAAM,eAAe,KAAK,YAAY;EAC7D,IAAI,gBACH,IAAI,eAAe,IACd;OAAA,eAAe,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,kBAAkB,GAC1E,OAAO,OAAO,MAAM,MAAM,eAAe,KAAK,CAAC;EAAA,OAGhD,OAAO;CAGV;CACA,IAAI,gBAAgB,MAAM;EACzB,MAAM,iBAAiB,MAAM,eAAe,KAAK,YAAY;EAC7D,IAAI,gBACH,IAAI,eAAe,IACd;OAAA,eAAe,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,kBAAkB,GAC1E,OAAO,OAAO,MAAM,MAAM,eAAe,KAAK,CAAC;EAAA,OAGhD,OAAO;CAGV;AACD;AAEA,SAAS,kBAAkB,KAAU,QAA6B,MAA2B;CAC5F,OAAO;EACN;EACA;EACA;CACD;AACD;AAEA,SAAS,kBACR,IACA,KACA,QACA,SAA8D,CAAC,GAC7C;CAClB,OAAO;EACN;EACA;EACA,SAAS,CAAC;EACV,SAAS,GAAG;EAKZ,YACC,OAAO,SAAS,KAAA,IAAY,QAAQ,QAAQ,OAAO,IAAI,IAAI,GAAG,KAAK;EACpE,YACC,OAAO,SAAS,KAAA,IAAY,QAAQ,QAAQ,OAAO,IAAI,IAAI,iBAAiB,GAAG,OAAO;EACvF,aACC,OAAO,UAAU,KAAA,IACd,QAAQ,QAAQ,OAAO,KAAK,IAC5B,QAAQ,QAAQ,qBAAqB,IAAI,YAAY,CAAC;EAC1D,SAAS,GAAG;EACZ,SAAS,GAAG;EACZ,SAAS,GAAG;CACb;AACD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { t as ServerEvent } from "./ServerEvent-CTx3Q-hk.mjs";
|
|
2
|
+
//#region src/site/serverEntry.d.ts
|
|
3
|
+
declare function load(ev: ServerEvent, template?: string): Promise<Response>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { load as t };
|
|
6
|
+
//# sourceMappingURL=serverEntry-BAO8m03V.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverEntry-BAO8m03V.d.mts","names":[],"sources":["../src/site/serverEntry.ts"],"mappings":";;iBA0CsB,KAAK,IAAI,aAAa,oBAAoB,QAAQ"}
|
package/dist/state.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.mts","names":[
|
|
1
|
+
{"version":3,"file":"state.d.mts","names":[],"sources":["../src/types/PageState.ts","../src/state/$page.ts"],"mappings":";UAAyB;EACxB;EACA,KAAK;EACL,OAAO;EACP;IACC;;;;;cCAI,OAAO"}
|
package/dist/state.mjs
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { t as $
|
|
2
|
-
|
|
3
|
-
export { $page_default as $page };
|
|
1
|
+
import { t as $page } from "./_page-4cQKs_Dn.mjs";
|
|
2
|
+
export { $page };
|
package/dist/test.d.mts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as Site } from "./Site-
|
|
3
|
-
|
|
1
|
+
import { t as ServerEvent } from "./ServerEvent-CTx3Q-hk.mjs";
|
|
2
|
+
import { t as Site } from "./Site-CE0_o5Ci.mjs";
|
|
4
3
|
//#region src/test/runTest.d.ts
|
|
5
|
-
|
|
6
4
|
/**
|
|
7
|
-
* Runs a site route in test mode
|
|
8
|
-
* @param site The site configuration, with routing configured
|
|
9
|
-
* @param route The route path e.g. `/home`
|
|
10
|
-
* @param ev An optional ServerEvent, which you can use to set test cookies and headers
|
|
11
|
-
* @returns An HTTP response containing the requested data, HTML, or error status
|
|
12
|
-
*/
|
|
5
|
+
* Runs a site route in test mode
|
|
6
|
+
* @param site The site configuration, with routing configured
|
|
7
|
+
* @param route The route path e.g. `/home`
|
|
8
|
+
* @param ev An optional ServerEvent, which you can use to set test cookies and headers
|
|
9
|
+
* @returns An HTTP response containing the requested data, HTML, or error status
|
|
10
|
+
*/
|
|
13
11
|
declare function runTest(site: Site, route: string, ev?: ServerEvent): Promise<Response>;
|
|
14
12
|
//#endregion
|
|
15
13
|
export { runTest };
|
package/dist/test.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.mts","names":[],"sources":["../src/test/runTest.ts"],"
|
|
1
|
+
{"version":3,"file":"test.d.mts","names":[],"sources":["../src/test/runTest.ts"],"mappings":";;;;;;;;;;iBA4C8B,QAC7B,MAAM,MACN,eACA,KAAK,cACH,QAAQ"}
|