@torpor/build 0.1.11 → 0.1.13

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 (65) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{Server-DhJ1nRFR.d.cts → Server-BC_dixZQ.d.cts} +5 -6
  3. package/dist/{Server-DhJ1nRFR.d.ts → Server-BC_dixZQ.d.ts} +5 -6
  4. package/dist/{Site-CM2pZtq6.d.cts → Site-BeRKXeJ4.d.cts} +7 -1
  5. package/dist/{Site-BB6kV7wC.d.ts → Site-D70KrWlY.d.ts} +7 -1
  6. package/dist/bin/index.cjs +17 -25
  7. package/dist/bin/index.cjs.map +1 -1
  8. package/dist/bin/index.js +4 -4
  9. package/dist/{chunk-FLQZX64D.js → chunk-27LTVTCS.js} +2 -2
  10. package/dist/chunk-27LTVTCS.js.map +1 -0
  11. package/dist/{chunk-4YLPLGR2.js → chunk-GWXPZFMX.js} +17 -26
  12. package/dist/chunk-GWXPZFMX.js.map +1 -0
  13. package/dist/{chunk-VAGHGWM5.js → chunk-PTCWU3AW.js} +1 -1
  14. package/dist/chunk-PTCWU3AW.js.map +1 -0
  15. package/dist/chunk-SJVHHGVW.js +13 -0
  16. package/dist/chunk-SJVHHGVW.js.map +1 -0
  17. package/dist/index.cjs +9 -2
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +8 -9
  20. package/dist/index.d.ts +8 -9
  21. package/dist/index.js +7 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/metafile-cjs.json +1 -1
  24. package/dist/metafile-esm.json +1 -1
  25. package/dist/response.cjs.map +1 -1
  26. package/dist/response.js +1 -1
  27. package/dist/run.cjs +17 -25
  28. package/dist/run.cjs.map +1 -1
  29. package/dist/run.d.cts +2 -2
  30. package/dist/run.d.ts +2 -2
  31. package/dist/run.js +4 -4
  32. package/dist/server.cjs +3 -2
  33. package/dist/server.cjs.map +1 -1
  34. package/dist/server.d.cts +2 -2
  35. package/dist/server.d.ts +2 -2
  36. package/dist/server.js +2 -2
  37. package/dist/state.cjs.map +1 -1
  38. package/dist/state.d.cts +2 -1
  39. package/dist/state.d.ts +2 -1
  40. package/dist/state.js.map +1 -1
  41. package/package.json +7 -7
  42. package/src/response/response.ts +1 -1
  43. package/src/server/CookieHelper.ts +2 -2
  44. package/src/server/HeaderHelper.ts +2 -2
  45. package/src/server/Routerx.ts +7 -2
  46. package/src/server/Server.ts +6 -1
  47. package/src/server/ServerEvent.ts +1 -1
  48. package/src/server/contentType.ts +1 -1
  49. package/src/site/Router.ts +9 -3
  50. package/src/site/Site.ts +8 -2
  51. package/src/site/pathToRegex.ts +13 -8
  52. package/src/site/prepareTemplate.ts +1 -1
  53. package/src/site/run.ts +9 -7
  54. package/src/site/runBuild.ts +9 -14
  55. package/src/site/runDev.ts +3 -8
  56. package/src/site/runPreview.ts +1 -1
  57. package/src/site/serverEntry.ts +1 -1
  58. package/src/state/$page.ts +6 -1
  59. package/tsup.config.ts +7 -2
  60. package/vitest.config.ts +2 -2
  61. package/dist/chunk-4YLPLGR2.js.map +0 -1
  62. package/dist/chunk-FLQZX64D.js.map +0 -1
  63. package/dist/chunk-T5K52YVJ.js +0 -12
  64. package/dist/chunk-T5K52YVJ.js.map +0 -1
  65. package/dist/chunk-VAGHGWM5.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  serverError
3
- } from "./chunk-VAGHGWM5.js";
3
+ } from "./chunk-PTCWU3AW.js";
4
4
  import {
5
5
  Server,
6
6
  connectMiddleware
7
- } from "./chunk-FLQZX64D.js";
7
+ } from "./chunk-27LTVTCS.js";
8
8
 
9
9
  // src/site/runBuild.ts
10
10
  import torpor from "@torpor/unplugin/vite";
