@torpor/build 0.3.0 → 0.4.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/CHANGELOG.md +33 -0
- package/dist/{RouteType-g8Ce5gOd.js → RouteType-VOBjKJ8I.js} +3 -3
- package/dist/{RouteType-g8Ce5gOd.js.map → RouteType-VOBjKJ8I.js.map} +1 -1
- package/dist/{Server-CSpY_-Ba.d.ts → Server-DL9neaq0.d.ts} +2 -2
- package/dist/Server-DL9neaq0.d.ts.map +1 -0
- package/dist/{ServerEvent-2-CnAy1W.js → ServerEvent-Dnk2FIKQ.js} +3 -4
- package/dist/{ServerEvent-2-CnAy1W.js.map → ServerEvent-Dnk2FIKQ.js.map} +1 -1
- package/dist/{Site-D4x1l0p5.d.ts → Site-B8TxSzPk.d.ts} +3 -3
- package/dist/Site-B8TxSzPk.d.ts.map +1 -0
- package/dist/{_page-CsdPubw4.js → _page-B8QZDML_.js} +3 -3
- package/dist/_page-B8QZDML_.js.map +1 -0
- package/dist/bin/index.js +6 -6
- package/dist/{connectMiddleware-DbLj0St1.js → connectMiddleware-PBcWWRr-.js} +4 -4
- package/dist/{connectMiddleware-DbLj0St1.js.map → connectMiddleware-PBcWWRr-.js.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/nav.js +47 -28
- package/dist/nav.js.map +1 -1
- package/dist/{pathToRegex-CTgx7hQP.js → pathToRegex-BTPkBIYJ.js} +2 -2
- package/dist/{pathToRegex-CTgx7hQP.js.map → pathToRegex-BTPkBIYJ.js.map} +1 -1
- package/dist/{response-D-XpIuMH.js → response-KnPcsvtU.js} +3 -3
- package/dist/{response-D-XpIuMH.js.map → response-KnPcsvtU.js.map} +1 -1
- package/dist/response.js +2 -2
- package/dist/{run-CNdaKSPR.js → run-CaFHeN6K.js} +10 -9
- package/dist/run-CaFHeN6K.js.map +1 -0
- package/dist/run.d.ts +2 -2
- package/dist/run.js +6 -6
- package/dist/{seeOther-BmehiI4C.js → seeOther-C-36lhS5.js} +2 -2
- package/dist/{seeOther-BmehiI4C.js.map → seeOther-C-36lhS5.js.map} +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -3
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +1 -1
- package/dist/test.d.ts +2 -2
- package/dist/test.js +8 -15
- package/dist/test.js.map +1 -1
- package/package.json +8 -8
- package/src/nav/formSubmit.ts +48 -0
- package/src/nav/loadData.ts +1 -1
- package/src/nav/navigate.ts +18 -9
- package/src/run/prepareTemplate.ts +8 -1
- package/src/run/runBuild.ts +0 -1
- package/src/run/runDev.ts +3 -3
- package/src/site/clientEntry.ts +5 -0
- package/src/site/clientEntryDev.ts +3 -0
- package/src/site/serverEntry.ts +25 -7
- package/src/state/internal.ts +4 -3
- package/src/test/runTest.ts +1 -1
- package/src/types/LayoutPath.ts +1 -1
- package/dist/Server-CSpY_-Ba.d.ts.map +0 -1
- package/dist/Site-D4x1l0p5.d.ts.map +0 -1
- package/dist/_page-CsdPubw4.js.map +0 -1
- package/dist/run-CNdaKSPR.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @torpor/build
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 168dff3: !Edit: rename Range to Region to avoid name conflicts
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 051998b: Feat: very rudimentary dev tools
|
|
12
|
+
- Updated dependencies [255aad3]
|
|
13
|
+
- Updated dependencies [8b377a2]
|
|
14
|
+
- Updated dependencies [450b739]
|
|
15
|
+
- Updated dependencies [168dff3]
|
|
16
|
+
- Updated dependencies [fc60fe0]
|
|
17
|
+
- Updated dependencies [42c6b60]
|
|
18
|
+
- Updated dependencies [2818679]
|
|
19
|
+
- Updated dependencies [38fd0a5]
|
|
20
|
+
- Updated dependencies [3e6f3f7]
|
|
21
|
+
- Updated dependencies [051998b]
|
|
22
|
+
- @torpor/view@0.4.0
|
|
23
|
+
- @torpor/unplugin@0.2.1
|
|
24
|
+
|
|
25
|
+
## 0.3.1
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 34d17f7: Feat: UI Form component and client-side submit
|
|
30
|
+
- Updated dependencies [f4716c5]
|
|
31
|
+
- Updated dependencies [1253f7a]
|
|
32
|
+
- Updated dependencies [6268e00]
|
|
33
|
+
- Updated dependencies [f2fb547]
|
|
34
|
+
- @torpor/view@0.3.2
|
|
35
|
+
|
|
3
36
|
## 0.3.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pathToRegex } from "./pathToRegex-
|
|
1
|
+
import { t as pathToRegex } from "./pathToRegex-BTPkBIYJ.js";
|
|
2
2
|
|
|
3
3
|
//#region src/site/Router.ts
|
|
4
4
|
/**
|
|
@@ -103,5 +103,5 @@ const HOOK_SERVER_ROUTE = 7;
|
|
|
103
103
|
const ERROR_ROUTE = 8;
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
|
-
export {
|
|
107
|
-
//# sourceMappingURL=RouteType-
|
|
106
|
+
export { LAYOUT_SERVER_ROUTE as a, SERVER_ROUTE as c, LAYOUT_ROUTE as i, Router as l, HOOK_ROUTE as n, PAGE_ROUTE as o, HOOK_SERVER_ROUTE as r, PAGE_SERVER_ROUTE as s, ERROR_ROUTE as t };
|
|
107
|
+
//# sourceMappingURL=RouteType-VOBjKJ8I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteType-
|
|
1
|
+
{"version":3,"file":"RouteType-VOBjKJ8I.js","names":["#sortRoutes","#loadHandler","#findLayouts","#findServer","#findServerHook","layouts: LayoutHandler[]"],"sources":["../src/site/Router.ts","../src/types/RouteType.ts"],"sourcesContent":["import type LayoutHandler from \"../types/LayoutHandler\";\nimport type ManifestRoute from \"../types/ManifestRoute\";\nimport type RouteHandler from \"../types/RouteHandler\";\nimport pathToRegex from \"../utils/pathToRegex\";\n\n/**\n * A router that handles file routes with layouts, hooks, etc.\n */\nexport default class Router {\n\troutes: Route[] = [];\n\n\tconstructor() {}\n\n\t//add(path: string, file: string) {\n\t//\t// TODO: Call the specific addX method based on the file path\n\t//\tthis.addPage(route, file);\n\t//}\n\n\taddPages(routes: ManifestRoute[]): this {\n\t\tfor (let r of routes) {\n\t\t\tthis.routes.push(\n\t\t\t\tnew Route(r.path, {\n\t\t\t\t\tpath: r.path,\n\t\t\t\t\ttype: r.type,\n\t\t\t\t\tendPoint: r.endPoint,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\t// TODO: Allow calling with the endpoint itself, so that you can setup an app with no scaffold\n\taddPage(path: string, type: number, endPoint: () => Promise<any>): this {\n\t\tthis.routes.push(\n\t\t\tnew Route(path, {\n\t\t\t\tpath,\n\t\t\t\ttype,\n\t\t\t\tendPoint,\n\t\t\t}),\n\t\t);\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\t/*\n\tloadPage(ev: ServerEvent, file: string): Response {\n\t\tlet page = this.pages.get(file);\n\t\tif (!page) {\n\t\t\tpage = {};\n\t\t\tthis.pages.set(file, page);\n\t\t}\n\t}\n\t*/\n\n\tmatch(path: string, query: URLSearchParams): Match | undefined {\n\t\tfor (let route of this.routes) {\n\t\t\tlet match = path.match(route.regex);\n\t\t\tif (match) {\n\t\t\t\t// Lazy load server endpoints and layouts\n\t\t\t\tif (!route.handler.loaded) {\n\t\t\t\t\tthis.#loadHandler(route.handler, route.path);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\thandler: route.handler,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t\tquery,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(`not found: '${path}'`);\n\t}\n\n\t#loadHandler(handler: RouteHandler, path: string) {\n\t\thandler.layouts = this.#findLayouts(path);\n\t\thandler.serverEndPoint = this.#findServer(path);\n\t\thandler.serverHook = this.#findServerHook(path);\n\t}\n\n\t#findLayouts(path: string): LayoutHandler[] | undefined {\n\t\tlet layouts: LayoutHandler[] = [];\n\t\tlet parts = path\n\t\t\t// Strip the trailing`~/server` (so we don't look for `~/server/_layout`\n\t\t\t// which will never exist)\n\t\t\t.replace(/\\/~server$/, \"\")\n\t\t\t// The path will always start with / so splitting e.g. `/first/second`\n\t\t\t// will result in ['', 'first', 'second'] and checks for `/_layout`,\n\t\t\t// `/first/_layout` and `/second/_layout`\n\t\t\t.split(\"/\");\n\t\tlet basePath = \"\";\n\t\tfor (let i = 0; i < parts.length; i++) {\n\t\t\tif (i > 0) {\n\t\t\t\tbasePath += \"/\" + parts[i];\n\t\t\t}\n\t\t\tconst layoutPath = basePath + \"/_layout\";\n\t\t\tconst layoutRoute = this.routes.find((r) => r.path === layoutPath);\n\t\t\tif (layoutRoute) {\n\t\t\t\tlayouts.push({\n\t\t\t\t\tpath: layoutPath,\n\t\t\t\t\tendPoint: layoutRoute.handler.endPoint,\n\t\t\t\t\tserverEndPoint: this.#findServer(layoutPath),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn layouts.length ? layouts : undefined;\n\t}\n\n\t#findServer(path: string): (() => Promise<any>) | undefined {\n\t\tconst serverPath = path.replace(/\\/$/, \"\") + \"/~server\";\n\t\tconst serverRoute = this.routes.find((r) => r.path === serverPath);\n\t\treturn serverRoute && serverRoute.handler.endPoint;\n\t}\n\n\t#findServerHook(path: string): (() => Promise<any>) | undefined {\n\t\t// TODO: Should this be a collection, like layouts?\n\t\tlet serverHookPath = \"/_hook/~server\";\n\t\t// HACK: Generalise this\n\t\tif (path.startsWith(\"/api/\")) {\n\t\t\tserverHookPath = \"/api\" + serverHookPath;\n\t\t}\n\t\tconst serverHookRoute = this.routes.find((r) => r.path === serverHookPath);\n\t\treturn serverHookRoute && serverHookRoute.handler.endPoint;\n\t}\n\n\t// HACK: We're doing this here as well as in Site, so that you can use the\n\t// Router externally without Site\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 Route {\n\tpath: string;\n\tregex: RegExp;\n\thandler: RouteHandler;\n\n\tconstructor(path: string, handler: RouteHandler) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.handler = handler;\n\t}\n}\n\ninterface Match {\n\thandler: RouteHandler;\n\tparams?: Record<string, string>;\n\tquery: URLSearchParams;\n}\n","export const PAGE_ROUTE = 0;\nexport const PAGE_SERVER_ROUTE = 1;\nexport const SERVER_ROUTE = 3;\nexport const LAYOUT_ROUTE = 4;\nexport const LAYOUT_SERVER_ROUTE = 5;\nexport const HOOK_ROUTE = 6;\nexport const HOOK_SERVER_ROUTE = 7;\nexport const ERROR_ROUTE = 8;\n\nexport type RouteType =\n\t| typeof PAGE_ROUTE\n\t| typeof PAGE_SERVER_ROUTE\n\t| typeof SERVER_ROUTE\n\t| typeof LAYOUT_ROUTE\n\t| typeof LAYOUT_SERVER_ROUTE\n\t| typeof HOOK_ROUTE\n\t| typeof HOOK_SERVER_ROUTE\n\t| typeof ERROR_ROUTE\n\t| -1;\n"],"mappings":"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"}
|
|
@@ -74,5 +74,5 @@ interface Match {
|
|
|
74
74
|
params?: Record<string, string>;
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
|
-
export { CookieHelper, HeaderHelper, MiddlewareFunction
|
|
78
|
-
//# sourceMappingURL=Server-
|
|
77
|
+
export { CookieHelper as a, HeaderHelper as i, MiddlewareFunction as n, ServerEvent as r, Server as t };
|
|
78
|
+
//# sourceMappingURL=Server-DL9neaq0.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Server-DL9neaq0.d.ts","names":[],"sources":["../src/server/CookieHelper.ts","../src/server/HeaderHelper.ts","../src/server/ServerEvent.ts","../src/server/types/MiddlewareFunction.ts","../src/server/types/ServerFunction.ts","../src/server/Server.ts"],"sourcesContent":[],"mappings":";;;cAEqB,YAAA;WACX;EAHyC,OAE9B,EAEX,GAFW,CAAA,MAAA,EAAA,MAAA,CAAA;EACX,WAAA,CAAA,OAAA,EAGY,OAHZ;EACA,GAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAEY,GAAA,CAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAcsB,gBAdtB,CAAA,EAAA,IAAA;EAcsB,MAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EASZ,gBATY,CAAA,EAAA,IAAA;;;;cCpBvB,YAAA;WACX;WACA;EDFyC,WAE9B,CAAA,OAAA,ECEC,ODFD;EACX,GAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EACA,GAAA,CAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAEY,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;cEHD,WAAA;EFH8B,OAE9B,EEEX,OFFW;EACX,QAAA,EEEC,QFFD,GAAA,SAAA,GAAA,IAAA;EACA,MAAA,CAAA,EEGA,MFHA,CAAA,MAAA,EAAA,MAAA,CAAA;EAEY,OAAA,EAAA,GAAA;EAcsB,OAAA,EETlC,YFSkC;EASZ,OAAA,EEjBtB,YFiBsB;EAAA,WAAA,CAAA,OAAA,EEfV,OFeU,EAAA,MAAA,CAAA,EEfQ,MFeR,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;KG3B3B,kBAAA,QACA,gCACe,yBACR;;;KCHP,cAAA,OACD,gBACC,8BAA8B,QAAQ;;;;AJJQ;;AAIzC,cKMW,MAAA,CLNX;EAEY,CAAA,OAAA;EAcsB,MAAA,EKRnC,YLQmC,EAAA;EASZ,UAAA,EKfnB,kBLemB,EAAA;EAAA,WAAA,CAAA;;;;;;EC3BtB,KAAA,EAAA,CAAA,KAAA,EIwBa,WJxBb,GIwB2B,GJxB3B,EAAA,IAAA,CAAA,EIwBuC,WJxBvC,EAAA,GIwBqD,OJxBrD,CIwB6D,QJxB7D,CAAA;EAEY;;;;;ACHG;EAGf,GAAA,CAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EGkEa,cHlEb,CAAA,EGkE8B,MHlE9B;EACC,KAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EGuEW,KHvEX,GAAA,SAAA;EAED,GAAA,CAAA,GAAA,EAAA,EGoFE,kBHpFF,EAAA,CAAA,EGoFyB,MHpFzB;;cG6GJ,YAAA,CHxGI;EAEY,IAAA,EAAA,MAAA;EAAkB,KAAA,EGwGhC,MHxGgC;EAAA,EAAA,EGyGnC,cHzGmC;gCG2GT;;UAmBrB,KAAA;EF5Ic,EAAA,EE6InB,cF3IA;EACA,MAAA,CAAA,EE2IK,MF3IL,CAAA,MAAA,EAAA,MAAA,CAAA"}
|
|
@@ -9,8 +9,7 @@ var CookieHelper = class {
|
|
|
9
9
|
}
|
|
10
10
|
get(name) {
|
|
11
11
|
if (this.cookies.has(name)) return parse(this.cookies.get(name))[name];
|
|
12
|
-
|
|
13
|
-
return parse(header ?? "")[name];
|
|
12
|
+
return parse(this.request.headers.get("cookie") ?? "")[name];
|
|
14
13
|
}
|
|
15
14
|
set(name, value, options) {
|
|
16
15
|
options ??= {};
|
|
@@ -70,5 +69,5 @@ var ServerEvent = class {
|
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
//#endregion
|
|
73
|
-
export {
|
|
74
|
-
//# sourceMappingURL=ServerEvent-
|
|
72
|
+
export { HeaderHelper as n, CookieHelper as r, ServerEvent as t };
|
|
73
|
+
//# sourceMappingURL=ServerEvent-Dnk2FIKQ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerEvent-
|
|
1
|
+
{"version":3,"file":"ServerEvent-Dnk2FIKQ.js","names":[],"sources":["../src/server/CookieHelper.ts","../src/server/HeaderHelper.ts","../src/server/ServerEvent.ts"],"sourcesContent":["import { SerializeOptions, parse, serialize } from \"cookie\";\n\nexport default class CookieHelper {\n\trequest: Request;\n\tcookies: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the value from the map\n\t\tif (this.cookies.has(name)) {\n\t\t\treturn parse(this.cookies.get(name)!)[name];\n\t\t}\n\t\t// Otherwise, return the value from the `cookie` header\n\t\tconst header = this.request.headers.get(\"cookie\");\n\t\treturn parse(header ?? \"\")[name];\n\t}\n\n\tset(name: string, value: string, options?: SerializeOptions): 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\t\tthis.cookies.set(name, serialize(name, value, options));\n\t}\n\n\tdelete(name: string, options?: SerializeOptions): void {\n\t\t// Set a cookie header with an immediate expiry date\n\t\toptions ??= {};\n\t\toptions.expires = new Date(0);\n\t\tthis.cookies.set(name, serialize(name, \"\", options));\n\t}\n}\n","export default class HeaderHelper {\n\trequest: Request;\n\theaders: Map<string, string> = new Map();\n\n\tconstructor(request: Request) {\n\t\tthis.request = request;\n\t}\n\n\tget(name: string): string | undefined {\n\t\t// If it's been set, return the updated value\n\t\tif (this.headers.has(name)) {\n\t\t\treturn this.headers.get(name);\n\t\t}\n\t\t// Otherwise, return the value from the header\n\t\treturn this.request.headers.get(name) ?? undefined;\n\t}\n\n\tset(name: string, value: string): 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 CookieHelper from \"./CookieHelper\";\nimport HeaderHelper from \"./HeaderHelper\";\n\nexport default class ServerEvent {\n\trequest: Request;\n\tresponse: Response | undefined | void;\n\t// TODO: Should we cast types??\n\tparams?: Record<string, string>;\n\n\tadapter: any;\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\n\tconstructor(request: Request, params?: Record<string, string>) {\n\t\tthis.request = request;\n\t\tthis.params = params;\n\t\tthis.cookies = new CookieHelper(request);\n\t\tthis.headers = new HeaderHelper(request);\n\n\t\t// Adapters may have added the `adapter` property to globalThis\n\t\t// @ts-ignore\n\t\tthis.adapter = globalThis.adapter;\n\t}\n\n\taddHeaders(): 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\t}\n}\n"],"mappings":";;;AAEA,IAAqB,eAArB,MAAkC;CACjC;CACA,0BAA+B,IAAI,KAAK;CAExC,YAAY,SAAkB;AAC7B,OAAK,UAAU;;CAGhB,IAAI,MAAkC;AAErC,MAAI,KAAK,QAAQ,IAAI,KAAK,CACzB,QAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAE,CAAC;AAIvC,SAAO,MADQ,KAAK,QAAQ,QAAQ,IAAI,SAAS,IAC1B,GAAG,CAAC;;CAG5B,IAAI,MAAc,OAAe,SAAkC;AAElE,cAAY,EAAE;AACd,UAAQ,aAAa;AACrB,UAAQ,WAAW;AACnB,UAAQ,aAAa;AACrB,OAAK,QAAQ,IAAI,MAAM,UAAU,MAAM,OAAO,QAAQ,CAAC;;CAGxD,OAAO,MAAc,SAAkC;AAEtD,cAAY,EAAE;AACd,UAAQ,0BAAU,IAAI,KAAK,EAAE;AAC7B,OAAK,QAAQ,IAAI,MAAM,UAAU,MAAM,IAAI,QAAQ,CAAC;;;;;;ACjCtD,IAAqB,eAArB,MAAkC;CACjC;CACA,0BAA+B,IAAI,KAAK;CAExC,YAAY,SAAkB;AAC7B,OAAK,UAAU;;CAGhB,IAAI,MAAkC;AAErC,MAAI,KAAK,QAAQ,IAAI,KAAK,CACzB,QAAO,KAAK,QAAQ,IAAI,KAAK;AAG9B,SAAO,KAAK,QAAQ,QAAQ,IAAI,KAAK,IAAI;;CAG1C,IAAI,MAAc,OAAqB;AACtC,OAAK,QAAQ,IAAI,MAAM,MAAM;;CAG9B,OAAO,MAAoB;AAC1B,OAAK,QAAQ,OAAO,KAAK;;;;;;ACnB3B,IAAqB,cAArB,MAAiC;CAChC;CACA;CAEA;CAEA;CAEA;CACA;CAEA,YAAY,SAAkB,QAAiC;AAC9D,OAAK,UAAU;AACf,OAAK,SAAS;AACd,OAAK,UAAU,IAAI,aAAa,QAAQ;AACxC,OAAK,UAAU,IAAI,aAAa,QAAQ;AAIxC,OAAK,UAAU,WAAW;;CAG3B,aAAmB;AAClB,MAAI,CAAC,KAAK,SACT,OAAM,IAAI,MAAM,2BAA2B;AAG5C,OAAK,IAAI,UAAU,KAAK,QAAQ,QAAQ,QAAQ,CAC/C,MAAK,SAAS,QAAQ,OAAO,cAAc,OAAO;AAGnD,OAAK,IAAI,UAAU,KAAK,QAAQ,QAAQ,SAAS,CAChD,MAAK,SAAS,QAAQ,OAAO,OAAO,IAAI,OAAO,GAAG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Server } from "./Server-
|
|
1
|
+
import { t as Server } from "./Server-DL9neaq0.js";
|
|
2
2
|
import { Plugin, UserConfig } from "vite";
|
|
3
3
|
|
|
4
4
|
//#region src/types/Adapter.d.ts
|
|
@@ -63,5 +63,5 @@ declare class Site {
|
|
|
63
63
|
addRouteFile(path: string, file: string, type?: "+page" | "+page.server" | "+server" | "_layout" | "_layout.server" | "_hook" | "_hook.server" | "_error"): void;
|
|
64
64
|
}
|
|
65
65
|
//#endregion
|
|
66
|
-
export { Adapter, Site };
|
|
67
|
-
//# sourceMappingURL=Site-
|
|
66
|
+
export { Adapter as n, Site as t };
|
|
67
|
+
//# sourceMappingURL=Site-B8TxSzPk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Site-B8TxSzPk.d.ts","names":[],"sources":["../src/types/Adapter.ts","../src/types/RouteType.ts","../src/site/Site.ts"],"sourcesContent":[],"mappings":";;;;UAGyB,OAAA;oBACN,SAAS;EAHX,SAEQ,CAAA,EAAA,CAAA,IAAA,EAEL,IAFK,EAAA,GAEI,OAFJ,CAAA,IAAA,CAAA,GAAA,IAAA;EACN,KAAA,EAAA,CAAA,MAAA,EAEF,MAFE,EAAA,IAAA,EAEY,IAFZ,EAAA,GAAA,IAAA;;;;cCJN,UAAA;cACA,iBAAA;cACA,YAAA;cACA,YAAA;ADAY,cCCZ,mBAAA,GDDY,CAAA;AACN,cCCN,UAAA,GDDM,CAAA;AAAS,cCEf,iBAAA,GDFe,CAAA;AACR,cCEP,WAAA,GDFO,CAAA;AAAS,KCIjB,SAAA,GDJiB,OCKnB,UDLmB,GAAA,OCMnB,iBDNmB,GAAA,OCOnB,YDPmB,GAAA,OCQnB,YDRmB,GAAA,OCSnB,mBDTmB,GAAA,OCUnB,UDVmB,GAAA,OCWnB,iBDXmB,GAAA,OCYnB,WDZmB,GAAA,CAAA,CAAA;;;;AAJZ;;;AAIG,cEsBC,IAAA,CFtBD;EAAS,CAAA,OAAA;EACZ,IAAA,EAAA,MAAA;EAAc,MAAA,EAAA;IAAA,IAAA,EAAA,MAAA;;UEuBc;;ED7B7C,OAAa,ECkCH,MDlCG,EAAA;EACb,OAAa,ECmCH,ODnCG;EACb;AACA;AACA;AACA;AACA;EACA,MAAa,EAAA,MAAA,EAAA;EAEb;;;;;;EAMU,UAAA,CAAA,ECkCI,UDlCJ;EACA,WAAA,CAAA;EACA;;;;kCC0C6B;EA5ChC"}
|
|
@@ -7,7 +7,7 @@ function internal() {
|
|
|
7
7
|
const $page$1 = $watch({
|
|
8
8
|
status: 404,
|
|
9
9
|
url: new URL("http://localhost"),
|
|
10
|
-
form:
|
|
10
|
+
form: void 0,
|
|
11
11
|
error: { message: "" }
|
|
12
12
|
}, { shallow: true });
|
|
13
13
|
const client = {
|
|
@@ -29,5 +29,5 @@ const $page = internal().$page;
|
|
|
29
29
|
var $page_default = $page;
|
|
30
30
|
|
|
31
31
|
//#endregion
|
|
32
|
-
export { $page_default
|
|
33
|
-
//# sourceMappingURL=_page-
|
|
32
|
+
export { internal as n, $page_default as t };
|
|
33
|
+
//# sourceMappingURL=_page-B8QZDML_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_page-B8QZDML_.js","names":["INTERNAL_GLOBAL: unique symbol","$page: PageState","client: ClientState","$page: PageState"],"sources":["../src/state/internal.ts","../src/state/$page.ts"],"sourcesContent":["import { $watch } from \"@torpor/view\";\nimport type ClientState from \"../types/ClientState\";\nimport type InternalState from \"../types/InternalState\";\nimport type PageState from \"../types/PageState\";\n\n// Do a weird little dance to ensure that everyone has the same $page and\n// client, regardless of if they are entering via serverEntry/clientEntry or\n// importing from the @torpor/build library (e.g. in components). There may be\n// an easier way to do this!\n\nconst INTERNAL_GLOBAL: unique symbol = Symbol.for(\"torpor-internal\");\n\nexport default function internal(): InternalState {\n\t// @ts-ignore\n\tif (globalThis[INTERNAL_GLOBAL] === undefined) {\n\t\t// TODO: Should use the SSR $watch if entering via serverEntry\n\t\tconst $page: PageState = $watch(\n\t\t\t{\n\t\t\t\tstatus: 404,\n\t\t\t\turl: new URL(\"http://localhost\"),\n\t\t\t\tform: undefined,\n\t\t\t\terror: {\n\t\t\t\t\tmessage: \"\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tshallow: true,\n\t\t\t},\n\t\t);\n\t\tconst client: ClientState = {\n\t\t\t// @ts-ignore This will definitely, 100% get set\n\t\t\trouter: null,\n\t\t\tlayoutStack: [],\n\t\t\t// TODO: Probably expire after 30 seconds or something?\n\t\t\tprefetchedData: {},\n\t\t};\n\n\t\t// @ts-ignore\n\t\tglobalThis[INTERNAL_GLOBAL] = {\n\t\t\t$page,\n\t\t\tclient,\n\t\t} satisfies InternalState;\n\t}\n\t// @ts-ignore\n\treturn globalThis[INTERNAL_GLOBAL] as InternalState;\n}\n","import type PageState from \"../types/PageState\";\nimport internal from \"./internal\";\n\nconst $page: PageState = internal().$page;\n\nexport default $page;\n"],"mappings":";;;AAUA,MAAMA,kBAAiC,OAAO,IAAI,kBAAkB;AAEpE,SAAwB,WAA0B;AAEjD,KAAI,WAAW,qBAAqB,QAAW;EAE9C,MAAMC,UAAmB,OACxB;GACC,QAAQ;GACR,KAAK,IAAI,IAAI,mBAAmB;GAChC,MAAM;GACN,OAAO,EACN,SAAS,IACT;GACD,EACD,EACC,SAAS,MACT,CACD;EACD,MAAMC,SAAsB;GAE3B,QAAQ;GACR,aAAa,EAAE;GAEf,gBAAgB,EAAE;GAClB;AAGD,aAAW,mBAAmB;GAC7B;GACA;GACA;;AAGF,QAAO,WAAW;;;;;ACzCnB,MAAMC,QAAmB,UAAU,CAAC;AAEpC,oBAAe"}
|
package/dist/bin/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import "../pathToRegex-
|
|
3
|
-
import "../seeOther-
|
|
4
|
-
import "../response-
|
|
5
|
-
import { run } from "../run-
|
|
6
|
-
import "../ServerEvent-
|
|
7
|
-
import "../connectMiddleware-
|
|
2
|
+
import "../pathToRegex-BTPkBIYJ.js";
|
|
3
|
+
import "../seeOther-C-36lhS5.js";
|
|
4
|
+
import "../response-KnPcsvtU.js";
|
|
5
|
+
import { t as run } from "../run-CaFHeN6K.js";
|
|
6
|
+
import "../ServerEvent-Dnk2FIKQ.js";
|
|
7
|
+
import "../connectMiddleware-PBcWWRr-.js";
|
|
8
8
|
|
|
9
9
|
//#region src/bin/index.ts
|
|
10
10
|
const workingDir = process.cwd();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { pathToRegex } from "./pathToRegex-
|
|
2
|
-
import { ServerEvent } from "./ServerEvent-
|
|
1
|
+
import { t as pathToRegex } from "./pathToRegex-BTPkBIYJ.js";
|
|
2
|
+
import { t as ServerEvent } from "./ServerEvent-Dnk2FIKQ.js";
|
|
3
3
|
import { ServerResponse } from "node:http";
|
|
4
4
|
import { PassThrough, Readable } from "node:stream";
|
|
5
5
|
|
|
@@ -248,5 +248,5 @@ const statusCodesWithoutBody = [
|
|
|
248
248
|
];
|
|
249
249
|
|
|
250
250
|
//#endregion
|
|
251
|
-
export { Server, connectMiddleware };
|
|
252
|
-
//# sourceMappingURL=connectMiddleware-
|
|
251
|
+
export { Server as n, connectMiddleware as t };
|
|
252
|
+
//# sourceMappingURL=connectMiddleware-PBcWWRr-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectMiddleware-DbLj0St1.js","names":["#sortRoutes","v","chunks: Buffer[]"],"sources":["../src/server/Server.ts","../src/server/connect/bufferToArrayBuffer.ts","../src/server/connect/flattenHeaders.ts","../src/server/connect/nodeMessageToNodeResponse.ts","../src/server/connect/readableToBuffer.ts","../src/server/connect/requestToNodeMessage.ts","../src/server/connect/connectMiddleware.ts"],"sourcesContent":["import pathToRegex from \"../utils/pathToRegex\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\nconst noop = () => {};\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst request = new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params);\n\n\t\tif (this.middleware.length) {\n\t\t\t// TODO: Get middleware that applies to this route only?\n\t\t\tawait this.middleware[0](ev, buildNext(this.middleware, 0));\n\t\t\tfunction buildNext(middleware: MiddlewareFunction[], i: number): () => void | Promise<void> {\n\t\t\t\tif (ev.response) {\n\t\t\t\t\treturn noop;\n\t\t\t\t}\n\n\t\t\t\tif (i < middleware.length - 1) {\n\t\t\t\t\tlet next = middleware[i + 1];\n\t\t\t\t\treturn async () => next(ev, buildNext(middleware, i + 1));\n\t\t\t\t} else {\n\t\t\t\t\treturn match\n\t\t\t\t\t\t? async () => {\n\t\t\t\t\t\t\t\tev.response = await match.fn(ev);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: noop;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tthis.routes.push(new RouteHandler(path, fn));\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string): Match | undefined {\n\t\tfor (let handler of this.routes) {\n\t\t\tlet match = path.match(handler.regex);\n\t\t\tif (match) {\n\t\t\t\treturn {\n\t\t\t\t\tfn: handler.fn,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tregex: RegExp;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n\ninterface Match {\n\tfn: ServerFunction;\n\tparams?: Record<string, string>;\n}\n","// From https://stackoverflow.com/a/79345620\n// No idea why it is needed\nexport default function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {\n\treturn buffer.buffer.slice(\n\t\tbuffer.byteOffset,\n\t\tbuffer.byteOffset + buffer.byteLength,\n\t) as ArrayBuffer;\n}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import {\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeader,\n\ttype OutgoingHttpHeaders,\n\tServerResponse,\n} from \"node:http\";\nimport { PassThrough, Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts\n\n/**\n * Creates a custom ServerResponse object that allows for intercepting and\n * streaming the response.\n *\n * @param incomingMessage The incoming HTTP request message.\n * @returns An object containing the custom ServerResponse and a function that\n * takes a callback to invoke when the response is readable, providing an object\n * with the readable stream, headers and status code.\n */\nexport default function nodeMessageToNodeResponse(\n\tincomingMessage: IncomingMessage,\n): ServerResponseResponse {\n\tconst res = new ServerResponse(incomingMessage);\n\tconst passThrough = new PassThrough();\n\tlet handled = false;\n\n\tconst onReadable = (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => {\n\t\tconst handleReadable = () => {\n\t\t\tif (handled) return;\n\t\t\thandled = true;\n\t\t\tcb({\n\t\t\t\treadable: Readable.from(passThrough),\n\t\t\t\theaders: res.getHeaders(),\n\t\t\t\tstatus: res.statusCode,\n\t\t\t});\n\t\t};\n\n\t\tpassThrough.once(\"readable\", handleReadable);\n\t\tpassThrough.once(\"end\", handleReadable);\n\t};\n\n\tpassThrough.once(\"finish\", () => {\n\t\tres.emit(\"finish\");\n\t});\n\tpassThrough.once(\"close\", () => {\n\t\tres.destroy();\n\t\tres.emit(\"close\");\n\t});\n\tpassThrough.on(\"drain\", () => {\n\t\tres.emit(\"drain\");\n\t});\n\n\tres.write = passThrough.write.bind(passThrough);\n\tres.end = passThrough.end.bind(passThrough) as any;\n\n\tres.writeHead = function writeHead(\n\t\tstatusCode: number,\n\t\tstatusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t\theaders?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t): ServerResponse {\n\t\tres.statusCode = statusCode;\n\t\tif (typeof statusMessage === \"object\") {\n\t\t\theaders = statusMessage;\n\t\t\tstatusMessage = undefined;\n\t\t}\n\t\tif (headers) {\n\t\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t};\n\n\treturn {\n\t\tres,\n\t\tonReadable,\n\t};\n}\n\ninterface ServerResponseResponse {\n\tres: ServerResponse;\n\tonReadable: (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => void;\n}\n","import { Readable } from \"node:stream\";\n\nexport default function readableToBuffer(req: Readable): Promise<Buffer> {\n\treturn new Promise<Buffer>((resolve, reject) => {\n\t\tconst chunks: Buffer[] = [];\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tchunks.push(chunk);\n\t\t});\n\t\treq.on(\"end\", () => {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\treq.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\t});\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\nconst DUMMY_BASE_URL = \"http://localhost\";\n\n/**\n * Creates an IncomingMessage object from a web Request.\n *\n * @param {Request} request - The web Request object.\n * @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.\n */\nexport default function requestToNodeMessage(request: Request): IncomingMessage {\n\tconst parsedUrl = new URL(request.url, DUMMY_BASE_URL);\n\tconst pathAndQuery = (parsedUrl.pathname || \"\") + (parsedUrl.search || \"\");\n\t// HACK: Using Readable.fromWeb locks request.body so that the request cannot be used again\n\t// As we're only using this for Vite middlewares, it's safe to discard the body for now?\n\tconst body = /*request.body ? Readable.fromWeb(request.body as any) :*/ Readable.from([]);\n\n\treturn Object.assign(body, {\n\t\turl: pathAndQuery,\n\t\tmethod: request.method,\n\t\theaders: Object.fromEntries(request.headers),\n\t}) as IncomingMessage;\n}\n","import { IncomingMessage, ServerResponse } from \"node:http\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport bufferToArrayBuffer from \"./bufferToArrayBuffer\";\nimport flattenHeaders from \"./flattenHeaders\";\nimport nodeMessageToNodeResponse from \"./nodeMessageToNodeResponse\";\nimport readableToBuffer from \"./readableToBuffer\";\nimport requestToNodeMessage from \"./requestToNodeMessage\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\n/**\n * Converts a Connect-style middleware to a web-compatible request handler.\n *\n * @param handler - The Connect-style middleware function to be converted.\n * @returns A function that handles web requests and returns a Response or undefined.\n */\nexport default function connectMiddleware(\n\thandler: ConnectMiddleware | ConnectMiddlewareBoolean,\n): MiddlewareFunction {\n\treturn async (ev, next) => {\n\t\tconst req = requestToNodeMessage(ev.request);\n\t\tconst { res, onReadable } = nodeMessageToNodeResponse(req);\n\n\t\treturn new Promise<void>(async (resolve, reject) => {\n\t\t\tonReadable(async ({ readable, headers, status }) => {\n\t\t\t\tconst responseBody = statusCodesWithoutBody.includes(status)\n\t\t\t\t\t? null\n\t\t\t\t\t: //(Readable.toWeb(readable) as ReadableStream);\n\t\t\t\t\t\t// HACK: Chunked bodies are not being\n\t\t\t\t\t\t// read correctly somewhere...\n\t\t\t\t\t\tbufferToArrayBuffer(await readableToBuffer(readable));\n\t\t\t\tev.response = new Response(responseBody, {\n\t\t\t\t\tstatus,\n\t\t\t\t\theaders: flattenHeaders(headers),\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tconst cnext = async (error?: unknown) => {\n\t\t\t\tif (error) {\n\t\t\t\t\t// eslint-disable-next-line no-base-to-string\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: Can we nest the next functions less? This is a bit weird\n\t\t\t\t\tawait next();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst handled = await handler(req, res, cnext);\n\t\t\t\tif (handled === false) {\n\t\t\t\t\tres.destroy();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tawait cnext(e);\n\t\t\t}\n\t\t});\n\t};\n}\n\nconst statusCodesWithoutBody = [\n\t100, // Continue\n\t101, // Switching Protocols\n\t102, // Processing (WebDAV)\n\t103, // Early Hints\n\t204, // No Content\n\t205, // Reset Content\n\t304, // Not Modified\n];\n\ntype NextFunction = (err?: unknown) => void;\ntype ConnectMiddleware<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => void | Promise<void>;\ntype ConnectMiddlewareBoolean<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => boolean | Promise<boolean>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"connectMiddleware-PBcWWRr-.js","names":["#sortRoutes","v","chunks: Buffer[]"],"sources":["../src/server/Server.ts","../src/server/connect/bufferToArrayBuffer.ts","../src/server/connect/flattenHeaders.ts","../src/server/connect/nodeMessageToNodeResponse.ts","../src/server/connect/readableToBuffer.ts","../src/server/connect/requestToNodeMessage.ts","../src/server/connect/connectMiddleware.ts"],"sourcesContent":["import pathToRegex from \"../utils/pathToRegex\";\nimport ServerEvent from \"./ServerEvent\";\nimport type MiddlewareFunction from \"./types/MiddlewareFunction\";\nimport type ServerFunction from \"./types/ServerFunction\";\n\nconst noop = () => {};\n\n/**\n * A Fetch API Request/Response server.\n */\nexport default class Server {\n\t// TODO: We don't use any of the routes, just add(\"*\") in runDev/runBuild...\n\troutes: RouteHandler[] = [];\n\t// TODO: We only use the Vite middleware here\n\tmiddleware: MiddlewareFunction[] = [];\n\n\tconstructor() {\n\t\tthis.routes = [];\n\t\tthis.middleware = [];\n\t}\n\n\t/**\n\t * The standard Fetch API method that should work in any runtime (including\n\t * Node with polyfills).\n\t * @returns\n\t */\n\tfetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst request = new Request(input, init);\n\t\tconst url = new URL(request.url);\n\t\tconst match = this.match(url.pathname);\n\t\tlet ev = new ServerEvent(request, match?.params);\n\n\t\tif (this.middleware.length) {\n\t\t\t// TODO: Get middleware that applies to this route only?\n\t\t\tawait this.middleware[0](ev, buildNext(this.middleware, 0));\n\t\t\tfunction buildNext(middleware: MiddlewareFunction[], i: number): () => void | Promise<void> {\n\t\t\t\tif (ev.response) {\n\t\t\t\t\treturn noop;\n\t\t\t\t}\n\n\t\t\t\tif (i < middleware.length - 1) {\n\t\t\t\t\tlet next = middleware[i + 1];\n\t\t\t\t\treturn async () => next(ev, buildNext(middleware, i + 1));\n\t\t\t\t} else {\n\t\t\t\t\treturn match\n\t\t\t\t\t\t? async () => {\n\t\t\t\t\t\t\t\tev.response = await match.fn(ev);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: noop;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (match) {\n\t\t\tev.response = await match.fn(ev);\n\t\t} else {\n\t\t\treturn new Response(null, { status: 404 });\n\t\t}\n\n\t\t// TODO: Should I be returning 200 if there's no response? Because it's not an error??\n\t\tev.response ??= new Response(null, { status: 200 });\n\t\tev.addHeaders();\n\n\t\treturn ev.response;\n\t};\n\n\t/**\n\t * Adds a server function at a route path.\n\t * @param path The route path pattern.\n\t * @param fn The function to call when the pattern is matched.\n\t * @returns\n\t */\n\tadd(path: string, fn: ServerFunction): Server {\n\t\tthis.routes.push(new RouteHandler(path, fn));\n\t\tthis.#sortRoutes();\n\t\treturn this;\n\t}\n\n\tmatch(path: string): Match | undefined {\n\t\tfor (let handler of this.routes) {\n\t\t\tlet match = path.match(handler.regex);\n\t\t\tif (match) {\n\t\t\t\treturn {\n\t\t\t\t\tfn: handler.fn,\n\t\t\t\t\tparams: match.groups,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconsole.log(`Server path not found: ${path}`);\n\t}\n\n\t// TODO:\n\t//use(path: string, ...fn: MiddlewareFunction[])\n\tuse(...fn: MiddlewareFunction[]): Server {\n\t\tthis.middleware = this.middleware.concat(fn);\n\t\treturn this;\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n\nclass RouteHandler {\n\tpath: string;\n\tregex: RegExp;\n\tfn: ServerFunction;\n\n\tconstructor(path: string, fn: ServerFunction) {\n\t\tthis.path = path;\n\t\tthis.regex = pathToRegex(path);\n\t\tthis.fn = fn;\n\t}\n}\n\n//class MiddlewareHandler {\n//\tpath: string;\n//\tregex: RegExp;\n//\tfn: MiddlewareFunction;\n//\n//\tconstructor(path: string, fn: MiddlewareFunction) {\n//\t\tthis.path = path;\n//\t\tthis.regex = pathToRegex(path);\n//\t\tthis.fn = fn;\n//\t}\n//}\n\ninterface Match {\n\tfn: ServerFunction;\n\tparams?: Record<string, string>;\n}\n","// From https://stackoverflow.com/a/79345620\n// No idea why it is needed\nexport default function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {\n\treturn buffer.buffer.slice(\n\t\tbuffer.byteOffset,\n\t\tbuffer.byteOffset + buffer.byteLength,\n\t) as ArrayBuffer;\n}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import {\n\ttype IncomingMessage,\n\ttype OutgoingHttpHeader,\n\ttype OutgoingHttpHeaders,\n\tServerResponse,\n} from \"node:http\";\nimport { PassThrough, Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/createServerResponse.ts\n\n/**\n * Creates a custom ServerResponse object that allows for intercepting and\n * streaming the response.\n *\n * @param incomingMessage The incoming HTTP request message.\n * @returns An object containing the custom ServerResponse and a function that\n * takes a callback to invoke when the response is readable, providing an object\n * with the readable stream, headers and status code.\n */\nexport default function nodeMessageToNodeResponse(\n\tincomingMessage: IncomingMessage,\n): ServerResponseResponse {\n\tconst res = new ServerResponse(incomingMessage);\n\tconst passThrough = new PassThrough();\n\tlet handled = false;\n\n\tconst onReadable = (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => {\n\t\tconst handleReadable = () => {\n\t\t\tif (handled) return;\n\t\t\thandled = true;\n\t\t\tcb({\n\t\t\t\treadable: Readable.from(passThrough),\n\t\t\t\theaders: res.getHeaders(),\n\t\t\t\tstatus: res.statusCode,\n\t\t\t});\n\t\t};\n\n\t\tpassThrough.once(\"readable\", handleReadable);\n\t\tpassThrough.once(\"end\", handleReadable);\n\t};\n\n\tpassThrough.once(\"finish\", () => {\n\t\tres.emit(\"finish\");\n\t});\n\tpassThrough.once(\"close\", () => {\n\t\tres.destroy();\n\t\tres.emit(\"close\");\n\t});\n\tpassThrough.on(\"drain\", () => {\n\t\tres.emit(\"drain\");\n\t});\n\n\tres.write = passThrough.write.bind(passThrough);\n\tres.end = passThrough.end.bind(passThrough) as any;\n\n\tres.writeHead = function writeHead(\n\t\tstatusCode: number,\n\t\tstatusMessage?: string | OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t\theaders?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n\t): ServerResponse {\n\t\tres.statusCode = statusCode;\n\t\tif (typeof statusMessage === \"object\") {\n\t\t\theaders = statusMessage;\n\t\t\tstatusMessage = undefined;\n\t\t}\n\t\tif (headers) {\n\t\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t};\n\n\treturn {\n\t\tres,\n\t\tonReadable,\n\t};\n}\n\ninterface ServerResponseResponse {\n\tres: ServerResponse;\n\tonReadable: (\n\t\tcb: (result: { readable: Readable; headers: OutgoingHttpHeaders; status: number }) => void,\n\t) => void;\n}\n","import { Readable } from \"node:stream\";\n\nexport default function readableToBuffer(req: Readable): Promise<Buffer> {\n\treturn new Promise<Buffer>((resolve, reject) => {\n\t\tconst chunks: Buffer[] = [];\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tchunks.push(chunk);\n\t\t});\n\t\treq.on(\"end\", () => {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\treq.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\t});\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\nconst DUMMY_BASE_URL = \"http://localhost\";\n\n/**\n * Creates an IncomingMessage object from a web Request.\n *\n * @param {Request} request - The web Request object.\n * @returns {IncomingMessage} An IncomingMessage-like object compatible with Node.js HTTP module.\n */\nexport default function requestToNodeMessage(request: Request): IncomingMessage {\n\tconst parsedUrl = new URL(request.url, DUMMY_BASE_URL);\n\tconst pathAndQuery = (parsedUrl.pathname || \"\") + (parsedUrl.search || \"\");\n\t// HACK: Using Readable.fromWeb locks request.body so that the request cannot be used again\n\t// As we're only using this for Vite middlewares, it's safe to discard the body for now?\n\tconst body = /*request.body ? Readable.fromWeb(request.body as any) :*/ Readable.from([]);\n\n\treturn Object.assign(body, {\n\t\turl: pathAndQuery,\n\t\tmethod: request.method,\n\t\theaders: Object.fromEntries(request.headers),\n\t}) as IncomingMessage;\n}\n","import { IncomingMessage, ServerResponse } from \"node:http\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport bufferToArrayBuffer from \"./bufferToArrayBuffer\";\nimport flattenHeaders from \"./flattenHeaders\";\nimport nodeMessageToNodeResponse from \"./nodeMessageToNodeResponse\";\nimport readableToBuffer from \"./readableToBuffer\";\nimport requestToNodeMessage from \"./requestToNodeMessage\";\n\n// From https://github.com/vikejs/vike-node/blob/main/packages/vike-node/src/runtime/adapters/connectToWeb.ts\n\n/**\n * Converts a Connect-style middleware to a web-compatible request handler.\n *\n * @param handler - The Connect-style middleware function to be converted.\n * @returns A function that handles web requests and returns a Response or undefined.\n */\nexport default function connectMiddleware(\n\thandler: ConnectMiddleware | ConnectMiddlewareBoolean,\n): MiddlewareFunction {\n\treturn async (ev, next) => {\n\t\tconst req = requestToNodeMessage(ev.request);\n\t\tconst { res, onReadable } = nodeMessageToNodeResponse(req);\n\n\t\treturn new Promise<void>(async (resolve, reject) => {\n\t\t\tonReadable(async ({ readable, headers, status }) => {\n\t\t\t\tconst responseBody = statusCodesWithoutBody.includes(status)\n\t\t\t\t\t? null\n\t\t\t\t\t: //(Readable.toWeb(readable) as ReadableStream);\n\t\t\t\t\t\t// HACK: Chunked bodies are not being\n\t\t\t\t\t\t// read correctly somewhere...\n\t\t\t\t\t\tbufferToArrayBuffer(await readableToBuffer(readable));\n\t\t\t\tev.response = new Response(responseBody, {\n\t\t\t\t\tstatus,\n\t\t\t\t\theaders: flattenHeaders(headers),\n\t\t\t\t});\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tconst cnext = async (error?: unknown) => {\n\t\t\t\tif (error) {\n\t\t\t\t\t// eslint-disable-next-line no-base-to-string\n\t\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t} else {\n\t\t\t\t\t// TODO: Can we nest the next functions less? This is a bit weird\n\t\t\t\t\tawait next();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst handled = await handler(req, res, cnext);\n\t\t\t\tif (handled === false) {\n\t\t\t\t\tres.destroy();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tawait cnext(e);\n\t\t\t}\n\t\t});\n\t};\n}\n\nconst statusCodesWithoutBody = [\n\t100, // Continue\n\t101, // Switching Protocols\n\t102, // Processing (WebDAV)\n\t103, // Early Hints\n\t204, // No Content\n\t205, // Reset Content\n\t304, // Not Modified\n];\n\ntype NextFunction = (err?: unknown) => void;\ntype ConnectMiddleware<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => void | Promise<void>;\ntype ConnectMiddlewareBoolean<\n\tPlatformRequest extends IncomingMessage = IncomingMessage,\n\tPlatformResponse extends ServerResponse = ServerResponse,\n> = (req: PlatformRequest, res: PlatformResponse, next: NextFunction) => boolean | Promise<boolean>;\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CookieHelper, HeaderHelper } from "./Server-
|
|
2
|
-
import { Adapter, Site } from "./Site-
|
|
1
|
+
import { a as CookieHelper, i as HeaderHelper } from "./Server-DL9neaq0.js";
|
|
2
|
+
import { n as Adapter, t as Site } from "./Site-B8TxSzPk.js";
|
|
3
3
|
import { Component } from "@torpor/view";
|
|
4
4
|
|
|
5
5
|
//#region src/types/ManifestRoute.d.ts
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/ManifestRoute.ts","../src/types/RouteLayoutHandler.ts","../src/types/RouteHandler.ts","../src/site/Router.ts","../src/types/PageLoadEvent.ts","../src/types/PageEndPoint.ts","../src/types/ServerLoadEvent.ts","../src/types/PageServerAction.ts","../src/types/PageServerLoad.ts","../src/types/PageServerEndPoint.ts","../src/types/ServerRequest.ts","../src/types/ServerEndPoint.ts","../src/types/ServerHook.ts"],"sourcesContent":[],"mappings":";;;;;UAAyB,aAAA;;;kBAGR;;;;UCHQ,kBAAA;;kBAER;yBACO;;;;UCDC,YAAA;;;kBAGR;QFLQ,CAAA,EAAA,OAAA;YEQd;yBACa;qBACJ;;;;;;;AFVK,cGQJ,MAAA,CHRI;;UGShB;;UFTgB,CAAA,MAAA,EEkBP,aFlBO,EAAA,CAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/ManifestRoute.ts","../src/types/RouteLayoutHandler.ts","../src/types/RouteHandler.ts","../src/site/Router.ts","../src/types/PageLoadEvent.ts","../src/types/PageEndPoint.ts","../src/types/ServerLoadEvent.ts","../src/types/PageServerAction.ts","../src/types/PageServerLoad.ts","../src/types/PageServerEndPoint.ts","../src/types/ServerRequest.ts","../src/types/ServerEndPoint.ts","../src/types/ServerHook.ts"],"sourcesContent":[],"mappings":";;;;;UAAyB,aAAA;;;kBAGR;;;;UCHQ,kBAAA;;kBAER;yBACO;;;;UCDC,YAAA;;;kBAGR;QFLQ,CAAA,EAAA,OAAA;YEQd;yBACa;qBACJ;;;;;;;AFVK,cGQJ,MAAA,CHRI;;UGShB;;UFTgB,CAAA,MAAA,EEkBP,aFlBO,EAAA,CAAA,EAAA,IAER;sDE+BoC;6BAsBzB,kBAAkB;;ADvDV,cCoJ9B,KAAA,CDlJmB;EAGR,IAAA,EAAA,MAAA;EAGN,KAAA,EC8IH,MD9IG;EACa,OAAA,EC8Id,YD9Ic;EACJ,WAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EC+IgB,YD/IhB;;UCsJV,KAAA;WACA;WACA;EAhKoB,KAMT,EA2Jb,eA3Ja;;;;UCRI,aAAA;;;;OAInB;;;;UAIG;;;;QAIF;AFZ6B;;;;;;AFAX,UKMA,YAAA,CLHR;;;;;;;;AEHmB;EAKnB,IAAA,CAAA,EAAA,CAAA,KAAA,EGWR,aHXQ,EAAA,GGYX,QHZW,GAAA,SAAA,GAAA,IAAA,GGYmB,OHZnB,CGY2B,QHZ3B,GAAA,SAAA,GAAA,IAAA,CAAA;EAGN;;;EAES,SAAA,CAAA,EGWP,SHXO;;;;ECRU,IAMT,CAAA,EEkBb,WFlBa,EAAA,GAAA,CAAA,CAAA,KAAA,EEkBY,aFlBZ,EAAA,GEkB8B,WFlB9B,EAAA,CAAA;;AACZ,KEoBJ,WAAA,GAAc,YFpBV,GEoByB,WFpBzB;UEsBC,YAAA,CFbQ;EAemC,KAAA,EAAA,MAAA;;UEE3C,WAAA,CFoBoC;EAAA,IAAA,EAAA,MAAA;EAAA,OA6FxC,EAAA,MAAA;;;;UGjJmB,eAAA;;;;OAInB;;;;UAIG;;;AJX2B;;EAQzB,OAAA,EIUD,MJVC,CAAA,MAAA,EAAA,GAAA,CAAA;EACa;;;WIad;;;AHpBoB;EAOrB,OAAA,EGkBC,YHlBD;EASS;;;EAqC4B,OAAA,EGxBpC,YHwBoC;EAAA;AAAA;;EAgGpC,OAAA,EGpHA,MHoHA,CGpHO,WHoHP,EAAA,GAAA,CAAA;;;;KIrJL,gBAAA,WACG,oBACH,8BAA8B,QAAQ;;;KCFtC,cAAA,WACG,oBACH,8BAA8B,QAAQ;;;;;;ARJlB,USMA,kBAAA,CTHR;;;;MCHQ,CAAA,EQUjB,cRViB;;;;ECAW,OAEX,CAAA,EOYd,MPZc,CAAA,MAAA,EOYC,gBPZD,CAAA;;;;KQApB,aAAA,WACG,oBACH,8BAA8B,QAAQ;;;;;;KCCtC,cAAA;MXLoB,EAAA,MAAA,CAAA,EWKc,aXLd;;;;;QWSlB;;;ATT6B;EAKnB,IAAA,CAAA,ESQT,aTRS;EAGN;;;EAES,KAAA,CAAA,ESOX,aTPW;;;;ECRU,GAMT,CAAA,EQad,aRbc;EACZ;;;EA8CmB,GAAA,CAAA,EQ9BrB,aR8BqB;EAAkB;;AAAA;EA+FtC,OAAA,CAAA,EQzHG,aRyHH;EACE;;;EAE0B,IAO1B,CAAA,EQ/HF,aR+HE;CACA;;;;;;US5Je,UAAA;;;;mBAIP,oBAAoB"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./pathToRegex-
|
|
2
|
-
import {
|
|
1
|
+
import "./pathToRegex-BTPkBIYJ.js";
|
|
2
|
+
import { a as LAYOUT_SERVER_ROUTE, c as SERVER_ROUTE, i as LAYOUT_ROUTE, l as Router, n as HOOK_ROUTE, o as PAGE_ROUTE, r as HOOK_SERVER_ROUTE, s as PAGE_SERVER_ROUTE, t as ERROR_ROUTE } from "./RouteType-VOBjKJ8I.js";
|
|
3
3
|
import { promises } from "node:fs";
|
|
4
4
|
import fpath from "node:path";
|
|
5
5
|
import tsconfigPaths from "vite-tsconfig-paths";
|
package/dist/nav.js
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
|
-
import { $page_default
|
|
1
|
+
import { n as internal, t as $page_default } from "./_page-B8QZDML_.js";
|
|
2
2
|
import { clearLayoutSlot, fillLayoutSlot, hydrate, mount } from "@torpor/view";
|
|
3
3
|
|
|
4
4
|
//#region src/state/client.ts
|
|
5
5
|
const client = internal().client;
|
|
6
6
|
var client_default = client;
|
|
7
7
|
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/nav/reload.ts
|
|
10
|
+
/**
|
|
11
|
+
* Reloads data for the currently loaded page and rerenders it.
|
|
12
|
+
*/
|
|
13
|
+
async function reload() {
|
|
14
|
+
return await navigate(new URL(document.location.href));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/nav/formSubmit.ts
|
|
19
|
+
async function formSubmit(e) {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
$page_default.form = void 0;
|
|
22
|
+
const form = e.target;
|
|
23
|
+
const options = {
|
|
24
|
+
body: new FormData(form),
|
|
25
|
+
method: "POST",
|
|
26
|
+
mode: "cors",
|
|
27
|
+
credentials: "same-origin",
|
|
28
|
+
headers: { "x-torpor-form-submit": "" }
|
|
29
|
+
};
|
|
30
|
+
const response = await fetch(form.action, options);
|
|
31
|
+
if (response.status === 200 && response.headers.has("x-torpor-form-redirect")) {
|
|
32
|
+
const redirect = response.headers.get("location");
|
|
33
|
+
await load(redirect);
|
|
34
|
+
window.location.href = redirect;
|
|
35
|
+
} else if (response.status >= 200 && response.status <= 299 || response.status >= 400 && response.status <= 499) {
|
|
36
|
+
if (response.headers.get("content-type") === "application/json") $page_default.form = await response.json();
|
|
37
|
+
await reload();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
8
41
|
//#endregion
|
|
9
42
|
//#region src/nav/loadData.ts
|
|
10
43
|
async function loadData(handler, params, path, newLayoutStack, clientEndPoint, serverEndPoint, prefetch = false) {
|
|
@@ -23,7 +56,7 @@ async function loadData(handler, params, path, newLayoutStack, clientEndPoint, s
|
|
|
23
56
|
path: layoutPath,
|
|
24
57
|
data: {},
|
|
25
58
|
reuse: false,
|
|
26
|
-
|
|
59
|
+
slotRegion: null
|
|
27
60
|
};
|
|
28
61
|
const layoutEndPoint = (await layout.endPoint())?.default;
|
|
29
62
|
const layoutServerEndPoint = layout.serverEndPoint && (await layout.serverEndPoint())?.default;
|
|
@@ -40,8 +73,7 @@ async function loadClientAndServerData(data, location, params, clientEndPoint, s
|
|
|
40
73
|
let prefetchedData = client_default.prefetchedData;
|
|
41
74
|
if (clientEndPoint?.load) if (prefetchedData[location]) Object.assign(data, prefetchedData[location]);
|
|
42
75
|
else {
|
|
43
|
-
const
|
|
44
|
-
const clientParams = buildClientParams(clientUrl, params, data);
|
|
76
|
+
const clientParams = buildClientParams(new URL(document.location.href), params, data);
|
|
45
77
|
const clientResponse = await clientEndPoint.load(clientParams);
|
|
46
78
|
if (clientResponse) if (clientResponse.ok) {
|
|
47
79
|
if (clientResponse.headers.get("Content-Type")?.includes("application/json")) {
|
|
@@ -84,7 +116,6 @@ async function navigate(url, withHydration = false) {
|
|
|
84
116
|
}
|
|
85
117
|
const path = url.pathname;
|
|
86
118
|
const query = url.searchParams;
|
|
87
|
-
console.log(`navigating to '${path}'${query.size ? ` with ${query}` : ""}`);
|
|
88
119
|
const route = client_default.router.match(path, query);
|
|
89
120
|
if (!route) {
|
|
90
121
|
console.log("404");
|
|
@@ -113,15 +144,14 @@ async function navigate(url, withHydration = false) {
|
|
|
113
144
|
$page_default.form = form;
|
|
114
145
|
formInput.remove();
|
|
115
146
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
};
|
|
147
|
+
let $props = { data };
|
|
148
|
+
$props.form = $page_default.form;
|
|
149
|
+
const $context = { TorporBuildContext: { onformsubmit: formSubmit } };
|
|
120
150
|
client_default.layoutStack.push({
|
|
121
151
|
path: route.handler.path,
|
|
122
152
|
data: {},
|
|
123
153
|
reuse: false,
|
|
124
|
-
|
|
154
|
+
slotRegion: null
|
|
125
155
|
});
|
|
126
156
|
client_default.layoutStack = newLayoutStack;
|
|
127
157
|
let layoutStack = client_default.layoutStack;
|
|
@@ -129,22 +159,22 @@ async function navigate(url, withHydration = false) {
|
|
|
129
159
|
let slots = void 0;
|
|
130
160
|
if (handler.layouts) {
|
|
131
161
|
let slotFunctions = [];
|
|
132
|
-
slotFunctions[handler.layouts.length] = function clientComponent(parent$1, anchor
|
|
162
|
+
slotFunctions[handler.layouts.length] = function clientComponent(parent$1, anchor) {
|
|
133
163
|
let i = layoutStack.length - 1;
|
|
134
|
-
layoutStack[i].
|
|
164
|
+
layoutStack[i].slotRegion = fillLayoutSlot(clientEndPoint.component, slotFunctions[i + 1], parent$1, anchor, $props, $context);
|
|
135
165
|
};
|
|
136
166
|
for (let i = handler.layouts.length - 1; i >= 0; i--) {
|
|
137
167
|
const layoutEndPoint = (await handler.layouts[i].endPoint())?.default;
|
|
138
168
|
if (layoutEndPoint?.component) if (layoutStack[i].reuse) {
|
|
139
|
-
parent = layoutStack[i].
|
|
140
|
-
clearLayoutSlot(layoutStack[i].
|
|
169
|
+
parent = layoutStack[i].slotRegion.startNode.parentNode;
|
|
170
|
+
clearLayoutSlot(layoutStack[i].slotRegion);
|
|
141
171
|
component = slotFunctions[i + 1];
|
|
142
172
|
break;
|
|
143
173
|
} else if (i === 0) {
|
|
144
174
|
component = layoutEndPoint.component;
|
|
145
175
|
slots = { _: slotFunctions[i + 1] };
|
|
146
|
-
} else slotFunctions[i] = function layoutComponent(parent$1, anchor, _, $context) {
|
|
147
|
-
layoutStack[i - 1].
|
|
176
|
+
} else slotFunctions[i] = function layoutComponent(parent$1, anchor, _, $context$1) {
|
|
177
|
+
layoutStack[i - 1].slotRegion = fillLayoutSlot(layoutEndPoint.component, slotFunctions[i + 1], parent$1, anchor, $props, $context$1);
|
|
148
178
|
};
|
|
149
179
|
}
|
|
150
180
|
}
|
|
@@ -165,18 +195,7 @@ async function navigate(url, withHydration = false) {
|
|
|
165
195
|
* Loads and renders the page at the supplied path.
|
|
166
196
|
*/
|
|
167
197
|
async function load(path) {
|
|
168
|
-
|
|
169
|
-
return await navigate(url);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
//#endregion
|
|
173
|
-
//#region src/nav/reload.ts
|
|
174
|
-
/**
|
|
175
|
-
* Reloads data for the currently loaded page and rerenders it.
|
|
176
|
-
*/
|
|
177
|
-
async function reload() {
|
|
178
|
-
const url = new URL(document.location.href);
|
|
179
|
-
return await navigate(url);
|
|
198
|
+
return await navigate(new URL(path, document.location.href));
|
|
180
199
|
}
|
|
181
200
|
|
|
182
201
|
//#endregion
|
package/dist/nav.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav.js","names":["client: ClientState","client","layoutEndPoint: PageEndPoint | undefined","layoutServerEndPoint: PageServerEndPoint | undefined","client","clientEndPoint: PageEndPoint | undefined","serverEndPoint: PageServerEndPoint | undefined","newLayoutStack: LayoutPath[]","form: Record<string, string> | undefined","$props: Record<string, any>","slots: Record<string, SlotRender> | undefined","slotFunctions: SlotRender[]","parent","layoutEndPoint: PageEndPoint | undefined"],"sources":["../src/state/client.ts","../src/nav/loadData.ts","../src/nav/navigate.ts","../src/nav/load.ts","../src/nav/reload.ts"],"sourcesContent":["import type ClientState from \"../types/ClientState\";\nimport internal from \"./internal\";\n\nconst client: ClientState = internal().client;\n\nexport default client;\n","import client from \"../state/client\";\nimport type LayoutPath from \"../types/LayoutPath\";\nimport type PageEndPoint from \"../types/PageEndPoint\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport type RouteHandler from \"../types/RouteHandler\";\n\nexport default async function loadData(\n\thandler: RouteHandler,\n\tparams: Record<string, string>,\n\tpath: string,\n\tnewLayoutStack: LayoutPath[],\n\tclientEndPoint: PageEndPoint | undefined,\n\tserverEndPoint: PageServerEndPoint | undefined,\n\tprefetch = false,\n): Promise<Record<string, string> | void> {\n\tlet data = {};\n\tif (handler.layouts) {\n\t\tlet layoutStack = client.layoutStack;\n\t\tfor (let [i, layout] of handler.layouts.entries()) {\n\t\t\tlet layoutPath = layout.path;\n\t\t\tfor (let key in params) {\n\t\t\t\tlayoutPath = layoutPath.replace(`[${key}]`, params[key]);\n\t\t\t}\n\t\t\tif (layoutStack.at(i)?.path === layoutPath) {\n\t\t\t\t// We've already loaded this layout, we can just re-use its data and UI\n\t\t\t\tif (!prefetch) {\n\t\t\t\t\tlayoutStack[i].reuse = true;\n\t\t\t\t}\n\t\t\t\tnewLayoutStack[i] = layoutStack[i];\n\t\t\t\tObject.assign(data, layoutStack[i].data);\n\t\t\t} else {\n\t\t\t\tconst stackLayout = { path: layoutPath, data: {}, reuse: false, slotRange: null };\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\tstackLayout.data,\n\t\t\t\t\tdocument.location.origin + layoutPath,\n\t\t\t\t\tparams,\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;\n\t\t\t\t}\n\t\t\t\tObject.assign(data, stackLayout.data);\n\t\t\t\tnewLayoutStack.push(stackLayout);\n\t\t\t}\n\t\t}\n\t}\n\tlet endPointResponse = await loadClientAndServerData(\n\t\tdata,\n\t\tdocument.location.origin + path,\n\t\tparams,\n\t\tclientEndPoint,\n\t\tserverEndPoint,\n\t);\n\tif (endPointResponse?.ok === false) {\n\t\treturn;\n\t}\n\treturn data;\n}\n\nasync function loadClientAndServerData(\n\tdata: Record<string, any>,\n\tlocation: string,\n\tparams: Record<string, string>,\n\tclientEndPoint?: PageEndPoint,\n\tserverEndPoint?: PageServerEndPoint,\n): Promise<Response | undefined | void> {\n\tlet prefetchedData = client.prefetchedData;\n\n\tif (clientEndPoint?.load) {\n\t\tif (prefetchedData[location]) {\n\t\t\tObject.assign(data, prefetchedData[location]);\n\t\t} else {\n\t\t\tconst clientUrl = new URL(document.location.href);\n\t\t\tconst clientParams = buildClientParams(clientUrl, params, data);\n\t\t\tconst clientResponse = await clientEndPoint.load(clientParams);\n\t\t\tif (clientResponse) {\n\t\t\t\tif (clientResponse.ok) {\n\t\t\t\t\tif (clientResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t\tconst clientData = await clientResponse.json();\n\t\t\t\t\t\tObject.assign(data, clientData);\n\t\t\t\t\t\tprefetchedData[location] = clientData;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn clientResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (serverEndPoint?.load) {\n\t\tconst serverUrl = location.replace(/\\/$/, \"\") + \"/~server\";\n\n\t\tif (prefetchedData[serverUrl]) {\n\t\t\tObject.assign(data, prefetchedData[serverUrl]);\n\t\t} else {\n\t\t\tconst serverResponse = await fetch(serverUrl);\n\t\t\tif (serverResponse) {\n\t\t\t\tif (serverResponse.ok) {\n\t\t\t\t\tif (serverResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t\tconst serverData = await serverResponse.json();\n\t\t\t\t\t\tObject.assign(data, serverData);\n\t\t\t\t\t\tprefetchedData[serverUrl] = serverData;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn serverResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction buildClientParams(url: URL, params: Record<string, string>, data: Record<string, any>) {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tdata,\n\t};\n}\n","import { clearLayoutSlot, fillLayoutSlot, hydrate } from \"@torpor/view\";\nimport { type Component, type SlotRender } from \"@torpor/view\";\nimport { mount } from \"@torpor/view\";\nimport $page from \"../state/$page\";\nimport client from \"../state/client\";\nimport type LayoutPath from \"../types/LayoutPath\";\nimport type PageEndPoint from \"../types/PageEndPoint\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport loadData from \"./loadData\";\n\n// @ts-ignore\nexport default async function navigate(url: URL, withHydration = false): Promise<boolean> {\n\tlet parent = document.getElementById(\"app\");\n\tif (!parent) {\n\t\t// TODO: 500\n\t\tconsole.log(\"500\");\n\t\treturn false;\n\t}\n\n\tconst path = url.pathname;\n\tconst query = url.searchParams;\n\n\tconsole.log(`navigating to '${path}'${query.size ? ` with ${query}` : \"\"}`);\n\n\tconst route = client.router.match(path, query);\n\tif (!route) {\n\t\t// TODO: 404\n\t\tconsole.log(\"404\");\n\t\treturn false;\n\t}\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\t// Make it look a bit classier by removing the query\n\t\twindow.history.replaceState({}, \"\", url.toString().split(\"?\")[0]);\n\t} else {\n\t\t$page.status = 200;\n\t}\n\n\tconst handler = route.handler;\n\tconst params = route.params || {};\n\n\t// There must be a client endpoint with a component\n\tconst clientEndPoint: PageEndPoint | undefined = (await handler.endPoint()).default;\n\tif (!clientEndPoint?.component) {\n\t\t// TODO: 404\n\t\tconsole.log(\"404\");\n\t\treturn false;\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\tlet newLayoutStack: LayoutPath[] = [];\n\n\t// Pass the data into $props\n\t// TODO: Don't load if this is the first time -- it should have been passed\n\t// to us, somehow...\n\tconst data = await loadData(\n\t\thandler,\n\t\tparams,\n\t\tpath,\n\t\tnewLayoutStack,\n\t\tclientEndPoint,\n\t\tserverEndPoint,\n\t);\n\t// We may have form data in a hidden input -- not sure if this is the best\n\t// way to do it\n\tlet formInput = document.getElementById(\"t-form-data\") as HTMLInputElement;\n\tlet form: Record<string, string> | undefined;\n\tif (formInput) {\n\t\tform = JSON.parse(formInput.value);\n\t\t$page.form = form;\n\t\tformInput.remove();\n\t}\n\tconst $props: Record<string, any> = { data, form };\n\n\tclient.layoutStack.push({ path: route.handler.path, data: {}, reuse: false, slotRange: null });\n\tclient.layoutStack = newLayoutStack;\n\tlet layoutStack = client.layoutStack;\n\n\t// If there are layouts, work our way upwards, pushing each component into\n\t// the default slot of its parent\n\t// TODO: There's probably a nicer way to do this with reducers or something\n\tlet component = clientEndPoint.component as Component;\n\tlet slots: Record<string, SlotRender> | undefined = undefined;\n\tif (handler.layouts) {\n\t\tlet slotFunctions: SlotRender[] = [];\n\t\t// The last slot function will render the client component\n\t\tslotFunctions[handler.layouts.length] = function clientComponent(parent, anchor, _, $context) {\n\t\t\tlet i = layoutStack.length - 1;\n\t\t\tlayoutStack[i].slotRange = fillLayoutSlot(\n\t\t\t\tclientEndPoint.component!,\n\t\t\t\tslotFunctions[i + 1],\n\t\t\t\tparent,\n\t\t\t\tanchor,\n\t\t\t\t$props,\n\t\t\t\t$context,\n\t\t\t);\n\t\t};\n\n\t\t// Each earlier slot function will render a layout\n\t\tfor (let i = handler.layouts.length - 1; i >= 0; i--) {\n\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await handler.layouts[i].endPoint())\n\t\t\t\t?.default;\n\t\t\tif (layoutEndPoint?.component) {\n\t\t\t\tif (layoutStack[i].reuse) {\n\t\t\t\t\t// Set the parent to add the new content to (from the old\n\t\t\t\t\t// content), clear the range under this point, and set the\n\t\t\t\t\t// component to the slot function within this layout\n\t\t\t\t\tparent = layoutStack[i].slotRange.startNode.parentNode as HTMLElement;\n\t\t\t\t\tclearLayoutSlot(layoutStack[i].slotRange);\n\t\t\t\t\tcomponent = slotFunctions[i + 1];\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (i === 0) {\n\t\t\t\t\tcomponent = layoutEndPoint.component as Component;\n\t\t\t\t\tslots = { _: slotFunctions[i + 1] };\n\t\t\t\t} else {\n\t\t\t\t\tslotFunctions[i] = function layoutComponent(parent, anchor, _, $context) {\n\t\t\t\t\t\tlayoutStack[i - 1].slotRange = fillLayoutSlot(\n\t\t\t\t\t\t\tlayoutEndPoint.component!,\n\t\t\t\t\t\t\tslotFunctions[i + 1],\n\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\tanchor,\n\t\t\t\t\t\t\t$props,\n\t\t\t\t\t\t\t$context,\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\t}\n\n\tif (withHydration) {\n\t\thydrate(parent, component, $props, slots);\n\t} else {\n\t\ttry {\n\t\t\tmount(parent, component, $props, slots);\n\t\t} catch (error) {\n\t\t\t// TODO: Show a proper Error component\n\t\t\tparent.innerHTML = '<span style=\"color: red\">Script syntax error</span><p>' + error + \"</p>\";\n\t\t\tconsole.log(error);\n\t\t}\n\t}\n\n\t// Reset prefetched data on each navigation\n\tclient.prefetchedData = {};\n\n\treturn true;\n}\n","import navigate from \"./navigate\";\n\n/**\n * Loads and renders the page at the supplied path.\n */\nexport default async function load(path: string): Promise<boolean> {\n\tconst url = new URL(path, document.location.href);\n\treturn await navigate(url);\n}\n","import navigate from \"./navigate\";\n\n/**\n * Reloads data for the currently loaded page and rerenders it.\n */\nexport default async function reload(): Promise<boolean> {\n\tconst url = new URL(document.location.href);\n\treturn await navigate(url);\n}\n"],"mappings":";;;;AAGA,MAAMA,SAAsB,UAAU,CAAC;AAEvC,qBAAe;;;;ACCf,eAA8B,SAC7B,SACA,QACA,MACA,gBACA,gBACA,gBACA,WAAW,OAC8B;CACzC,IAAI,OAAO,EAAE;AACb,KAAI,QAAQ,SAAS;EACpB,IAAI,cAAcC,eAAO;AACzB,OAAK,IAAI,CAAC,GAAG,WAAW,QAAQ,QAAQ,SAAS,EAAE;GAClD,IAAI,aAAa,OAAO;AACxB,QAAK,IAAI,OAAO,OACf,cAAa,WAAW,QAAQ,IAAI,IAAI,IAAI,OAAO,KAAK;AAEzD,OAAI,YAAY,GAAG,EAAE,EAAE,SAAS,YAAY;AAE3C,QAAI,CAAC,SACJ,aAAY,GAAG,QAAQ;AAExB,mBAAe,KAAK,YAAY;AAChC,WAAO,OAAO,MAAM,YAAY,GAAG,KAAK;UAClC;IACN,MAAM,cAAc;KAAE,MAAM;KAAY,MAAM,EAAE;KAAE,OAAO;KAAO,WAAW;KAAM;IACjF,MAAMC,kBAA4C,MAAM,OAAO,UAAU,GAAG;IAC5E,MAAMC,uBACL,OAAO,mBAAmB,MAAM,OAAO,gBAAgB,GAAG;AAQ3D,SAPuB,MAAM,wBAC5B,YAAY,MACZ,SAAS,SAAS,SAAS,YAC3B,QACA,gBACA,qBACA,GACmB,OAAO,MAC1B;AAED,WAAO,OAAO,MAAM,YAAY,KAAK;AACrC,mBAAe,KAAK,YAAY;;;;AAWnC,MAPuB,MAAM,wBAC5B,MACA,SAAS,SAAS,SAAS,MAC3B,QACA,gBACA,eACA,GACqB,OAAO,MAC5B;AAED,QAAO;;AAGR,eAAe,wBACd,MACA,UACA,QACA,gBACA,gBACuC;CACvC,IAAI,iBAAiBF,eAAO;AAE5B,KAAI,gBAAgB,KACnB,KAAI,eAAe,UAClB,QAAO,OAAO,MAAM,eAAe,UAAU;MACvC;EACN,MAAM,YAAY,IAAI,IAAI,SAAS,SAAS,KAAK;EACjD,MAAM,eAAe,kBAAkB,WAAW,QAAQ,KAAK;EAC/D,MAAM,iBAAiB,MAAM,eAAe,KAAK,aAAa;AAC9D,MAAI,eACH,KAAI,eAAe,IAClB;OAAI,eAAe,QAAQ,IAAI,eAAe,EAAE,SAAS,mBAAmB,EAAE;IAC7E,MAAM,aAAa,MAAM,eAAe,MAAM;AAC9C,WAAO,OAAO,MAAM,WAAW;AAC/B,mBAAe,YAAY;;QAG5B,QAAO;;AAKX,KAAI,gBAAgB,MAAM;EACzB,MAAM,YAAY,SAAS,QAAQ,OAAO,GAAG,GAAG;AAEhD,MAAI,eAAe,WAClB,QAAO,OAAO,MAAM,eAAe,WAAW;OACxC;GACN,MAAM,iBAAiB,MAAM,MAAM,UAAU;AAC7C,OAAI,eACH,KAAI,eAAe,IAClB;QAAI,eAAe,QAAQ,IAAI,eAAe,EAAE,SAAS,mBAAmB,EAAE;KAC7E,MAAM,aAAa,MAAM,eAAe,MAAM;AAC9C,YAAO,OAAO,MAAM,WAAW;AAC/B,oBAAe,aAAa;;SAG7B,QAAO;;;;AAOZ,SAAS,kBAAkB,KAAU,QAAgC,MAA2B;AAC/F,QAAO;EACN;EACA;EACA;EACA;;;;;AC5GF,eAA8B,SAAS,KAAU,gBAAgB,OAAyB;CACzF,IAAI,SAAS,SAAS,eAAe,MAAM;AAC3C,KAAI,CAAC,QAAQ;AAEZ,UAAQ,IAAI,MAAM;AAClB,SAAO;;CAGR,MAAM,OAAO,IAAI;CACjB,MAAM,QAAQ,IAAI;AAElB,SAAQ,IAAI,kBAAkB,KAAK,GAAG,MAAM,OAAO,SAAS,UAAU,KAAK;CAE3E,MAAM,QAAQG,eAAO,OAAO,MAAM,MAAM,MAAM;AAC9C,KAAI,CAAC,OAAO;AAEX,UAAQ,IAAI,MAAM;AAClB,SAAO;;AAIR,eAAM,MAAM;AACZ,KAAI,KAAK,SAAS,UAAU,EAAE;AAC7B,gBAAM,SAAS,SAAS,MAAM,IAAI,SAAS,IAAI,MAAM;AACrD,gBAAM,QAAQ,EAAE,SAAS,MAAM,IAAI,UAAU,IAAI,IAAI;AAErD,SAAO,QAAQ,aAAa,EAAE,EAAE,IAAI,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG;OAEjE,eAAM,SAAS;CAGhB,MAAM,UAAU,MAAM;CACtB,MAAM,SAAS,MAAM,UAAU,EAAE;CAGjC,MAAMC,kBAA4C,MAAM,QAAQ,UAAU,EAAE;AAC5E,KAAI,CAAC,gBAAgB,WAAW;AAE/B,UAAQ,IAAI,MAAM;AAClB,SAAO;;CAIR,MAAMC,iBACL,QAAQ,mBAAmB,MAAM,QAAQ,gBAAgB,GAAG;CAE7D,IAAIC,iBAA+B,EAAE;CAKrC,MAAM,OAAO,MAAM,SAClB,SACA,QACA,MACA,gBACA,gBACA,eACA;CAGD,IAAI,YAAY,SAAS,eAAe,cAAc;CACtD,IAAIC;AACJ,KAAI,WAAW;AACd,SAAO,KAAK,MAAM,UAAU,MAAM;AAClC,gBAAM,OAAO;AACb,YAAU,QAAQ;;CAEnB,MAAMC,SAA8B;EAAE;EAAM;EAAM;AAElD,gBAAO,YAAY,KAAK;EAAE,MAAM,MAAM,QAAQ;EAAM,MAAM,EAAE;EAAE,OAAO;EAAO,WAAW;EAAM,CAAC;AAC9F,gBAAO,cAAc;CACrB,IAAI,cAAcL,eAAO;CAKzB,IAAI,YAAY,eAAe;CAC/B,IAAIM,QAAgD;AACpD,KAAI,QAAQ,SAAS;EACpB,IAAIC,gBAA8B,EAAE;AAEpC,gBAAc,QAAQ,QAAQ,UAAU,SAAS,gBAAgB,UAAQ,QAAQ,GAAG,UAAU;GAC7F,IAAI,IAAI,YAAY,SAAS;AAC7B,eAAY,GAAG,YAAY,eAC1B,eAAe,WACf,cAAc,IAAI,IAClBC,UACA,QACA,QACA,SACA;;AAIF,OAAK,IAAI,IAAI,QAAQ,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;GACrD,MAAMC,kBAA4C,MAAM,QAAQ,QAAQ,GAAG,UAAU,GAClF;AACH,OAAI,gBAAgB,UACnB,KAAI,YAAY,GAAG,OAAO;AAIzB,aAAS,YAAY,GAAG,UAAU,UAAU;AAC5C,oBAAgB,YAAY,GAAG,UAAU;AACzC,gBAAY,cAAc,IAAI;AAC9B;cACU,MAAM,GAAG;AACnB,gBAAY,eAAe;AAC3B,YAAQ,EAAE,GAAG,cAAc,IAAI,IAAI;SAEnC,eAAc,KAAK,SAAS,gBAAgB,UAAQ,QAAQ,GAAG,UAAU;AACxE,gBAAY,IAAI,GAAG,YAAY,eAC9B,eAAe,WACf,cAAc,IAAI,IAClBD,UACA,QACA,QACA,SACA;;;;AAON,KAAI,cACH,SAAQ,QAAQ,WAAW,QAAQ,MAAM;KAEzC,KAAI;AACH,QAAM,QAAQ,WAAW,QAAQ,MAAM;UAC/B,OAAO;AAEf,SAAO,YAAY,6DAA2D,QAAQ;AACtF,UAAQ,IAAI,MAAM;;AAKpB,gBAAO,iBAAiB,EAAE;AAE1B,QAAO;;;;;;;;ACnJR,eAA8B,KAAK,MAAgC;CAClE,MAAM,MAAM,IAAI,IAAI,MAAM,SAAS,SAAS,KAAK;AACjD,QAAO,MAAM,SAAS,IAAI;;;;;;;;ACF3B,eAA8B,SAA2B;CACxD,MAAM,MAAM,IAAI,IAAI,SAAS,SAAS,KAAK;AAC3C,QAAO,MAAM,SAAS,IAAI"}
|
|
1
|
+
{"version":3,"file":"nav.js","names":["client: ClientState","client","layoutEndPoint: PageEndPoint | undefined","layoutServerEndPoint: PageServerEndPoint | undefined","client","clientEndPoint: PageEndPoint | undefined","serverEndPoint: PageServerEndPoint | undefined","newLayoutStack: LayoutPath[]","form: Record<string, string> | undefined","$props: Record<string, any>","$page","slots: Record<string, SlotRender> | undefined","slotFunctions: SlotRender[]","parent","layoutEndPoint: PageEndPoint | undefined","$context"],"sources":["../src/state/client.ts","../src/nav/reload.ts","../src/nav/formSubmit.ts","../src/nav/loadData.ts","../src/nav/navigate.ts","../src/nav/load.ts"],"sourcesContent":["import type ClientState from \"../types/ClientState\";\nimport internal from \"./internal\";\n\nconst client: ClientState = internal().client;\n\nexport default client;\n","import navigate from \"./navigate\";\n\n/**\n * Reloads data for the currently loaded page and rerenders it.\n */\nexport default async function reload(): Promise<boolean> {\n\tconst url = new URL(document.location.href);\n\treturn await navigate(url);\n}\n","import $page from \"../state/$page\";\nimport load from \"./load\";\nimport reload from \"./reload\";\n\nexport default async function formSubmit(e: SubmitEvent): Promise<void> {\n\t// We'll take it from here\n\te.preventDefault();\n\n\t// Reset $page on submit and link navigation\n\t// TODO: Should we put data in $page.data??\n\t$page.form = undefined;\n\n\t// Perform a POST fetch to the form's action location\n\tconst form = e.target as HTMLFormElement;\n\tconst options = {\n\t\tbody: new FormData(form),\n\t\tmethod: \"POST\",\n\t\tmode: \"cors\",\n\t\tcredentials: \"same-origin\",\n\t\t// Add a special header which tells the server that we want the raw\n\t\t// error response (if applicable) rather than the reloaded page that you\n\t\t// would get if submitting a page without javascript\n\t\theaders: {\n\t\t\t\"x-torpor-form-submit\": \"\",\n\t\t},\n\t};\n\tconst response = await fetch(\n\t\tform.action,\n\t\t// @ts-ignore -- don't know what it's complaining about here\n\t\toptions,\n\t);\n\n\tif (response.status === 200 && response.headers.has(\"x-torpor-form-redirect\")) {\n\t\t// TODO: Should do the correct type of redirect e.g. seeOther etc\n\t\tconst redirect = response.headers.get(\"location\")!;\n\t\tawait load(redirect);\n\t\twindow.location.href = redirect;\n\t} else if (\n\t\t(response.status >= 200 && response.status <= 299) ||\n\t\t(response.status >= 400 && response.status <= 499)\n\t) {\n\t\t// Put the response into `$page.form`, and it will be put into `$props` in reload\n\t\tif (response.headers.get(\"content-type\") === \"application/json\") {\n\t\t\t$page.form = await response.json();\n\t\t}\n\t\tawait reload();\n\t}\n}\n","import client from \"../state/client\";\nimport type LayoutPath from \"../types/LayoutPath\";\nimport type PageEndPoint from \"../types/PageEndPoint\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport type RouteHandler from \"../types/RouteHandler\";\n\nexport default async function loadData(\n\thandler: RouteHandler,\n\tparams: Record<string, string>,\n\tpath: string,\n\tnewLayoutStack: LayoutPath[],\n\tclientEndPoint: PageEndPoint | undefined,\n\tserverEndPoint: PageServerEndPoint | undefined,\n\tprefetch = false,\n): Promise<Record<string, string> | void> {\n\tlet data = {};\n\tif (handler.layouts) {\n\t\tlet layoutStack = client.layoutStack;\n\t\tfor (let [i, layout] of handler.layouts.entries()) {\n\t\t\tlet layoutPath = layout.path;\n\t\t\tfor (let key in params) {\n\t\t\t\tlayoutPath = layoutPath.replace(`[${key}]`, params[key]);\n\t\t\t}\n\t\t\tif (layoutStack.at(i)?.path === layoutPath) {\n\t\t\t\t// We've already loaded this layout, we can just re-use its data and UI\n\t\t\t\tif (!prefetch) {\n\t\t\t\t\tlayoutStack[i].reuse = true;\n\t\t\t\t}\n\t\t\t\tnewLayoutStack[i] = layoutStack[i];\n\t\t\t\tObject.assign(data, layoutStack[i].data);\n\t\t\t} else {\n\t\t\t\tconst stackLayout = { path: layoutPath, data: {}, reuse: false, slotRegion: null };\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\tstackLayout.data,\n\t\t\t\t\tdocument.location.origin + layoutPath,\n\t\t\t\t\tparams,\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;\n\t\t\t\t}\n\t\t\t\tObject.assign(data, stackLayout.data);\n\t\t\t\tnewLayoutStack.push(stackLayout);\n\t\t\t}\n\t\t}\n\t}\n\tlet endPointResponse = await loadClientAndServerData(\n\t\tdata,\n\t\tdocument.location.origin + path,\n\t\tparams,\n\t\tclientEndPoint,\n\t\tserverEndPoint,\n\t);\n\tif (endPointResponse?.ok === false) {\n\t\treturn;\n\t}\n\treturn data;\n}\n\nasync function loadClientAndServerData(\n\tdata: Record<string, any>,\n\tlocation: string,\n\tparams: Record<string, string>,\n\tclientEndPoint?: PageEndPoint,\n\tserverEndPoint?: PageServerEndPoint,\n): Promise<Response | undefined | void> {\n\tlet prefetchedData = client.prefetchedData;\n\n\tif (clientEndPoint?.load) {\n\t\tif (prefetchedData[location]) {\n\t\t\tObject.assign(data, prefetchedData[location]);\n\t\t} else {\n\t\t\tconst clientUrl = new URL(document.location.href);\n\t\t\tconst clientParams = buildClientParams(clientUrl, params, data);\n\t\t\tconst clientResponse = await clientEndPoint.load(clientParams);\n\t\t\tif (clientResponse) {\n\t\t\t\tif (clientResponse.ok) {\n\t\t\t\t\tif (clientResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t\tconst clientData = await clientResponse.json();\n\t\t\t\t\t\tObject.assign(data, clientData);\n\t\t\t\t\t\tprefetchedData[location] = clientData;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn clientResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (serverEndPoint?.load) {\n\t\tconst serverUrl = location.replace(/\\/$/, \"\") + \"/~server\";\n\n\t\tif (prefetchedData[serverUrl]) {\n\t\t\tObject.assign(data, prefetchedData[serverUrl]);\n\t\t} else {\n\t\t\tconst serverResponse = await fetch(serverUrl);\n\t\t\tif (serverResponse) {\n\t\t\t\tif (serverResponse.ok) {\n\t\t\t\t\tif (serverResponse.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\t\t\t\tconst serverData = await serverResponse.json();\n\t\t\t\t\t\tObject.assign(data, serverData);\n\t\t\t\t\t\tprefetchedData[serverUrl] = serverData;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn serverResponse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction buildClientParams(url: URL, params: Record<string, string>, data: Record<string, any>) {\n\treturn {\n\t\turl,\n\t\tparams,\n\t\tdata,\n\t};\n}\n","import { clearLayoutSlot, fillLayoutSlot, hydrate } from \"@torpor/view\";\nimport { type Component, type SlotRender } from \"@torpor/view\";\nimport { mount } from \"@torpor/view\";\nimport $page from \"../state/$page\";\nimport client from \"../state/client\";\nimport type LayoutPath from \"../types/LayoutPath\";\nimport type PageEndPoint from \"../types/PageEndPoint\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport formSubmit from \"./formSubmit\";\nimport loadData from \"./loadData\";\n\n// @ts-ignore\nexport default async function navigate(url: URL, withHydration = false): Promise<boolean> {\n\tlet parent = document.getElementById(\"app\");\n\tif (!parent) {\n\t\t// TODO: 500\n\t\tconsole.log(\"500\");\n\t\treturn false;\n\t}\n\n\tconst path = url.pathname;\n\tconst query = url.searchParams;\n\n\t//console.log(`navigating to '${path}'${query.size ? ` with ${query}` : \"\"}`);\n\n\tconst route = client.router.match(path, query);\n\tif (!route) {\n\t\t// TODO: 404\n\t\tconsole.log(\"404\");\n\t\treturn false;\n\t}\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\t// Make it look a bit classier by removing the query\n\t\twindow.history.replaceState({}, \"\", url.toString().split(\"?\")[0]);\n\t} else {\n\t\t$page.status = 200;\n\t}\n\tconst handler = route.handler;\n\tconst params = route.params || {};\n\n\t// There must be a client endpoint with a component\n\tconst clientEndPoint: PageEndPoint | undefined = (await handler.endPoint()).default;\n\tif (!clientEndPoint?.component) {\n\t\t// TODO: 404\n\t\tconsole.log(\"404\");\n\t\treturn false;\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\tlet newLayoutStack: LayoutPath[] = [];\n\n\t// Pass the data into $props\n\t// TODO: Don't load if this is the first time -- it should have been passed\n\t// to us, somehow...\n\tconst data = await loadData(\n\t\thandler,\n\t\tparams,\n\t\tpath,\n\t\tnewLayoutStack,\n\t\tclientEndPoint,\n\t\tserverEndPoint,\n\t);\n\t// We may have form data in a hidden input -- not sure if this is the best\n\t// way to do it\n\tlet formInput = document.getElementById(\"t-form-data\") as HTMLInputElement;\n\tlet form: Record<string, string> | undefined;\n\tif (formInput) {\n\t\tform = JSON.parse(formInput.value);\n\t\t$page.form = form;\n\t\tformInput.remove();\n\t}\n\tlet $props: Record<string, any> = { data };\n\n\t// We may have form data in $page.form, either from the hidden input\n\t// (above), or added via onformsubmit (below)\n\t$props.form = $page.form;\n\n\t// Add some special context for submitting Forms client-side\n\tconst $context = {\n\t\tTorporBuildContext: { onformsubmit: formSubmit },\n\t};\n\n\tclient.layoutStack.push({ path: route.handler.path, data: {}, reuse: false, slotRegion: null });\n\tclient.layoutStack = newLayoutStack;\n\tlet layoutStack = client.layoutStack;\n\n\t// If there are layouts, work our way upwards, pushing each component into\n\t// the default slot of its parent\n\t// TODO: There's probably a nicer way to do this with reducers or something\n\tlet component = clientEndPoint.component as Component;\n\tlet slots: Record<string, SlotRender> | undefined = undefined;\n\tif (handler.layouts) {\n\t\tlet slotFunctions: SlotRender[] = [];\n\t\t// The last slot function will render the client component\n\t\tslotFunctions[handler.layouts.length] = function clientComponent(parent, anchor) {\n\t\t\tlet i = layoutStack.length - 1;\n\t\t\tlayoutStack[i].slotRegion = fillLayoutSlot(\n\t\t\t\tclientEndPoint.component!,\n\t\t\t\tslotFunctions[i + 1],\n\t\t\t\tparent,\n\t\t\t\tanchor,\n\t\t\t\t$props,\n\t\t\t\t$context,\n\t\t\t);\n\t\t};\n\n\t\t// Each earlier slot function will render a layout\n\t\tfor (let i = handler.layouts.length - 1; i >= 0; i--) {\n\t\t\tconst layoutEndPoint: PageEndPoint | undefined = (await handler.layouts[i].endPoint())\n\t\t\t\t?.default;\n\t\t\tif (layoutEndPoint?.component) {\n\t\t\t\tif (layoutStack[i].reuse) {\n\t\t\t\t\t// Set the parent to add the new content to (from the old\n\t\t\t\t\t// content), clear the range under this point, and set the\n\t\t\t\t\t// component to the slot function within this layout\n\t\t\t\t\tparent = layoutStack[i].slotRegion.startNode.parentNode as HTMLElement;\n\t\t\t\t\tclearLayoutSlot(layoutStack[i].slotRegion);\n\t\t\t\t\tcomponent = slotFunctions[i + 1];\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (i === 0) {\n\t\t\t\t\tcomponent = layoutEndPoint.component as Component;\n\t\t\t\t\tslots = { _: slotFunctions[i + 1] };\n\t\t\t\t} else {\n\t\t\t\t\tslotFunctions[i] = function layoutComponent(parent, anchor, _, $context) {\n\t\t\t\t\t\tlayoutStack[i - 1].slotRegion = fillLayoutSlot(\n\t\t\t\t\t\t\tlayoutEndPoint.component!,\n\t\t\t\t\t\t\tslotFunctions[i + 1],\n\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\tanchor,\n\t\t\t\t\t\t\t$props,\n\t\t\t\t\t\t\t$context,\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\t}\n\n\tif (withHydration) {\n\t\thydrate(parent, component, $props, slots);\n\t} else {\n\t\ttry {\n\t\t\tmount(parent, component, $props, slots);\n\t\t} catch (error) {\n\t\t\t// TODO: Show a proper Error component\n\t\t\tparent.innerHTML = '<span style=\"color: red\">Script syntax error</span><p>' + error + \"</p>\";\n\t\t\tconsole.log(error);\n\t\t}\n\t}\n\n\t// Reset prefetched data on each navigation\n\tclient.prefetchedData = {};\n\n\treturn true;\n}\n","import navigate from \"./navigate\";\n\n/**\n * Loads and renders the page at the supplied path.\n */\nexport default async function load(path: string): Promise<boolean> {\n\tconst url = new URL(path, document.location.href);\n\treturn await navigate(url);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathToRegex-
|
|
1
|
+
{"version":3,"file":"pathToRegex-BTPkBIYJ.js","names":[],"sources":["../src/utils/pathToRegex.ts"],"sourcesContent":["export default function pathToRegex(path: string): RegExp {\n\tconst pattern =\n\t\tpath\n\t\t\t.split(\"/\")\n\t\t\t// Replace `[slug]` with a grouped match so we can pull out params\n\t\t\t.map((p) => {\n\t\t\t\treturn p.replace(/\\[([^/]+?)\\]/, \"(?<$1>[^\\\\/]+?)\");\n\t\t\t})\n\t\t\t.join(\"\\\\/\")\n\t\t\t// Replace globs with regex syntax\n\t\t\t.replaceAll(\"*\", \".*\") +\n\t\t// Ignore trailing slashes -- `/path` should be treated the same as `/path/`\n\t\t\"/*\";\n\treturn new RegExp(`^${pattern}/*$`);\n}\n"],"mappings":";AAAA,SAAwB,YAAY,MAAsB;CACzD,MAAM,UACL,KACE,MAAM,IAAI,CAEV,KAAK,MAAM;AACX,SAAO,EAAE,QAAQ,gBAAgB,kBAAkB;GAClD,CACD,KAAK,MAAM,CAEX,WAAW,KAAK,KAAK,GAEvB;AACD,wBAAO,IAAI,OAAO,IAAI,QAAQ,KAAK"}
|