@elurjs/kit 2.4.4

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 (255) hide show
  1. package/CHANGELOG.md +874 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1330 -0
  4. package/bin/elur-kit.js +54 -0
  5. package/dist/lib/action/define.d.cts +72 -0
  6. package/dist/lib/action/define.d.ts +72 -0
  7. package/dist/lib/action/error-store.d.cts +29 -0
  8. package/dist/lib/action/error-store.d.ts +29 -0
  9. package/dist/lib/action/index.cjs +1 -0
  10. package/dist/lib/action/index.d.cts +64 -0
  11. package/dist/lib/action/index.d.ts +64 -0
  12. package/dist/lib/action/index.js +2 -0
  13. package/dist/lib/action/origin.d.cts +20 -0
  14. package/dist/lib/action/origin.d.ts +20 -0
  15. package/dist/lib/action/scan.d.cts +28 -0
  16. package/dist/lib/action/scan.d.ts +28 -0
  17. package/dist/lib/action/server.d.cts +30 -0
  18. package/dist/lib/action/server.d.ts +30 -0
  19. package/dist/lib/action-BB6N5yD-.js +111 -0
  20. package/dist/lib/action-BB6N5yD-.js.map +1 -0
  21. package/dist/lib/action-DZHihU3Z.cjs +2 -0
  22. package/dist/lib/action-DZHihU3Z.cjs.map +1 -0
  23. package/dist/lib/adapters/bun.cjs +30 -0
  24. package/dist/lib/adapters/bun.cjs.map +1 -0
  25. package/dist/lib/adapters/bun.d.cts +13 -0
  26. package/dist/lib/adapters/bun.d.ts +13 -0
  27. package/dist/lib/adapters/bun.js +65 -0
  28. package/dist/lib/adapters/bun.js.map +1 -0
  29. package/dist/lib/adapters/index.cjs +0 -0
  30. package/dist/lib/adapters/index.d.cts +30 -0
  31. package/dist/lib/adapters/index.d.ts +30 -0
  32. package/dist/lib/adapters/index.js +0 -0
  33. package/dist/lib/adapters/netlify.cjs +10 -0
  34. package/dist/lib/adapters/netlify.cjs.map +1 -0
  35. package/dist/lib/adapters/netlify.d.cts +13 -0
  36. package/dist/lib/adapters/netlify.d.ts +13 -0
  37. package/dist/lib/adapters/netlify.js +51 -0
  38. package/dist/lib/adapters/netlify.js.map +1 -0
  39. package/dist/lib/adapters/node.cjs +46 -0
  40. package/dist/lib/adapters/node.cjs.map +1 -0
  41. package/dist/lib/adapters/node.d.cts +13 -0
  42. package/dist/lib/adapters/node.d.ts +13 -0
  43. package/dist/lib/adapters/node.js +105 -0
  44. package/dist/lib/adapters/node.js.map +1 -0
  45. package/dist/lib/adapters/shared.d.cts +17 -0
  46. package/dist/lib/adapters/shared.d.ts +17 -0
  47. package/dist/lib/adapters/vercel.cjs +2 -0
  48. package/dist/lib/adapters/vercel.cjs.map +1 -0
  49. package/dist/lib/adapters/vercel.d.cts +9 -0
  50. package/dist/lib/adapters/vercel.d.ts +9 -0
  51. package/dist/lib/adapters/vercel.js +62 -0
  52. package/dist/lib/adapters/vercel.js.map +1 -0
  53. package/dist/lib/build/build.d.cts +83 -0
  54. package/dist/lib/build/build.d.ts +83 -0
  55. package/dist/lib/build/document-shell.d.cts +48 -0
  56. package/dist/lib/build/document-shell.d.ts +48 -0
  57. package/dist/lib/build/transform-source.d.cts +26 -0
  58. package/dist/lib/build/transform-source.d.ts +26 -0
  59. package/dist/lib/build/vite-build.d.cts +78 -0
  60. package/dist/lib/build/vite-build.d.ts +78 -0
  61. package/dist/lib/cache/policy.d.cts +25 -0
  62. package/dist/lib/cache/policy.d.ts +25 -0
  63. package/dist/lib/cache.d.cts +13 -0
  64. package/dist/lib/cache.d.ts +13 -0
  65. package/dist/lib/capabilities-C0TDQoMY.cjs +2 -0
  66. package/dist/lib/capabilities-C0TDQoMY.cjs.map +1 -0
  67. package/dist/lib/capabilities-C7txofmY.js +45 -0
  68. package/dist/lib/capabilities-C7txofmY.js.map +1 -0
  69. package/dist/lib/cli/commands.d.cts +15 -0
  70. package/dist/lib/cli/commands.d.ts +15 -0
  71. package/dist/lib/cli.cjs +5132 -0
  72. package/dist/lib/cli.cjs.map +1 -0
  73. package/dist/lib/cli.d.cts +30 -0
  74. package/dist/lib/cli.d.ts +30 -0
  75. package/dist/lib/cli.js +5131 -0
  76. package/dist/lib/cli.js.map +1 -0
  77. package/dist/lib/collections-Dbc8aRLf.js +233 -0
  78. package/dist/lib/collections-Dbc8aRLf.js.map +1 -0
  79. package/dist/lib/collections-VDy5g9p8.cjs +13 -0
  80. package/dist/lib/collections-VDy5g9p8.cjs.map +1 -0
  81. package/dist/lib/config/index.cjs +2 -0
  82. package/dist/lib/config/index.cjs.map +1 -0
  83. package/dist/lib/config/index.d.cts +100 -0
  84. package/dist/lib/config/index.d.ts +100 -0
  85. package/dist/lib/config/index.js +122 -0
  86. package/dist/lib/config/index.js.map +1 -0
  87. package/dist/lib/content/collections.d.cts +69 -0
  88. package/dist/lib/content/collections.d.ts +69 -0
  89. package/dist/lib/content/frontmatter.d.cts +20 -0
  90. package/dist/lib/content/frontmatter.d.ts +20 -0
  91. package/dist/lib/content/index.cjs +2 -0
  92. package/dist/lib/content/index.cjs.map +1 -0
  93. package/dist/lib/content/index.d.cts +5 -0
  94. package/dist/lib/content/index.d.ts +5 -0
  95. package/dist/lib/content/index.js +28 -0
  96. package/dist/lib/content/index.js.map +1 -0
  97. package/dist/lib/content/markdown.d.cts +6 -0
  98. package/dist/lib/content/markdown.d.ts +6 -0
  99. package/dist/lib/content/raw.d.cts +9 -0
  100. package/dist/lib/content/raw.d.ts +9 -0
  101. package/dist/lib/content/schema.d.cts +14 -0
  102. package/dist/lib/content/schema.d.ts +14 -0
  103. package/dist/lib/errors-0X7pCFNU.cjs +2 -0
  104. package/dist/lib/errors-0X7pCFNU.cjs.map +1 -0
  105. package/dist/lib/errors-ePYxDlhU.js +70 -0
  106. package/dist/lib/errors-ePYxDlhU.js.map +1 -0
  107. package/dist/lib/errors.d.cts +84 -0
  108. package/dist/lib/errors.d.ts +84 -0
  109. package/dist/lib/hydrate-8a3TbQbs.cjs +2 -0
  110. package/dist/lib/hydrate-8a3TbQbs.cjs.map +1 -0
  111. package/dist/lib/hydrate-CgZGrTxF.js +126 -0
  112. package/dist/lib/hydrate-CgZGrTxF.js.map +1 -0
  113. package/dist/lib/image/index.cjs +2 -0
  114. package/dist/lib/image/index.cjs.map +1 -0
  115. package/dist/lib/image/index.d.cts +37 -0
  116. package/dist/lib/image/index.d.ts +37 -0
  117. package/dist/lib/image/index.js +49 -0
  118. package/dist/lib/image/index.js.map +1 -0
  119. package/dist/lib/image/pipeline.d.cts +37 -0
  120. package/dist/lib/image/pipeline.d.ts +37 -0
  121. package/dist/lib/image/registry.cjs +2 -0
  122. package/dist/lib/image/registry.cjs.map +1 -0
  123. package/dist/lib/image/registry.d.cts +26 -0
  124. package/dist/lib/image/registry.d.ts +26 -0
  125. package/dist/lib/image/registry.js +23 -0
  126. package/dist/lib/image/registry.js.map +1 -0
  127. package/dist/lib/image/service.cjs +2 -0
  128. package/dist/lib/image/service.cjs.map +1 -0
  129. package/dist/lib/image/service.d.cts +164 -0
  130. package/dist/lib/image/service.d.ts +164 -0
  131. package/dist/lib/image/service.js +308 -0
  132. package/dist/lib/image/service.js.map +1 -0
  133. package/dist/lib/index.cjs +1 -0
  134. package/dist/lib/index.cjs.map +1 -0
  135. package/dist/lib/index.d.cts +38 -0
  136. package/dist/lib/index.d.ts +38 -0
  137. package/dist/lib/index.js +1 -0
  138. package/dist/lib/index.js.map +1 -0
  139. package/dist/lib/integrations/hooks.d.cts +58 -0
  140. package/dist/lib/integrations/hooks.d.ts +58 -0
  141. package/dist/lib/integrations/index.cjs +1 -0
  142. package/dist/lib/integrations/index.d.cts +18 -0
  143. package/dist/lib/integrations/index.d.ts +18 -0
  144. package/dist/lib/integrations/index.js +2 -0
  145. package/dist/lib/integrations-7dpN1RYB.js +35 -0
  146. package/dist/lib/integrations-7dpN1RYB.js.map +1 -0
  147. package/dist/lib/integrations-DDqfWjvH.cjs +2 -0
  148. package/dist/lib/integrations-DDqfWjvH.cjs.map +1 -0
  149. package/dist/lib/interpolation-plugin-Bt-KRKVY.js +365 -0
  150. package/dist/lib/interpolation-plugin-Bt-KRKVY.js.map +1 -0
  151. package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs +31 -0
  152. package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs.map +1 -0
  153. package/dist/lib/island/generate-entry.d.cts +27 -0
  154. package/dist/lib/island/generate-entry.d.ts +27 -0
  155. package/dist/lib/island/hydrate.d.cts +33 -0
  156. package/dist/lib/island/hydrate.d.ts +33 -0
  157. package/dist/lib/island/index.cjs +1 -0
  158. package/dist/lib/island/index.d.cts +2 -0
  159. package/dist/lib/island/index.d.ts +2 -0
  160. package/dist/lib/island/index.js +1 -0
  161. package/dist/lib/island/island.d.cts +32 -0
  162. package/dist/lib/island/island.d.ts +32 -0
  163. package/dist/lib/island/scan.d.cts +14 -0
  164. package/dist/lib/island/scan.d.ts +14 -0
  165. package/dist/lib/manifest/index.cjs +3 -0
  166. package/dist/lib/manifest/index.cjs.map +1 -0
  167. package/dist/lib/manifest/index.d.cts +18 -0
  168. package/dist/lib/manifest/index.d.ts +18 -0
  169. package/dist/lib/manifest/index.js +110 -0
  170. package/dist/lib/manifest/index.js.map +1 -0
  171. package/dist/lib/middleware/index.d.cts +56 -0
  172. package/dist/lib/middleware/index.d.ts +56 -0
  173. package/dist/lib/middleware/stream-boundary.d.cts +53 -0
  174. package/dist/lib/middleware/stream-boundary.d.ts +53 -0
  175. package/dist/lib/node-http-DRAUhO0c.js +617 -0
  176. package/dist/lib/node-http-DRAUhO0c.js.map +1 -0
  177. package/dist/lib/node-http-DhxguYyz.cjs +13 -0
  178. package/dist/lib/node-http-DhxguYyz.cjs.map +1 -0
  179. package/dist/lib/render/render-to-string.d.cts +12 -0
  180. package/dist/lib/render/render-to-string.d.ts +12 -0
  181. package/dist/lib/render/ssr-flag.d.cts +4 -0
  182. package/dist/lib/render/ssr-flag.d.ts +4 -0
  183. package/dist/lib/route-scanner-JY6YrNH5.cjs +2 -0
  184. package/dist/lib/route-scanner-JY6YrNH5.cjs.map +1 -0
  185. package/dist/lib/route-scanner-XcLId7lK.js +100 -0
  186. package/dist/lib/route-scanner-XcLId7lK.js.map +1 -0
  187. package/dist/lib/router/client.cjs +2 -0
  188. package/dist/lib/router/client.cjs.map +1 -0
  189. package/dist/lib/router/client.d.cts +47 -0
  190. package/dist/lib/router/client.d.ts +47 -0
  191. package/dist/lib/router/client.js +298 -0
  192. package/dist/lib/router/client.js.map +1 -0
  193. package/dist/lib/router/route-scanner.d.cts +50 -0
  194. package/dist/lib/router/route-scanner.d.ts +50 -0
  195. package/dist/lib/runtime/capabilities.d.cts +47 -0
  196. package/dist/lib/runtime/capabilities.d.ts +47 -0
  197. package/dist/lib/runtime/context.d.cts +140 -0
  198. package/dist/lib/runtime/context.d.ts +140 -0
  199. package/dist/lib/runtime/handler.d.cts +39 -0
  200. package/dist/lib/runtime/handler.d.ts +39 -0
  201. package/dist/lib/runtime/index.cjs +1 -0
  202. package/dist/lib/runtime/index.d.cts +6 -0
  203. package/dist/lib/runtime/index.d.ts +6 -0
  204. package/dist/lib/runtime/index.js +4 -0
  205. package/dist/lib/runtime/node-http.d.cts +2 -0
  206. package/dist/lib/runtime/node-http.d.ts +2 -0
  207. package/dist/lib/runtime/security-headers.d.cts +13 -0
  208. package/dist/lib/runtime/security-headers.d.ts +13 -0
  209. package/dist/lib/runtime/static.d.cts +1 -0
  210. package/dist/lib/runtime/static.d.ts +1 -0
  211. package/dist/lib/runtime-CrH5X-Es.cjs +2 -0
  212. package/dist/lib/runtime-CrH5X-Es.cjs.map +1 -0
  213. package/dist/lib/runtime-Ds2-wH6P.js +520 -0
  214. package/dist/lib/runtime-Ds2-wH6P.js.map +1 -0
  215. package/dist/lib/scan-CY2O9ty6.cjs +2 -0
  216. package/dist/lib/scan-CY2O9ty6.cjs.map +1 -0
  217. package/dist/lib/scan-CjMUgnsd.js +22 -0
  218. package/dist/lib/scan-CjMUgnsd.js.map +1 -0
  219. package/dist/lib/scan-DXzYtmRQ.cjs +2 -0
  220. package/dist/lib/scan-DXzYtmRQ.cjs.map +1 -0
  221. package/dist/lib/scan-Dn93ycXG.js +33 -0
  222. package/dist/lib/scan-Dn93ycXG.js.map +1 -0
  223. package/dist/lib/seo/index.cjs +10 -0
  224. package/dist/lib/seo/index.cjs.map +1 -0
  225. package/dist/lib/seo/index.d.cts +99 -0
  226. package/dist/lib/seo/index.d.ts +99 -0
  227. package/dist/lib/seo/index.js +41 -0
  228. package/dist/lib/seo/index.js.map +1 -0
  229. package/dist/lib/shared-CfqOLsKj.cjs +183 -0
  230. package/dist/lib/shared-CfqOLsKj.cjs.map +1 -0
  231. package/dist/lib/shared-DU3iQgr7.js +236 -0
  232. package/dist/lib/shared-DU3iQgr7.js.map +1 -0
  233. package/dist/lib/ssr/match.d.cts +25 -0
  234. package/dist/lib/ssr/match.d.ts +25 -0
  235. package/dist/lib/ssr/render.d.cts +62 -0
  236. package/dist/lib/ssr/render.d.ts +62 -0
  237. package/dist/lib/ssr/server.d.cts +41 -0
  238. package/dist/lib/ssr/server.d.ts +41 -0
  239. package/dist/lib/ssr/stream.d.cts +48 -0
  240. package/dist/lib/ssr/stream.d.ts +48 -0
  241. package/dist/lib/stream-CpOG052V.js +104 -0
  242. package/dist/lib/stream-CpOG052V.js.map +1 -0
  243. package/dist/lib/stream-DmZjYqHm.cjs +17 -0
  244. package/dist/lib/stream-DmZjYqHm.cjs.map +1 -0
  245. package/dist/lib/types.d.cts +97 -0
  246. package/dist/lib/types.d.ts +97 -0
  247. package/dist/lib/vite/index.cjs +2 -0
  248. package/dist/lib/vite/index.cjs.map +1 -0
  249. package/dist/lib/vite/index.d.cts +41 -0
  250. package/dist/lib/vite/index.d.ts +41 -0
  251. package/dist/lib/vite/index.js +229 -0
  252. package/dist/lib/vite/index.js.map +1 -0
  253. package/dist/lib/vite/interpolation-plugin.d.cts +64 -0
  254. package/dist/lib/vite/interpolation-plugin.d.ts +64 -0
  255. package/package.json +292 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","names":[],"sources":["../../../src/adapters/node.ts"],"sourcesContent":["import { mkdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { writeSsrEntry } from \"./shared.js\";\nimport { DEFAULT_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Node adapter for elur-kit.\n *\n * Produces a self-contained Node server entry at `.elur/node-server.mjs`.\n * Run it with:\n *\n * node .elur/node-server.mjs\n *\n * The server serves static files from `dist/` and renders pages on demand for\n * unmatched routes.\n */\nexport const nodeAdapter: Adapter = {\n name: \"node\",\n capabilities: DEFAULT_CAPABILITIES,\n\n async build(options) {\n const root = resolve(options.root);\n const outDir = resolve(root, options.outDir);\n const generatedDir = resolve(root, \".elur\");\n\n try {\n await stat(outDir);\n } catch {\n throw new Error(\n `Output directory not found: ${outDir}. Run \"elur-kit build\" first.`,\n );\n }\n\n await rm(generatedDir, { recursive: true, force: true });\n await mkdir(generatedDir, { recursive: true });\n\n const appDir = resolve(root, options.appDir);\n const routes = await scanRoutes(appDir);\n\n const entryPath = resolve(generatedDir, \"node-index.ts\");\n await writeSsrEntry(entryPath, routes, options);\n\n const serverPath = resolve(generatedDir, \"node-server.ts\");\n await writeFile(\n serverPath,\n buildNodeServerSource(relativeToUrlPath(generatedDir, outDir), options),\n \"utf8\",\n );\n\n await build({\n configFile: false,\n root,\n build: {\n outDir: generatedDir,\n emptyOutDir: false,\n ssr: true,\n lib: {\n entry: serverPath,\n formats: [\"es\"],\n },\n rollupOptions: {\n external: [/^@elurjs\\/kit(?:\\/.*)?$/, /^@elurjs\\/core(?:\\/.*)?$/, /^node:/],\n output: {\n entryFileNames: \"node-server.mjs\",\n inlineDynamicImports: true,\n },\n },\n },\n });\n },\n};\n\nfunction buildNodeServerSource(\n outDirUrl: string,\n options: {\n clientEntry: string;\n lang: string;\n port?: number;\n },\n): string {\n return `// AUTO-GENERATED by @elurjs/kit. Do not edit.\nimport { createServer } from \"node:http\";\nimport { fileURLToPath } from \"node:url\";\nimport { createWebHandler } from \"@elurjs/kit/runtime\";\nimport { incomingMessageToRequest } from \"@elurjs/kit/runtime\";\nimport handler from \"./node-index.ts\";\n\nconst outDir = fileURLToPath(new URL(${JSON.stringify(outDirUrl)}, import.meta.url));\nconst port = Number(process.env.PORT) || ${options.port ?? 3000};\n\n// The adapter-bundled handler already handles actions, API routes, render\n// endpoint and dynamic SSR. We only need to add static file serving from\n// the output directory, then fall through to the bundled handler.\nconst webHandler = createWebHandler(\n { pages: [], api: [], error404: undefined, error500: undefined },\n {},\n { staticRoot: outDir, lang: ${JSON.stringify(options.lang)}, clientEntry: ${JSON.stringify(options.clientEntry)} },\n);\n\ncreateServer(async (req, res) => {\n const body = req.method !== \"GET\" && req.method !== \"HEAD\"\n ? await readBody(req)\n : undefined;\n const request = incomingMessageToRequest(req, body);\n // Try static files first via the unified handler, then fall back to the\n // bundled SSR handler for dynamic routes.\n let response = await webHandler(request);\n if (response.status === 404) {\n response = await handler(request);\n }\n res.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n res.end(Buffer.from(await response.arrayBuffer()));\n}).listen(port, () => {\n console.log(\\`Node server running at http://localhost:\\${port}\\`);\n});\n\nfunction readBody(req: import(\"node:http\").IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n req.on(\"end\", () => resolve(Buffer.concat(chunks)));\n req.on(\"error\", reject);\n });\n}\n`;\n}\n\nfunction relativeToUrlPath(from: string, to: string): string {\n const path = relative(from, to).split(\"\\\\\").join(\"/\");\n return `${path.startsWith(\".\") ? path : `./${path}`}/`;\n}\n"],"mappings":";;;;;;;AAmBA,IAAa,IAAuB;CAClC,MAAM;CACN,cAAc;CAEd,MAAM,MAAM,GAAS;EACnB,IAAM,IAAO,EAAQ,EAAQ,IAAI,GAC3B,IAAS,EAAQ,GAAM,EAAQ,MAAM,GACrC,IAAe,EAAQ,GAAM,OAAO;EAE1C,IAAI;GACF,MAAM,EAAK,CAAM;EACnB,QAAQ;GACN,MAAU,MACR,+BAA+B,EAAO,8BACxC;EACF;EAGA,AADA,MAAM,EAAG,GAAc;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC,GACvD,MAAM,EAAM,GAAc,EAAE,WAAW,GAAK,CAAC;EAE7C,IAAM,IAAS,EAAQ,GAAM,EAAQ,MAAM,GACrC,IAAS,MAAM,EAAW,CAAM,GAEhC,IAAY,EAAQ,GAAc,eAAe;EACvD,MAAM,EAAc,GAAW,GAAQ,CAAO;EAE9C,IAAM,IAAa,EAAQ,GAAc,gBAAgB;EAOzD,AANA,MAAM,EACJ,GACA,EAAsB,EAAkB,GAAc,CAAM,GAAG,CAAO,GACtE,MACF,GAEA,MAAM,EAAM;GACV,YAAY;GACZ;GACA,OAAO;IACL,QAAQ;IACR,aAAa;IACb,KAAK;IACL,KAAK;KACH,OAAO;KACP,SAAS,CAAC,IAAI;IAChB;IACA,eAAe;KACb,UAAU;MAAC;MAA2B;MAA4B;KAAQ;KAC1E,QAAQ;MACN,gBAAgB;MAChB,sBAAsB;KACxB;IACF;GACF;EACF,CAAC;CACH;AACF;AAEA,SAAS,EACP,GACA,GAKQ;CACR,OAAO;;;;;;;uCAO8B,KAAK,UAAU,CAAS,EAAE;2CACtB,EAAQ,QAAQ,IAAK;;;;;;;;gCAQhC,KAAK,UAAU,EAAQ,IAAI,EAAE,iBAAiB,KAAK,UAAU,EAAQ,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BlH;AAEA,SAAS,EAAkB,GAAc,GAAoB;CAC3D,IAAM,IAAO,EAAS,GAAM,CAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG;CACpD,OAAO,GAAG,EAAK,WAAW,GAAG,IAAI,IAAO,KAAK,IAAO;AACtD"}
