@kosmojs/dev 0.2.10 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/pkg/index.js CHANGED
@@ -1,8 +1,12 @@
1
- import{join as e,resolve as t}from"node:path";import{styleText as n}from"node:util";import{DEFAULT_APIBASE as r,RequestBodyTargets as i,RequestValidationTargets as a,createRouteResolver as o,createTemplateResolver as s,defaults as c}from"@kosmojs/core";import{createHonoPattern as l,createPathPattern as u,defineGenerator as d,defineGeneratorFactory as f,mergeConfigs as p,nestedRoutesFactory as m,pathResolver as h,pathTokensFactory as g,renderFactory as _,renderToFile as ee,sortRoutes as v,spinnerFactory as te,vitePlugins as y}from"@kosmojs/lib";import{routeRenderHelpers as b}from"@kosmojs/core/generators";import x from"crc/crc32";import ne from"@mdx-js/rollup";import{build as S,createFilter as C}from"vite";import re from"yaml";import{parse as ie}from"path-to-regexp";import ae from"typebox";import oe from"@vitejs/plugin-react";import w from"vite-plugin-solid";import{access as se,constants as ce,cp as T,mkdir as le,rm as E,writeFile as ue}from"node:fs/promises";import{svelte as de}from"@sveltejs/vite-plugin-svelte";import fe from"@vitejs/plugin-vue";var D={type:`module`,private:!0,name:`@kosmojs/fetch-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/fetch-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`},devDependencies:{"path-to-regexp":`^8.4.2`}},O=`import { compile } from "path-to-regexp";
1
+ import{join as e,resolve as t}from"node:path";import{styleText as n}from"node:util";import{DEFAULT_APIBASE as r,RequestBodyTargets as i,RequestValidationTargets as a,createRouteResolver as o,createTemplateResolver as s,defaults as c}from"@kosmojs/core";import{createHonoPattern as l,createPathPattern as u,defineGenerator as d,defineGeneratorFactory as f,mergeConfigs as p,nestedRoutesFactory as m,pathResolver as h,pathTokensFactory as g,renderFactory as _,renderToFile as ee,sortRoutes as v,spinnerFactory as te,vitePlugins as y}from"@kosmojs/lib";import{routeRenderHelpers as b}from"@kosmojs/core/generators";import x from"crc/crc32";import ne from"@mdx-js/rollup";import{build as S,createFilter as C}from"vite";import re from"yaml";import{parse as ie}from"path-to-regexp";import ae from"typebox";import oe from"@vitejs/plugin-react";import w from"vite-plugin-solid";import{access as se,constants as ce,cp as T,mkdir as le,rm as E,writeFile as ue}from"node:fs/promises";import{svelte as de}from"@sveltejs/vite-plugin-svelte";import fe from"@vitejs/plugin-vue";var D={type:`module`,private:!0,name:`@kosmojs/fetch-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/fetch-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`},devDependencies:{"path-to-regexp":`^8.4.2`}},O=`import { compile } from "path-to-regexp";
2
2
 
3
- import type { ApiRouteSerialized, ValidationTarget } from "@kosmojs/core";
3
+ import {
4
+ type ApiRouteSerialized,
5
+ stringifySearchParams,
6
+ type ValidationTarget,
7
+ } from "@kosmojs/core";
4
8
  import type { HTTPMethod } from "@kosmojs/core/api";
5
- import { createHost, type HostOpt, join, stringify } from "@kosmojs/core/fetch";
9
+ import { createHost, type HostOpt, join } from "@kosmojs/core/fetch";
6
10
 
7
11
  export * from "./transport";
8
12
 
