@torpor/build 0.4.5 → 0.4.7

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{RouteType-VOBjKJ8I.js → RouteType-B6BMOyYw.mjs} +13 -12
  3. package/dist/RouteType-B6BMOyYw.mjs.map +1 -0
  4. package/dist/{Server-DL9neaq0.d.ts → Server-CF5wDJp6.d.mts} +1 -1
  5. package/dist/Server-CF5wDJp6.d.mts.map +1 -0
  6. package/dist/{ServerEvent-Dnk2FIKQ.js → ServerEvent-CxPwA4lH.mjs} +1 -1
  7. package/dist/ServerEvent-CxPwA4lH.mjs.map +1 -0
  8. package/dist/{Site-B8TxSzPk.d.ts → Site-DgC6WWn1.d.mts} +20 -9
  9. package/dist/Site-DgC6WWn1.d.mts.map +1 -0
  10. package/dist/{_page-ef72MjgG.js → _page-DBSsnHFG.mjs} +1 -1
  11. package/dist/_page-DBSsnHFG.mjs.map +1 -0
  12. package/dist/bin/index.js +7 -7
  13. package/dist/bin/index.js.map +1 -1
  14. package/dist/{connectMiddleware-PBcWWRr-.js → connectMiddleware-D7nehjj3.mjs} +3 -3
  15. package/dist/connectMiddleware-D7nehjj3.mjs.map +1 -0
  16. package/dist/{index.d.ts → index.d.mts} +11 -6
  17. package/dist/index.d.mts.map +1 -0
  18. package/dist/{index.js → index.mjs} +21 -12
  19. package/dist/index.mjs.map +1 -0
  20. package/dist/{nav.d.ts → nav.d.mts} +1 -1
  21. package/dist/nav.d.mts.map +1 -0
  22. package/dist/{nav.js → nav.mjs} +15 -11
  23. package/dist/nav.mjs.map +1 -0
  24. package/dist/{pathToRegex-BTPkBIYJ.js → pathToRegex-TUAMc3zS.mjs} +1 -1
  25. package/dist/pathToRegex-TUAMc3zS.mjs.map +1 -0
  26. package/dist/{response-KnPcsvtU.js → response-C5TtAsh1.mjs} +2 -2
  27. package/dist/response-C5TtAsh1.mjs.map +1 -0
  28. package/dist/{response.d.ts → response.d.mts} +1 -1
  29. package/dist/response.d.mts.map +1 -0
  30. package/dist/{response.js → response.mjs} +2 -2
  31. package/dist/{run-CJy-W5tX.js → run-BPFtSYA3.mjs} +37 -37
  32. package/dist/run-BPFtSYA3.mjs.map +1 -0
  33. package/dist/{run.d.ts → run.d.mts} +3 -3
  34. package/dist/run.d.mts.map +1 -0
  35. package/dist/run.mjs +8 -0
  36. package/dist/{seeOther-C-36lhS5.js → seeOther-B4Yhu9iq.mjs} +1 -1
  37. package/dist/seeOther-B4Yhu9iq.mjs.map +1 -0
  38. package/dist/{server.d.ts → server.d.mts} +2 -2
  39. package/dist/server.d.mts.map +1 -0
  40. package/dist/{server.js → server.mjs} +3 -3
  41. package/dist/{state.d.ts → state.d.mts} +1 -1
  42. package/dist/state.d.mts.map +1 -0
  43. package/dist/state.mjs +3 -0
  44. package/dist/{test.d.ts → test.d.mts} +3 -3
  45. package/dist/test.d.mts.map +1 -0
  46. package/dist/{test.js → test.mjs} +12 -11
  47. package/dist/test.mjs.map +1 -0
  48. package/package.json +26 -24
  49. package/scripts/postbuild.ts +12 -0
  50. package/src/nav/loadData.ts +16 -5
  51. package/src/nav/navigate.ts +1 -0
  52. package/src/site/Router.ts +12 -13
  53. package/src/site/Site.ts +29 -4
  54. package/src/site/clientEntry.ts +1 -1
  55. package/src/site/manifest.ts +5 -2
  56. package/src/test/runTest.ts +1 -0
  57. package/src/types/ManifestRoute.ts +1 -0
  58. package/src/types/Route.ts +11 -0
  59. package/src/types/RouteHandler.ts +4 -0
  60. package/test/api/_hook.server.ts +3 -0
  61. package/test/api/posts/+page.server.ts +3 -0
  62. package/test/api/posts/[id]/+page.server.ts +3 -0
  63. package/test/router.test.ts +78 -0
  64. package/test/routes/+page.server.ts +3 -0
  65. package/test/routes/+page.ts +3 -0
  66. package/test/routes/_error.ts +3 -0
  67. package/test/routes/_hook.server.ts +3 -0
  68. package/test/routes/_layout.server.ts +3 -0
  69. package/test/routes/_layout.ts +3 -0
  70. package/test/routes/posts/+page.ts +3 -0
  71. package/test/routes/posts/[id]/+page.ts +3 -0
  72. package/test/site.test.ts +40 -0
  73. package/tsdown.config.ts +3 -10
  74. package/vitest.config.ts +2 -2
  75. package/dist/RouteType-VOBjKJ8I.js.map +0 -1
  76. package/dist/Server-DL9neaq0.d.ts.map +0 -1
  77. package/dist/ServerEvent-Dnk2FIKQ.js.map +0 -1
  78. package/dist/Site-B8TxSzPk.d.ts.map +0 -1
  79. package/dist/_page-ef72MjgG.js.map +0 -1
  80. package/dist/connectMiddleware-PBcWWRr-.js.map +0 -1
  81. package/dist/index.d.ts.map +0 -1
  82. package/dist/index.js.map +0 -1
  83. package/dist/nav.d.ts.map +0 -1
  84. package/dist/nav.js.map +0 -1
  85. package/dist/pathToRegex-BTPkBIYJ.js.map +0 -1
  86. package/dist/response-KnPcsvtU.js.map +0 -1
  87. package/dist/response.d.ts.map +0 -1
  88. package/dist/run-CJy-W5tX.js.map +0 -1
  89. package/dist/run.d.ts.map +0 -1
  90. package/dist/run.js +0 -8
  91. package/dist/seeOther-C-36lhS5.js.map +0 -1
  92. package/dist/server.d.ts.map +0 -1
  93. package/dist/state.d.ts.map +0 -1
  94. package/dist/state.js +0 -3
  95. package/dist/test.d.ts.map +0 -1
  96. package/dist/test.js.map +0 -1
  97. /package/dist/bin/{index.d.ts → index.d.mts} +0 -0
