@torpor/build 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/dist/Server-CB99REgs.d.cts +74 -0
  4. package/dist/Server-CB99REgs.d.ts +74 -0
  5. package/dist/Site-CgoeDt8k.d.cts +29 -0
  6. package/dist/Site-D95nwrAg.d.ts +29 -0
  7. package/dist/adapters/cloudflare/index.cjs +125 -0
  8. package/dist/adapters/cloudflare/index.cjs.map +1 -0
  9. package/dist/adapters/cloudflare/index.d.cts +13 -0
  10. package/dist/adapters/cloudflare/index.d.ts +13 -0
  11. package/dist/adapters/cloudflare/index.js +80 -0
  12. package/dist/adapters/cloudflare/index.js.map +1 -0
  13. package/dist/adapters/node/index.cjs +152 -0
  14. package/dist/adapters/node/index.cjs.map +1 -0
  15. package/dist/adapters/node/index.d.cts +8 -0
  16. package/dist/adapters/node/index.d.ts +8 -0
  17. package/dist/adapters/node/index.js +8 -0
  18. package/dist/adapters/node/index.js.map +1 -0
  19. package/dist/bin/index.cjs +541 -93
  20. package/dist/bin/index.cjs.map +1 -1
  21. package/dist/bin/index.js +511 -22
  22. package/dist/bin/index.js.map +1 -1
  23. package/dist/chunk-5X4T3PZN.js +23 -0
  24. package/dist/chunk-5X4T3PZN.js.map +1 -0
  25. package/dist/chunk-ALHFYD7U.js +113 -0
  26. package/dist/chunk-ALHFYD7U.js.map +1 -0
  27. package/dist/chunk-V4XTDQEV.js +19 -0
  28. package/dist/chunk-V4XTDQEV.js.map +1 -0
  29. package/dist/chunk-VAGHGWM5.js +110 -0
  30. package/dist/chunk-VAGHGWM5.js.map +1 -0
  31. package/dist/index.cjs +200 -97
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +33 -36
  34. package/dist/index.d.ts +33 -36
  35. package/dist/index.js +85 -17
  36. package/dist/index.js.map +1 -1
  37. package/dist/metafile-cjs.json +1 -1
  38. package/dist/metafile-esm.json +1 -1
  39. package/dist/response.js +17 -91
  40. package/dist/response.js.map +1 -1
  41. package/package.json +26 -9
  42. package/src/adapters/cloudflare/_worker.ts +38 -0
  43. package/src/adapters/cloudflare/index.ts +98 -0
  44. package/src/adapters/node/constants.ts +1 -0
  45. package/src/adapters/node/createFetchHandler.ts +29 -0
  46. package/src/adapters/node/createMiddlewareHandler.ts +79 -0
  47. package/src/adapters/node/createNodeServer.ts +8 -0
  48. package/src/adapters/node/flattenHeaders.ts +44 -0
  49. package/src/adapters/node/index.ts +18 -0
  50. package/src/adapters/node/nodeMessageToNodeResponse.ts +89 -0
  51. package/src/adapters/node/nodeMessageToRequest.ts +43 -0
  52. package/src/adapters/node/readableToBuffer.ts +16 -0
  53. package/src/adapters/node/requestToNodeMessage.ts +26 -0
  54. package/src/adapters/node/responseToNodeResponse.ts +44 -0
  55. package/src/bin/index.ts +43 -36
  56. package/src/index.ts +6 -14
  57. package/src/server/CookieHelper.ts +36 -0
  58. package/src/server/HeaderHelper.ts +25 -0
  59. package/src/server/Server.ts +119 -0
  60. package/src/server/ServerEvent.ts +33 -0
  61. package/src/server/ServerFunction.ts +5 -0
  62. package/src/server/contentType.ts +85 -0
  63. package/src/site/Router.ts +136 -0
  64. package/src/site/Routerx.ts +67 -0
  65. package/src/site/Site.ts +114 -0
  66. package/src/site/clientEntry.ts +22 -20
  67. package/src/site/manifest.ts +49 -0
  68. package/src/site/pathToRegex.ts +10 -0
  69. package/src/site/prepareTemplate.ts +20 -0
  70. package/src/site/runBuild.ts +92 -0
  71. package/src/site/runDev.ts +84 -0
  72. package/src/site/runPreview.ts +83 -0
  73. package/src/site/serverEntry.ts +113 -200
  74. package/src/types/Adapter.ts +10 -0
  75. package/src/types/HttpMethod.ts +12 -0
  76. package/src/types/LayoutHandler.ts +7 -0
  77. package/src/types/ManifestRoute.ts +8 -0
  78. package/src/types/MiddlewareFunction.ts +8 -0
  79. package/src/types/PageEndPoint.ts +4 -3
  80. package/src/types/{PageEvent.ts → PageLoadEvent.ts} +3 -2
  81. package/src/types/PageServerAction.ts +5 -2
  82. package/src/types/PageServerEndPoint.ts +1 -0
  83. package/src/types/PageServerLoad.ts +5 -2
  84. package/src/types/RouteHandler.ts +6 -5
  85. package/src/types/RouteHandlerCollection.ts +1 -0
  86. package/src/types/RouteLayoutHandler.ts +3 -2
  87. package/src/types/RouteMatchResult.ts +3 -2
  88. package/src/types/RouteType.ts +7 -0
  89. package/src/types/ServerEndPoint.ts +1 -0
  90. package/src/types/ServerHook.ts +3 -2
  91. package/src/types/{ServerEvent.ts → ServerLoadEvent.ts} +13 -6
  92. package/src/types/ServerRequest.ts +5 -2
  93. package/src/types/manifest.d.ts +7 -0
  94. package/test/app.test.ts +47 -0
  95. package/tsconfig.json +1 -1
  96. package/tsup.config.ts +11 -1
  97. package/vitest.config.ts +3 -0
  98. package/dist/chunk-L7GOYKUG.js +0 -93
  99. package/dist/chunk-L7GOYKUG.js.map +0 -1
  100. package/src/site/FileSystemRouter.ts +0 -25
  101. package/src/site/buildRoutePath.ts +0 -25
  102. package/src/site/defineConfig.ts +0 -75
  103. package/src/site/lazyRoute.ts +0 -72
  104. package/src/site/routeHandlers.ts +0 -126
  105. package/src/types/CookieHelper.ts +0 -8
  106. package/src/types/UserConfig.ts +0 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/index.ts"],"sourcesContent":["#! /usr/bin/env node\n//import { existsSync, promises as fs } from \"node:fs\";\nimport fs from \"node:fs\";\nimport path from \"path\";\nimport defineConfig from \"../site/defineConfig\";\nimport { type UserConfig } from \"../types/UserConfig\";\n\n// Check for a torpor.config.js/ts file in the working directory\n// TODO: Make sure it's valid, try/catch, etc\n// TODO: There has GOT to be an easier way\nlet options: UserConfig | undefined;\nconst workingDir = process.cwd();\nconst jsConfigFile = path.join(workingDir, \"torpor.config.js\");\nconst tsConfigFile = path.join(workingDir, \"torpor.config.ts\");\nlet source: string | undefined;\nif (fs.existsSync(jsConfigFile)) {\n\t//const configFile = path.relative(\".\", tsConfigFile);\n\t//options = await import(configFile);\n\tsource = fs.readFileSync(jsConfigFile, \"utf8\");\n\tsource = source\n\t\t.replace(\n\t\t\t/import\\s+\\{\\s+defineConfig\\s+\\}\\s+from\\s+[\"']@torpor\\/build[\"']/,\n\t\t\t\"const defineConfig = (x) => x\",\n\t\t)\n\t\t.replace(\"export default\", \"\");\n} else if (fs.existsSync(tsConfigFile)) {\n\tconsole.log(\"TS config file is not supported\");\n}\n\nif (source) {\n\toptions = eval(source);\n}\n\ndefineConfig(options);\n\n// This already gets done in vinxi.createApp so we can't do it twice\n//const app = defineConfig(options);\n//if (process.argv.includes(\"--dev\")) {\n//\tawait app.dev();\n//} else if (process.argv.includes(\"--build\")) {\n//\tawait app.build();\n//}\n"],"mappings":";;;;;;AAEA,OAAO,QAAQ;AACf,OAAO,UAAU;AAOjB,IAAI;AACJ,IAAM,aAAa,QAAQ,IAAI;AAC/B,IAAM,eAAe,KAAK,KAAK,YAAY,kBAAkB;AAC7D,IAAM,eAAe,KAAK,KAAK,YAAY,kBAAkB;AAC7D,IAAI;AACJ,IAAI,GAAG,WAAW,YAAY,GAAG;AAGhC,WAAS,GAAG,aAAa,cAAc,MAAM;AAC7C,WAAS,OACP;AAAA,IACA;AAAA,IACA;AAAA,EACD,EACC,QAAQ,kBAAkB,EAAE;AAC/B,WAAW,GAAG,WAAW,YAAY,GAAG;AACvC,UAAQ,IAAI,iCAAiC;AAC9C;AAEA,IAAI,QAAQ;AACX,YAAU,KAAK,MAAM;AACtB;AAEA,aAAa,OAAO;","names":[]}