@@ -47,7 +51,7 @@ export const fetchHelpers = <ParamsT extends readonly unknown[]>(
47
51
 
48
52
  const base = (params: ParamsT, query?: Record<string, unknown>) => {
49
53
  const path = join("/", parametrize(params));
50
- return query ? [path, stringify(query)].join("?") : path;
54
+ return query ? [path, stringifySearchParams(query)].join("?") : path;
51
55
  };
52
56
 
53
57
  const path = (params: ParamsT, query?: Record<string, unknown>) => {
@@ -128,7 +132,7 @@ export default {
128
132
  {{/each}}
129
133
  {{/each}}
130
134
  }
131
- `,j=`import fetchFactory, { join, stringify } from "@kosmojs/core/fetch";
135
+ `,j=`import fetchFactory, { join } from "@kosmojs/core/fetch";
132
136
 
133
137
  import { base, apiBase, apiRouteMap } from "{{ createImport 'libCore' }}";
134
138
  import { transport, fetchHelpers } from "{{ createImport 'lib' '@fetch' }}";
@@ -178,21 +182,17 @@ const {
178
182
 
179
183
  const fetchApi = fetchFactory(
180
184
  join(base, apiBase),
181
- { transport, stringify },
185
+ { transport },
182
186
  );
183
187
 
184
188
  {{#each routeMethods}}
185
189
  export const {{method}} = (
186
190
  _params{{#if ../route.optionalParams}}?{{/if}}: MaybeWrapped<ParamsT>,
187
191
  _payload?: {
188
- {{#each ../payloadTargets}}
189
- {{#if payloadType}}
190
- {{target}}: {{payloadType.name}} extends { {{../method}}: unknown }
191
- ? MaybeWrapped<{{payloadType.name}}["{{../method}}"]>
192
+ {{#each payloadTypes}}
193
+ {{target}}: {{id}} extends { {{method}}: unknown }
194
+ ? MaybeWrapped<{{id}}["{{method}}"]>
192
195
  : unknown,
193
- {{else}}
194
- {{target}}?: unknown;
195
- {{/if}}
196
196
  {{/each}}
197
197
  },
198
198
  opt?: {
@@ -215,10 +215,10 @@ export const {{method}} = (
215
215
  paramsMapper(params as never, { coerceNumbers: true }),
216
216
  );
217
217
  }
218
- {{#each ../payloadTypes}}
219
- if (validationSchemas.{{target}}?.{{../method}}) {
220
- validationSchemas.{{target}}.{{../method}}.validate(
221
- payloadResolver(payload, "{{target}}", "{{../method}}"),
218
+ {{#each payloadTypes}}
219
+ if (validationSchemas.{{target}}?.{{method}}) {
220
+ validationSchemas.{{target}}.{{method}}.validate(
221
+ payloadResolver(payload as never, "{{target}}", "{{../method}}"),
222
222
  );
223
223
  }
224
224
  {{/each}}
@@ -237,7 +237,7 @@ export default {
237
237
  };
238
238
  `,M=`export type MaybeWrapped<T> = T;
239
239
  export const unwrap = <T>(data: T) => data;
240
- `,N=f(e=>{let{createPath:t,createImportHelpers:n}=h(e),{renderToFile:r}=_({helpers:{...n({origin:`lib`}),...b()}}),i=async(e,n)=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]).sort(v);await r(t.lib(`fetch.ts`),A,{routes:i});for(let{kind:e,entry:i}of n)if(e===`apiRoute`){let e=[];for(let t of i.validationDefinitions)if(t.target===`response`)for(let{id:n,body:r,resolvedType:i}of t.variants)r&&e.push({id:n,target:t.target,method:t.method,resolvedType:i});else{let{id:n,resolvedType:r}=t.schema;e.push({id:n,target:t.target,method:t.method,resolvedType:r})}let n=i.methods.map(t=>({method:t,responseType:e.find(e=>e.target===`response`&&e.method===t)})),o=Object.entries(e.reduce((e,{id:t,target:n,method:r,resolvedType:i})=>{if([`headers`,`cookies`,`response`].includes(n))return e;let a=`${n.replace(/^./,e=>e.toUpperCase())}T`;return e[a]||(e[a]=[]),e[a].push({id:t,target:n,method:r,resolvedType:i}),e},{})).map(([e,t])=>({name:e,types:t,target:t[0].target})),s=Object.keys(a).map(e=>({target:e,payloadType:o.find(t=>t.target===e)})),c=Object.values(e.reduce((e,{id:t,target:n,method:r,resolvedType:i})=>(n===`response`&&(e[r]||(e[r]={method:r,types:[]}),e[r].types.push({id:t,target:n,method:r,resolvedType:i})),e),{}));await r(t.libApi(i.name,`fetch.ts`),j,{route:i,validationTypes:e,routeMethods:n,payloadTypes:o,payloadTargets:s,responseTypes:c})}};return{async start(){for(let[e,n]of[[`unwrap.ts`,M],[`@fetch/transport.ts`,k],[`@fetch/index.ts`,O]])await r(t.lib(e),n,{})},async watch(e,t){await i(e,t?e.filter(({kind:e,entry:n})=>t.kind===`update`&&e===`apiRoute`&&n.fileFullpath===t.file):e)},async build(e){await i(e,e)},async ssrBuild(){for(let[e,n]of[[`@fetch/transport.ts`,`export { transport } from "${c.libPrefix}/@ssr/fetch";`]])await r(t.lib(e),n,{})}}}),P=d({meta:{name:`Fetch`,slot:`fetch`},dependencies:{"path-to-regexp":D.devDependencies[`path-to-regexp`]},factory:N}),F={type:`module`,private:!0,name:`@kosmojs/hono-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/hono-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`},devDependencies:{"@hono/node-server":`^2.1.0`,hono:`^4.13.1`,"path-to-regexp":`^8.4.2`,vite:`^8.2.1`}},I=`import { Hono } from "hono";
240
+ `,N=f(e=>{let{createPath:t,createImportHelpers:n}=h(e),{renderToFile:r}=_({helpers:{...n({origin:`lib`}),...b()}}),i=async(e,n)=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]).sort(v);await r(t.lib(`fetch.ts`),A,{routes:i});for(let{kind:e,entry:i}of n)if(e===`apiRoute`){let e=[];for(let t of i.validationDefinitions)if(t.target===`response`)for(let{id:n,body:r,resolvedType:i}of t.variants)r&&e.push({id:n,target:t.target,method:t.method,resolvedType:i});else{let{id:n,resolvedType:r}=t.schema;e.push({id:n,target:t.target,method:t.method,resolvedType:r})}let n=i.methods.map(t=>({method:t,payloadTypes:e.filter(e=>e.method===t&&![`headers`,`cookies`,`response`].includes(e.target)),responseType:e.find(e=>e.target===`response`&&e.method===t)})),a=Object.values(e.reduce((e,{id:t,target:n,method:r,resolvedType:i})=>(n===`response`&&(e[r]||(e[r]={method:r,types:[]}),e[r].types.push({id:t,target:n,method:r,resolvedType:i})),e),{}));await r(t.libApi(i.name,`fetch.ts`),j,{route:i,validationTypes:e,routeMethods:n,responseTypes:a})}};return{async start(){for(let[e,n]of[[`unwrap.ts`,M],[`@fetch/transport.ts`,k],[`@fetch/index.ts`,O]])await r(t.lib(e),n,{})},async watch(e,t){await i(e,t?e.filter(({kind:e,entry:n})=>t.kind===`update`&&e===`apiRoute`&&n.fileFullpath===t.file):e)},async build(e){await i(e,e)},async ssrBuild(){for(let[e,n]of[[`@fetch/transport.ts`,`export { transport } from "${c.libPrefix}/@ssr/fetch";`]])await r(t.lib(e),n,{})}}}),P=d({meta:{name:`Fetch`,slot:`fetch`},dependencies:{"path-to-regexp":D.devDependencies[`path-to-regexp`]},factory:N}),F={type:`module`,private:!0,name:`@kosmojs/hono-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/hono-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`},devDependencies:{"@hono/node-server":`^2.1.0`,hono:`^4.13.1`,"path-to-regexp":`^8.4.2`,vite:`^8.2.1`}},I=`import { Hono } from "hono";
241
241
 
242
242
  import type { AppFactory } from "@kosmojs/core/api";
243
243
 
@@ -277,8 +277,12 @@ export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
277
277
  };
278
278
  `,z=`import type { Context } from "hono";
279
279
 
280
- import type { RequestBodyTarget, RequestMetadataTarget } from "@kosmojs/core";
281
- import { parseCookies, parseQuerystring } from "@kosmojs/core/api";
280
+ import {
281
+ parseCookies,
282
+ parseSearchParams,
283
+ type RequestBodyTarget,
284
+ type RequestMetadataTarget,
285
+ } from "@kosmojs/core";
282
286
 
283
287
  export type BodyparserOptions = {
284
288
  json: never;
@@ -290,7 +294,7 @@ export const metaparsers: {
290
294
  [T in RequestMetadataTarget]: (ctx: Context) => unknown;
291
295
  } = {
292
296
  query(ctx) {
293
- return parseQuerystring(ctx.req.url);
297
+ return parseSearchParams(ctx.req.url);
294
298
  },
295
299
 
296
300
  headers(ctx) {
@@ -1197,7 +1201,7 @@ export default [
1197
1201
  return next();
1198
1202
  }),
1199
1203
  ];
1200
- `,Te=f((t,n)=>{let{createPath:r,createImportHelpers:i}=h(t),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=_({helpers:{...i({origin:`lib`}),...b(),paramsDefaults({params:e}){return`[${e.schema.map(()=>`unknown?`).join(`, `)}]`},paramsMappings({params:e}){return`[${e.schema.map(({name:e,kind:t})=>`["${e}", unknown, ${t===`required`?`true`:`false`}]`).join(`, `)}]`},cascadingState({cascadingMiddleware:e}){return a(e.map(({id:e})=>`UseT${e}`))}}}),{renderToFile:c}=_({helpers:i({origin:`src`})}),u=e=>e?.trim().length===0,d=s(n?.templates,be),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await c(r.api(n.file),d(n.name,n),{route:n},{overwrite:u}):t===`apiUse`&&await c(r.api(n.file),xe,{},{overwrite:u})},p=async t=>{let i=t.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=t.flatMap(({kind:t,entry:r})=>{if(t!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((t,n)=>{let r=t[t.length-1];return t.push(r?e(r,n):n),t},[]),o={...r,path:r.honoPattern,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=g(e);return t===r.name?[{...o,name:e,id:`${o.id}_${x(e)}`,fullpath:l(n),pathTokens:n}]:[]})]}).sort(v);for(let[e,t]of[[`@api/routes.ts`,V]])await o(r.lib(e),t,{routes:a,cascadingMiddleware:i})};return{config({command:e}){return{define:{KOSMO_PRODUCTION_BUILD:e===`build`?`true`:`false`}}},async start(){for(let[e,t]of[[`api.ts`,me],[`api:factory.ts`,he],[`@api/app.ts`,I],[`@api/parsers.ts`,z],[`@api/dev.ts`,L],[`@api/errors.ts`,R],[`@api/router.ts`,B],[`@api/server.ts`,pe]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,ge],[`dev.ts`,_e],[`errors.ts`,ye],[`router.ts`,Se],[`server.ts`,Ce],[`use.ts`,we]])await c(r.api(e),t,{},{overwrite:u});await o(r.api(`env.d.ts`),ve,{},{overwrite:u})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)}}}),Ee=d({meta:{name:`Hono`,slot:`backend`},dependencies:{hono:F.devDependencies.hono,"@hono/node-server":F.devDependencies[`@hono/node-server`],"path-to-regexp":F.devDependencies[`path-to-regexp`]},factory:Te}),H={type:`module`,private:!0,name:`@kosmojs/koa-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`},"./lib":{types:`./pkg/lib.d.ts`,default:`./pkg/lib.js`}},scripts:{build:`wsbuild src/index.ts src/lib.ts`,test:`vitest --root ../.. --project generators/koa-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`},devDependencies:{"@koa/router":`^15.7.0`,"@types/formidable":`^3.5.1`,"@types/koa":`^3.0.3`,"@types/koa-compose":`^3.2.9`,formidable:`^3.5.4`,koa:`^3.2.1`,"koa-compose":`^4.1.0`,"light-my-request":`^6.6.0`,"path-to-regexp":`^8.4.2`,"raw-body":`^4.0.0`,vite:`^8.2.1`}},De=`import Koa from "koa";
1204
+ `,Te=f((t,n)=>{let{createPath:r,createImportHelpers:i}=h(t),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=_({helpers:{...i({origin:`lib`}),...b(),paramsDefaults({params:e}){return`[${e.schema.map(()=>`unknown?`).join(`, `)}]`},paramsMappings({params:e}){return`[${e.schema.map(({name:e,kind:t})=>`["${e}", unknown, ${t===`required`?`true`:`false`}]`).join(`, `)}]`},cascadingState({cascadingMiddleware:e}){return a(e.map(({id:e})=>`UseT${e}`))}}}),{renderToFile:c}=_({helpers:i({origin:`src`})}),u=e=>e?.trim().length===0,d=s(n?.templates,be),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await c(r.api(n.file),d(n.name,n),{route:n},{overwrite:u}):t===`apiUse`&&await c(r.api(n.file),xe,{},{overwrite:u})},p=async t=>{let i=t.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=t.flatMap(({kind:t,entry:r})=>{if(t!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((t,n)=>{let r=t[t.length-1];return t.push(r?e(r,n):n),t},[]),o={...r,path:r.honoPattern,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=g(e);return t===r.name?[{...o,name:e,id:`${o.id}_${x(e)}`,fullpath:l(n),pathTokens:n}]:[]})]}).sort(v);for(let[e,t]of[[`@api/routes.ts`,V]])await o(r.lib(e),t,{routes:a,cascadingMiddleware:i})};return{config({command:e}){return{define:{KOSMO_PRODUCTION_BUILD:e===`build`?`true`:`false`}}},async start(){for(let[e,t]of[[`api.ts`,me],[`api:factory.ts`,he],[`@api/app.ts`,I],[`@api/parsers.ts`,z],[`@api/dev.ts`,L],[`@api/errors.ts`,R],[`@api/router.ts`,B],[`@api/server.ts`,pe]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,ge],[`dev.ts`,_e],[`errors.ts`,ye],[`router.ts`,Se],[`server.ts`,Ce],[`use.ts`,we]])await c(r.api(e),t,{},{overwrite:u});await o(r.api(`env.d.ts`),ve,{},{overwrite:u})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)}}}),Ee=d({meta:{name:`Hono`,slot:`backend`},dependencies:{hono:F.devDependencies.hono,"@hono/node-server":F.devDependencies[`@hono/node-server`],"path-to-regexp":F.devDependencies[`path-to-regexp`]},factory:Te}),H={type:`module`,private:!0,name:`@kosmojs/koa-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`},"./lib":{types:`./pkg/lib.d.ts`,default:`./pkg/lib.js`}},scripts:{build:`wsbuild src/index.ts src/lib.ts`,test:`vitest --root ../.. --project generators/koa-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`},devDependencies:{"@koa/router":`^15.7.0`,"@types/formidable":`^3.5.1`,"@types/koa":`^3.0.3`,"@types/koa-compose":`^3.2.9`,formidable:`^3.5.4`,koa:`^3.2.1`,"koa-compose":`^4.1.0`,"light-my-request":`^6.6.0`,"path-to-regexp":`^8.4.2`,"raw-body":`^4.0.0`,vite:`^8.2.1`}},De=`import Koa from "koa";
1201
1205
 
1202
1206
  import type { AppFactory } from "@kosmojs/core/api";
1203
1207
 
@@ -1233,8 +1237,12 @@ import type { RouterContext } from "@koa/router";
1233
1237
  import Formidable, { type Options as FormidableOptions } from "formidable";
1234
1238
  import rawParser from "raw-body";
1235
1239
 
1236
- import type { RequestBodyTarget, RequestMetadataTarget } from "@kosmojs/core";
1237
- import { parseCookies, parseQuerystring } from "@kosmojs/core/api";
1240
+ import {
1241
+ parseCookies,
1242
+ parseSearchParams,
1243
+ type RequestBodyTarget,
1244
+ type RequestMetadataTarget,
1245
+ } from "@kosmojs/core";
1238
1246
 
1239
1247
  import type {
1240
1248
  DefaultContext,
@@ -1246,7 +1254,7 @@ export const metaparsers: {
1246
1254
  [T in RequestMetadataTarget]: (ctx: RouterContext) => unknown;
1247
1255
  } = {
1248
1256
  query(ctx) {
1249
- return parseQuerystring(ctx.req.url ?? "");
1257
+ return parseSearchParams(ctx.req.url ?? "");
1250
1258
  },
1251
1259
 
1252
1260
  headers(ctx) {
@@ -2260,7 +2268,7 @@ export default [
2260
2268
  * */
2261
2269
  use(defaultErrorHandler, { slot: "errorHandler" }),
2262
2270
  ];
2263
- `,Ge=f((t,n)=>{let{createPath:r,createImportHelpers:i}=h(t),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=_({helpers:{...i({origin:`lib`}),...b(),paramsDefaults({params:e}){return`[${e.schema.map(()=>`unknown?`).join(`, `)}]`},paramsMappings({params:e}){return`[${e.schema.map(({name:e,kind:t})=>`["${e}", unknown, ${t===`required`?`true`:`false`}]`).join(`, `)}]`},cascadingState({cascadingMiddleware:e}){return a(e.map(({id:e})=>`UseT${e}`))}}}),{renderToFile:c}=_({helpers:i({origin:`src`})}),l=e=>e?.trim().length===0,d=s(n?.templates,Be),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await c(r.api(n.file),d(n.name,n),{route:n},{overwrite:l}):t===`apiUse`&&await c(r.api(n.file),Ve,{},{overwrite:l})},p=async t=>{let i=t.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=t.flatMap(({kind:t,entry:r})=>{if(t!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((t,n)=>{let r=t[t.length-1];return t.push(r?e(r,n):n),t},[]),o={...r,path:r.pathPattern,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=g(e);return t===r.name?[{...o,name:e,id:`${o.id}_${x(e)}`,fullpath:u(n),pathTokens:n}]:[]})]}).sort(v);for(let[e,t]of[[`@api/routes.ts`,Me]])await o(r.lib(e),t,{routes:a,cascadingMiddleware:i})};return{config({command:e}){return{define:{KOSMO_PRODUCTION_BUILD:e===`build`?`true`:`false`}}},async start(){for(let[e,t]of[[`api.ts`,Pe],[`api:factory.ts`,Fe],[`@api/app.ts`,De],[`@api/dev.ts`,Oe],[`@api/errors.ts`,ke],[`@api/parsers.ts`,Ae],[`@api/router.ts`,je],[`@api/server.ts`,Ne]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,Ie],[`dev.ts`,Le],[`errors.ts`,ze],[`router.ts`,He],[`server.ts`,Ue],[`use.ts`,We]])await c(r.api(e),t,{},{overwrite:l});await o(r.api(`env.d.ts`),Re,{},{overwrite:l})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)}}}),Ke=d({meta:{name:`Koa`,slot:`backend`,types:[`@types/koa`]},dependencies:{koa:H.devDependencies.koa,"@koa/router":H.devDependencies[`@koa/router`],"path-to-regexp":H.devDependencies[`path-to-regexp`],formidable:H.devDependencies.formidable,"raw-body":H.devDependencies[`raw-body`]},devDependencies:{"@types/koa":H.devDependencies[`@types/koa`],"@types/formidable":H.devDependencies[`@types/formidable`]},factory:Ge}),U={type:`module`,private:!0,name:`@kosmojs/mdx-generator`,version:`0.2.10`,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:^`,"@mdx-js/rollup":`^3.1.1`,vite:`^8.2.1`},devDependencies:{"@mdx-js/mdx":`^3.1.1`,"@mdx-js/preact":`^3.1.1`,"path-to-regexp":`^8.4.2`,preact:`^10.29.8`,"preact-render-to-string":`^6.7.0`,"remark-frontmatter":`^5.0.0`,"remark-mdx-frontmatter":`^5.2.0`}},qe=()=>{let e=[`🎉 Well done! You just created a new MDX page.`,`🚀 Success! A fresh MDX page is ready to roll.`,`🌟 Nice work! Another MDX page added to your site.`,`🧩 All set! A new MDX page has been scaffolded.`,`🔧 Scaffold complete! Your new MDX page is in place.`,`✅ Built! Your MDX page is scaffolded and ready.`,`✨ Fantastic! Your new MDX page is good to go.`,`🎯 Nailed it! A brand new MDX page just landed.`,`💫 Awesome! Another MDX page joins the party.`,`⚡ Lightning fast! A new MDX page created successfully.`];return e[Math.floor(Math.random()*e.length)]},Je=(e,t,n)=>{let{remarkPlugins:r=[],rehypePlugins:i=[]}={...n},a=()=>{let t=[`${c.srcDir}/${e.name}/${c.entryDir}/client.ts`].map(e=>C(e)),n=e=>t.some(t=>t(e));return{name:`kosmo:mdx[hmr]`,enforce:`post`,transform(e,t){if(!(!n(t)||e.includes(`import.meta.hot.accept`)))return{code:[e,`
2271
+ `,Ge=f((t,n)=>{let{createPath:r,createImportHelpers:i}=h(t),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=_({helpers:{...i({origin:`lib`}),...b(),paramsDefaults({params:e}){return`[${e.schema.map(()=>`unknown?`).join(`, `)}]`},paramsMappings({params:e}){return`[${e.schema.map(({name:e,kind:t})=>`["${e}", unknown, ${t===`required`?`true`:`false`}]`).join(`, `)}]`},cascadingState({cascadingMiddleware:e}){return a(e.map(({id:e})=>`UseT${e}`))}}}),{renderToFile:c}=_({helpers:i({origin:`src`})}),l=e=>e?.trim().length===0,d=s(n?.templates,Be),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await c(r.api(n.file),d(n.name,n),{route:n},{overwrite:l}):t===`apiUse`&&await c(r.api(n.file),Ve,{},{overwrite:l})},p=async t=>{let i=t.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=t.flatMap(({kind:t,entry:r})=>{if(t!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((t,n)=>{let r=t[t.length-1];return t.push(r?e(r,n):n),t},[]),o={...r,path:r.pathPattern,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=g(e);return t===r.name?[{...o,name:e,id:`${o.id}_${x(e)}`,fullpath:u(n),pathTokens:n}]:[]})]}).sort(v);for(let[e,t]of[[`@api/routes.ts`,Me]])await o(r.lib(e),t,{routes:a,cascadingMiddleware:i})};return{config({command:e}){return{define:{KOSMO_PRODUCTION_BUILD:e===`build`?`true`:`false`}}},async start(){for(let[e,t]of[[`api.ts`,Pe],[`api:factory.ts`,Fe],[`@api/app.ts`,De],[`@api/dev.ts`,Oe],[`@api/errors.ts`,ke],[`@api/parsers.ts`,Ae],[`@api/router.ts`,je],[`@api/server.ts`,Ne]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,Ie],[`dev.ts`,Le],[`errors.ts`,ze],[`router.ts`,He],[`server.ts`,Ue],[`use.ts`,We]])await c(r.api(e),t,{},{overwrite:l});await o(r.api(`env.d.ts`),Re,{},{overwrite:l})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)}}}),Ke=d({meta:{name:`Koa`,slot:`backend`,types:[`@types/koa`]},dependencies:{koa:H.devDependencies.koa,"@koa/router":H.devDependencies[`@koa/router`],"path-to-regexp":H.devDependencies[`path-to-regexp`],formidable:H.devDependencies.formidable,"raw-body":H.devDependencies[`raw-body`]},devDependencies:{"@types/koa":H.devDependencies[`@types/koa`],"@types/formidable":H.devDependencies[`@types/formidable`]},factory:Ge}),U={type:`module`,private:!0,name:`@kosmojs/mdx-generator`,version:`0.3.0`,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:^`,"@mdx-js/rollup":`^3.1.1`,vite:`^8.2.1`},devDependencies:{"@mdx-js/mdx":`^3.1.1`,"@mdx-js/preact":`^3.1.1`,"path-to-regexp":`^8.4.2`,preact:`^10.29.8`,"preact-render-to-string":`^6.7.0`,"remark-frontmatter":`^5.0.0`,"remark-mdx-frontmatter":`^5.2.0`}},qe=()=>{let e=[`🎉 Well done! You just created a new MDX page.`,`🚀 Success! A fresh MDX page is ready to roll.`,`🌟 Nice work! Another MDX page added to your site.`,`🧩 All set! A new MDX page has been scaffolded.`,`🔧 Scaffold complete! Your new MDX page is in place.`,`✅ Built! Your MDX page is scaffolded and ready.`,`✨ Fantastic! Your new MDX page is good to go.`,`🎯 Nailed it! A brand new MDX page just landed.`,`💫 Awesome! Another MDX page joins the party.`,`⚡ Lightning fast! A new MDX page created successfully.`];return e[Math.floor(Math.random()*e.length)]},Je=(e,t,n)=>{let{remarkPlugins:r=[],rehypePlugins:i=[]}={...n},a=()=>{let t=[`${c.srcDir}/${e.name}/${c.entryDir}/client.ts`].map(e=>C(e)),n=e=>t.some(t=>t(e));return{name:`kosmo:mdx[hmr]`,enforce:`post`,transform(e,t){if(!(!n(t)||e.includes(`import.meta.hot.accept`)))return{code:[e,`
2264
2272
  if (import.meta.hot) {
2265
2273
  import.meta.hot.accept(() => {});
2266
2274
  }
@@ -2402,6 +2410,8 @@ declare module "*.md" {
2402
2410
  import { match, pathToRegexp } from "path-to-regexp";
2403
2411
  import { type ComponentType, createContext, h, type VNode } from "preact";
2404
2412
 
2413
+ import { parseSearchParams } from "@kosmojs/core";
2414
+
2405
2415
  import { paramNames } from "{{ createImport 'lib' 'params' }}";
2406
2416
  import { base } from "{{ createImport 'libCore' }}";
2407
2417
 
@@ -2415,7 +2425,7 @@ export type RawRoute = {
2415
2425
  };
2416
2426
 
2417
2427
  type Loader = (
2418
- route: Pick<Route, "name" | "params" | "paramsEntries">,
2428
+ route: Pick<Route, "name" | "params" | "paramsEntries" | "searchParams">,
2419
2429
  ) => Promise<unknown> | undefined;
2420
2430
 
2421
2431
  type LayoutModule = {
@@ -2435,6 +2445,7 @@ export type Route = {
2435
2445
  name: string;
2436
2446
  params: Record<string, string | Array<string>>;
2437
2447
  paramsEntries: [keys: Array<string>, values: Array<unknown>];
2448
+ searchParams: Record<string, unknown>;
2438
2449
  frontmatter: Record<string, unknown>;
2439
2450
  loaderData: Record<string, unknown>;
2440
2451
  };
@@ -2443,6 +2454,7 @@ export const RouterContext = createContext<Route>({
2443
2454
  name: "",
2444
2455
  params: {},
2445
2456
  paramsEntries: [[], []],
2457
+ searchParams: {},
2446
2458
  frontmatter: {},
2447
2459
  loaderData: {},
2448
2460
  });
@@ -2472,6 +2484,7 @@ export const createRouter = (
2472
2484
 
2473
2485
  return {
2474
2486
  async resolve(url: URL = new URL(window.location.href)) {
2487
+ const searchParams = parseSearchParams(url);
2475
2488
  const urlSegments = url.pathname.split("/").filter(Boolean).length;
2476
2489
 
2477
2490
  // 1: use lightweight \`RegExp.test()\` on linear scan - no capture allocation
@@ -2516,7 +2529,7 @@ export const createRouter = (
2516
2529
 
2517
2530
  loaderData[name] = await runLoader(name, () => {
2518
2531
  return routeModule.loader
2519
- ? routeModule.loader({ name, params, paramsEntries })
2532
+ ? routeModule.loader({ name, params, paramsEntries, searchParams })
2520
2533
  : undefined; // should not survive serialization if no loader defined
2521
2534
  });
2522
2535
 
@@ -2531,7 +2544,7 @@ export const createRouter = (
2531
2544
  const key = \`\${name}/layout\`;
2532
2545
  loaderData[key] = await runLoader(key, () => {
2533
2546
  return layoutModule.loader
2534
- ? layoutModule.loader({ name, params, paramsEntries })
2547
+ ? layoutModule.loader({ name, params, paramsEntries, searchParams })
2535
2548
  : undefined; // should not survive serialization if no loader defined
2536
2549
  });
2537
2550
  }
@@ -2540,6 +2553,7 @@ export const createRouter = (
2540
2553
  name,
2541
2554
  params,
2542
2555
  paramsEntries,
2556
+ searchParams,
2543
2557
  frontmatter,
2544
2558
  loaderData,
2545
2559
  };
@@ -3012,11 +3026,11 @@ import { RouterContext } from "./mdx";
3012
3026
  import type { ParamsMap, paramNames } from "{{ createImport 'lib' 'params' }}";
3013
3027
 
3014
3028
  export function useRoute() {
3015
- return useContext(RouterContext);
3029
+ return structuredClone(useContext(RouterContext));
3016
3030
  }
3017
3031
 
3018
3032
  export function useParams<T extends keyof ParamsMap>(): ParamsMap[T] {
3019
- return useContext(RouterContext).params as ParamsMap[T];
3033
+ return useRoute().params as ParamsMap[T];
3020
3034
  }
3021
3035
 
3022
3036
  type SameLengthTuple<T extends readonly unknown[], U> = { [K in keyof T]: U };
@@ -3025,7 +3039,11 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
3025
3039
  (typeof paramNames)[T],
3026
3040
  SameLengthTuple<(typeof paramNames)[T], unknown>,
3027
3041
  ] {
3028
- return useContext(RouterContext).paramsEntries as never;
3042
+ return useRoute().paramsEntries as never;
3043
+ }
3044
+
3045
+ export function useSearchParams() {
3046
+ return useRoute().searchParams;
3029
3047
  }
3030
3048
 
3031
3049
  /**
@@ -3035,7 +3053,7 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
3035
3053
  * a hook can't tell which layout it runs in.
3036
3054
  * */
3037
3055
  export const useLoaderData = <T>(key?: string): T | undefined => {
3038
- const route = useContext(RouterContext);
3056
+ const route = useRoute();
3039
3057
  return route.loaderData?.[key || route.name] as T;
3040
3058
  };
3041
3059
 
@@ -3045,7 +3063,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
3045
3063
  export const useFrontmatter = <
3046
3064
  T extends Record<string, unknown> = Record<string, unknown>,
3047
3065
  >(): T => {
3048
- return useContext(RouterContext).frontmatter as T;
3066
+ return useRoute().frontmatter as T;
3049
3067
  };
3050
3068
  `,lt=`import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3051
3069
 
@@ -3197,7 +3215,7 @@ export default routerFactory((routes) => {
3197
3215
  },
3198
3216
  };
3199
3217
  });
3200
- `,bt=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b(),serializeParams(e){return JSON.stringify(e.params)}}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,l=s(t?.templates,_t),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?vt:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:qe()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),gt,{route:r},{overwrite:o})},d=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageLayout`?[t]:[]),r=e.flatMap(({kind:e,entry:n})=>{if(e===`pageRoute`){let{name:e,file:r}=n;return[{...n,layouts:t.flatMap(t=>t.name===e||r.startsWith(`${t.name}/`)?[t]:[]).sort(v)}]}return[]}).sort(v);for(let[e,a]of[[`client.ts`,Xe],[`server.ts`,Ze]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,it],[`router.ts`,at],[`ssg:routes.ts`,st]])await i(n.lib(e),t,{pageRoutes:r})};return{config({command:n}){return{oxc:{jsx:{importSource:`preact`}},plugins:Je(e,n,t)}},async start(){for(let[e,t]of[[`env.d.ts`,Qe],[`app.ts`,Ye],[`mdx.ts`,$e],[`use.ts`,ct],[`ssg.ts`,ot],[`pageSamples/styles.module.css`,nt],[`pageSamples/welcome.tsx`,rt],[`pageSamples/page.tsx`,tt],[`pageSamples/404.tsx`,et]])await i(n.lib(e),t,{});for(let[e,t]of[[`pages/404.mdx`,ht],[`components/Link.tsx`,ut],[`components/mdx.ts`,dt],[`app.mdx`,lt],[`router.ts`,yt]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),mt,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,ft],[`server.ts`,pt]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){(!t||t.kind===`create`)&&await u(e),await d(e)},async build(e){await u(e),await d(e)}}}),xt=d({meta:{name:`MDX`,jsxImportSource:`preact`},dependencies:{"path-to-regexp":U.devDependencies[`path-to-regexp`]},devDependencies:{preact:U.devDependencies.preact,"preact-render-to-string":U.devDependencies[`preact-render-to-string`],"@mdx-js/preact":U.devDependencies[`@mdx-js/preact`],"remark-frontmatter":U.devDependencies[`remark-frontmatter`],"remark-mdx-frontmatter":U.devDependencies[`remark-mdx-frontmatter`]},factory:bt}),St={json:`application/json`,form:[`application/x-www-form-urlencoded`,`multipart/form-data`],raw:void 0},Ct=()=>{let t=e=>[`Buffer`,`ArrayBuffer`,`Blob`].includes(e)?{type:`string`,format:`binary`}:ae.Script(e),n=(e,t,n)=>{let r=n?`${t}_${n.replace(/[^\w.-]/g,`_`)}${x(n)}`:t;return`${e.id}_${r}`},r=(e,t,r,i)=>[`#`,`components`,e,n(t,r,i)].join(`/`),a=e=>e.split(`/`).reduce((e,t)=>e+ +!t.includes(`{`),0),o=t=>{if(t.name===`index`)return[`/`];let{tokens:n}=ie(t.pathPattern),r=e=>e.flatMap(e=>{switch(e.type){case`param`:return[e.name];case`wildcard`:return[e.name];case`group`:return r(e.tokens);default:return[]}}),i=(e,t)=>{if(!e.length)return[t];let[n,...a]=e;switch(n.type){case`text`:return i(a,{path:`${t.path}${n.value}`,params:t.params});case`param`:return i(a,{path:`${t.path}{${n.name}}`,params:[...t.params,n.name]});case`wildcard`:return i(a,{path:`${t.path}{${n.name}*}`,params:[...t.params,n.name]});case`group`:{let e=i(a,t),o=i([...n.tokens,...a],t),s=r(n.tokens),c=o.filter(e=>s.some(t=>e.params.includes(t)));return[...e,...c]}}},o=i(n,{path:``,params:[]}),s=t.params.schema.reduce((e,{name:t},n)=>(e[n]=t,e),{});return o.reduce((t,n)=>{let r=e(`/`,n.path);return t.includes(r)||n.params.every((e,t)=>e===s[t])&&t.push(r),t},[]).sort((e,t)=>a(t)-a(e))},s=(e,t)=>{let n=e.params.resolvedType?.properties?.flatMap(n=>RegExp(`\\{${n.name}\\*?\\}`).test(t)?[{$ref:r(`parameters`,e,e.params.id,n.name)}]:[]);return n?.length?n:void 0},c=(e,t)=>{let n=e.validationDefinitions.find(e=>e.method===t&&e.target===`response`);return Array.isArray(n?.variants)?n.variants.reduce((t,{id:n,status:i,contentType:a,body:o})=>(t[i]=wt(i,a)||{description:`Success`,content:{[a||`application/json`]:{schema:o?{$ref:r(`schemas`,e,n)}:{type:`object`}}}},t),{}):{200:{description:`Success - TODO: Add response schema`,content:{"text/plain":{schema:{type:`string`}}}}}},l=e=>{let{parameters:r,schemas:i}={parameters:{},schemas:{}};for(let r of e.validationDefinitions)if(r.target===`response`)for(let{id:a,resolvedType:o}of r.variants)o?.typeboxSchema&&(i[n(e,a)]=t(o.typeboxSchema));else if(r.target===`query`){let{id:a,resolvedType:o}=r.schema;for(let r of o?.properties||[])if(r?.typeboxSchema){let o=n(e,a,r.name);i[o]=t(r.typeboxSchema)}}else{let{id:a,resolvedType:o}=r.schema;o?.typeboxSchema&&(i[n(e,a)]=t(o.typeboxSchema))}if(e.params.resolvedType)for(let i of e.params.resolvedType.properties||[])i?.typeboxSchema&&(r[n(e,e.params.id,i.name)]={name:i.name,in:`path`,required:!0,schema:t(i.typeboxSchema)});return{parameters:r,schemas:i}},u=e=>{let t={},n=e.validationDefinitions.flatMap(e=>e.target===`response`?[]:e.schema.resolvedType?[e]:[]);for(let a of o(e))for(let o of e.methods){let l={responses:c(e,o)},u=s(e,a);u&&(l.parameters=u);let d=n.find(e=>e.method===o&&e.target===`query`);if(d?.schema)for(let t of d.schema.resolvedType?.properties||[])l.parameters||=[],l.parameters.push({name:t.name,in:`query`,required:!t.optional,schema:{$ref:r(`schemas`,e,d.schema.id,t.name)}});let f=n.filter(e=>e.method===o&&Object.keys(i).includes(e.target));f.length&&(l.requestBody={required:!0,content:f.reduce((t,n)=>{let{contentType:i=St[n.target]}=n;if(i){let a={$ref:r(`schemas`,e,n.schema.id)};for(let e of[i].flat())t[e]={schema:a}}return t},{})}),t[a]||(t[a]={}),t[a][o.toLowerCase()]=l}return t};return{generateComponentId:n,generateComponentPath:r,generatePathVariations:o,generateOpenAPISchema:e=>{let{components:t,paths:n}=e.sort(v).flatMap(t=>e.some(e=>e.name!==t.name&&e.name.startsWith(t.name))?[]:[t]).reduce((e,t)=>{let n=u(t),{parameters:r,schemas:i}=l(t);return{paths:{...e.paths,...n},components:{parameters:{...e.components.parameters,...r},schemas:{...e.components.schemas,...i}}}},{paths:{},components:{parameters:{},schemas:{}}});return{paths:n,components:t}}}},wt=(e,t)=>{let n={type:`string`,format:`uri`,...t?{enum:[t]}:{}};return{301:{description:`Moved Permanently`,headers:{Location:{description:`New permanent location`,schema:n}}},302:{description:`Found`,headers:{Location:{description:`Temporary location`,schema:n}}},303:{description:`See Other`,headers:{Location:{description:`Location to GET after POST/PUT/DELETE`,schema:n}}},307:{description:`Temporary Redirect`,headers:{Location:{description:`Temporary location (preserves request method)`,schema:n}}},308:{description:`Permanent Redirect`,headers:{Location:{description:`New permanent location (preserves request method)`,schema:n}}}}[e]},Tt=f((e,t)=>{let{outfile:n=``,...r}={...t},{createPath:i}=h(e),{generateOpenAPISchema:a}=Ct(),o=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),{paths:o,components:s}=a(t),c={...JSON.parse(JSON.stringify(r)),paths:o,components:s},l=/ya?ml/.test(n)?re.stringify(c):JSON.stringify(c,null,2);await ee(i.src(n),l,{})};return{async watch(e){await o(e)},async build(e){await o(e)}}}),Et=d({meta:{name:`OpenAPI`,resolveTypes:!0},factory:Tt}),W={type:`module`,private:!0,name:`@kosmojs/react-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/react-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@vitejs/plugin-react":`^6.0.5`},devDependencies:{"@tanstack/react-query":`^5.101.4`,"@types/react":`^19.2.18`,"@types/react-dom":`^19.2.4`,"path-to-regexp":`^8.4.2`,react:`^19.2.8`,"react-dom":`^19.2.8`,"react-router":`^8.3.0`}},Dt=e=>{let t=e.map(e=>e.orig).join(`/`),r=e=>e.kind===`splat`?`*`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[r(e.parts[0])]:(/\.\w+$/.test(e.orig)||(console.warn(`❗${n([`red`,`bold`],`WARN`)}: React Router v7 only supports dot-suffix mixed segments (e.g. :param.html).`),console.warn(` ${n([`magenta`],e.orig)} in ${n([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:r(e)).join(``)])).join(`/`)},Ot=()=>{let e=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,t=n=>n.flatMap(({index:n,layout:r,children:i})=>{let{name:a,pathTokens:o}={...n,...r};if(!o)return[];let s=`${a}:layout`,c=Dt(o),l=o.at(-1);return e(l)?n&&r?[{name:s,path:c,component:r.id,children:[{name:a,path:`*`,component:n.id}]}]:n?[{path:c,children:[{name:a,path:`*`,component:n.id},...t(i)]}]:r?[{name:s,path:c,component:r.id,children:t(i)}]:[]:n&&r?[{name:s,path:c,component:r.id,children:[{name:a,index:!0,component:n.id},...t(i)]}]:n?[{path:c,children:[{name:a,index:!0,component:n.id},...t(i)]}]:r?[{name:s,path:c,component:r.id,children:t(i)}]:[]});return t},kt=()=>{let e=[`🎉 Well done! You just created a new React route.`,`🚀 Success! A fresh React route is ready to roll.`,`🌟 Nice work! Another React route added to your app.`,`⚡ Quick and easy! Your new React route is good to go.`,`🥳 Congrats! Your app just leveled up with a new React route.`,`🧩 All set! A new React route has been scaffolded.`,`🔧 Scaffold complete! Your new React route is in place.`,`✨ Fantastic! Your new React route is ready.`,`🎯 Nailed it! A brand new React route just landed.`,`💫 Awesome! Another React route joins the lineup.`];return e[Math.floor(Math.random()*e.length)]},At=`import type { ReactNode } from "react";
3218
+ `,bt=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b(),serializeParams(e){return JSON.stringify(e.params)}}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,l=s(t?.templates,_t),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?vt:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:qe()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),gt,{route:r},{overwrite:o})},d=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageLayout`?[t]:[]),r=e.flatMap(({kind:e,entry:n})=>{if(e===`pageRoute`){let{name:e,file:r}=n;return[{...n,layouts:t.flatMap(t=>t.name===e||r.startsWith(`${t.name}/`)?[t]:[]).sort(v)}]}return[]}).sort(v);for(let[e,a]of[[`client.ts`,Xe],[`server.ts`,Ze]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,it],[`router.ts`,at],[`ssg:routes.ts`,st]])await i(n.lib(e),t,{pageRoutes:r})};return{config({command:n}){return{oxc:{jsx:{importSource:`preact`}},plugins:Je(e,n,t)}},async start(){for(let[e,t]of[[`env.d.ts`,Qe],[`app.ts`,Ye],[`mdx.ts`,$e],[`use.ts`,ct],[`ssg.ts`,ot],[`pageSamples/styles.module.css`,nt],[`pageSamples/welcome.tsx`,rt],[`pageSamples/page.tsx`,tt],[`pageSamples/404.tsx`,et]])await i(n.lib(e),t,{});for(let[e,t]of[[`pages/404.mdx`,ht],[`components/Link.tsx`,ut],[`components/mdx.ts`,dt],[`app.mdx`,lt],[`router.ts`,yt]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),mt,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,ft],[`server.ts`,pt]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){(!t||t.kind===`create`)&&await u(e),await d(e)},async build(e){await u(e),await d(e)}}}),xt=d({meta:{name:`MDX`,jsxImportSource:`preact`},dependencies:{"path-to-regexp":U.devDependencies[`path-to-regexp`]},devDependencies:{preact:U.devDependencies.preact,"preact-render-to-string":U.devDependencies[`preact-render-to-string`],"@mdx-js/preact":U.devDependencies[`@mdx-js/preact`],"remark-frontmatter":U.devDependencies[`remark-frontmatter`],"remark-mdx-frontmatter":U.devDependencies[`remark-mdx-frontmatter`]},factory:bt}),St={json:`application/json`,form:[`application/x-www-form-urlencoded`,`multipart/form-data`],raw:void 0},Ct=()=>{let t=e=>[`Buffer`,`ArrayBuffer`,`Blob`].includes(e)?{type:`string`,format:`binary`}:ae.Script(e),n=(e,t,n)=>{let r=n?`${t}_${n.replace(/[^\w.-]/g,`_`)}${x(n)}`:t;return`${e.id}_${r}`},r=(e,t,r,i)=>[`#`,`components`,e,n(t,r,i)].join(`/`),a=e=>e.split(`/`).reduce((e,t)=>e+ +!t.includes(`{`),0),o=t=>{if(t.name===`index`)return[`/`];let{tokens:n}=ie(t.pathPattern),r=e=>e.flatMap(e=>{switch(e.type){case`param`:return[e.name];case`wildcard`:return[e.name];case`group`:return r(e.tokens);default:return[]}}),i=(e,t)=>{if(!e.length)return[t];let[n,...a]=e;switch(n.type){case`text`:return i(a,{path:`${t.path}${n.value}`,params:t.params});case`param`:return i(a,{path:`${t.path}{${n.name}}`,params:[...t.params,n.name]});case`wildcard`:return i(a,{path:`${t.path}{${n.name}*}`,params:[...t.params,n.name]});case`group`:{let e=i(a,t),o=i([...n.tokens,...a],t),s=r(n.tokens),c=o.filter(e=>s.some(t=>e.params.includes(t)));return[...e,...c]}}},o=i(n,{path:``,params:[]}),s=t.params.schema.reduce((e,{name:t},n)=>(e[n]=t,e),{});return o.reduce((t,n)=>{let r=e(`/`,n.path);return t.includes(r)||n.params.every((e,t)=>e===s[t])&&t.push(r),t},[]).sort((e,t)=>a(t)-a(e))},s=(e,t)=>{let n=e.params.resolvedType?.properties?.flatMap(n=>RegExp(`\\{${n.name}\\*?\\}`).test(t)?[{$ref:r(`parameters`,e,e.params.id,n.name)}]:[]);return n?.length?n:void 0},c=(e,t)=>{let n=e.validationDefinitions.find(e=>e.method===t&&e.target===`response`);return Array.isArray(n?.variants)?n.variants.reduce((t,{id:n,status:i,contentType:a,body:o})=>(t[i]=wt(i,a)||{description:`Success`,content:{[a||`application/json`]:{schema:o?{$ref:r(`schemas`,e,n)}:{type:`object`}}}},t),{}):{200:{description:`Success - TODO: Add response schema`,content:{"text/plain":{schema:{type:`string`}}}}}},l=e=>{let{parameters:r,schemas:i}={parameters:{},schemas:{}};for(let r of e.validationDefinitions)if(r.target===`response`)for(let{id:a,resolvedType:o}of r.variants)o?.typeboxSchema&&(i[n(e,a)]=t(o.typeboxSchema));else if(r.target===`query`){let{id:a,resolvedType:o}=r.schema;for(let r of o?.properties||[])if(r?.typeboxSchema){let o=n(e,a,r.name);i[o]=t(r.typeboxSchema)}}else{let{id:a,resolvedType:o}=r.schema;o?.typeboxSchema&&(i[n(e,a)]=t(o.typeboxSchema))}if(e.params.resolvedType)for(let i of e.params.resolvedType.properties||[])i?.typeboxSchema&&(r[n(e,e.params.id,i.name)]={name:i.name,in:`path`,required:!0,schema:t(i.typeboxSchema)});return{parameters:r,schemas:i}},u=e=>{let t={},n=e.validationDefinitions.flatMap(e=>e.target===`response`?[]:e.schema.resolvedType?[e]:[]);for(let a of o(e))for(let o of e.methods){let l={responses:c(e,o)},u=s(e,a);u&&(l.parameters=u);let d=n.find(e=>e.method===o&&e.target===`query`);if(d?.schema)for(let t of d.schema.resolvedType?.properties||[])l.parameters||=[],l.parameters.push({name:t.name,in:`query`,required:!t.optional,schema:{$ref:r(`schemas`,e,d.schema.id,t.name)}});let f=n.filter(e=>e.method===o&&Object.keys(i).includes(e.target));f.length&&(l.requestBody={required:!0,content:f.reduce((t,n)=>{let{contentType:i=St[n.target]}=n;if(i){let a={$ref:r(`schemas`,e,n.schema.id)};for(let e of[i].flat())t[e]={schema:a}}return t},{})}),t[a]||(t[a]={}),t[a][o.toLowerCase()]=l}return t};return{generateComponentId:n,generateComponentPath:r,generatePathVariations:o,generateOpenAPISchema:e=>{let t=new Map;for(let n of e)t.set(n.name,o(n));let{components:n,paths:r}=e.sort(v).flatMap(n=>{let r=t.get(n.name)??[];return r.length>0&&e.some(e=>{if(e.name===n.name)return!1;let i=t.get(e.name)??[],a=new Set(i);return r.every(e=>a.has(e))})?[]:[n]}).reduce((e,t)=>{let n=u(t),{parameters:r,schemas:i}=l(t);return{paths:{...e.paths,...n},components:{parameters:{...e.components.parameters,...r},schemas:{...e.components.schemas,...i}}}},{paths:{},components:{parameters:{},schemas:{}}});return{paths:r,components:n}}}},wt=(e,t)=>{let n={type:`string`,format:`uri`,...t?{enum:[t]}:{}};return{301:{description:`Moved Permanently`,headers:{Location:{description:`New permanent location`,schema:n}}},302:{description:`Found`,headers:{Location:{description:`Temporary location`,schema:n}}},303:{description:`See Other`,headers:{Location:{description:`Location to GET after POST/PUT/DELETE`,schema:n}}},307:{description:`Temporary Redirect`,headers:{Location:{description:`Temporary location (preserves request method)`,schema:n}}},308:{description:`Permanent Redirect`,headers:{Location:{description:`New permanent location (preserves request method)`,schema:n}}}}[e]},Tt=f((e,t)=>{let{outfile:n=``,...r}={...t},{createPath:i}=h(e),{generateOpenAPISchema:a}=Ct(),o=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]),{paths:o,components:s}=a(t),c={...JSON.parse(JSON.stringify(r)),paths:o,components:s},l=/ya?ml/.test(n)?re.stringify(c):JSON.stringify(c,null,2);await ee(i.src(n),l,{})};return{async watch(e){await o(e)},async build(e){await o(e)}}}),Et=d({meta:{name:`OpenAPI`,resolveTypes:!0},factory:Tt}),W={type:`module`,private:!0,name:`@kosmojs/react-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/react-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@vitejs/plugin-react":`^6.0.5`},devDependencies:{"@tanstack/react-query":`^5.101.4`,"@types/react":`^19.2.18`,"@types/react-dom":`^19.2.4`,"path-to-regexp":`^8.4.2`,react:`^19.2.8`,"react-dom":`^19.2.8`,"react-router":`^8.3.0`}},Dt=e=>{let t=e.map(e=>e.orig).join(`/`),r=e=>e.kind===`splat`?`*`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[r(e.parts[0])]:(/\.\w+$/.test(e.orig)||(console.warn(`❗${n([`red`,`bold`],`WARN`)}: React Router v7 only supports dot-suffix mixed segments (e.g. :param.html).`),console.warn(` ${n([`magenta`],e.orig)} in ${n([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:r(e)).join(``)])).join(`/`)},Ot=()=>{let e=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,t=n=>n.flatMap(({index:n,layout:r,children:i})=>{let{name:a,pathTokens:o}={...n,...r};if(!o)return[];let s=`${a}:layout`,c=Dt(o),l=o.at(-1);return e(l)?n&&r?[{name:s,path:c,component:r.id,children:[{name:a,path:`*`,component:n.id}]}]:n?[{path:c,children:[{name:a,path:`*`,component:n.id},...t(i)]}]:r?[{name:s,path:c,component:r.id,children:t(i)}]:[]:n&&r?[{name:s,path:c,component:r.id,children:[{name:a,index:!0,component:n.id},...t(i)]}]:n?[{path:c,children:[{name:a,index:!0,component:n.id},...t(i)]}]:r?[{name:s,path:c,component:r.id,children:t(i)}]:[]});return t},kt=()=>{let e=[`🎉 Well done! You just created a new React route.`,`🚀 Success! A fresh React route is ready to roll.`,`🌟 Nice work! Another React route added to your app.`,`⚡ Quick and easy! Your new React route is good to go.`,`🥳 Congrats! Your app just leveled up with a new React route.`,`🧩 All set! A new React route has been scaffolded.`,`🔧 Scaffold complete! Your new React route is in place.`,`✨ Fantastic! Your new React route is ready.`,`🎯 Nailed it! A brand new React route just landed.`,`💫 Awesome! Another React route joins the lineup.`];return e[Math.floor(Math.random()*e.length)]},At=`import type { ReactNode } from "react";
3201
3219
 
3202
3220
  export const AppProvider = ({ children }: { children: ReactNode }) => {
3203
3221
  return children;
@@ -3698,28 +3716,15 @@ export const getQueryClient = (): QueryClient => {
3698
3716
  export const loaderFactory = (opt?: { withPreload?: boolean }) => {
3699
3717
  return (componentLoader: ComponentLoader) => {
3700
3718
  const loader = async (arg: unknown) => {
3701
- try {
3702
- const component = await componentLoader();
3703
- // Return null, not undefined, when a route has no loader. RR keys
3704
- // hydration data by route id; an undefined value is dropped by
3705
- // JSON.stringify during serialization, leaving the id absent, which
3706
- // makes RR re-run the loader on the client and double-render. null
3707
- // survives serialization, so the id stays present and RR skips it.
3708
- return typeof component.loader === "function"
3709
- ? await component.loader(arg)
3710
- : null;
3711
- } catch (error) {
3712
- // TODO: swallowing loader errors is wrong. Returning null hydrates the
3713
- // route as "loaded, value null" - RR never sees the failure, so no
3714
- // errorElement/ErrorBoundary fires on server or client, and this
3715
- // console.error runs server-side during SSR so the client sees nothing.
3716
- // Proper fix: let the error reach RR's \`context.errors\` (rethrow, or
3717
- // return a Response/data() with an error status) so it serializes into
3718
- // __staticRouterHydrationData.errors and renders the route boundary
3719
- // isomorphically.
3720
- console.error(error);
3721
- return null;
3722
- }
3719
+ const component = await componentLoader();
3720
+ // Return null, not undefined, when a route has no loader.
3721
+ // React Router keys hydration data by route id;
3722
+ // an undefined value is dropped by JSON.stringify during serialization,
3723
+ // leaving the id absent, which makes RR re-run the loader on the client and double-render.
3724
+ // null survives serialization, so the id stays present.
3725
+ return typeof component.loader === "function"
3726
+ ? await component.loader(arg)
3727
+ : null;
3723
3728
  };
3724
3729
  return opt?.withPreload ? { loader } : {};
3725
3730
  };
@@ -3925,7 +3930,7 @@ export default routerFactory((routes) => {
3925
3930
  },
3926
3931
  };
3927
3932
  });
3928
- `,$t=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()},partials:{routePartial:Nt}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=Ot(),l=e=>!e?.trim().length,u=s(t?.templates,Xt),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Zt:u(r.name,r),{route:r,message:kt()},{overwrite:l}):t===`pageLayout`&&await a(n.pages(r.file),Yt,{route:r},{overwrite:l})},f=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(v),r=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),a=o(m(r));for(let[e,t]of[[`client.ts`,Mt],[`server.ts`,Pt]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a});await i(n.lib(`router.tsx`),Ht,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[oe(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,``],[`react.ts`,Vt],[`pageSamples/styles.module.css`,Lt],[`pageSamples/welcome.tsx`,Rt],[`pageSamples/page.tsx`,It],[`pageSamples/404.tsx`,Ft],...t?.tanstack?.query?[[`app.tsx`,jt],[`query.ts`,zt]]:[[`app.tsx`,At],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.tsx`,Jt],[`components/Link.tsx`,Wt],[`app.tsx`,Ut],[`router.ts`,Qt]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:l});await a(n.src(`index.html`),qt,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Gt],[`server.ts`,Kt]])await a(n.entry(e),t,{},{overwrite:l})},async watch(e,t){(!t||t.kind===`create`)&&await d(e),await f(e)},async build(e){await d(e),await f(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?Bt:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),en=d({meta:{name:`React`,jsx:`preserve`,jsxImportSource:`react`},dependencies(e){return{react:W.devDependencies.react,"react-router":W.devDependencies[`react-router`],"path-to-regexp":W.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/react-query":W.devDependencies[`@tanstack/react-query`]}:{}}},devDependencies:{"@types/react":W.devDependencies[`@types/react`],"@types/react-dom":W.devDependencies[`@types/react-dom`],"react-dom":W.devDependencies[`react-dom`]},factory:$t}),G={type:`module`,private:!0,name:`@kosmojs/solid-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/solid-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"vite-plugin-solid":`^2.11.14`},devDependencies:{"@solidjs/router":`^1.0.0`,"@tanstack/solid-query":`^5.101.4`,"path-to-regexp":`^8.4.2`,"solid-js":`^1.9.14`}},tn=()=>{let e=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,t=t=>t?.kind===`param`?t.parts[0]?.kind===`optional`||e(t):!1,n=r=>r.flatMap(({index:r,layout:i,children:a})=>{let{pathTokens:o}={...r,...i},s=K(o.map((e,n)=>e.kind===`param`&&(t(o[n+1])||a.some(e=>e.index?.pathTokens.some(t)))?{...e,parts:[{...e.parts[0],kind:`required`}]}:e)),c=o.at(-1);if(e(c)){let e=K([c]);return r&&i?[{path:s,component:i.id,children:[{path:e,component:r.id}]}]:r?[{path:s,children:[{path:e,component:r.id},...n(a)]}]:i?[{path:s,component:i.id,children:n(a)}]:[]}return r&&i?[{path:s,component:i.id,children:[{path:`/`,component:r.id},...n(a)]}]:r?[{path:s,children:[{path:`/`,component:r.id},...n(a)]}]:i?[{path:s,component:i.id,children:n(a)}]:[]});return n},K=e=>{let t=e.map(e=>e.orig).join(`/`),r=e=>e.kind===`splat`?`*${e.name}`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[r(e.parts[0])]:(e.parts.length&&(console.warn(`❗${n([`red`,`bold`],`WARN`)}: At the moment Solid Router does not support mixed path segments.`),console.warn(` ${n([`magenta`],e.orig)} segment in ${n([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:r(e)).join(``)])).join(`/`)},nn=()=>{let e=[`🎉 Well done! You just created a new Solid route.`,`🚀 Success! A fresh Solid route is ready to roll.`,`🌟 Nice work! Another Solid route added to your app.`,`🧩 All set! A new Solid route has been scaffolded.`,`🔧 Scaffold complete! Your new Solid route is in place.`,`✅ Built! Your Solid route is scaffolded and ready.`,`✨ Fantastic! Your new Solid route is good to go.`,`🎯 Nailed it! A brand new Solid route just landed.`,`💫 Awesome! Another Solid route joins the party.`,`⚡ Lightning fast! A new Solid route created successfully.`];return e[Math.floor(Math.random()*e.length)]},rn=`import type { ParentComponent } from "solid-js";
3933
+ `,$t=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()},partials:{routePartial:Nt}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=Ot(),l=e=>!e?.trim().length,u=s(t?.templates,Xt),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Zt:u(r.name,r),{route:r,message:kt()},{overwrite:l}):t===`pageLayout`&&await a(n.pages(r.file),Yt,{route:r},{overwrite:l})},f=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(v),r=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),a=o(m(r));for(let[e,t]of[[`client.ts`,Mt],[`server.ts`,Pt]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a});await i(n.lib(`router.tsx`),Ht,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[oe(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,``],[`react.ts`,Vt],[`pageSamples/styles.module.css`,Lt],[`pageSamples/welcome.tsx`,Rt],[`pageSamples/page.tsx`,It],[`pageSamples/404.tsx`,Ft],...t?.tanstack?.query?[[`app.tsx`,jt],[`query.ts`,zt]]:[[`app.tsx`,At],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.tsx`,Jt],[`components/Link.tsx`,Wt],[`app.tsx`,Ut],[`router.ts`,Qt]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:l});await a(n.src(`index.html`),qt,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Gt],[`server.ts`,Kt]])await a(n.entry(e),t,{},{overwrite:l})},async watch(e,t){(!t||t.kind===`create`)&&await d(e),await f(e)},async build(e){await d(e),await f(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?Bt:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),en=d({meta:{name:`React`,jsx:`preserve`,jsxImportSource:`react`},dependencies(e){return{react:W.devDependencies.react,"react-router":W.devDependencies[`react-router`],"path-to-regexp":W.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/react-query":W.devDependencies[`@tanstack/react-query`]}:{}}},devDependencies:{"@types/react":W.devDependencies[`@types/react`],"@types/react-dom":W.devDependencies[`@types/react-dom`],"react-dom":W.devDependencies[`react-dom`]},factory:$t}),G={type:`module`,private:!0,name:`@kosmojs/solid-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/solid-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"vite-plugin-solid":`^2.11.14`},devDependencies:{"@solidjs/router":`^1.0.0`,"@tanstack/solid-query":`^5.101.4`,"path-to-regexp":`^8.4.2`,"solid-js":`^1.9.14`}},tn=()=>{let e=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,t=t=>t?.kind===`param`?t.parts[0]?.kind===`optional`||e(t):!1,n=r=>r.flatMap(({index:r,layout:i,children:a})=>{let{pathTokens:o}={...r,...i},s=K(o.map((e,n)=>e.kind===`param`&&(t(o[n+1])||a.some(e=>e.index?.pathTokens.some(t)))?{...e,parts:[{...e.parts[0],kind:`required`}]}:e)),c=o.at(-1);if(e(c)){let e=K([c]);return r&&i?[{path:s,component:i.id,children:[{path:e,component:r.id}]}]:r?[{path:s,children:[{path:e,component:r.id},...n(a)]}]:i?[{path:s,component:i.id,children:n(a)}]:[]}return r&&i?[{path:s,component:i.id,children:[{path:`/`,component:r.id},...n(a)]}]:r?[{path:s,children:[{path:`/`,component:r.id},...n(a)]}]:i?[{path:s,component:i.id,children:n(a)}]:[]});return n},K=e=>{let t=e.map(e=>e.orig).join(`/`),r=e=>e.kind===`splat`?`*${e.name}`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[r(e.parts[0])]:(e.parts.length&&(console.warn(`❗${n([`red`,`bold`],`WARN`)}: At the moment Solid Router does not support mixed path segments.`),console.warn(` ${n([`magenta`],e.orig)} segment in ${n([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:r(e)).join(``)])).join(`/`)},nn=()=>{let e=[`🎉 Well done! You just created a new Solid route.`,`🚀 Success! A fresh Solid route is ready to roll.`,`🌟 Nice work! Another Solid route added to your app.`,`🧩 All set! A new Solid route has been scaffolded.`,`🔧 Scaffold complete! Your new Solid route is in place.`,`✅ Built! Your Solid route is scaffolded and ready.`,`✨ Fantastic! Your new Solid route is good to go.`,`🎯 Nailed it! A brand new Solid route just landed.`,`💫 Awesome! Another Solid route joins the party.`,`⚡ Lightning fast! A new Solid route created successfully.`];return e[Math.floor(Math.random()*e.length)]},rn=`import type { ParentComponent } from "solid-js";
3929
3934
 
3930
3935
  export const AppProvider: ParentComponent = (props) => {
3931
3936
  return props.children;
@@ -4065,7 +4070,12 @@ export const renderToStream: RenderToStreamWrapper<
4065
4070
  > = async (resolver, { headerTags = [], ...options } = {}) => {
4066
4071
  const stream = renderToStreamOrig(() => resolver().component, options);
4067
4072
  const { readable, writable } = new TransformStream<string, string>();
4068
- stream.pipeTo(writable);
4073
+ /**
4074
+ * On failure, pipeTo aborts the writable, which errors the readable side
4075
+ * and surfaces the error to the stream consumer; catching here only keeps
4076
+ * the rejection from escaping as an unhandled one.
4077
+ * */
4078
+ stream.pipeTo(writable).catch(() => {});
4069
4079
  return {
4070
4080
  head: [...headerTags, generateHydrationScript()].join("\\n"),
4071
4081
  html: readable,
@@ -4430,7 +4440,7 @@ export const createRouters = (
4430
4440
 
4431
4441
  const serverRouter = (url: URL) => {
4432
4442
  const component = (
4433
- <Router root={app} base={base} url={url.pathname}>
4443
+ <Router root={app} base={base} url={url.pathname + url.search}>
4434
4444
  {routes}
4435
4445
  </Router>
4436
4446
  );
@@ -4448,15 +4458,10 @@ export default createRouterFactory<RouteDefinition, JSX.Element>();
4448
4458
  export const loaderFactory = (opt?: { withPreload?: boolean }) => {
4449
4459
  return (componentLoader: ComponentLoader) => {
4450
4460
  const preload = async () => {
4451
- try {
4452
- const component = await componentLoader();
4453
- return typeof component.preload === "function"
4454
- ? component.preload
4455
- : undefined;
4456
- } catch (error) {
4457
- console.error(error);
4458
- return;
4459
- }
4461
+ const component = await componentLoader();
4462
+ return typeof component.preload === "function"
4463
+ ? component.preload
4464
+ : undefined;
4460
4465
  };
4461
4466
  return opt?.withPreload ? { preload } : {};
4462
4467
  };
@@ -4604,16 +4609,19 @@ export default routerFactory((routes) => {
4604
4609
  },
4605
4610
  };
4606
4611
  });
4607
- `,On=f((e,t)=>{let{generators:n=[]}=e.config,{createPath:r,createImportHelpers:i}=h(e),{renderToFile:a}=_({helpers:{...i({origin:`lib`}),...b()},partials:{routePartial:sn}}),{renderToFile:o}=_({helpers:i({origin:`src`})}),l=tn(),u=e=>!e?.trim().length,d=s(t?.templates,Tn),f=async e=>{for(let{kind:t,entry:n}of e)t===`pageRoute`?await o(r.pages(n.file),n.name===`index`?En:d(n.name,n),{route:n,message:nn()},{overwrite:u}):t===`pageLayout`&&await o(r.pages(n.file),wn,{route:n},{overwrite:u})},p=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(v),n=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),i=l(m(n));for(let[e,t]of[[`client.ts`,on],[`server.ts`,cn]])await a(r.libEntry(e),t,{pageEntries:n,nestedRoutes:i});await a(r.lib(`router.tsx`),hn,{entries:e,indexRoutes:t})};return{config({command:e}){let{templates:r,...i}={...t};return{oxc:{jsx:{importSource:`solid-js`}},plugins:e===`build`?[w({...i,...n.some(e=>e.meta.slot===`ssr`)?{ssr:!0,solid:{...i?.solid,hydratable:!0}}:{}})]:[w({...i,dev:!0,hot:!0})]}},async start(){for(let[e,n]of[[`env.d.ts`,``],[`solid.ts`,gn],[`unwrap.ts`,_n],[`pageSamples/styles.module.css`,dn],[`pageSamples/welcome.tsx`,fn],[`pageSamples/page.tsx`,un],[`pageSamples/404.tsx`,ln],...t?.tanstack?.query?[[`app.tsx`,an],[`query.ts`,pn]]:[[`app.tsx`,rn],[`query.ts`,`/** tanstack query disabled */`]]])await a(r.lib(e),n,{});for(let[e,t]of[[`pages/404.tsx`,Cn],[`components/Link.tsx`,yn],[`app.tsx`,vn],[`router.ts`,Dn]])await o(r.src(e),t,{entryDir:c.entryDir},{overwrite:u});await o(r.src(`index.html`),Sn,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,bn],[`server.ts`,xn]])await o(r.entry(e),t,{},{overwrite:u})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)},async ssrBuild(){await a(r.lib(`query.ts`),t?.tanstack?.query?mn:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),kn=d({meta:{name:`SolidJS`,jsx:`preserve`,jsxImportSource:`solid-js`},dependencies(e){return{"solid-js":G.devDependencies[`solid-js`],"@solidjs/router":G.devDependencies[`@solidjs/router`],"path-to-regexp":G.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/solid-query":G.devDependencies[`@tanstack/solid-query`]}:{}}},factory:On}),An=f(r=>{let{generators:i=[],refineTypeName:a,...o}={...r.config},{createPath:s}=h(r);return{async postBuild(){let a=s.distDir(`ssg`),c=t(a,`../ssr/server.js`);if(!await se(c,ce.F_OK).then(()=>!0,()=>!1)){console.error(),console.error(n(`red`,`❗Please enable ssrGenerator in ${r.name}/kosmo.config.ts`)),console.error(` SSG generator can not run without SSR server`),console.error();return}let l=te(`${r.name}: SSG`);l.append(`preparing...`);let{createDisposableServer:u}=await import(c);await T(t(a,`../client/assets`),e(a,`assets`),{recursive:!0}),l.append(`bundling routes...`),await S(p(o,...i.map(({factory:e})=>e(r).config?.({kind:`client`,command:`build`})),{root:s.lib(),appType:`custom`,plugins:[y.tsconfigPaths(r),y.nodePrefix()],resolve:{conditions:[`node`]},build:{ssr:s.lib(`ssg.ts`),target:`esnext`,sourcemap:!1,emptyOutDir:!0,rolldownOptions:{output:{dir:a,entryFileNames:`routes.js`,format:`esm`}}}}));try{let t=await import(e(a,`routes.js`)).then(e=>e.default);u(async n=>{for(let[r,i]of t.entries()){l.append(`[ ${r+1} of ${t.length} ] ${i}`);let o=await jn(n,i);o!==void 0&&(await le(e(a,i),{recursive:!0}),await ue(e(a,e(i,`index.html`)),o,`utf8`))}l.succeed(`done ✨`)})}finally{await E(`${a}/routes.js`)}}}}),jn=async(e,t)=>{try{let n=`http://localhost:${e}${t}`;return await(await fetch(n)).text()}catch(e){console.error(n(`red`,`✗ SSG: Failed generating ${t} route: ${e.message}`));return}},Mn=d({meta:{name:`SSG`,slot:`ssg`},factory:An}),q={type:`module`,private:!0,name:`@kosmojs/ssr-generator`,version:`0.2.10`,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:^`,vite:`^8.2.1`},devDependencies:{"@hono/node-server":`^2.1.0`,hono:`^4.13.1`,"light-my-request":`^6.6.0`,tinyglobby:`^0.2.17`}},Nn=`{{#if apiGenerator}}
4612
+ `,On=f((e,t)=>{let{generators:n=[]}=e.config,{createPath:r,createImportHelpers:i}=h(e),{renderToFile:a}=_({helpers:{...i({origin:`lib`}),...b()},partials:{routePartial:sn}}),{renderToFile:o}=_({helpers:i({origin:`src`})}),l=tn(),u=e=>!e?.trim().length,d=s(t?.templates,Tn),f=async e=>{for(let{kind:t,entry:n}of e)t===`pageRoute`?await o(r.pages(n.file),n.name===`index`?En:d(n.name,n),{route:n,message:nn()},{overwrite:u}):t===`pageLayout`&&await o(r.pages(n.file),wn,{route:n},{overwrite:u})},p=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(v),n=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),i=l(m(n));for(let[e,t]of[[`client.ts`,on],[`server.ts`,cn]])await a(r.libEntry(e),t,{pageEntries:n,nestedRoutes:i});await a(r.lib(`router.tsx`),hn,{entries:e,indexRoutes:t})};return{config({command:e}){let{templates:r,...i}={...t};return{oxc:{jsx:{importSource:`solid-js`}},plugins:e===`build`?[w({...i,...n.some(e=>e.meta.slot===`ssr`)?{ssr:!0,solid:{...i?.solid,hydratable:!0}}:{}})]:[w({...i,dev:!0,hot:!0})]}},async start(){for(let[e,n]of[[`env.d.ts`,``],[`solid.ts`,gn],[`unwrap.ts`,_n],[`pageSamples/styles.module.css`,dn],[`pageSamples/welcome.tsx`,fn],[`pageSamples/page.tsx`,un],[`pageSamples/404.tsx`,ln],...t?.tanstack?.query?[[`app.tsx`,an],[`query.ts`,pn]]:[[`app.tsx`,rn],[`query.ts`,`/** tanstack query disabled */`]]])await a(r.lib(e),n,{});for(let[e,t]of[[`pages/404.tsx`,Cn],[`components/Link.tsx`,yn],[`app.tsx`,vn],[`router.ts`,Dn]])await o(r.src(e),t,{entryDir:c.entryDir},{overwrite:u});await o(r.src(`index.html`),Sn,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,bn],[`server.ts`,xn]])await o(r.entry(e),t,{},{overwrite:u})},async watch(e,t){(!t||t.kind===`create`)&&await f(e),await p(e)},async build(e){await f(e),await p(e)},async ssrBuild(){await a(r.lib(`query.ts`),t?.tanstack?.query?mn:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),kn=d({meta:{name:`SolidJS`,jsx:`preserve`,jsxImportSource:`solid-js`},dependencies(e){return{"solid-js":G.devDependencies[`solid-js`],"@solidjs/router":G.devDependencies[`@solidjs/router`],"path-to-regexp":G.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/solid-query":G.devDependencies[`@tanstack/solid-query`]}:{}}},factory:On}),An=f(r=>{let{generators:i=[],refineTypeName:a,...o}={...r.config},{createPath:s}=h(r);return{async postBuild(){let a=s.distDir(`ssg`),c=t(a,`../ssr/server.js`);if(!await se(c,ce.F_OK).then(()=>!0,()=>!1)){console.error(),console.error(n(`red`,`❗Please enable ssrGenerator in ${r.name}/kosmo.config.ts`)),console.error(` SSG generator can not run without SSR server`),console.error();return}let l=te(`${r.name}: SSG`);l.append(`preparing...`);let{createDisposableServer:u}=await import(c);await T(t(a,`../client/assets`),e(a,`assets`),{recursive:!0}),l.append(`bundling routes...`),await S(p(o,...i.map(({factory:e})=>e(r).config?.({kind:`client`,command:`build`})),{root:s.lib(),appType:`custom`,plugins:[y.tsconfigPaths(r),y.nodePrefix()],resolve:{conditions:[`node`]},build:{ssr:s.lib(`ssg.ts`),target:`esnext`,sourcemap:!1,emptyOutDir:!0,rolldownOptions:{output:{dir:a,entryFileNames:`routes.js`,format:`esm`}}}}));try{let t=await import(e(a,`routes.js`)).then(e=>e.default);u(async n=>{for(let[r,i]of t.entries()){l.append(`[ ${r+1} of ${t.length} ] ${i}`);let o=await jn(n,i);o!==void 0&&(await le(e(a,i),{recursive:!0}),await ue(e(a,e(i,`index.html`)),o,`utf8`))}l.succeed(`done ✨`)})}finally{await E(`${a}/routes.js`)}}}}),jn=async(e,t)=>{try{let n=`http://localhost:${e}${t}`;return await(await fetch(n)).text()}catch(e){console.error(n(`red`,`✗ SSG: Failed generating ${t} route: ${e.message}`));return}},Mn=d({meta:{name:`SSG`,slot:`ssg`},factory:An}),q={type:`module`,private:!0,name:`@kosmojs/ssr-generator`,version:`0.3.0`,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:^`,vite:`^8.2.1`},devDependencies:{"@hono/node-server":`^2.1.0`,hono:`^4.13.1`,"light-my-request":`^6.6.0`,tinyglobby:`^0.2.17`}},Nn=`{{#if apiGenerator}}
4608
4613
  export { default as apiApp } from "{{ createImport 'api' 'app' }}";
4609
4614
  {{else}}
4610
4615
  export const apiApp = undefined;
4611
4616
  {{/if}}
4612
4617
  `,Pn=`import { AsyncLocalStorage } from "node:async_hooks";
4613
4618
 
4619
+ import type { FetchApp, NodeApp } from "@kosmojs/core";
4620
+
4614
4621
  export type RequestContext = {
4615
4622
  headers?: HeadersInit;
4616
4623
  tsqClient?: unknown;
4624
+ error?: unknown;
4617
4625
  };
4618
4626
 
4619
4627
  export const redirectCodes = [
@@ -4646,6 +4654,10 @@ export const maxRedirects = 5;
4646
4654
  * Server-only module - never reaches browser bundles.
4647
4655
  * */
4648
4656
  export const store = new AsyncLocalStorage<RequestContext>();
4657
+
4658
+ export const isFetchApp = (app: FetchApp | NodeApp): app is FetchApp => {
4659
+ return typeof (app as FetchApp).fetch === "function";
4660
+ };
4649
4661
  `,Fn=`import { type RequestContext, store } from "./base";
4650
4662
 
4651
4663
  import { renderWrapper } from "{{ createImport 'libEntry' 'server' }}";
@@ -4664,12 +4676,22 @@ export const withSsrContext = <T>(
4664
4676
  ): T => {
4665
4677
  return store.run(context, () => renderWrapper(context, render));
4666
4678
  };
4679
+
4680
+ export const errorProvider = () => {
4681
+ return store.getStore()?.error;
4682
+ };
4667
4683
  `,In=`import { inject } from "light-my-request";
4668
4684
 
4669
- import { type FetchApp, isFetchApp, type NodeApp } from "@kosmojs/core";
4685
+ import type { FetchApp, NodeApp } from "@kosmojs/core";
4670
4686
  import type { Transport } from "@kosmojs/core/fetch";
4671
4687
 
4672
- import { maxRedirects, redirectCodes, ssrOrigin, store } from "./base";
4688
+ import {
4689
+ isFetchApp,
4690
+ maxRedirects,
4691
+ redirectCodes,
4692
+ ssrOrigin,
4693
+ store,
4694
+ } from "./base";
4673
4695
 
4674
4696
  import { apiApp } from "{{ createImport 'lib' '@ssr/api' }}";
4675
4697
 
@@ -4680,16 +4702,61 @@ const headersProvider = (): HeadersInit | undefined => {
4680
4702
  return store.getStore()?.headers;
4681
4703
  };
4682
4704
 
4683
- /**
4684
- * Builds a fetch-compatible transport that dispatches requests
4685
- * directly into the given app - no sockets, no interception.
4686
- * Redirects are followed in-process, including the 303 and 301/302 method rewrite to GET.
4687
- * */
4688
- const createTransport = (app: FetchApp | NodeApp): Transport => {
4689
- const dispatch = isFetchApp(app) //
4705
+ const createDispatch = (app: FetchApp | NodeApp) => {
4706
+ return isFetchApp(app)
4690
4707
  ? app.fetch
4691
- : createNodeDispatch(app);
4708
+ : async (request: Request): Promise<Response> => {
4709
+ /**
4710
+ * Node dispatch: serializes the web Request into light-my-request's
4711
+ * injection format and lifts the injected response back into a web Response.
4712
+ * */
4713
+ const url = new URL(request.url);
4714
+
4715
+ const payload = ["GET", "HEAD"].includes(request.method)
4716
+ ? undefined
4717
+ : Buffer.from(await request.arrayBuffer());
4718
+
4719
+ const result = await inject(app.callback() as never, {
4720
+ method: request.method as never,
4721
+ url: url.pathname + url.search,
4722
+ headers: Object.fromEntries(request.headers),
4723
+ ...(payload?.length ? { payload } : {}),
4724
+ });
4725
+
4726
+ const headers = new Headers();
4727
+
4728
+ for (const [key, value] of Object.entries(result.headers)) {
4729
+ for (const entry of Array.isArray(value) ? value : [value]) {
4730
+ if (entry !== undefined) {
4731
+ headers.append(key, String(entry));
4732
+ }
4733
+ }
4734
+ }
4735
+
4736
+ /**
4737
+ * 204/304 responses must not carry a body per the Response
4738
+ * constructor contract.
4739
+ * */
4740
+ const body = [204, 304].includes(result.statusCode)
4741
+ ? null
4742
+ : new Uint8Array(result.rawPayload);
4743
+
4744
+ return new Response(body, {
4745
+ status: result.statusCode,
4746
+ statusText: result.statusMessage,
4747
+ headers,
4748
+ });
4749
+ };
4750
+ };
4751
+
4752
+ const createTransport = (app: FetchApp | NodeApp): Transport => {
4753
+ const dispatch = createDispatch(app);
4692
4754
 
4755
+ /**
4756
+ * Build a fetch-compatible transport that dispatches requests
4757
+ * directly into the given app - no sockets, no interception.
4758
+ * Redirects are followed in-process, including the 303 and 301/302 method rewrite to GET.
4759
+ * */
4693
4760
  return async (input, init) => {
4694
4761
  /**
4695
4762
  * Request-scoped headers act as defaults: anything set explicitly
@@ -4757,52 +4824,65 @@ const createTransport = (app: FetchApp | NodeApp): Transport => {
4757
4824
  };
4758
4825
  };
4759
4826
 
4760
- /**
4761
- * Node dispatch: serializes the web Request into light-my-request's
4762
- * injection format and lifts the injected response back into a web Response.
4763
- * */
4764
- const createNodeDispatch = (app: NodeApp) => {
4765
- return async (request: Request): Promise<Response> => {
4766
- const url = new URL(request.url);
4827
+ const ssrTransport = apiApp ? createTransport(apiApp) : undefined;
4767
4828
 
4768
- const payload = ["GET", "HEAD"].includes(request.method)
4769
- ? undefined
4770
- : Buffer.from(await request.arrayBuffer());
4771
-
4772
- const result = await inject(app.callback() as never, {
4773
- method: request.method as never,
4774
- url: url.pathname + url.search,
4775
- headers: Object.fromEntries(request.headers),
4776
- ...(payload?.length ? { payload } : {}),
4777
- });
4778
-
4779
- const headers = new Headers();
4780
-
4781
- for (const [key, value] of Object.entries(result.headers)) {
4782
- for (const entry of Array.isArray(value) ? value : [value]) {
4783
- if (entry !== undefined) {
4784
- headers.append(key, String(entry));
4829
+ export const transport = ssrTransport
4830
+ ? async (input: RequestInfo | URL, init?: RequestInit) => {
4831
+ try {
4832
+ const response = await ssrTransport(input, init);
4833
+ if (response?.ok) {
4834
+ return response;
4835
+ }
4836
+ // the rethrow here needed cause ssrTransport does not throw on non-2xx responses
4837
+ throw new SSRFetchError([
4838
+ input,
4839
+ response,
4840
+ typeof response?.text === "function"
4841
+ ? await response.text()
4842
+ : response?.statusText,
4843
+ ]);
4844
+ } catch (error) {
4845
+ /**
4846
+ * Capture the fetch error at the transport level and stash it on the request store.
4847
+ * Some frameworks - Solid notably - swallow a rejecting loader and still emit a partial render tree.
4848
+ * Storing the error here keeps it observable regardless of how the framework handles the loader rejection.
4849
+ * */
4850
+ const storage = store.getStore();
4851
+ if (storage) {
4852
+ storage.error = error;
4785
4853
  }
4854
+ throw error;
4786
4855
  }
4787
4856
  }
4857
+ : undefined; // let fetch clients pick the transport
4858
+
4859
+ class SSRFetchError extends Error {
4860
+ constructor([input, response, message]: [
4861
+ input: RequestInfo | URL,
4862
+ response: Response,
4863
+ message: string | undefined,
4864
+ ]) {
4865
+ const pathname = pathnameOf(input);
4866
+ const status = response.status ?? "unknown";
4867
+ super(\`\${pathname}: \${status} [ \${message} ]\`.trim());
4868
+ this.name = "SSRFetchError";
4869
+ }
4870
+ }
4788
4871
 
4789
- /**
4790
- * 204/304 responses must not carry a body per the Response
4791
- * constructor contract.
4792
- * */
4793
- const body = [204, 304].includes(result.statusCode)
4794
- ? null
4795
- : new Uint8Array(result.rawPayload);
4796
-
4797
- return new Response(body, {
4798
- status: result.statusCode,
4799
- statusText: result.statusMessage,
4800
- headers,
4801
- });
4802
- };
4872
+ const pathnameOf = (input: RequestInfo | URL): string => {
4873
+ try {
4874
+ if (typeof input === "string") {
4875
+ return new URL(input, "http://x").pathname;
4876
+ }
4877
+ if (input instanceof URL) {
4878
+ return input.pathname;
4879
+ }
4880
+ if (input instanceof Request) {
4881
+ return new URL(input.url).pathname;
4882
+ }
4883
+ } catch {}
4884
+ return String(input);
4803
4885
  };
4804
-
4805
- export const transport = apiApp ? createTransport(apiApp) : globalThis.fetch;
4806
4886
  `,Ln=`export const routeMap = [
4807
4887
  {{#each pageRoutes}}
4808
4888
  { pathPattern: "{{honoPattern}}", renderMode: "{{renderMode}}" },
@@ -4824,14 +4904,9 @@ import { HTTPException } from "hono/http-exception";
4824
4904
  import { stream } from "hono/streaming";
4825
4905
  import { glob } from "tinyglobby";
4826
4906
 
4827
- import {
4828
- type FetchApp,
4829
- isFetchApp,
4830
- type NodeApp,
4831
- type SSRSetup,
4832
- } from "@kosmojs/core";
4907
+ import type { FetchApp, NodeApp, SSRSetup } from "@kosmojs/core";
4833
4908
 
4834
- import { redirectCodes, ssrOrigin } from "./@ssr/base";
4909
+ import { isFetchApp, redirectCodes, ssrOrigin } from "./@ssr/base";
4835
4910
 
4836
4911
  import { routeMap } from "{{ createImport 'lib' '@ssr/routes' }}";
4837
4912
  import { apiBase, base } from "{{ createImport 'libCore' }}";
@@ -4853,12 +4928,14 @@ export const createApp = async () => {
4853
4928
  const {
4854
4929
  ssrApp,
4855
4930
  withSsrContext,
4931
+ errorProvider,
4856
4932
  }: {
4857
4933
  ssrApp: SSRSetup;
4858
4934
  withSsrContext: <T>(
4859
4935
  context: { headers?: Record<string, string>; url?: string },
4860
4936
  render: () => T,
4861
4937
  ) => Promise<T>;
4938
+ errorProvider: () => Error | undefined;
4862
4939
  } = await import(\`\${ROOT}/app.js\`);
4863
4940
 
4864
4941
  // Read the client index.html that includes <!--app-head--> and <!--app-html-->
@@ -4918,13 +4995,47 @@ export const createApp = async () => {
4918
4995
  };
4919
4996
 
4920
4997
  const renderPage = async (url: URL, ctx: Context) => {
4921
- const { head = "", html } = await withSsrContext(
4998
+ const {
4999
+ head = "",
5000
+ html,
5001
+ error,
5002
+ } = await withSsrContext(
4922
5003
  {
4923
5004
  headers: Object.fromEntries(ctx.req.raw.headers),
4924
5005
  url: ctx.req.url,
4925
5006
  },
4926
- () => renderToString(url, ssrOptions()),
5007
+ async () => {
5008
+ try {
5009
+ /**
5010
+ * Catch a hard SSR render failure and fall back to CSR,
5011
+ * where the client's error boundaries can surface a meaningful error.
5012
+ * Server-side error boundaries behave inconsistently across frameworks,
5013
+ * can not rely on them here.
5014
+ * Instead, the SSR output are discarded and the client shell served verbatim,
5015
+ * letting the client re-render and handle the error uniformly.
5016
+ * This is the render-level counterpart to the transport-level catch in loaders.
5017
+ * */
5018
+ const { head = "", html } = await renderToString(url, ssrOptions());
5019
+ return { head, html, error: errorProvider() };
5020
+ } catch (error) {
5021
+ return { error };
5022
+ }
5023
+ },
4927
5024
  );
5025
+
5026
+ if (error) {
5027
+ console.error("WARN: SSR failed, fallback to CSR");
5028
+ console.error(error);
5029
+ console.error();
5030
+ return [
5031
+ htmlStart.replace(
5032
+ "<!--app-head-->",
5033
+ \`<script>console.error("WARN: SSR failed, fallback to CSR")<\/script>\`,
5034
+ ),
5035
+ htmlEnd,
5036
+ ].join("");
5037
+ }
5038
+
4928
5039
  return [
4929
5040
  htmlStart.replace("<!--app-head-->", head),
4930
5041
  html ?? "",
@@ -5193,7 +5304,7 @@ if (isMain) {
5193
5304
  process.exit(1);
5194
5305
  }
5195
5306
  }
5196
- `,zn=`string`,Bn=f((n,r)=>{let{generators:i=[],refineTypeName:a,...s}=n.config,{createPath:c,createImportHelpers:l}=h(n),{renderToFile:u}=_({helpers:{...l({origin:`lib`})}});return{async build(e){let t=r?.renderMode?typeof r.renderMode==`string`?()=>r.renderMode:o(r?.renderMode,`string`):()=>zn,n={renderMode:JSON.stringify(r?.renderMode||null),pageRoutes:e.flatMap(e=>e.kind===`pageRoute`?[{...e.entry,renderMode:t(e.entry.name)}]:[]).sort(v),apiGenerator:i.some(e=>e.meta.slot===`backend`)};for(let[e,t]of[[`ssr.ts`,Rn],[`@ssr/api.ts`,Nn],[`@ssr/__kosmo_ssr_bundle.ts`,Fn],[`@ssr/base.ts`,Pn],[`@ssr/fetch.ts`,In],[`@ssr/routes.ts`,Ln]])await u(c.lib(e),t,n)},async postBuild(){let r=c.distDir(`ssr`),a=[y.tsconfigPaths(n),y.nodePrefix()];for(let e of i)await e.factory(n).ssrBuild?.();await S(p(s,...i.map(({factory:e})=>e(n).config?.({kind:`client`,command:`build`})),{root:c.src(),plugins:a,define:{KOSMO_PRODUCTION_BUILD:`true`},build:{ssr:c.lib(`@ssr/__kosmo_ssr_bundle`),ssrEmitAssets:!0,sourcemap:!0,emptyOutDir:!0,minify:!1,rolldownOptions:{output:{dir:r,entryFileNames:`app.js`,format:`esm`}}}})),await S({root:c.lib(),configFile:!1,appType:`custom`,plugins:a,resolve:{conditions:[`node`]},build:{ssr:c.lib(`ssr.ts`),target:`esnext`,sourcemap:!0,emptyOutDir:!0,rolldownOptions:{output:{dir:e(r,`server`),entryFileNames:`server.js`,format:`esm`}}}}),await T(t(r,`../client`),r,{recursive:!0});for(let e of[`server.js`,`server.js.map`])await T(`${r}/server/${e}`,`${r}/${e}`);await E(`${r}/server`,{recursive:!0,force:!0})}}}),Vn=d({meta:{name:`SSR`,slot:`ssr`},dependencies:{tinyglobby:q.devDependencies.tinyglobby,hono:q.devDependencies.hono,"@hono/node-server":q.devDependencies[`@hono/node-server`],"light-my-request":q.devDependencies[`light-my-request`]},factory:Bn}),J={type:`module`,private:!0,name:`@kosmojs/svelte-generator`,version:`0.2.10`,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:^`,"@sveltejs/vite-plugin-svelte":`^7.2.0`,vite:`^8.2.1`},devDependencies:{"@tanstack/svelte-query":`^6.1.38`,"path-to-regexp":`^8.4.2`,svelte:`^5.56.8`}},Hn=()=>{let e=[`🎉 Well done! You just created a new Svelte page.`,`🚀 Success! A fresh Svelte page is ready to roll.`,`🌟 Nice work! Another Svelte page added to your app.`,`🧩 All set! A new Svelte page has been scaffolded.`,`🔧 Scaffold complete! Your new Svelte page is in place.`,`✅ Built! Your Svelte page is scaffolded and ready.`,`✨ Fantastic! Your new Svelte page is good to go.`,`🎯 Nailed it! A brand new Svelte page just landed.`,`💫 Awesome! Another Svelte page joins the party.`,`⚡ Lightning fast! A new Svelte page created successfully.`];return e[Math.floor(Math.random()*e.length)]},Y=`<script lang="ts">
5307
+ `,zn=`string`,Bn=f((n,r)=>{let{generators:i=[],refineTypeName:a,...s}=n.config,{createPath:c,createImportHelpers:l}=h(n),{renderToFile:u}=_({helpers:{...l({origin:`lib`})}});return{async build(e){let t=r?.renderMode?typeof r.renderMode==`string`?()=>r.renderMode:o(r?.renderMode,`string`):()=>zn,n={renderMode:JSON.stringify(r?.renderMode||null),pageRoutes:e.flatMap(e=>e.kind===`pageRoute`?[{...e.entry,renderMode:t(e.entry.name)}]:[]).sort(v),apiGenerator:i.some(e=>e.meta.slot===`backend`)};for(let[e,t]of[[`ssr.ts`,Rn],[`@ssr/api.ts`,Nn],[`@ssr/__kosmo_ssr_bundle.ts`,Fn],[`@ssr/base.ts`,Pn],[`@ssr/fetch.ts`,In],[`@ssr/routes.ts`,Ln]])await u(c.lib(e),t,n)},async postBuild(){let r=c.distDir(`ssr`),a=[y.tsconfigPaths(n),y.nodePrefix()];for(let e of i)await e.factory(n).ssrBuild?.();await S(p(s,...i.map(({factory:e})=>e(n).config?.({kind:`client`,command:`build`})),{root:c.src(),plugins:a,define:{KOSMO_PRODUCTION_BUILD:`true`},build:{ssr:c.lib(`@ssr/__kosmo_ssr_bundle`),ssrEmitAssets:!0,sourcemap:!0,emptyOutDir:!0,minify:!1,rolldownOptions:{output:{dir:r,entryFileNames:`app.js`,format:`esm`}}}})),await S({root:c.lib(),configFile:!1,appType:`custom`,plugins:a,resolve:{conditions:[`node`]},build:{ssr:c.lib(`ssr.ts`),target:`esnext`,sourcemap:!0,emptyOutDir:!0,rolldownOptions:{output:{dir:e(r,`server`),entryFileNames:`server.js`,format:`esm`}}}}),await T(t(r,`../client`),r,{recursive:!0});for(let e of[`server.js`,`server.js.map`])await T(`${r}/server/${e}`,`${r}/${e}`);await E(`${r}/server`,{recursive:!0,force:!0})}}}),Vn=d({meta:{name:`SSR`,slot:`ssr`},dependencies:{tinyglobby:q.devDependencies.tinyglobby,hono:q.devDependencies.hono,"@hono/node-server":q.devDependencies[`@hono/node-server`],"light-my-request":q.devDependencies[`light-my-request`]},factory:Bn}),J={type:`module`,private:!0,name:`@kosmojs/svelte-generator`,version:`0.3.0`,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:^`,"@sveltejs/vite-plugin-svelte":`^7.2.0`,vite:`^8.2.1`},devDependencies:{"@tanstack/svelte-query":`^6.1.38`,"path-to-regexp":`^8.4.2`,svelte:`^5.56.8`}},Hn=()=>{let e=[`🎉 Well done! You just created a new Svelte page.`,`🚀 Success! A fresh Svelte page is ready to roll.`,`🌟 Nice work! Another Svelte page added to your app.`,`🧩 All set! A new Svelte page has been scaffolded.`,`🔧 Scaffold complete! Your new Svelte page is in place.`,`✅ Built! Your Svelte page is scaffolded and ready.`,`✨ Fantastic! Your new Svelte page is good to go.`,`🎯 Nailed it! A brand new Svelte page just landed.`,`💫 Awesome! Another Svelte page joins the party.`,`⚡ Lightning fast! A new Svelte page created successfully.`];return e[Math.floor(Math.random()*e.length)]},Y=`<script lang="ts">
5197
5308
  import type { Snippet } from "svelte";
5198
5309
 
5199
5310
  let { children }: { children: Snippet } = $props();
@@ -5723,6 +5834,8 @@ export default createRouterFactory<
5723
5834
  `,nr=`import { match, pathToRegexp } from "path-to-regexp";
5724
5835
  import { type Component, createContext } from "svelte";
5725
5836
 
5837
+ import { parseSearchParams } from "@kosmojs/core";
5838
+
5726
5839
  import { paramNames } from "{{ createImport 'lib' 'params' }}";
5727
5840
  import { base } from "{{ createImport 'libCore' }}";
5728
5841
 
@@ -5746,7 +5859,7 @@ export type RawRoute = {
5746
5859
  };
5747
5860
 
5748
5861
  type Loader = (
5749
- route: Pick<Route, "name" | "params" | "paramsEntries">,
5862
+ route: Pick<Route, "name" | "params" | "paramsEntries" | "searchParams">,
5750
5863
  ) => Promise<unknown> | undefined;
5751
5864
 
5752
5865
  /**
@@ -5788,6 +5901,7 @@ export type Route = {
5788
5901
  name: string;
5789
5902
  params: Record<string, string | Array<string>>;
5790
5903
  paramsEntries: [keys: Array<string>, values: Array<unknown>];
5904
+ searchParams: Record<string, unknown>;
5791
5905
  loaderData: Record<string, unknown>;
5792
5906
  };
5793
5907
 
@@ -5827,6 +5941,7 @@ export const createRouter = (
5827
5941
 
5828
5942
  return {
5829
5943
  async resolve(url: URL = new URL(window.location.href)) {
5944
+ const searchParams = parseSearchParams(url);
5830
5945
  const urlSegments = url.pathname.split("/").filter(Boolean).length;
5831
5946
 
5832
5947
  // 1: use lightweight \`RegExp.test()\` on linear scan - no capture allocation
@@ -5869,7 +5984,7 @@ export const createRouter = (
5869
5984
 
5870
5985
  loaderData[name] = await runLoader(name, () => {
5871
5986
  return routeModule.loader
5872
- ? routeModule.loader({ name, params, paramsEntries })
5987
+ ? routeModule.loader({ name, params, paramsEntries, searchParams })
5873
5988
  : undefined; // should not survive serialization if no loader defined
5874
5989
  });
5875
5990
 
@@ -5881,7 +5996,12 @@ export const createRouter = (
5881
5996
  const key = \`\${layoutName}/layout\`;
5882
5997
  loaderData[key] = await runLoader(key, () => {
5883
5998
  return layoutModule.loader
5884
- ? layoutModule.loader({ name: layoutName, params, paramsEntries })
5999
+ ? layoutModule.loader({
6000
+ name: layoutName,
6001
+ params,
6002
+ paramsEntries,
6003
+ searchParams,
6004
+ })
5885
6005
  : undefined; // should not survive serialization if no loader defined
5886
6006
  });
5887
6007
  }
@@ -5890,6 +6010,7 @@ export const createRouter = (
5890
6010
  name,
5891
6011
  params,
5892
6012
  paramsEntries,
6013
+ searchParams,
5893
6014
  loaderData,
5894
6015
  };
5895
6016
 
@@ -5957,6 +6078,10 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
5957
6078
  return useRoute().paramsEntries as never;
5958
6079
  }
5959
6080
 
6081
+ export function useSearchParams() {
6082
+ return useRoute().searchParams;
6083
+ }
6084
+
5960
6085
  /**
5961
6086
  * Reads loader data for the current page or one of its layouts.
5962
6087
  * Without a key, returns the page's own data.
@@ -6120,7 +6245,7 @@ export default routerFactory((routes) => {
6120
6245
  },
6121
6246
  };
6122
6247
  });
6123
- `,mr=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,l=s(t?.templates,dr),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?fr:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:Hn()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),ur,{route:r},{overwrite:o})},d=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageLayout`?[t]:[]),r=e.flatMap(({kind:e,entry:n})=>{if(e===`pageRoute`){let{name:e,file:r}=n;return[{...n,layouts:t.flatMap(t=>t.name===e||r.startsWith(`${t.name}/`)?[t]:[]).sort(v)}]}return[]}).sort(v);for(let[e,a]of[[`client.ts`,Wn],[`server.ts`,Gn]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,Qn],[`router.ts`,tr]])await i(n.lib(e),t,{pageRoutes:r})};return{config(){let{templates:e,...n}={...t};return{plugins:de(n)}},async start(){for(let[e,r]of[[`env.d.ts`,Kn],[`svelte.ts`,nr],[`Layouts.svelte`,qn],[`use.ts`,rr],[`pageSamples/styles.module.css`,Xn],[`pageSamples/welcome.svelte`,Zn],[`pageSamples/page.svelte`,Yn],[`pageSamples/404.svelte`,Jn],...t?.tanstack?.query?[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,Un],[`app/index.ts`,`export { default as AppProvider } from "./app-tsq.svelte";`],[`query.ts`,$n]]:[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,`/** tanstack query disabled */`],[`app/index.ts`,`export { default as AppProvider } from "./app.svelte";`],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.svelte`,lr],[`components/Link.svelte`,ar],[`app.svelte`,ir],[`router.ts`,pr]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),cr,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,or],[`server.ts`,sr]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){(!t||t.kind===`create`)&&await u(e),await d(e)},async build(e){await u(e),await d(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?er:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),hr=d({meta:{name:`Svelte`},dependencies(e){return{svelte:J.devDependencies.svelte,"path-to-regexp":J.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/svelte-query":J.devDependencies[`@tanstack/svelte-query`]}:{}}},factory:mr}),gr={type:`module`,private:!0,name:`@kosmojs/typebox-generator`,version:`0.2.10`,cacheVersion:`1`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/typebox-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`,semver:`^7.8.5`},devDependencies:{"@kosmojs/core-generator":`workspace:^`,"@kosmojs/koa-generator":`workspace:^`,typebox:`^1.3.11`}},_r=`import Type from "typebox";
6248
+ `,mr=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,l=s(t?.templates,dr),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?fr:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:Hn()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),ur,{route:r},{overwrite:o})},d=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageLayout`?[t]:[]),r=e.flatMap(({kind:e,entry:n})=>{if(e===`pageRoute`){let{name:e,file:r}=n;return[{...n,layouts:t.flatMap(t=>t.name===e||r.startsWith(`${t.name}/`)?[t]:[]).sort(v)}]}return[]}).sort(v);for(let[e,a]of[[`client.ts`,Wn],[`server.ts`,Gn]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,Qn],[`router.ts`,tr]])await i(n.lib(e),t,{pageRoutes:r})};return{config(){let{templates:e,...n}={...t};return{plugins:de(n)}},async start(){for(let[e,r]of[[`env.d.ts`,Kn],[`svelte.ts`,nr],[`Layouts.svelte`,qn],[`use.ts`,rr],[`pageSamples/styles.module.css`,Xn],[`pageSamples/welcome.svelte`,Zn],[`pageSamples/page.svelte`,Yn],[`pageSamples/404.svelte`,Jn],...t?.tanstack?.query?[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,Un],[`app/index.ts`,`export { default as AppProvider } from "./app-tsq.svelte";`],[`query.ts`,$n]]:[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,`/** tanstack query disabled */`],[`app/index.ts`,`export { default as AppProvider } from "./app.svelte";`],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.svelte`,lr],[`components/Link.svelte`,ar],[`app.svelte`,ir],[`router.ts`,pr]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),cr,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,or],[`server.ts`,sr]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){(!t||t.kind===`create`)&&await u(e),await d(e)},async build(e){await u(e),await d(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?er:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),hr=d({meta:{name:`Svelte`},dependencies(e){return{svelte:J.devDependencies.svelte,"path-to-regexp":J.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/svelte-query":J.devDependencies[`@tanstack/svelte-query`]}:{}}},factory:mr}),gr={type:`module`,private:!0,name:`@kosmojs/typebox-generator`,version:`0.3.0`,cacheVersion:`1`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/typebox-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`,semver:`^7.8.5`},devDependencies:{"@kosmojs/core-generator":`workspace:^`,"@kosmojs/koa-generator":`workspace:^`,typebox:`^1.3.11`}},_r=`import Type from "typebox";
6124
6249
 
6125
6250
  /**
6126
6251
  * Custom types for JavaScript constructs that have no JSON Schema
@@ -7496,7 +7621,7 @@ export const validationSchemas: ValidationSchemas = {
7496
7621
  {{/each}}
7497
7622
  },
7498
7623
  };
7499
- `,Sr={exactOptionalPropertyTypes:!0},Cr=f((e,t)=>{let{createPath:n,createImport:r,createImportHelpers:i}=h(e),{renderToFile:o}=_({helpers:{...i({origin:`lib`})}}),{validationMessages:s={},customTypesImport:c=r.lib([`@typebox/custom-types`],{origin:`lib`}),settings:l}={...t},u=async e=>{for(let{kind:t,entry:r}of e){if(t!==`apiRoute`)continue;let e=[r.params,...r.validationDefinitions.flatMap(e=>e.target===`response`?e.variants:[e.schema])].flatMap(({resolvedType:e})=>e?[e]:[]),i=[...new Set(r.validationDefinitions.flatMap(({target:e})=>Object.keys(a).includes(e)?[e]:[]))].map(e=>({target:e,methods:r.methods.flatMap(t=>{let n=r.validationDefinitions.find(n=>n.method===t&&n.target===e);return n?[{route:r.name,method:t,target:e,schema:n.schema,...n.runtimeValidation===void 0?{}:{runtimeValidation:JSON.stringify(n.runtimeValidation)},...n.customErrors===void 0?{}:{customErrors:JSON.stringify(n.customErrors)}}]:[]})})),s=r.methods.flatMap(e=>{let t=r.validationDefinitions.find(t=>t.method===e&&t.target===`response`);return t?[{method:e,variants:t.variants.map(e=>({route:r.name,target:`response`,...e,...t.runtimeValidation===void 0?{}:{runtimeValidation:JSON.stringify(t.runtimeValidation)},...t.customErrors===void 0?{}:{customErrors:JSON.stringify(t.customErrors)}}))}]:[]});await o(n.libApi(r.name,`schemas.ts`),xr,{route:r,resolvedTypes:e,requestSchemas:i,responseSchemas:s})}};return{async start(){for(let[e,t]of[[`custom-types.ts`,_r],[`error-handler.ts`,vr],[`index.ts`,yr],[`setup.ts`,br]])await o(n.lib(`@typebox`,e),t,{validationMessages:JSON.stringify(s),customTypesImport:c,settings:JSON.stringify({...Sr,...l})})},async watch(e,t){await u(t?e.filter(({kind:e,entry:n})=>t.kind===`update`&&e===`apiRoute`&&n.fileFullpath===t.file):e)},async build(e){await u(e)}}}),X={PROPERTY:`PROPERTY`,PROPERTIES:`PROPERTIES`,ALLOWED_VALUES:`ALLOWED_VALUES`,FOUND_N_DUPLICATES:`FOUND_N_DUPLICATES`,VALIDATION_PASSED:`VALIDATION_PASSED`,VALIDATION_FAILED_PREFIX:`VALIDATION_FAILED_PREFIX`,ERROR_SUMMARY:`ERROR_SUMMARY`,PLURAL_SUFFIX:`PLURAL_SUFFIX`,FIRST:`FIRST`,SECOND:`SECOND`,THIRD:`THIRD`,FOURTH:`FOURTH`,FIFTH:`FIFTH`,TYPE_INVALID:`TYPE_INVALID`,STRING_MIN_LENGTH:`STRING_MIN_LENGTH`,STRING_MAX_LENGTH:`STRING_MAX_LENGTH`,STRING_PATTERN:`STRING_PATTERN`,STRING_FORMAT:`STRING_FORMAT`,STRING_FORMAT_EMAIL:`STRING_FORMAT_EMAIL`,STRING_FORMAT_DATE:`STRING_FORMAT_DATE`,STRING_FORMAT_DATETIME:`STRING_FORMAT_DATETIME`,STRING_FORMAT_TIME:`STRING_FORMAT_TIME`,STRING_FORMAT_URI:`STRING_FORMAT_URI`,STRING_FORMAT_URL:`STRING_FORMAT_URL`,STRING_FORMAT_UUID:`STRING_FORMAT_UUID`,STRING_FORMAT_IPV4:`STRING_FORMAT_IPV4`,STRING_FORMAT_IPV6:`STRING_FORMAT_IPV6`,STRING_FORMAT_HOSTNAME:`STRING_FORMAT_HOSTNAME`,STRING_FORMAT_JSON_POINTER:`STRING_FORMAT_JSON_POINTER`,STRING_FORMAT_REGEX:`STRING_FORMAT_REGEX`,NUMBER_MINIMUM:`NUMBER_MINIMUM`,NUMBER_MAXIMUM:`NUMBER_MAXIMUM`,NUMBER_EXCLUSIVE_MINIMUM:`NUMBER_EXCLUSIVE_MINIMUM`,NUMBER_EXCLUSIVE_MAXIMUM:`NUMBER_EXCLUSIVE_MAXIMUM`,NUMBER_MULTIPLE_OF:`NUMBER_MULTIPLE_OF`,ARRAY_MIN_ITEMS:`ARRAY_MIN_ITEMS`,ARRAY_MAX_ITEMS:`ARRAY_MAX_ITEMS`,ARRAY_UNIQUE_ITEMS:`ARRAY_UNIQUE_ITEMS`,ARRAY_CONTAINS:`ARRAY_CONTAINS`,ARRAY_MIN_CONTAINS:`ARRAY_MIN_CONTAINS`,ARRAY_MAX_CONTAINS:`ARRAY_MAX_CONTAINS`,ARRAY_PREFIX_ITEMS:`ARRAY_PREFIX_ITEMS`,ARRAY_ITEMS:`ARRAY_ITEMS`,ARRAY_UNEVALUATED_ITEMS:`ARRAY_UNEVALUATED_ITEMS`,TUPLE_MIN_ITEMS:`TUPLE_MIN_ITEMS`,TUPLE_MAX_ITEMS:`TUPLE_MAX_ITEMS`,OBJECT_REQUIRED:`OBJECT_REQUIRED`,OBJECT_ADDITIONAL_PROPERTIES:`OBJECT_ADDITIONAL_PROPERTIES`,OBJECT_MIN_PROPERTIES:`OBJECT_MIN_PROPERTIES`,OBJECT_MAX_PROPERTIES:`OBJECT_MAX_PROPERTIES`,OBJECT_PROPERTY_NAMES:`OBJECT_PROPERTY_NAMES`,OBJECT_DEPENDENCIES:`OBJECT_DEPENDENCIES`,OBJECT_UNEVALUATED_PROPERTIES:`OBJECT_UNEVALUATED_PROPERTIES`,ENUM_MISMATCH:`ENUM_MISMATCH`,CONST_MISMATCH:`CONST_MISMATCH`,CONDITIONAL_IF:`CONDITIONAL_IF`,CONDITIONAL_THEN:`CONDITIONAL_THEN`,CONDITIONAL_ELSE:`CONDITIONAL_ELSE`,COMPOSITION_ONE_OF:`COMPOSITION_ONE_OF`,COMPOSITION_ANY_OF:`COMPOSITION_ANY_OF`,COMPOSITION_ALL_OF:`COMPOSITION_ALL_OF`,COMPOSITION_NOT:`COMPOSITION_NOT`,CONTENT_DISCRIMINATOR:`CONTENT_DISCRIMINATOR`,CONTENT_ENCODING:`CONTENT_ENCODING`,CONTENT_MEDIA_TYPE:`CONTENT_MEDIA_TYPE`,CUSTOM_RANGE:`CUSTOM_RANGE`,CUSTOM_EXCLUSIVE_RANGE:`CUSTOM_EXCLUSIVE_RANGE`,CUSTOM_REGEXP:`CUSTOM_REGEXP`,CUSTOM_DYNAMIC_DEFAULTS:`CUSTOM_DYNAMIC_DEFAULTS`,CUSTOM_SELECT:`CUSTOM_SELECT`,CUSTOM_TRANSFORM:`CUSTOM_TRANSFORM`,CUSTOM_UNIQUE_ITEM_PROPERTIES:`CUSTOM_UNIQUE_ITEM_PROPERTIES`,UNKNOWN:`UNKNOWN`};X.PROPERTY,X.PROPERTIES,X.ALLOWED_VALUES,X.FOUND_N_DUPLICATES,X.VALIDATION_PASSED,X.VALIDATION_FAILED_PREFIX,X.ERROR_SUMMARY,X.PLURAL_SUFFIX,X.FIRST,X.SECOND,X.THIRD,X.FOURTH,X.FIFTH,X.TYPE_INVALID,X.STRING_MIN_LENGTH,X.STRING_MAX_LENGTH,X.STRING_PATTERN,X.STRING_FORMAT,X.STRING_FORMAT_EMAIL,X.STRING_FORMAT_DATE,X.STRING_FORMAT_DATETIME,X.STRING_FORMAT_TIME,X.STRING_FORMAT_URI,X.STRING_FORMAT_URL,X.STRING_FORMAT_UUID,X.STRING_FORMAT_IPV4,X.STRING_FORMAT_IPV6,X.STRING_FORMAT_HOSTNAME,X.STRING_FORMAT_JSON_POINTER,X.STRING_FORMAT_REGEX,X.NUMBER_MINIMUM,X.NUMBER_MAXIMUM,X.NUMBER_EXCLUSIVE_MINIMUM,X.NUMBER_EXCLUSIVE_MAXIMUM,X.NUMBER_MULTIPLE_OF,X.ARRAY_MIN_ITEMS,X.ARRAY_MAX_ITEMS,X.ARRAY_UNIQUE_ITEMS,X.ARRAY_CONTAINS,X.ARRAY_MIN_CONTAINS,X.ARRAY_MAX_CONTAINS,X.ARRAY_PREFIX_ITEMS,X.ARRAY_ITEMS,X.ARRAY_UNEVALUATED_ITEMS,X.TUPLE_MIN_ITEMS,X.TUPLE_MAX_ITEMS,X.OBJECT_REQUIRED,X.OBJECT_ADDITIONAL_PROPERTIES,X.OBJECT_MIN_PROPERTIES,X.OBJECT_MAX_PROPERTIES,X.OBJECT_PROPERTY_NAMES,X.OBJECT_DEPENDENCIES,X.OBJECT_UNEVALUATED_PROPERTIES,X.ENUM_MISMATCH,X.CONST_MISMATCH,X.CONDITIONAL_IF,X.CONDITIONAL_THEN,X.CONDITIONAL_ELSE,X.COMPOSITION_ONE_OF,X.COMPOSITION_ANY_OF,X.COMPOSITION_ALL_OF,X.COMPOSITION_NOT,X.CONTENT_DISCRIMINATOR,X.CONTENT_ENCODING,X.CONTENT_MEDIA_TYPE,X.CUSTOM_RANGE,X.CUSTOM_EXCLUSIVE_RANGE,X.CUSTOM_REGEXP,X.CUSTOM_DYNAMIC_DEFAULTS,X.CUSTOM_SELECT,X.CUSTOM_TRANSFORM,X.CUSTOM_UNIQUE_ITEM_PROPERTIES,X.UNKNOWN;var wr=d({meta:{name:`TypeBox`,resolveTypes:!0},dependencies:{typebox:gr.devDependencies.typebox},factory:Cr}),Z={type:`module`,private:!0,name:`@kosmojs/vue-generator`,version:`0.2.10`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/vue-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@vitejs/plugin-vue":`^6.0.8`},devDependencies:{"@tanstack/vue-query":`^5.101.4`,"path-to-regexp":`^8.4.2`,vue:`^3.5.41`,"vue-router":`^5.2.0`}},Q=e=>{let t=e=>e.kind===`splat`?`:${e.name}(.*)?`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[t(e.parts[0])]:[e.parts.map(e=>e.type===`static`?e.value:t(e)).join(``)]).join(`/`)},Tr=()=>{let t=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,n=(r,i)=>r.flatMap(({index:r,layout:a,children:o})=>{let{name:s,pathTokens:c}={...r,...a};if(!c)return[];let l=`${s}/layout`,u=i?Q(c):e(`/`,Q(c)),d=c.at(-1);return t(d)?r&&a?[{name:l,path:u,component:a.id,children:[{name:s,path:``,component:r.id}]}]:r?[{path:u,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:a?[{name:l,path:u,component:a.id,children:n(o,s)}]:[]:r&&a?[{name:l,path:u,component:a.id,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:r?[{path:u,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:a?[{name:l,path:u,component:a.id,children:n(o,s)}]:[]});return n},Er=()=>{let e=[`🎉 Well done! You just created a new Vue route.`,`🚀 Success! A fresh Vue route is ready to roll.`,`🌟 Nice work! Another Vue route added to your app.`,`🧩 All set! A new Vue route has been scaffolded.`,`🔧 Scaffold complete! Your new Vue route is in place.`,`✅ Built! Your Vue route is scaffolded and ready.`,`✨ Fantastic! Your new Vue route is good to go.`,`🎯 Nailed it! A brand new Vue route just landed.`,`💫 Awesome! Another Vue route joins the party.`,`⚡ Lightning fast! A new Vue route created successfully.`];return e[Math.floor(Math.random()*e.length)]},Dr=`import type { Plugin } from "vue";
7624
+ `,Sr={exactOptionalPropertyTypes:!0},Cr=f((e,t)=>{let{createPath:n,createImport:r,createImportHelpers:i}=h(e),{renderToFile:o}=_({helpers:{...i({origin:`lib`})}}),{validationMessages:s={},customTypesImport:c=r.lib([`@typebox/custom-types`],{origin:`lib`}),settings:l}={...t},u=async e=>{for(let{kind:t,entry:r}of e){if(t!==`apiRoute`)continue;let e=[r.params,...r.validationDefinitions.flatMap(e=>e.target===`response`?e.variants:[e.schema])].flatMap(({resolvedType:e})=>e?[e]:[]),i=[...new Set(r.validationDefinitions.flatMap(({target:e})=>Object.keys(a).includes(e)?[e]:[]))].map(e=>({target:e,methods:r.methods.flatMap(t=>{let n=r.validationDefinitions.find(n=>n.method===t&&n.target===e);return n?[{route:r.name,method:t,target:e,schema:n.schema,...n.runtimeValidation===void 0?{}:{runtimeValidation:JSON.stringify(n.runtimeValidation)},...n.customErrors===void 0?{}:{customErrors:JSON.stringify(n.customErrors)}}]:[]})})),s=r.methods.flatMap(e=>{let t=r.validationDefinitions.find(t=>t.method===e&&t.target===`response`);return t?[{method:e,variants:t.variants.map(e=>({route:r.name,target:`response`,...e,...t.runtimeValidation===void 0?{}:{runtimeValidation:JSON.stringify(t.runtimeValidation)},...t.customErrors===void 0?{}:{customErrors:JSON.stringify(t.customErrors)}}))}]:[]});await o(n.libApi(r.name,`schemas.ts`),xr,{route:r,resolvedTypes:e,requestSchemas:i,responseSchemas:s})}};return{async start(){for(let[e,t]of[[`custom-types.ts`,_r],[`error-handler.ts`,vr],[`index.ts`,yr],[`setup.ts`,br]])await o(n.lib(`@typebox`,e),t,{validationMessages:JSON.stringify(s),customTypesImport:c,settings:JSON.stringify({...Sr,...l})})},async watch(e,t){await u(t?e.filter(({kind:e,entry:n})=>t.kind===`update`&&e===`apiRoute`&&n.fileFullpath===t.file):e)},async build(e){await u(e)}}}),X={PROPERTY:`PROPERTY`,PROPERTIES:`PROPERTIES`,ALLOWED_VALUES:`ALLOWED_VALUES`,FOUND_N_DUPLICATES:`FOUND_N_DUPLICATES`,VALIDATION_PASSED:`VALIDATION_PASSED`,VALIDATION_FAILED_PREFIX:`VALIDATION_FAILED_PREFIX`,ERROR_SUMMARY:`ERROR_SUMMARY`,PLURAL_SUFFIX:`PLURAL_SUFFIX`,FIRST:`FIRST`,SECOND:`SECOND`,THIRD:`THIRD`,FOURTH:`FOURTH`,FIFTH:`FIFTH`,TYPE_INVALID:`TYPE_INVALID`,STRING_MIN_LENGTH:`STRING_MIN_LENGTH`,STRING_MAX_LENGTH:`STRING_MAX_LENGTH`,STRING_PATTERN:`STRING_PATTERN`,STRING_FORMAT:`STRING_FORMAT`,STRING_FORMAT_EMAIL:`STRING_FORMAT_EMAIL`,STRING_FORMAT_DATE:`STRING_FORMAT_DATE`,STRING_FORMAT_DATETIME:`STRING_FORMAT_DATETIME`,STRING_FORMAT_TIME:`STRING_FORMAT_TIME`,STRING_FORMAT_URI:`STRING_FORMAT_URI`,STRING_FORMAT_URL:`STRING_FORMAT_URL`,STRING_FORMAT_UUID:`STRING_FORMAT_UUID`,STRING_FORMAT_IPV4:`STRING_FORMAT_IPV4`,STRING_FORMAT_IPV6:`STRING_FORMAT_IPV6`,STRING_FORMAT_HOSTNAME:`STRING_FORMAT_HOSTNAME`,STRING_FORMAT_JSON_POINTER:`STRING_FORMAT_JSON_POINTER`,STRING_FORMAT_REGEX:`STRING_FORMAT_REGEX`,NUMBER_MINIMUM:`NUMBER_MINIMUM`,NUMBER_MAXIMUM:`NUMBER_MAXIMUM`,NUMBER_EXCLUSIVE_MINIMUM:`NUMBER_EXCLUSIVE_MINIMUM`,NUMBER_EXCLUSIVE_MAXIMUM:`NUMBER_EXCLUSIVE_MAXIMUM`,NUMBER_MULTIPLE_OF:`NUMBER_MULTIPLE_OF`,ARRAY_MIN_ITEMS:`ARRAY_MIN_ITEMS`,ARRAY_MAX_ITEMS:`ARRAY_MAX_ITEMS`,ARRAY_UNIQUE_ITEMS:`ARRAY_UNIQUE_ITEMS`,ARRAY_CONTAINS:`ARRAY_CONTAINS`,ARRAY_MIN_CONTAINS:`ARRAY_MIN_CONTAINS`,ARRAY_MAX_CONTAINS:`ARRAY_MAX_CONTAINS`,ARRAY_PREFIX_ITEMS:`ARRAY_PREFIX_ITEMS`,ARRAY_ITEMS:`ARRAY_ITEMS`,ARRAY_UNEVALUATED_ITEMS:`ARRAY_UNEVALUATED_ITEMS`,TUPLE_MIN_ITEMS:`TUPLE_MIN_ITEMS`,TUPLE_MAX_ITEMS:`TUPLE_MAX_ITEMS`,OBJECT_REQUIRED:`OBJECT_REQUIRED`,OBJECT_ADDITIONAL_PROPERTIES:`OBJECT_ADDITIONAL_PROPERTIES`,OBJECT_MIN_PROPERTIES:`OBJECT_MIN_PROPERTIES`,OBJECT_MAX_PROPERTIES:`OBJECT_MAX_PROPERTIES`,OBJECT_PROPERTY_NAMES:`OBJECT_PROPERTY_NAMES`,OBJECT_DEPENDENCIES:`OBJECT_DEPENDENCIES`,OBJECT_UNEVALUATED_PROPERTIES:`OBJECT_UNEVALUATED_PROPERTIES`,ENUM_MISMATCH:`ENUM_MISMATCH`,CONST_MISMATCH:`CONST_MISMATCH`,CONDITIONAL_IF:`CONDITIONAL_IF`,CONDITIONAL_THEN:`CONDITIONAL_THEN`,CONDITIONAL_ELSE:`CONDITIONAL_ELSE`,COMPOSITION_ONE_OF:`COMPOSITION_ONE_OF`,COMPOSITION_ANY_OF:`COMPOSITION_ANY_OF`,COMPOSITION_ALL_OF:`COMPOSITION_ALL_OF`,COMPOSITION_NOT:`COMPOSITION_NOT`,CONTENT_DISCRIMINATOR:`CONTENT_DISCRIMINATOR`,CONTENT_ENCODING:`CONTENT_ENCODING`,CONTENT_MEDIA_TYPE:`CONTENT_MEDIA_TYPE`,CUSTOM_RANGE:`CUSTOM_RANGE`,CUSTOM_EXCLUSIVE_RANGE:`CUSTOM_EXCLUSIVE_RANGE`,CUSTOM_REGEXP:`CUSTOM_REGEXP`,CUSTOM_DYNAMIC_DEFAULTS:`CUSTOM_DYNAMIC_DEFAULTS`,CUSTOM_SELECT:`CUSTOM_SELECT`,CUSTOM_TRANSFORM:`CUSTOM_TRANSFORM`,CUSTOM_UNIQUE_ITEM_PROPERTIES:`CUSTOM_UNIQUE_ITEM_PROPERTIES`,UNKNOWN:`UNKNOWN`};X.PROPERTY,X.PROPERTIES,X.ALLOWED_VALUES,X.FOUND_N_DUPLICATES,X.VALIDATION_PASSED,X.VALIDATION_FAILED_PREFIX,X.ERROR_SUMMARY,X.PLURAL_SUFFIX,X.FIRST,X.SECOND,X.THIRD,X.FOURTH,X.FIFTH,X.TYPE_INVALID,X.STRING_MIN_LENGTH,X.STRING_MAX_LENGTH,X.STRING_PATTERN,X.STRING_FORMAT,X.STRING_FORMAT_EMAIL,X.STRING_FORMAT_DATE,X.STRING_FORMAT_DATETIME,X.STRING_FORMAT_TIME,X.STRING_FORMAT_URI,X.STRING_FORMAT_URL,X.STRING_FORMAT_UUID,X.STRING_FORMAT_IPV4,X.STRING_FORMAT_IPV6,X.STRING_FORMAT_HOSTNAME,X.STRING_FORMAT_JSON_POINTER,X.STRING_FORMAT_REGEX,X.NUMBER_MINIMUM,X.NUMBER_MAXIMUM,X.NUMBER_EXCLUSIVE_MINIMUM,X.NUMBER_EXCLUSIVE_MAXIMUM,X.NUMBER_MULTIPLE_OF,X.ARRAY_MIN_ITEMS,X.ARRAY_MAX_ITEMS,X.ARRAY_UNIQUE_ITEMS,X.ARRAY_CONTAINS,X.ARRAY_MIN_CONTAINS,X.ARRAY_MAX_CONTAINS,X.ARRAY_PREFIX_ITEMS,X.ARRAY_ITEMS,X.ARRAY_UNEVALUATED_ITEMS,X.TUPLE_MIN_ITEMS,X.TUPLE_MAX_ITEMS,X.OBJECT_REQUIRED,X.OBJECT_ADDITIONAL_PROPERTIES,X.OBJECT_MIN_PROPERTIES,X.OBJECT_MAX_PROPERTIES,X.OBJECT_PROPERTY_NAMES,X.OBJECT_DEPENDENCIES,X.OBJECT_UNEVALUATED_PROPERTIES,X.ENUM_MISMATCH,X.CONST_MISMATCH,X.CONDITIONAL_IF,X.CONDITIONAL_THEN,X.CONDITIONAL_ELSE,X.COMPOSITION_ONE_OF,X.COMPOSITION_ANY_OF,X.COMPOSITION_ALL_OF,X.COMPOSITION_NOT,X.CONTENT_DISCRIMINATOR,X.CONTENT_ENCODING,X.CONTENT_MEDIA_TYPE,X.CUSTOM_RANGE,X.CUSTOM_EXCLUSIVE_RANGE,X.CUSTOM_REGEXP,X.CUSTOM_DYNAMIC_DEFAULTS,X.CUSTOM_SELECT,X.CUSTOM_TRANSFORM,X.CUSTOM_UNIQUE_ITEM_PROPERTIES,X.UNKNOWN;var wr=d({meta:{name:`TypeBox`,resolveTypes:!0},dependencies:{typebox:gr.devDependencies.typebox},factory:Cr}),Z={type:`module`,private:!0,name:`@kosmojs/vue-generator`,version:`0.3.0`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,test:`vitest --root ../.. --project generators/vue-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@vitejs/plugin-vue":`^6.0.8`},devDependencies:{"@tanstack/vue-query":`^5.101.4`,"path-to-regexp":`^8.4.2`,vue:`^3.5.41`,"vue-router":`^5.2.0`}},Q=e=>{let t=e=>e.kind===`splat`?`:${e.name}(.*)?`:e.kind===`optional`?`:${e.name}?`:`:${e.name}`;return e.flatMap(e=>e.kind===`static`?[e.parts[0].value]:e.kind===`param`?[t(e.parts[0])]:[e.parts.map(e=>e.type===`static`?e.value:t(e)).join(``)]).join(`/`)},Tr=()=>{let t=e=>e?.kind===`param`&&e.parts[0]?.kind===`splat`,n=(r,i)=>r.flatMap(({index:r,layout:a,children:o})=>{let{name:s,pathTokens:c}={...r,...a};if(!c)return[];let l=`${s}/layout`,u=i?Q(c):e(`/`,Q(c)),d=c.at(-1);return t(d)?r&&a?[{name:l,path:u,component:a.id,children:[{name:s,path:``,component:r.id}]}]:r?[{path:u,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:a?[{name:l,path:u,component:a.id,children:n(o,s)}]:[]:r&&a?[{name:l,path:u,component:a.id,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:r?[{path:u,children:[{name:s,path:``,component:r.id},...n(o,s)]}]:a?[{name:l,path:u,component:a.id,children:n(o,s)}]:[]});return n},Er=()=>{let e=[`🎉 Well done! You just created a new Vue route.`,`🚀 Success! A fresh Vue route is ready to roll.`,`🌟 Nice work! Another Vue route added to your app.`,`🧩 All set! A new Vue route has been scaffolded.`,`🔧 Scaffold complete! Your new Vue route is in place.`,`✅ Built! Your Vue route is scaffolded and ready.`,`✨ Fantastic! Your new Vue route is good to go.`,`🎯 Nailed it! A brand new Vue route just landed.`,`💫 Awesome! Another Vue route joins the party.`,`⚡ Lightning fast! A new Vue route created successfully.`];return e[Math.floor(Math.random()*e.length)]},Dr=`import type { Plugin } from "vue";
7500
7625
 
7501
7626
  export { default as AppProvider } from "./provider.vue";
7502
7627
 
@@ -7652,21 +7777,17 @@ export const renderToStream: RenderToStreamWrapper<
7652
7777
  Parameters<typeof renderToWebStream>[1]
7653
7778
  > = async (resolver, { headerTags = [], context = {} } = {}) => {
7654
7779
  const { component, loaderData } = await resolver();
7655
- const source = renderToWebStream(component, context);
7656
-
7657
- const appendScript = new TransformStream<Uint8Array, Uint8Array>({
7658
- flush(controller) {
7659
- // runs once, after \`source\` has fully flushed and closed
7660
- const script = createHydrationScript(loaderData);
7661
- if (script) {
7662
- controller.enqueue(new TextEncoder().encode(script));
7663
- }
7664
- },
7665
- });
7780
+
7781
+ /**
7782
+ * loaderData is fully resolved before streaming starts, so the hydration
7783
+ * script ships in head - same as string mode. Head is written with the shell,
7784
+ * guaranteeing delivery even when the stream errors mid-body.
7785
+ * */
7786
+ const script = createHydrationScript(loaderData);
7666
7787
 
7667
7788
  return {
7668
- head: [...headerTags].join("\\n"),
7669
- html: source.pipeThrough(appendScript),
7789
+ head: [...headerTags, ...script ? [script] : []].join("\\n"),
7790
+ html: renderToWebStream(component, context),
7670
7791
  };
7671
7792
  }
7672
7793
 
@@ -8128,7 +8249,7 @@ export const createRouters = (
8128
8249
  // would otherwise skip the guard
8129
8250
  installLoaderGuard(router);
8130
8251
 
8131
- await router.push(url.pathname.replace(base, ""));
8252
+ await router.push(url.pathname + url.search);
8132
8253
 
8133
8254
  await router.isReady();
8134
8255