@@ -68,19 +68,15 @@ async function runBuild(site) {
68
68
  let serverScript = path2.join(siteFolder, "serverEntry.ts");
69
69
  await build(
70
70
  defineConfig({
71
- plugins: [
72
- manifest(site),
73
- // @ts-ignore
74
- torpor(),
75
- ...site.plugins
76
- ],
71
+ plugins: [manifest(site), torpor(), ...site.plugins],
77
72
  build: {
78
73
  outDir: clientFolder,
79
74
  rollupOptions: {
80
75
  input: [
81
76
  siteHtml,
82
77
  clientScript,
83
- ...site.routes.filter((r) => !/server\.(ts|js)$/.test(r.file)).map((r) => path2.resolve(site.root, r.file))
78
+ ...site.routes.filter((r) => !/server\.(ts|js)$/.test(r.file)).map((r) => path2.resolve(site.root, r.file)),
79
+ ...site.inputs.filter((f) => !/server\.(ts|js)$/.test(f))
84
80
  ]
85
81
  },
86
82
  ssrManifest: true
@@ -89,16 +85,15 @@ async function runBuild(site) {
89
85
  );
90
86
  await build(
91
87
  defineConfig({
92
- plugins: [
93
- manifest(site, true),
94
- // @ts-ignore
95
- torpor(),
96
- ...site.plugins
97
- ],
88
+ plugins: [manifest(site, true), torpor(), ...site.plugins],
98
89
  build: {
99
90
  outDir: serverFolder,
100
91
  rollupOptions: {
101
- input: [serverScript, ...site.routes.map((r) => path2.resolve(site.root, r.file))]
92
+ input: [
93
+ serverScript,
94
+ ...site.routes.map((r) => path2.resolve(site.root, r.file)),
95
+ ...site.inputs
96
+ ]
102
97
  },
103
98
  ssr: serverScript
104
99
  }
@@ -140,12 +135,7 @@ async function runDev(site) {
140
135
  const vite = await createViteServer({
141
136
  server: { middlewareMode: true },
142
137
  appType: "custom",
143
- plugins: [
144
- manifest(site, true),
145
- // @ts-ignore not sure...
146
- torpor2(),
147
- ...site.plugins
148
- ]
138
+ plugins: [manifest(site, true), torpor2(), ...site.plugins]
149
139
  });
150
140
  const templateFile = path3.resolve(site.root, "src/site.html");
151
141
  let template = await fs2.readFile(templateFile, "utf-8");
@@ -322,10 +312,11 @@ async function run(folder, mode) {
322
312
  configFile = jsConfigFile;
323
313
  } else if (fs4.existsSync(tsConfigFile)) {
324
314
  configFile = path5.join(folder, "site.config.temp.js");
325
- let source = (await transformWithEsbuild(fs4.readFileSync(tsConfigFile, "utf-8"), tsConfigFile, {
315
+ let source = fs4.readFileSync(tsConfigFile, "utf-8");
316
+ let transformed = await transformWithEsbuild(source, tsConfigFile, {
326
317
  loader: "ts"
327
- })).code;
328
- fs4.writeFileSync(configFile, source);
318
+ });
319
+ fs4.writeFileSync(configFile, transformed.code);
329
320
  deleteConfigFile = true;
330
321
  } else {
331
322
  throw new Error("site.config file not found");
@@ -364,4 +355,4 @@ export {
364
355
  runPreview,
365
356
  run
366
357
  };
367
- //# sourceMappingURL=chunk-4YLPLGR2.js.map
358
+ //# sourceMappingURL=chunk-GWXPZFMX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/site/runBuild.ts","../src/site/manifest.ts","../src/site/runDev.ts","../src/site/prepareTemplate.ts","../src/site/runPreview.ts","../src/server/contentType.ts","../src/site/run.ts"],"sourcesContent":["import torpor from \"@torpor/unplugin/vite\";\nimport { existsSync, promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { build, defineConfig } from \"vite\";\nimport Site from \"./Site.ts\";\nimport manifest from \"./manifest.ts\";\n\n// TODO: Don't cache index.html in dev?\n// TODO: Multiple hook.server locations\n// TODO: Don't reload layouts during client routing\n// TODO: Call the correct +page and +server routes when in the same folder\n\nexport default async function runBuild(site: Site): Promise<void> {\n\t// Delete the dist folder if it exists\n\tconst distFolder = path.resolve(site.root, \"dist\");\n\tif (existsSync(distFolder)) {\n\t\tawait fs.rm(distFolder, { recursive: true });\n\t}\n\tconst clientFolder = path.join(distFolder, \"client\");\n\tconst serverFolder = path.join(distFolder, \"server\");\n\n\t// HOOK: Prebuild\n\tif (site.adapter.prebuild) {\n\t\tawait site.adapter.prebuild(site);\n\t}\n\n\t// TODO: From a setting\n\tlet siteHtml = path.resolve(site.root, \"src/site.html\");\n\n\t// TODO: Is this going to be the correct path after installing from npm?\n\tconst siteFolder = path.resolve(site.root, \"./node_modules/@torpor/build/src/site/\");\n\tlet clientScript = path.join(siteFolder, \"clientEntry.ts\");\n\tlet serverScript = path.join(siteFolder, \"serverEntry.ts\");\n\n\t// Build the client assets, including site.html and the route files\n\t// EXCLUDING anything with `server.js` in the name\n\tawait build(\n\t\tdefineConfig({\n\t\t\tplugins: [manifest(site), torpor(), ...site.plugins],\n\t\t\tbuild: {\n\t\t\t\toutDir: clientFolder,\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: [\n\t\t\t\t\t\tsiteHtml,\n\t\t\t\t\t\tclientScript,\n\t\t\t\t\t\t...site.routes\n\t\t\t\t\t\t\t.filter((r) => !/server\\.(ts|js)$/.test(r.file))\n\t\t\t\t\t\t\t.map((r) => path.resolve(site.root, r.file)),\n\t\t\t\t\t\t...site.inputs.filter((f) => !/server\\.(ts|js)$/.test(f)),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tssrManifest: true,\n\t\t\t},\n\t\t}),\n\t);\n\n\t// Build the server assets, including the server entry script and the route\n\t// files\n\tawait build(\n\t\tdefineConfig({\n\t\t\tplugins: [manifest(site, true), torpor(), ...site.plugins],\n\t\t\tbuild: {\n\t\t\t\toutDir: serverFolder,\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: [\n\t\t\t\t\t\tserverScript,\n\t\t\t\t\t\t...site.routes.map((r) => path.resolve(site.root, r.file)),\n\t\t\t\t\t\t...site.inputs,\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tssr: serverScript,\n\t\t\t},\n\t\t}),\n\t);\n\n\t// Move the site.html file into /client\n\t// HACK: Should do this in Rollup if possible?\n\tsiteHtml = path.join(clientFolder, \"site.html\");\n\tawait fs.rename(path.join(clientFolder, \"src\", \"site.html\"), siteHtml);\n\tawait fs.rm(path.join(clientFolder, \"src\"), { recursive: true });\n\n\t// HOOK: Postbuild\n\tif (site.adapter.postbuild) {\n\t\tawait site.adapter.postbuild(site);\n\t}\n}\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { Plugin } from \"vite\";\nimport Site from \"./Site\";\n\nconst moduleId = \"@torpor/build/manifest\";\n\n/**\n * A Vite plugin that provides information about the app to both clientEntry and\n * serverEntry.\n */\nexport default function manifest(site: Site, server = false): Plugin {\n\treturn {\n\t\tname: \"torpor-manifest\",\n\t\tresolveId: {\n\t\t\torder: \"pre\",\n\t\t\thandler(id) {\n\t\t\t\tif (id === moduleId) {\n\t\t\t\t\treturn id;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t// @ts-ignore\n\t\tload(id, viteOptions) {\n\t\t\tif (id === moduleId) {\n\t\t\t\tlet serverRequest = server && !!viteOptions?.ssr;\n\t\t\t\treturn `\n${!serverRequest ? \"const load = { default: { load: true } };\" : \"\"}\nexport default {\n routes: [\n ${site.routes\n\t\t\t.map((r) => {\n\t\t\t\tif (serverRequest || !/server\\.(ts|js)$/.test(r.file)) {\n\t\t\t\t\treturn `{ path: \"${r.path}\", type: ${r.type}, endPoint: ${serverRequest || !/server\\.(ts|js)$/.test(r.file) ? `() => import(/* @vite-ignore */ \"${path.join(site.root, r.file)}\")` : \"undefined\"} }`;\n\t\t\t\t} else {\n\t\t\t\t\t// On the client, for a server route, we need to check\n\t\t\t\t\t// whether there's a load function and set a dummy endPoint\n\t\t\t\t\t// if so. The correct endpoint will be hit in clientEntry\n\t\t\t\t\t// HACK: Should do this better than checking for `load:` in source...\n\t\t\t\t\tconst haveLoad = readFileSync(path.join(site.root, r.file)).includes(\"load:\");\n\t\t\t\t\treturn `{ path: \"${r.path}\", type: ${r.type}, endPoint: ${haveLoad ? \"() => load\" : \"undefined\"} }`;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.join(\",\\n \")}\n ],\n};\n`;\n\t\t\t}\n\t\t},\n\t};\n}\n","import torpor from \"@torpor/unplugin/vite\";\nimport { configDotenv } from \"dotenv\";\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { createServer as createViteServer } from \"vite\";\nimport { serverError } from \"../response.ts\";\nimport Server from \"../server/Server.ts\";\nimport connectMiddleware from \"../server/connect/connectMiddleware.ts\";\nimport Site from \"./Site.ts\";\nimport manifest from \"./manifest.ts\";\nimport prepareTemplate from \"./prepareTemplate.ts\";\n\nexport default async function runDev(site: Site): Promise<void> {\n\tconst server = new Server();\n\n\t// Create the Vite server in middleware mode and configure the app type as\n\t// \"custom\", disabling Vite's own HTML serving logic so the parent server\n\t// can take control\n\tconst vite = await createViteServer({\n\t\tserver: { middlewareMode: true },\n\t\tappType: \"custom\",\n\t\tplugins: [manifest(site, true), torpor(), ...site.plugins],\n\t});\n\n\t// Read site.html\n\t// It's called site.html because @torpor/build builds the site (html, routes\n\t// etc) while the user builds the app (components etc)\n\tconst templateFile = path.resolve(site.root, \"src/site.html\");\n\tlet template = await fs.readFile(templateFile, \"utf-8\");\n\n\t// Apply Vite HTML transforms. This injects the Vite HMR client, and also\n\t// applies HTML transforms from Vite plugins. Note that we only support a\n\t// universal transform, not individual transforms for each route\n\ttemplate = await vite.transformIndexHtml(\"\", template);\n\n\t// TODO: Is this going to be the correct path after installing from npm?\n\tconst siteFolder = path.resolve(site.root, \"./node_modules/@torpor/build/src/site/\");\n\tlet clientScript = path.join(siteFolder, \"clientEntry.ts\");\n\tlet serverScript = path.join(siteFolder, \"serverEntry.ts\");\n\n\t// Prepare site.html so that we can just splice components into it\n\ttemplate = prepareTemplate(template, clientScript);\n\n\t// Use Vite's Connect instance as middleware. We need to wrap it with\n\t// createMiddlewareHandler that converts Connect middleware to\n\t// Request/Response web handlers\n\tserver.use(connectMiddleware(vite.middlewares));\n\n\t// Every request (GET, POST, etc) goes through loadEndPoint\n\tserver.add(\"*\", async (ev) => {\n\t\ttry {\n\t\t\t// Load the server entry. ssrLoadModule automatically transforms ESM\n\t\t\t// source code to be usable in Node.js. No bundling is required, and\n\t\t\t// it provides efficient invalidation similar to HMR\n\t\t\tconst { load } = await vite.ssrLoadModule(serverScript);\n\n\t\t\t// Render the app HTML (or fetch server data etc) via serverEntry's\n\t\t\t// exported `load` function\n\t\t\treturn await load(ev, template);\n\t\t} catch (e: any) {\n\t\t\t// If an error is caught, let Vite fix the stack trace so it maps\n\t\t\t// back to your actual source code\n\t\t\tvite.ssrFixStacktrace(e);\n\t\t\treturn serverError(e);\n\t\t}\n\t});\n\n\t// Load environment variables from a `.env` file, with defaults if not set\n\tconfigDotenv();\n\n\tprocess.env.PROTOCOL ??= \"http:\";\n\tprocess.env.HOST ??= \"localhost\";\n\tprocess.env.PORT ??= \"7059\";\n\n\t// Serve the site\n\tsite.adapter.serve(server, site);\n}\n","export default function prepareTemplate(template: string, clientScript: string): string {\n\tlet contentStart = regexIndexOf(template, /\\<div\\s+id=(\"app\"|'app'|app)\\s+/);\n\tcontentStart = template.indexOf(\">\", contentStart) + 1;\n\tlet contentEnd = template.indexOf(\"</div>\", contentStart);\n\tif (contentStart === -1 || contentEnd === -1) {\n\t\tthrow new Error(`Couldn't find <div id=\"app\"></div>`);\n\t}\n\treturn (\n\t\ttemplate.substring(0, contentStart) +\n\t\t\"%COMPONENT_HTML%\" +\n\t\ttemplate.substring(contentEnd) +\n\t\t`<script type=\"module\" src=\"${clientScript}\"></script>`\n\t);\n}\n\n// From https://stackoverflow.com/a/274094\nfunction regexIndexOf(string: string, regex: RegExp, position?: number) {\n\tvar indexOf = string.substring(position || 0).search(regex);\n\treturn indexOf >= 0 ? indexOf + (position || 0) : indexOf;\n}\n","import { configDotenv } from \"dotenv\";\nimport { existsSync, promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { serverError } from \"../response.ts\";\nimport Server from \"../server/Server.ts\";\nimport contentType from \"../server/contentType.ts\";\nimport Site from \"./Site\";\nimport prepareTemplate from \"./prepareTemplate.ts\";\nimport runBuild from \"./runBuild\";\n\nexport default async function runPreview(site: Site): Promise<void> {\n\t// Build the site\n\tawait runBuild(site);\n\n\tconst distFolder = path.resolve(site.root, \"dist\");\n\tconst clientFolder = path.join(distFolder, \"client\");\n\tconst serverFolder = path.join(distFolder, \"server\");\n\n\t// Find the client script file in /assets\n\tlet clientScript = (await fs.readdir(path.join(clientFolder, \"assets\"))).find((f) =>\n\t\tf.startsWith(\"clientEntry-\"),\n\t);\n\tif (!clientScript) {\n\t\tthrow new Error(\"clientEntry.js not found\");\n\t}\n\tclientScript = `/assets/${clientScript}`;\n\n\t// Read site.html\n\t// It's called site.html because @torpor/build builds the site (html, routes\n\t// etc) while the user builds the app (components etc)\n\tlet siteHtml = path.join(clientFolder, \"site.html\");\n\tlet template = await fs.readFile(siteHtml, \"utf-8\");\n\n\t// Prepare site.html so that we can just splice components into it\n\ttemplate = prepareTemplate(template, clientScript);\n\n\t// Configure the server\n\tconst server = new Server();\n\n\t// Serve dist/client/assets statically\n\tserver.add(\"/assets/*\", async (ev) => {\n\t\ttry {\n\t\t\tconst url = new URL(ev.request.url);\n\t\t\tconst file = path.join(site.root, \"dist\", \"client\", url.pathname);\n\t\t\tif (existsSync(file)) {\n\t\t\t\t// TODO: Stream the data?\n\t\t\t\treturn new Response(await fs.readFile(file), {\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": contentType(path.extname(file)),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e: any) {\n\t\t\treturn serverError(e);\n\t\t}\n\t});\n\n\t// Every request (GET, POST, etc) goes through loadEndPoint\n\tconst serverScript = path.resolve(serverFolder, \"serverEntry.js\");\n\tserver.add(\"*\", async (ev) => {\n\t\ttry {\n\t\t\t// Load the server entry\n\t\t\tconst { load } = await import(serverScript);\n\n\t\t\t// Render the app HTML (or fetch server data etc) via serverEntry's\n\t\t\t// exported `load` function\n\t\t\treturn await load(ev, template);\n\t\t} catch (e: any) {\n\t\t\treturn serverError(e);\n\t\t}\n\t});\n\n\t// Load environment variables from a `.env` file, with defaults if not set\n\tconfigDotenv();\n\n\tprocess.env.PROTOCOL ??= \"http:\";\n\tprocess.env.HOST ??= \"localhost\";\n\tprocess.env.PORT ??= \"7059\";\n\n\t// Serve the site\n\tsite.adapter.serve(server, site);\n}\n","// From https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types\n\nexport default function contentType(extension: string): string {\n\treturn types[extension] || \"application/octet-stream\";\n}\n\nconst types: Record<string, string> = {\n\t\".aac\": \"audio/aac\",\n\t\".abw\": \"application/x-abiword\",\n\t\".apng\": \"image/apng\",\n\t\".arc\": \"application/x-freearc\",\n\t\".avif\": \"image/avif\",\n\t\".avi\": \"video/x-msvideo\",\n\t\".azw\": \"application/vnd.amazon.ebook\",\n\t\".bin\": \"application/octet-stream\",\n\t\".bmp\": \"image/bmp\",\n\t\".bz\": \"application/x-bzip\",\n\t\".bz2\": \"application/x-bzip2\",\n\t\".cda\": \"application/x-cdf\",\n\t\".csh\": \"application/x-csh\",\n\t\".css\": \"text/css\",\n\t\".csv\": \"text/csv\",\n\t\".doc\": \"application/msword\",\n\t\".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n\t\".eot\": \"application/vnd.ms-fontobject\",\n\t\".epub\": \"application/epub+zip\",\n\t\".gz\": \"application/gzip\",\n\t\".gif\": \"image/gif\",\n\t\".htm\": \"text/html\",\n\t\".html\": \"text/html\",\n\t\".ico\": \"image/vnd.microsoft.icon\",\n\t\".ics\": \"text/calendar\",\n\t\".jar\": \"application/java-archive\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".jpg\": \"image/jpeg\",\n\t\".js\": \"text/javascript\",\n\t\".json\": \"application/json\",\n\t\".jsonld\": \"application/ld+json\",\n\t\".mid\": \"audio/midi\",\n\t\".midi\": \"audio/midi\",\n\t\".mjs\": \"text/javascript\",\n\t\".mp3\": \"audio/mpeg\",\n\t\".mp4\": \"video/mp4\",\n\t\".mpeg\": \"video/mpeg\",\n\t\".mpkg\": \"application/vnd.apple.installer+xml\",\n\t\".odp\": \"application/vnd.oasis.opendocument.presentation\",\n\t\".ods\": \"application/vnd.oasis.opendocument.spreadsheet\",\n\t\".odt\": \"application/vnd.oasis.opendocument.text\",\n\t\".oga\": \"audio/ogg\",\n\t\".ogv\": \"video/ogg\",\n\t\".ogx\": \"application/ogg\",\n\t\".opus\": \"audio/ogg\",\n\t\".otf\": \"font/otf\",\n\t\".png\": \"image/png\",\n\t\".pdf\": \"application/pdf\",\n\t\".php\": \"application/x-httpd-php\",\n\t\".ppt\": \"application/vnd.ms-powerpoint\",\n\t\".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n\t\".rar\": \"application/vnd.rar\",\n\t\".rtf\": \"application/rtf\",\n\t\".sh\": \"application/x-sh\",\n\t\".svg\": \"image/svg+xml\",\n\t\".tar\": \"application/x-tar\",\n\t\".tif\": \"image/tiff\",\n\t\".tiff\": \"image/tiff\",\n\t\".ts\": \"video/mp2t\",\n\t\".ttf\": \"font/ttf\",\n\t\".txt\": \"text/plain\",\n\t\".vsd\": \"application/vnd.visio\",\n\t\".wav\": \"audio/wav\",\n\t\".weba\": \"audio/webm\",\n\t\".webm\": \"video/webm\",\n\t\".webp\": \"image/webp\",\n\t\".woff\": \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\t\".xhtml\": \"application/xhtml+xml\",\n\t\".xls\": \"application/vnd.ms-excel\",\n\t\".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n\t\".xml\": \"application/xml\",\n\t\".xul\": \"application/vnd.mozilla.xul+xml\",\n\t\".zip\": \"application/zip\",\n\t\".3gp\": \"video/3gpp\",\n\t\".3g2\": \"video/3gpp2\",\n\t\".7z\": \"application/x-7z-compressed\",\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { transformWithEsbuild } from \"vite\";\nimport Site from \"./Site\";\nimport runBuild from \"./runBuild\";\nimport runDev from \"./runDev\";\nimport runPreview from \"./runPreview\";\n\nexport default async function run(\n\tfolder: string,\n\tmode: \"dev\" | \"build\" | \"preview\",\n): Promise<void> {\n\t// Look for and load a site.config.js/ts file in the working directory\n\tlet configFile = \"\";\n\tlet deleteConfigFile = false;\n\tconst jsConfigFile = path.join(folder, \"site.config.js\");\n\tconst tsConfigFile = path.join(folder, \"site.config.ts\");\n\tif (fs.existsSync(jsConfigFile)) {\n\t\t// If it's JS, we can just import it straight up\n\t\tconfigFile = jsConfigFile;\n\t} else if (fs.existsSync(tsConfigFile)) {\n\t\t// If it's TS, we need to convert it to JS\n\t\t// TODO: Put the generated file somewhere better (dist?)\n\t\tconfigFile = path.join(folder, \"site.config.temp.js\");\n\t\tlet source = fs.readFileSync(tsConfigFile, \"utf-8\");\n\t\tlet transformed = await transformWithEsbuild(source, tsConfigFile, {\n\t\t\tloader: \"ts\",\n\t\t});\n\t\tfs.writeFileSync(configFile, transformed.code);\n\t\tdeleteConfigFile = true;\n\t} else {\n\t\tthrow new Error(\"site.config file not found\");\n\t}\n\n\tconst site = (await import(configFile)).default as Site;\n\tif (!site || !site.root || !site.routes) {\n\t\tthrow new Error(\"Invalid site in config file\");\n\t}\n\tif (deleteConfigFile) {\n\t\tfs.rmSync(configFile);\n\t}\n\n\tswitch (mode) {\n\t\tcase \"dev\": {\n\t\t\tawait runDev(site);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"build\": {\n\t\t\tawait runBuild(site);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"preview\": {\n\t\t\tawait runPreview(site);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tconsole.log(\"No mode passed, running in dev\");\n\t\t\tawait runDev(site);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;AAAA,OAAO,YAAY;AACnB,SAAS,YAAY,YAAY,UAAU;AAC3C,OAAOA,WAAU;AACjB,SAAS,OAAO,oBAAoB;;;ACHpC,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AAIjB,IAAM,WAAW;AAMF,SAAR,SAA0B,MAAY,SAAS,OAAe;AACpE,SAAO;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,IAAI;AACX,YAAI,OAAO,UAAU;AACpB,iBAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAAA;AAAA,IAEA,KAAK,IAAI,aAAa;AACrB,UAAI,OAAO,UAAU;AACpB,YAAI,gBAAgB,UAAU,CAAC,CAAC,aAAa;AAC7C,eAAO;AAAA,EACT,CAAC,gBAAgB,8CAA8C,EAAE;AAAA;AAAA;AAAA,MAG7D,KAAK,OACP,IAAI,CAAC,MAAM;AACX,cAAI,iBAAiB,CAAC,mBAAmB,KAAK,EAAE,IAAI,GAAG;AACtD,mBAAO,YAAY,EAAE,IAAI,YAAY,EAAE,IAAI,eAAe,iBAAiB,CAAC,mBAAmB,KAAK,EAAE,IAAI,IAAI,oCAAoC,KAAK,KAAK,KAAK,MAAM,EAAE,IAAI,CAAC,OAAO,WAAW;AAAA,UACjM,OAAO;AAKN,kBAAM,WAAW,aAAa,KAAK,KAAK,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,OAAO;AAC5E,mBAAO,YAAY,EAAE,IAAI,YAAY,EAAE,IAAI,eAAe,WAAW,eAAe,WAAW;AAAA,UAChG;AAAA,QACD,CAAC,EACA,KAAK,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA,MAIhB;AAAA,IACD;AAAA,EACD;AACD;;;ADtCA,eAAO,SAAgC,MAA2B;AAEjE,QAAM,aAAaC,MAAK,QAAQ,KAAK,MAAM,MAAM;AACjD,MAAI,WAAW,UAAU,GAAG;AAC3B,UAAM,GAAG,GAAG,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AACA,QAAM,eAAeA,MAAK,KAAK,YAAY,QAAQ;AACnD,QAAM,eAAeA,MAAK,KAAK,YAAY,QAAQ;AAGnD,MAAI,KAAK,QAAQ,UAAU;AAC1B,UAAM,KAAK,QAAQ,SAAS,IAAI;AAAA,EACjC;AAGA,MAAI,WAAWA,MAAK,QAAQ,KAAK,MAAM,eAAe;AAGtD,QAAM,aAAaA,MAAK,QAAQ,KAAK,MAAM,wCAAwC;AACnF,MAAI,eAAeA,MAAK,KAAK,YAAY,gBAAgB;AACzD,MAAI,eAAeA,MAAK,KAAK,YAAY,gBAAgB;AAIzD,QAAM;AAAA,IACL,aAAa;AAAA,MACZ,SAAS,CAAC,SAAS,IAAI,GAAG,OAAO,GAAG,GAAG,KAAK,OAAO;AAAA,MACnD,OAAO;AAAA,QACN,QAAQ;AAAA,QACR,eAAe;AAAA,UACd,OAAO;AAAA,YACN;AAAA,YACA;AAAA,YACA,GAAG,KAAK,OACN,OAAO,CAAC,MAAM,CAAC,mBAAmB,KAAK,EAAE,IAAI,CAAC,EAC9C,IAAI,CAAC,MAAMA,MAAK,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC;AAAA,YAC5C,GAAG,KAAK,OAAO,OAAO,CAAC,MAAM,CAAC,mBAAmB,KAAK,CAAC,CAAC;AAAA,UACzD;AAAA,QACD;AAAA,QACA,aAAa;AAAA,MACd;AAAA,IACD,CAAC;AAAA,EACF;AAIA,QAAM;AAAA,IACL,aAAa;AAAA,MACZ,SAAS,CAAC,SAAS,MAAM,IAAI,GAAG,OAAO,GAAG,GAAG,KAAK,OAAO;AAAA,MACzD,OAAO;AAAA,QACN,QAAQ;AAAA,QACR,eAAe;AAAA,UACd,OAAO;AAAA,YACN;AAAA,YACA,GAAG,KAAK,OAAO,IAAI,CAAC,MAAMA,MAAK,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC;AAAA,YACzD,GAAG,KAAK;AAAA,UACT;AAAA,QACD;AAAA,QACA,KAAK;AAAA,MACN;AAAA,IACD,CAAC;AAAA,EACF;AAIA,aAAWA,MAAK,KAAK,cAAc,WAAW;AAC9C,QAAM,GAAG,OAAOA,MAAK,KAAK,cAAc,OAAO,WAAW,GAAG,QAAQ;AACrE,QAAM,GAAG,GAAGA,MAAK,KAAK,cAAc,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;AAG/D,MAAI,KAAK,QAAQ,WAAW;AAC3B,UAAM,KAAK,QAAQ,UAAU,IAAI;AAAA,EAClC;AACD;;;AErFA,OAAOC,aAAY;AACnB,SAAS,oBAAoB;AAC7B,SAAS,YAAYC,WAAU;AAC/B,OAAOC,WAAU;AACjB,SAAS,gBAAgB,wBAAwB;;;ACJlC,SAAR,gBAAiC,UAAkB,cAA8B;AACvF,MAAI,eAAe,aAAa,UAAU,iCAAiC;AAC3E,iBAAe,SAAS,QAAQ,KAAK,YAAY,IAAI;AACrD,MAAI,aAAa,SAAS,QAAQ,UAAU,YAAY;AACxD,MAAI,iBAAiB,MAAM,eAAe,IAAI;AAC7C,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACrD;AACA,SACC,SAAS,UAAU,GAAG,YAAY,IAClC,qBACA,SAAS,UAAU,UAAU,IAC7B,8BAA8B,YAAY;AAE5C;AAGA,SAAS,aAAa,QAAgB,OAAe,UAAmB;AACvE,MAAI,UAAU,OAAO,UAAU,YAAY,CAAC,EAAE,OAAO,KAAK;AAC1D,SAAO,WAAW,IAAI,WAAW,YAAY,KAAK;AACnD;;;ADPA,eAAO,OAA8B,MAA2B;AAC/D,QAAM,SAAS,IAAI,OAAO;AAK1B,QAAM,OAAO,MAAM,iBAAiB;AAAA,IACnC,QAAQ,EAAE,gBAAgB,KAAK;AAAA,IAC/B,SAAS;AAAA,IACT,SAAS,CAAC,SAAS,MAAM,IAAI,GAAGC,QAAO,GAAG,GAAG,KAAK,OAAO;AAAA,EAC1D,CAAC;AAKD,QAAM,eAAeC,MAAK,QAAQ,KAAK,MAAM,eAAe;AAC5D,MAAI,WAAW,MAAMC,IAAG,SAAS,cAAc,OAAO;AAKtD,aAAW,MAAM,KAAK,mBAAmB,IAAI,QAAQ;AAGrD,QAAM,aAAaD,MAAK,QAAQ,KAAK,MAAM,wCAAwC;AACnF,MAAI,eAAeA,MAAK,KAAK,YAAY,gBAAgB;AACzD,MAAI,eAAeA,MAAK,KAAK,YAAY,gBAAgB;AAGzD,aAAW,gBAAgB,UAAU,YAAY;AAKjD,SAAO,IAAI,kBAAkB,KAAK,WAAW,CAAC;AAG9C,SAAO,IAAI,KAAK,OAAO,OAAO;AAC7B,QAAI;AAIH,YAAM,EAAE,KAAK,IAAI,MAAM,KAAK,cAAc,YAAY;AAItD,aAAO,MAAM,KAAK,IAAI,QAAQ;AAAA,IAC/B,SAAS,GAAQ;AAGhB,WAAK,iBAAiB,CAAC;AACvB,aAAO,YAAY,CAAC;AAAA,IACrB;AAAA,EACD,CAAC;AAGD,eAAa;AAEb,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,SAAS;AACrB,UAAQ,IAAI,SAAS;AAGrB,OAAK,QAAQ,MAAM,QAAQ,IAAI;AAChC;;;AE5EA,SAAS,gBAAAE,qBAAoB;AAC7B,SAAS,cAAAC,aAAY,YAAYC,WAAU;AAC3C,OAAOC,WAAU;;;ACAF,SAAR,YAA6B,WAA2B;AAC9D,SAAO,MAAM,SAAS,KAAK;AAC5B;AAEA,IAAM,QAAgC;AAAA,EACrC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AACR;;;AD1EA,eAAO,WAAkC,MAA2B;AAEnE,QAAM,SAAS,IAAI;AAEnB,QAAM,aAAaC,MAAK,QAAQ,KAAK,MAAM,MAAM;AACjD,QAAM,eAAeA,MAAK,KAAK,YAAY,QAAQ;AACnD,QAAM,eAAeA,MAAK,KAAK,YAAY,QAAQ;AAGnD,MAAI,gBAAgB,MAAMC,IAAG,QAAQD,MAAK,KAAK,cAAc,QAAQ,CAAC,GAAG;AAAA,IAAK,CAAC,MAC9E,EAAE,WAAW,cAAc;AAAA,EAC5B;AACA,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC3C;AACA,iBAAe,WAAW,YAAY;AAKtC,MAAI,WAAWA,MAAK,KAAK,cAAc,WAAW;AAClD,MAAI,WAAW,MAAMC,IAAG,SAAS,UAAU,OAAO;AAGlD,aAAW,gBAAgB,UAAU,YAAY;AAGjD,QAAM,SAAS,IAAI,OAAO;AAG1B,SAAO,IAAI,aAAa,OAAO,OAAO;AACrC,QAAI;AACH,YAAM,MAAM,IAAI,IAAI,GAAG,QAAQ,GAAG;AAClC,YAAM,OAAOD,MAAK,KAAK,KAAK,MAAM,QAAQ,UAAU,IAAI,QAAQ;AAChE,UAAIE,YAAW,IAAI,GAAG;AAErB,eAAO,IAAI,SAAS,MAAMD,IAAG,SAAS,IAAI,GAAG;AAAA,UAC5C,QAAQ;AAAA,UACR,SAAS;AAAA,YACR,gBAAgB,YAAYD,MAAK,QAAQ,IAAI,CAAC;AAAA,UAC/C;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD,SAAS,GAAQ;AAChB,aAAO,YAAY,CAAC;AAAA,IACrB;AAAA,EACD,CAAC;AAGD,QAAM,eAAeA,MAAK,QAAQ,cAAc,gBAAgB;AAChE,SAAO,IAAI,KAAK,OAAO,OAAO;AAC7B,QAAI;AAEH,YAAM,EAAE,KAAK,IAAI,MAAM,OAAO;AAI9B,aAAO,MAAM,KAAK,IAAI,QAAQ;AAAA,IAC/B,SAAS,GAAQ;AAChB,aAAO,YAAY,CAAC;AAAA,IACrB;AAAA,EACD,CAAC;AAGD,EAAAG,cAAa;AAEb,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,SAAS;AACrB,UAAQ,IAAI,SAAS;AAGrB,OAAK,QAAQ,MAAM,QAAQ,IAAI;AAChC;;;AElFA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,4BAA4B;AAMrC,eAAO,IACN,QACA,MACgB;AAEhB,MAAI,aAAa;AACjB,MAAI,mBAAmB;AACvB,QAAM,eAAeC,MAAK,KAAK,QAAQ,gBAAgB;AACvD,QAAM,eAAeA,MAAK,KAAK,QAAQ,gBAAgB;AACvD,MAAIC,IAAG,WAAW,YAAY,GAAG;AAEhC,iBAAa;AAAA,EACd,WAAWA,IAAG,WAAW,YAAY,GAAG;AAGvC,iBAAaD,MAAK,KAAK,QAAQ,qBAAqB;AACpD,QAAI,SAASC,IAAG,aAAa,cAAc,OAAO;AAClD,QAAI,cAAc,MAAM,qBAAqB,QAAQ,cAAc;AAAA,MAClE,QAAQ;AAAA,IACT,CAAC;AACD,IAAAA,IAAG,cAAc,YAAY,YAAY,IAAI;AAC7C,uBAAmB;AAAA,EACpB,OAAO;AACN,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC7C;AAEA,QAAM,QAAQ,MAAM,OAAO,aAAa;AACxC,MAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,QAAQ;AACxC,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC9C;AACA,MAAI,kBAAkB;AACrB,IAAAA,IAAG,OAAO,UAAU;AAAA,EACrB;AAEA,UAAQ,MAAM;AAAA,IACb,KAAK,OAAO;AACX,YAAM,OAAO,IAAI;AACjB;AAAA,IACD;AAAA,IACA,KAAK,SAAS;AACb,YAAM,SAAS,IAAI;AACnB;AAAA,IACD;AAAA,IACA,KAAK,WAAW;AACf,YAAM,WAAW,IAAI;AACrB;AAAA,IACD;AAAA,IACA,SAAS;AACR,cAAQ,IAAI,gCAAgC;AAC5C,YAAM,OAAO,IAAI;AACjB;AAAA,IACD;AAAA,EACD;AACD;","names":["path","path","torpor","fs","path","torpor","path","fs","configDotenv","existsSync","fs","path","path","fs","existsSync","configDotenv","fs","path","path","fs"]}
@@ -107,4 +107,4 @@ export {
107
107
  unauthorized,
108
108
  unprocessable
109
109
  };
110
- //# sourceMappingURL=chunk-VAGHGWM5.js.map
110
+ //# sourceMappingURL=chunk-PTCWU3AW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/response/response.ts","../src/response/badRequest.ts","../src/response/created.ts","../src/response/forbidden.ts","../src/response/methodNotAllowed.ts","../src/response/transfer.ts","../src/response/moved.ts","../src/response/notFound.ts","../src/response/notModified.ts","../src/response/ok.ts","../src/response/redirect.ts","../src/response/seeOther.ts","../src/response/serverError.ts","../src/response/unauthorized.ts","../src/response/unprocessable.ts"],"sourcesContent":["/**\n * Creates a response with the supplied status code and optional body.\n *\n * If the body is an object, it will be converted to JSON and the content-type\n * header set to \"application/json\". Otherwise, if the body is a string, the\n * content-type header will be set to \"text/plain\".\n */\nexport default function response(status: number, body?: object | string): Response {\n\tlet headers: Record<string, string> | undefined = undefined;\n\tif (body) {\n\t\tif (typeof body === \"object\") {\n\t\t\theaders = { \"content-type\": \"application/json\" };\n\t\t\tbody = JSON.stringify(body);\n\t\t} else {\n\t\t\theaders = { \"content-type\": \"text/plain\" };\n\t\t}\n\t}\n\treturn new Response(body, {\n\t\tstatus,\n\t\theaders,\n\t});\n}\n","import response from \"./response\";\n\n/**\n * 400 Bad Request\n *\n * The server cannot or will not process the request due to something that is\n * perceived to be a client error (e.g., malformed request syntax, invalid\n * request message framing, or deceptive request routing).\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400\n */\nexport default function badRequest(body?: object | string): Response {\n\treturn response(400, body);\n}\n","import response from \"./response\";\n\n/**\n * 201 Created\n *\n * The request succeeded, and a new resource was created as a result. This is\n * typically the response sent after POST requests, or some PUT requests.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201\n */\nexport default function created(body?: object | string): Response {\n\treturn response(201, body);\n}\n","import response from \"./response\";\n\n/**\n * 403 Forbidden\n *\n * The client does not have access rights to the content; that is, it is\n * unauthorized, so the server is refusing to give the requested resource.\n * Unlike 401 Unauthorized, the client's identity is known to the server.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403\n */\nexport default function forbidden(body?: object | string): Response {\n\treturn response(403, body);\n}\n","import response from \"./response\";\n\n/**\n * 405 Method Not Allowed\n *\n * The request method is known by the server but is not supported by the target\n * resource. For example, an API may not allow calling DELETE to remove a\n * resource.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405\n */\nexport default function methodNotAllowed(body?: object | string): Response {\n\treturn response(405, body);\n}\n","/**\n * Creates a redirect response with the supplied status code.\n */\nexport default function transfer(\n\tstatus: 300 | 301 | 302 | 303 | 304 | 307 | 308,\n\tlocation: string,\n): Response {\n\treturn new Response(null, {\n\t\tstatus,\n\t\theaders: {\n\t\t\tlocation,\n\t\t},\n\t});\n}\n","import transfer from \"./transfer\";\n\n/**\n * 308 Permanent Redirect\n *\n * This means that the resource is now permanently located at another URI,\n * specified by the Location: HTTP Response header. This has the same semantics\n * as the 301 Moved Permanently HTTP response code, with the exception that the\n * user agent must not change the HTTP method used: if a POST was used in the\n * first request, a POST must be used in the second request.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308\n */\nexport default function moved(location: string): Response {\n\treturn transfer(308, location);\n}\n","import response from \"./response\";\n\n/**\n * 404 Not Found\n *\n * The server cannot find the requested resource. In the browser, this means the\n * URL is not recognized. In an API, this can also mean that the endpoint is\n * valid but the resource itself does not exist. Servers may also send this\n * response instead of 403 Forbidden to hide the existence of a resource from an\n * unauthorized client. This response code is probably the most well known due\n * to its frequent occurrence on the web.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404\n */\nexport default function notFound(body?: object | string): Response {\n\treturn response(404, body);\n}\n","import transfer from \"./transfer\";\n\n/**\n * 304 Not Modified\n *\n * This is used for caching purposes. It tells the client that the response has\n * not been modified, so the client can continue to use the same cached version\n * of the response.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304\n */\nexport default function notModified(location: string): Response {\n\treturn transfer(304, location);\n}\n","import response from \"./response\";\n\n/**\n * 200 OK\n *\n * The request succeeded. The result meaning of \"success\" depends on the HTTP\n * method:\n * - GET: The resource has been fetched and transmitted in the message body.\n * - HEAD: The representation headers are included in the response without any\n * message body.\n * - PUT or POST: The resource describing the result of the action is\n * transmitted in the message body.\n * - TRACE: The message body contains the request message as received by the\n * server.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200\n */\nexport default function ok(body?: object | string): Response {\n\treturn response(200, body);\n}\n","import transfer from \"./transfer\";\n\n/**\n * 307 Temporary Redirect\n *\n * The server sends this response to direct the client to get the requested\n * resource at another URI with the same method that was used in the prior\n * request. This has the same semantics as the 302 Found HTTP response code,\n * with the exception that the user agent must not change the HTTP method used:\n * if a POST was used in the first request, a POST must be used in the second\n * request.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307\n */\nexport default function redirect(location: string): Response {\n\treturn transfer(307, location);\n}\n","import transfer from \"./transfer\";\n\n/**\n * 303 See Other\n *\n * The server sent this response to direct the client to get the requested\n * resource at another URI with a GET request.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303\n */\nexport default function seeOther(location: string): Response {\n\treturn transfer(303, location);\n}\n","import response from \"./response\";\n\n/**\n * 500 Server Error\n *\n * The server has encountered a situation it does not know how to handle.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500\n */\nexport default function serverError(body?: object | string): Response {\n\treturn response(500, body);\n}\n","import response from \"./response\";\n\n/**\n * 401 Unauthorized\n *\n * Although the HTTP standard specifies \"unauthorized\", semantically this\n * response means \"unauthenticated\". That is, the client must authenticate\n * itself to get the requested response.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401\n */\nexport default function unauthorized(body?: object | string): Response {\n\treturn response(401, body);\n}\n","import response from \"./response\";\n\n/**\n * 422 Unprocessable Content\n *\n * The request was well-formed but was unable to be followed due to semantic errors.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422\n */\nexport default function unprocessable(body?: object | string): Response {\n\treturn response(422, body);\n}\n"],"mappings":";AAOe,SAAR,SAA0B,QAAgB,MAAkC;AAClF,MAAI,UAA8C;AAClD,MAAI,MAAM;AACT,QAAI,OAAO,SAAS,UAAU;AAC7B,gBAAU,EAAE,gBAAgB,mBAAmB;AAC/C,aAAO,KAAK,UAAU,IAAI;AAAA,IAC3B,OAAO;AACN,gBAAU,EAAE,gBAAgB,aAAa;AAAA,IAC1C;AAAA,EACD;AACA,SAAO,IAAI,SAAS,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,EACD,CAAC;AACF;;;ACVe,SAAR,WAA4B,MAAkC;AACpE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACHe,SAAR,QAAyB,MAAkC;AACjE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACDe,SAAR,UAA2B,MAAkC;AACnE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACFe,SAAR,iBAAkC,MAAkC;AAC1E,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACVe,SAAR,SACN,QACA,UACW;AACX,SAAO,IAAI,SAAS,MAAM;AAAA,IACzB;AAAA,IACA,SAAS;AAAA,MACR;AAAA,IACD;AAAA,EACD,CAAC;AACF;;;ACAe,SAAR,MAAuB,UAA4B;AACzD,SAAO,SAAS,KAAK,QAAQ;AAC9B;;;ACDe,SAAR,SAA0B,MAAkC;AAClE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACLe,SAAR,YAA6B,UAA4B;AAC/D,SAAO,SAAS,KAAK,QAAQ;AAC9B;;;ACIe,SAAR,GAAoB,MAAkC;AAC5D,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACLe,SAAR,SAA0B,UAA4B;AAC5D,SAAO,SAAS,KAAK,QAAQ;AAC9B;;;ACNe,SAAR,SAA0B,UAA4B;AAC5D,SAAO,SAAS,KAAK,QAAQ;AAC9B;;;ACHe,SAAR,YAA6B,MAAkC;AACrE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACAe,SAAR,aAA8B,MAAkC;AACtE,SAAO,SAAS,KAAK,IAAI;AAC1B;;;ACJe,SAAR,cAA+B,MAAkC;AACvE,SAAO,SAAS,KAAK,IAAI;AAC1B;","names":[]}
@@ -0,0 +1,13 @@
1
+ // src/site/pathToRegex.ts
2
+ function pathToRegex(path) {
3
+ const pattern = path.split("/").map((p) => {
4
+ return p.replace(/\[([^\/]+?)\]/, "(?<$1>[^\\/]+?)");
5
+ }).join("\\/").replaceAll("*", ".*") + // Ignore trailing slashes -- `/path` should be treated the same as `/path/`
6
+ "/*";
7
+ return new RegExp(`^${pattern}/*$`);
8
+ }
9
+
10
+ export {
11
+ pathToRegex
12
+ };
13
+ //# sourceMappingURL=chunk-SJVHHGVW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/site/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":";AAAe,SAAR,YAA6B,MAAsB;AACzD,QAAM,UACL,KACE,MAAM,GAAG,EAET,IAAI,CAAC,MAAM;AACX,WAAO,EAAE,QAAQ,iBAAiB,iBAAiB;AAAA,EACpD,CAAC,EACA,KAAK,KAAK,EAEV,WAAW,KAAK,IAAI;AAAA,EAEtB;AACD,SAAO,IAAI,OAAO,IAAI,OAAO,KAAK;AACnC;","names":[]}
package/dist/index.cjs CHANGED
@@ -39,8 +39,9 @@ module.exports = __toCommonJS(index_exports);
39
39
  function pathToRegex(path2) {
40
40
  const pattern = path2.split("/").map((p) => {
41
41
  return p.replace(/\[([^\/]+?)\]/, "(?<$1>[^\\/]+?)");
42
- }).join("\\/").replaceAll("*", ".*");
43
- return new RegExp(`^${pattern}$`);
42
+ }).join("\\/").replaceAll("*", ".*") + // Ignore trailing slashes -- `/path` should be treated the same as `/path/`
43
+ "/*";
44
+ return new RegExp(`^${pattern}/*$`);
44
45
  }
45
46
 
46
47
  // src/site/Router.ts
@@ -202,6 +203,12 @@ var Site = class {
202
203
  plugins = [(0, import_vite_tsconfig_paths.default)({ loose: true })];
203
204
  // Is default adapter a bad idea?
204
205
  adapter = defaultAdapter_default;
206
+ /**
207
+ * Extra inputs, as absolute file paths, that will be compiled with the
208
+ * output. What you do with them after that is up to you. File paths ending
209
+ * with server.ts/js will only be compiled with the server output
210
+ */
211
+ inputs = [];
205
212
  constructor() {
206
213
  this.root = process.cwd();
207
214
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/site/pathToRegex.ts","../src/site/Router.ts","../src/site/Site.ts","../src/types/RouteType.ts","../src/site/defaultAdapter.ts"],"sourcesContent":["import Router from \"./site/Router\";\nimport Site from \"./site/Site\";\nimport type Adapter from \"./types/Adapter\";\nimport type PageEndPoint from \"./types/PageEndPoint\";\nimport type PageLoadEvent from \"./types/PageLoadEvent\";\nimport type PageServerAction from \"./types/PageServerAction\";\nimport type PageServerEndPoint from \"./types/PageServerEndPoint\";\nimport type PageServerLoad from \"./types/PageServerLoad\";\nimport type ServerEndPoint from \"./types/ServerEndPoint\";\nimport type ServerHook from \"./types/ServerHook\";\nimport type ServerLoadEvent from \"./types/ServerLoadEvent\";\nimport type ServerRequest from \"./types/ServerRequest\";\n\nexport { Site, Router };\n\nexport type {\n\tAdapter,\n\tPageEndPoint,\n\tPageServerEndPoint,\n\tPageServerLoad,\n\tPageServerAction,\n\tServerEndPoint,\n\tServerRequest,\n\tServerHook,\n\tPageLoadEvent,\n\tServerLoadEvent,\n};\n","export default function pathToRegex(path: string): RegExp {\n\tconst pattern = path\n\t\t.split(\"/\")\n\t\t.map((p) => {\n\t\t\treturn p.replace(/\\[([^\\/]+?)\\]/, \"(?<$1>[^\\\\/]+?)\");\n\t\t})\n\t\t.join(\"\\\\/\")\n\t\t.replaceAll(\"*\", \".*\");\n\treturn new RegExp(`^${pattern}$`);\n}\n","import type LayoutHandler from \"../types/LayoutHandler\";\nimport type ManifestRoute from \"../types/ManifestRoute\";\nimport type RouteHandler from \"../types/RouteHandler\";\nimport pathToRegex from \"./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[]) {\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>) {\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) {\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","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { Plugin } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport Adapter from \"../types/Adapter\";\nimport {\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: { path: string; file: string; type: number }[] = [];\n\t// Is default plugins a bad idea?\n\t// HACK: Set loose because otherwise it uses a list of allowed extensions\n\t// TODO: Should probably just do this ourselves and let the user pass in\n\t// tsconfigPaths themselves if they want to do something funky\n\tplugins: Plugin[] = [tsconfigPaths({ loose: true })];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\tasync addRouteFolder(folder: string) {\n\t\tconst routeFolder = path.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(path.basename(file))) {\n\t\t\t\tlet routePath = file\n\t\t\t\t\t.replace(/^\\//, \"\")\n\t\t\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t\t\t.replace(/\\/$/, \"\");\n\t\t\t\troutePath = routePath.length > 0 ? `/${routePath}` : \"/\";\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = path.relative(this.root, path.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({ path: routePath, file, type });\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\taddRouteFile(path: string, file: string) {\n\t\tlet type = this.#routeType(file);\n\t\tthis.routes.push({ path, file, type });\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routeType(file: string): number {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// TODO: You could make your site in a single file, like e.g. Hono...\n\t//addPage(path: string, endPoint: PageEndPoint, serverEndPoint?: PageServerEndPoint) {}\n\t//addEndPoint(path: string, endPoint: ServerEndPoint) {}\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","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;\n","import Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n"],"mappings":"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","names":["path","path","tsconfigPaths","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/site/pathToRegex.ts","../src/site/Router.ts","../src/site/Site.ts","../src/types/RouteType.ts","../src/site/defaultAdapter.ts"],"sourcesContent":["import Router from \"./site/Router\";\nimport Site from \"./site/Site\";\nimport type Adapter from \"./types/Adapter\";\nimport type PageEndPoint from \"./types/PageEndPoint\";\nimport type PageLoadEvent from \"./types/PageLoadEvent\";\nimport type PageServerAction from \"./types/PageServerAction\";\nimport type PageServerEndPoint from \"./types/PageServerEndPoint\";\nimport type PageServerLoad from \"./types/PageServerLoad\";\nimport type ServerEndPoint from \"./types/ServerEndPoint\";\nimport type ServerHook from \"./types/ServerHook\";\nimport type ServerLoadEvent from \"./types/ServerLoadEvent\";\nimport type ServerRequest from \"./types/ServerRequest\";\n\nexport { Site, Router };\n\nexport type {\n\tAdapter,\n\tPageEndPoint,\n\tPageServerEndPoint,\n\tPageServerLoad,\n\tPageServerAction,\n\tServerEndPoint,\n\tServerRequest,\n\tServerHook,\n\tPageLoadEvent,\n\tServerLoadEvent,\n};\n","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","import type LayoutHandler from \"../types/LayoutHandler\";\nimport type ManifestRoute from \"../types/ManifestRoute\";\nimport type RouteHandler from \"../types/RouteHandler\";\nimport pathToRegex from \"./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\ntype Match = {\n\thandler: RouteHandler;\n\tparams?: Record<string, string>;\n\tquery: URLSearchParams;\n};\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { Plugin } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport Adapter from \"../types/Adapter\";\nimport {\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: { path: string; file: string; type: number }[] = [];\n\t// Is default plugins a bad idea?\n\t// HACK: Set loose because otherwise it uses a list of allowed extensions\n\t// TODO: Should probably just do this ourselves and let the user pass in\n\t// tsconfigPaths themselves if they want to do something funky\n\tplugins: Plugin[] = [tsconfigPaths({ loose: true })];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\t/**\n\t * Extra inputs, as absolute file paths, that will be compiled with the\n\t * output. What you do with them after that is up to you. File paths ending\n\t * with server.ts/js will only be compiled with the server output\n\t */\n\tinputs: string[] = [];\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\tasync addRouteFolder(folder: string): Promise<void> {\n\t\tconst routeFolder = path.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(path.basename(file))) {\n\t\t\t\tlet routePath = file\n\t\t\t\t\t.replace(/^\\//, \"\")\n\t\t\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t\t\t.replace(/\\/$/, \"\");\n\t\t\t\troutePath = routePath.length > 0 ? `/${routePath}` : \"/\";\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = path.relative(this.root, path.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({ path: routePath, file, type });\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\taddRouteFile(path: string, file: string): void {\n\t\tlet type = this.#routeType(file);\n\t\tthis.routes.push({ path, file, type });\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routeType(file: string): number {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// TODO: You could make your site in a single file, like e.g. Hono...\n\t//addPage(path: string, endPoint: PageEndPoint, serverEndPoint?: PageServerEndPoint) {}\n\t//addEndPoint(path: string, endPoint: ServerEndPoint) {}\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","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;\n","import Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n"],"mappings":"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","names":["path","path","tsconfigPaths","path","fs"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- export { A as Adapter, S as Site } from './Site-CM2pZtq6.cjs';
1
+ export { A as Adapter, S as Site } from './Site-BeRKXeJ4.cjs';
2
2
  import { Component } from '@torpor/view';
3
- import { C as CookieHelper, H as HeaderHelper } from './Server-DhJ1nRFR.cjs';
3
+ import { C as CookieHelper, H as HeaderHelper } from './Server-BC_dixZQ.cjs';
4
4
  import 'vite';
5
5
  import 'cookie';
6
6
 
@@ -35,13 +35,7 @@ declare class Router {
35
35
  constructor();
36
36
  addPages(routes: ManifestRoute[]): this;
37
37
  addPage(path: string, type: number, endPoint: () => Promise<any>): this;
38
- match(path: string, query: URLSearchParams): {
39
- handler: RouteHandler;
40
- params: {
41
- [key: string]: string;
42
- } | undefined;
43
- query: URLSearchParams;
44
- } | undefined;
38
+ match(path: string, query: URLSearchParams): Match | undefined;
45
39
  }
46
40
  declare class Route {
47
41
  path: string;
@@ -49,6 +43,11 @@ declare class Route {
49
43
  handler: RouteHandler;
50
44
  constructor(path: string, handler: RouteHandler);
51
45
  }
46
+ type Match = {
47
+ handler: RouteHandler;
48
+ params?: Record<string, string>;
49
+ query: URLSearchParams;
50
+ };
52
51
 
53
52
  type PageLoadEvent = {
54
53
  /**
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { A as Adapter, S as Site } from './Site-BB6kV7wC.js';
1
+ export { A as Adapter, S as Site } from './Site-D70KrWlY.js';
2
2
  import { Component } from '@torpor/view';
3
- import { C as CookieHelper, H as HeaderHelper } from './Server-DhJ1nRFR.js';
3
+ import { C as CookieHelper, H as HeaderHelper } from './Server-BC_dixZQ.js';
4
4
  import 'vite';
5
5
  import 'cookie';
6
6
 
@@ -35,13 +35,7 @@ declare class Router {
35
35
  constructor();
36
36
  addPages(routes: ManifestRoute[]): this;
37
37
  addPage(path: string, type: number, endPoint: () => Promise<any>): this;
38
- match(path: string, query: URLSearchParams): {
39
- handler: RouteHandler;
40
- params: {
41
- [key: string]: string;
42
- } | undefined;
43
- query: URLSearchParams;
44
- } | undefined;
38
+ match(path: string, query: URLSearchParams): Match | undefined;
45
39
  }
46
40
  declare class Route {
47
41
  path: string;
@@ -49,6 +43,11 @@ declare class Route {
49
43
  handler: RouteHandler;
50
44
  constructor(path: string, handler: RouteHandler);
51
45
  }
46
+ type Match = {
47
+ handler: RouteHandler;
48
+ params?: Record<string, string>;
49
+ query: URLSearchParams;
50
+ };
52
51
 
53
52
  type PageLoadEvent = {
54
53
  /**
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pathToRegex
3
- } from "./chunk-T5K52YVJ.js";
3
+ } from "./chunk-SJVHHGVW.js";
4
4
 
5
5
  // src/site/Router.ts
6
6
  var Router = class {
@@ -161,6 +161,12 @@ var Site = class {
161
161
  plugins = [tsconfigPaths({ loose: true })];
162
162
  // Is default adapter a bad idea?
163
163
  adapter = defaultAdapter_default;
164
+ /**
165
+ * Extra inputs, as absolute file paths, that will be compiled with the
166
+ * output. What you do with them after that is up to you. File paths ending
167
+ * with server.ts/js will only be compiled with the server output
168
+ */
169
+ inputs = [];
164
170
  constructor() {
165
171
  this.root = process.cwd();
166
172
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/site/Router.ts","../src/site/Site.ts","../src/types/RouteType.ts","../src/site/defaultAdapter.ts"],"sourcesContent":["import type LayoutHandler from \"../types/LayoutHandler\";\nimport type ManifestRoute from \"../types/ManifestRoute\";\nimport type RouteHandler from \"../types/RouteHandler\";\nimport pathToRegex from \"./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[]) {\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>) {\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) {\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","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { Plugin } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport Adapter from \"../types/Adapter\";\nimport {\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: { path: string; file: string; type: number }[] = [];\n\t// Is default plugins a bad idea?\n\t// HACK: Set loose because otherwise it uses a list of allowed extensions\n\t// TODO: Should probably just do this ourselves and let the user pass in\n\t// tsconfigPaths themselves if they want to do something funky\n\tplugins: Plugin[] = [tsconfigPaths({ loose: true })];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\tasync addRouteFolder(folder: string) {\n\t\tconst routeFolder = path.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(path.basename(file))) {\n\t\t\t\tlet routePath = file\n\t\t\t\t\t.replace(/^\\//, \"\")\n\t\t\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t\t\t.replace(/\\/$/, \"\");\n\t\t\t\troutePath = routePath.length > 0 ? `/${routePath}` : \"/\";\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = path.relative(this.root, path.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({ path: routePath, file, type });\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\taddRouteFile(path: string, file: string) {\n\t\tlet type = this.#routeType(file);\n\t\tthis.routes.push({ path, file, type });\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routeType(file: string): number {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// TODO: You could make your site in a single file, like e.g. Hono...\n\t//addPage(path: string, endPoint: PageEndPoint, serverEndPoint?: PageServerEndPoint) {}\n\t//addEndPoint(path: string, endPoint: ServerEndPoint) {}\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","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;\n","import Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n"],"mappings":"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","names":["path","path"]}
1
+ {"version":3,"sources":["../src/site/Router.ts","../src/site/Site.ts","../src/types/RouteType.ts","../src/site/defaultAdapter.ts"],"sourcesContent":["import type LayoutHandler from \"../types/LayoutHandler\";\nimport type ManifestRoute from \"../types/ManifestRoute\";\nimport type RouteHandler from \"../types/RouteHandler\";\nimport pathToRegex from \"./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\ntype Match = {\n\thandler: RouteHandler;\n\tparams?: Record<string, string>;\n\tquery: URLSearchParams;\n};\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { Plugin } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport Adapter from \"../types/Adapter\";\nimport {\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: { path: string; file: string; type: number }[] = [];\n\t// Is default plugins a bad idea?\n\t// HACK: Set loose because otherwise it uses a list of allowed extensions\n\t// TODO: Should probably just do this ourselves and let the user pass in\n\t// tsconfigPaths themselves if they want to do something funky\n\tplugins: Plugin[] = [tsconfigPaths({ loose: true })];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\t/**\n\t * Extra inputs, as absolute file paths, that will be compiled with the\n\t * output. What you do with them after that is up to you. File paths ending\n\t * with server.ts/js will only be compiled with the server output\n\t */\n\tinputs: string[] = [];\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\tasync addRouteFolder(folder: string): Promise<void> {\n\t\tconst routeFolder = path.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(path.basename(file))) {\n\t\t\t\tlet routePath = file\n\t\t\t\t\t.replace(/^\\//, \"\")\n\t\t\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t\t\t.replace(/\\/$/, \"\");\n\t\t\t\troutePath = routePath.length > 0 ? `/${routePath}` : \"/\";\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = path.relative(this.root, path.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({ path: routePath, file, type });\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\taddRouteFile(path: string, file: string): void {\n\t\tlet type = this.#routeType(file);\n\t\tthis.routes.push({ path, file, type });\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routeType(file: string): number {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// TODO: You could make your site in a single file, like e.g. Hono...\n\t//addPage(path: string, endPoint: PageEndPoint, serverEndPoint?: PageServerEndPoint) {}\n\t//addEndPoint(path: string, endPoint: ServerEndPoint) {}\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","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;\n","import Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n"],"mappings":"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","names":["path","path"]}