@torpor/build 1.2.0 → 1.3.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/MiddlewareFunction-BZilnEei.d.mts +50 -0
- package/dist/MiddlewareFunction-BZilnEei.d.mts.map +1 -0
- package/dist/{Router-COdQuVUi.d.mts → Router-dAu_5PlG.d.mts} +2 -2
- package/dist/{Router-COdQuVUi.d.mts.map → Router-dAu_5PlG.d.mts.map} +1 -1
- package/dist/{Server-Dr6yqVa5.mjs → Server-CSti9cvM.mjs} +2 -2
- package/dist/Server-CSti9cvM.mjs.map +1 -0
- package/dist/{Server-Cler2w5O.d.mts → Server-qn5Ws_d0.d.mts} +3 -23
- package/dist/Server-qn5Ws_d0.d.mts.map +1 -0
- package/dist/ServerEvent-Bh9cEpro.mjs +335 -0
- package/dist/ServerEvent-Bh9cEpro.mjs.map +1 -0
- package/dist/ServerHook-BTSGfLiJ.d.mts +21 -0
- package/dist/ServerHook-BTSGfLiJ.d.mts.map +1 -0
- package/dist/{ServerHook-BlLArueW.d.mts → ServerLoadEvent-DzbxxkF8.d.mts} +13 -21
- package/dist/ServerLoadEvent-DzbxxkF8.d.mts.map +1 -0
- package/dist/SessionHelper-MaodMaLU.d.mts +148 -0
- package/dist/SessionHelper-MaodMaLU.d.mts.map +1 -0
- package/dist/{Site-CTADVh7d.d.mts → Site-CWyj0R-l.d.mts} +89 -75
- package/dist/Site-CWyj0R-l.d.mts.map +1 -0
- package/dist/{_page-4cQKs_Dn.mjs → _page-CW6SLuT4.mjs} +2 -1
- package/dist/{_page-4cQKs_Dn.mjs.map → _page-CW6SLuT4.mjs.map} +1 -1
- package/dist/basePath-DQnbHc7o.mjs +99 -0
- package/dist/basePath-DQnbHc7o.mjs.map +1 -0
- package/dist/bin/index.js +1 -1
- package/dist/clientEntry.mjs +16 -5
- package/dist/clientEntry.mjs.map +1 -1
- package/dist/dev.d.mts +2 -2
- package/dist/dev.mjs +2 -2
- package/dist/discovery.d.mts +43 -0
- package/dist/discovery.d.mts.map +1 -0
- package/dist/discovery.mjs +72 -0
- package/dist/discovery.mjs.map +1 -0
- package/dist/env-C2SUAwAq.mjs +49 -0
- package/dist/env-C2SUAwAq.mjs.map +1 -0
- package/dist/env.d.mts +84 -0
- package/dist/env.d.mts.map +1 -0
- package/dist/env.mjs +2 -0
- package/dist/form.d.mts +14 -5
- package/dist/form.d.mts.map +1 -1
- package/dist/form.mjs +14 -4
- package/dist/form.mjs.map +1 -1
- package/dist/index.d.mts +5 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +54 -0
- package/dist/index.mjs.map +1 -1
- package/dist/{load-C9RpS_4j.mjs → load-CydkUApM.mjs} +31 -20
- package/dist/load-CydkUApM.mjs.map +1 -0
- package/dist/nav.d.mts.map +1 -1
- package/dist/nav.mjs +4 -2
- package/dist/nav.mjs.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/run.d.mts +1 -1
- package/dist/run.d.mts.map +1 -1
- package/dist/run.mjs +1 -1
- package/dist/{runOpenApi-yIzYasNN.mjs → runOpenApi-6iKszj_5.mjs} +230 -24
- package/dist/runOpenApi-6iKszj_5.mjs.map +1 -0
- package/dist/server/Server.d.mts +1 -1
- package/dist/server/Server.mjs +1 -1
- package/dist/server.d.mts +3 -2
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +2 -2
- package/dist/serverEntry-CnCVNNjp.mjs +13 -0
- package/dist/serverEntry-CnCVNNjp.mjs.map +1 -0
- package/dist/{serverEntry-DVv9YI3I.d.mts → serverEntry-fj0XfTs4.d.mts} +5 -4
- package/dist/serverEntry-fj0XfTs4.d.mts.map +1 -0
- package/dist/serverEntry.d.mts +2 -2
- package/dist/serverEntry.mjs +2 -2
- package/dist/{serverHandlers-fzIlmvX-.mjs → serverHandlers-B6EcNfBP.mjs} +95 -23
- package/dist/serverHandlers-B6EcNfBP.mjs.map +1 -0
- package/dist/sitemap-4imxJVrG.mjs +30 -0
- package/dist/sitemap-4imxJVrG.mjs.map +1 -0
- package/dist/sitemap-BjqN4d4W.d.mts +112 -0
- package/dist/sitemap-BjqN4d4W.d.mts.map +1 -0
- package/dist/state.d.mts +6 -0
- package/dist/state.d.mts.map +1 -1
- package/dist/state.mjs +1 -1
- package/dist/test.d.mts +2 -2
- package/dist/test.mjs +2 -2
- package/package.json +11 -3
- package/src/types/manifest.d.ts +3 -0
- package/dist/Server-Cler2w5O.d.mts.map +0 -1
- package/dist/Server-Dr6yqVa5.mjs.map +0 -1
- package/dist/ServerEvent-CTx3Q-hk.d.mts +0 -48
- package/dist/ServerEvent-CTx3Q-hk.d.mts.map +0 -1
- package/dist/ServerEvent-gmOvC_Yf.mjs +0 -100
- package/dist/ServerEvent-gmOvC_Yf.mjs.map +0 -1
- package/dist/ServerHook-BlLArueW.d.mts.map +0 -1
- package/dist/Site-CTADVh7d.d.mts.map +0 -1
- package/dist/load-C9RpS_4j.mjs.map +0 -1
- package/dist/runOpenApi-yIzYasNN.mjs.map +0 -1
- package/dist/serverEntry-CUXFQ07g.mjs +0 -11
- package/dist/serverEntry-CUXFQ07g.mjs.map +0 -1
- package/dist/serverEntry-DVv9YI3I.d.mts.map +0 -1
- package/dist/serverHandlers-fzIlmvX-.mjs.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { i as CookieHelper, n as HeaderHelper, r as FlashHelper, t as SessionHelper } from "./SessionHelper-MaodMaLU.mjs";
|
|
2
|
+
//#region src/server/ServerEvent.d.ts
|
|
3
|
+
declare class ServerEvent {
|
|
4
|
+
#private;
|
|
5
|
+
request: Request;
|
|
6
|
+
response: Response | undefined | void;
|
|
7
|
+
/**
|
|
8
|
+
* Set when the route handler (or a middleware enter hook) threw an
|
|
9
|
+
* error. Exit hooks can return a Response to handle it; if none does,
|
|
10
|
+
* the error is rethrown to the caller.
|
|
11
|
+
*/
|
|
12
|
+
error: unknown;
|
|
13
|
+
params?: Record<string, string>;
|
|
14
|
+
adapter: any;
|
|
15
|
+
cookies: CookieHelper;
|
|
16
|
+
headers: HeaderHelper;
|
|
17
|
+
session: SessionHelper;
|
|
18
|
+
flash: FlashHelper;
|
|
19
|
+
/** The request URL, parsed lazily. */
|
|
20
|
+
get url(): URL;
|
|
21
|
+
constructor(request: Request, params?: Record<string, string>, url?: URL);
|
|
22
|
+
addHeaders(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Reads the request body as JSON.
|
|
25
|
+
*/
|
|
26
|
+
json(): Promise<unknown>;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/server/types/MiddlewareFunction.d.ts
|
|
30
|
+
type MiddlewareFunction = {
|
|
31
|
+
/**
|
|
32
|
+
* Called before the route handler. Middleware are run in the order they
|
|
33
|
+
* were added. Return a Response to short-circuit the request; the
|
|
34
|
+
* remaining middleware and the route handler are then skipped.
|
|
35
|
+
*/
|
|
36
|
+
enter?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
37
|
+
/**
|
|
38
|
+
* Called after the route handler (even if it threw), in reverse order.
|
|
39
|
+
* Return a Response to replace the response. Middleware that were skipped
|
|
40
|
+
* by a short-circuit don't get their exit hook run.
|
|
41
|
+
*
|
|
42
|
+
* If the route handler (or a later enter hook) threw, the error is
|
|
43
|
+
* available as `ev.error`; returning a Response handles the error and
|
|
44
|
+
* stops it from propagating.
|
|
45
|
+
*/
|
|
46
|
+
exit?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { ServerEvent as n, MiddlewareFunction as t };
|
|
50
|
+
//# sourceMappingURL=MiddlewareFunction-BZilnEei.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiddlewareFunction-BZilnEei.d.mts","names":[],"sources":["../src/server/ServerEvent.ts","../src/server/types/MiddlewareFunction.ts"],"mappings":";;cAMqB;;EACpB,SAAS;EACT,UAAU;;;;;;EAMV;EAEA,SAAS;EAET;EAEA,SAAS;EACT,SAAS;EACT,SAAS;EACT,OAAO;;MAOH,OAAO;EAIX,YAAY,SAAS,SAAS,SAAS,wBAAwB,MAAM;EAcrE;;;;EA8BA,QAAQ;;;;KC5EJ;;;;;;EAMJ,SAAS,IAAI,gBAAgB,kBAAkB,QAAQ;;;;;;;;;;EAUvD,QAAQ,IAAI,gBAAgB,kBAAkB,QAAQ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ServerHook } from "./ServerHook-
|
|
1
|
+
import { t as ServerHook } from "./ServerHook-BTSGfLiJ.mjs";
|
|
2
2
|
//#region src/types/ManifestRoute.d.ts
|
|
3
3
|
interface ManifestRoute {
|
|
4
4
|
path: string;
|
|
@@ -56,4 +56,4 @@ interface RouteMatch {
|
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
58
|
export { Router as t };
|
|
59
|
-
//# sourceMappingURL=Router-
|
|
59
|
+
//# sourceMappingURL=Router-dAu_5PlG.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router-
|
|
1
|
+
{"version":3,"file":"Router-dAu_5PlG.d.mts","names":[],"sources":["../src/types/ManifestRoute.ts","../src/types/RouteLayoutHandler.ts","../src/types/RouteHandler.ts","../src/site/Router.ts"],"mappings":";;UAAyB;EACxB;EACA;EACA,gBAAgB;EAChB;;;;UCJwB;EACxB;EACA,gBAAgB;EAChB,uBAAuB;;;;;;;UCGC;EACxB;EACA;EACA,gBAAgB;EAChB;EAEA;EACA,UAAU;EACV,uBAAuB;EACvB,qBAAqB;EAIrB,gBAAgB;EAChB;EACA,gBAAgB,QAAQ;;;;;;;cCbJ;;EACpB,QAAQ;EAMR;EAOA,SAAS,QAAQ;EAQjB,QAAQ,cAAc,cAAc,gBAAgB,cAAc;EAuBlE,MAAM,cAAc,OAAO,kBAAkB;;cA2GxC;EACL;EACA,SAAS;EAET,YAAY,cAAc,SAAS;;UAM1B;EACT,SAAS;EACT,SAAS;EACT,OAAO"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as PathTrie } from "./pathTrie-D4Ax2Mu9.mjs";
|
|
2
|
-
import { t as ServerEvent } from "./ServerEvent-
|
|
2
|
+
import { t as ServerEvent } from "./ServerEvent-Bh9cEpro.mjs";
|
|
3
3
|
//#region src/server/Server.ts
|
|
4
4
|
/**
|
|
5
5
|
* A Fetch API Request/Response server.
|
|
@@ -101,4 +101,4 @@ var RouteHandler = class {
|
|
|
101
101
|
//#endregion
|
|
102
102
|
export { Server as t };
|
|
103
103
|
|
|
104
|
-
//# sourceMappingURL=Server-
|
|
104
|
+
//# sourceMappingURL=Server-CSti9cvM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Server-CSti9cvM.mjs","names":["#trie","#sortRoutes"],"sources":["../src/server/Server.ts"],"sourcesContent":["import PathTrie from \"../utils/pathTrie\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// Match index for the routes above\n\t#trie = new PathTrie<RouteHandler>();\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\t// Use the request as-is when we were given one, so that the adapter\n\t\t// doesn't pay for constructing it twice\n\t\tconst request = input instanceof Request && !init ? input : new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params, url);\n\n\t\tif (this.middleware.length) {\n\t\t\t// Route-scoped middleware is set on server endpoints (or globally on\n\t\t\t// `site.middleware`); this list is the low-level, per-Server primitive\n\t\t\tlet entered = 0;\n\t\t\tlet response: Response | undefined = undefined;\n\t\t\tlet error: unknown = undefined;\n\t\t\ttry {\n\t\t\t\tfor (; entered < this.middleware.length && !response; entered++) {\n\t\t\t\t\t// A middleware returns a Response to short-circuit the request\n\t\t\t\t\tconst result = await this.middleware[entered].enter?.(ev);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tresponse = result;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!response && match) {\n\t\t\t\t\tconst result = await match.fn(ev);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tresponse = result;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Exits can handle the error by returning a Response; if none\n\t\t\t\t// does, it is rethrown below\n\t\t\t\terror = e;\n\t\t\t\tev.error = e;\n\t\t\t} finally {\n\t\t\t\tif (response) {\n\t\t\t\t\tev.response = response;\n\t\t\t\t}\n\t\t\t\t// Run exit hooks in reverse order for the middleware that were\n\t\t\t\t// entered. An exit hook can return a Response to replace the\n\t\t\t\t// response, or to handle ev.error\n\t\t\t\twhile (entered > 0) {\n\t\t\t\t\tentered--;\n\t\t\t\t\tconst result = await this.middleware[entered].exit?.(ev);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tresponse = result;\n\t\t\t\t\t\tev.response = result;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (error && !response) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tlet handler = new RouteHandler(path, fn);\n\t\tthis.routes.push(handler);\n\t\tthis.#trie.insert(path, handler);\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string): Match | undefined {\n\t\tconst found = this.#trie.match(path);\n\t\tif (found) {\n\t\t\treturn {\n\t\t\t\tfn: found.value.fn,\n\t\t\t\tparams: found.params,\n\t\t\t};\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n\ninterface Match {\n\tfn: ServerFunction;\n\tparams?: Record<string, string>;\n}\n"],"mappings":";;;;;;AAQA,IAAqB,SAArB,MAA4B;CAE3B,SAAyB,CAAC;CAE1B,QAAQ,IAAI,SAAuB;CAEnC,aAAmC,CAAC;CAEpC,cAAc;EACb,KAAK,SAAS,CAAC;EACf,KAAK,aAAa,CAAC;CACpB;;;;;;CAOA,QAAQ,OAAO,OAA0B,SAA0C;EAGlF,MAAM,UAAU,iBAAiB,WAAW,CAAC,OAAO,QAAQ,IAAI,QAAQ,OAAO,IAAI;EACnF,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;EAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;EACrC,IAAI,KAAK,IAAI,YAAY,SAAS,OAAO,QAAQ,GAAG;EAEpD,IAAI,KAAK,WAAW,QAAQ;GAG3B,IAAI,UAAU;GACd,IAAI,WAAiC,KAAA;GACrC,IAAI,QAAiB,KAAA;GACrB,IAAI;IACH,OAAO,UAAU,KAAK,WAAW,UAAU,CAAC,UAAU,WAAW;KAEhE,MAAM,SAAS,MAAM,KAAK,WAAW,QAAQ,CAAC,QAAQ,EAAE;KACxD,IAAI,QACH,WAAW;IAEb;IACA,IAAI,CAAC,YAAY,OAAO;KACvB,MAAM,SAAS,MAAM,MAAM,GAAG,EAAE;KAChC,IAAI,QACH,WAAW;IAEb;GACD,SAAS,GAAG;IAGX,QAAQ;IACR,GAAG,QAAQ;GACZ,UAAU;IACT,IAAI,UACH,GAAG,WAAW;IAKf,OAAO,UAAU,GAAG;KACnB;KACA,MAAM,SAAS,MAAM,KAAK,WAAW,QAAQ,CAAC,OAAO,EAAE;KACvD,IAAI,QAAQ;MACX,WAAW;MACX,GAAG,WAAW;KACf;IACD;GACD;GACA,IAAI,SAAS,CAAC,UACb,MAAM;EAER,OAAO,IAAI,OACV,GAAG,WAAW,MAAM,MAAM,GAAG,EAAE;OAE/B,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;EAI1C,GAAG,aAAa,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;EAClD,GAAG,WAAW;EAEd,OAAO,GAAG;CACX;;;;;;;CAQA,IAAI,MAAc,IAA4B;EAC7C,IAAI,UAAU,IAAI,aAAa,MAAM,EAAE;EACvC,KAAK,OAAO,KAAK,OAAO;EACxB,KAAKA,MAAM,OAAO,MAAM,OAAO;EAC/B,KAAKC,YAAY;EACjB,OAAO;CACR;CAEA,MAAM,MAAiC;EACtC,MAAM,QAAQ,KAAKD,MAAM,MAAM,IAAI;EACnC,IAAI,OACH,OAAO;GACN,IAAI,MAAM,MAAM;GAChB,QAAQ,MAAM;EACf;EAED,QAAQ,IAAI,0BAA0B,MAAM;CAC7C;CAIA,IAAI,GAAG,IAAkC;EACxC,KAAK,aAAa,KAAK,WAAW,OAAO,EAAE;EAC3C,OAAO;CACR;CAEA,cAAc;EACb,KAAK,SAAS,KAAK,OAAO,MAAM,GAAG,MAAM;GAGxC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,GAAG,KAC3D,IAAI,EAAE,KAAK,OAAO,OAAO,EAAE,KAAK,OAAO,KACtC,OAAO;QACD,IAAI,EAAE,KAAK,OAAO,OAAO,EAAE,KAAK,OAAO,KAC7C,OAAO;QACD,IAAI,EAAE,KAAK,OAAO,EAAE,KAAK,IAAI,CAEpC,OACC,OAAO,EAAE,KAAK,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE;GAG1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK;EAC/B,CAAC;CACF;AACD;AAEA,IAAM,eAAN,MAAmB;CAClB;CACA;CAEA,YAAY,MAAc,IAAoB;EAC7C,KAAK,OAAO;EACZ,KAAK,KAAK;CACX;AACD"}
|
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/server/types/MiddlewareFunction.d.ts
|
|
3
|
-
type MiddlewareFunction = {
|
|
4
|
-
/**
|
|
5
|
-
* Called before the route handler. Middleware are run in the order they
|
|
6
|
-
* were added. Return a Response to short-circuit the request; the
|
|
7
|
-
* remaining middleware and the route handler are then skipped.
|
|
8
|
-
*/
|
|
9
|
-
enter?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
10
|
-
/**
|
|
11
|
-
* Called after the route handler (even if it threw), in reverse order.
|
|
12
|
-
* Return a Response to replace the response. Middleware that were skipped
|
|
13
|
-
* by a short-circuit don't get their exit hook run.
|
|
14
|
-
*
|
|
15
|
-
* If the route handler (or a later enter hook) threw, the error is
|
|
16
|
-
* available as `ev.error`; returning a Response handles the error and
|
|
17
|
-
* stops it from propagating.
|
|
18
|
-
*/
|
|
19
|
-
exit?: (ev: ServerEvent) => Response | void | Promise<Response | void>;
|
|
20
|
-
};
|
|
21
|
-
//#endregion
|
|
1
|
+
import { n as ServerEvent, t as MiddlewareFunction } from "./MiddlewareFunction-BZilnEei.mjs";
|
|
22
2
|
//#region src/server/types/ServerFunction.d.ts
|
|
23
3
|
type ServerFunction = (e: ServerEvent) => Response | undefined | void | Promise<Response | undefined | void>;
|
|
24
4
|
//#endregion
|
|
@@ -57,5 +37,5 @@ interface Match {
|
|
|
57
37
|
params?: Record<string, string>;
|
|
58
38
|
}
|
|
59
39
|
//#endregion
|
|
60
|
-
export {
|
|
61
|
-
//# sourceMappingURL=Server-
|
|
40
|
+
export { Server as t };
|
|
41
|
+
//# sourceMappingURL=Server-qn5Ws_d0.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Server-qn5Ws_d0.d.mts","names":[],"sources":["../src/server/types/ServerFunction.ts","../src/server/Server.ts"],"mappings":";;KAEK,kBACJ,GAAG,gBACC,8BAA8B,QAAQ;;;;;;cCItB;;EAEpB,QAAQ;EAIR,YAAY;EAEZ;;;;;;EAUA,QAAe,OAAO,cAAc,KAAK,OAAO,gBAAc,QAAQ;;;;;;;EAuEtE,IAAI,cAAc,IAAI,iBAAiB;EAQvC,MAAM,eAAe;EAarB,OAAO,IAAI,uBAAuB;;cAyB7B;EACL;EACA,IAAI;EAEJ,YAAY,cAAc,IAAI;;UAkBrB;EACT,IAAI;EACJ,SAAS"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { t as env } from "./env-C2SUAwAq.mjs";
|
|
2
|
+
import { n as getBasePath, t as addBaseToPath } from "./basePath-DQnbHc7o.mjs";
|
|
3
|
+
import { parseCookie, stringifySetCookie } from "cookie";
|
|
4
|
+
//#region src/server/CookieHelper.ts
|
|
5
|
+
var CookieHelper = class {
|
|
6
|
+
request;
|
|
7
|
+
cookies = /* @__PURE__ */ new Map();
|
|
8
|
+
constructor(request) {
|
|
9
|
+
this.request = request;
|
|
10
|
+
}
|
|
11
|
+
get(name) {
|
|
12
|
+
if (this.cookies.has(name)) return parseCookie(this.cookies.get(name))[name];
|
|
13
|
+
const header = this.request.headers.get("Cookie");
|
|
14
|
+
return parseCookie(header ?? "")[name];
|
|
15
|
+
}
|
|
16
|
+
set(name, value, options) {
|
|
17
|
+
options ??= {};
|
|
18
|
+
options.httpOnly ??= true;
|
|
19
|
+
options.secure ??= true;
|
|
20
|
+
options.sameSite ??= "lax";
|
|
21
|
+
this.cookies.set(name, stringifySetCookie({
|
|
22
|
+
name,
|
|
23
|
+
value,
|
|
24
|
+
...options
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
delete(name, options) {
|
|
28
|
+
options ??= {};
|
|
29
|
+
options.httpOnly ??= true;
|
|
30
|
+
options.secure ??= true;
|
|
31
|
+
options.sameSite ??= "lax";
|
|
32
|
+
options.expires = /* @__PURE__ */ new Date(0);
|
|
33
|
+
this.cookies.set(name, stringifySetCookie({
|
|
34
|
+
name,
|
|
35
|
+
value: "",
|
|
36
|
+
...options
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/server/FlashHelper.ts
|
|
42
|
+
const COOKIE_NAME$1 = "torpor-flash";
|
|
43
|
+
/**
|
|
44
|
+
* A one-time values store set in a form action and shown on the next page
|
|
45
|
+
* render, which survives the redirect. Available as `event.flash`; the
|
|
46
|
+
* framework reads it into `$page.flash` when a page is rendered, so
|
|
47
|
+
* components display it reactively:
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* actions: {
|
|
51
|
+
* save: async (event) => {
|
|
52
|
+
* // ...save...
|
|
53
|
+
* event.flash.set("Project saved"); // { message: "Project saved" }
|
|
54
|
+
* event.flash.set({ error: "Import failed", retryable: true });
|
|
55
|
+
* return seeOther(`/projects/${id}`);
|
|
56
|
+
* },
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* ```torp
|
|
61
|
+
* @if ($page.flash?.message) {
|
|
62
|
+
* <p class="flash">{$page.flash.message}</p>
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* The values ride in a (session-lifetime) cookie that is deleted when it is
|
|
67
|
+
* read, so a page refresh shows them once. No signing: the only person who
|
|
68
|
+
* can fake a flash is the one seeing it, and values are rendered as text.
|
|
69
|
+
* They must be JSON-safe and small enough to fit in the cookie (~4KB). A
|
|
70
|
+
* common shape for a styled banner is `{ type, message }`, for use e.g.
|
|
71
|
+
* with the Notification component -- but the framework only requires the
|
|
72
|
+
* values to be an object. Without cookies the message is simply lost --
|
|
73
|
+
* the action itself still completes.
|
|
74
|
+
*/
|
|
75
|
+
var FlashHelper = class {
|
|
76
|
+
#cookies;
|
|
77
|
+
constructor(cookies) {
|
|
78
|
+
this.#cookies = cookies;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Reads the flash values, if any, and clears them: the same response
|
|
82
|
+
* deletes the cookie, so the message shows exactly once. (When the
|
|
83
|
+
* message was set during this same request, e.g. a form action that
|
|
84
|
+
* re-renders instead of redirecting, the cookie is consumed without it
|
|
85
|
+
* ever reaching the browser.)
|
|
86
|
+
*/
|
|
87
|
+
get() {
|
|
88
|
+
const cookie = this.#cookies.get(COOKIE_NAME$1);
|
|
89
|
+
if (!cookie) return void 0;
|
|
90
|
+
this.#cookies.delete(COOKIE_NAME$1, { path: "/" });
|
|
91
|
+
try {
|
|
92
|
+
const decoded = JSON.parse(decodeURIComponent(cookie));
|
|
93
|
+
if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return;
|
|
94
|
+
return decoded;
|
|
95
|
+
} catch {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sets the flash values. A string is stored as `{ message: value }`, an
|
|
101
|
+
* object as-is, e.g. `flash.set({ error: "Import failed" })`.
|
|
102
|
+
*/
|
|
103
|
+
set(value) {
|
|
104
|
+
const data = typeof value === "string" ? { message: value } : value;
|
|
105
|
+
this.#cookies.set(COOKIE_NAME$1, encodeURIComponent(JSON.stringify(data)), { path: "/" });
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Clears an unread flash message, e.g. so it isn't shown on a later
|
|
109
|
+
* re-render of the same page.
|
|
110
|
+
*/
|
|
111
|
+
clear() {
|
|
112
|
+
this.#cookies.delete(COOKIE_NAME$1, { path: "/" });
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/server/HeaderHelper.ts
|
|
117
|
+
var HeaderHelper = class {
|
|
118
|
+
request;
|
|
119
|
+
headers = /* @__PURE__ */ new Map();
|
|
120
|
+
constructor(request) {
|
|
121
|
+
this.request = request;
|
|
122
|
+
}
|
|
123
|
+
get(name) {
|
|
124
|
+
if (this.headers.has(name)) return this.headers.get(name);
|
|
125
|
+
return this.request.headers.get(name) ?? void 0;
|
|
126
|
+
}
|
|
127
|
+
set(name, value) {
|
|
128
|
+
this.headers.set(name, value);
|
|
129
|
+
}
|
|
130
|
+
delete(name) {
|
|
131
|
+
this.headers.delete(name);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/server/SessionHelper.ts
|
|
136
|
+
const COOKIE_NAME = "torpor-session";
|
|
137
|
+
const DEFAULT_MAX_AGE = 2592e3;
|
|
138
|
+
const keys = /* @__PURE__ */ new Map();
|
|
139
|
+
/**
|
|
140
|
+
* A helper for reading and writing the signed session cookie, available as
|
|
141
|
+
* `event.session` in load functions, actions, +server endpoints and hooks.
|
|
142
|
+
*
|
|
143
|
+
* The value is signed with HMAC-SHA256 using `TORPOR_SESSION_SECRET` from
|
|
144
|
+
* the environment, so it can't be forged or tampered with -- but it is
|
|
145
|
+
* still client-side storage: everything rides in the cookie, it can't be
|
|
146
|
+
* revoked individually, and it is limited to ~4KB. When you need
|
|
147
|
+
* revocation, store `session.id` in your database, check it on each
|
|
148
|
+
* authed request (e.g. in a `_hook.server.ts`), and delete the row to
|
|
149
|
+
* revoke.
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
* // Login action
|
|
153
|
+
* const user = await checkPassword(event.form());
|
|
154
|
+
* await event.session.regenerate({ userId: user.id });
|
|
155
|
+
*
|
|
156
|
+
* // Root hook
|
|
157
|
+
* const session = await event.session.get();
|
|
158
|
+
* if (session) {
|
|
159
|
+
* event.appData.user = await getUser(session.userId);
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
var SessionHelper = class {
|
|
164
|
+
#cookies;
|
|
165
|
+
#id;
|
|
166
|
+
constructor(cookies) {
|
|
167
|
+
this.#cookies = cookies;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The id embedded in the current session cookie, or undefined when
|
|
171
|
+
* there is no valid session. Stable across `set` calls, so it can be
|
|
172
|
+
* used as a database key; `regenerate` mints a new one.
|
|
173
|
+
*/
|
|
174
|
+
get id() {
|
|
175
|
+
return this.#id;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Reads and verifies the session, returning its data, or undefined when
|
|
179
|
+
* there is no cookie, the signature doesn't match, or the session has
|
|
180
|
+
* expired.
|
|
181
|
+
*/
|
|
182
|
+
async get() {
|
|
183
|
+
const value = this.#cookies.get(COOKIE_NAME);
|
|
184
|
+
if (!value) return void 0;
|
|
185
|
+
const payload = await verifyValue(value);
|
|
186
|
+
if (!payload) return void 0;
|
|
187
|
+
this.#id = payload.id;
|
|
188
|
+
return payload.data;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Writes the session, signing the data and setting the cookie. Keeps
|
|
192
|
+
* the current session id, minting one when there isn't a valid session
|
|
193
|
+
* yet. Call `regenerate` instead when the session's identity should
|
|
194
|
+
* change (e.g. at login, to prevent session fixation).
|
|
195
|
+
*/
|
|
196
|
+
async set(data, options) {
|
|
197
|
+
const id = this.#id ?? crypto.randomUUID();
|
|
198
|
+
this.#id = id;
|
|
199
|
+
await this.#write(id, data, options);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Writes the session with a fresh id, replacing any existing one. Use
|
|
203
|
+
* it when a session's privilege level changes (login, permission
|
|
204
|
+
* upgrade), so a cookie that was set before the change can't be reused.
|
|
205
|
+
*/
|
|
206
|
+
async regenerate(data = {}, options) {
|
|
207
|
+
const id = crypto.randomUUID();
|
|
208
|
+
this.#id = id;
|
|
209
|
+
await this.#write(id, data, options);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Deletes the session cookie. Note that a server-side record (if you
|
|
213
|
+
* keep one) must be deleted or revoked separately.
|
|
214
|
+
*/
|
|
215
|
+
async destroy() {
|
|
216
|
+
this.#id = void 0;
|
|
217
|
+
this.#cookies.delete(COOKIE_NAME, { path: "/" });
|
|
218
|
+
}
|
|
219
|
+
async #write(id, data, options) {
|
|
220
|
+
const maxAge = options?.maxAge ?? DEFAULT_MAX_AGE;
|
|
221
|
+
const payload = {
|
|
222
|
+
id,
|
|
223
|
+
data,
|
|
224
|
+
exp: Date.now() + maxAge * 1e3
|
|
225
|
+
};
|
|
226
|
+
const encoded = encodeBase64Url(new TextEncoder().encode(JSON.stringify(payload)));
|
|
227
|
+
const signature = await sign(encoded);
|
|
228
|
+
this.#cookies.set(COOKIE_NAME, `${encoded}.${signature}`, {
|
|
229
|
+
path: "/",
|
|
230
|
+
maxAge
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
function secret() {
|
|
235
|
+
const value = env().TORPOR_SESSION_SECRET;
|
|
236
|
+
if (!value) throw new Error("TORPOR_SESSION_SECRET is not set. Add it to the environment (or to a .env file in dev and preview) to use sessions.");
|
|
237
|
+
return value;
|
|
238
|
+
}
|
|
239
|
+
function signingKey() {
|
|
240
|
+
const value = secret();
|
|
241
|
+
let key = keys.get(value);
|
|
242
|
+
if (!key) {
|
|
243
|
+
key = crypto.subtle.importKey("raw", new TextEncoder().encode(value), {
|
|
244
|
+
name: "HMAC",
|
|
245
|
+
hash: "SHA-256"
|
|
246
|
+
}, false, ["sign", "verify"]);
|
|
247
|
+
keys.set(value, key);
|
|
248
|
+
}
|
|
249
|
+
return key;
|
|
250
|
+
}
|
|
251
|
+
async function sign(payload) {
|
|
252
|
+
const signature = await crypto.subtle.sign("HMAC", await signingKey(), new TextEncoder().encode(payload));
|
|
253
|
+
return encodeBase64Url(new Uint8Array(signature));
|
|
254
|
+
}
|
|
255
|
+
async function verifyValue(value) {
|
|
256
|
+
const dot = value.lastIndexOf(".");
|
|
257
|
+
if (dot === -1) return void 0;
|
|
258
|
+
const encoded = value.slice(0, dot);
|
|
259
|
+
if (!await crypto.subtle.verify("HMAC", await signingKey(), decodeBase64Url(value.slice(dot + 1)), new TextEncoder().encode(encoded))) return void 0;
|
|
260
|
+
let payload;
|
|
261
|
+
try {
|
|
262
|
+
payload = JSON.parse(new TextDecoder().decode(decodeBase64Url(encoded)));
|
|
263
|
+
} catch {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (typeof payload?.id !== "string" || typeof payload?.exp !== "number" || typeof payload?.data !== "object" || payload.data === null || payload.exp < Date.now()) return;
|
|
267
|
+
return payload;
|
|
268
|
+
}
|
|
269
|
+
function encodeBase64Url(bytes) {
|
|
270
|
+
let binary = "";
|
|
271
|
+
for (let i = 0; i < bytes.length; i += 4096) binary += String.fromCharCode(...bytes.subarray(i, i + 4096));
|
|
272
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
273
|
+
}
|
|
274
|
+
function decodeBase64Url(value) {
|
|
275
|
+
const binary = atob(value.replaceAll("-", "+").replaceAll("_", "/"));
|
|
276
|
+
const bytes = new Uint8Array(binary.length);
|
|
277
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
278
|
+
return bytes;
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/server/ServerEvent.ts
|
|
282
|
+
var ServerEvent = class {
|
|
283
|
+
request;
|
|
284
|
+
response;
|
|
285
|
+
/**
|
|
286
|
+
* Set when the route handler (or a middleware enter hook) threw an
|
|
287
|
+
* error. Exit hooks can return a Response to handle it; if none does,
|
|
288
|
+
* the error is rethrown to the caller.
|
|
289
|
+
*/
|
|
290
|
+
error;
|
|
291
|
+
params;
|
|
292
|
+
adapter;
|
|
293
|
+
cookies;
|
|
294
|
+
headers;
|
|
295
|
+
session;
|
|
296
|
+
flash;
|
|
297
|
+
#url;
|
|
298
|
+
/** The request URL, parsed lazily. */
|
|
299
|
+
get url() {
|
|
300
|
+
return this.#url ??= new URL(this.request.url);
|
|
301
|
+
}
|
|
302
|
+
constructor(request, params, url) {
|
|
303
|
+
this.request = request;
|
|
304
|
+
this.params = params;
|
|
305
|
+
this.#url = url;
|
|
306
|
+
this.cookies = new CookieHelper(request);
|
|
307
|
+
this.headers = new HeaderHelper(request);
|
|
308
|
+
this.session = new SessionHelper(this.cookies);
|
|
309
|
+
this.flash = new FlashHelper(this.cookies);
|
|
310
|
+
this.adapter = globalThis.adapter;
|
|
311
|
+
}
|
|
312
|
+
addHeaders() {
|
|
313
|
+
if (!this.response) throw new Error("Response not created yet");
|
|
314
|
+
for (let cookie of this.cookies.cookies.values()) this.response.headers.append("set-cookie", cookie);
|
|
315
|
+
for (let header of this.headers.headers.entries()) this.response.headers.append(header[0], header[1]);
|
|
316
|
+
const base = getBasePath();
|
|
317
|
+
if (base) {
|
|
318
|
+
const location = this.response.headers.get("Location");
|
|
319
|
+
if (location) {
|
|
320
|
+
const rewritten = addBaseToPath(location, base);
|
|
321
|
+
if (rewritten !== location) this.response.headers.set("Location", rewritten);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Reads the request body as JSON.
|
|
327
|
+
*/
|
|
328
|
+
json() {
|
|
329
|
+
return this.request.json();
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
//#endregion
|
|
333
|
+
export { HeaderHelper as n, CookieHelper as r, ServerEvent as t };
|
|
334
|
+
|
|
335
|
+
//# sourceMappingURL=ServerEvent-Bh9cEpro.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerEvent-Bh9cEpro.mjs","names":["COOKIE_NAME","#cookies","#cookies","#id","#write","#url"],"sources":["../src/server/CookieHelper.ts","../src/server/FlashHelper.ts","../src/server/HeaderHelper.ts","../src/server/SessionHelper.ts","../src/server/ServerEvent.ts"],"sourcesContent":["import { type SerializeOptions, parseCookie, stringifySetCookie } from \"cookie\";\n\nexport default class CookieHelper {\n\trequest: Request;\n\tcookies: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the value from the map\n\t\tif (this.cookies.has(name)) {\n\t\t\t// The stored value is a serialized Set-Cookie header; pull the\n\t\t\t// \"name=value\" prefix off and re-parse to get just the value\n\t\t\treturn parseCookie(this.cookies.get(name)!)[name];\n\t\t}\n\n\t\t// Otherwise, return the value from the `cookie` header\n\t\tconst header = this.request.headers.get(\"Cookie\");\n\t\treturn parseCookie(header ?? \"\")[name];\n\t}\n\n\tset(name: string, value: string, options?: SerializeOptions): void {\n\t\t// Set a cookie header with some default values for security\n\t\toptions ??= {};\n\t\toptions.httpOnly ??= true;\n\t\toptions.secure ??= true;\n\t\toptions.sameSite ??= \"lax\";\n\n\t\tthis.cookies.set(name, stringifySetCookie({ name, value, ...options }));\n\t}\n\n\tdelete(name: string, options?: SerializeOptions): void {\n\t\t// Set a cookie header with an empty value and an immediate expiry date.\n\t\t// Apply the same secure defaults as `set` so a previously-set Secure\n\t\t// cookie is actually overridden by the deletion.\n\t\toptions ??= {};\n\t\toptions.httpOnly ??= true;\n\t\toptions.secure ??= true;\n\t\toptions.sameSite ??= \"lax\";\n\t\toptions.expires = new Date(0);\n\n\t\tthis.cookies.set(name, stringifySetCookie({ name, value: \"\", ...options }));\n\t}\n}\n","import CookieHelper from \"./CookieHelper\";\n\nconst COOKIE_NAME = \"torpor-flash\";\n\n/**\n * A one-time values store set in a form action and shown on the next page\n * render, which survives the redirect. Available as `event.flash`; the\n * framework reads it into `$page.flash` when a page is rendered, so\n * components display it reactively:\n *\n * ```ts\n * actions: {\n * \tsave: async (event) => {\n * \t\t// ...save...\n * \t\tevent.flash.set(\"Project saved\"); // { message: \"Project saved\" }\n * \t\tevent.flash.set({ error: \"Import failed\", retryable: true });\n * \t\treturn seeOther(`/projects/${id}`);\n * \t},\n * }\n * ```\n *\n * ```torp\n * @if ($page.flash?.message) {\n * \t<p class=\"flash\">{$page.flash.message}</p>\n * }\n * ```\n *\n * The values ride in a (session-lifetime) cookie that is deleted when it is\n * read, so a page refresh shows them once. No signing: the only person who\n * can fake a flash is the one seeing it, and values are rendered as text.\n * They must be JSON-safe and small enough to fit in the cookie (~4KB). A\n * common shape for a styled banner is `{ type, message }`, for use e.g.\n * with the Notification component -- but the framework only requires the\n * values to be an object. Without cookies the message is simply lost --\n * the action itself still completes.\n */\nexport default class FlashHelper {\n\t#cookies: CookieHelper;\n\n\tconstructor(cookies: CookieHelper) {\n\t\tthis.#cookies = cookies;\n\t}\n\n\t/**\n\t * Reads the flash values, if any, and clears them: the same response\n\t * deletes the cookie, so the message shows exactly once. (When the\n\t * message was set during this same request, e.g. a form action that\n\t * re-renders instead of redirecting, the cookie is consumed without it\n\t * ever reaching the browser.)\n\t */\n\tget(): Record<string, unknown> | undefined {\n\t\tconst cookie = this.#cookies.get(COOKIE_NAME);\n\t\tif (!cookie) return undefined;\n\t\tthis.#cookies.delete(COOKIE_NAME, { path: \"/\" });\n\t\ttry {\n\t\t\tconst decoded = JSON.parse(decodeURIComponent(cookie));\n\t\t\tif (typeof decoded !== \"object\" || decoded === null || Array.isArray(decoded)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn decoded as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Sets the flash values. A string is stored as `{ message: value }`, an\n\t * object as-is, e.g. `flash.set({ error: \"Import failed\" })`.\n\t */\n\tset(value: string | Record<string, unknown>): void {\n\t\tconst data = typeof value === \"string\" ? { message: value } : value;\n\t\tthis.#cookies.set(COOKIE_NAME, encodeURIComponent(JSON.stringify(data)), { path: \"/\" });\n\t}\n\n\t/**\n\t * Clears an unread flash message, e.g. so it isn't shown on a later\n\t * re-render of the same page.\n\t */\n\tclear(): void {\n\t\tthis.#cookies.delete(COOKIE_NAME, { path: \"/\" });\n\t}\n}\n","export default class HeaderHelper {\n\trequest: Request;\n\theaders: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.headers.has(name)) {\n\t\t\treturn this.headers.get(name);\n\t\t}\n\t\t// Otherwise, return the value from the header\n\t\treturn this.request.headers.get(name) ?? undefined;\n\t}\n\n\tset(name: string, value: string): void {\n\t\tthis.headers.set(name, value);\n\t}\n\n\tdelete(name: string): void {\n\t\tthis.headers.delete(name);\n\t}\n}\n","import env from \"../env\";\nimport CookieHelper from \"./CookieHelper\";\n\nconst COOKIE_NAME = \"torpor-session\";\nconst DEFAULT_MAX_AGE = 30 * 24 * 60 * 60; // 30 days, in seconds\n\n/**\n * The data stored in the session. Must be JSON-safe, and small enough to\n * fit in a cookie (4KB) along with the id, expiry and signature.\n */\ntype SessionData = Record<string, unknown>;\n\ntype SessionPayload = {\n\tid: string;\n\tdata: SessionData;\n\t/** Expiry, as a Unix epoch in milliseconds */\n\texp: number;\n};\n\n// The imported signing key, cached per secret so repeated calls (per\n// request) don't re-import\nconst keys = new Map<string, Promise<CryptoKey>>();\n\n/**\n * A helper for reading and writing the signed session cookie, available as\n * `event.session` in load functions, actions, +server endpoints and hooks.\n *\n * The value is signed with HMAC-SHA256 using `TORPOR_SESSION_SECRET` from\n * the environment, so it can't be forged or tampered with -- but it is\n * still client-side storage: everything rides in the cookie, it can't be\n * revoked individually, and it is limited to ~4KB. When you need\n * revocation, store `session.id` in your database, check it on each\n * authed request (e.g. in a `_hook.server.ts`), and delete the row to\n * revoke.\n *\n * ```ts\n * // Login action\n * const user = await checkPassword(event.form());\n * await event.session.regenerate({ userId: user.id });\n *\n * // Root hook\n * const session = await event.session.get();\n * if (session) {\n * \tevent.appData.user = await getUser(session.userId);\n * }\n * ```\n */\nexport default class SessionHelper {\n\t#cookies: CookieHelper;\n\t#id: string | undefined;\n\n\tconstructor(cookies: CookieHelper) {\n\t\tthis.#cookies = cookies;\n\t}\n\n\t/**\n\t * The id embedded in the current session cookie, or undefined when\n\t * there is no valid session. Stable across `set` calls, so it can be\n\t * used as a database key; `regenerate` mints a new one.\n\t */\n\tget id(): string | undefined {\n\t\treturn this.#id;\n\t}\n\n\t/**\n\t * Reads and verifies the session, returning its data, or undefined when\n\t * there is no cookie, the signature doesn't match, or the session has\n\t * expired.\n\t */\n\tasync get(): Promise<SessionData | undefined> {\n\t\tconst value = this.#cookies.get(COOKIE_NAME);\n\t\tif (!value) return undefined;\n\t\tconst payload = await verifyValue(value);\n\t\tif (!payload) return undefined;\n\t\tthis.#id = payload.id;\n\t\treturn payload.data;\n\t}\n\n\t/**\n\t * Writes the session, signing the data and setting the cookie. Keeps\n\t * the current session id, minting one when there isn't a valid session\n\t * yet. Call `regenerate` instead when the session's identity should\n\t * change (e.g. at login, to prevent session fixation).\n\t */\n\tasync set(data: SessionData, options?: { maxAge?: number }): Promise<void> {\n\t\tconst id = this.#id ?? crypto.randomUUID();\n\t\tthis.#id = id;\n\t\tawait this.#write(id, data, options);\n\t}\n\n\t/**\n\t * Writes the session with a fresh id, replacing any existing one. Use\n\t * it when a session's privilege level changes (login, permission\n\t * upgrade), so a cookie that was set before the change can't be reused.\n\t */\n\tasync regenerate(data: SessionData = {}, options?: { maxAge?: number }): Promise<void> {\n\t\tconst id = crypto.randomUUID();\n\t\tthis.#id = id;\n\t\tawait this.#write(id, data, options);\n\t}\n\n\t/**\n\t * Deletes the session cookie. Note that a server-side record (if you\n\t * keep one) must be deleted or revoked separately.\n\t */\n\tasync destroy(): Promise<void> {\n\t\tthis.#id = undefined;\n\t\tthis.#cookies.delete(COOKIE_NAME, { path: \"/\" });\n\t}\n\n\tasync #write(\n\t\tid: string,\n\t\tdata: SessionData,\n\t\toptions: { maxAge?: number } | undefined,\n\t): Promise<void> {\n\t\tconst maxAge = options?.maxAge ?? DEFAULT_MAX_AGE;\n\t\tconst payload: SessionPayload = { id, data, exp: Date.now() + maxAge * 1000 };\n\t\tconst encoded = encodeBase64Url(new TextEncoder().encode(JSON.stringify(payload)));\n\t\tconst signature = await sign(encoded);\n\t\tthis.#cookies.set(COOKIE_NAME, `${encoded}.${signature}`, { path: \"/\", maxAge });\n\t}\n}\n\nfunction secret(): string {\n\tconst value = env().TORPOR_SESSION_SECRET;\n\tif (!value) {\n\t\tthrow new Error(\n\t\t\t\"TORPOR_SESSION_SECRET is not set. Add it to the environment (or to a .env \" +\n\t\t\t\t\"file in dev and preview) to use sessions.\",\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction signingKey(): Promise<CryptoKey> {\n\tconst value = secret();\n\tlet key = keys.get(value);\n\tif (!key) {\n\t\tkey = crypto.subtle.importKey(\n\t\t\t\"raw\",\n\t\t\tnew TextEncoder().encode(value),\n\t\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\t\tfalse,\n\t\t\t[\"sign\", \"verify\"],\n\t\t);\n\t\tkeys.set(value, key);\n\t}\n\treturn key;\n}\n\nasync function sign(payload: string): Promise<string> {\n\tconst signature = await crypto.subtle.sign(\n\t\t\"HMAC\",\n\t\tawait signingKey(),\n\t\tnew TextEncoder().encode(payload),\n\t);\n\treturn encodeBase64Url(new Uint8Array(signature));\n}\n\nasync function verifyValue(value: string): Promise<SessionPayload | undefined> {\n\tconst dot = value.lastIndexOf(\".\");\n\tif (dot === -1) return undefined;\n\tconst encoded = value.slice(0, dot);\n\tconst valid = await crypto.subtle.verify(\n\t\t\"HMAC\",\n\t\tawait signingKey(),\n\t\tdecodeBase64Url(value.slice(dot + 1)),\n\t\tnew TextEncoder().encode(encoded),\n\t);\n\tif (!valid) return undefined;\n\n\tlet payload: SessionPayload;\n\ttry {\n\t\tpayload = JSON.parse(new TextDecoder().decode(decodeBase64Url(encoded)));\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (\n\t\ttypeof payload?.id !== \"string\" ||\n\t\ttypeof payload?.exp !== \"number\" ||\n\t\ttypeof payload?.data !== \"object\" ||\n\t\tpayload.data === null ||\n\t\tpayload.exp < Date.now()\n\t) {\n\t\treturn undefined;\n\t}\n\treturn payload;\n}\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n\t// btoa can't take raw bytes, and long argument lists overflow, so\n\t// convert in chunks\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i += 0x1000) {\n\t\tbinary += String.fromCharCode(...bytes.subarray(i, i + 0x1000));\n\t}\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nfunction decodeBase64Url(value: string): Uint8Array<ArrayBuffer> {\n\tconst binary = atob(value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\"));\n\tconst bytes = new Uint8Array(binary.length);\n\tfor (let i = 0; i < binary.length; i++) {\n\t\tbytes[i] = binary.charCodeAt(i);\n\t}\n\treturn bytes;\n}\n","import { addBaseToPath, getBasePath } from \"../site/basePath\";\nimport CookieHelper from \"./CookieHelper\";\nimport FlashHelper from \"./FlashHelper\";\nimport HeaderHelper from \"./HeaderHelper\";\nimport SessionHelper from \"./SessionHelper\";\n\nexport default class ServerEvent {\n\trequest: Request;\n\tresponse: Response | undefined | void;\n\t/**\n\t * Set when the route handler (or a middleware enter hook) threw an\n\t * error. Exit hooks can return a Response to handle it; if none does,\n\t * the error is rethrown to the caller.\n\t */\n\terror: unknown;\n\t// TODO: Should we cast types??\n\tparams?: Record<string, string>;\n\n\tadapter: any;\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\tsession: SessionHelper;\n\tflash: FlashHelper;\n\n\t// Parsed once per request; Server.fetch passes the URL it already needed\n\t// for matching so it isn't parsed twice\n\t#url: URL | undefined;\n\n\t/** The request URL, parsed lazily. */\n\tget url(): URL {\n\t\treturn (this.#url ??= new URL(this.request.url));\n\t}\n\n\tconstructor(request: Request, params?: Record<string, string>, url?: URL) {\n\t\tthis.request = request;\n\t\tthis.params = params;\n\t\tthis.#url = url;\n\t\tthis.cookies = new CookieHelper(request);\n\t\tthis.headers = new HeaderHelper(request);\n\t\tthis.session = new SessionHelper(this.cookies);\n\t\tthis.flash = new FlashHelper(this.cookies);\n\n\t\t// Adapters may have added the `adapter` property to globalThis\n\t\t// @ts-ignore\n\t\tthis.adapter = globalThis.adapter;\n\t}\n\n\taddHeaders(): void {\n\t\tif (!this.response) {\n\t\t\tthrow new Error(\"Response not created yet\");\n\t\t}\n\n\t\tfor (let cookie of this.cookies.cookies.values()) {\n\t\t\tthis.response.headers.append(\"set-cookie\", cookie);\n\t\t}\n\n\t\tfor (let header of this.headers.headers.entries()) {\n\t\t\tthis.response.headers.append(header[0], header[1]);\n\t\t}\n\n\t\t// Redirect locations are written base-free, so that user code isn't\n\t\t// aware of the base path\n\t\tconst base = getBasePath();\n\t\tif (base) {\n\t\t\tconst location = this.response.headers.get(\"Location\");\n\t\t\tif (location) {\n\t\t\t\tconst rewritten = addBaseToPath(location, base);\n\t\t\t\tif (rewritten !== location) {\n\t\t\t\t\tthis.response.headers.set(\"Location\", rewritten);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Reads the request body as JSON.\n\t */\n\tjson(): Promise<unknown> {\n\t\treturn this.request.json();\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { r as ServerLoadEvent } from "./ServerLoadEvent-DzbxxkF8.mjs";
|
|
2
|
+
//#region src/types/ServerHook.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* For _hook.server.
|
|
5
|
+
*/
|
|
6
|
+
interface ServerHook<Route extends string | undefined = undefined> {
|
|
7
|
+
/**
|
|
8
|
+
* Called before each server request is handled. Return a Response to
|
|
9
|
+
* short-circuit the request, skipping the load, action or view rendering
|
|
10
|
+
* (e.g. a redirect for unauthenticated users).
|
|
11
|
+
*/
|
|
12
|
+
enter?: (event: ServerLoadEvent<Route>) => Promise<Response | void> | Response | void;
|
|
13
|
+
/**
|
|
14
|
+
* Called after the request has been handled, even if the handler threw
|
|
15
|
+
* an error or the enter hook short-circuited it.
|
|
16
|
+
*/
|
|
17
|
+
exit?: (event: ServerLoadEvent<Route>) => Promise<void> | void;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ServerHook as t };
|
|
21
|
+
//# sourceMappingURL=ServerHook-BTSGfLiJ.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerHook-BTSGfLiJ.d.mts","names":[],"sources":["../src/types/ServerHook.ts"],"mappings":";;;;;UAKyB,WAAW;;;;;;EAMnC,SAAS,OAAO,gBAAgB,WAAW,QAAQ,mBAAmB;;;;;EAKtE,QAAQ,OAAO,gBAAgB,WAAW"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as HeaderHelper, r as
|
|
1
|
+
import { i as CookieHelper, n as HeaderHelper, r as FlashHelper, t as SessionHelper } from "./SessionHelper-MaodMaLU.mjs";
|
|
2
2
|
import { a as RouteParamsOf } from "./ParseRouteParams-DBmqlmLh.mjs";
|
|
3
3
|
//#region src/types/ServerLoadEvent.d.ts
|
|
4
4
|
/**
|
|
@@ -60,32 +60,24 @@ interface ServerLoadEvent<Route extends string | undefined = undefined, Body = u
|
|
|
60
60
|
*/
|
|
61
61
|
cookies: CookieHelper;
|
|
62
62
|
/**
|
|
63
|
-
* A helper for
|
|
63
|
+
* A helper for reading and writing the signed session cookie. See
|
|
64
|
+
* [Sessions](/build/sessions).
|
|
64
65
|
*/
|
|
65
|
-
|
|
66
|
+
session: SessionHelper;
|
|
66
67
|
/**
|
|
67
|
-
*
|
|
68
|
+
* A helper for setting one-time flash messages, shown on the next page
|
|
69
|
+
* render as `$page.flash = { type, message }`.
|
|
68
70
|
*/
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/types/ServerHook.d.ts
|
|
73
|
-
/**
|
|
74
|
-
* For _hook.server.
|
|
75
|
-
*/
|
|
76
|
-
interface ServerHook<Route extends string | undefined = undefined> {
|
|
71
|
+
flash: FlashHelper;
|
|
77
72
|
/**
|
|
78
|
-
*
|
|
79
|
-
* short-circuit the request, skipping the load, action or view rendering
|
|
80
|
-
* (e.g. a redirect for unauthenticated users).
|
|
73
|
+
* A helper for getting and setting headers.
|
|
81
74
|
*/
|
|
82
|
-
|
|
75
|
+
headers: HeaderHelper;
|
|
83
76
|
/**
|
|
84
|
-
*
|
|
85
|
-
* an error or the enter hook short-circuited it.
|
|
77
|
+
* An optional adapter object, containing adapter-specific functionality.
|
|
86
78
|
*/
|
|
87
|
-
|
|
79
|
+
adapter: Record<PropertyKey, any>;
|
|
88
80
|
}
|
|
89
81
|
//#endregion
|
|
90
|
-
export {
|
|
91
|
-
//# sourceMappingURL=
|
|
82
|
+
export { QueryRecord as n, ServerLoadEvent as r, FormDataRecord as t };
|
|
83
|
+
//# sourceMappingURL=ServerLoadEvent-DzbxxkF8.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerLoadEvent-DzbxxkF8.d.mts","names":[],"sources":["../src/types/ServerLoadEvent.ts"],"mappings":";;;;;;;KAUY,iBAAiB,eAAe,qBAAqB;;;;;KAMrD,cAAc;;;;;;;;UASD,gBACxB,8CACA,gBACA,WAAW,gBACX,YAAY,aACZ,SAAS,cAAc;;;;EAKvB,KAAK;;;;;;EAML,QAAQ;;;;;EAOR,SAAS;;;;EAIT,SAAS;;;;EAKT,YAAY,QAAQ;;;;;;EAMpB,YAAY,QAAQ;;;;;;;EAOpB,aAAa,QAAQ;;;;EAIrB,SAAS;;;;;EAKT,SAAS;;;;;EAKT,OAAO;;;;EAIP,SAAS;;;;EAIT,SAAS,OAAO"}
|