@@ -8,6 +8,7 @@ export default async function loadData(
8
8
  handler: RouteHandler,
9
9
  params: Record<string, string>,
10
10
  path: string,
11
+ query: URLSearchParams,
11
12
  newLayoutStack: LayoutPath[],
12
13
  clientEndPoint: PageEndPoint | undefined,
13
14
  serverEndPoint: PageServerEndPoint | undefined,
@@ -36,6 +37,7 @@ export default async function loadData(
36
37
  const layoutResponse = await loadClientAndServerData(
37
38
  stackLayout.data,
38
39
  document.location.origin + layoutPath,
40
+ query,
39
41
  params,
40
42
  layoutEndPoint,
41
43
  layoutServerEndPoint,
@@ -51,6 +53,7 @@ export default async function loadData(
51
53
  let endPointResponse = await loadClientAndServerData(
52
54
  data,
53
55
  document.location.origin + path,
56
+ query,
54
57
  params,
55
58
  clientEndPoint,
56
59
  serverEndPoint,
@@ -64,6 +67,7 @@ export default async function loadData(
64
67
  async function loadClientAndServerData(
65
68
  data: Record<string, any>,
66
69
  location: string,
70
+ query: URLSearchParams,
67
71
  params: Record<string, string>,
68
72
  clientEndPoint?: PageEndPoint,
69
73
  serverEndPoint?: PageServerEndPoint,
@@ -75,6 +79,9 @@ async function loadClientAndServerData(
75
79
  Object.assign(data, prefetchedData[location]);
76
80
  } else {
77
81
  const clientUrl = new URL(document.location.href);
82
+ for (let [name, value] of query) {
83
+ clientUrl.searchParams.append(name, value);
84
+ }
78
85
  const clientParams = buildClientParams(clientUrl, params, data);
79
86
  const clientResponse = await clientEndPoint.load(clientParams);
80
87
  if (clientResponse) {
@@ -90,19 +97,23 @@ async function loadClientAndServerData(
90
97
  }
91
98
  }
92
99
  }
93
- if (serverEndPoint?.load) {
94
- const serverUrl = location.replace(/\/$/, "") + "/~server";
95
100
 
96
- if (prefetchedData[serverUrl]) {
97
- Object.assign(data, prefetchedData[serverUrl]);
101
+ if (serverEndPoint?.load) {
102
+ const serverLocation = location.replace(/\/$/, "") + "/~server";
103
+ if (prefetchedData[serverLocation]) {
104
+ Object.assign(data, prefetchedData[serverLocation]);
98
105
  } else {
106
+ const serverUrl = new URL(serverLocation);
107
+ for (let [name, value] of query) {
108
+ serverUrl.searchParams.append(name, value);
109
+ }
99
110
  const serverResponse = await fetch(serverUrl);
100
111
  if (serverResponse) {
101
112
  if (serverResponse.ok) {
102
113
  if (serverResponse.headers.get("Content-Type")?.includes("application/json")) {
103
114
  const serverData = await serverResponse.json();
104
115
  Object.assign(data, serverData);
105
- prefetchedData[serverUrl] = serverData;
116
+ prefetchedData[serverLocation] = serverData;
106
117
  }
107
118
  } else {
108
119
  return serverResponse;
@@ -64,6 +64,7 @@ export default async function navigate(url: URL, withHydration = false): Promise
64
64
  handler,
65
65
  params,
66
66
  path,
67
+ query,
67
68
  newLayoutStack,
68
69
  clientEndPoint,
69
70
  serverEndPoint,
@@ -23,6 +23,7 @@ export default class Router {
23
23
  path: r.path,
24
24
  type: r.type,
25
25
  endPoint: r.endPoint,
26
+ subFolder: r.subFolder,
26
27
  }),
27
28
  );
28
29
  }
@@ -31,12 +32,13 @@ export default class Router {
31
32
  }
32
33
 
33
34
  // TODO: Allow calling with the endpoint itself, so that you can setup an app with no scaffold
34
- addPage(path: string, type: number, endPoint: () => Promise<any>): this {
35
+ addPage(path: string, type: number, endPoint: () => Promise<any>, subFolder?: string): this {
35
36
  this.routes.push(
36
37
  new Route(path, {
37
38
  path,
38
39
  type,
39
40
  endPoint,
41
+ subFolder,
40
42
  }),
41
43
  );
42
44
  this.#sortRoutes();
@@ -53,7 +55,7 @@ export default class Router {
53
55
  }
54
56
  */
55
57
 
56
- match(path: string, query: URLSearchParams): Match | undefined {
58
+ match(path: string, query: URLSearchParams): RouteMatch | undefined {
57
59
  for (let route of this.routes) {
58
60
  let match = path.match(route.regex);
59
61
  if (match) {
@@ -69,17 +71,15 @@ export default class Router {
69
71
  };
70
72
  }
71
73
  }
72
-
73
- console.log(`not found: '${path}'`);
74
74
  }
75
75
 
76
76
  #loadHandler(handler: RouteHandler, path: string) {
77
- handler.layouts = this.#findLayouts(path);
77
+ handler.layouts = this.#findLayouts(path, handler);
78
78
  handler.serverEndPoint = this.#findServer(path);
79
- handler.serverHook = this.#findServerHook(path);
79
+ handler.serverHook = this.#findServerHook(handler);
80
80
  }
81
81
 
82
- #findLayouts(path: string): LayoutHandler[] | undefined {
82
+ #findLayouts(path: string, handler: RouteHandler): LayoutHandler[] | undefined {
83
83
  let layouts: LayoutHandler[] = [];
84
84
  let parts = path
85
85
  // Strip the trailing`~/server` (so we don't look for `~/server/_layout`
@@ -96,7 +96,7 @@ export default class Router {
96
96
  }
97
97
  const layoutPath = basePath + "/_layout";
98
98
  const layoutRoute = this.routes.find((r) => r.path === layoutPath);
99
- if (layoutRoute) {
99
+ if (layoutRoute && layoutRoute.handler.subFolder === handler.subFolder) {
100
100
  layouts.push({
101
101
  path: layoutPath,
102
102
  endPoint: layoutRoute.handler.endPoint,
@@ -113,12 +113,11 @@ export default class Router {
113
113
  return serverRoute && serverRoute.handler.endPoint;
114
114
  }
115
115
 
116
- #findServerHook(path: string): (() => Promise<any>) | undefined {
116
+ #findServerHook(handler: RouteHandler): (() => Promise<any>) | undefined {
117
117
  // TODO: Should this be a collection, like layouts?
118
118
  let serverHookPath = "/_hook/~server";
119
- // HACK: Generalise this
120
- if (path.startsWith("/api/")) {
121
- serverHookPath = "/api" + serverHookPath;
119
+ if (handler.subFolder !== undefined) {
120
+ serverHookPath = handler.subFolder + serverHookPath;
122
121
  }
123
122
  const serverHookRoute = this.routes.find((r) => r.path === serverHookPath);
124
123
  return serverHookRoute && serverHookRoute.handler.endPoint;
@@ -158,7 +157,7 @@ class Route {
158
157
  }
159
158
  }
160
159
 
161
- interface Match {
160
+ interface RouteMatch {
162
161
  handler: RouteHandler;
163
162
  params?: Record<string, string>;
164
163
  query: URLSearchParams;
package/src/site/Site.ts CHANGED
@@ -3,6 +3,7 @@ import fpath from "node:path";
3
3
  import { type Plugin, type UserConfig } from "vite";
4
4
  import tsconfigPaths from "vite-tsconfig-paths";
5
5
  import type Adapter from "../types/Adapter";
6
+ import type Route from "../types/Route";
6
7
  import {
7
8
  ERROR_ROUTE,
8
9
  HOOK_ROUTE,
@@ -27,7 +28,7 @@ import defaultAdapter from "./defaultAdapter";
27
28
  */
28
29
  export default class Site {
29
30
  root: string;
30
- routes: { path: string; file: string; type: RouteType }[] = [];
31
+ routes: Route[] = [];
31
32
  // Is default plugins a bad idea?
32
33
  // HACK: Set loose because otherwise it uses a list of allowed extensions
33
34
  // TODO: Should probably just do this ourselves and let the user pass in
@@ -56,17 +57,32 @@ export default class Site {
56
57
  /**
57
58
  * Adds a folder of routes, based on the names of the files in the folder
58
59
  * @param folder The folder containing the routes
60
+ * @param subFolder If a subFolder is set, all routes in the folder will be
61
+ * placed under the subFolder, and only hooks, layouts etc will be used if
62
+ * they have the same subFolder. This can be used to create e.g. an `api`
63
+ * set of routes with their own hook for authorization from various clients
59
64
  */
60
- async addRouteFolder(folder: string): Promise<void> {
65
+ async addRouteFolder(folder: string, subFolder?: string): Promise<void> {
61
66
  const routeFolder = fpath.join(this.root, folder);
62
67
  const routeFiles = await fs.readdir(routeFolder, { recursive: true });
68
+ if (subFolder !== undefined && !subFolder.startsWith("/")) {
69
+ subFolder = "/" + subFolder;
70
+ }
63
71
  for (let file of routeFiles) {
64
72
  // The file must start with `+` or `_` and end with `.js` or `.ts`
65
73
  if (/^(\+|_).+(\.js|\.ts)$/.test(fpath.basename(file))) {
66
74
  let routePath = this.#routePath(file);
75
+ if (subFolder !== undefined) {
76
+ routePath = subFolder + routePath;
77
+ }
67
78
  let type = this.#routeType(file);
68
79
  file = fpath.relative(this.root, fpath.resolve(routeFolder, file));
69
- this.routes.push({ path: routePath, file, type });
80
+ this.routes.push({
81
+ path: routePath,
82
+ file,
83
+ type,
84
+ subFolder: subFolder,
85
+ });
70
86
  }
71
87
  }
72
88
  this.#sortRoutes();
@@ -91,10 +107,19 @@ export default class Site {
91
107
  | "_hook"
92
108
  | "_hook.server"
93
109
  | "_error",
110
+ subFolder?: string,
94
111
  ): void {
95
112
  let routePath = this.#routePath(fpath.join(path, type ?? fpath.basename(file)));
96
113
  let routeType = type ? this.#routeTypeFromString(type) : this.#routeType(file);
97
- this.routes.push({ path: routePath, file, type: routeType });
114
+ if (subFolder !== undefined && !subFolder.startsWith("/")) {
115
+ subFolder = "/" + subFolder;
116
+ }
117
+ this.routes.push({
118
+ path: routePath,
119
+ file,
120
+ type: routeType,
121
+ subFolder: subFolder,
122
+ });
98
123
  this.#sortRoutes();
99
124
  }
100
125
 
@@ -72,7 +72,7 @@ async function maybePrefetch(e: MouseEvent | TouchEvent) {
72
72
  // Just dummy this up
73
73
  let newStack: LayoutPath[] = [];
74
74
 
75
- await loadData(handler, params, path, newStack, clientEndPoint, serverEndPoint, true);
75
+ await loadData(handler, params, path, query, newStack, clientEndPoint, serverEndPoint, true);
76
76
  }
77
77
  }
78
78
  }
@@ -30,16 +30,19 @@ export default {
30
30
  routes: [
31
31
  ${site.routes
32
32
  .map((r) => {
33
+ let endPoint: string;
33
34
  if (serverRequest || !/server\.(ts|js)$/.test(r.file)) {
34
- return `{ path: "${r.path}", type: ${r.type}, endPoint: ${serverRequest || !/server\.(ts|js)$/.test(r.file) ? `() => import(/* @vite-ignore */ "${path.join(site.root, r.file)}")` : "undefined"} }`;
35
+ endPoint = `() => import(/* @vite-ignore */ "${path.join(site.root, r.file)}")`;
35
36
  } else {
36
37
  // On the client, for a server route, we need to check
37
38
  // whether there's a load function and set a dummy endPoint
38
39
  // if so. The correct endpoint will be hit in clientEntry
39
40
  // HACK: Should do this better than checking for `load:` in source...
40
41
  const haveLoad = readFileSync(path.join(site.root, r.file)).includes("load:");
41
- return `{ path: "${r.path}", type: ${r.type}, endPoint: ${haveLoad ? "() => load" : "undefined"} }`;
42
+ endPoint = haveLoad ? "() => load" : "undefined";
42
43
  }
44
+ const sub = r.subFolder ? `"${r.subFolder}"` : "undefined";
45
+ return `{ path: "${r.path}", type: ${r.type}, endPoint: ${endPoint}, subFolder: ${sub} }`;
43
46
  })
44
47
  .join(",\n ")}
45
48
  ],
@@ -48,6 +48,7 @@ export default async function runTest(
48
48
  path: r.path,
49
49
  type: r.type,
50
50
  endPoint: () => import(/* @vite-ignore */ path.join(site.root, r.file)),
51
+ subFolder: r.subFolder,
51
52
  })),
52
53
  );
53
54
 
@@ -2,4 +2,5 @@ export default interface ManifestRoute {
2
2
  path: string;
3
3
  type: number;
4
4
  endPoint: () => Promise<any>;
5
+ subFolder: string | undefined;
5
6
  }
@@ -0,0 +1,11 @@
1
+ import { type RouteType } from "./RouteType";
2
+
3
+ /**
4
+ * A route that is added to the Site.
5
+ */
6
+ export default interface Route {
7
+ path: string;
8
+ file: string;
9
+ type: RouteType;
10
+ subFolder?: string;
11
+ }
@@ -1,9 +1,13 @@
1
1
  import type RouteLayoutHandler from "./RouteLayoutHandler";
2
2
 
3
+ /**
4
+ * A handler for a route in the Router.
5
+ */
3
6
  export default interface RouteHandler {
4
7
  path: string;
5
8
  type: number;
6
9
  endPoint: () => Promise<any>;
10
+ subFolder?: string;
7
11
 
8
12
  loaded?: boolean;
9
13
  layouts?: RouteLayoutHandler[];
@@ -0,0 +1,3 @@
1
+ import type { ServerHook } from "@torpor/build";
2
+
3
+ export default {} satisfies ServerHook as ServerHook;
@@ -0,0 +1,3 @@
1
+ import { type PageServerEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageServerEndPoint as PageServerEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageServerEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageServerEndPoint as PageServerEndPoint;
@@ -0,0 +1,78 @@
1
+ import { assert, expect, test } from "vitest";
2
+ import Router from "../src/site/Router";
3
+ import { HOOK_SERVER_ROUTE, LAYOUT_ROUTE, PAGE_ROUTE } from "../src/types/RouteType";
4
+
5
+ test("router method sorting", () => {
6
+ let r = new Router();
7
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
8
+ r.addPage("/posts/drafts/[id]", PAGE_ROUTE, async () => {});
9
+ expect(r.routes.map((r) => r.path).join(",")).toBe("/posts/drafts/[id],/posts/[id]");
10
+ });
11
+
12
+ test("router matching", () => {
13
+ let r = new Router();
14
+ r.addPage("/posts", PAGE_ROUTE, async () => {});
15
+ const match = r.match("/posts", new URLSearchParams());
16
+ assert(match, "no match");
17
+ expect(match.params).toBeUndefined();
18
+ assert(match.handler, "no handler");
19
+ });
20
+
21
+ test("router matching with param", () => {
22
+ let r = new Router();
23
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
24
+ r.addPage("/posts/drafts/[id]", PAGE_ROUTE, async () => {});
25
+ const match = r.match("/posts/5", new URLSearchParams());
26
+ assert(match, "no match");
27
+ assert(match.params, "no params");
28
+ expect(match.params["id"]).toBe("5");
29
+ });
30
+
31
+ test("router matching not found", () => {
32
+ let r = new Router();
33
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
34
+ r.addPage("/posts/drafts/[id]", PAGE_ROUTE, async () => {});
35
+ const match = r.match("/postss/5", new URLSearchParams());
36
+ expect(match).toBeUndefined();
37
+ });
38
+
39
+ test("router matching layouts", () => {
40
+ let r = new Router();
41
+ r.addPage("/_layout", LAYOUT_ROUTE, async () => {});
42
+ r.addPage("/posts/_layout", LAYOUT_ROUTE, async () => {});
43
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
44
+ r.addPage("/posts/drafts/[id]", PAGE_ROUTE, async () => {});
45
+ const match = r.match("/posts/5", new URLSearchParams());
46
+ assert(match, "no match");
47
+ assert(match.handler.layouts, "no layouts");
48
+ expect(match.handler.layouts.length).toBe(2);
49
+ });
50
+
51
+ test("router matching hook", () => {
52
+ let r = new Router();
53
+ r.addPage("/_hook/~server", HOOK_SERVER_ROUTE, async () => {});
54
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
55
+ const match = r.match("/posts/5", new URLSearchParams());
56
+ assert(match, "no match");
57
+ assert(match.handler.serverHook, "no hook");
58
+ });
59
+
60
+ test("router matching base folder", async () => {
61
+ let r = new Router();
62
+ r.addPage("/_hook/~server", HOOK_SERVER_ROUTE, async () => {});
63
+ r.addPage("/_layout", LAYOUT_ROUTE, async () => {});
64
+ r.addPage("/posts/_layout", LAYOUT_ROUTE, async () => {});
65
+ r.addPage("/posts/[id]", PAGE_ROUTE, async () => {});
66
+ r.addPage("/api/posts/[id]", PAGE_ROUTE, async () => {}, "/api");
67
+ r.addPage("/api/_hook/~server", HOOK_SERVER_ROUTE, async () => "api hook", "/api");
68
+ const match = r.match("/api/posts/5", new URLSearchParams());
69
+ assert(match, "no match");
70
+ assert(match.params, "no params");
71
+ expect(match.params["id"]).toBe("5");
72
+
73
+ expect(match.handler.path).toBe("/api/posts/[id]");
74
+ assert(match.handler.serverHook, "no hook");
75
+ expect(await match.handler.serverHook()).toBe("api hook");
76
+
77
+ expect(match.handler.layouts).toBeUndefined();
78
+ });
@@ -0,0 +1,3 @@
1
+ import { type PageServerEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageServerEndPoint as PageServerEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageEndPoint as PageEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageEndPoint as PageEndPoint;
@@ -0,0 +1,3 @@
1
+ import type { ServerHook } from "@torpor/build";
2
+
3
+ export default {} satisfies ServerHook as ServerHook;
@@ -0,0 +1,3 @@
1
+ import type { PageServerEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageServerEndPoint as PageServerEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageEndPoint as PageEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageEndPoint as PageEndPoint;
@@ -0,0 +1,3 @@
1
+ import { type PageEndPoint } from "@torpor/build";
2
+
3
+ export default {} satisfies PageEndPoint as PageEndPoint;
@@ -0,0 +1,40 @@
1
+ import { expect, test } from "vitest";
2
+ import Site from "../src/site/Site";
3
+
4
+ test("site routes", async () => {
5
+ let site = new Site();
6
+ await site.addRouteFolder("./test/routes");
7
+ expect(site.routes.map((r) => r.path).join("\n")).toBe(
8
+ `
9
+ /
10
+ /_error
11
+ /_hook/~server
12
+ /_layout
13
+ /_layout/~server
14
+ /~server
15
+ /posts
16
+ /posts/[id]
17
+ `.trim(),
18
+ );
19
+ });
20
+
21
+ test("site routes with base folder", async () => {
22
+ let site = new Site();
23
+ await site.addRouteFolder("./test/routes");
24
+ await site.addRouteFolder("./test/api", "api");
25
+ expect(site.routes.map((r) => r.path).join("\n")).toBe(
26
+ `
27
+ /
28
+ /_error
29
+ /_hook/~server
30
+ /_layout
31
+ /_layout/~server
32
+ /~server
33
+ /api/_hook/~server
34
+ /api/posts/~server
35
+ /api/posts/[id]/~server
36
+ /posts
37
+ /posts/[id]
38
+ `.trim(),
39
+ );
40
+ });
package/tsdown.config.ts CHANGED
@@ -1,9 +1,4 @@
1
- import { type Options, defineConfig } from "tsdown";
2
-
3
- type Config =
4
- | Options
5
- | Options[]
6
- | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
1
+ import { type UserConfig, defineConfig } from "tsdown";
7
2
 
8
3
  export default defineConfig({
9
4
  entry: [
@@ -16,10 +11,8 @@ export default defineConfig({
16
11
  "src/test.ts",
17
12
  "src/bin/index.ts",
18
13
  ],
19
- format: "esm",
20
- dts: true,
21
- sourcemap: true,
22
14
  // Put this in here to stop issues with bundling Vite from bin/index.ts
23
15
  // I'm not sure if this will cause further issues down the line?
24
16
  external: ["vite"],
25
- }) satisfies Config as Config;
17
+ onSuccess: "npm run build:fix",
18
+ }) satisfies UserConfig as UserConfig;
package/vitest.config.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { type UserConfigFnObject, defineConfig } from "vitest/config";
1
+ import { type ViteUserConfigFnObject, defineConfig } from "vitest/config";
2
2
 
3
- export default defineConfig(() => ({})) satisfies UserConfigFnObject as UserConfigFnObject;
3
+ export default defineConfig(() => ({})) satisfies ViteUserConfigFnObject as ViteUserConfigFnObject;
@@ -1 +0,0 @@
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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"}
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
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 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_page-ef72MjgG.js","names":["PAGE_SYMBOL: unique symbol","$page: PageState"],"sources":["../src/state/$page.ts"],"sourcesContent":["import { $watch } from \"@torpor/view\";\nimport type PageState from \"../types/PageState\";\n\nconst PAGE_SYMBOL: unique symbol = Symbol.for(\"t_page\");\n\nconst $page: PageState =\n\t// @ts-ignore\n\t(globalThis[PAGE_SYMBOL] ??=\n\t\t// TODO: Should use the SSR $watch if entering via serverEntry\n\t\t$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\nexport default $page;\n"],"mappings":";;;AAGA,MAAMA,cAA6B,OAAO,IAAI,SAAS;AAEvD,MAAMC,QAEJ,WAAW,iBAEX,OACC;CACC,QAAQ;CACR,KAAK,IAAI,IAAI,mBAAmB;CAChC,MAAM;CACN,OAAO,EACN,SAAS,IACT;CACD,EACD,EACC,SAAS,MACT,CACD;AAEH,oBAAe"}
@@ -1 +0,0 @@
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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"}
@@ -1 +0,0 @@
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"}