vite-elysia-forge 0.0.2 → 0.0.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.
package/dist/cli.js CHANGED
@@ -8,5 +8,4 @@ startServer({
8
8
  port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
9
9
  distDir: "dist",
10
10
  });
11
- `;writeFileSync(t,u);try{let i=await Bun.build({entrypoints:[t],outdir:"dist",target:"bun",minify:!0,naming:"server.js"});if(!i.success){console.error("\u274C Server build failed");for(let a of i.logs)console.error(a);process.exit(1);}}catch(i){console.error("\u274C Failed to build server. Ensure you are running this command with Bun."),console.error(i),process.exit(1);}finally{existsSync(t)&&unlinkSync(t);}console.log("\u2705 Build complete!"),console.log(" Run your production server with:"),console.log(" $ bun dist/server.js");}if(import.meta.main){let o=process.argv.slice(2);if(o[0]==="build"){let r=o[1];g(r);}else console.log("Usage: vite-elysia-forge build [api-entry]"),console.log(" api-entry: Path to your API entry file (default: src/server/api.ts)");}export{g as build};//# sourceMappingURL=cli.js.map
12
- //# sourceMappingURL=cli.js.map
11
+ `;writeFileSync(t,u);try{let i=await Bun.build({entrypoints:[t],outdir:"dist",target:"bun",minify:!0,naming:"server.js"});if(!i.success){console.error("\u274C Server build failed");for(let a of i.logs)console.error(a);process.exit(1);}}catch(i){console.error("\u274C Failed to build server. Ensure you are running this command with Bun."),console.error(i),process.exit(1);}finally{existsSync(t)&&unlinkSync(t);}console.log("\u2705 Build complete!"),console.log(" Run your production server with:"),console.log(" $ bun dist/server.js");}if(import.meta.main){let o=process.argv.slice(2);if(o[0]==="build"){let r=o[1];g(r);}else console.log("Usage: vite-elysia-forge build [api-entry]"),console.log(" api-entry: Path to your API entry file (default: src/server/api.ts)");}export{g as build};
package/dist/index.cjs CHANGED
@@ -1,3 +1,2 @@
1
- 'use strict';var path=require('path'),P=require('pino');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var P__default=/*#__PURE__*/_interopDefault(P);var M=process.env.NODE_ENV==="production",f=P__default.default({name:"vite-elysia-forge",transport:M?void 0:{target:"pino-pretty",options:{colorize:true}}});function B({serverFile:m="/server/api.ts"}){return {name:"vite-elysia-forge",async configureServer(n){let c=m,y=path.resolve(n.config.root,c.slice(1)),p=async()=>(await n.ssrLoadModule(c)).api,g=await p();n.watcher.add(y),n.watcher.on("change",async e=>{let o=await n.moduleGraph.getModuleByUrl(c);if(!o)return;let r=n.moduleGraph.getModulesByFile(e);if(!r||r.size===0)return;let i=false,a=new Set,s=[...r];for(;s.length>0;){let t=s.shift();if(!(!t||!t.id||a.has(t.id))){if(a.add(t.id),t.id===o.id){i=true;break}for(let l of t.importers)s.push(l);}}if(i)try{n.moduleGraph.invalidateModule(o),g=await p(),f.info("Reloaded Elysia API module");}catch(t){f.error(`Failed to reload Elysia API: ${t}`);}}),n.middlewares.use(async(e,o,r)=>{if(!e.url?.startsWith("/api"))return r();try{let i="http",a=e.headers.host||"localhost:3000",s=`${i}://${a}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let l=new Request(s,{method:e.method,headers:e.headers,body:t}),u=await g.handle(l);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let w=await u.text();o.end(w);}catch(i){f.error(`Elysia error: ${i}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var A=B;
2
- module.exports=A;//# sourceMappingURL=index.cjs.map
3
- //# sourceMappingURL=index.cjs.map
1
+ 'use strict';var path=require('path');function M({serverFile:g="/server/api.ts"}){return {name:"vite-elysia-forge",async configureServer(s){let l=g,y=path.resolve(s.config.root,l.slice(1)),f=async()=>(await s.ssrLoadModule(l)).api,p=await f();s.watcher.add(y),s.watcher.on("change",async e=>{let o=await s.moduleGraph.getModuleByUrl(l);if(!o)return;let i=s.moduleGraph.getModulesByFile(e);if(!i||i.size===0)return;let n=false,r=new Set,a=[...i];for(;a.length>0;){let t=a.shift();if(!(!t||!t.id||r.has(t.id))){if(r.add(t.id),t.id===o.id){n=true;break}for(let c of t.importers)a.push(c);}}if(n)try{s.moduleGraph.invalidateModule(o),p=await f(),console.log("[vite-elysia-forge] Reloaded Elysia API module");}catch(t){console.error(`[vite-elysia-forge] Failed to reload Elysia API: ${t}`);}}),s.middlewares.use(async(e,o,i)=>{if(!e.url?.startsWith("/api"))return i();try{let n="http",r=e.headers.host||"localhost:3000",a=`${n}://${r}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let c=new Request(a,{method:e.method,headers:e.headers,body:t}),u=await p.handle(c);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let m=await u.text();o.end(m);}catch(n){console.error(`[vite-elysia-forge] Elysia error: ${n}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var P=M;
2
+ module.exports=P;
package/dist/index.d.cts CHANGED
@@ -1,12 +1,25 @@
1
1
  import { Plugin } from 'vite';
2
2
 
3
+ /**
4
+ * Configuration options for the Vite Elysia Forge plugin.
5
+ */
3
6
  interface ConfigOptions {
4
7
  /**
5
8
  * The URL path to the server API module.
9
+ * This file should export the Elysia app instance as `api`.
6
10
  * @default "/server/api.ts"
7
11
  */
8
12
  serverFile?: string;
9
13
  }
14
+ /**
15
+ * A Vite plugin that integrates ElysiaJS into the Vite development server.
16
+ *
17
+ * This plugin allows you to run your Elysia backend alongside your frontend code
18
+ * in the same Vite dev server, enabling seamless full-stack development.
19
+ *
20
+ * @param options - Configuration options for the plugin.
21
+ * @returns A Vite plugin instance.
22
+ */
10
23
  declare function elysiaPlugin({ serverFile }: ConfigOptions): Plugin;
11
24
 
12
- export { elysiaPlugin as default };
25
+ export { type ConfigOptions, elysiaPlugin as default };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,25 @@
1
1
  import { Plugin } from 'vite';
2
2
 
3
+ /**
4
+ * Configuration options for the Vite Elysia Forge plugin.
5
+ */
3
6
  interface ConfigOptions {
4
7
  /**
5
8
  * The URL path to the server API module.
9
+ * This file should export the Elysia app instance as `api`.
6
10
  * @default "/server/api.ts"
7
11
  */
8
12
  serverFile?: string;
9
13
  }
14
+ /**
15
+ * A Vite plugin that integrates ElysiaJS into the Vite development server.
16
+ *
17
+ * This plugin allows you to run your Elysia backend alongside your frontend code
18
+ * in the same Vite dev server, enabling seamless full-stack development.
19
+ *
20
+ * @param options - Configuration options for the plugin.
21
+ * @returns A Vite plugin instance.
22
+ */
10
23
  declare function elysiaPlugin({ serverFile }: ConfigOptions): Plugin;
11
24
 
12
- export { elysiaPlugin as default };
25
+ export { type ConfigOptions, elysiaPlugin as default };
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
- import {resolve}from'path';import P from'pino';var M=process.env.NODE_ENV==="production",f=P({name:"vite-elysia-forge",transport:M?void 0:{target:"pino-pretty",options:{colorize:true}}});function B({serverFile:m="/server/api.ts"}){return {name:"vite-elysia-forge",async configureServer(n){let c=m,y=resolve(n.config.root,c.slice(1)),p=async()=>(await n.ssrLoadModule(c)).api,g=await p();n.watcher.add(y),n.watcher.on("change",async e=>{let o=await n.moduleGraph.getModuleByUrl(c);if(!o)return;let r=n.moduleGraph.getModulesByFile(e);if(!r||r.size===0)return;let i=false,a=new Set,s=[...r];for(;s.length>0;){let t=s.shift();if(!(!t||!t.id||a.has(t.id))){if(a.add(t.id),t.id===o.id){i=true;break}for(let l of t.importers)s.push(l);}}if(i)try{n.moduleGraph.invalidateModule(o),g=await p(),f.info("Reloaded Elysia API module");}catch(t){f.error(`Failed to reload Elysia API: ${t}`);}}),n.middlewares.use(async(e,o,r)=>{if(!e.url?.startsWith("/api"))return r();try{let i="http",a=e.headers.host||"localhost:3000",s=`${i}://${a}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let l=new Request(s,{method:e.method,headers:e.headers,body:t}),u=await g.handle(l);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let w=await u.text();o.end(w);}catch(i){f.error(`Elysia error: ${i}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var A=B;
2
- export{A as default};//# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
1
+ import {resolve}from'path';function M({serverFile:g="/server/api.ts"}){return {name:"vite-elysia-forge",async configureServer(s){let l=g,y=resolve(s.config.root,l.slice(1)),f=async()=>(await s.ssrLoadModule(l)).api,p=await f();s.watcher.add(y),s.watcher.on("change",async e=>{let o=await s.moduleGraph.getModuleByUrl(l);if(!o)return;let i=s.moduleGraph.getModulesByFile(e);if(!i||i.size===0)return;let n=false,r=new Set,a=[...i];for(;a.length>0;){let t=a.shift();if(!(!t||!t.id||r.has(t.id))){if(r.add(t.id),t.id===o.id){n=true;break}for(let c of t.importers)a.push(c);}}if(n)try{s.moduleGraph.invalidateModule(o),p=await f(),console.log("[vite-elysia-forge] Reloaded Elysia API module");}catch(t){console.error(`[vite-elysia-forge] Failed to reload Elysia API: ${t}`);}}),s.middlewares.use(async(e,o,i)=>{if(!e.url?.startsWith("/api"))return i();try{let n="http",r=e.headers.host||"localhost:3000",a=`${n}://${r}${e.url}`,t;if(e.method!=="GET"&&e.method!=="HEAD"){let d=[];for await(let h of e)d.push(h);t=Buffer.concat(d).toString();}let c=new Request(a,{method:e.method,headers:e.headers,body:t}),u=await p.handle(c);o.statusCode=u.status,u.headers.forEach((d,h)=>{o.setHeader(h,d);});let m=await u.text();o.end(m);}catch(n){console.error(`[vite-elysia-forge] Elysia error: ${n}`),o.statusCode=500,o.end("Internal Server Error");}});}}}var P=M;
2
+ export{P as default};
@@ -1,12 +1,43 @@
1
+ /**
2
+ * Options for starting the production server.
3
+ */
1
4
  interface ProductionOptions {
5
+ /**
6
+ * The port to listen on.
7
+ * @default 3000
8
+ */
2
9
  port?: number;
10
+ /**
11
+ * The directory containing the built frontend assets.
12
+ * @default "dist"
13
+ */
3
14
  distDir?: string;
15
+ /**
16
+ * The name of the HTML entry file.
17
+ * @default "index.html"
18
+ */
4
19
  htmlFile?: string;
20
+ /**
21
+ * The prefix for API routes. Requests starting with this prefix will be handled by the Elysia app.
22
+ * @default "/api"
23
+ */
5
24
  apiPrefix?: string;
25
+ /**
26
+ * The Elysia app instance or an object with a `handle` method.
27
+ */
6
28
  api: {
7
29
  handle: (request: Request) => Promise<Response>;
8
30
  } | any;
9
31
  }
32
+ /**
33
+ * Starts a production server using Bun.serve.
34
+ *
35
+ * This function serves the static frontend assets from the distribution directory
36
+ * and handles API requests using the provided Elysia app instance.
37
+ *
38
+ * @param options - Configuration options for the production server.
39
+ * @throws {Error} If not running in a Bun environment.
40
+ */
10
41
  declare const startServer: (options: ProductionOptions) => void;
11
42
 
12
- export { startServer };
43
+ export { type ProductionOptions, startServer };
@@ -1,3 +1,2 @@
1
- import {resolve,join}from'path';var f=t=>{let i=t.port||3e3,r=resolve(process.cwd(),t.distDir||"dist"),u=join(r,t.htmlFile||"index.html"),l=t.apiPrefix||"/api",c=t.api;if(typeof Bun>"u")throw new Error("This production server utility requires Bun.");Bun.serve({port:i,async fetch(n){let s=new URL(n.url);if(s.pathname.startsWith(l))return c.handle(n);let e=s.pathname;e==="/"&&(e="/index.html");let p=join(r,e.startsWith("/")?e.slice(1):e),o=Bun.file(p);return await o.exists()?new Response(o):n.method==="GET"?new Response(Bun.file(u)):new Response("Not Found",{status:404})}}),console.log(`Production server running at http://localhost:${i}`);};
2
- export{f as startServer};//# sourceMappingURL=production.js.map
3
- //# sourceMappingURL=production.js.map
1
+ import {resolve,join}from'path';var f=t=>{let n=t.port||3e3,r=resolve(process.cwd(),t.distDir||"dist"),u=join(r,t.htmlFile||"index.html"),l=t.apiPrefix||"/api",p=t.api;if(typeof Bun>"u")throw new Error("This production server utility requires Bun.");Bun.serve({port:n,async fetch(i){let s=new URL(i.url);if(s.pathname.startsWith(l))return p.handle(i);let e=s.pathname;e==="/"&&(e="/index.html");let c=join(r,e.startsWith("/")?e.slice(1):e),o=Bun.file(c);return await o.exists()?new Response(o):i.method==="GET"?new Response(Bun.file(u)):new Response("Not Found",{status:404})}}),console.log(`Production server running at http://localhost:${n}`);};
2
+ export{f as startServer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-elysia-forge",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A Vite plugin to seamlessly integrate ElysiaJS for full-stack development with Bun runtime.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -36,8 +36,7 @@
36
36
  },
37
37
  "./production": {
38
38
  "types": "./dist/production.d.ts",
39
- "import": "./dist/production.js",
40
- "require": "./dist/production.cjs"
39
+ "import": "./dist/production.js"
41
40
  }
42
41
  },
43
42
  "files": [
package/dist/cli.cjs DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env bun
2
- 'use strict';var child_process=require('child_process'),fs=require('fs'),path=require('path');async function g(o="src/server/api.ts"){let n=path.resolve(process.cwd(),o);fs.existsSync(n)||(console.error(`\u274C API entry file "${o}" not found.`),console.error(' By default, vite-elysia-forge looks for "src/server/api.ts".'),console.error(" If your API is located elsewhere, please specify the path:"),console.error(" $ vite-elysia-forge build <path-to-your-api-file>"),process.exit(1)),console.log("\u{1F4E6} Building Vite app...");let r=child_process.spawnSync("bun",["x","vite","build"],{stdio:"inherit",env:{...process.env,NODE_ENV:"production"}});r.status!==0&&(console.error("\u274C Vite build failed"),process.exit(r.status||1)),console.log("\u{1F95F} Building Elysia server for Bun...");let s=path.resolve(process.cwd(),".output");fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});let t=path.resolve(s,".temp-prod.ts"),e=path.relative(s,n);e=e.split(path.sep).join("/"),e.startsWith(".")||(e="./"+e);let u=`
3
- import { startServer } from "@chijioke-udokporo/vite-elysia-forge/production";
4
- import { api } from "${e}";
5
-
6
- startServer({
7
- api,
8
- port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
9
- distDir: "dist",
10
- });
11
- `;fs.writeFileSync(t,u);try{let i=await Bun.build({entrypoints:[t],outdir:"dist",target:"bun",minify:!0,naming:"server.js"});if(!i.success){console.error("\u274C Server build failed");for(let a of i.logs)console.error(a);process.exit(1);}}catch(i){console.error("\u274C Failed to build server. Ensure you are running this command with Bun."),console.error(i),process.exit(1);}finally{fs.existsSync(t)&&fs.unlinkSync(t);}console.log("\u2705 Build complete!"),console.log(" Run your production server with:"),console.log(" $ bun dist/server.js");}if(undefined){let o=process.argv.slice(2);if(o[0]==="build"){let r=o[1];g(r);}else console.log("Usage: vite-elysia-forge build [api-entry]"),console.log(" api-entry: Path to your API entry file (default: src/server/api.ts)");}exports.build=g;//# sourceMappingURL=cli.cjs.map
12
- //# sourceMappingURL=cli.cjs.map
package/dist/cli.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["build","apiEntry","absoluteApiEntry","resolve","existsSync","viteBuild","spawnSync","outputDir","mkdirSync","tempEntry","relativeApiEntry","relative","sep","tempContent","writeFileSync","result","log","e","unlinkSync","args","entry"],"mappings":"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","file":"cli.cjs","sourcesContent":["#!/usr/bin/env bun\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, writeFileSync, unlinkSync, mkdirSync } from \"node:fs\";\nimport { resolve, relative, sep } from \"node:path\";\n\nexport async function build(apiEntry: string = \"src/server/api.ts\") {\n const absoluteApiEntry = resolve(process.cwd(), apiEntry);\n\n if (!existsSync(absoluteApiEntry)) {\n console.error(`❌ API entry file \"${apiEntry}\" not found.`);\n console.error(` By default, vite-elysia-forge looks for \"src/server/api.ts\".`);\n console.error(` If your API is located elsewhere, please specify the path:`);\n console.error(` $ vite-elysia-forge build <path-to-your-api-file>`);\n process.exit(1);\n }\n\n console.log(\"📦 Building Vite app...\");\n // Run vite build\n const viteBuild = spawnSync(\"bun\", [\"x\", \"vite\", \"build\"], {\n stdio: \"inherit\",\n env: { ...process.env, NODE_ENV: \"production\" },\n });\n\n if (viteBuild.status !== 0) {\n console.error(\"❌ Vite build failed\");\n process.exit(viteBuild.status || 1);\n }\n\n console.log(\"🥟 Building Elysia server for Bun...\");\n\n // Create a temporary entry file\n const outputDir = resolve(process.cwd(), \".output\");\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n const tempEntry = resolve(outputDir, \".temp-prod.ts\");\n\n // Calculate relative path from outputDir to api entry\n let relativeApiEntry = relative(outputDir, absoluteApiEntry);\n // Normalize path separators for imports (Windows support)\n relativeApiEntry = relativeApiEntry.split(sep).join(\"/\");\n if (!relativeApiEntry.startsWith(\".\")) {\n relativeApiEntry = \"./\" + relativeApiEntry;\n }\n\n const tempContent = `\nimport { startServer } from \"@chijioke-udokporo/vite-elysia-forge/production\";\nimport { api } from \"${relativeApiEntry}\";\n\nstartServer({\n api,\n port: process.env.PORT ? parseInt(process.env.PORT) : 3000,\n distDir: \"dist\",\n});\n`;\n\n writeFileSync(tempEntry, tempContent);\n\n // We use Bun.build to bundle the server\n // This requires the script to be run with Bun\n try {\n const result = await Bun.build({\n entrypoints: [tempEntry],\n outdir: \"dist\", // Output to dist alongside vite assets\n target: \"bun\",\n minify: true,\n naming: \"server.js\", // Fixed name for simplicity\n });\n\n if (!result.success) {\n console.error(\"❌ Server build failed\");\n for (const log of result.logs) {\n console.error(log);\n }\n process.exit(1);\n }\n } catch (e) {\n console.error(\"❌ Failed to build server. Ensure you are running this command with Bun.\");\n console.error(e);\n process.exit(1);\n } finally {\n // Clean up temp file\n if (existsSync(tempEntry)) {\n unlinkSync(tempEntry);\n }\n }\n\n console.log(\"✅ Build complete!\");\n console.log(\" Run your production server with:\");\n console.log(\" $ bun dist/server.js\");\n}\n\nif (import.meta.main) {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === \"build\") {\n const entry = args[1];\n build(entry);\n } else {\n console.log(\"Usage: vite-elysia-forge build [api-entry]\");\n console.log(\" api-entry: Path to your API entry file (default: src/server/api.ts)\");\n }\n}\n"]}
package/dist/cli.d.cts DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env bun
2
- declare function build(apiEntry?: string): Promise<void>;
3
-
4
- export { build };
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["build","apiEntry","absoluteApiEntry","resolve","existsSync","viteBuild","spawnSync","outputDir","mkdirSync","tempEntry","relativeApiEntry","relative","sep","tempContent","writeFileSync","result","log","e","unlinkSync","args","entry"],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env bun\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, writeFileSync, unlinkSync, mkdirSync } from \"node:fs\";\nimport { resolve, relative, sep } from \"node:path\";\n\nexport async function build(apiEntry: string = \"src/server/api.ts\") {\n const absoluteApiEntry = resolve(process.cwd(), apiEntry);\n\n if (!existsSync(absoluteApiEntry)) {\n console.error(`❌ API entry file \"${apiEntry}\" not found.`);\n console.error(` By default, vite-elysia-forge looks for \"src/server/api.ts\".`);\n console.error(` If your API is located elsewhere, please specify the path:`);\n console.error(` $ vite-elysia-forge build <path-to-your-api-file>`);\n process.exit(1);\n }\n\n console.log(\"📦 Building Vite app...\");\n // Run vite build\n const viteBuild = spawnSync(\"bun\", [\"x\", \"vite\", \"build\"], {\n stdio: \"inherit\",\n env: { ...process.env, NODE_ENV: \"production\" },\n });\n\n if (viteBuild.status !== 0) {\n console.error(\"❌ Vite build failed\");\n process.exit(viteBuild.status || 1);\n }\n\n console.log(\"🥟 Building Elysia server for Bun...\");\n\n // Create a temporary entry file\n const outputDir = resolve(process.cwd(), \".output\");\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n const tempEntry = resolve(outputDir, \".temp-prod.ts\");\n\n // Calculate relative path from outputDir to api entry\n let relativeApiEntry = relative(outputDir, absoluteApiEntry);\n // Normalize path separators for imports (Windows support)\n relativeApiEntry = relativeApiEntry.split(sep).join(\"/\");\n if (!relativeApiEntry.startsWith(\".\")) {\n relativeApiEntry = \"./\" + relativeApiEntry;\n }\n\n const tempContent = `\nimport { startServer } from \"@chijioke-udokporo/vite-elysia-forge/production\";\nimport { api } from \"${relativeApiEntry}\";\n\nstartServer({\n api,\n port: process.env.PORT ? parseInt(process.env.PORT) : 3000,\n distDir: \"dist\",\n});\n`;\n\n writeFileSync(tempEntry, tempContent);\n\n // We use Bun.build to bundle the server\n // This requires the script to be run with Bun\n try {\n const result = await Bun.build({\n entrypoints: [tempEntry],\n outdir: \"dist\", // Output to dist alongside vite assets\n target: \"bun\",\n minify: true,\n naming: \"server.js\", // Fixed name for simplicity\n });\n\n if (!result.success) {\n console.error(\"❌ Server build failed\");\n for (const log of result.logs) {\n console.error(log);\n }\n process.exit(1);\n }\n } catch (e) {\n console.error(\"❌ Failed to build server. Ensure you are running this command with Bun.\");\n console.error(e);\n process.exit(1);\n } finally {\n // Clean up temp file\n if (existsSync(tempEntry)) {\n unlinkSync(tempEntry);\n }\n }\n\n console.log(\"✅ Build complete!\");\n console.log(\" Run your production server with:\");\n console.log(\" $ bun dist/server.js\");\n}\n\nif (import.meta.main) {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === \"build\") {\n const entry = args[1];\n build(entry);\n } else {\n console.log(\"Usage: vite-elysia-forge build [api-entry]\");\n console.log(\" api-entry: Path to your API entry file (default: src/server/api.ts)\");\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["isProduction","logger","Pino","elysiaPlugin","serverFile","server","apiModulePath","apiFile","resolve","loadApi","api","file","entryMod","changedMods","isDependency","seen","queue","node","importer","error","req","res","next","protocol","host","url","body","chunks","chunk","request","response","value","key","responseBody","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import { resolve } from \"node:path\";\nimport Pino from \"pino\";\nimport type { Plugin, ModuleNode } from \"vite\";\n\nconst isProduction = process.env.NODE_ENV === \"production\";\n\nconst logger = Pino({\n name: \"vite-elysia-forge\",\n transport: isProduction\n ? undefined\n : {\n target: \"pino-pretty\",\n options: { colorize: true },\n },\n});\n\ninterface ConfigOptions {\n /**\n * The URL path to the server API module.\n * @default \"/server/api.ts\"\n */\n\n serverFile?: string;\n}\n\nfunction elysiaPlugin({ serverFile = \"/server/api.ts\" }: ConfigOptions): Plugin {\n return {\n name: \"vite-elysia-forge\",\n async configureServer(server) {\n const apiModulePath = serverFile;\n const apiFile = resolve(server.config.root, apiModulePath.slice(1));\n\n const loadApi = async () => {\n const mod = await server.ssrLoadModule(apiModulePath);\n return mod.api as { handle: (request: Request) => Promise<Response> };\n };\n\n let api = await loadApi();\n\n server.watcher.add(apiFile);\n server.watcher.on(\"change\", async (file) => {\n const entryMod = await server.moduleGraph.getModuleByUrl(apiModulePath);\n if (!entryMod) return;\n\n const changedMods = server.moduleGraph.getModulesByFile(file);\n if (!changedMods || changedMods.size === 0) return;\n\n let isDependency = false;\n const seen = new Set<string>();\n const queue = [...changedMods];\n\n while (queue.length > 0) {\n const node = queue.shift();\n if (!node || !node.id || seen.has(node.id)) continue;\n seen.add(node.id);\n\n if (node.id === entryMod.id) {\n isDependency = true;\n break;\n }\n\n for (const importer of node.importers) {\n queue.push(importer);\n }\n }\n\n if (!isDependency) return;\n\n try {\n server.moduleGraph.invalidateModule(entryMod);\n api = await loadApi();\n logger.info(\"Reloaded Elysia API module\");\n } catch (error) {\n logger.error(`Failed to reload Elysia API: ${error}`);\n }\n });\n\n server.middlewares.use(async (req, res, next) => {\n // Only handle /api routes\n if (!req.url?.startsWith(\"/api\")) {\n return next();\n }\n\n try {\n // Build the full URL\n const protocol = \"http\";\n const host = req.headers.host || \"localhost:3000\";\n const url = `${protocol}://${host}${req.url}`;\n\n // Collect body for non-GET requests\n let body: string | undefined;\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk);\n }\n body = Buffer.concat(chunks).toString();\n }\n\n // Create a Request object for Elysia\n const request = new Request(url, {\n method: req.method,\n headers: req.headers as Record<string, string>,\n body: body,\n });\n\n // Handle with Elysia\n const response = await api.handle(request);\n\n // Send response\n res.statusCode = response.status;\n response.headers.forEach((value: string, key: string) => {\n res.setHeader(key, value);\n });\n\n const responseBody = await response.text();\n res.end(responseBody);\n } catch (error) {\n logger.error(`Elysia error: ${error}`);\n res.statusCode = 500;\n res.end(\"Internal Server Error\");\n }\n });\n },\n };\n}\n\nexport default elysiaPlugin;\n"]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["isProduction","logger","Pino","elysiaPlugin","serverFile","server","apiModulePath","apiFile","resolve","loadApi","api","file","entryMod","changedMods","isDependency","seen","queue","node","importer","error","req","res","next","protocol","host","url","body","chunks","chunk","request","response","value","key","responseBody","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import { resolve } from \"node:path\";\nimport Pino from \"pino\";\nimport type { Plugin, ModuleNode } from \"vite\";\n\nconst isProduction = process.env.NODE_ENV === \"production\";\n\nconst logger = Pino({\n name: \"vite-elysia-forge\",\n transport: isProduction\n ? undefined\n : {\n target: \"pino-pretty\",\n options: { colorize: true },\n },\n});\n\ninterface ConfigOptions {\n /**\n * The URL path to the server API module.\n * @default \"/server/api.ts\"\n */\n\n serverFile?: string;\n}\n\nfunction elysiaPlugin({ serverFile = \"/server/api.ts\" }: ConfigOptions): Plugin {\n return {\n name: \"vite-elysia-forge\",\n async configureServer(server) {\n const apiModulePath = serverFile;\n const apiFile = resolve(server.config.root, apiModulePath.slice(1));\n\n const loadApi = async () => {\n const mod = await server.ssrLoadModule(apiModulePath);\n return mod.api as { handle: (request: Request) => Promise<Response> };\n };\n\n let api = await loadApi();\n\n server.watcher.add(apiFile);\n server.watcher.on(\"change\", async (file) => {\n const entryMod = await server.moduleGraph.getModuleByUrl(apiModulePath);\n if (!entryMod) return;\n\n const changedMods = server.moduleGraph.getModulesByFile(file);\n if (!changedMods || changedMods.size === 0) return;\n\n let isDependency = false;\n const seen = new Set<string>();\n const queue = [...changedMods];\n\n while (queue.length > 0) {\n const node = queue.shift();\n if (!node || !node.id || seen.has(node.id)) continue;\n seen.add(node.id);\n\n if (node.id === entryMod.id) {\n isDependency = true;\n break;\n }\n\n for (const importer of node.importers) {\n queue.push(importer);\n }\n }\n\n if (!isDependency) return;\n\n try {\n server.moduleGraph.invalidateModule(entryMod);\n api = await loadApi();\n logger.info(\"Reloaded Elysia API module\");\n } catch (error) {\n logger.error(`Failed to reload Elysia API: ${error}`);\n }\n });\n\n server.middlewares.use(async (req, res, next) => {\n // Only handle /api routes\n if (!req.url?.startsWith(\"/api\")) {\n return next();\n }\n\n try {\n // Build the full URL\n const protocol = \"http\";\n const host = req.headers.host || \"localhost:3000\";\n const url = `${protocol}://${host}${req.url}`;\n\n // Collect body for non-GET requests\n let body: string | undefined;\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk);\n }\n body = Buffer.concat(chunks).toString();\n }\n\n // Create a Request object for Elysia\n const request = new Request(url, {\n method: req.method,\n headers: req.headers as Record<string, string>,\n body: body,\n });\n\n // Handle with Elysia\n const response = await api.handle(request);\n\n // Send response\n res.statusCode = response.status;\n response.headers.forEach((value: string, key: string) => {\n res.setHeader(key, value);\n });\n\n const responseBody = await response.text();\n res.end(responseBody);\n } catch (error) {\n logger.error(`Elysia error: ${error}`);\n res.statusCode = 500;\n res.end(\"Internal Server Error\");\n }\n });\n },\n };\n}\n\nexport default elysiaPlugin;\n"]}
@@ -1,3 +0,0 @@
1
- 'use strict';var path=require('path');var f=t=>{let i=t.port||3e3,r=path.resolve(process.cwd(),t.distDir||"dist"),u=path.join(r,t.htmlFile||"index.html"),l=t.apiPrefix||"/api",c=t.api;if(typeof Bun>"u")throw new Error("This production server utility requires Bun.");Bun.serve({port:i,async fetch(n){let s=new URL(n.url);if(s.pathname.startsWith(l))return c.handle(n);let e=s.pathname;e==="/"&&(e="/index.html");let p=path.join(r,e.startsWith("/")?e.slice(1):e),o=Bun.file(p);return await o.exists()?new Response(o):n.method==="GET"?new Response(Bun.file(u)):new Response("Not Found",{status:404})}}),console.log(`Production server running at http://localhost:${i}`);};
2
- exports.startServer=f;//# sourceMappingURL=production.cjs.map
3
- //# sourceMappingURL=production.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/production.ts"],"names":["startServer","options","port","dist","resolve","indexHtml","join","apiPrefix","api","req","url","path","filePath","file"],"mappings":"sCAUO,IAAMA,CAAAA,CAAeC,CAAAA,EAA+B,CACzD,IAAMC,CAAAA,CAAOD,CAAAA,CAAQ,MAAQ,GAAA,CACvBE,CAAAA,CAAOC,YAAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,CAAGH,CAAAA,CAAQ,OAAA,EAAW,MAAM,CAAA,CACvDI,CAAAA,CAAYC,SAAAA,CAAKH,CAAAA,CAAMF,CAAAA,CAAQ,QAAA,EAAY,YAAY,EACvDM,CAAAA,CAAYN,CAAAA,CAAQ,SAAA,EAAa,MAAA,CACjCO,CAAAA,CAAMP,CAAAA,CAAQ,GAAA,CAEpB,GAAI,OAAO,GAAA,CAAQ,GAAA,CACjB,MAAM,IAAI,KAAA,CAAM,8CAA8C,CAAA,CAGhE,IAAI,KAAA,CAAM,CACR,IAAA,CAAAC,CAAAA,CACA,MAAM,KAAA,CAAMO,CAAAA,CAAK,CACf,IAAMC,CAAAA,CAAM,IAAI,GAAA,CAAID,CAAAA,CAAI,GAAG,CAAA,CAG3B,GAAIC,CAAAA,CAAI,SAAS,UAAA,CAAWH,CAAS,CAAA,CACnC,OAAOC,CAAAA,CAAI,MAAA,CAAOC,CAAG,CAAA,CAIvB,IAAIE,CAAAA,CAAOD,CAAAA,CAAI,QAAA,CACXC,CAAAA,GAAS,GAAA,GAAKA,CAAAA,CAAO,aAAA,CAAA,CAEzB,IAAMC,CAAAA,CAAWN,SAAAA,CAAKH,CAAAA,CAAMQ,CAAAA,CAAK,UAAA,CAAW,GAAG,CAAA,CAAIA,CAAAA,CAAK,MAAM,CAAC,CAAA,CAAIA,CAAI,CAAA,CACjEE,CAAAA,CAAO,GAAA,CAAI,IAAA,CAAKD,CAAQ,EAE9B,OAAI,MAAMC,CAAAA,CAAK,MAAA,EAAO,CACb,IAAI,QAAA,CAASA,CAAI,CAAA,CAItBJ,CAAAA,CAAI,MAAA,GAAW,KAAA,CACV,IAAI,QAAA,CAAS,GAAA,CAAI,IAAA,CAAKJ,CAAS,CAAC,CAAA,CAGlC,IAAI,QAAA,CAAS,WAAA,CAAa,CAAE,MAAA,CAAQ,GAAI,CAAC,CAClD,CACF,CAAC,CAAA,CAED,OAAA,CAAQ,GAAA,CAAI,CAAA,8CAAA,EAAiDH,CAAI,EAAE,EACrE","file":"production.cjs","sourcesContent":["import { resolve, join } from \"node:path\";\n\ninterface ProductionOptions {\n port?: number;\n distDir?: string;\n htmlFile?: string;\n apiPrefix?: string;\n api: { handle: (request: Request) => Promise<Response> } | any;\n}\n\nexport const startServer = (options: ProductionOptions) => {\n const port = options.port || 3000;\n const dist = resolve(process.cwd(), options.distDir || \"dist\");\n const indexHtml = join(dist, options.htmlFile || \"index.html\");\n const apiPrefix = options.apiPrefix || \"/api\";\n const api = options.api;\n\n if (typeof Bun === \"undefined\") {\n throw new Error(\"This production server utility requires Bun.\");\n }\n\n Bun.serve({\n port,\n async fetch(req) {\n const url = new URL(req.url);\n\n // 1. Handle API requests\n if (url.pathname.startsWith(apiPrefix)) {\n return api.handle(req);\n }\n\n // 2. Serve static files\n let path = url.pathname;\n if (path === \"/\") path = \"/index.html\";\n\n const filePath = join(dist, path.startsWith(\"/\") ? path.slice(1) : path);\n const file = Bun.file(filePath);\n\n if (await file.exists()) {\n return new Response(file);\n }\n\n // 3. SPA Fallback\n if (req.method === \"GET\") {\n return new Response(Bun.file(indexHtml));\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n });\n\n console.log(`Production server running at http://localhost:${port}`);\n};\n"]}
@@ -1,12 +0,0 @@
1
- interface ProductionOptions {
2
- port?: number;
3
- distDir?: string;
4
- htmlFile?: string;
5
- apiPrefix?: string;
6
- api: {
7
- handle: (request: Request) => Promise<Response>;
8
- } | any;
9
- }
10
- declare const startServer: (options: ProductionOptions) => void;
11
-
12
- export { startServer };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/production.ts"],"names":["startServer","options","port","dist","resolve","indexHtml","join","apiPrefix","api","req","url","path","filePath","file"],"mappings":"gCAUO,IAAMA,CAAAA,CAAeC,CAAAA,EAA+B,CACzD,IAAMC,CAAAA,CAAOD,CAAAA,CAAQ,MAAQ,GAAA,CACvBE,CAAAA,CAAOC,OAAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,CAAGH,CAAAA,CAAQ,OAAA,EAAW,MAAM,CAAA,CACvDI,CAAAA,CAAYC,IAAAA,CAAKH,CAAAA,CAAMF,CAAAA,CAAQ,QAAA,EAAY,YAAY,EACvDM,CAAAA,CAAYN,CAAAA,CAAQ,SAAA,EAAa,MAAA,CACjCO,CAAAA,CAAMP,CAAAA,CAAQ,GAAA,CAEpB,GAAI,OAAO,GAAA,CAAQ,GAAA,CACjB,MAAM,IAAI,KAAA,CAAM,8CAA8C,CAAA,CAGhE,IAAI,KAAA,CAAM,CACR,IAAA,CAAAC,CAAAA,CACA,MAAM,KAAA,CAAMO,CAAAA,CAAK,CACf,IAAMC,CAAAA,CAAM,IAAI,GAAA,CAAID,CAAAA,CAAI,GAAG,CAAA,CAG3B,GAAIC,CAAAA,CAAI,SAAS,UAAA,CAAWH,CAAS,CAAA,CACnC,OAAOC,CAAAA,CAAI,MAAA,CAAOC,CAAG,CAAA,CAIvB,IAAIE,CAAAA,CAAOD,CAAAA,CAAI,QAAA,CACXC,CAAAA,GAAS,GAAA,GAAKA,CAAAA,CAAO,aAAA,CAAA,CAEzB,IAAMC,CAAAA,CAAWN,IAAAA,CAAKH,CAAAA,CAAMQ,CAAAA,CAAK,UAAA,CAAW,GAAG,CAAA,CAAIA,CAAAA,CAAK,MAAM,CAAC,CAAA,CAAIA,CAAI,CAAA,CACjEE,CAAAA,CAAO,GAAA,CAAI,IAAA,CAAKD,CAAQ,EAE9B,OAAI,MAAMC,CAAAA,CAAK,MAAA,EAAO,CACb,IAAI,QAAA,CAASA,CAAI,CAAA,CAItBJ,CAAAA,CAAI,MAAA,GAAW,KAAA,CACV,IAAI,QAAA,CAAS,GAAA,CAAI,IAAA,CAAKJ,CAAS,CAAC,CAAA,CAGlC,IAAI,QAAA,CAAS,WAAA,CAAa,CAAE,MAAA,CAAQ,GAAI,CAAC,CAClD,CACF,CAAC,CAAA,CAED,OAAA,CAAQ,GAAA,CAAI,CAAA,8CAAA,EAAiDH,CAAI,EAAE,EACrE","file":"production.js","sourcesContent":["import { resolve, join } from \"node:path\";\n\ninterface ProductionOptions {\n port?: number;\n distDir?: string;\n htmlFile?: string;\n apiPrefix?: string;\n api: { handle: (request: Request) => Promise<Response> } | any;\n}\n\nexport const startServer = (options: ProductionOptions) => {\n const port = options.port || 3000;\n const dist = resolve(process.cwd(), options.distDir || \"dist\");\n const indexHtml = join(dist, options.htmlFile || \"index.html\");\n const apiPrefix = options.apiPrefix || \"/api\";\n const api = options.api;\n\n if (typeof Bun === \"undefined\") {\n throw new Error(\"This production server utility requires Bun.\");\n }\n\n Bun.serve({\n port,\n async fetch(req) {\n const url = new URL(req.url);\n\n // 1. Handle API requests\n if (url.pathname.startsWith(apiPrefix)) {\n return api.handle(req);\n }\n\n // 2. Serve static files\n let path = url.pathname;\n if (path === \"/\") path = \"/index.html\";\n\n const filePath = join(dist, path.startsWith(\"/\") ? path.slice(1) : path);\n const file = Bun.file(filePath);\n\n if (await file.exists()) {\n return new Response(file);\n }\n\n // 3. SPA Fallback\n if (req.method === \"GET\") {\n return new Response(Bun.file(indexHtml));\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n });\n\n console.log(`Production server running at http://localhost:${port}`);\n};\n"]}