1
+ {"version":3,"sources":["../../src/bin/index.ts","../../src/site/runBuild.ts","../../src/site/manifest.ts","../../src/site/runDev.ts","../../src/adapters/node/nodeMessageToNodeResponse.ts","../../src/adapters/node/readableToBuffer.ts","../../src/adapters/node/requestToNodeMessage.ts","../../src/adapters/node/createMiddlewareHandler.ts","../../src/site/pathToRegex.ts","../../src/server/CookieHelper.ts","../../src/server/HeaderHelper.ts","../../src/server/ServerEvent.ts","../../src/server/Server.ts"],"sourcesContent":["#! /usr/bin/env node\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { transformWithEsbuild } from \"vite\";\nimport Site from \"../site/Site\";\nimport runBuild from \"../site/runBuild\";\nimport runDev from \"../site/runDev\";\n\nrun();\n\nasync function run() {\n\t// Look for and load a site.config.js/ts file in the working directory\n\tconst workingDir = process.cwd();\n\tlet configFile = \"\";\n\tlet deleteConfigFile = false;\n\tconst jsConfigFile = path.join(workingDir, \"site.config.js\");\n\tconst tsConfigFile = path.join(workingDir, \"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(workingDir, \"site.config.temp.js\");\n\t\tlet source = (\n\t\t\tawait transformWithEsbuild(fs.readFileSync(tsConfigFile, \"utf-8\"), tsConfigFile, {\n\t\t\t\tloader: \"ts\",\n\t\t\t})\n\t\t).code;\n\t\tfs.writeFileSync(configFile, source);\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\tif (process.argv.includes(\"--dev\")) {\n\t\tawait runDev(site);\n\t} else if (process.argv.includes(\"--build\")) {\n\t\tawait runBuild(site);\n\t}\n}\n","import torpor from \"@torpor/unplugin/vite\";\nimport { existsSync, promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { build, defineConfig } from \"vite\";\nimport Site from \"./Site.ts\";\nimport manifest from \"./manifest.ts\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\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) {\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\tlet clientScript = path.resolve(__dirname, \"../../src/site/clientEntry.ts\");\n\tlet serverScript = path.resolve(__dirname, \"../../src/site/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: [\n\t\t\t\tmanifest(site),\n\t\t\t\t// @ts-ignore\n\t\t\t\ttorpor(),\n\t\t\t\t...site.plugins,\n\t\t\t],\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],\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: [\n\t\t\t\tmanifest(site, true),\n\t\t\t\t// @ts-ignore\n\t\t\t\ttorpor(),\n\t\t\t\t...site.plugins,\n\t\t\t],\n\t\t\tbuild: {\n\t\t\t\toutDir: serverFolder,\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: [serverScript, ...site.routes.map((r) => path.resolve(site.root, r.file))],\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\tload(id) {\n\t\t\tif (id === moduleId) {\n\t\t\t\treturn `\n${!server ? \"const load = { default: { load: true } };\" : \"\"}\nexport default {\n routes: [\n ${site.routes\n\t\t\t.map((r) => {\n\t\t\t\tif (server || !/server\\.(ts|js)$/.test(r.file)) {\n\t\t\t\t\treturn `{ path: \"${r.path}\", file: \"${r.file}\", type: ${r.type}, endPoint: ${server || !/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}\", file: \"${r.file}\", 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 { fileURLToPath } from \"node:url\";\nimport { createServer as createViteServer } from \"vite\";\nimport createMiddlewareHandler from \"../adapters/node/createMiddlewareHandler.ts\";\nimport { serverError } from \"../response.ts\";\nimport Server from \"../server/Server.ts\";\nimport Site from \"./Site.ts\";\nimport manifest from \"./manifest.ts\";\nimport prepareTemplate from \"./prepareTemplate.ts\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport default async function runDev(site: Site) {\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: [\n\t\t\tmanifest(site, true),\n\t\t\t// @ts-ignore not sure...\n\t\t\ttorpor(),\n\t\t\t...site.plugins,\n\t\t],\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 clientScript = path.resolve(__dirname, \"../../src/site/clientEntry.ts\");\n\tconst serverScript = path.resolve(__dirname, \"../../src/site/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(createMiddlewareHandler(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","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\ntype 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 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 createMiddlewareHandler(\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\tawait 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\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\tcnext(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","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 { 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 updated value\n\t\tif (this.cookies.has(name)) {\n\t\t\treturn this.cookies.get(name);\n\t\t}\n\t\t// Otherwise, return the cookie 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) {\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) {\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) {\n\t\tthis.headers.set(name, value);\n\t}\n\n\tdelete(name: string) {\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;\n\t// TODO: Should we cast types??\n\tparams?: { [key: string]: string };\n\n\tcookies: CookieHelper;\n\theaders: HeaderHelper;\n\n\tconstructor(request: Request, params?: { [key: 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\t}\n\n\taddHeaders() {\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","import pathToRegex from \"../site/pathToRegex\";\nimport type MiddlewareFunction from \"../types/MiddlewareFunction\";\nimport ServerEvent from \"./ServerEvent\";\nimport type ServerFunction from \"./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\treturn this;\n\t}\n\n\tmatch(path: string) {\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\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"],"mappings":"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","names":["fs","path","path","path","torpor","fs","path","fileURLToPath","Readable","path","buildNext","path","__dirname","path","fileURLToPath","torpor","fs","path","fs"]}
@@ -0,0 +1,23 @@
1
+ // src/adapters/node/flattenHeaders.ts
2
+ function flattenHeaders(headers) {
3
+ const flatHeaders = new Headers();
4
+ for (const [key, value] of Object.entries(headers)) {
5
+ if (value === void 0 || value === null) {
6
+ continue;
7
+ } else if (Array.isArray(value)) {
8
+ for (const v of value) {
9
+ if (v !== void 0 && v !== null) {
10
+ value.forEach((v2) => flatHeaders.append(key, v2));
11
+ }
12
+ }
13
+ } else {
14
+ flatHeaders.set(key, String(value));
15
+ }
16
+ }
17
+ return flatHeaders;
18
+ }
19
+
20
+ export {
21
+ flattenHeaders
22
+ };
23
+ //# sourceMappingURL=chunk-5X4T3PZN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/node/flattenHeaders.ts"],"sourcesContent":["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"],"mappings":";AAGe,SAAR,eACN,SACc;AACd,QAAM,cAAc,IAAI,QAAQ;AAChC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AACnD,QAAI,UAAU,UAAa,UAAU,MAAM;AAC1C;AAAA,IACD,WAAW,MAAM,QAAQ,KAAK,GAAG;AAChC,iBAAW,KAAK,OAAO;AACtB,YAAI,MAAM,UAAa,MAAM,MAAM;AAClC,gBAAM,QAAQ,CAACA,OAAM,YAAY,OAAO,KAAKA,EAAC,CAAC;AAAA,QAChD;AAAA,MACD;AAAA,IACD,OAAO;AACN,kBAAY,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IACnC;AAAA,EACD;AACA,SAAO;AAuBR;","names":["v"]}
@@ -0,0 +1,113 @@
1
+ import {
2
+ flattenHeaders
3
+ } from "./chunk-5X4T3PZN.js";
4
+
5
+ // src/adapters/node/createNodeServer.ts
6
+ import { createServer } from "node:http";
7
+
8
+ // src/adapters/node/constants.ts
9
+ var INTERNAL_BODY = Symbol("internal_body");
10
+
11
+ // src/adapters/node/nodeMessageToRequest.ts
12
+ import { Readable } from "node:stream";
13
+ async function nodeMessageToRequest(req) {
14
+ let path = req.url;
15
+ if (path === void 0) {
16
+ throw new Error(`Empty request URL`);
17
+ }
18
+ if (!path.startsWith("/")) {
19
+ path = "/" + path;
20
+ }
21
+ const { host } = req.headers;
22
+ if (host == void 0) {
23
+ throw new Error(`Missing "Host" header`);
24
+ }
25
+ const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
26
+ const url = `${protocol}://${host}${path}`;
27
+ const headers = flattenHeaders(req.headers);
28
+ const body = req.method !== "GET" && req.method !== "HEAD" ? Readable.toWeb(req) : null;
29
+ return new Request(url, {
30
+ method: req.method,
31
+ headers,
32
+ body,
33
+ // @ts-ignore this is needed for using a Readable for some reason
34
+ duplex: "half"
35
+ });
36
+ }
37
+
38
+ // src/adapters/node/responseToNodeResponse.ts
39
+ import { isArrayBufferView } from "node:util/types";
40
+ async function responseToNodeResponse(res, outgoing) {
41
+ outgoing.statusCode = res.status;
42
+ outgoing.statusMessage = res.statusText;
43
+ res.headers.forEach((value, key) => {
44
+ outgoing.setHeader(key, value);
45
+ });
46
+ const body = res[INTERNAL_BODY];
47
+ if (body === null || body === void 0) {
48
+ outgoing.writeHead(res.status, res.statusText);
49
+ outgoing.end();
50
+ } else if (typeof body === "string" || body instanceof Uint8Array) {
51
+ outgoing.writeHead(res.status, res.statusText);
52
+ outgoing.end(body);
53
+ } else if (body instanceof Blob) {
54
+ outgoing.writeHead(res.status, res.statusText);
55
+ outgoing.end(new Uint8Array(await body.arrayBuffer()));
56
+ } else if (body instanceof ArrayBuffer) {
57
+ outgoing.writeHead(res.status, res.statusText);
58
+ outgoing.end(new Uint8Array(body));
59
+ } else if (isArrayBufferView(body)) {
60
+ outgoing.writeHead(res.status, res.statusText);
61
+ outgoing.end(new Uint8Array(body.buffer));
62
+ } else if (body instanceof FormData) {
63
+ outgoing.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
64
+ outgoing.writeHead(res.status, res.statusText);
65
+ outgoing.end();
66
+ } else {
67
+ outgoing.writeHead(res.status, res.statusText);
68
+ outgoing.end();
69
+ }
70
+ }
71
+
72
+ // src/adapters/node/createFetchHandler.ts
73
+ var GlobalResponse = Response;
74
+ globalThis.Response = class Response2 extends GlobalResponse {
75
+ [INTERNAL_BODY] = null;
76
+ constructor(body, init) {
77
+ super(body, init);
78
+ this[INTERNAL_BODY] = body;
79
+ }
80
+ };
81
+ function createFetchHandler(handler) {
82
+ return async (incoming, outgoing) => {
83
+ const req = await nodeMessageToRequest(incoming);
84
+ const res = await handler(req);
85
+ return await responseToNodeResponse(res, outgoing);
86
+ };
87
+ }
88
+
89
+ // src/adapters/node/createNodeServer.ts
90
+ function createNodeServer(handler) {
91
+ return createServer(createFetchHandler(handler));
92
+ }
93
+
94
+ // src/adapters/node/index.ts
95
+ var node_default = {
96
+ serve: (server) => {
97
+ process.env.PROTOCOL ??= "http:";
98
+ process.env.HOST ??= "localhost";
99
+ process.env.PORT ??= "7059";
100
+ console.log(`
101
+ Connecting to ${process.env.HOST}:${process.env.PORT}`);
102
+ const devServer = createNodeServer(server.fetch);
103
+ devServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {
104
+ console.log(`Listening on ${process.env.HOST}:${process.env.PORT}
105
+ `);
106
+ });
107
+ }
108
+ };
109
+
110
+ export {
111
+ node_default
112
+ };
113
+ //# sourceMappingURL=chunk-ALHFYD7U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/node/createNodeServer.ts","../src/adapters/node/constants.ts","../src/adapters/node/nodeMessageToRequest.ts","../src/adapters/node/responseToNodeResponse.ts","../src/adapters/node/createFetchHandler.ts","../src/adapters/node/index.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport { createFetchHandler } from \"./createFetchHandler\";\n\nexport default function createNodeServer(handler: (req: Request) => Response | Promise<Response>) {\n\t// Create a server, polyfill it so that it can handle standard fetch methods,\n\t// and pass our app fetch method to the handler\n\treturn createServer(createFetchHandler(handler));\n}\n","export const INTERNAL_BODY = Symbol(\"internal_body\");\n","import { type IncomingMessage } from \"node:http\";\nimport { Http2ServerRequest } from \"node:http2\";\nimport { Readable } from \"node:stream\";\nimport flattenHeaders from \"./flattenHeaders\";\n\n// From https://stackoverflow.com/a/78849544\n// and https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n\nexport default async function nodeMessageToRequest(\n\treq: IncomingMessage | Http2ServerRequest,\n): Promise<Request> {\n\t// Build the full url\n\tlet path = req.url;\n\tif (path === undefined) {\n\t\tthrow new Error(`Empty request URL`);\n\t}\n\tif (!path.startsWith(\"/\")) {\n\t\tpath = \"/\" + path;\n\t}\n\tconst { host } = req.headers;\n\tif (host == undefined) {\n\t\tthrow new Error(`Missing \"Host\" header`);\n\t}\n\tconst protocol = \"encrypted\" in req.socket && req.socket.encrypted ? \"https\" : \"http\";\n\tconst url = `${protocol}://${host}${path}`;\n\n\t// Flatten the headers\n\tconst headers = flattenHeaders(req.headers);\n\n\t// Convert body to Buffer if applicable\n\tconst body =\n\t\treq.method !== \"GET\" && req.method !== \"HEAD\"\n\t\t\t? (Readable.toWeb(req) as ReadableStream) // await readableToBuffer(req)\n\t\t\t: null;\n\n\treturn new Request(url, {\n\t\tmethod: req.method,\n\t\theaders: headers,\n\t\tbody: body,\n\t\t// @ts-ignore this is needed for using a Readable for some reason\n\t\tduplex: \"half\",\n\t});\n}\n","import { ServerResponse } from \"node:http\";\nimport { Http2ServerResponse } from \"node:http2\";\nimport { isArrayBufferView } from \"node:util/types\";\nimport { INTERNAL_BODY } from \"./constants\";\n\nexport default async function responseToNodeResponse(\n\tres: Response,\n\toutgoing: ServerResponse | Http2ServerResponse,\n) {\n\toutgoing.statusCode = res.status;\n\toutgoing.statusMessage = res.statusText;\n\n\tres.headers.forEach((value, key) => {\n\t\toutgoing.setHeader(key, value);\n\t});\n\n\tconst body = (res as any)[INTERNAL_BODY];\n\n\tif (body === null || body === undefined) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else if (typeof body === \"string\" || body instanceof Uint8Array) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(body);\n\t} else if (body instanceof Blob) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(await body.arrayBuffer()));\n\t} else if (body instanceof ArrayBuffer) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body));\n\t} else if (isArrayBufferView(body)) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body.buffer));\n\t} else if (body instanceof FormData) {\n\t\t// TODO\n\t\toutgoing.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded;charset=UTF-8\");\n\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t}\n}\n","import { type IncomingMessage, ServerResponse } from \"node:http\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"node:http2\";\nimport { INTERNAL_BODY } from \"./constants\";\nimport nodeMessageToRequest from \"./nodeMessageToRequest\";\nimport responseToNodeResponse from \"./responseToNodeResponse\";\n\n// From https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n// Referenced from https://marvinh.dev/blog/modern-way-to-write-javascript-servers/\n\nconst GlobalResponse = Response;\nglobalThis.Response = class Response extends GlobalResponse {\n\t[INTERNAL_BODY]: BodyInit | null | undefined = null;\n\n\tconstructor(body?: BodyInit | null, init?: ResponseInit) {\n\t\tsuper(body, init);\n\t\tthis[INTERNAL_BODY] = body;\n\t}\n};\n\nexport function createFetchHandler(handler: (req: Request) => Response | Promise<Response>) {\n\treturn async (\n\t\tincoming: IncomingMessage | Http2ServerRequest,\n\t\toutgoing: ServerResponse | Http2ServerResponse,\n\t) => {\n\t\tconst req = await nodeMessageToRequest(incoming);\n\t\tconst res = await handler(req);\n\t\treturn await responseToNodeResponse(res, outgoing);\n\t};\n}\n","import Server from \"../../server/Server\";\nimport type Adapter from \"../../types/Adapter\";\nimport createNodeServer from \"./createNodeServer\";\n\nexport default {\n\tserve: (server: Server) => {\n\t\tprocess.env.PROTOCOL ??= \"http:\";\n\t\tprocess.env.HOST ??= \"localhost\";\n\t\tprocess.env.PORT ??= \"7059\";\n\n\t\t// Create the Node server and start listening\n\t\tconsole.log(`\\nConnecting to ${process.env.HOST}:${process.env.PORT}`);\n\t\tconst devServer = createNodeServer(server.fetch);\n\t\tdevServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {\n\t\t\tconsole.log(`Listening on ${process.env.HOST}:${process.env.PORT}\\n`);\n\t\t});\n\t},\n} satisfies Adapter;\n"],"mappings":"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","names":["Response"]}
@@ -0,0 +1,19 @@
1
+ // src/site/prepareTemplate.ts
2
+ function prepareTemplate(template, clientScript) {
3
+ let contentStart = regexIndexOf(template, /\<div\s+id=("app"|'app'|app)\s+/);
4
+ contentStart = template.indexOf(">", contentStart) + 1;
5
+ let contentEnd = template.indexOf("</div>", contentStart);
6
+ if (contentStart === -1 || contentEnd === -1) {
7
+ throw new Error(`Couldn't find <div id="app"></div>`);
8
+ }
9
+ return template.substring(0, contentStart) + "%COMPONENT_HTML%" + template.substring(contentEnd) + `<script type="module" src="${clientScript}"></script>`;
10
+ }
11
+ function regexIndexOf(string, regex, position) {
12
+ var indexOf = string.substring(position || 0).search(regex);
13
+ return indexOf >= 0 ? indexOf + (position || 0) : indexOf;
14
+ }
15
+
16
+ export {
17
+ prepareTemplate
18
+ };
19
+ //# sourceMappingURL=chunk-V4XTDQEV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/site/prepareTemplate.ts"],"sourcesContent":["export default function prepareTemplate(template: string, clientScript: 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"],"mappings":";AAAe,SAAR,gBAAiC,UAAkB,cAAsB;AAC/E,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;","names":[]}
@@ -0,0 +1,110 @@
1
+ // src/response/response.ts
2
+ function response(status, body) {
3
+ let headers = void 0;
4
+ if (body) {
5
+ if (typeof body === "object") {
6
+ headers = { "content-type": "application/json" };
7
+ body = JSON.stringify(body);
8
+ } else {
9
+ headers = { "content-type": "text/plain" };
10
+ }
11
+ }
12
+ return new Response(body, {
13
+ status,
14
+ headers
15
+ });
16
+ }
17
+
18
+ // src/response/badRequest.ts
19
+ function badRequest(body) {
20
+ return response(400, body);
21
+ }
22
+
23
+ // src/response/created.ts
24
+ function created(body) {
25
+ return response(201, body);
26
+ }
27
+
28
+ // src/response/forbidden.ts
29
+ function forbidden(body) {
30
+ return response(403, body);
31
+ }
32
+
33
+ // src/response/methodNotAllowed.ts
34
+ function methodNotAllowed(body) {
35
+ return response(405, body);
36
+ }
37
+
38
+ // src/response/transfer.ts
39
+ function transfer(status, location) {
40
+ return new Response(null, {
41
+ status,
42
+ headers: {
43
+ location
44
+ }
45
+ });
46
+ }
47
+
48
+ // src/response/moved.ts
49
+ function moved(location) {
50
+ return transfer(308, location);
51
+ }
52
+
53
+ // src/response/notFound.ts
54
+ function notFound(body) {
55
+ return response(404, body);
56
+ }
57
+
58
+ // src/response/notModified.ts
59
+ function notModified(location) {
60
+ return transfer(304, location);
61
+ }
62
+
63
+ // src/response/ok.ts
64
+ function ok(body) {
65
+ return response(200, body);
66
+ }
67
+
68
+ // src/response/redirect.ts
69
+ function redirect(location) {
70
+ return transfer(307, location);
71
+ }
72
+
73
+ // src/response/seeOther.ts
74
+ function seeOther(location) {
75
+ return transfer(303, location);
76
+ }
77
+
78
+ // src/response/serverError.ts
79
+ function serverError(body) {
80
+ return response(500, body);
81
+ }
82
+
83
+ // src/response/unauthorized.ts
84
+ function unauthorized(body) {
85
+ return response(401, body);
86
+ }
87
+
88
+ // src/response/unprocessable.ts
89
+ function unprocessable(body) {
90
+ return response(422, body);
91
+ }
92
+
93
+ export {
94
+ response,
95
+ badRequest,
96
+ created,
97
+ forbidden,
98
+ methodNotAllowed,
99
+ transfer,
100
+ moved,
101
+ notFound,
102
+ notModified,
103
+ ok,
104
+ redirect,
105
+ seeOther,
106
+ serverError,
107
+ unauthorized,
108
+ unprocessable
109
+ };
110
+ //# sourceMappingURL=chunk-VAGHGWM5.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) {\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,MAAwB;AACxE,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":[]}