@kosmojs/dev 0.2.7 → 0.2.9

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@kosmojs/dev",
4
- "version": "0.2.7",
4
+ "version": "0.2.9",
5
5
  "cacheVersion": "001",
6
6
  "author": "Slee Woo",
7
7
  "license": "MIT",
@@ -31,27 +31,28 @@
31
31
  "@vitejs/plugin-vue": "^6.0.8",
32
32
  "crc": "^4.3.2",
33
33
  "path-to-regexp": "^8.4.2",
34
- "typebox": "^1.3.8",
34
+ "semver": "^7.8.5",
35
+ "typebox": "^1.3.10",
35
36
  "vite": "^8.2.0",
36
37
  "vite-plugin-solid": "^2.11.14",
37
38
  "yaml": "^2.9.0",
38
- "@kosmojs/lib": "^0.2.7",
39
- "@kosmojs/core": "^0.2.7"
39
+ "@kosmojs/core": "^0.2.9",
40
+ "@kosmojs/lib": "^0.2.9"
40
41
  },
41
42
  "devDependencies": {
42
- "@kosmojs/core-generator": "^0.2.7",
43
- "@kosmojs/fetch-generator": "^0.2.7",
44
- "@kosmojs/koa-generator": "^0.2.7",
45
- "@kosmojs/mdx-generator": "^0.2.7",
46
- "@kosmojs/solid-generator": "^0.2.7",
47
- "@kosmojs/ssg-generator": "^0.2.7",
48
- "@kosmojs/svelte-generator": "^0.2.7",
49
- "@kosmojs/hono-generator": "^0.2.7",
50
- "@kosmojs/typebox-generator": "^0.2.7",
51
- "@kosmojs/ssr-generator": "^0.2.7",
52
- "@kosmojs/vue-generator": "^0.2.7",
53
- "@kosmojs/react-generator": "^0.2.7",
54
- "@kosmojs/openapi-generator": "^0.2.7"
43
+ "@kosmojs/core-generator": "^0.2.9",
44
+ "@kosmojs/fetch-generator": "^0.2.9",
45
+ "@kosmojs/hono-generator": "^0.2.9",
46
+ "@kosmojs/koa-generator": "^0.2.9",
47
+ "@kosmojs/mdx-generator": "^0.2.9",
48
+ "@kosmojs/openapi-generator": "^0.2.9",
49
+ "@kosmojs/react-generator": "^0.2.9",
50
+ "@kosmojs/solid-generator": "^0.2.9",
51
+ "@kosmojs/ssg-generator": "^0.2.9",
52
+ "@kosmojs/ssr-generator": "^0.2.9",
53
+ "@kosmojs/svelte-generator": "^0.2.9",
54
+ "@kosmojs/vue-generator": "^0.2.9",
55
+ "@kosmojs/typebox-generator": "^0.2.9"
55
56
  },
56
57
  "scripts": {
57
58
  "build": "wsbuild src/index.ts src/chassis.ts"
package/pkg/chassis.js CHANGED
@@ -1,8 +1,8 @@
1
- import{createRequire as e}from"node:module";import{dirname as t,join as n,resolve as r}from"node:path";import{styleText as i}from"node:util";import{defaults as a}from"@kosmojs/core";import{defineGenerator as o,defineGeneratorFactory as s,mergeConfigs as c,pathExists as l,pathResolver as u,renderFactory as d,renderToFile as f,routesFactory as p,spinnerFactory as m,vitePlugins as h}from"@kosmojs/lib";import{routeRenderHelpers as g}from"@kosmojs/core/generators";import _ from"crc/crc32";import{build as v,createServer as y}from"vite";import{mkdir as b,readFile as x,writeFile as S}from"node:fs/promises";import C from"node:http";import w from"node:net";import{readFileSync as T}from"node:fs";var E={type:`module`,private:!0,name:`@kosmojs/core-generator`,version:`0.2.7`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`},devDependencies:{"path-to-regexp":`^8.4.2`}},D=`export const base = "{{config.base}}";
1
+ import{createRequire as e}from"node:module";import{dirname as t,join as n,resolve as r}from"node:path";import{styleText as i}from"node:util";import{defaults as a}from"@kosmojs/core";import{defineGenerator as o,defineGeneratorFactory as s,mergeConfigs as c,pathExists as l,pathResolver as u,renderFactory as d,renderToFile as f,routesFactory as p,spinnerFactory as m,vitePlugins as h}from"@kosmojs/lib";import{routeRenderHelpers as g}from"@kosmojs/core/generators";import _ from"crc/crc32";import{build as v,createServer as y}from"vite";import{mkdir as b,readFile as x,writeFile as S}from"node:fs/promises";import C from"node:http";import w from"node:net";import T from"semver";import{readFileSync as E}from"node:fs";var D={type:`module`,private:!0,name:`@kosmojs/core-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,semver:`^7.8.5`},devDependencies:{"@types/semver":`^7.8.0`,"path-to-regexp":`^8.4.2`}},O=`export const base = "{{config.base}}";
2
2
  export const apiBase = "{{config.apiBase}}";
3
- `,O=`export * from "./config";
3
+ `,k=`export * from "./config";
4
4
  export * from "./routeMap";
5
- `,k=`import { compile } from "path-to-regexp";
5
+ `,A=`import { compile } from "path-to-regexp";
6
6
 
7
7
  import type { PathMapperSignature } from "@kosmojs/core";
8
8
  import { createHost, join, stringify } from "@kosmojs/core/fetch";
@@ -69,7 +69,7 @@ export const pathMapper = <ParamsT extends readonly unknown[]>(
69
69
  href,
70
70
  };
71
71
  };
72
- `,A=`{{> pathMapper}}
72
+ `,j=`{{> pathMapper}}
73
73
 
74
74
  import { base, apiBase } from "./config";
75
75
 
@@ -105,8 +105,7 @@ export const pageRouteMap = {
105
105
  ),
106
106
  {{/each}}
107
107
  };
108
- `,j=`declare const KOSMO_PRODUCTION_BUILD: boolean;
109
- declare const KOSMO_SERVERSIDE_FETCH: boolean;
108
+ `,M=`declare const KOSMO_PRODUCTION_BUILD: boolean;
110
109
 
111
110
  /**
112
111
  * Enhances base TypeScript types with JSON Schema validation constraints.
@@ -304,7 +303,7 @@ interface TStringOptions {
304
303
  */
305
304
  pattern?: string | RegExp;
306
305
  }
307
- `,M=`# Ignore all files
306
+ `,N=`# Ignore all files
308
307
  *
309
308
 
310
309
  # But don't ignore directories (so Git can traverse them)