@@ -0,0 +1,17 @@
1
+ import { scanRoutes } from "../router/route-scanner.js";
2
+ import type { AdapterOptions } from "./index.js";
3
+ /**
4
+ * Shared helper: copy a directory recursively.
5
+ */
6
+ export declare function copyStatic(from: string, to: string): Promise<void>;
7
+ /**
8
+ * Build a self-contained SSR entry file for a platform adapter.
9
+ * The generated module exports a default `handler(request: Request): Response`
10
+ * and embeds the full route table plus a registry of all page/layout/data/
11
+ * action modules so the runtime never touches the file system.
12
+ */
13
+ export declare function buildSsrEntry(routes: Awaited<ReturnType<typeof scanRoutes>>, options: AdapterOptions, entryDir: string): Promise<string>;
14
+ /**
15
+ * Write a generated SSR entry file for an adapter.
16
+ */
17
+ export declare function writeSsrEntry(entryPath: string, routes: Awaited<ReturnType<typeof scanRoutes>>, options: AdapterOptions): Promise<void>;
@@ -0,0 +1,17 @@
1
+ import { scanRoutes } from "../router/route-scanner.js";
2
+ import type { AdapterOptions } from "./index.js";
3
+ /**
4
+ * Shared helper: copy a directory recursively.
5
+ */
6
+ export declare function copyStatic(from: string, to: string): Promise<void>;
7
+ /**
8
+ * Build a self-contained SSR entry file for a platform adapter.
9
+ * The generated module exports a default `handler(request: Request): Response`
10
+ * and embeds the full route table plus a registry of all page/layout/data/
11
+ * action modules so the runtime never touches the file system.
12
+ */
13
+ export declare function buildSsrEntry(routes: Awaited<ReturnType<typeof scanRoutes>>, options: AdapterOptions, entryDir: string): Promise<string>;
14
+ /**
15
+ * Write a generated SSR entry file for an adapter.
16
+ */
17
+ export declare function writeSsrEntry(entryPath: string, routes: Awaited<ReturnType<typeof scanRoutes>>, options: AdapterOptions): Promise<void>;
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../route-scanner-JY6YrNH5.cjs"),t=require("../shared-CfqOLsKj.cjs"),n=require("../capabilities-C0TDQoMY.cjs");let r=require("node:fs/promises"),i=require("node:path"),a=require("vite");var o={name:`vercel`,capabilities:n.r,async build(n){let o=(0,i.resolve)(n.root),s=(0,i.resolve)(o,n.outDir),c=(0,i.resolve)(o,`.vercel/output`),l=(0,i.join)(c,`functions`,`__elur-js-kit.func`),u=(0,i.resolve)(o,`.elur`);try{await(0,r.stat)(s)}catch{throw Error(`Output directory not found: ${s}. Run "elur-kit build" first.`)}await(0,r.rm)(c,{recursive:!0,force:!0}),await(0,r.mkdir)(c,{recursive:!0}),await(0,r.mkdir)(l,{recursive:!0}),await(0,r.mkdir)(u,{recursive:!0}),await t.t(s,(0,i.join)(c,`static`));let d=(0,i.resolve)(o,n.appDir),f=await e.t(d),p=(0,i.resolve)(u,`vercel-index.ts`);await t.n(p,f,n),await(0,a.build)({configFile:!1,root:o,build:{outDir:l,emptyOutDir:!0,ssr:!0,lib:{entry:p,formats:[`es`],fileName:()=>`index.js`},rollupOptions:{external:[],output:{inlineDynamicImports:!0}}}});let m=(0,i.join)(l,`vercel-index.js`),h=(0,i.join)(l,`index.js`);try{await(0,r.stat)(m),await(0,r.rename)(m,h)}catch{}await(0,r.writeFile)((0,i.join)(l,`.vc-config.json`),JSON.stringify({runtime:`nodejs20.x`,handler:`index.js`,launcherType:`Nodejs`,shouldAddHelpers:!0},null,2),`utf8`),await(0,r.writeFile)((0,i.join)(c,`config.json`),JSON.stringify({version:3,routes:[{handle:`filesystem`},{src:`/(.*)`,dest:`/__elur-js-kit`}]},null,2),`utf8`)}};exports.vercelAdapter=o;
2
+ //# sourceMappingURL=vercel.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel.cjs","names":[],"sources":["../../../src/adapters/vercel.ts"],"sourcesContent":["import { mkdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { copyStatic, writeSsrEntry } from \"./shared.js\";\nimport { SERVERLESS_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Vercel adapter for elur-kit.\n *\n * Produces a `.vercel/output` directory compatible with the Vercel Build Output\n * API (v3). Static files are served from `dist/` and unmatched routes fall back\n * to the SSR function.\n */\nexport const vercelAdapter: Adapter = {\n name: \"vercel\",\n capabilities: SERVERLESS_CAPABILITIES,\n\n async build(options) {\n const root = resolve(options.root);\n const outDir = resolve(root, options.outDir);\n const vercelOut = resolve(root, \".vercel/output\");\n const functionsDir = join(vercelOut, \"functions\", \"__elur-js-kit.func\");\n const generatedDir = resolve(root, \".elur\");\n\n // Verify the production build exists.\n try {\n await stat(outDir);\n } catch {\n throw new Error(\n `Output directory not found: ${outDir}. Run \"elur-kit build\" first.`,\n );\n }\n\n // Clean previous adapter output.\n await rm(vercelOut, { recursive: true, force: true });\n await mkdir(vercelOut, { recursive: true });\n await mkdir(functionsDir, { recursive: true });\n await mkdir(generatedDir, { recursive: true });\n\n // Copy static files.\n await copyStatic(outDir, join(vercelOut, \"static\"));\n\n // Scan routes and generate a self-contained function entry.\n const appDir = resolve(root, options.appDir);\n const routes = await scanRoutes(appDir);\n\n const entryPath = resolve(generatedDir, \"vercel-index.ts\");\n await writeSsrEntry(entryPath, routes, options);\n\n // Bundle the function entry.\n await build({\n configFile: false,\n root,\n build: {\n outDir: functionsDir,\n emptyOutDir: true,\n ssr: true,\n lib: {\n entry: entryPath,\n formats: [\"es\"],\n fileName: () => \"index.js\",\n },\n rollupOptions: {\n external: [],\n output: {\n inlineDynamicImports: true,\n },\n },\n },\n });\n\n // Vite SSR lib builds may use the entry file name, so force the expected handler name.\n const generatedHandler = join(functionsDir, \"vercel-index.js\");\n const targetHandler = join(functionsDir, \"index.js\");\n try {\n await stat(generatedHandler);\n await rename(generatedHandler, targetHandler);\n } catch {\n // If the file is already named index.js, nothing to do.\n }\n\n // Write Vercel function config.\n await writeFile(\n join(functionsDir, \".vc-config.json\"),\n JSON.stringify(\n {\n runtime: \"nodejs20.x\",\n handler: \"index.js\",\n launcherType: \"Nodejs\",\n shouldAddHelpers: true,\n },\n null,\n 2,\n ),\n \"utf8\",\n );\n\n // Write Vercel root config.\n await writeFile(\n join(vercelOut, \"config.json\"),\n JSON.stringify(\n {\n version: 3,\n routes: [\n { handle: \"filesystem\" },\n { src: \"/(.*)\", \"dest\": \"/__elur-js-kit\" },\n ],\n },\n null,\n 2,\n ),\n \"utf8\",\n );\n },\n};\n"],"mappings":"6QAeA,IAAa,EAAyB,CACpC,KAAM,SACN,aAAc,EAAA,EAEd,MAAM,MAAM,EAAS,CACnB,IAAM,GAAA,EAAO,EAAA,QAAA,CAAQ,EAAQ,IAAI,EAC3B,GAAA,EAAS,EAAA,QAAA,CAAQ,EAAM,EAAQ,MAAM,EACrC,GAAA,EAAY,EAAA,QAAA,CAAQ,EAAM,gBAAgB,EAC1C,GAAA,EAAe,EAAA,KAAA,CAAK,EAAW,YAAa,oBAAoB,EAChE,GAAA,EAAe,EAAA,QAAA,CAAQ,EAAM,OAAO,EAG1C,GAAI,CACF,MAAA,EAAM,EAAA,KAAA,CAAK,CAAM,CACnB,MAAQ,CACN,MAAU,MACR,+BAA+B,EAAO,8BACxC,CACF,CAGA,MAAA,EAAM,EAAA,GAAA,CAAG,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EACpD,MAAA,EAAM,EAAA,MAAA,CAAM,EAAW,CAAE,UAAW,EAAK,CAAC,EAC1C,MAAA,EAAM,EAAA,MAAA,CAAM,EAAc,CAAE,UAAW,EAAK,CAAC,EAC7C,MAAA,EAAM,EAAA,MAAA,CAAM,EAAc,CAAE,UAAW,EAAK,CAAC,EAG7C,MAAM,EAAA,EAAW,GAAA,EAAQ,EAAA,KAAA,CAAK,EAAW,QAAQ,CAAC,EAGlD,IAAM,GAAA,EAAS,EAAA,QAAA,CAAQ,EAAM,EAAQ,MAAM,EACrC,EAAS,MAAM,EAAA,EAAW,CAAM,EAEhC,GAAA,EAAY,EAAA,QAAA,CAAQ,EAAc,iBAAiB,EACzD,MAAM,EAAA,EAAc,EAAW,EAAQ,CAAO,EAG9C,MAAA,EAAM,EAAA,MAAA,CAAM,CACV,WAAY,GACZ,OACA,MAAO,CACL,OAAQ,EACR,YAAa,GACb,IAAK,GACL,IAAK,CACH,MAAO,EACP,QAAS,CAAC,IAAI,EACd,aAAgB,UAClB,EACA,cAAe,CACb,SAAU,CAAC,EACX,OAAQ,CACN,qBAAsB,EACxB,CACF,CACF,CACF,CAAC,EAGD,IAAM,GAAA,EAAmB,EAAA,KAAA,CAAK,EAAc,iBAAiB,EACvD,GAAA,EAAgB,EAAA,KAAA,CAAK,EAAc,UAAU,EACnD,GAAI,CACF,MAAA,EAAM,EAAA,KAAA,CAAK,CAAgB,EAC3B,MAAA,EAAM,EAAA,OAAA,CAAO,EAAkB,CAAa,CAC9C,MAAQ,CAER,CAGA,MAAA,EAAM,EAAA,UAAA,EAAA,EACJ,EAAA,KAAA,CAAK,EAAc,iBAAiB,EACpC,KAAK,UACH,CACE,QAAS,aACT,QAAS,WACT,aAAc,SACd,iBAAkB,EACpB,EACA,KACA,CACF,EACA,MACF,EAGA,MAAA,EAAM,EAAA,UAAA,EAAA,EACJ,EAAA,KAAA,CAAK,EAAW,aAAa,EAC7B,KAAK,UACH,CACE,QAAS,EACT,OAAQ,CACN,CAAE,OAAQ,YAAa,EACvB,CAAE,IAAK,QAAS,KAAQ,gBAAiB,CAC3C,CACF,EACA,KACA,CACF,EACA,MACF,CACF,CACF"}
@@ -0,0 +1,9 @@
1
+ import type { Adapter } from "./index.js";
2
+ /**
3
+ * Vercel adapter for elur-kit.
4
+ *
5
+ * Produces a `.vercel/output` directory compatible with the Vercel Build Output
6
+ * API (v3). Static files are served from `dist/` and unmatched routes fall back
7
+ * to the SSR function.
8
+ */
9
+ export declare const vercelAdapter: Adapter;
@@ -0,0 +1,9 @@
1
+ import type { Adapter } from "./index.js";
2
+ /**
3
+ * Vercel adapter for elur-kit.
4
+ *
5
+ * Produces a `.vercel/output` directory compatible with the Vercel Build Output
6
+ * API (v3). Static files are served from `dist/` and unmatched routes fall back
7
+ * to the SSR function.
8
+ */
9
+ export declare const vercelAdapter: Adapter;
@@ -0,0 +1,62 @@
1
+ import { t as e } from "../route-scanner-XcLId7lK.js";
2
+ import { n as t, t as n } from "../shared-DU3iQgr7.js";
3
+ import { r } from "../capabilities-C7txofmY.js";
4
+ import { mkdir as i, rename as a, rm as o, stat as s, writeFile as c } from "node:fs/promises";
5
+ import { join as l, resolve as u } from "node:path";
6
+ import { build as d } from "vite";
7
+ //#region src/adapters/vercel.ts
8
+ var f = {
9
+ name: "vercel",
10
+ capabilities: r,
11
+ async build(r) {
12
+ let f = u(r.root), p = u(f, r.outDir), m = u(f, ".vercel/output"), h = l(m, "functions", "__elur-js-kit.func"), g = u(f, ".elur");
13
+ try {
14
+ await s(p);
15
+ } catch {
16
+ throw Error(`Output directory not found: ${p}. Run "elur-kit build" first.`);
17
+ }
18
+ await o(m, {
19
+ recursive: !0,
20
+ force: !0
21
+ }), await i(m, { recursive: !0 }), await i(h, { recursive: !0 }), await i(g, { recursive: !0 }), await n(p, l(m, "static"));
22
+ let _ = u(f, r.appDir), v = await e(_), y = u(g, "vercel-index.ts");
23
+ await t(y, v, r), await d({
24
+ configFile: !1,
25
+ root: f,
26
+ build: {
27
+ outDir: h,
28
+ emptyOutDir: !0,
29
+ ssr: !0,
30
+ lib: {
31
+ entry: y,
32
+ formats: ["es"],
33
+ fileName: () => "index.js"
34
+ },
35
+ rollupOptions: {
36
+ external: [],
37
+ output: { inlineDynamicImports: !0 }
38
+ }
39
+ }
40
+ });
41
+ let b = l(h, "vercel-index.js"), x = l(h, "index.js");
42
+ try {
43
+ await s(b), await a(b, x);
44
+ } catch {}
45
+ await c(l(h, ".vc-config.json"), JSON.stringify({
46
+ runtime: "nodejs20.x",
47
+ handler: "index.js",
48
+ launcherType: "Nodejs",
49
+ shouldAddHelpers: !0
50
+ }, null, 2), "utf8"), await c(l(m, "config.json"), JSON.stringify({
51
+ version: 3,
52
+ routes: [{ handle: "filesystem" }, {
53
+ src: "/(.*)",
54
+ dest: "/__elur-js-kit"
55
+ }]
56
+ }, null, 2), "utf8");
57
+ }
58
+ };
59
+ //#endregion
60
+ export { f as vercelAdapter };
61
+
62
+ //# sourceMappingURL=vercel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel.js","names":[],"sources":["../../../src/adapters/vercel.ts"],"sourcesContent":["import { mkdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { build } from \"vite\";\nimport { scanRoutes } from \"../router/route-scanner.js\";\nimport type { Adapter } from \"./index.js\";\nimport { copyStatic, writeSsrEntry } from \"./shared.js\";\nimport { SERVERLESS_CAPABILITIES } from \"../runtime/capabilities.js\";\n\n/**\n * Vercel adapter for elur-kit.\n *\n * Produces a `.vercel/output` directory compatible with the Vercel Build Output\n * API (v3). Static files are served from `dist/` and unmatched routes fall back\n * to the SSR function.\n */\nexport const vercelAdapter: Adapter = {\n name: \"vercel\",\n capabilities: SERVERLESS_CAPABILITIES,\n\n async build(options) {\n const root = resolve(options.root);\n const outDir = resolve(root, options.outDir);\n const vercelOut = resolve(root, \".vercel/output\");\n const functionsDir = join(vercelOut, \"functions\", \"__elur-js-kit.func\");\n const generatedDir = resolve(root, \".elur\");\n\n // Verify the production build exists.\n try {\n await stat(outDir);\n } catch {\n throw new Error(\n `Output directory not found: ${outDir}. Run \"elur-kit build\" first.`,\n );\n }\n\n // Clean previous adapter output.\n await rm(vercelOut, { recursive: true, force: true });\n await mkdir(vercelOut, { recursive: true });\n await mkdir(functionsDir, { recursive: true });\n await mkdir(generatedDir, { recursive: true });\n\n // Copy static files.\n await copyStatic(outDir, join(vercelOut, \"static\"));\n\n // Scan routes and generate a self-contained function entry.\n const appDir = resolve(root, options.appDir);\n const routes = await scanRoutes(appDir);\n\n const entryPath = resolve(generatedDir, \"vercel-index.ts\");\n await writeSsrEntry(entryPath, routes, options);\n\n // Bundle the function entry.\n await build({\n configFile: false,\n root,\n build: {\n outDir: functionsDir,\n emptyOutDir: true,\n ssr: true,\n lib: {\n entry: entryPath,\n formats: [\"es\"],\n fileName: () => \"index.js\",\n },\n rollupOptions: {\n external: [],\n output: {\n inlineDynamicImports: true,\n },\n },\n },\n });\n\n // Vite SSR lib builds may use the entry file name, so force the expected handler name.\n const generatedHandler = join(functionsDir, \"vercel-index.js\");\n const targetHandler = join(functionsDir, \"index.js\");\n try {\n await stat(generatedHandler);\n await rename(generatedHandler, targetHandler);\n } catch {\n // If the file is already named index.js, nothing to do.\n }\n\n // Write Vercel function config.\n await writeFile(\n join(functionsDir, \".vc-config.json\"),\n JSON.stringify(\n {\n runtime: \"nodejs20.x\",\n handler: \"index.js\",\n launcherType: \"Nodejs\",\n shouldAddHelpers: true,\n },\n null,\n 2,\n ),\n \"utf8\",\n );\n\n // Write Vercel root config.\n await writeFile(\n join(vercelOut, \"config.json\"),\n JSON.stringify(\n {\n version: 3,\n routes: [\n { handle: \"filesystem\" },\n { src: \"/(.*)\", \"dest\": \"/__elur-js-kit\" },\n ],\n },\n null,\n 2,\n ),\n \"utf8\",\n );\n },\n};\n"],"mappings":";;;;;;;AAeA,IAAa,IAAyB;CACpC,MAAM;CACN,cAAc;CAEd,MAAM,MAAM,GAAS;EACnB,IAAM,IAAO,EAAQ,EAAQ,IAAI,GAC3B,IAAS,EAAQ,GAAM,EAAQ,MAAM,GACrC,IAAY,EAAQ,GAAM,gBAAgB,GAC1C,IAAe,EAAK,GAAW,aAAa,oBAAoB,GAChE,IAAe,EAAQ,GAAM,OAAO;EAG1C,IAAI;GACF,MAAM,EAAK,CAAM;EACnB,QAAQ;GACN,MAAU,MACR,+BAA+B,EAAO,8BACxC;EACF;EASA,AANA,MAAM,EAAG,GAAW;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC,GACpD,MAAM,EAAM,GAAW,EAAE,WAAW,GAAK,CAAC,GAC1C,MAAM,EAAM,GAAc,EAAE,WAAW,GAAK,CAAC,GAC7C,MAAM,EAAM,GAAc,EAAE,WAAW,GAAK,CAAC,GAG7C,MAAM,EAAW,GAAQ,EAAK,GAAW,QAAQ,CAAC;EAGlD,IAAM,IAAS,EAAQ,GAAM,EAAQ,MAAM,GACrC,IAAS,MAAM,EAAW,CAAM,GAEhC,IAAY,EAAQ,GAAc,iBAAiB;EAIzD,AAHA,MAAM,EAAc,GAAW,GAAQ,CAAO,GAG9C,MAAM,EAAM;GACV,YAAY;GACZ;GACA,OAAO;IACL,QAAQ;IACR,aAAa;IACb,KAAK;IACL,KAAK;KACH,OAAO;KACP,SAAS,CAAC,IAAI;KACd,gBAAgB;IAClB;IACA,eAAe;KACb,UAAU,CAAC;KACX,QAAQ,EACN,sBAAsB,GACxB;IACF;GACF;EACF,CAAC;EAGD,IAAM,IAAmB,EAAK,GAAc,iBAAiB,GACvD,IAAgB,EAAK,GAAc,UAAU;EACnD,IAAI;GAEF,AADA,MAAM,EAAK,CAAgB,GAC3B,MAAM,EAAO,GAAkB,CAAa;EAC9C,QAAQ,CAER;EAmBA,AAhBA,MAAM,EACJ,EAAK,GAAc,iBAAiB,GACpC,KAAK,UACH;GACE,SAAS;GACT,SAAS;GACT,cAAc;GACd,kBAAkB;EACpB,GACA,MACA,CACF,GACA,MACF,GAGA,MAAM,EACJ,EAAK,GAAW,aAAa,GAC7B,KAAK,UACH;GACE,SAAS;GACT,QAAQ,CACN,EAAE,QAAQ,aAAa,GACvB;IAAE,KAAK;IAAS,MAAQ;GAAiB,CAC3C;EACF,GACA,MACA,CACF,GACA,MACF;CACF;AACF"}
@@ -0,0 +1,83 @@
1
+ import { scanRoutes, type PageRoute, type ScannedRoutes } from "../router/route-scanner.js";
2
+ import { type IslandModule } from "../island/scan.js";
3
+ import { type ImageFormat } from "../image/index.js";
4
+ import { type ElurKitIntegration } from "../integrations/index.js";
5
+ export interface BuildConfig {
6
+ /** Absolute path to the app directory (e.g. /project/src/app). */
7
+ appDir: string;
8
+ /** Absolute path to the output directory (e.g. /project/dist). */
9
+ outDir: string;
10
+ /** Absolute path to the project root (e.g. /project). When provided, action
11
+ * paths in the serialized HTML shell are made relative to this root. */
12
+ root?: string;
13
+ /** Base path for the client entry module, e.g. "/_elur/entry-client.js". */
14
+ clientEntry?: string;
15
+ /** Default language for the HTML shell. */
16
+ lang?: string;
17
+ /**
18
+ * Absolute path to the islands directory (e.g. /project/src/islands).
19
+ * When set, `build` scans it and generates a client entry module listing
20
+ * every island so you don't have to maintain `entry-client.ts` by hand.
21
+ */
22
+ islandsDir?: string;
23
+ /**
24
+ * Absolute path where the generated client entry module is written
25
+ * (e.g. /project/.elur/entry-client.ts). Required when `islandsDir` is set.
26
+ */
27
+ generatedEntry?: string;
28
+ /**
29
+ * Import specifier the generated entry uses for `hydrateIslands`.
30
+ * Defaults to the published subpath `@elurjs/kit/island`.
31
+ */
32
+ hydrateImport?: string;
33
+ /**
34
+ * Import specifier the generated entry uses for `startClientRouter`.
35
+ * Defaults to the published subpath `@elurjs/kit/router`.
36
+ */
37
+ routerImport?: string;
38
+ /** Absolute path to the public directory for static assets (optional). */
39
+ publicDir?: string;
40
+ /** Image formats to generate when sharp is available. Defaults to ["webp", "avif"]. */
41
+ imageFormats?: ImageFormat[];
42
+ /**
43
+ * Whether the SSR render endpoint (`/__elur-js/render`) exists at runtime.
44
+ * Defaults to `true` (dev, preview and SSR deployments). Set to `false` for
45
+ * fully static outputs so the emitted HTML tells the client router to skip
46
+ * the endpoint (no 404 storms on static hosts like Vercel).
47
+ */
48
+ renderEndpoint?: boolean;
49
+ /**
50
+ * Integrations to invoke during the build lifecycle. When provided, the
51
+ * `build` hook fires after all pages and image variants are generated,
52
+ * giving integrations a chance to write post-build artifacts (sitemaps,
53
+ * robots.txt, search indexes, etc.) into the output directory.
54
+ */
55
+ integrations?: ElurKitIntegration[];
56
+ }
57
+ export interface BuildResult {
58
+ /** Number of static HTML pages generated. */
59
+ pages: number;
60
+ /** Paths that were skipped because they are dynamic without a static param list. */
61
+ skipped: string[];
62
+ /** Absolute paths to the generated HTML files. */
63
+ files: string[];
64
+ /** Islands discovered when `islandsDir` is set. */
65
+ islands: IslandModule[];
66
+ /** Absolute path to the generated client entry, if one was written. */
67
+ generatedEntry?: string;
68
+ /** Number of image variants generated (0 if sharp is not installed). */
69
+ imagesProcessed: number;
70
+ /** Absolute path to the output directory where build artifacts were written.
71
+ * When called via the CLI, this is the atomic staging directory (not the
72
+ * final `dist/`). Integration `build` hooks should write post-build
73
+ * artifacts here so they survive the atomic swap. */
74
+ outDir: string;
75
+ }
76
+ /**
77
+ * Builds a static site from a scanned route tree.
78
+ *
79
+ * @param config Build configuration.
80
+ * @returns Summary of generated files.
81
+ */
82
+ export declare function build(config: BuildConfig): Promise<BuildResult>;
83
+ export { scanRoutes, type PageRoute, type ScannedRoutes };
@@ -0,0 +1,83 @@
1
+ import { scanRoutes, type PageRoute, type ScannedRoutes } from "../router/route-scanner.js";
2
+ import { type IslandModule } from "../island/scan.js";
3
+ import { type ImageFormat } from "../image/index.js";
4
+ import { type ElurKitIntegration } from "../integrations/index.js";
5
+ export interface BuildConfig {
6
+ /** Absolute path to the app directory (e.g. /project/src/app). */
7
+ appDir: string;
8
+ /** Absolute path to the output directory (e.g. /project/dist). */
9
+ outDir: string;
10
+ /** Absolute path to the project root (e.g. /project). When provided, action
11
+ * paths in the serialized HTML shell are made relative to this root. */
12
+ root?: string;
13
+ /** Base path for the client entry module, e.g. "/_elur/entry-client.js". */
14
+ clientEntry?: string;
15
+ /** Default language for the HTML shell. */
16
+ lang?: string;
17
+ /**
18
+ * Absolute path to the islands directory (e.g. /project/src/islands).
19
+ * When set, `build` scans it and generates a client entry module listing
20
+ * every island so you don't have to maintain `entry-client.ts` by hand.
21
+ */
22
+ islandsDir?: string;
23
+ /**
24
+ * Absolute path where the generated client entry module is written
25
+ * (e.g. /project/.elur/entry-client.ts). Required when `islandsDir` is set.
26
+ */
27
+ generatedEntry?: string;
28
+ /**
29
+ * Import specifier the generated entry uses for `hydrateIslands`.
30
+ * Defaults to the published subpath `@elurjs/kit/island`.
31
+ */
32
+ hydrateImport?: string;
33
+ /**
34
+ * Import specifier the generated entry uses for `startClientRouter`.
35
+ * Defaults to the published subpath `@elurjs/kit/router`.
36
+ */
37
+ routerImport?: string;
38
+ /** Absolute path to the public directory for static assets (optional). */
39
+ publicDir?: string;
40
+ /** Image formats to generate when sharp is available. Defaults to ["webp", "avif"]. */
41
+ imageFormats?: ImageFormat[];
42
+ /**
43
+ * Whether the SSR render endpoint (`/__elur-js/render`) exists at runtime.
44
+ * Defaults to `true` (dev, preview and SSR deployments). Set to `false` for
45
+ * fully static outputs so the emitted HTML tells the client router to skip
46
+ * the endpoint (no 404 storms on static hosts like Vercel).
47
+ */
48
+ renderEndpoint?: boolean;
49
+ /**
50
+ * Integrations to invoke during the build lifecycle. When provided, the
51
+ * `build` hook fires after all pages and image variants are generated,
52
+ * giving integrations a chance to write post-build artifacts (sitemaps,
53
+ * robots.txt, search indexes, etc.) into the output directory.
54
+ */
55
+ integrations?: ElurKitIntegration[];
56
+ }
57
+ export interface BuildResult {
58
+ /** Number of static HTML pages generated. */
59
+ pages: number;
60
+ /** Paths that were skipped because they are dynamic without a static param list. */
61
+ skipped: string[];
62
+ /** Absolute paths to the generated HTML files. */
63
+ files: string[];
64
+ /** Islands discovered when `islandsDir` is set. */
65
+ islands: IslandModule[];
66
+ /** Absolute path to the generated client entry, if one was written. */
67
+ generatedEntry?: string;
68
+ /** Number of image variants generated (0 if sharp is not installed). */
69
+ imagesProcessed: number;
70
+ /** Absolute path to the output directory where build artifacts were written.
71
+ * When called via the CLI, this is the atomic staging directory (not the
72
+ * final `dist/`). Integration `build` hooks should write post-build
73
+ * artifacts here so they survive the atomic swap. */
74
+ outDir: string;
75
+ }
76
+ /**
77
+ * Builds a static site from a scanned route tree.
78
+ *
79
+ * @param config Build configuration.
80
+ * @returns Summary of generated files.
81
+ */
82
+ export declare function build(config: BuildConfig): Promise<BuildResult>;
83
+ export { scanRoutes, type PageRoute, type ScannedRoutes };
@@ -0,0 +1,48 @@
1
+ import type { PageMetadata } from "../types.js";
2
+ export interface ShellOptions {
3
+ /** Rendered inner HTML that goes inside `#app`. */
4
+ body: string;
5
+ /** `<title>` text. */
6
+ title?: string;
7
+ /** `<html lang>` attribute. */
8
+ lang?: string;
9
+ /** Additional attributes for the `<html>` element, e.g. `{ "data-theme": "dark" }`. */
10
+ htmlAttributes?: Record<string, string>;
11
+ /**
12
+ * Inline scripts injected into `<head>`. They run synchronously while the
13
+ * document parses — before the first paint and before the (deferred) client
14
+ * bundle — so they are the right place for no-flash bootstrapping (e.g.
15
+ * applying a stored theme before the page becomes visible).
16
+ */
17
+ headScripts?: string[];
18
+ /**
19
+ * Raw HTML strings injected into `<head>` — e.g. `<link rel="icon">`,
20
+ * `<link rel="manifest">`, `<meta name="theme-color">`. Each string is
21
+ * rendered as-is inside `<head>`.
22
+ */
23
+ headLinks?: string[];
24
+ /** Loader data serialized into `<script id="elur-data">`. */
25
+ data?: unknown;
26
+ /** Per-page action names serialized into `<script id="elur-actions">`. */
27
+ actions?: Record<string, string[]>;
28
+ /** Path to the client entry module, e.g. `/_elur/entry-client.js`. */
29
+ clientEntry?: string;
30
+ /** Page metadata emitted as `<meta>`, `<link>` and OG/Twitter tags in `<head>`. */
31
+ metadata?: PageMetadata;
32
+ /**
33
+ * Whether the SSR render endpoint (`/__elur-js/render`) is available at
34
+ * runtime. Defaults to `true`. When `false` (static deployments), the shell
35
+ * emits `<meta name="elur:render-endpoint" content="off" />` so the client
36
+ * router skips probing the endpoint entirely — preventing a storm of 404
37
+ * requests on fully static sites.
38
+ */
39
+ renderEndpoint?: boolean;
40
+ }
41
+ /**
42
+ * Builds the `<head>` tags for a `PageMetadata` object. Every tag is marked with
43
+ * `data-elur-head` so the client-side router can replace them on navigation
44
+ * without touching charset/viewport or user-supplied `headScripts`.
45
+ */
46
+ export declare function buildHeadTags(metadata: PageMetadata, fallbackTitle: string): string;
47
+ /** Wraps rendered body HTML into a full HTML document. */
48
+ export declare function documentShell(opts: ShellOptions): string;
@@ -0,0 +1,48 @@
1
+ import type { PageMetadata } from "../types.js";
2
+ export interface ShellOptions {
3
+ /** Rendered inner HTML that goes inside `#app`. */
4
+ body: string;
5
+ /** `<title>` text. */
6
+ title?: string;
7
+ /** `<html lang>` attribute. */
8
+ lang?: string;
9
+ /** Additional attributes for the `<html>` element, e.g. `{ "data-theme": "dark" }`. */
10
+ htmlAttributes?: Record<string, string>;
11
+ /**
12
+ * Inline scripts injected into `<head>`. They run synchronously while the
13
+ * document parses — before the first paint and before the (deferred) client
14
+ * bundle — so they are the right place for no-flash bootstrapping (e.g.
15
+ * applying a stored theme before the page becomes visible).
16
+ */
17
+ headScripts?: string[];
18
+ /**
19
+ * Raw HTML strings injected into `<head>` — e.g. `<link rel="icon">`,
20
+ * `<link rel="manifest">`, `<meta name="theme-color">`. Each string is
21
+ * rendered as-is inside `<head>`.
22
+ */
23
+ headLinks?: string[];
24
+ /** Loader data serialized into `<script id="elur-data">`. */
25
+ data?: unknown;
26
+ /** Per-page action names serialized into `<script id="elur-actions">`. */
27
+ actions?: Record<string, string[]>;
28
+ /** Path to the client entry module, e.g. `/_elur/entry-client.js`. */
29
+ clientEntry?: string;
30
+ /** Page metadata emitted as `<meta>`, `<link>` and OG/Twitter tags in `<head>`. */
31
+ metadata?: PageMetadata;
32
+ /**
33
+ * Whether the SSR render endpoint (`/__elur-js/render`) is available at
34
+ * runtime. Defaults to `true`. When `false` (static deployments), the shell
35
+ * emits `<meta name="elur:render-endpoint" content="off" />` so the client
36
+ * router skips probing the endpoint entirely — preventing a storm of 404
37
+ * requests on fully static sites.
38
+ */
39
+ renderEndpoint?: boolean;
40
+ }
41
+ /**
42
+ * Builds the `<head>` tags for a `PageMetadata` object. Every tag is marked with
43
+ * `data-elur-head` so the client-side router can replace them on navigation
44
+ * without touching charset/viewport or user-supplied `headScripts`.
45
+ */
46
+ export declare function buildHeadTags(metadata: PageMetadata, fallbackTitle: string): string;
47
+ /** Wraps rendered body HTML into a full HTML document. */
48
+ export declare function documentShell(opts: ShellOptions): string;
@@ -0,0 +1,26 @@
1
+ import { type InterpolationMode } from "../vite/interpolation-plugin.js";
2
+ export interface TransformProjectOptions {
3
+ root: string;
4
+ appDir: string;
5
+ islandsDir?: string;
6
+ /**
7
+ * Absolute path to the transformed tree root. The tree mirrors the project
8
+ * layout relative to the common ancestor of `appDir`/`islandsDir`, so
9
+ * relative imports between app and islands keep resolving. Relative imports
10
+ * that escape that ancestor are compensated for the added directory depth.
11
+ */
12
+ outDir: string;
13
+ /**
14
+ * How the legacy interpolation transform is handled (default: "auto").
15
+ * With a Elur core that supports partial attribute interpolation natively
16
+ * the transform is not applied; use "legacy" for migrations against older
17
+ * cores and "off" to never transform.
18
+ */
19
+ interpolation?: InterpolationMode;
20
+ }
21
+ /**
22
+ * Absolute path of the transformed app directory inside the mirror tree,
23
+ * matching where `transformProjectFiles` copies the app files.
24
+ */
25
+ export declare function transformedAppDir(root: string, appDir: string, islandsDir: string | undefined, outDir: string): string;
26
+ export declare function transformProjectFiles(options: TransformProjectOptions): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { type InterpolationMode } from "../vite/interpolation-plugin.js";
2
+ export interface TransformProjectOptions {
3
+ root: string;
4
+ appDir: string;
5
+ islandsDir?: string;
6
+ /**
7
+ * Absolute path to the transformed tree root. The tree mirrors the project
8
+ * layout relative to the common ancestor of `appDir`/`islandsDir`, so
9
+ * relative imports between app and islands keep resolving. Relative imports
10
+ * that escape that ancestor are compensated for the added directory depth.
11
+ */
12
+ outDir: string;
13
+ /**
14
+ * How the legacy interpolation transform is handled (default: "auto").
15
+ * With a Elur core that supports partial attribute interpolation natively
16
+ * the transform is not applied; use "legacy" for migrations against older
17
+ * cores and "off" to never transform.
18
+ */
19
+ interpolation?: InterpolationMode;
20
+ }
21
+ /**
22
+ * Absolute path of the transformed app directory inside the mirror tree,
23
+ * matching where `transformProjectFiles` copies the app files.
24
+ */
25
+ export declare function transformedAppDir(root: string, appDir: string, islandsDir: string | undefined, outDir: string): string;
26
+ export declare function transformProjectFiles(options: TransformProjectOptions): Promise<void>;
@@ -0,0 +1,78 @@
1
+ import { type InterpolationMode } from "../vite/interpolation-plugin.js";
2
+ export interface ClientBuildOptions {
3
+ /** Project root (absolute). */
4
+ root: string;
5
+ /** Absolute path to the user's Vite client config (e.g. vite.client.config.ts). */
6
+ userConfigPath: string;
7
+ /** Absolute path to the app directory (used by the interpolation plugin). */
8
+ appDir: string;
9
+ /** Absolute path to the islands directory (used by the interpolation plugin). */
10
+ islandsDir: string;
11
+ /** Output directory for the client bundle (absolute). */
12
+ outDir: string;
13
+ /** Optional base path. */
14
+ base?: string;
15
+ /** Optional log prefix. */
16
+ logPrefix?: string;
17
+ /**
18
+ * How the legacy interpolation transform is handled (default: "auto").
19
+ * With a Elur core that supports partial attribute interpolation natively
20
+ * the transform is not applied; use "legacy" for migrations against older
21
+ * cores and "off" to never transform.
22
+ */
23
+ interpolation?: InterpolationMode;
24
+ }
25
+ export interface ClientBuildResult {
26
+ /** Output directory (same as `outDir` input). */
27
+ outDir: string;
28
+ /** Number of chunks/assets emitted, if reported by Vite. */
29
+ outputCount: number;
30
+ }
31
+ /**
32
+ * Build the client hydration bundle using the Vite JavaScript API.
33
+ *
34
+ * The user's config is loaded programmatically and the elur interpolation
35
+ * plugin is injected so partial attribute interpolations inside islands are
36
+ * transformed before reaching the browser.
37
+ */
38
+ export declare function buildClientBundle(options: ClientBuildOptions): Promise<ClientBuildResult>;
39
+ export interface AtomicStageOptions {
40
+ /** Final destination directory (absolute). */
41
+ outDir: string;
42
+ /** Build into this temp directory first, then rename to `outDir`. */
43
+ tempDir?: string;
44
+ /** Whether to preserve existing content in `outDir` during the swap. */
45
+ keepExisting?: boolean;
46
+ }
47
+ export interface AtomicStage {
48
+ tempDir: string;
49
+ /** Call after the build succeeds to atomically swap temp → outDir. */
50
+ commit: () => Promise<void>;
51
+ /** Call on failure to clean up the temp directory. */
52
+ rollback: () => Promise<void>;
53
+ }
54
+ /**
55
+ * Prepare an atomic staging directory for build output.
56
+ *
57
+ * Usage:
58
+ * const stage = await beginAtomicStage({ outDir });
59
+ * try {
60
+ * await buildInto(stage.tempDir);
61
+ * await stage.commit();
62
+ * } catch (err) {
63
+ * await stage.rollback();
64
+ * throw err;
65
+ * }
66
+ */
67
+ export declare function beginAtomicStage(options: AtomicStageOptions): Promise<AtomicStage>;
68
+ export interface CopyPublicAssetsOptions {
69
+ /** Absolute path to the public directory. */
70
+ publicDir: string;
71
+ /** Absolute path to the output directory. */
72
+ outDir: string;
73
+ }
74
+ /**
75
+ * Copy the public directory into the output directory.
76
+ * Returns the number of files copied.
77
+ */
78
+ export declare function copyPublicAssets(options: CopyPublicAssetsOptions): Promise<number>;
@@ -0,0 +1,78 @@
1
+ import { type InterpolationMode } from "../vite/interpolation-plugin.js";
2
+ export interface ClientBuildOptions {
3
+ /** Project root (absolute). */
4
+ root: string;
5
+ /** Absolute path to the user's Vite client config (e.g. vite.client.config.ts). */
6
+ userConfigPath: string;
7
+ /** Absolute path to the app directory (used by the interpolation plugin). */
8
+ appDir: string;
9
+ /** Absolute path to the islands directory (used by the interpolation plugin). */
10
+ islandsDir: string;
11
+ /** Output directory for the client bundle (absolute). */
12
+ outDir: string;
13
+ /** Optional base path. */
14
+ base?: string;
15
+ /** Optional log prefix. */
16
+ logPrefix?: string;
17
+ /**
18
+ * How the legacy interpolation transform is handled (default: "auto").
19
+ * With a Elur core that supports partial attribute interpolation natively
20
+ * the transform is not applied; use "legacy" for migrations against older
21
+ * cores and "off" to never transform.
22
+ */
23
+ interpolation?: InterpolationMode;
24
+ }
25
+ export interface ClientBuildResult {
26
+ /** Output directory (same as `outDir` input). */
27
+ outDir: string;
28
+ /** Number of chunks/assets emitted, if reported by Vite. */
29
+ outputCount: number;
30
+ }
31
+ /**
32
+ * Build the client hydration bundle using the Vite JavaScript API.
33
+ *
34
+ * The user's config is loaded programmatically and the elur interpolation
35
+ * plugin is injected so partial attribute interpolations inside islands are
36
+ * transformed before reaching the browser.
37
+ */
38
+ export declare function buildClientBundle(options: ClientBuildOptions): Promise<ClientBuildResult>;
39
+ export interface AtomicStageOptions {
40
+ /** Final destination directory (absolute). */
41
+ outDir: string;
42
+ /** Build into this temp directory first, then rename to `outDir`. */
43
+ tempDir?: string;
44
+ /** Whether to preserve existing content in `outDir` during the swap. */
45
+ keepExisting?: boolean;
46
+ }
47
+ export interface AtomicStage {
48
+ tempDir: string;
49
+ /** Call after the build succeeds to atomically swap temp → outDir. */
50
+ commit: () => Promise<void>;
51
+ /** Call on failure to clean up the temp directory. */
52
+ rollback: () => Promise<void>;
53
+ }
54
+ /**
55
+ * Prepare an atomic staging directory for build output.
56
+ *
57
+ * Usage:
58
+ * const stage = await beginAtomicStage({ outDir });
59
+ * try {
60
+ * await buildInto(stage.tempDir);
61
+ * await stage.commit();
62
+ * } catch (err) {
63
+ * await stage.rollback();
64
+ * throw err;
65
+ * }
66
+ */
67
+ export declare function beginAtomicStage(options: AtomicStageOptions): Promise<AtomicStage>;
68
+ export interface CopyPublicAssetsOptions {
69
+ /** Absolute path to the public directory. */
70
+ publicDir: string;
71
+ /** Absolute path to the output directory. */
72
+ outDir: string;
73
+ }
74
+ /**
75
+ * Copy the public directory into the output directory.
76
+ * Returns the number of files copied.
77
+ */
78
+ export declare function copyPublicAssets(options: CopyPublicAssetsOptions): Promise<number>;