@@ -313,15 +312,15 @@ interface TStringOptions {
313
312
  # And don't ignore these files at any depth
314
313
  !cache.json
315
314
  !types.ts
316
- `,N=`export declare global {
315
+ `,P=`export declare global {
317
316
  interface Window {
318
317
  __KOSMO_HYDRATION_BOOL__: boolean;
319
318
  __KOSMO_HYDRATION_DATA__: Record<string, unknown> | undefined;
320
319
  }
321
320
  }
322
- `,P=`// stub schemas, specialized generators supposed to overwrite this file
321
+ `,F=`// stub schemas, specialized generators supposed to overwrite this file
323
322
  import type { ValidationSchemas } from "@kosmojs/core/api";
324
323
  export type { ValidationSchemas };
325
324
  export const validationSchemas: ValidationSchemas = {};
326
- `,F=e=>{let t="${configDir}",n={types:[`@types/node`,`vite/client`],moduleResolution:`bundler`,module:`ESNext`,target:`ESNext`,strict:!0,exactOptionalPropertyTypes:!0,noImplicitAny:!0,noImplicitThis:!0,noImplicitOverride:!0,noImplicitReturns:!0,noUnusedLocals:!1,noUnusedParameters:!1,allowArbitraryExtensions:!0,allowImportingTsExtensions:!0,allowUnreachableCode:!1,allowUnusedLabels:!1,useUnknownInCatchVariables:!0,noFallthroughCasesInSwitch:!0,noUncheckedSideEffectImports:!0,resolveJsonModule:!0,esModuleInterop:!0,verbatimModuleSyntax:!0,skipLibCheck:!0,noEmit:!0};return e?{include:[`${t}/`,`${t}/../../${a.libDir}/${e}/`,`${t}/../../**/*.d.ts`],compilerOptions:{...n,types:[...n.types],paths:{[`${a.appPrefix}/*`]:[`${t}/../../*`],[`${a.srcPrefix}/*`]:[`${t}/*`],[`${a.libPrefix}/*`]:[`${t}/../../${a.libDir}/${e}/*`]}}}:{include:[`${t}/`],exclude:[`${t}/${a.srcDir}/`],compilerOptions:{...n,paths:{[`${a.appPrefix}/*`]:[`${t}/*`]}}}},I=s((e,n)=>{let{createPath:r,createImportHelpers:i}=u(n),a=async()=>{await f(r.lib(`../tsconfig.json`),JSON.stringify(F(),void 0,2),{});{let e=F(n.name),t={},i=new Set(e.compilerOptions.types||[]);for(let{meta:e}of n.config.generators||[]){e.jsx&&(t.jsx=e.jsx),e.jsxImportSource&&(t.jsxImportSource=e.jsxImportSource);for(let t of e.types||[])i.add(t)}await f(r.lib(`tsconfig.json`),JSON.stringify({...e,compilerOptions:{...e.compilerOptions,...t,types:[...i.values()]}},void 0,2),{})}for(let[e,t]of[[`env.d.ts`,j],[`global.d.ts`,N]])await f(r.lib(`../${e}`),t,{});await f(r.lib(`../.gitignore`),M,{},{overwrite:!1}),await f(r.lib(`ssg.ts`),`export default [];`,{})},o=async e=>{let{renderToFile:a}=d({helpers:{...i({origin:`lib`}),...g()},partials:{pathMapper:k}});await a(r.libCore(`routeMap.ts`),A,{apiRoutes:e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),pageRoutes:e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[])});for(let[e,t]of[[`config.ts`,D],[`index.ts`,O]])await a(r.libCore(e),t,n);for(let{kind:n,entry:i}of e)n===`apiRoute`&&await a(r.libApi(t(i.file),`schemas.ts`),P,{route:i},{overwrite:!1})};return{meta:e,start:a,watch:o,build:o}}),L=o(()=>{let e={name:`Core`,dependencies:{"path-to-regexp":E.devDependencies[`path-to-regexp`]}};return{meta:e,options:void 0,factory:t=>I(e,t)}}),R=JSON.parse(T(e(import.meta.url).resolve(`@kosmojs/dev/package.json`),`utf-8`)),z=(e,n,i)=>{let a=u(n).createPath.libApi(t(e.file),`cache.json`),o=async t=>{if(!t?.hash||!t.typeDeclarations||!t.referencedFiles)return;let a=await B(e.fileFullpath,{...i});if(V(t.hash,a)){for(let[e,i]of Object.entries(t.referencedFiles))if(!V(i,await B(r(n.root,e))))return;return t}};return{async get(e){if(await l(a))try{let t=JSON.parse(await x(a,`utf8`));return e?.validate?o(t):t}catch{}},async set(r){let o=await B(e.fileFullpath,{...i}),s={};for(let e of r.referencedFiles)s[e.replace(`${n.root}/`,``)]=await B(e);let c={...r,hash:o,referencedFiles:s};return await b(t(a),{recursive:!0}),await S(a,JSON.stringify(c,null,2),`utf8`),c}}},B=async(e,t)=>{let n;try{n=await x(e,`utf8`)}catch{return 0}return n?_(JSON.stringify({...t,[R.cacheVersion]:n})):0},V=(e,t)=>e===t,H=async e=>{let{devPort:t,command:r}=e;for(let t of e.sourceFolders)for(let e of W(t)){if(!e.meta?.name||typeof e.factory!=`function`)throw Error(`${t.name}: Unrecognized generator - must be created via defineGenerator()`);let n=e.factory(t);if(!n.meta?.name)throw Error(`${t.name}: ${e.meta.name} generator is missing meta property`);try{await n.start?.()}catch(n){throw console.error(i(`red`,`${t.name}: ${e.meta.name} generator failed to initialize`)),n}}if(r===`build`){for(let t of e.sourceFolders){let{createPath:e}=u(t),n=[];{let{resolvers:e}=await p(t,z),r=m(`${t.name}: resolving routes`);for(let{name:t,handler:i}of e.values())r.append(`[ ${n.length+1} of ${e.size} ] ${t}`),n.push(await i());r.succeed(`ready ✨`)}let i=W(t);for(let e of i)await e.factory(t).build?.(n);let a=[h.tsconfigPaths(t),h.nodePrefix()];await v(c(t.config,...i.map(({factory:e})=>e(t).config?.({kind:`client`,command:r})),{root:e.src(),cacheDir:U(t,r,`client`),plugins:a,build:{outDir:e.distDir(`client`),manifest:!0,emptyOutDir:!0}}));let o=i.find(e=>e.meta.slot===`api`);if(o){let n=e.distDir(`api`);await v(c(o.options,o.factory(t).config?.({kind:`backend`,command:r}),{base:`./`,root:e.src(),appType:`custom`,plugins:a,resolve:{conditions:[`node`]},build:{ssr:!0,target:`esnext`,sourcemap:!0,emptyOutDir:!0,rolldownOptions:{input:[e.api(`app.ts`),e.api(`server.ts`)],output:{dir:n,format:`esm`}}},cacheDir:U(t,r,`backend`)}))}for(let e of i)await e.factory(t).postBuild?.(n)}return async()=>{}}let o=[],s=[],l={};for(let t of e.sourceFolders)l[t.name]=await G(t);let d=await q(t);for(let t of e.sourceFolders){let{createPath:e}=u(t),i=K(t),f=W(t),p=[h.tsconfigPaths(t),h.nodePrefix()];{let n=await y(c(t.config,...f.map(({factory:e})=>e(t).config?.({kind:`client`,command:r})),{root:e.src(),cacheDir:U(t,r,`client`),plugins:p,server:{port:d++,middlewareMode:!0,hmr:{port:d++}}}));for(let[e,r]of Object.entries(l[t.name]))n.watcher.on(e,r);o.push([[t.config.base],()=>i.base,()=>n.middlewares]),s.push(n.close)}let m=f.find(e=>e.meta.slot===`api`);if(m){let u=await y(c(m.options,m.factory(t).config?.({kind:`backend`,command:r}),{root:e.src(),appType:`custom`,cacheDir:U(t,r,`backend`),plugins:p,server:{port:d++,middlewareMode:!0,hmr:{port:d++}},resolve:{conditions:[`node`]},environments:{api:{resolve:{conditions:[`node`]}}}})),f=u.environments.api,h=async()=>(f.runner.clearCache(),f.runner.import(n(a.apiDir,`dev.ts`)).then(e=>e.default)),g=await h();for(let[e,n]of Object.entries(l[t.name]))u.watcher.on(e,async e=>{f.moduleGraph.getModulesByFile(e)?.size&&(await n(e),await g?.teardownHandler?.(),g=await h())});o.push([[t.config.base,t.config.apiBase],()=>g.requestMatcher||i.api,()=>g.requestHandler()]),s.push(u.close)}}let f=([e])=>{let[t,n]=e,r=t.split(`/`).filter(Boolean).length;return n?r+5:r},g=o.sort((e,t)=>f(t)-f(e)),_=C.createServer((e,t)=>{for(let[,n,r]of g){let[i,a]=[n(),r()];if(i(e)){a(e,t);return}}t.writeHead(404,{"Content-Type":`text/html`}),t.end(`<h1>404: Not Found</h1>`)});return _.on(`error`,e=>{console.error(i(`red`,`Failed to start dev server on port ${t}`)),console.error(e.message),process.exit(1)}),_.listen(t),s.push(async()=>{_.close()}),async()=>{for(let e of s)await e();await new Promise(e=>setTimeout(e,100))}},U=({root:e,name:t},n,i)=>r(e,`var/.vite/${t}/${n}/${i}`),W=e=>{let{generators:t=[]}=e.config,n={},r=[];for(let e of t)e.meta.slot?n[e.meta.slot]=e:r.push(e);return[L(),...n.api?[n.api]:[],...n.fetch&&n.api?[n.fetch]:[],...r,...n.ssr?[n.ssr]:[],...n.ssg?[n.ssg]:[]]},G=async e=>{let{resolvers:t,resolversFactory:n}=await p(e,z),{createPath:r}=u(e),a=[];for(let t of W(e)){let n=t.factory(e);a.push({name:t.meta.name,factory:n})}let o=new Map,s=async t=>{let n=Array.from(o.values());for(let{name:r,factory:o}of a)try{await o.watch?.(n,t)}catch(n){console.error(i(`red`,`${e.name}: ${r} generator failed`)),t&&console.error(t),console.error(n)}},c=async n=>{let a=t.get(n);if(a)try{let e=await a.handler(n);return o.set(e.entry.fileFullpath,e),e}catch(t){let a=n.replace(`${r.api()}/`,``);console.error(i(`red`,`${e.name}: ${a} route resolution failed`)),console.error(t);return}};{let n=m(`${e.name}: resolving routes`);for(let{name:e,handler:r}of t.values()){n.append(`[ ${o.size+1} of ${t.size} ] ${e}`);let i=await r();o.set(i.entry.fileFullpath,i)}n.succeed(`ready ✨`)}return await s(),{async add(e){let[r]=n([e]).values();r&&(t.set(e,r),await c(e)&&await s({kind:`create`,file:e}))},async change(e){if(o.has(e))await c(e);else{let t=o.values().flatMap(({kind:t,entry:n})=>t===`apiRoute`&&n.referencedFiles.includes(e)?[n]:[]);for(let e of t)await c(e.fileFullpath)}await s({kind:`update`,file:e})},async unlink(e){t.delete(e),o.delete(e),await s({kind:`delete`,file:e})}}},K=({config:e})=>{let t=RegExp(`^${e.base}($|/*)`),r=RegExp(`^${n(e.base,e.apiBase)}($|/*)`);return{base(e){return!r.test(e.url)&&t.test(e.url)},api(e){return r.test(e.url)}}},q=async e=>{let t=0,n=0;for(let r of[3,2,1,``])if(t=Number(`${r}${e}`)+100,n=t+100,n<65e3)break;if(n>=65e3)throw Error(`the devPort in package.json should be less than 64000`);let r=n-t+1,i=Math.floor(Math.random()*r),a=await Array.from({length:r},(e,n)=>t+(i+n)%r).reduce(async(e,t)=>await e||(await J(t)?t:void 0),Promise.resolve(void 0));if(!a)throw Error(`No free ports found in range ${t}-${n}`);return a},J=e=>new Promise(t=>{let n=w.createServer();n.once(`error`,()=>t(!1)),n.once(`listening`,()=>{n.close(),t(!0)}),n.listen(e,`127.0.0.1`)});export{H as default};
325
+ `,I=e=>{let t="${configDir}",n={types:[`@types/node`,`vite/client`],moduleResolution:`bundler`,module:`ESNext`,target:`ESNext`,strict:!0,exactOptionalPropertyTypes:!0,noImplicitAny:!0,noImplicitThis:!0,noImplicitOverride:!0,noImplicitReturns:!0,noUnusedLocals:!1,noUnusedParameters:!1,allowArbitraryExtensions:!0,allowImportingTsExtensions:!0,allowUnreachableCode:!1,allowUnusedLabels:!1,useUnknownInCatchVariables:!0,noFallthroughCasesInSwitch:!0,noUncheckedSideEffectImports:!0,resolveJsonModule:!0,esModuleInterop:!0,verbatimModuleSyntax:!0,skipLibCheck:!0,noEmit:!0};return e?{include:[`${t}/`,`${t}/../../${a.libDir}/${e}/`,`${t}/../../**/*.d.ts`],compilerOptions:{...n,types:[...n.types],paths:{[`${a.appPrefix}/*`]:[`${t}/../../*`],[`${a.srcPrefix}/*`]:[`${t}/*`],[`${a.libPrefix}/*`]:[`${t}/../../${a.libDir}/${e}/*`]}}}:{include:[`${t}/`],exclude:[`${t}/${a.srcDir}/`],compilerOptions:{...n,paths:{[`${a.appPrefix}/*`]:[`${t}/*`]}}}},L=s(e=>{let{createPath:n,createImportHelpers:o}=u(e),s=async()=>{let{generators:t=[]}=e.config;{let{dependencies:n={},devDependencies:a={}}=await import(r(e.root,`package.json`),{with:{type:`json`}}).then(e=>e.default),o=[],s=[],c=t.flatMap(e=>[`dependencies`,`devDependencies`].flatMap(t=>e[t]?Object.entries(typeof e[t]==`function`?e[t](e.options):e[t]).flatMap(([e,n])=>{let r=T.minVersion(n)?.version;return r?[[e,r,t]]:[]}):[]));for(let[e,t,r]of c){let i=n[e]||a[e],c=i?T.minVersion(i)?.version:void 0;!i||!c?o.push([e,t,r]):T.lt(c,t)&&s.push([e,t,r])}if(o.length){console.error(i([`red`,`italic`],`✗ There are ${o.length} missing dependencies, please consider installing them.`));for(let e of[`dependencies`,`devDependencies`]){let t=o.filter(t=>t[2]===e);t.length&&console.error(`${e}: ${i([`blue`],t.map(([e])=>e).join(` `))}`)}}s.length&&(console.error(i([`blue`,`italic`],`! There are ${s.length} outdated dependencies, please consider updating them:`)),console.error(i([`blue`],`${s.map(([e])=>e).join(` `)}`)))}{await f(r(e.root,`tsconfig.json`),JSON.stringify({extends:`./${a.libDir}/tsconfig.json`},void 0,2),{},{overwrite:!1}),await f(n.lib(`../tsconfig.json`),JSON.stringify(I(),void 0,2),{}),await f(n.src(`tsconfig.json`),JSON.stringify({extends:`../../${a.libDir}/${e.name}/tsconfig.json`},void 0,2),{},{overwrite:!1});let t=I(e.name),i={},o=new Set(t.compilerOptions.types||[]);for(let{meta:t}of e.config.generators||[]){t.jsx&&(i.jsx=t.jsx),t.jsxImportSource&&(i.jsxImportSource=t.jsxImportSource);for(let e of t.types||[])o.add(e)}await f(n.lib(`tsconfig.json`),JSON.stringify({...t,compilerOptions:{...t.compilerOptions,...i,types:[...o.values()]}},void 0,2),{})}for(let[e,t]of[[`env.d.ts`,M],[`global.d.ts`,P]])await f(n.lib(`../${e}`),t,{});await f(n.lib(`../.gitignore`),N,{},{overwrite:!1});for(let[e,t]of[[`ssg.ts`,`export default [];`]])await f(n.lib(e),t,{})},c=async r=>{let{renderToFile:i}=d({helpers:{...o({origin:`lib`}),...g()},partials:{pathMapper:A}});await i(n.libCore(`routeMap.ts`),j,{apiRoutes:r.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),pageRoutes:r.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[])});for(let[t,r]of[[`config.ts`,O],[`index.ts`,k]])await i(n.libCore(t),r,e);for(let{kind:e,entry:a}of r)e===`apiRoute`&&await i(n.libApi(t(a.file),`schemas.ts`),F,{route:a},{overwrite:!1})};return{start:s,watch:c,build:c}}),R=o({meta:{name:`Core`},dependencies:{"path-to-regexp":D.devDependencies[`path-to-regexp`]},factory:L}),z=JSON.parse(E(e(import.meta.url).resolve(`@kosmojs/dev/package.json`),`utf-8`)),B=(e,n,i)=>{let a=u(n).createPath.libApi(t(e.file),`cache.json`),o=async t=>{if(!t?.hash||!t.typeDeclarations||!t.referencedFiles)return;let a=await V(e.fileFullpath,{...i});if(H(t.hash,a)){for(let[e,i]of Object.entries(t.referencedFiles))if(!H(i,await V(r(n.root,e))))return;return t}};return{async get(e){if(await l(a))try{let t=JSON.parse(await x(a,`utf8`));return e?.validate?o(t):t}catch{}},async set(r){let o=await V(e.fileFullpath,{...i}),s={};for(let e of r.referencedFiles)s[e.replace(`${n.root}/`,``)]=await V(e);let c={...r,hash:o,referencedFiles:s};return await b(t(a),{recursive:!0}),await S(a,JSON.stringify(c,null,2),`utf8`),c}}},V=async(e,t)=>{let n;try{n=await x(e,`utf8`)}catch{return 0}return n?_(JSON.stringify({...t,[z.cacheVersion]:n})):0},H=(e,t)=>e===t,U=async e=>{let{devPort:t,command:r}=e;for(let t of e.sourceFolders)for(let e of G(t)){if(!e.meta?.name||typeof e.factory!=`function`)throw Error(`${t.name}: Unrecognized generator - must be created via defineGenerator()`);try{await e.factory(t).start?.()}catch(n){throw console.error(i(`red`,`${t.name}: ${e.meta.name} generator failed to initialize`)),n}}if(r===`build`){for(let t of e.sourceFolders){let{createPath:e}=u(t),n=[];{let{resolvers:e}=await p(t,B),r=m(`${t.name}: resolving routes`);for(let{name:t,handler:i}of e.values())r.append(`[ ${n.length+1} of ${e.size} ] ${t}`),n.push(await i());r.succeed(`ready ✨`)}let i=G(t);for(let e of i)await e.factory(t).build?.(n);let a=[h.tsconfigPaths(t),h.nodePrefix()];await v(c(t.config,...i.map(({factory:e})=>e(t).config?.({kind:`client`,command:r})),{root:e.src(),cacheDir:W(t,r,`client`),plugins:a,build:{outDir:e.distDir(`client`),manifest:!0,emptyOutDir:!0}}));let o=i.find(e=>e.meta.slot===`backend`);if(o){let n=e.distDir(`api`);await v(c(o.options,o.factory(t).config?.({kind:`backend`,command:r}),{base:`./`,root:e.src(),appType:`custom`,plugins:a,resolve:{conditions:[`node`]},build:{ssr:!0,target:`esnext`,sourcemap:!0,emptyOutDir:!0,rolldownOptions:{input:[e.api(`app.ts`),e.api(`server.ts`)],output:{dir:n,format:`esm`}}},cacheDir:W(t,r,`backend`)}))}for(let e of i)await e.factory(t).postBuild?.(n)}return async()=>{}}let o=[],s=[],l={};for(let t of e.sourceFolders)l[t.name]=await K(t);let d=await J(t);for(let t of e.sourceFolders){let{createPath:e}=u(t),i=q(t),f=G(t),p=[h.tsconfigPaths(t),h.nodePrefix()];{let n=await y(c(t.config,...f.map(({factory:e})=>e(t).config?.({kind:`client`,command:r})),{root:e.src(),cacheDir:W(t,r,`client`),plugins:p,server:{port:d++,middlewareMode:!0,hmr:{port:d++}}}));for(let[e,r]of Object.entries(l[t.name]))n.watcher.on(e,r);o.push([[t.config.base],()=>i.base,()=>n.middlewares]),s.push(n.close)}let m=f.find(e=>e.meta.slot===`backend`);if(m){let u=await y(c(m.options,m.factory(t).config?.({kind:`backend`,command:r}),{root:e.src(),appType:`custom`,cacheDir:W(t,r,`backend`),plugins:p,server:{port:d++,middlewareMode:!0,hmr:{port:d++}},resolve:{conditions:[`node`]},environments:{api:{resolve:{conditions:[`node`]}}}})),f=u.environments.api,h=async()=>(f.runner.clearCache(),f.runner.import(n(a.apiDir,`dev.ts`)).then(e=>e.default)),g=await h();for(let[e,n]of Object.entries(l[t.name]))u.watcher.on(e,async e=>{f.moduleGraph.getModulesByFile(e)?.size&&(await n(e),await g?.teardownHandler?.(),g=await h())});o.push([[t.config.base,t.config.apiBase],()=>g.requestMatcher||i.api,()=>g.requestHandler()]),s.push(u.close)}}let f=([e])=>{let[t,n]=e,r=t.split(`/`).filter(Boolean).length;return n?r+5:r},g=o.sort((e,t)=>f(t)-f(e)),_=C.createServer((e,t)=>{for(let[,n,r]of g){let[i,a]=[n(),r()];if(i(e)){a(e,t);return}}t.writeHead(404,{"Content-Type":`text/html`}),t.end(`<h1>404: Not Found</h1>`)});return _.on(`error`,e=>{console.error(i(`red`,`Failed to start dev server on port ${t}`)),console.error(e.message),process.exit(1)}),_.listen(t),s.push(async()=>{_.close()}),async()=>{for(let e of s)await e();await new Promise(e=>setTimeout(e,100))}},W=({root:e,name:t},n,i)=>r(e,`var/.vite/${t}/${n}/${i}`),G=e=>{let{generators:t=[]}=e.config,n={},r=[];for(let e of t)e.meta.slot?n[e.meta.slot]=e:r.push(e);return[R(),...n.backend?[n.backend]:[],...n.fetch&&n.backend?[n.fetch]:[],...r,...n.ssr?[n.ssr]:[],...n.ssg?[n.ssg]:[]]},K=async e=>{let{resolvers:t,resolversFactory:n}=await p(e,B),{createPath:r}=u(e),a=[];for(let t of G(e)){let n=t.factory(e);a.push({name:t.meta.name,factory:n})}let o=new Map,s=async t=>{let n=Array.from(o.values());for(let{name:r,factory:o}of a)try{await o.watch?.(n,t)}catch(n){console.error(i(`red`,`${e.name}: ${r} generator failed`)),t&&console.error(t),console.error(n)}},c=async n=>{let a=t.get(n);if(a)try{let e=await a.handler(n);return o.set(e.entry.fileFullpath,e),e}catch(t){let a=n.replace(`${r.api()}/`,``);console.error(i(`red`,`${e.name}: ${a} route resolution failed`)),console.error(t);return}};{let n=m(`${e.name}: resolving routes`);for(let{name:e,handler:r}of t.values()){n.append(`[ ${o.size+1} of ${t.size} ] ${e}`);let i=await r();o.set(i.entry.fileFullpath,i)}n.succeed(`ready ✨`)}return await s(),{async add(e){let[r]=n([e]).values();r&&(t.set(e,r),await c(e)&&await s({kind:`create`,file:e}))},async change(e){if(o.has(e))await c(e);else{let t=o.values().flatMap(({kind:t,entry:n})=>t===`apiRoute`&&n.referencedFiles.includes(e)?[n]:[]);for(let e of t)await c(e.fileFullpath)}await s({kind:`update`,file:e})},async unlink(e){t.delete(e),o.delete(e),await s({kind:`delete`,file:e})}}},q=({config:e})=>{let t=RegExp(`^${e.base}($|/*)`),r=RegExp(`^${n(e.base,e.apiBase)}($|/*)`);return{base(e){return!r.test(e.url)&&t.test(e.url)},api(e){return r.test(e.url)}}},J=async e=>{let t=0,n=0;for(let r of[3,2,1,``])if(t=Number(`${r}${e}`)+100,n=t+100,n<65e3)break;if(n>=65e3)throw Error(`the devPort in package.json should be less than 64000`);let r=n-t+1,i=Math.floor(Math.random()*r),a=await Array.from({length:r},(e,n)=>t+(i+n)%r).reduce(async(e,t)=>await e||(await Y(t)?t:void 0),Promise.resolve(void 0));if(!a)throw Error(`No free ports found in range ${t}-${n}`);return a},Y=e=>new Promise(t=>{let n=w.createServer();n.once(`error`,()=>t(!1)),n.once(`listening`,()=>{n.close(),t(!0)}),n.listen(e,`127.0.0.1`)});export{U as default};
327
326
  //# sourceMappingURL=chassis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chassis.js","names":["c","s","r","i","o","a","t","e","n"],"sources":["../../../generators/core-generator/pkg/index.js","../src/cache.ts","../src/chassis.ts"],"sourcesContent":["import{dirname as e}from\"node:path\";import{routeRenderHelpers as t}from\"@kosmojs/core/generators\";import{defineGenerator as n,defineGeneratorFactory as r,pathResolver as i,renderFactory as a,renderToFile as o}from\"@kosmojs/lib\";import{defaults as s}from\"@kosmojs/core\";var c={type:`module`,private:!0,name:`@kosmojs/core-generator`,version:`0.2.7`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{\".\":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{\"@kosmojs/core\":`workspace:^`,\"@kosmojs/lib\":`workspace:^`},devDependencies:{\"path-to-regexp\":`^8.4.2`}},l=`export const base = \"{{config.base}}\";\nexport const apiBase = \"{{config.apiBase}}\";\n`,u=`export * from \"./config\";\nexport * from \"./routeMap\";\n`,d=`import { compile } from \"path-to-regexp\";\n\nimport type { PathMapperSignature } from \"@kosmojs/core\";\nimport { createHost, join, stringify } from \"@kosmojs/core/fetch\";\n\nexport const pathMapper = <ParamsT extends readonly unknown[]>(\n basePath: string,\n routeName: string,\n pathPattern: string,\n paramsMap: Array<[name: string, kind: string]>,\n numericParams: Array<string>,\n): PathMapperSignature<ParamsT> => {\n const toPath = compile(pathPattern);\n\n const castParam = (name: string, value: unknown) => {\n if (numericParams.includes(name)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : String(value);\n }\n return String(value);\n };\n\n const paramsMapper: PathMapperSignature<ParamsT>[\"paramsMapper\"] = (\n params,\n ) => {\n return paramsMap.reduce<Record<string, unknown>>((map, [name, kind], i) => {\n if (kind === \"splat\") {\n if (Array.isArray(params[i]) && params[i].length) {\n map[name] = params[i].map((v) => castParam(name, v));\n }\n } else if (params[i] !== undefined) {\n map[name] = castParam(name, params[i]);\n }\n return map;\n }, {});\n };\n\n const parametrize: PathMapperSignature<ParamsT>[\"parametrize\"] = (params) => {\n try {\n return toPath(paramsMapper(params) as never);\n } catch (error) {\n console.error(\\`❗ERROR: Failed building path for \\${routeName}\\`);\n throw error;\n }\n };\n\n const base: PathMapperSignature<ParamsT>[\"base\"] = (params, query) => {\n const path = join(\"/\", parametrize(params));\n return query ? [path, stringify(query)].join(\"?\") : path;\n };\n\n const path: PathMapperSignature<ParamsT>[\"path\"] = (params, query) => {\n return join(basePath, base(params, query));\n };\n\n const href: PathMapperSignature<ParamsT>[\"href\"] = (host, params, query) => {\n return createHost(host) + path(params, query);\n };\n\n return {\n paramsMapper,\n parametrize,\n base,\n path,\n href,\n };\n};\n`,f=`{{> pathMapper}}\n\nimport { base, apiBase } from \"./config\";\n\n{{#if pageRoutes.length}}\nexport type LinkProps =\n {{#each pageRoutes}}\n | [ \"{{name}}\", {{serializeParamsTupleElements .}} ]\n {{/each}};\n{{else}}\nexport type LinkProps = never;\n{{/if}}\n\nexport const apiRouteMap = {\n {{#each apiRoutes}}\n \"{{name}}\": pathMapper<[{{serializeParamsTupleElements .}}]>(\n apiBase,\n \"{{name}}\",\n \"{{pathPattern}}\",\n [{{#each params.schema}}[\"{{name}}\", \"{{kind}}\"], {{/each}}],\n [{{#each numericParams}}\"{{.}}\", {{/each}}],\n ),\n {{/each}}\n};\n\nexport const pageRouteMap = {\n {{#each pageRoutes}}\n \"{{name}}\": pathMapper<[{{serializeParamsTupleElements .}}]>(\n base,\n \"{{name}}\",\n \"{{pathPattern}}\",\n [{{#each params.schema}}[\"{{name}}\", \"{{kind}}\"], {{/each}}],\n [{{#each numericParams}}\"{{.}}\", {{/each}}],\n ),\n {{/each}}\n};\n`,p=`declare const KOSMO_PRODUCTION_BUILD: boolean;\ndeclare const KOSMO_SERVERSIDE_FETCH: boolean;\n\n/**\n * Enhances base TypeScript types with JSON Schema validation constraints.\n * Allows declaring refined types that carry validation metadata for runtime\n * schema validation while maintaining full TypeScript type safety.\n *\n * Useful for generating validation schemas and ensuring\n * data conforms to specific business rules beyond basic type checking.\n * */\ndeclare type VRefine<\n T extends unknown[] | number | string | object,\n _ extends T extends unknown[]\n ? TArrayOptions\n : T extends number\n ? TNumberOptions\n : T extends string\n ? TStringOptions\n : TObjectOptions,\n> = T;\n\n/**\n * Type definitions inspired by and gently adapted from TypeBox.\n * Original TypeBox created by sinclairzx81: https://github.com/sinclairzx81/typebox\n * TypeBox is licensed under MIT: https://github.com/sinclairzx81/typebox/blob/main/license\n *\n * These types provide JSON Schema compatible type refinements for TypeScript.\n * */\ninterface TSchema {}\n\n// ------------------------------------------------------------------\n// ObjectOptions\n// ------------------------------------------------------------------\ninterface TObjectOptions {\n /**\n * Defines whether additional properties are allowed beyond those explicitly defined in \\`properties\\`.\n */\n additionalProperties?: TSchema | boolean;\n /**\n * The minimum number of properties required in the object.\n */\n minProperties?: number;\n /**\n * The maximum number of properties allowed in the object.\n */\n maxProperties?: number;\n /**\n * Defines conditional requirements for properties.\n */\n dependencies?: Record<string, boolean | TSchema | string[]>;\n /**\n * Specifies properties that *must* be present if a given property is present.\n */\n dependentRequired?: Record<string, string[]>;\n /**\n * Defines schemas that apply if a specific property is present.\n */\n dependentSchemas?: Record<string, TSchema>;\n /**\n * Maps regular expressions to schemas properties matching a pattern must validate against the schema.\n */\n patternProperties?: Record<string, TSchema>;\n /**\n * A schema that all property names within the object must validate against.\n */\n propertyNames?: TSchema;\n}\n\n// ------------------------------------------------------------------\n// ArrayOptions\n// ------------------------------------------------------------------\ninterface TArrayOptions {\n /**\n * The minimum number of items allowed in the array.\n */\n minItems?: number;\n /**\n * The maximum number of items allowed in the array.\n */\n maxItems?: number;\n /**\n * A schema that at least one item in the array must validate against.\n */\n contains?: TSchema;\n /**\n * The minimum number of array items that must validate against the \\`contains\\` schema.\n */\n minContains?: number;\n /**\n * The maximum number of array items that may validate against the \\`contains\\` schema.\n */\n maxContains?: number;\n /**\n * An array of schemas, where each schema in \\`prefixItems\\` validates against items at corresponding positions from the beginning of the array.\n */\n prefixItems?: TSchema[];\n /**\n * If \\`true\\`, all items in the array must be unique.\n */\n uniqueItems?: boolean;\n}\n\n// ------------------------------------------------------------------\n// NumberOptions\n// ------------------------------------------------------------------\ninterface TNumberOptions {\n /**\n * Specifies an exclusive upper limit for the number (number must be less than this value).\n */\n exclusiveMaximum?: number | bigint;\n /**\n * Specifies an exclusive lower limit for the number (number must be greater than this value).\n */\n exclusiveMinimum?: number | bigint;\n /**\n * Specifies an inclusive upper limit for the number (number must be less than or equal to this value).\n */\n maximum?: number | bigint;\n /**\n * Specifies an inclusive lower limit for the number (number must be greater than or equal to this value).\n */\n minimum?: number | bigint;\n /**\n * Specifies that the number must be a multiple of this value.\n */\n multipleOf?: number | bigint;\n}\n\n// ------------------------------------------------------------------\n// StringOptions\n// ------------------------------------------------------------------\ntype TFormat =\n | \"date-time\"\n | \"date\"\n | \"duration\"\n | \"email\"\n | \"hostname\"\n | \"idn-email\"\n | \"idn-hostname\"\n | \"ipv4\"\n | \"ipv6\"\n | \"iri-reference\"\n | \"iri\"\n | \"json-pointer-uri-fragment\"\n | \"json-pointer\"\n | \"json-string\"\n | \"regex\"\n | \"relative-json-pointer\"\n | \"time\"\n | \"uri-reference\"\n | \"uri-template\"\n | \"url\"\n | \"uuid\";\n\ninterface TStringOptions {\n /**\n * Specifies the expected string format.\n *\n * Common values include:\n * - \\`base64\\` – Base64-encoded string.\n * - \\`date-time\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date-time format.\n * - \\`date\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date (YYYY-MM-DD).\n * - \\`duration\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) duration format.\n * - \\`email\\` – RFC 5321/5322 compliant email address.\n * - \\`hostname\\` – RFC 1034/1035 compliant host name.\n * - \\`idn-email\\` – Internationalized email address.\n * - \\`idn-hostname\\` – Internationalized host name.\n * - \\`ipv4\\` – IPv4 address.\n * - \\`ipv6\\` – IPv6 address.\n * - \\`iri\\` / \\`iri-reference\\` – Internationalized Resource Identifier.\n * - \\`json-pointer\\` / \\`json-pointer-uri-fragment\\` – JSON Pointer format.\n * - \\`json-string\\` – String containing valid JSON.\n * - \\`regex\\` – Regular expression syntax.\n * - \\`relative-json-pointer\\` – Relative JSON Pointer format.\n * - \\`time\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) time (HH:MM:SS).\n * - \\`uri-reference\\` / \\`uri-template\\` – URI reference or template.\n * - \\`url\\` – Web URL format.\n * - \\`uuid\\` – RFC 4122 UUID string.\n *\n * May also be a custom format string.\n */\n format?: TFormat;\n /**\n * Specifies the minimum number of characters allowed in the string.\n * Must be a non-negative integer.\n */\n minLength?: number;\n /**\n * Specifies the maximum number of characters allowed in the string.\n * Must be a non-negative integer.\n */\n maxLength?: number;\n /**\n * Specifies a regular expression pattern that the string value must match.\n * Can be provided as a string (ECMA-262 regex syntax) or a \\`RegExp\\` object.\n */\n pattern?: string | RegExp;\n}\n`,m=`# Ignore all files\n*\n\n# But don't ignore directories (so Git can traverse them)\n!*/\n\n# And don't ignore these files at any depth\n!cache.json\n!types.ts\n`,h=`export declare global {\n interface Window {\n __KOSMO_HYDRATION_BOOL__: boolean;\n __KOSMO_HYDRATION_DATA__: Record<string, unknown> | undefined;\n }\n}\n`,g=`// stub schemas, specialized generators supposed to overwrite this file\nimport type { ValidationSchemas } from \"@kosmojs/core/api\";\nexport type { ValidationSchemas };\nexport const validationSchemas: ValidationSchemas = {};\n`,_=e=>{let t=\"${configDir}\",n={types:[`@types/node`,`vite/client`],moduleResolution:`bundler`,module:`ESNext`,target:`ESNext`,strict:!0,exactOptionalPropertyTypes:!0,noImplicitAny:!0,noImplicitThis:!0,noImplicitOverride:!0,noImplicitReturns:!0,noUnusedLocals:!1,noUnusedParameters:!1,allowArbitraryExtensions:!0,allowImportingTsExtensions:!0,allowUnreachableCode:!1,allowUnusedLabels:!1,useUnknownInCatchVariables:!0,noFallthroughCasesInSwitch:!0,noUncheckedSideEffectImports:!0,resolveJsonModule:!0,esModuleInterop:!0,verbatimModuleSyntax:!0,skipLibCheck:!0,noEmit:!0};return e?{include:[`${t}/`,`${t}/../../${s.libDir}/${e}/`,`${t}/../../**/*.d.ts`],compilerOptions:{...n,types:[...n.types],paths:{[`${s.appPrefix}/*`]:[`${t}/../../*`],[`${s.srcPrefix}/*`]:[`${t}/*`],[`${s.libPrefix}/*`]:[`${t}/../../${s.libDir}/${e}/*`]}}}:{include:[`${t}/`],exclude:[`${t}/${s.srcDir}/`],compilerOptions:{...n,paths:{[`${s.appPrefix}/*`]:[`${t}/*`]}}}},v=r((n,r)=>{let{createPath:s,createImportHelpers:c}=i(r),v=async()=>{await o(s.lib(`../tsconfig.json`),JSON.stringify(_(),void 0,2),{});{let e=_(r.name),t={},n=new Set(e.compilerOptions.types||[]);for(let{meta:e}of r.config.generators||[]){e.jsx&&(t.jsx=e.jsx),e.jsxImportSource&&(t.jsxImportSource=e.jsxImportSource);for(let t of e.types||[])n.add(t)}await o(s.lib(`tsconfig.json`),JSON.stringify({...e,compilerOptions:{...e.compilerOptions,...t,types:[...n.values()]}},void 0,2),{})}for(let[e,t]of[[`env.d.ts`,p],[`global.d.ts`,h]])await o(s.lib(`../${e}`),t,{});await o(s.lib(`../.gitignore`),m,{},{overwrite:!1}),await o(s.lib(`ssg.ts`),`export default [];`,{})},y=async n=>{let{renderToFile:i}=a({helpers:{...c({origin:`lib`}),...t()},partials:{pathMapper:d}});await i(s.libCore(`routeMap.ts`),f,{apiRoutes:n.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),pageRoutes:n.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[])});for(let[e,t]of[[`config.ts`,l],[`index.ts`,u]])await i(s.libCore(e),t,r);for(let{kind:t,entry:r}of n)t===`apiRoute`&&await i(s.libApi(e(r.file),`schemas.ts`),g,{route:r},{overwrite:!1})};return{meta:n,start:v,watch:y,build:y}}),y=n(()=>{let e={name:`Core`,dependencies:{\"path-to-regexp\":c.devDependencies[`path-to-regexp`]}};return{meta:e,options:void 0,factory:t=>v(e,t)}});export{y as default};\n//# sourceMappingURL=index.js.map","import { readFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\n\nimport type {\n RouteResolverCache,\n RouteResolverCacheFactory,\n} from \"@kosmojs/core\";\nimport { pathExists, pathResolver } from \"@kosmojs/lib\";\n\n/**\n * Read the installed package.json at runtime to get the actual version.\n * A static `import ... with { type: \"json\" }` would be inlined by the\n * bundler with the pre-bump version, defeating the point.\n * */\nconst self = JSON.parse(\n readFileSync(\n createRequire(import.meta.url).resolve(\"@kosmojs/dev/package.json\"),\n \"utf-8\",\n ),\n);\n\nexport const cacheFactory: RouteResolverCacheFactory = (\n route,\n sourceFolder,\n extraContext,\n) => {\n const cacheFile = pathResolver(sourceFolder).createPath.libApi(\n dirname(route.file),\n \"cache.json\",\n );\n\n const validateCache = async (cache: RouteResolverCache) => {\n if (!cache?.hash) {\n return;\n }\n\n if (!cache.typeDeclarations || !cache.referencedFiles) {\n // incomplete cache\n return;\n }\n\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n if (!identicalHashSum(cache.hash, hash)) {\n // route itself updated\n return;\n }\n\n for (const [file, hash] of Object.entries(cache.referencedFiles)) {\n if (\n !identicalHashSum(\n hash,\n await generateFileHash(resolve(sourceFolder.root, file)),\n )\n ) {\n // some referenced file updated\n return;\n }\n }\n\n return cache;\n };\n\n return {\n async get(opt?: { validate?: boolean }) {\n if (await pathExists(cacheFile)) {\n try {\n const cache = JSON.parse(await readFile(cacheFile, \"utf8\"));\n return opt?.validate //\n ? validateCache(cache)\n : cache;\n } catch (_e) {}\n }\n return undefined;\n },\n\n async set(cache) {\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n const referencedFiles: Record<string, number> = {};\n\n for (const file of cache.referencedFiles) {\n referencedFiles[\n // Strip project root to ensure cached paths are relative\n // and portable across environments (CI, local, etc.)\n file.replace(`${sourceFolder.root}/`, \"\")\n ] = await generateFileHash(file);\n }\n\n const value = { ...cache, hash, referencedFiles };\n\n await mkdir(dirname(cacheFile), { recursive: true });\n await writeFile(cacheFile, JSON.stringify(value, null, 2), \"utf8\");\n\n return value;\n },\n };\n};\n\nconst generateFileHash = async (\n file: string,\n extraContext?: object,\n): Promise<number> => {\n let fileContent: string | undefined;\n try {\n fileContent = await readFile(file, \"utf8\");\n } catch (_e) {\n // file could be deleted since last build\n return 0;\n }\n return fileContent\n ? crc(\n JSON.stringify({\n ...extraContext,\n [self.cacheVersion]: fileContent,\n }),\n )\n : 0;\n};\n\n// return true if sums are identical\nconst identicalHashSum = (a: number, b: number) => {\n return a === b;\n};\n","import http, { type IncomingMessage, type ServerResponse } from \"node:http\";\nimport net from \"node:net\";\nimport { join, resolve } from \"node:path\";\nimport { styleText } from \"node:util\";\n\nimport { build, createServer, type RunnableDevEnvironment } from \"vite\";\n\nimport {\n defaults,\n type GeneratorBase,\n type GeneratorFactoryInstance,\n type GeneratorMeta,\n type ProjectSettings,\n type ResolvedEntry,\n type SourceFolder,\n type WatcherEvent,\n} from \"@kosmojs/core\";\nimport type { DevSetup } from \"@kosmojs/core/api\";\nimport {\n mergeConfigs,\n pathResolver,\n routesFactory,\n spinnerFactory,\n vitePlugins,\n} from \"@kosmojs/lib\";\n\nimport coreGenerator from \"@kosmojs/core-generator\";\n\nimport { cacheFactory } from \"./cache\";\n\nexport default async (\n projectSettings: ProjectSettings,\n): Promise<() => Promise<void>> => {\n const { devPort, command } = projectSettings;\n\n // NOTE: initialize generators before anything else, regardless command\n for (const sourceFolder of projectSettings.sourceFolders) {\n for (const base of folderGenerators(sourceFolder)) {\n if (!base.meta?.name || typeof base.factory !== \"function\") {\n throw new Error(\n `${sourceFolder.name}: Unrecognized generator - must be created via defineGenerator()`,\n );\n }\n\n const factory = base.factory(sourceFolder);\n\n if (!factory.meta?.name) {\n throw new Error(\n `${sourceFolder.name}: ${base.meta.name} generator is missing meta property`,\n );\n }\n\n try {\n await factory.start?.();\n } catch (error) {\n console.error(\n styleText(\n \"red\",\n `${sourceFolder.name}: ${base.meta.name} generator failed to initialize`,\n ),\n );\n throw error;\n }\n }\n }\n\n if (command === \"build\") {\n for (const sourceFolder of projectSettings.sourceFolders) {\n const { createPath } = pathResolver(sourceFolder);\n\n const resolvedRoutes = [];\n\n {\n const { resolvers } = await routesFactory(sourceFolder, cacheFactory);\n\n const spinner = spinnerFactory(\n `${sourceFolder.name}: resolving routes`,\n );\n\n for (const { name, handler } of resolvers.values()) {\n spinner.append(\n `[ ${resolvedRoutes.length + 1} of ${resolvers.size} ] ${name}`,\n );\n resolvedRoutes.push(await handler());\n }\n\n spinner.succeed(\"ready ✨\");\n }\n\n const generators = folderGenerators(sourceFolder);\n\n for (const generator of generators) {\n await generator.factory(sourceFolder).build?.(resolvedRoutes);\n }\n\n const plugins = [\n vitePlugins.tsconfigPaths(sourceFolder),\n vitePlugins.nodePrefix(),\n ];\n\n // INFO: === build client ===\n await build(\n mergeConfigs(\n // user-provided config - lowest priority\n sourceFolder.config,\n // generators configs - higher priority\n ...generators.map(({ factory }) => {\n return factory(sourceFolder).config?.({ kind: \"client\", command });\n }),\n // main config - highest priority\n {\n // base provided by sourceFolder.config\n root: createPath.src(),\n cacheDir: cacheDir(sourceFolder, command, \"client\"),\n plugins,\n build: {\n outDir: createPath.distDir(\"client\"),\n manifest: true,\n emptyOutDir: true,\n },\n },\n ),\n );\n\n const apiGenerator = generators.find((e) => e.meta.slot === \"api\");\n\n // INFO: === build backend ===\n if (apiGenerator) {\n const dir = createPath.distDir(\"api\");\n\n // NOTE: sourceFolder.config is client-specific config - not using for backend!\n // To provide backend-specific config pass it as api generator options.\n await build(\n mergeConfigs(\n // user-provided config - lowest priority\n apiGenerator.options,\n // generator config - higher priority\n apiGenerator\n .factory(sourceFolder)\n .config?.({ kind: \"backend\", command }),\n // main config - highest priority\n {\n base: \"./\",\n root: createPath.src(),\n appType: \"custom\",\n plugins,\n resolve: {\n conditions: [\"node\"],\n },\n build: {\n ssr: true,\n target: \"esnext\",\n sourcemap: true,\n emptyOutDir: true,\n rolldownOptions: {\n input: [\n createPath.api(\"app.ts\"),\n createPath.api(\"server.ts\"),\n ],\n output: {\n dir,\n format: \"esm\",\n },\n },\n },\n cacheDir: cacheDir(sourceFolder, command, \"backend\"),\n },\n ),\n );\n }\n\n for (const generator of generators) {\n await generator.factory(sourceFolder).postBuild?.(resolvedRoutes);\n }\n }\n\n return async () => {};\n }\n\n type RequestMatcher = (req: IncomingMessage) => boolean;\n type RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;\n\n const requestHandlers: Array<\n [\n segments: [base: string, api?: string],\n matcherFactory: () => RequestMatcher,\n handlerFactory: () => RequestHandler,\n ]\n > = [];\n\n const teardownHandlers: Array<() => Promise<unknown>> = [];\n\n const eventMap: Record<string, Awaited<ReturnType<typeof eventFactory>>> = {};\n\n // WARN: call this before starting any server!\n for (const sourceFolder of projectSettings.sourceFolders) {\n eventMap[sourceFolder.name] = await eventFactory(sourceFolder);\n }\n\n let port = await findFreePort(devPort);\n\n for (const sourceFolder of projectSettings.sourceFolders) {\n const { createPath } = pathResolver(sourceFolder);\n\n const requestMatchers = matchersFactory(sourceFolder);\n\n const generators = folderGenerators(sourceFolder);\n\n const plugins = [\n vitePlugins.tsconfigPaths(sourceFolder),\n vitePlugins.nodePrefix(),\n ];\n\n // INFO: === start client server ===\n {\n const viteServer = await createServer(\n mergeConfigs(\n // user-provided config - lowest priority\n sourceFolder.config,\n // generators configs - higher priority\n ...generators.map(({ factory }) => {\n return factory(sourceFolder).config?.({ kind: \"client\", command });\n }),\n // main config - highest priority\n {\n // base provided by sourceFolder.config\n root: createPath.src(),\n cacheDir: cacheDir(sourceFolder, command, \"client\"),\n plugins,\n server: {\n port: port++,\n middlewareMode: true,\n hmr: { port: port++ },\n },\n },\n ),\n );\n\n for (const [evt, handler] of Object.entries(\n eventMap[sourceFolder.name],\n )) {\n viteServer.watcher.on(evt, handler);\n }\n\n requestHandlers.push([\n [sourceFolder.config.base],\n () => requestMatchers.base,\n () => viteServer.middlewares,\n ]);\n\n teardownHandlers.push(viteServer.close);\n }\n\n const apiGenerator = generators.find((e) => e.meta.slot === \"api\");\n\n // INFO: === start backend server ===\n if (apiGenerator) {\n // NOTE: sourceFolder.config is client-specific config - not using for backend!\n // To provide backend-specific config pass it as api generator options.\n const viteServer = await createServer(\n mergeConfigs(\n // user-provided config - lowest priority\n apiGenerator.options,\n // generator config - higher priority\n apiGenerator\n .factory(sourceFolder)\n .config?.({ kind: \"backend\", command }),\n // main config - highest priority\n {\n root: createPath.src(),\n appType: \"custom\",\n cacheDir: cacheDir(sourceFolder, command, \"backend\"),\n plugins,\n server: {\n port: port++,\n middlewareMode: true,\n hmr: { port: port++ },\n },\n resolve: {\n conditions: [\"node\"],\n },\n environments: {\n api: {\n resolve: {\n conditions: [\"node\"],\n },\n },\n },\n },\n ),\n );\n\n const env = viteServer.environments.api as RunnableDevEnvironment;\n\n const loadDevSetup = async () => {\n env.runner.clearCache();\n return env.runner\n .import<{ default: DevSetup }>(join(defaults.apiDir, \"dev.ts\"))\n .then((e) => e.default);\n };\n\n let devSetup = await loadDevSetup();\n\n for (const [evt, handler] of Object.entries(\n eventMap[sourceFolder.name],\n )) {\n viteServer.watcher.on(evt, async (file) => {\n const mods = env.moduleGraph.getModulesByFile(file);\n if (mods?.size) {\n await handler(file);\n await devSetup?.teardownHandler?.();\n devSetup = await loadDevSetup();\n }\n });\n }\n\n requestHandlers.push([\n [sourceFolder.config.base, sourceFolder.config.apiBase],\n () => devSetup.requestMatcher || requestMatchers.api,\n () => devSetup.requestHandler(),\n ]);\n\n teardownHandlers.push(viteServer.close);\n }\n }\n\n /**\n * Sorting is essential to ensure more specific paths are matched before broader ones.\n *\n * Given source folders:\n * - main app: baseurl=/ apiurl=/api\n * - admin app: baseurl=/admin apiurl=/admin/api\n *\n * Correct sort order:\n * 1. /admin/api — most specific\n * 2. /api\n * 3. /admin\n * 4. /\n * */\n const requestHandlerWeight = ([\n segments,\n ]: (typeof requestHandlers)[number]) => {\n const [base, api] = segments;\n /**\n * set weight to number of non-empty segments:\n * \"/\" weight is 0\n * \"/admin\" weight is 1\n * */\n const weight = base.split(\"/\").filter(Boolean).length;\n return api ? weight + 5 : weight;\n };\n\n const handlers = requestHandlers.sort(\n (a, b) => requestHandlerWeight(b) - requestHandlerWeight(a),\n );\n\n const httpServer = http.createServer((req, res) => {\n for (const [, matcherFactory, handlerFactory] of handlers) {\n // should be called on every request\n const [matcher, handler] = [matcherFactory(), handlerFactory()];\n if (matcher(req)) {\n handler(req, res);\n return;\n }\n }\n res.writeHead(404, { \"Content-Type\": \"text/html\" });\n res.end(\"<h1>404: Not Found</h1>\");\n });\n\n httpServer.on(\"error\", (error) => {\n console.error(\n styleText(\"red\", `Failed to start dev server on port ${devPort}`),\n );\n console.error(error.message);\n process.exit(1);\n });\n\n httpServer.listen(devPort);\n\n teardownHandlers.push(async () => {\n httpServer.close();\n });\n\n return async () => {\n for (const handler of teardownHandlers) {\n await handler();\n }\n // Let chokidar fully release file handles\n await new Promise((resolve) => setTimeout(resolve, 100));\n };\n};\n\nconst cacheDir = (\n { root, name }: SourceFolder,\n command: ProjectSettings[\"command\"],\n mode: \"client\" | \"backend\",\n) => {\n return resolve(root, `var/.vite/${name}/${command}/${mode}`);\n};\n\nconst folderGenerators = (sourceFolder: SourceFolder): Array<GeneratorBase> => {\n const { generators = [] } = sourceFolder.config;\n\n const baseGenerators: Partial<\n Record<NonNullable<GeneratorMeta[\"slot\"]>, GeneratorBase>\n > = {};\n\n const userGenerators: Array<GeneratorBase> = [];\n\n for (const base of generators) {\n if (base.meta.slot) {\n baseGenerators[base.meta.slot] = base;\n } else {\n userGenerators.push(base);\n }\n }\n\n return [\n // core generator should run first\n coreGenerator(),\n // then api generator\n ...(baseGenerators.api ? [baseGenerators.api] : []),\n // then fetch generator, only if api generator also enabled\n ...(baseGenerators.fetch && baseGenerators.api\n ? [baseGenerators.fetch]\n : []),\n // then user generators in the order they were added\n ...userGenerators,\n // then ssr generator should run after user generators\n ...(baseGenerators.ssr ? [baseGenerators.ssr] : []),\n // and ssg generator should run last\n ...(baseGenerators.ssg ? [baseGenerators.ssg] : []),\n ];\n};\n\nconst eventFactory = async (\n sourceFolder: SourceFolder,\n): Promise<\n Record<\"add\" | \"change\" | \"unlink\", (f: string) => Promise<void>>\n> => {\n const { resolvers, resolversFactory } = await routesFactory(\n sourceFolder,\n cacheFactory,\n );\n\n const { createPath } = pathResolver(sourceFolder);\n\n const generators: Array<{\n name: string | undefined;\n factory: GeneratorFactoryInstance;\n }> = [];\n\n for (const base of folderGenerators(sourceFolder)) {\n const factory = base.factory(sourceFolder);\n generators.push({ name: base.meta.name, factory });\n }\n\n const resolvedRoutes = new Map<\n string, // fileFullpath\n ResolvedEntry\n >();\n\n const runGenerators = async (event?: WatcherEvent) => {\n /**\n * Watch handlers receive the full list of entries\n * and should process only those whose source file or dependencies were updated.\n * */\n const entries = Array.from(resolvedRoutes.values());\n\n for (const { name, factory } of generators) {\n try {\n await factory.watch?.(entries, event);\n } catch (error) {\n console.error(\n styleText(\"red\", `${sourceFolder.name}: ${name} generator failed`),\n );\n if (event) {\n console.error(event);\n }\n console.error(error);\n }\n }\n };\n\n const updateResolvedEntry = async (file: string) => {\n const resolver = resolvers.get(file);\n\n if (!resolver) {\n return;\n }\n\n try {\n const resolvedEntry = await resolver.handler(file);\n resolvedRoutes.set(resolvedEntry.entry.fileFullpath, resolvedEntry);\n return resolvedEntry;\n } catch (error) {\n const route = file.replace(`${createPath.api()}/`, \"\");\n console.error(\n styleText(\n \"red\",\n `${sourceFolder.name}: ${route} route resolution failed`,\n ),\n );\n console.error(error);\n return;\n }\n };\n\n {\n const spinner = spinnerFactory(`${sourceFolder.name}: resolving routes`);\n for (const { name, handler } of resolvers.values()) {\n spinner.append(\n `[ ${resolvedRoutes.size + 1} of ${resolvers.size} ] ${name}`,\n );\n const route = await handler();\n resolvedRoutes.set(route.entry.fileFullpath, route);\n }\n spinner.succeed(\"ready ✨\");\n }\n\n // NOTE: call only after routes resolved\n await runGenerators();\n\n return {\n async add(file: string) {\n const [resolver] = resolversFactory([file]).values();\n\n if (!resolver) {\n return;\n }\n\n resolvers.set(file, resolver);\n\n // call only after `resolvers.set(file)`\n const resolvedEntry = await updateResolvedEntry(file);\n\n if (resolvedEntry) {\n await runGenerators({ kind: \"create\", file });\n }\n },\n\n async change(file: string) {\n if (resolvedRoutes.has(file)) {\n // route updated\n await updateResolvedEntry(file);\n } else {\n // updating entries that are referencing updated file\n const relatedRoutes = resolvedRoutes\n .values()\n .flatMap(({ kind, entry }) => {\n return kind === \"apiRoute\"\n ? entry.referencedFiles.includes(file)\n ? [entry]\n : []\n : [];\n });\n\n for (const route of relatedRoutes) {\n await updateResolvedEntry(route.fileFullpath);\n }\n }\n\n await runGenerators({ kind: \"update\", file });\n },\n\n async unlink(file) {\n // route deleted\n resolvers.delete(file);\n resolvedRoutes.delete(file);\n await runGenerators({ kind: \"delete\", file });\n },\n };\n};\n\nconst matchersFactory: (\n sourceFolder: SourceFolder,\n) => Record<\"base\" | \"api\", (req: IncomingMessage) => boolean> = ({\n config,\n}) => {\n const basePattern = new RegExp(`^${config.base}($|/*)`);\n const apiPattern = new RegExp(`^${join(config.base, config.apiBase)}($|/*)`);\n return {\n base(req) {\n return apiPattern.test(req.url as string)\n ? false\n : basePattern.test(req.url as string);\n },\n api(req) {\n return apiPattern.test(req.url as string);\n },\n };\n};\n\nconst findFreePort = async (devPort: number): Promise<number> => {\n let minPort = 0;\n let maxPort = 0;\n\n for (const n of [3, 2, 1, \"\"]) {\n minPort = Number(`${n}${devPort}`) + 100;\n maxPort = minPort + 100;\n if (maxPort < 65000) {\n break;\n }\n }\n\n if (maxPort >= 65000) {\n throw new Error(\"the devPort in package.json should be less than 64000\");\n }\n\n const range = maxPort - minPort + 1;\n const startOffset = Math.floor(Math.random() * range);\n\n const ports = Array.from({ length: range }, (_, i) => {\n return minPort + ((startOffset + i) % range);\n });\n\n const freePort = await ports.reduce(\n async (prevPromise, port) => {\n const freePort = await prevPromise;\n if (freePort) {\n return freePort;\n }\n const isFree = await isPortFree(port);\n return isFree ? port : undefined;\n },\n Promise.resolve(undefined as number | undefined),\n );\n\n if (!freePort) {\n throw new Error(`No free ports found in range ${minPort}-${maxPort}`);\n }\n\n return freePort;\n};\n\nconst isPortFree = (port: number): Promise<boolean> => {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once(\"error\", () => resolve(false));\n\n server.once(\"listening\", () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port, \"127.0.0.1\");\n });\n};\n"],"mappings":"srBAA6Q,IAAIA,EAAE,CAAC,KAAK,SAAS,QAAQ,CAAC,EAAE,KAAK,0BAA0B,QAAQ,QAAQ,OAAO,WAAW,QAAQ,MAAM,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,mBAAmB,QAAQ,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,sBAAsB,EAAE,aAAa,CAAC,gBAAgB,cAAc,eAAe,aAAa,EAAE,gBAAgB,CAAC,iBAAiB,QAAQ,CAAC,EAAE,EAAE;;EAE5mB,EAAE;;EAEF,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmEF,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCF,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuMF,EAAE;;;;;;;;;EASF,EAAE;;;;;;EAMF,EAAE;;;;EAIF,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,MAAM,CAAC,cAAc,aAAa,EAAE,iBAAiB,UAAU,OAAO,SAAS,OAAO,SAAS,OAAO,CAAC,EAAE,2BAA2B,CAAC,EAAE,cAAc,CAAC,EAAE,eAAe,CAAC,EAAE,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,EAAE,eAAe,CAAC,EAAE,mBAAmB,CAAC,EAAE,yBAAyB,CAAC,EAAE,2BAA2B,CAAC,EAAE,qBAAqB,CAAC,EAAE,kBAAkB,CAAC,EAAE,2BAA2B,CAAC,EAAE,2BAA2B,CAAC,EAAE,6BAA6B,CAAC,EAAE,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,EAAE,qBAAqB,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,SAASC,EAAE,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAGA,EAAE,UAAU,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,GAAGA,EAAE,UAAU,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAGA,EAAE,UAAU,KAAK,CAAC,GAAG,EAAE,SAASA,EAAE,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,EAAE,GAAGA,EAAE,OAAO,EAAE,EAAE,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAGA,EAAE,UAAU,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAEC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,oBAAoB,GAAGC,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,MAAMC,EAAE,EAAE,IAAI,kBAAkB,EAAE,KAAK,UAAU,EAAE,EAAE,IAAK,GAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,gBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,IAAI,IAAI,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,MAAMA,EAAE,EAAE,IAAI,eAAe,EAAE,KAAK,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAK,GAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,MAAMA,EAAE,EAAE,IAAI,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,MAAMA,EAAE,EAAE,IAAI,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAMA,EAAE,EAAE,IAAI,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,KAAM,IAAG,CAAC,GAAG,CAAC,aAAa,GAAGC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,KAAK,CAAC,EAAE,GAAGC,EAAE,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,aAAa,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,EAAE,IAAI,YAAY,MAAM,EAAE,EAAE,OAAOC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAEC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,aAAa,CAAC,iBAAiBR,EAAE,gBAAgB,iBAAiB,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,IAAK,GAAE,QAAQ,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,ECnTlsE,EAAO,KAAK,MAChB,EACE,EAAc,YAAY,GAAG,CAAC,CAAC,QAAQ,2BAA2B,EAClE,OACF,CACF,EAEa,GACX,EACA,EACA,IACG,CACH,IAAM,EAAY,EAAa,CAAY,CAAC,CAAC,WAAW,OACtD,EAAQ,EAAM,IAAI,EAClB,YACF,EAEM,EAAgB,KAAO,IAA8B,CAKzD,GAJI,CAAC,GAAO,MAIR,CAAC,EAAM,kBAAoB,CAAC,EAAM,gBAEpC,OAGF,IAAM,EAAO,MAAM,EAAiB,EAAM,aAAc,CACtD,GAAG,CACL,CAAC,EAEI,KAAiB,EAAM,KAAM,CAAI,EAKtC,KAAK,GAAM,CAAC,EAAM,KAAS,OAAO,QAAQ,EAAM,eAAe,EAC7D,GACE,CAAC,EACC,EACA,MAAM,EAAiB,EAAQ,EAAa,KAAM,CAAI,CAAC,CACzD,EAGA,OAIJ,OAAO,CAJH,CAKN,EAEA,MAAO,CACL,MAAM,IAAI,EAA8B,CACtC,GAAI,MAAM,EAAW,CAAS,EAC5B,GAAI,CACF,IAAM,EAAQ,KAAK,MAAM,MAAM,EAAS,EAAW,MAAM,CAAC,EAC1D,OAAO,GAAK,SACR,EAAc,CAAK,EACnB,CACN,MAAa,CAAC,CAGlB,EAEA,MAAM,IAAI,EAAO,CACf,IAAM,EAAO,MAAM,EAAiB,EAAM,aAAc,CACtD,GAAG,CACL,CAAC,EAEK,EAA0C,CAAC,EAEjD,IAAK,IAAM,KAAQ,EAAM,gBACvB,EAGE,EAAK,QAAQ,GAAG,EAAa,KAAK,GAAI,EAAE,GACtC,MAAM,EAAiB,CAAI,EAGjC,IAAM,EAAQ,CAAE,GAAG,EAAO,OAAM,iBAAgB,EAKhD,OAHA,MAAM,EAAM,EAAQ,CAAS,EAAG,CAAE,UAAW,EAAK,CAAC,EACnD,MAAM,EAAU,EAAW,KAAK,UAAU,EAAO,KAAM,CAAC,EAAG,MAAM,EAE1D,CACT,CACF,CACF,EAEM,EAAmB,MACvB,EACA,IACoB,CACpB,IAAI,EACJ,GAAI,CACF,EAAc,MAAM,EAAS,EAAM,MAAM,CAC3C,MAAa,CAEX,MAAO,EACT,CACA,OAAO,EACH,EACE,KAAK,UAAU,CACb,GAAG,GACF,EAAK,cAAe,CACvB,CAAC,CACH,EACA,CACN,EAGM,GAAoB,EAAW,IAC5B,IAAM,ECpGf,EAAe,KACb,IACiC,CACjC,GAAM,CAAE,UAAS,WAAY,EAG7B,IAAK,IAAM,KAAgB,EAAgB,cACzC,IAAK,IAAM,KAAQ,EAAiB,CAAY,EAAG,CACjD,GAAI,CAAC,EAAK,MAAM,MAAQ,OAAO,EAAK,SAAY,WAC9C,MAAU,MACR,GAAG,EAAa,KAAK,iEACvB,EAGF,IAAM,EAAU,EAAK,QAAQ,CAAY,EAEzC,GAAI,CAAC,EAAQ,MAAM,KACjB,MAAU,MACR,GAAG,EAAa,KAAK,IAAI,EAAK,KAAK,KAAK,oCAC1C,EAGF,GAAI,CACF,MAAM,EAAQ,QAAQ,CACxB,OAAS,EAAO,CAOd,MANA,QAAQ,MACN,EACE,MACA,GAAG,EAAa,KAAK,IAAI,EAAK,KAAK,KAAK,gCAC1C,CACF,EACM,CACR,CACF,CAGF,GAAI,IAAY,QAAS,CACvB,IAAK,IAAM,KAAgB,EAAgB,cAAe,CACxD,GAAM,CAAE,cAAe,EAAa,CAAY,EAE1C,EAAiB,CAAC,EAExB,CACE,GAAM,CAAE,aAAc,MAAM,EAAc,EAAc,CAAY,EAE9D,EAAU,EACd,GAAG,EAAa,KAAK,mBACvB,EAEA,IAAK,GAAM,CAAE,OAAM,aAAa,EAAU,OAAO,EAC/C,EAAQ,OACN,KAAK,EAAe,OAAS,EAAE,MAAM,EAAU,KAAK,KAAK,GAC3D,EACA,EAAe,KAAK,MAAM,EAAQ,CAAC,EAGrC,EAAQ,QAAQ,SAAS,CAC3B,CAEA,IAAM,EAAa,EAAiB,CAAY,EAEhD,IAAK,IAAM,KAAa,EACtB,MAAM,EAAU,QAAQ,CAAY,CAAC,CAAC,QAAQ,CAAc,EAG9D,IAAM,EAAU,CACd,EAAY,cAAc,CAAY,EACtC,EAAY,WAAW,CACzB,EAGA,MAAM,EACJ,EAEE,EAAa,OAEb,GAAG,EAAW,KAAK,CAAE,aACZ,EAAQ,CAAY,CAAC,CAAC,SAAS,CAAE,KAAM,SAAU,SAAQ,CAAC,CAClE,EAED,CAEE,KAAM,EAAW,IAAI,EACrB,SAAU,EAAS,EAAc,EAAS,QAAQ,EAClD,UACA,MAAO,CACL,OAAQ,EAAW,QAAQ,QAAQ,EACnC,SAAU,GACV,YAAa,EACf,CACF,CACF,CACF,EAEA,IAAM,EAAe,EAAW,KAAM,GAAM,EAAE,KAAK,OAAS,KAAK,EAGjE,GAAI,EAAc,CAChB,IAAM,EAAM,EAAW,QAAQ,KAAK,EAIpC,MAAM,EACJ,EAEE,EAAa,QAEb,EACG,QAAQ,CAAY,CAAC,CACrB,SAAS,CAAE,KAAM,UAAW,SAAQ,CAAC,EAExC,CACE,KAAM,KACN,KAAM,EAAW,IAAI,EACrB,QAAS,SACT,UACA,QAAS,CACP,WAAY,CAAC,MAAM,CACrB,EACA,MAAO,CACL,IAAK,GACL,OAAQ,SACR,UAAW,GACX,YAAa,GACb,gBAAiB,CACf,MAAO,CACL,EAAW,IAAI,QAAQ,EACvB,EAAW,IAAI,WAAW,CAC5B,EACA,OAAQ,CACN,MACA,OAAQ,KACV,CACF,CACF,EACA,SAAU,EAAS,EAAc,EAAS,SAAS,CACrD,CACF,CACF,CACF,CAEA,IAAK,IAAM,KAAa,EACtB,MAAM,EAAU,QAAQ,CAAY,CAAC,CAAC,YAAY,CAAc,CAEpE,CAEA,OAAO,SAAY,CAAC,CACtB,CAKA,IAAM,EAMF,CAAC,EAEC,EAAkD,CAAC,EAEnD,EAAqE,CAAC,EAG5E,IAAK,IAAM,KAAgB,EAAgB,cACzC,EAAS,EAAa,MAAQ,MAAM,EAAa,CAAY,EAG/D,IAAI,EAAO,MAAM,EAAa,CAAO,EAErC,IAAK,IAAM,KAAgB,EAAgB,cAAe,CACxD,GAAM,CAAE,cAAe,EAAa,CAAY,EAE1C,EAAkB,EAAgB,CAAY,EAE9C,EAAa,EAAiB,CAAY,EAE1C,EAAU,CACd,EAAY,cAAc,CAAY,EACtC,EAAY,WAAW,CACzB,EAGA,CACE,IAAM,EAAa,MAAM,EACvB,EAEE,EAAa,OAEb,GAAG,EAAW,KAAK,CAAE,aACZ,EAAQ,CAAY,CAAC,CAAC,SAAS,CAAE,KAAM,SAAU,SAAQ,CAAC,CAClE,EAED,CAEE,KAAM,EAAW,IAAI,EACrB,SAAU,EAAS,EAAc,EAAS,QAAQ,EAClD,UACA,OAAQ,CACN,KAAM,IACN,eAAgB,GAChB,IAAK,CAAE,KAAM,GAAO,CACtB,CACF,CACF,CACF,EAEA,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAClC,EAAS,EAAa,KACxB,EACE,EAAW,QAAQ,GAAG,EAAK,CAAO,EAGpC,EAAgB,KAAK,CACnB,CAAC,EAAa,OAAO,IAAI,MACnB,EAAgB,SAChB,EAAW,WACnB,CAAC,EAED,EAAiB,KAAK,EAAW,KAAK,CACxC,CAEA,IAAM,EAAe,EAAW,KAAM,GAAM,EAAE,KAAK,OAAS,KAAK,EAGjE,GAAI,EAAc,CAGhB,IAAM,EAAa,MAAM,EACvB,EAEE,EAAa,QAEb,EACG,QAAQ,CAAY,CAAC,CACrB,SAAS,CAAE,KAAM,UAAW,SAAQ,CAAC,EAExC,CACE,KAAM,EAAW,IAAI,EACrB,QAAS,SACT,SAAU,EAAS,EAAc,EAAS,SAAS,EACnD,UACA,OAAQ,CACN,KAAM,IACN,eAAgB,GAChB,IAAK,CAAE,KAAM,GAAO,CACtB,EACA,QAAS,CACP,WAAY,CAAC,MAAM,CACrB,EACA,aAAc,CACZ,IAAK,CACH,QAAS,CACP,WAAY,CAAC,MAAM,CACrB,CACF,CACF,CACF,CACF,CACF,EAEM,EAAM,EAAW,aAAa,IAE9B,EAAe,UACnB,EAAI,OAAO,WAAW,EACf,EAAI,OACR,OAA8B,EAAK,EAAS,OAAQ,QAAQ,CAAC,CAAC,CAC9D,KAAM,GAAM,EAAE,OAAO,GAGtB,EAAW,MAAM,EAAa,EAElC,IAAK,GAAM,CAAC,EAAK,KAAY,OAAO,QAClC,EAAS,EAAa,KACxB,EACE,EAAW,QAAQ,GAAG,EAAK,KAAO,IAAS,CAC5B,EAAI,YAAY,iBAAiB,CAC1C,CAAA,EAAM,OACR,MAAM,EAAQ,CAAI,EAClB,MAAM,GAAU,kBAAkB,EAClC,EAAW,MAAM,EAAa,EAElC,CAAC,EAGH,EAAgB,KAAK,CACnB,CAAC,EAAa,OAAO,KAAM,EAAa,OAAO,OAAO,MAChD,EAAS,gBAAkB,EAAgB,QAC3C,EAAS,eAAe,CAChC,CAAC,EAED,EAAiB,KAAK,EAAW,KAAK,CACxC,CACF,CAeA,IAAM,GAAwB,CAC5B,KACsC,CACtC,GAAM,CAAC,EAAM,GAAO,EAMd,EAAS,EAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,OAC/C,OAAO,EAAM,EAAS,EAAI,CAC5B,EAEM,EAAW,EAAgB,MAC9B,EAAG,IAAM,EAAqB,CAAC,EAAI,EAAqB,CAAC,CAC5D,EAEM,EAAa,EAAK,cAAc,EAAK,IAAQ,CACjD,IAAK,GAAM,EAAG,EAAgB,KAAmB,EAAU,CAEzD,GAAM,CAAC,EAAS,GAAW,CAAC,EAAe,EAAG,EAAe,CAAC,EAC9D,GAAI,EAAQ,CAAG,EAAG,CAChB,EAAQ,EAAK,CAAG,EAChB,MACF,CACF,CACA,EAAI,UAAU,IAAK,CAAE,eAAgB,WAAY,CAAC,EAClD,EAAI,IAAI,yBAAyB,CACnC,CAAC,EAgBD,OAdA,EAAW,GAAG,QAAU,GAAU,CAChC,QAAQ,MACN,EAAU,MAAO,sCAAsC,GAAS,CAClE,EACA,QAAQ,MAAM,EAAM,OAAO,EAC3B,QAAQ,KAAK,CAAC,CAChB,CAAC,EAED,EAAW,OAAO,CAAO,EAEzB,EAAiB,KAAK,SAAY,CAChC,EAAW,MAAM,CACnB,CAAC,EAEM,SAAY,CACjB,IAAK,IAAM,KAAW,EACpB,MAAM,EAAQ,EAGhB,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,GAAG,CAAC,CACzD,CACF,EAEM,GACJ,CAAE,OAAM,QACR,EACA,IAEO,EAAQ,EAAM,aAAa,EAAK,GAAG,EAAQ,GAAG,GAAM,EAGvD,EAAoB,GAAqD,CAC7E,GAAM,CAAE,aAAa,CAAC,GAAM,EAAa,OAEnC,EAEF,CAAC,EAEC,EAAuC,CAAC,EAE9C,IAAK,IAAM,KAAQ,EACb,EAAK,KAAK,KACZ,EAAe,EAAK,KAAK,MAAQ,EAEjC,EAAe,KAAK,CAAI,EAI5B,MAAO,CAEL,EAAc,EAEd,GAAI,EAAe,IAAM,CAAC,EAAe,GAAG,EAAI,CAAC,EAEjD,GAAI,EAAe,OAAS,EAAe,IACvC,CAAC,EAAe,KAAK,EACrB,CAAC,EAEL,GAAG,EAEH,GAAI,EAAe,IAAM,CAAC,EAAe,GAAG,EAAI,CAAC,EAEjD,GAAI,EAAe,IAAM,CAAC,EAAe,GAAG,EAAI,CAAC,CACnD,CACF,EAEM,EAAe,KACnB,IAGG,CACH,GAAM,CAAE,YAAW,oBAAqB,MAAM,EAC5C,EACA,CACF,EAEM,CAAE,cAAe,EAAa,CAAY,EAE1C,EAGD,CAAC,EAEN,IAAK,IAAM,KAAQ,EAAiB,CAAY,EAAG,CACjD,IAAM,EAAU,EAAK,QAAQ,CAAY,EACzC,EAAW,KAAK,CAAE,KAAM,EAAK,KAAK,KAAM,SAAQ,CAAC,CACnD,CAEA,IAAM,EAAiB,IAAI,IAKrB,EAAgB,KAAO,IAAyB,CAKpD,IAAM,EAAU,MAAM,KAAK,EAAe,OAAO,CAAC,EAElD,IAAK,GAAM,CAAE,OAAM,aAAa,EAC9B,GAAI,CACF,MAAM,EAAQ,QAAQ,EAAS,CAAK,CACtC,OAAS,EAAO,CACd,QAAQ,MACN,EAAU,MAAO,GAAG,EAAa,KAAK,IAAI,EAAK,kBAAkB,CACnE,EACI,GACF,QAAQ,MAAM,CAAK,EAErB,QAAQ,MAAM,CAAK,CACrB,CAEJ,EAEM,EAAsB,KAAO,IAAiB,CAClD,IAAM,EAAW,EAAU,IAAI,CAAI,EAE9B,KAIL,GAAI,CACF,IAAM,EAAgB,MAAM,EAAS,QAAQ,CAAI,EAEjD,OADA,EAAe,IAAI,EAAc,MAAM,aAAc,CAAa,EAC3D,CACT,OAAS,EAAO,CACd,IAAM,EAAQ,EAAK,QAAQ,GAAG,EAAW,IAAI,EAAE,GAAI,EAAE,EACrD,QAAQ,MACN,EACE,MACA,GAAG,EAAa,KAAK,IAAI,EAAM,yBACjC,CACF,EACA,QAAQ,MAAM,CAAK,EACnB,MACF,CACF,EAEA,CACE,IAAM,EAAU,EAAe,GAAG,EAAa,KAAK,mBAAmB,EACvE,IAAK,GAAM,CAAE,OAAM,aAAa,EAAU,OAAO,EAAG,CAClD,EAAQ,OACN,KAAK,EAAe,KAAO,EAAE,MAAM,EAAU,KAAK,KAAK,GACzD,EACA,IAAM,EAAQ,MAAM,EAAQ,EAC5B,EAAe,IAAI,EAAM,MAAM,aAAc,CAAK,CACpD,CACA,EAAQ,QAAQ,SAAS,CAC3B,CAKA,OAFA,MAAM,EAAc,EAEb,CACL,MAAM,IAAI,EAAc,CACtB,GAAM,CAAC,GAAY,EAAiB,CAAC,CAAI,CAAC,CAAC,CAAC,OAAO,EAE9C,IAIL,EAAU,IAAI,EAAM,CAAQ,EAKxB,MAFwB,EAAoB,CAAI,GAGlD,MAAM,EAAc,CAAE,KAAM,SAAU,MAAK,CAAC,EAEhD,EAEA,MAAM,OAAO,EAAc,CACzB,GAAI,EAAe,IAAI,CAAI,EAEzB,MAAM,EAAoB,CAAI,MACzB,CAEL,IAAM,EAAgB,EACnB,OAAO,CAAC,CACR,SAAS,CAAE,OAAM,WACT,IAAS,YACZ,EAAM,gBAAgB,SAAS,CAAI,EACjC,CAAC,CAAK,EACN,CAAC,CAER,EAEH,IAAK,IAAM,KAAS,EAClB,MAAM,EAAoB,EAAM,YAAY,CAEhD,CAEA,MAAM,EAAc,CAAE,KAAM,SAAU,MAAK,CAAC,CAC9C,EAEA,MAAM,OAAO,EAAM,CAEjB,EAAU,OAAO,CAAI,EACrB,EAAe,OAAO,CAAI,EAC1B,MAAM,EAAc,CAAE,KAAM,SAAU,MAAK,CAAC,CAC9C,CACF,CACF,EAEM,GAE4D,CAChE,YACI,CACJ,IAAM,EAAkB,OAAO,IAAI,EAAO,KAAK,OAAO,EAChD,EAAiB,OAAO,IAAI,EAAK,EAAO,KAAM,EAAO,OAAO,EAAE,OAAO,EAC3E,MAAO,CACL,KAAK,EAAK,CACR,MAAO,GAAW,KAAK,EAAI,GAAa,GAEpC,EAAY,KAAK,EAAI,GAAa,CACxC,EACA,IAAI,EAAK,CACP,OAAO,EAAW,KAAK,EAAI,GAAa,CAC1C,CACF,CACF,EAEM,EAAe,KAAO,IAAqC,CAC/D,IAAI,EAAU,EACV,EAAU,EAEd,IAAK,IAAM,IAAK,CAAC,EAAG,EAAG,EAAG,EAAE,EAG1B,GAFA,EAAU,OAAO,GAAG,IAAI,GAAS,EAAI,IACrC,EAAU,EAAU,IAChB,EAAU,KACZ,MAIJ,GAAI,GAAW,KACb,MAAU,MAAM,uDAAuD,EAGzE,IAAM,EAAQ,EAAU,EAAU,EAC5B,EAAc,KAAK,MAAM,KAAK,OAAO,EAAI,CAAK,EAM9C,EAAW,MAJH,MAAM,KAAK,CAAE,OAAQ,CAAM,GAAI,EAAG,IACvC,GAAY,EAAc,GAAK,CAGjB,CAAA,CAAM,OAC3B,MAAO,EAAa,IAEd,MADmB,IAKhB,MADc,EAAW,CAAI,EACpB,EAAO,IAAA,IAEzB,QAAQ,QAAQ,IAAA,EAA+B,CACjD,EAEA,GAAI,CAAC,EACH,MAAU,MAAM,gCAAgC,EAAQ,GAAG,GAAS,EAGtE,OAAO,CACT,EAEM,EAAc,GACX,IAAI,QAAS,GAAY,CAC9B,IAAM,EAAS,EAAI,aAAa,EAEhC,EAAO,KAAK,YAAe,EAAQ,EAAK,CAAC,EAEzC,EAAO,KAAK,gBAAmB,CAC7B,EAAO,MAAM,EACb,EAAQ,EAAI,CACd,CAAC,EAED,EAAO,OAAO,EAAM,WAAW,CACjC,CAAC"}
1
+ {"version":3,"file":"chassis.js","names":["l","t","n","o","c","s","i","r","u","a","e"],"sources":["../../../generators/core-generator/pkg/index.js","../src/cache.ts","../src/chassis.ts"],"sourcesContent":["import{defineGenerator as e,defineGeneratorFactory as t,pathResolver as n,renderFactory as r,renderToFile as i}from\"@kosmojs/lib\";import{dirname as a,resolve as o}from\"node:path\";import{styleText as s}from\"node:util\";import c from\"semver\";import{defaults as l}from\"@kosmojs/core\";import{routeRenderHelpers as u}from\"@kosmojs/core/generators\";var d={type:`module`,private:!0,name:`@kosmojs/core-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{\".\":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{\"@kosmojs/core\":`workspace:^`,\"@kosmojs/lib\":`workspace:^`,semver:`^7.8.5`},devDependencies:{\"@types/semver\":`^7.8.0`,\"path-to-regexp\":`^8.4.2`}},f=`export const base = \"{{config.base}}\";\nexport const apiBase = \"{{config.apiBase}}\";\n`,p=`export * from \"./config\";\nexport * from \"./routeMap\";\n`,m=`import { compile } from \"path-to-regexp\";\n\nimport type { PathMapperSignature } from \"@kosmojs/core\";\nimport { createHost, join, stringify } from \"@kosmojs/core/fetch\";\n\nexport const pathMapper = <ParamsT extends readonly unknown[]>(\n basePath: string,\n routeName: string,\n pathPattern: string,\n paramsMap: Array<[name: string, kind: string]>,\n numericParams: Array<string>,\n): PathMapperSignature<ParamsT> => {\n const toPath = compile(pathPattern);\n\n const castParam = (name: string, value: unknown) => {\n if (numericParams.includes(name)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : String(value);\n }\n return String(value);\n };\n\n const paramsMapper: PathMapperSignature<ParamsT>[\"paramsMapper\"] = (\n params,\n ) => {\n return paramsMap.reduce<Record<string, unknown>>((map, [name, kind], i) => {\n if (kind === \"splat\") {\n if (Array.isArray(params[i]) && params[i].length) {\n map[name] = params[i].map((v) => castParam(name, v));\n }\n } else if (params[i] !== undefined) {\n map[name] = castParam(name, params[i]);\n }\n return map;\n }, {});\n };\n\n const parametrize: PathMapperSignature<ParamsT>[\"parametrize\"] = (params) => {\n try {\n return toPath(paramsMapper(params) as never);\n } catch (error) {\n console.error(\\`❗ERROR: Failed building path for \\${routeName}\\`);\n throw error;\n }\n };\n\n const base: PathMapperSignature<ParamsT>[\"base\"] = (params, query) => {\n const path = join(\"/\", parametrize(params));\n return query ? [path, stringify(query)].join(\"?\") : path;\n };\n\n const path: PathMapperSignature<ParamsT>[\"path\"] = (params, query) => {\n return join(basePath, base(params, query));\n };\n\n const href: PathMapperSignature<ParamsT>[\"href\"] = (host, params, query) => {\n return createHost(host) + path(params, query);\n };\n\n return {\n paramsMapper,\n parametrize,\n base,\n path,\n href,\n };\n};\n`,h=`{{> pathMapper}}\n\nimport { base, apiBase } from \"./config\";\n\n{{#if pageRoutes.length}}\nexport type LinkProps =\n {{#each pageRoutes}}\n | [ \"{{name}}\", {{serializeParamsTupleElements .}} ]\n {{/each}};\n{{else}}\nexport type LinkProps = never;\n{{/if}}\n\nexport const apiRouteMap = {\n {{#each apiRoutes}}\n \"{{name}}\": pathMapper<[{{serializeParamsTupleElements .}}]>(\n apiBase,\n \"{{name}}\",\n \"{{pathPattern}}\",\n [{{#each params.schema}}[\"{{name}}\", \"{{kind}}\"], {{/each}}],\n [{{#each numericParams}}\"{{.}}\", {{/each}}],\n ),\n {{/each}}\n};\n\nexport const pageRouteMap = {\n {{#each pageRoutes}}\n \"{{name}}\": pathMapper<[{{serializeParamsTupleElements .}}]>(\n base,\n \"{{name}}\",\n \"{{pathPattern}}\",\n [{{#each params.schema}}[\"{{name}}\", \"{{kind}}\"], {{/each}}],\n [{{#each numericParams}}\"{{.}}\", {{/each}}],\n ),\n {{/each}}\n};\n`,g=`declare const KOSMO_PRODUCTION_BUILD: boolean;\n\n/**\n * Enhances base TypeScript types with JSON Schema validation constraints.\n * Allows declaring refined types that carry validation metadata for runtime\n * schema validation while maintaining full TypeScript type safety.\n *\n * Useful for generating validation schemas and ensuring\n * data conforms to specific business rules beyond basic type checking.\n * */\ndeclare type VRefine<\n T extends unknown[] | number | string | object,\n _ extends T extends unknown[]\n ? TArrayOptions\n : T extends number\n ? TNumberOptions\n : T extends string\n ? TStringOptions\n : TObjectOptions,\n> = T;\n\n/**\n * Type definitions inspired by and gently adapted from TypeBox.\n * Original TypeBox created by sinclairzx81: https://github.com/sinclairzx81/typebox\n * TypeBox is licensed under MIT: https://github.com/sinclairzx81/typebox/blob/main/license\n *\n * These types provide JSON Schema compatible type refinements for TypeScript.\n * */\ninterface TSchema {}\n\n// ------------------------------------------------------------------\n// ObjectOptions\n// ------------------------------------------------------------------\ninterface TObjectOptions {\n /**\n * Defines whether additional properties are allowed beyond those explicitly defined in \\`properties\\`.\n */\n additionalProperties?: TSchema | boolean;\n /**\n * The minimum number of properties required in the object.\n */\n minProperties?: number;\n /**\n * The maximum number of properties allowed in the object.\n */\n maxProperties?: number;\n /**\n * Defines conditional requirements for properties.\n */\n dependencies?: Record<string, boolean | TSchema | string[]>;\n /**\n * Specifies properties that *must* be present if a given property is present.\n */\n dependentRequired?: Record<string, string[]>;\n /**\n * Defines schemas that apply if a specific property is present.\n */\n dependentSchemas?: Record<string, TSchema>;\n /**\n * Maps regular expressions to schemas properties matching a pattern must validate against the schema.\n */\n patternProperties?: Record<string, TSchema>;\n /**\n * A schema that all property names within the object must validate against.\n */\n propertyNames?: TSchema;\n}\n\n// ------------------------------------------------------------------\n// ArrayOptions\n// ------------------------------------------------------------------\ninterface TArrayOptions {\n /**\n * The minimum number of items allowed in the array.\n */\n minItems?: number;\n /**\n * The maximum number of items allowed in the array.\n */\n maxItems?: number;\n /**\n * A schema that at least one item in the array must validate against.\n */\n contains?: TSchema;\n /**\n * The minimum number of array items that must validate against the \\`contains\\` schema.\n */\n minContains?: number;\n /**\n * The maximum number of array items that may validate against the \\`contains\\` schema.\n */\n maxContains?: number;\n /**\n * An array of schemas, where each schema in \\`prefixItems\\` validates against items at corresponding positions from the beginning of the array.\n */\n prefixItems?: TSchema[];\n /**\n * If \\`true\\`, all items in the array must be unique.\n */\n uniqueItems?: boolean;\n}\n\n// ------------------------------------------------------------------\n// NumberOptions\n// ------------------------------------------------------------------\ninterface TNumberOptions {\n /**\n * Specifies an exclusive upper limit for the number (number must be less than this value).\n */\n exclusiveMaximum?: number | bigint;\n /**\n * Specifies an exclusive lower limit for the number (number must be greater than this value).\n */\n exclusiveMinimum?: number | bigint;\n /**\n * Specifies an inclusive upper limit for the number (number must be less than or equal to this value).\n */\n maximum?: number | bigint;\n /**\n * Specifies an inclusive lower limit for the number (number must be greater than or equal to this value).\n */\n minimum?: number | bigint;\n /**\n * Specifies that the number must be a multiple of this value.\n */\n multipleOf?: number | bigint;\n}\n\n// ------------------------------------------------------------------\n// StringOptions\n// ------------------------------------------------------------------\ntype TFormat =\n | \"date-time\"\n | \"date\"\n | \"duration\"\n | \"email\"\n | \"hostname\"\n | \"idn-email\"\n | \"idn-hostname\"\n | \"ipv4\"\n | \"ipv6\"\n | \"iri-reference\"\n | \"iri\"\n | \"json-pointer-uri-fragment\"\n | \"json-pointer\"\n | \"json-string\"\n | \"regex\"\n | \"relative-json-pointer\"\n | \"time\"\n | \"uri-reference\"\n | \"uri-template\"\n | \"url\"\n | \"uuid\";\n\ninterface TStringOptions {\n /**\n * Specifies the expected string format.\n *\n * Common values include:\n * - \\`base64\\` – Base64-encoded string.\n * - \\`date-time\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date-time format.\n * - \\`date\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date (YYYY-MM-DD).\n * - \\`duration\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) duration format.\n * - \\`email\\` – RFC 5321/5322 compliant email address.\n * - \\`hostname\\` – RFC 1034/1035 compliant host name.\n * - \\`idn-email\\` – Internationalized email address.\n * - \\`idn-hostname\\` – Internationalized host name.\n * - \\`ipv4\\` – IPv4 address.\n * - \\`ipv6\\` – IPv6 address.\n * - \\`iri\\` / \\`iri-reference\\` – Internationalized Resource Identifier.\n * - \\`json-pointer\\` / \\`json-pointer-uri-fragment\\` – JSON Pointer format.\n * - \\`json-string\\` – String containing valid JSON.\n * - \\`regex\\` – Regular expression syntax.\n * - \\`relative-json-pointer\\` – Relative JSON Pointer format.\n * - \\`time\\` – [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) time (HH:MM:SS).\n * - \\`uri-reference\\` / \\`uri-template\\` – URI reference or template.\n * - \\`url\\` – Web URL format.\n * - \\`uuid\\` – RFC 4122 UUID string.\n *\n * May also be a custom format string.\n */\n format?: TFormat;\n /**\n * Specifies the minimum number of characters allowed in the string.\n * Must be a non-negative integer.\n */\n minLength?: number;\n /**\n * Specifies the maximum number of characters allowed in the string.\n * Must be a non-negative integer.\n */\n maxLength?: number;\n /**\n * Specifies a regular expression pattern that the string value must match.\n * Can be provided as a string (ECMA-262 regex syntax) or a \\`RegExp\\` object.\n */\n pattern?: string | RegExp;\n}\n`,_=`# Ignore all files\n*\n\n# But don't ignore directories (so Git can traverse them)\n!*/\n\n# And don't ignore these files at any depth\n!cache.json\n!types.ts\n`,v=`export declare global {\n interface Window {\n __KOSMO_HYDRATION_BOOL__: boolean;\n __KOSMO_HYDRATION_DATA__: Record<string, unknown> | undefined;\n }\n}\n`,y=`// stub schemas, specialized generators supposed to overwrite this file\nimport type { ValidationSchemas } from \"@kosmojs/core/api\";\nexport type { ValidationSchemas };\nexport const validationSchemas: ValidationSchemas = {};\n`,b=e=>{let t=\"${configDir}\",n={types:[`@types/node`,`vite/client`],moduleResolution:`bundler`,module:`ESNext`,target:`ESNext`,strict:!0,exactOptionalPropertyTypes:!0,noImplicitAny:!0,noImplicitThis:!0,noImplicitOverride:!0,noImplicitReturns:!0,noUnusedLocals:!1,noUnusedParameters:!1,allowArbitraryExtensions:!0,allowImportingTsExtensions:!0,allowUnreachableCode:!1,allowUnusedLabels:!1,useUnknownInCatchVariables:!0,noFallthroughCasesInSwitch:!0,noUncheckedSideEffectImports:!0,resolveJsonModule:!0,esModuleInterop:!0,verbatimModuleSyntax:!0,skipLibCheck:!0,noEmit:!0};return e?{include:[`${t}/`,`${t}/../../${l.libDir}/${e}/`,`${t}/../../**/*.d.ts`],compilerOptions:{...n,types:[...n.types],paths:{[`${l.appPrefix}/*`]:[`${t}/../../*`],[`${l.srcPrefix}/*`]:[`${t}/*`],[`${l.libPrefix}/*`]:[`${t}/../../${l.libDir}/${e}/*`]}}}:{include:[`${t}/`],exclude:[`${t}/${l.srcDir}/`],compilerOptions:{...n,paths:{[`${l.appPrefix}/*`]:[`${t}/*`]}}}},x=t(e=>{let{createPath:t,createImportHelpers:d}=n(e),x=async()=>{let{generators:n=[]}=e.config;{let{dependencies:t={},devDependencies:r={}}=await import(o(e.root,`package.json`),{with:{type:`json`}}).then(e=>e.default),i=[],a=[],l=n.flatMap(e=>[`dependencies`,`devDependencies`].flatMap(t=>e[t]?Object.entries(typeof e[t]==`function`?e[t](e.options):e[t]).flatMap(([e,n])=>{let r=c.minVersion(n)?.version;return r?[[e,r,t]]:[]}):[]));for(let[e,n,o]of l){let s=t[e]||r[e],l=s?c.minVersion(s)?.version:void 0;!s||!l?i.push([e,n,o]):c.lt(l,n)&&a.push([e,n,o])}if(i.length){console.error(s([`red`,`italic`],`✗ There are ${i.length} missing dependencies, please consider installing them.`));for(let e of[`dependencies`,`devDependencies`]){let t=i.filter(t=>t[2]===e);t.length&&console.error(`${e}: ${s([`blue`],t.map(([e])=>e).join(` `))}`)}}a.length&&(console.error(s([`blue`,`italic`],`! There are ${a.length} outdated dependencies, please consider updating them:`)),console.error(s([`blue`],`${a.map(([e])=>e).join(` `)}`)))}{await i(o(e.root,`tsconfig.json`),JSON.stringify({extends:`./${l.libDir}/tsconfig.json`},void 0,2),{},{overwrite:!1}),await i(t.lib(`../tsconfig.json`),JSON.stringify(b(),void 0,2),{}),await i(t.src(`tsconfig.json`),JSON.stringify({extends:`../../${l.libDir}/${e.name}/tsconfig.json`},void 0,2),{},{overwrite:!1});let n=b(e.name),r={},a=new Set(n.compilerOptions.types||[]);for(let{meta:t}of e.config.generators||[]){t.jsx&&(r.jsx=t.jsx),t.jsxImportSource&&(r.jsxImportSource=t.jsxImportSource);for(let e of t.types||[])a.add(e)}await i(t.lib(`tsconfig.json`),JSON.stringify({...n,compilerOptions:{...n.compilerOptions,...r,types:[...a.values()]}},void 0,2),{})}for(let[e,n]of[[`env.d.ts`,g],[`global.d.ts`,v]])await i(t.lib(`../${e}`),n,{});await i(t.lib(`../.gitignore`),_,{},{overwrite:!1});for(let[e,n]of[[`ssg.ts`,`export default [];`]])await i(t.lib(e),n,{})},S=async n=>{let{renderToFile:i}=r({helpers:{...d({origin:`lib`}),...u()},partials:{pathMapper:m}});await i(t.libCore(`routeMap.ts`),h,{apiRoutes:n.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),pageRoutes:n.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[])});for(let[n,r]of[[`config.ts`,f],[`index.ts`,p]])await i(t.libCore(n),r,e);for(let{kind:e,entry:r}of n)e===`apiRoute`&&await i(t.libApi(a(r.file),`schemas.ts`),y,{route:r},{overwrite:!1})};return{start:x,watch:S,build:S}}),S=e({meta:{name:`Core`},dependencies:{\"path-to-regexp\":d.devDependencies[`path-to-regexp`]},factory:x});export{S as default};\n//# sourceMappingURL=index.js.map","import { readFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\n\nimport type {\n RouteResolverCache,\n RouteResolverCacheFactory,\n} from \"@kosmojs/core\";\nimport { pathExists, pathResolver } from \"@kosmojs/lib\";\n\n/**\n * Read the installed package.json at runtime to get the actual version.\n * A static `import ... with { type: \"json\" }` would be inlined by the\n * bundler with the pre-bump version, defeating the point.\n * */\nconst self = JSON.parse(\n readFileSync(\n createRequire(import.meta.url).resolve(\"@kosmojs/dev/package.json\"),\n \"utf-8\",\n ),\n);\n\nexport const cacheFactory: RouteResolverCacheFactory = (\n route,\n sourceFolder,\n extraContext,\n) => {\n const cacheFile = pathResolver(sourceFolder).createPath.libApi(\n dirname(route.file),\n \"cache.json\",\n );\n\n const validateCache = async (cache: RouteResolverCache) => {\n if (!cache?.hash) {\n return;\n }\n\n if (!cache.typeDeclarations || !cache.referencedFiles) {\n // incomplete cache\n return;\n }\n\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n if (!identicalHashSum(cache.hash, hash)) {\n // route itself updated\n return;\n }\n\n for (const [file, hash] of Object.entries(cache.referencedFiles)) {\n if (\n !identicalHashSum(\n hash,\n await generateFileHash(resolve(sourceFolder.root, file)),\n )\n ) {\n // some referenced file updated\n return;\n }\n }\n\n return cache;\n };\n\n return {\n async get(opt?: { validate?: boolean }) {\n if (await pathExists(cacheFile)) {\n try {\n const cache = JSON.parse(await readFile(cacheFile, \"utf8\"));\n return opt?.validate //\n ? validateCache(cache)\n : cache;\n } catch (_e) {}\n }\n return undefined;\n },\n\n async set(cache) {\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n const referencedFiles: Record<string, number> = {};\n\n for (const file of cache.referencedFiles) {\n referencedFiles[\n // Strip project root to ensure cached paths are relative\n // and portable across environments (CI, local, etc.)\n file.replace(`${sourceFolder.root}/`, \"\")\n ] = await generateFileHash(file);\n }\n\n const value = { ...cache, hash, referencedFiles };\n\n await mkdir(dirname(cacheFile), { recursive: true });\n await writeFile(cacheFile, JSON.stringify(value, null, 2), \"utf8\");\n\n return value;\n },\n };\n};\n\nconst generateFileHash = async (\n file: string,\n extraContext?: object,\n): Promise<number> => {\n let fileContent: string | undefined;\n try {\n fileContent = await readFile(file, \"utf8\");\n } catch (_e) {\n // file could be deleted since last build\n return 0;\n }\n return fileContent\n ? crc(\n JSON.stringify({\n ...extraContext,\n [self.cacheVersion]: fileContent,\n }),\n )\n : 0;\n};\n\n// return true if sums are identical\nconst identicalHashSum = (a: number, b: number) => {\n return a === b;\n};\n","import http, { type IncomingMessage, type ServerResponse } from \"node:http\";\nimport net from \"node:net\";\nimport { join, resolve } from \"node:path\";\nimport { styleText } from \"node:util\";\n\nimport { build, createServer, type RunnableDevEnvironment } from \"vite\";\n\nimport {\n defaults,\n type GeneratorFactory,\n type GeneratorMeta,\n type GeneratorSignature,\n type ProjectSettings,\n type ResolvedEntry,\n type SourceFolder,\n type WatcherEvent,\n} from \"@kosmojs/core\";\nimport type { DevSetup } from \"@kosmojs/core/api\";\nimport {\n mergeConfigs,\n pathResolver,\n routesFactory,\n spinnerFactory,\n vitePlugins,\n} from \"@kosmojs/lib\";\n\nimport coreGenerator from \"@kosmojs/core-generator\";\n\nimport { cacheFactory } from \"./cache\";\n\nexport default async (\n projectSettings: ProjectSettings,\n): Promise<() => Promise<void>> => {\n const { devPort, command } = projectSettings;\n\n // NOTE: initialize generators before anything else, regardless command\n for (const sourceFolder of projectSettings.sourceFolders) {\n for (const generator of folderGenerators(sourceFolder)) {\n if (!generator.meta?.name || typeof generator.factory !== \"function\") {\n throw new Error(\n `${sourceFolder.name}: Unrecognized generator - must be created via defineGenerator()`,\n );\n }\n\n try {\n await generator.factory(sourceFolder).start?.();\n } catch (error) {\n console.error(\n styleText(\n \"red\",\n `${sourceFolder.name}: ${generator.meta.name} generator failed to initialize`,\n ),\n );\n throw error;\n }\n }\n }\n\n if (command === \"build\") {\n for (const sourceFolder of projectSettings.sourceFolders) {\n const { createPath } = pathResolver(sourceFolder);\n\n const resolvedRoutes = [];\n\n {\n const { resolvers } = await routesFactory(sourceFolder, cacheFactory);\n\n const spinner = spinnerFactory(\n `${sourceFolder.name}: resolving routes`,\n );\n\n for (const { name, handler } of resolvers.values()) {\n spinner.append(\n `[ ${resolvedRoutes.length + 1} of ${resolvers.size} ] ${name}`,\n );\n resolvedRoutes.push(await handler());\n }\n\n spinner.succeed(\"ready ✨\");\n }\n\n const generators = folderGenerators(sourceFolder);\n\n for (const generator of generators) {\n await generator.factory(sourceFolder).build?.(resolvedRoutes);\n }\n\n const plugins = [\n vitePlugins.tsconfigPaths(sourceFolder),\n vitePlugins.nodePrefix(),\n ];\n\n // INFO: === build client ===\n await build(\n mergeConfigs(\n // user-provided config - lowest priority\n sourceFolder.config,\n // generators configs - higher priority\n ...generators.map(({ factory }) => {\n return factory(sourceFolder).config?.({ kind: \"client\", command });\n }),\n // main config - highest priority\n {\n // base provided by sourceFolder.config\n root: createPath.src(),\n cacheDir: cacheDir(sourceFolder, command, \"client\"),\n plugins,\n build: {\n outDir: createPath.distDir(\"client\"),\n manifest: true,\n emptyOutDir: true,\n },\n },\n ),\n );\n\n const apiGenerator = generators.find((e) => e.meta.slot === \"backend\");\n\n // INFO: === build backend ===\n if (apiGenerator) {\n const dir = createPath.distDir(\"api\");\n\n // NOTE: sourceFolder.config is client-specific config - not using for backend!\n // To provide backend-specific config pass it as api generator options.\n await build(\n mergeConfigs(\n // user-provided config - lowest priority\n apiGenerator.options,\n // generator config - higher priority\n apiGenerator\n .factory(sourceFolder)\n .config?.({ kind: \"backend\", command }),\n // main config - highest priority\n {\n base: \"./\",\n root: createPath.src(),\n appType: \"custom\",\n plugins,\n resolve: {\n conditions: [\"node\"],\n },\n build: {\n ssr: true,\n target: \"esnext\",\n sourcemap: true,\n emptyOutDir: true,\n rolldownOptions: {\n input: [\n createPath.api(\"app.ts\"),\n createPath.api(\"server.ts\"),\n ],\n output: {\n dir,\n format: \"esm\",\n },\n },\n },\n cacheDir: cacheDir(sourceFolder, command, \"backend\"),\n },\n ),\n );\n }\n\n for (const generator of generators) {\n await generator.factory(sourceFolder).postBuild?.(resolvedRoutes);\n }\n }\n\n return async () => {};\n }\n\n type RequestMatcher = (req: IncomingMessage) => boolean;\n type RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;\n\n const requestHandlers: Array<\n [\n segments: [base: string, api?: string],\n matcherFactory: () => RequestMatcher,\n handlerFactory: () => RequestHandler,\n ]\n > = [];\n\n const teardownHandlers: Array<() => Promise<unknown>> = [];\n\n const eventMap: Record<string, Awaited<ReturnType<typeof eventFactory>>> = {};\n\n // WARN: call this before starting any server!\n for (const sourceFolder of projectSettings.sourceFolders) {\n eventMap[sourceFolder.name] = await eventFactory(sourceFolder);\n }\n\n let port = await findFreePort(devPort);\n\n for (const sourceFolder of projectSettings.sourceFolders) {\n const { createPath } = pathResolver(sourceFolder);\n\n const requestMatchers = matchersFactory(sourceFolder);\n\n const generators = folderGenerators(sourceFolder);\n\n const plugins = [\n vitePlugins.tsconfigPaths(sourceFolder),\n vitePlugins.nodePrefix(),\n ];\n\n // INFO: === start client server ===\n {\n const viteServer = await createServer(\n mergeConfigs(\n // user-provided config - lowest priority\n sourceFolder.config,\n // generators configs - higher priority\n ...generators.map(({ factory }) => {\n return factory(sourceFolder).config?.({ kind: \"client\", command });\n }),\n // main config - highest priority\n {\n // base provided by sourceFolder.config\n root: createPath.src(),\n cacheDir: cacheDir(sourceFolder, command, \"client\"),\n plugins,\n server: {\n port: port++,\n middlewareMode: true,\n hmr: { port: port++ },\n },\n },\n ),\n );\n\n for (const [evt, handler] of Object.entries(\n eventMap[sourceFolder.name],\n )) {\n viteServer.watcher.on(evt, handler);\n }\n\n requestHandlers.push([\n [sourceFolder.config.base],\n () => requestMatchers.base,\n () => viteServer.middlewares,\n ]);\n\n teardownHandlers.push(viteServer.close);\n }\n\n const apiGenerator = generators.find((e) => e.meta.slot === \"backend\");\n\n // INFO: === start backend server ===\n if (apiGenerator) {\n // NOTE: sourceFolder.config is client-specific config - not using for backend!\n // To provide backend-specific config pass it as api generator options.\n const viteServer = await createServer(\n mergeConfigs(\n // user-provided config - lowest priority\n apiGenerator.options,\n // generator config - higher priority\n apiGenerator\n .factory(sourceFolder)\n .config?.({ kind: \"backend\", command }),\n // main config - highest priority\n {\n root: createPath.src(),\n appType: \"custom\",\n cacheDir: cacheDir(sourceFolder, command, \"backend\"),\n plugins,\n server: {\n port: port++,\n middlewareMode: true,\n hmr: { port: port++ },\n },\n resolve: {\n conditions: [\"node\"],\n },\n environments: {\n api: {\n resolve: {\n conditions: [\"node\"],\n },\n },\n },\n },\n ),\n );\n\n const env = viteServer.environments.api as RunnableDevEnvironment;\n\n const loadDevSetup = async () => {\n env.runner.clearCache();\n return env.runner\n .import<{ default: DevSetup }>(join(defaults.apiDir, \"dev.ts\"))\n .then((e) => e.default);\n };\n\n let devSetup = await loadDevSetup();\n\n for (const [evt, handler] of Object.entries(\n eventMap[sourceFolder.name],\n )) {\n viteServer.watcher.on(evt, async (file) => {\n const mods = env.moduleGraph.getModulesByFile(file);\n if (mods?.size) {\n await handler(file);\n await devSetup?.teardownHandler?.();\n devSetup = await loadDevSetup();\n }\n });\n }\n\n requestHandlers.push([\n [sourceFolder.config.base, sourceFolder.config.apiBase],\n () => devSetup.requestMatcher || requestMatchers.api,\n () => devSetup.requestHandler(),\n ]);\n\n teardownHandlers.push(viteServer.close);\n }\n }\n\n /**\n * Sorting is essential to ensure more specific paths are matched before broader ones.\n *\n * Given source folders:\n * - main app: baseurl=/ apiurl=/api\n * - admin app: baseurl=/admin apiurl=/admin/api\n *\n * Correct sort order:\n * 1. /admin/api — most specific\n * 2. /api\n * 3. /admin\n * 4. /\n * */\n const requestHandlerWeight = ([\n segments,\n ]: (typeof requestHandlers)[number]) => {\n const [base, api] = segments;\n /**\n * set weight to number of non-empty segments:\n * \"/\" weight is 0\n * \"/admin\" weight is 1\n * */\n const weight = base.split(\"/\").filter(Boolean).length;\n return api ? weight + 5 : weight;\n };\n\n const handlers = requestHandlers.sort(\n (a, b) => requestHandlerWeight(b) - requestHandlerWeight(a),\n );\n\n const httpServer = http.createServer((req, res) => {\n for (const [, matcherFactory, handlerFactory] of handlers) {\n // should be called on every request\n const [matcher, handler] = [matcherFactory(), handlerFactory()];\n if (matcher(req)) {\n handler(req, res);\n return;\n }\n }\n res.writeHead(404, { \"Content-Type\": \"text/html\" });\n res.end(\"<h1>404: Not Found</h1>\");\n });\n\n httpServer.on(\"error\", (error) => {\n console.error(\n styleText(\"red\", `Failed to start dev server on port ${devPort}`),\n );\n console.error(error.message);\n process.exit(1);\n });\n\n httpServer.listen(devPort);\n\n teardownHandlers.push(async () => {\n httpServer.close();\n });\n\n return async () => {\n for (const handler of teardownHandlers) {\n await handler();\n }\n // Let chokidar fully release file handles\n await new Promise((resolve) => setTimeout(resolve, 100));\n };\n};\n\nconst cacheDir = (\n { root, name }: SourceFolder,\n command: ProjectSettings[\"command\"],\n mode: \"client\" | \"backend\",\n) => {\n return resolve(root, `var/.vite/${name}/${command}/${mode}`);\n};\n\nconst folderGenerators = (\n sourceFolder: SourceFolder,\n): Array<GeneratorSignature> => {\n const { generators = [] } = sourceFolder.config;\n\n const baseGenerators: Partial<\n Record<NonNullable<GeneratorMeta[\"slot\"]>, GeneratorSignature>\n > = {};\n\n const userGenerators: Array<GeneratorSignature> = [];\n\n for (const generator of generators) {\n if (generator.meta.slot) {\n baseGenerators[generator.meta.slot] = generator;\n } else {\n userGenerators.push(generator);\n }\n }\n\n return [\n // core generator should run first\n coreGenerator(),\n // then backend generator\n ...(baseGenerators.backend ? [baseGenerators.backend] : []),\n // then fetch generator, only if backend generator also enabled\n ...(baseGenerators.fetch && baseGenerators.backend\n ? [baseGenerators.fetch]\n : []),\n // then user generators in the order they were added\n ...userGenerators,\n // ssr generator should run after user generators\n ...(baseGenerators.ssr ? [baseGenerators.ssr] : []),\n // ssg generator should run after ssr generator\n ...(baseGenerators.ssg ? [baseGenerators.ssg] : []),\n ];\n};\n\nconst eventFactory = async (\n sourceFolder: SourceFolder,\n): Promise<\n Record<\"add\" | \"change\" | \"unlink\", (f: string) => Promise<void>>\n> => {\n const { resolvers, resolversFactory } = await routesFactory(\n sourceFolder,\n cacheFactory,\n );\n\n const { createPath } = pathResolver(sourceFolder);\n\n const generators: Array<{\n name: string | undefined;\n factory: GeneratorFactory;\n }> = [];\n\n for (const generator of folderGenerators(sourceFolder)) {\n const factory = generator.factory(sourceFolder);\n generators.push({ name: generator.meta.name, factory });\n }\n\n const resolvedRoutes = new Map<\n string, // fileFullpath\n ResolvedEntry\n >();\n\n const runGenerators = async (event?: WatcherEvent) => {\n /**\n * Watch handlers receive the full list of entries\n * and should process only those whose source file or dependencies were updated.\n * */\n const entries = Array.from(resolvedRoutes.values());\n\n for (const { name, factory } of generators) {\n try {\n await factory.watch?.(entries, event);\n } catch (error) {\n console.error(\n styleText(\"red\", `${sourceFolder.name}: ${name} generator failed`),\n );\n if (event) {\n console.error(event);\n }\n console.error(error);\n }\n }\n };\n\n const updateResolvedEntry = async (file: string) => {\n const resolver = resolvers.get(file);\n\n if (!resolver) {\n return;\n }\n\n try {\n const resolvedEntry = await resolver.handler(file);\n resolvedRoutes.set(resolvedEntry.entry.fileFullpath, resolvedEntry);\n return resolvedEntry;\n } catch (error) {\n const route = file.replace(`${createPath.api()}/`, \"\");\n console.error(\n styleText(\n \"red\",\n `${sourceFolder.name}: ${route} route resolution failed`,\n ),\n );\n console.error(error);\n return;\n }\n };\n\n {\n const spinner = spinnerFactory(`${sourceFolder.name}: resolving routes`);\n for (const { name, handler } of resolvers.values()) {\n spinner.append(\n `[ ${resolvedRoutes.size + 1} of ${resolvers.size} ] ${name}`,\n );\n const route = await handler();\n resolvedRoutes.set(route.entry.fileFullpath, route);\n }\n spinner.succeed(\"ready ✨\");\n }\n\n // NOTE: call only after routes resolved\n await runGenerators();\n\n return {\n async add(file: string) {\n const [resolver] = resolversFactory([file]).values();\n\n if (!resolver) {\n return;\n }\n\n resolvers.set(file, resolver);\n\n // call only after `resolvers.set(file)`\n const resolvedEntry = await updateResolvedEntry(file);\n\n if (resolvedEntry) {\n await runGenerators({ kind: \"create\", file });\n }\n },\n\n async change(file: string) {\n if (resolvedRoutes.has(file)) {\n // route updated\n await updateResolvedEntry(file);\n } else {\n // updating entries that are referencing updated file\n const relatedRoutes = resolvedRoutes\n .values()\n .flatMap(({ kind, entry }) => {\n return kind === \"apiRoute\"\n ? entry.referencedFiles.includes(file)\n ? [entry]\n : []\n : [];\n });\n\n for (const route of relatedRoutes) {\n await updateResolvedEntry(route.fileFullpath);\n }\n }\n\n await runGenerators({ kind: \"update\", file });\n },\n\n async unlink(file) {\n // route deleted\n resolvers.delete(file);\n resolvedRoutes.delete(file);\n await runGenerators({ kind: \"delete\", file });\n },\n };\n};\n\nconst matchersFactory: (\n sourceFolder: SourceFolder,\n) => Record<\"base\" | \"api\", (req: IncomingMessage) => boolean> = ({\n config,\n}) => {\n const basePattern = new RegExp(`^${config.base}($|/*)`);\n const apiPattern = new RegExp(`^${join(config.base, config.apiBase)}($|/*)`);\n return {\n base(req) {\n return apiPattern.test(req.url as string)\n ? false\n : basePattern.test(req.url as string);\n },\n api(req) {\n return apiPattern.test(req.url as string);\n },\n };\n};\n\nconst findFreePort = async (devPort: number): Promise<number> => {\n let minPort = 0;\n let maxPort = 0;\n\n for (const n of [3, 2, 1, \"\"]) {\n minPort = Number(`${n}${devPort}`) + 100;\n maxPort = minPort + 100;\n if (maxPort < 65000) {\n break;\n }\n }\n\n if (maxPort >= 65000) {\n throw new Error(\"the devPort in package.json should be less than 64000\");\n }\n\n const range = maxPort - minPort + 1;\n const startOffset = Math.floor(Math.random() * range);\n\n const ports = Array.from({ length: range }, (_, i) => {\n return minPort + ((startOffset + i) % range);\n });\n\n const freePort = await ports.reduce(\n async (prevPromise, port) => {\n const freePort = await prevPromise;\n if (freePort) {\n return freePort;\n }\n const isFree = await isPortFree(port);\n return isFree ? port : undefined;\n },\n Promise.resolve(undefined as number | undefined),\n );\n\n if (!freePort) {\n throw new Error(`No free ports found in range ${minPort}-${maxPort}`);\n }\n\n return freePort;\n};\n\nconst isPortFree = (port: number): Promise<boolean> => {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once(\"error\", () => resolve(false));\n\n server.once(\"listening\", () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port, \"127.0.0.1\");\n });\n};\n"],"mappings":"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"}