@kosmojs/dev 0.2.9 → 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,4 +1,120 @@
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.9`,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=`{{#each routes}}
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
+
3
+ import {
4
+ type ApiRouteSerialized,
5
+ stringifySearchParams,
6
+ type ValidationTarget,
7
+ } from "@kosmojs/core";
8
+ import type { HTTPMethod } from "@kosmojs/core/api";
9
+ import { createHost, type HostOpt, join } from "@kosmojs/core/fetch";
10
+
11
+ export * from "./transport";
12
+
13
+ export const fetchHelpers = <ParamsT extends readonly unknown[]>(
14
+ basePath: string,
15
+ route: ApiRouteSerialized,
16
+ ) => {
17
+ const toPath = compile(route.pathPattern);
18
+
19
+ const maybeNumber = (val: unknown) => {
20
+ if (val === undefined || val === null) {
21
+ return val;
22
+ }
23
+ const n = Number(val);
24
+ return Number.isFinite(n) ? n : val;
25
+ };
26
+
27
+ const paramsMapper = (params: ParamsT, opt?: { coerceNumbers?: boolean }) => {
28
+ return route.params.reduce<Record<string, unknown>>((map, name, i) => {
29
+ const coerceNumbers = opt?.coerceNumbers
30
+ ? route.numericProperties.params.includes(name)
31
+ : false;
32
+ if (Array.isArray(params[i])) {
33
+ map[name] = coerceNumbers
34
+ ? params[i].map((v) => maybeNumber(v))
35
+ : params[i].map(String);
36
+ } else if (params[i] !== undefined) {
37
+ map[name] = coerceNumbers ? maybeNumber(params[i]) : String(params[i]);
38
+ }
39
+ return map;
40
+ }, {});
41
+ };
42
+
43
+ const parametrize = (params: ParamsT) => {
44
+ try {
45
+ return toPath(paramsMapper(params) as never);
46
+ } catch (error) {
47
+ console.error(\`❗ERROR: Failed building path for \${route.name}\`);
48
+ throw error;
49
+ }
50
+ };
51
+
52
+ const base = (params: ParamsT, query?: Record<string, unknown>) => {
53
+ const path = join("/", parametrize(params));
54
+ return query ? [path, stringifySearchParams(query)].join("?") : path;
55
+ };
56
+
57
+ const path = (params: ParamsT, query?: Record<string, unknown>) => {
58
+ return join(basePath, base(params, query));
59
+ };
60
+
61
+ const href = (
62
+ host: HostOpt,
63
+ params: ParamsT,
64
+ query?: Record<string, unknown>,
65
+ ) => {
66
+ return createHost(host) + path(params, query);
67
+ };
68
+
69
+ const payloadResolver = <T>(
70
+ payload: Record<ValidationTarget, T> | undefined,
71
+ target: ValidationTarget,
72
+ method: HTTPMethod,
73
+ ) => {
74
+ const data = payload?.[target];
75
+
76
+ if (target === "query") {
77
+ return Object.fromEntries(
78
+ Object.entries({ ...data }).map(([k, v]) => {
79
+ return [
80
+ k,
81
+ route.numericProperties.query[method]?.includes(k)
82
+ ? Array.isArray(v)
83
+ ? v.map((v) => maybeNumber(v))
84
+ : maybeNumber(v)
85
+ : v,
86
+ ];
87
+ }),
88
+ );
89
+ }
90
+
91
+ if (data instanceof FormData) {
92
+ return [...data].reduce<
93
+ Record<string, FormDataEntryValue | Array<FormDataEntryValue>>
94
+ >((map, [key, val]) => {
95
+ if (key in map) {
96
+ map[key] = [map[key]].flat().concat(val);
97
+ } else {
98
+ map[key] = val;
99
+ }
100
+ return map;
101
+ }, {}) as T;
102
+ }
103
+
104
+ return data;
105
+ };
106
+
107
+ return {
108
+ paramsMapper,
109
+ parametrize,
110
+ base,
111
+ path,
112
+ href,
113
+ payloadResolver,
114
+ };
115
+ };
116
+ `,k=`export const transport = undefined;
117
+ `,A=`{{#each routes}}
2
118
  import {{id}} from "{{ createImport 'libApi' name 'fetch' }}";
3
119
  {{/each}}
4
120
 
@@ -16,14 +132,10 @@ export default {
16
132
  {{/each}}
17
133
  {{/each}}
18
134
  }
19
- `,k=`import fetchFactory, {
20
- join,
21
- stringify,
22
- payloadResolver,
23
- } from "@kosmojs/core/fetch";
135
+ `,j=`import fetchFactory, { join } from "@kosmojs/core/fetch";
24
136
 
25
137
  import { base, apiBase, apiRouteMap } from "{{ createImport 'libCore' }}";
26
- import { transport } from "{{ createImport 'lib' '@fetch' }}";
138
+ import { transport, fetchHelpers } from "{{ createImport 'lib' '@fetch' }}";
27
139
 
28
140
  import {
29
141
  type MaybeWrapped,
@@ -60,27 +172,27 @@ export type ResponseT = {
60
172
  const {
61
173
  paramsMapper,
62
174
  parametrize,
175
+ payloadResolver,
63
176
  path,
64
177
  href,
65
- } = apiRouteMap["{{route.name}}"];
178
+ } = fetchHelpers<[{{serializeParamsTupleElements route}}]>(
179
+ apiBase,
180
+ apiRouteMap["{{route.name}}"],
181
+ );
66
182
 
67
183
  const fetchApi = fetchFactory(
68
184
  join(base, apiBase),
69
- { transport, stringify },
185
+ { transport },
70
186
  );
71
187
 
72
188
  {{#each routeMethods}}
73
189
  export const {{method}} = (
74
190
  _params{{#if ../route.optionalParams}}?{{/if}}: MaybeWrapped<ParamsT>,
75
191
  _payload?: {
76
- {{#each ../payloadTargets}}
77
- {{#if payloadType}}
78
- {{target}}: {{payloadType.name}} extends { {{../method}}: unknown }
79
- ? MaybeWrapped<{{payloadType.name}}["{{../method}}"]>
192
+ {{#each payloadTypes}}
193
+ {{target}}: {{id}} extends { {{method}}: unknown }
194
+ ? MaybeWrapped<{{id}}["{{method}}"]>
80
195
  : unknown,
81
- {{else}}
82
- {{target}}?: unknown;
83
- {{/if}}
84
196
  {{/each}}
85
197
  },
86
198
  opt?: {
@@ -99,12 +211,14 @@ export const {{method}} = (
99
211
  // validate only on client, skip double validation in SSR mode
100
212
  if (!import.meta.env.SSR) {
101
213
  if (validationSchemas.params) {
102
- validationSchemas.params.validate(paramsMapper(params as never));
214
+ validationSchemas.params.validate(
215
+ paramsMapper(params as never, { coerceNumbers: true }),
216
+ );
103
217
  }
104
- {{#each ../payloadTypes}}
105
- if (validationSchemas.{{target}}?.{{../method}}) {
106
- validationSchemas.{{target}}.{{../method}}.validate(
107
- payloadResolver(payload, "{{target}}")
218
+ {{#each payloadTypes}}
219
+ if (validationSchemas.{{target}}?.{{method}}) {
220
+ validationSchemas.{{target}}.{{method}}.validate(
221
+ payloadResolver(payload as never, "{{target}}", "{{../method}}"),
108
222
  );
109
223
  }
110
224
  {{/each}}
@@ -121,9 +235,9 @@ export default {
121
235
  href,
122
236
  validationSchemas,
123
237
  };
124
- `,A=`export type MaybeWrapped<T> = T;
238
+ `,M=`export type MaybeWrapped<T> = T;
125
239
  export const unwrap = <T>(data: T) => data;
126
- `,j=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`),O,{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`),k,{route:i,validationTypes:e,routeMethods:n,payloadTypes:o,payloadTargets:s,responseTypes:c})}};return{async start(){for(let[e,n]of[[`unwrap.ts`,A],[`@fetch.ts`,`export const transport = undefined;`]])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.ts`,`export { transport } from "${c.libPrefix}/@ssr/fetch";`]])await r(t.lib(e),n,{})}}}),M=d({meta:{name:`Fetch`,slot:`fetch`},dependencies:{"path-to-regexp":D.devDependencies[`path-to-regexp`]},factory:j}),N={type:`module`,private:!0,name:`@kosmojs/hono-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,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.0`,"path-to-regexp":`^8.4.2`,vite:`^8.2.0`}},P=`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";
127
241
 
128
242
  import type { AppFactory } from "@kosmojs/core/api";
129
243
 
@@ -144,10 +258,10 @@ export const appFactory: AppFactory<App, AppOptions> = (factory) => {
144
258
  };
145
259
  return factory({ createApp });
146
260
  };
147
- `,F=`import type { DevSetup } from "@kosmojs/core/api";
261
+ `,L=`import type { DevSetup } from "@kosmojs/core/api";
148
262
 
149
263
  export const devSetup = (setup: DevSetup) => setup;
150
- `,I=`import type { Context } from "hono";
264
+ `,R=`import type { Context } from "hono";
151
265
 
152
266
  import type { AppEnv } from "./app";
153
267
 
@@ -161,10 +275,14 @@ export type ErrorHandlerFactory = (handler: ErrorHandler) => ErrorHandler;
161
275
  export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
162
276
  return handler;
163
277
  };
164
- `,L=`import type { Context } from "hono";
278
+ `,z=`import type { Context } from "hono";
165
279
 
166
- import type { RequestBodyTarget, RequestMetadataTarget } from "@kosmojs/core";
167
- import { parseCookies, parseQuerystring } from "@kosmojs/core/api";
280
+ import {
281
+ parseCookies,
282
+ parseSearchParams,
283
+ type RequestBodyTarget,
284
+ type RequestMetadataTarget,
285
+ } from "@kosmojs/core";
168
286
 
169
287
  export type BodyparserOptions = {
170
288
  json: never;
@@ -176,7 +294,7 @@ export const metaparsers: {
176
294
  [T in RequestMetadataTarget]: (ctx: Context) => unknown;
177
295
  } = {
178
296
  query(ctx) {
179
- return parseQuerystring(ctx.req.url);
297
+ return parseSearchParams(ctx.req.url);
180
298
  },
181
299
 
182
300
  headers(ctx) {
@@ -206,7 +324,7 @@ export const bodyparsers: {
206
324
  return ctx.req[as]();
207
325
  },
208
326
  };
209
- `,R=`import type { MiddlewareHandler } from "hono";
327
+ `,B=`import type { MiddlewareHandler } from "hono";
210
328
  import type { Router } from "hono/router";
211
329
  import { RegExpRouter } from "hono/router/reg-exp-router";
212
330
  import { SmartRouter } from "hono/router/smart-router";
@@ -239,6 +357,7 @@ import { type BodyparserOptions, bodyparsers, metaparsers } from "./parsers";
239
357
  import { routeSources } from "./routes";
240
358
 
241
359
  import globalMiddleware from "{{ createImport 'api' 'use' }}";
360
+ import { apiRouteMap } from "{{ createImport 'libCore' }}";
242
361
 
243
362
  /**
244
363
  * Create route-level middleware stack that handles:
@@ -255,7 +374,15 @@ import globalMiddleware from "{{ createImport 'api' 'use' }}";
255
374
  * */
256
375
  export const createRouteMiddleware: CreateRouteMiddleware<
257
376
  ParameterizedMiddleware
258
- > = ({ name, pathPattern, params, numericParams, validationSchemas }) => {
377
+ > = ({ name, pathPattern, validationSchemas }) => {
378
+ const route = apiRouteMap[name];
379
+
380
+ if (!route) {
381
+ throw new Error(\`createRouteMiddleware: \${name} route does not exists\`);
382
+ }
383
+
384
+ const { params, numericProperties } = route;
385
+
259
386
  const pathMatcher = match(pathPattern);
260
387
 
261
388
  const matchPath = (path: string) => {
@@ -266,6 +393,14 @@ export const createRouteMiddleware: CreateRouteMiddleware<
266
393
  }
267
394
  };
268
395
 
396
+ const maybeNumber = (val: unknown) => {
397
+ if (val === undefined || val === null) {
398
+ return val;
399
+ }
400
+ const n = Number(val);
401
+ return Number.isFinite(n) ? n : val;
402
+ };
403
+
269
404
  const validationMiddleware = [
270
405
  /**
271
406
  * Extends Hono context with:
@@ -303,7 +438,21 @@ export const createRouteMiddleware: CreateRouteMiddleware<
303
438
  ];
304
439
  map[target] = () => {
305
440
  if (!ctx[StateKey].has(target)) {
306
- ctx[StateKey].set(target, parser(ctx));
441
+ ctx[StateKey].set(
442
+ target,
443
+ target === "query"
444
+ ? Object.fromEntries(
445
+ Object.entries(parser(ctx)).map(([k, v]) => [
446
+ k,
447
+ numericProperties.query[ctx.req.method]?.includes(k)
448
+ ? Array.isArray(v)
449
+ ? v.map((e) => maybeNumber(e))
450
+ : maybeNumber(v)
451
+ : v,
452
+ ]),
453
+ )
454
+ : parser(ctx),
455
+ );
307
456
  }
308
457
  return ctx[StateKey].get(target);
309
458
  };
@@ -358,12 +507,12 @@ export const createRouteMiddleware: CreateRouteMiddleware<
358
507
  (map: Record<string, unknown>, name) => {
359
508
  const value = matched ? matched.params[name] : undefined;
360
509
  if (Array.isArray(value)) {
361
- map[name] = numericParams.includes(name)
362
- ? value.map(Number)
510
+ map[name] = numericProperties.params.includes(name)
511
+ ? value.map((e) => maybeNumber(e))
363
512
  : value;
364
513
  } else if (value) {
365
- map[name] = numericParams.includes(name) //
366
- ? Number(value)
514
+ map[name] = numericProperties.params.includes(name)
515
+ ? maybeNumber(value)
367
516
  : value;
368
517
  }
369
518
  return map;
@@ -606,7 +755,7 @@ export const routerFactory: RouterFactory<Router<never>, never> = (factory) => {
606
755
  };
607
756
  return factory({ createRouter });
608
757
  };
609
- `,z=`import { join } from "node:path";
758
+ `,V=`import { join } from "node:path";
610
759
 
611
760
  import type { RouteSource } from "@kosmojs/core/api";
612
761
 
@@ -647,13 +796,11 @@ export const routeSources: Array<RouteSource<never>> = [
647
796
  file: "{{file}}",
648
797
  cascadingMiddleware: [ {{#each cascadingMiddleware}}{{id}}, {{/each}}].flat() as Array<never>,
649
798
  definitionItems: {{id}} as never,
650
- params: [ {{#each params.schema}}"{{name}}", {{/each}}],
651
- numericParams: [ {{#each numericParams}}"{{.}}", {{/each}}],
652
799
  validationSchemas: {{id}}_schemas,
653
800
  },
654
801
  {{/each}}
655
802
  ];
656
- `,B=`import { chmod, unlink } from "node:fs/promises";
803
+ `,pe=`import { chmod, unlink } from "node:fs/promises";
657
804
  import { parseArgs, styleText } from "node:util";
658
805
 
659
806
  import { createAdaptorServer } from "@hono/node-server";
@@ -753,7 +900,7 @@ process.on("unhandledRejection", (reason) => {
753
900
  process.exit(1);
754
901
  }
755
902
  });
756
- `,V=`import type { Context, Next } from "hono";
903
+ `,me=`import type { Context, Next } from "hono";
757
904
 
758
905
  import type { ValidationDefmap, ValidationOptmap } from "@kosmojs/core";
759
906
  import {
@@ -936,13 +1083,13 @@ export const defineRoute: <
936
1083
  use: use as never,
937
1084
  });
938
1085
  };
939
- `,pe=`export * from "./@api/app";
1086
+ `,he=`export * from "./@api/app";
940
1087
  export * from "./@api/dev";
941
1088
  export * from "./@api/errors";
942
1089
  export * from "./@api/router";
943
1090
  export * from "./@api/routes";
944
1091
  export * from "./@api/server";
945
- `,me=`import defaultErrorHandler from "./errors";
1092
+ `,ge=`import defaultErrorHandler from "./errors";
946
1093
  import router from "./router";
947
1094
 
948
1095
  import { appFactory, routes } from "{{ createImport 'lib' 'api:factory' }}";
@@ -958,7 +1105,7 @@ export default appFactory(({ createApp }) => {
958
1105
 
959
1106
  return app;
960
1107
  });
961
- `,he=`import { getRequestListener } from "@hono/node-server";
1108
+ `,_e=`import { getRequestListener } from "@hono/node-server";
962
1109
 
963
1110
  import app from "./app";
964
1111
 
@@ -972,11 +1119,11 @@ export default devSetup({
972
1119
  // close db connections, server sockets etc.
973
1120
  },
974
1121
  });
975
- `,ge=`export declare module "{{ createImport 'libApi' }}" {
1122
+ `,ve=`export declare module "{{ createImport 'libApi' }}" {
976
1123
  interface DefaultVariables {}
977
1124
  interface DefaultBindings {}
978
1125
  }
979
- `,_e=`import { accepts } from "hono/accepts";
1126
+ `,ye=`import { accepts } from "hono/accepts";
980
1127
  import { HTTPException } from "hono/http-exception";
981
1128
 
982
1129
  import { ValidationError, HTTPError } from "@kosmojs/core/errors";
@@ -1010,7 +1157,7 @@ export default errorHandlerFactory(
1010
1157
  : ctx.text(message, status);
1011
1158
  },
1012
1159
  );
1013
- `,ve=`import { defineRoute } from "{{ createImport 'libApi' }}";
1160
+ `,be=`import { defineRoute } from "{{ createImport 'libApi' }}";
1014
1161
 
1015
1162
  export default defineRoute<"{{route.name}}">(({ GET }) => [
1016
1163
  GET(async (ctx) => {
@@ -1019,7 +1166,7 @@ export default defineRoute<"{{route.name}}">(({ GET }) => [
1019
1166
  return ctx.text("Automatically generated route");
1020
1167
  }),
1021
1168
  ]);
1022
- `,ye=`import { use } from "{{ createImport 'libApi' }}";
1169
+ `,xe=`import { use } from "{{ createImport 'libApi' }}";
1023
1170
 
1024
1171
  export type UseT = {};
1025
1172
 
@@ -1030,20 +1177,20 @@ export default [
1030
1177
  return next();
1031
1178
  }),
1032
1179
  ];
1033
- `,be=`import { routerFactory } from "{{ createImport 'lib' 'api:factory' }}";
1180
+ `,Se=`import { routerFactory } from "{{ createImport 'lib' 'api:factory' }}";
1034
1181
 
1035
1182
  export default routerFactory(({ createRouter }) => {
1036
1183
  const router = createRouter();
1037
1184
  return router;
1038
1185
  });
1039
- `,xe=`import app from "./app";
1186
+ `,Ce=`import app from "./app";
1040
1187
 
1041
1188
  import { serverFactory } from "{{ createImport 'lib' 'api:factory' }}";
1042
1189
 
1043
1190
  serverFactory(async ({ createServer }) => {
1044
1191
  await createServer(app);
1045
1192
  });
1046
- `,Se=`import { use } from "{{ createImport 'libApi' }}";
1193
+ `,we=`import { use } from "{{ createImport 'libApi' }}";
1047
1194
 
1048
1195
  /**
1049
1196
  * Define global middleware applied to all routes.
@@ -1054,7 +1201,7 @@ export default [
1054
1201
  return next();
1055
1202
  }),
1056
1203
  ];
1057
- `,Ce=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`}),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,ve),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),ye,{},{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`,z]])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`,V],[`api:factory.ts`,pe],[`@api/app.ts`,P],[`@api/parsers.ts`,L],[`@api/dev.ts`,F],[`@api/errors.ts`,I],[`@api/router.ts`,R],[`@api/server.ts`,B]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,me],[`dev.ts`,he],[`errors.ts`,_e],[`router.ts`,be],[`server.ts`,xe],[`use.ts`,Se]])await c(r.api(e),t,{},{overwrite:u});await o(r.api(`env.d.ts`),ge,{},{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)}}}),we=d({meta:{name:`Hono`,slot:`backend`},dependencies:{hono:N.devDependencies.hono,"@hono/node-server":N.devDependencies[`@hono/node-server`],"path-to-regexp":N.devDependencies[`path-to-regexp`]},factory:Ce}),H={type:`module`,private:!0,name:`@kosmojs/koa-generator`,version:`0.2.9`,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.0`}},Te=`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";
1058
1205
 
1059
1206
  import type { AppFactory } from "@kosmojs/core/api";
1060
1207
 
@@ -1072,10 +1219,10 @@ export const appFactory: AppFactory<App, AppOptions> = (factory) => {
1072
1219
  };
1073
1220
  return factory({ createApp });
1074
1221
  };
1075
- `,Ee=`import type { DevSetup } from "@kosmojs/core/api";
1222
+ `,Oe=`import type { DevSetup } from "@kosmojs/core/api";
1076
1223
 
1077
1224
  export const devSetup = (setup: DevSetup) => setup;
1078
- `,De=`import type { ParameterizedMiddleware } from "../api";
1225
+ `,ke=`import type { ParameterizedMiddleware } from "../api";
1079
1226
 
1080
1227
  export type ErrorHandlerFactory = (
1081
1228
  h: ParameterizedMiddleware,
@@ -1084,14 +1231,18 @@ export type ErrorHandlerFactory = (
1084
1231
  export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
1085
1232
  return handler;
1086
1233
  };
1087
- `,Oe=`import zlib from "node:zlib";
1234
+ `,Ae=`import zlib from "node:zlib";
1088
1235
 
1089
1236
  import type { RouterContext } from "@koa/router";
1090
1237
  import Formidable, { type Options as FormidableOptions } from "formidable";
1091
1238
  import rawParser from "raw-body";
1092
1239
 
1093
- import type { RequestBodyTarget, RequestMetadataTarget } from "@kosmojs/core";
1094
- import { parseCookies, parseQuerystring } from "@kosmojs/core/api";
1240
+ import {
1241
+ parseCookies,
1242
+ parseSearchParams,
1243
+ type RequestBodyTarget,
1244
+ type RequestMetadataTarget,
1245
+ } from "@kosmojs/core";
1095
1246
 
1096
1247
  import type {
1097
1248
  DefaultContext,
@@ -1103,7 +1254,7 @@ export const metaparsers: {
1103
1254
  [T in RequestMetadataTarget]: (ctx: RouterContext) => unknown;
1104
1255
  } = {
1105
1256
  query(ctx) {
1106
- return parseQuerystring(ctx.req.url ?? "");
1257
+ return parseSearchParams(ctx.req.url ?? "");
1107
1258
  },
1108
1259
 
1109
1260
  headers(ctx) {
@@ -1293,7 +1444,7 @@ export const bodyparsers: {
1293
1444
  return rawParser(stream, rawParserOptions);
1294
1445
  },
1295
1446
  };
1296
- `,ke=`import KoaRouter, { type RouterMiddleware } from "@koa/router";
1447
+ `,je=`import KoaRouter, { type RouterMiddleware } from "@koa/router";
1297
1448
  import { match } from "path-to-regexp";
1298
1449
 
1299
1450
  import type {
@@ -1322,6 +1473,7 @@ import { type BodyparserOptions, bodyparsers, metaparsers } from "./parsers";
1322
1473
  import { routeSources } from "./routes";
1323
1474
 
1324
1475
  import globalMiddleware from "{{ createImport 'api' 'use' }}";
1476
+ import { apiRouteMap } from "{{ createImport 'libCore' }}";
1325
1477
 
1326
1478
  export type Router = import("@koa/router").Router<DefaultState, DefaultContext>;
1327
1479
  export type RouterOptions = import("@koa/router").RouterOptions;
@@ -1341,7 +1493,15 @@ export type RouterOptions = import("@koa/router").RouterOptions;
1341
1493
  * */
1342
1494
  export const createRouteMiddleware: CreateRouteMiddleware<
1343
1495
  ParameterizedMiddleware
1344
- > = ({ name, pathPattern, params, numericParams, validationSchemas }) => {
1496
+ > = ({ name, pathPattern, validationSchemas }) => {
1497
+ const route = apiRouteMap[name];
1498
+
1499
+ if (!route) {
1500
+ throw new Error(\`createRouteMiddleware: \${name} route does not exists\`);
1501
+ }
1502
+
1503
+ const { params, numericProperties } = route;
1504
+
1345
1505
  const pathMatcher = match(pathPattern);
1346
1506
 
1347
1507
  const matchPath = (path: string) => {
@@ -1351,6 +1511,15 @@ export const createRouteMiddleware: CreateRouteMiddleware<
1351
1511
  return undefined;
1352
1512
  }
1353
1513
  };
1514
+
1515
+ const maybeNumber = (val: unknown) => {
1516
+ if (val === undefined || val === null) {
1517
+ return val;
1518
+ }
1519
+ const n = Number(val);
1520
+ return Number.isFinite(n) ? n : val;
1521
+ };
1522
+
1354
1523
  const validationMiddleware = [
1355
1524
  /**
1356
1525
  * Extends Koa context with:
@@ -1388,7 +1557,21 @@ export const createRouteMiddleware: CreateRouteMiddleware<
1388
1557
  ];
1389
1558
  map[target] = () => {
1390
1559
  if (!ctx[StateKey].has(target)) {
1391
- ctx[StateKey].set(target, parser(ctx));
1560
+ ctx[StateKey].set(
1561
+ target,
1562
+ target === "query"
1563
+ ? Object.fromEntries(
1564
+ Object.entries(parser(ctx)).map(([k, v]) => [
1565
+ k,
1566
+ numericProperties.query[ctx.method]?.includes(k)
1567
+ ? Array.isArray(v)
1568
+ ? v.map((e) => maybeNumber(e))
1569
+ : maybeNumber(v)
1570
+ : v,
1571
+ ]),
1572
+ )
1573
+ : parser(ctx),
1574
+ );
1392
1575
  }
1393
1576
  return ctx[StateKey].get(target);
1394
1577
  };
@@ -1443,12 +1626,12 @@ export const createRouteMiddleware: CreateRouteMiddleware<
1443
1626
  (map: Record<string, unknown>, name) => {
1444
1627
  const value = matched ? matched.params[name] : undefined;
1445
1628
  if (Array.isArray(value)) {
1446
- map[name] = numericParams.includes(name)
1447
- ? value.map(Number)
1629
+ map[name] = numericProperties.params.includes(name)
1630
+ ? value.map((e) => maybeNumber(e))
1448
1631
  : value;
1449
1632
  } else if (value) {
1450
- map[name] = numericParams.includes(name) //
1451
- ? Number(value)
1633
+ map[name] = numericProperties.params.includes(name)
1634
+ ? maybeNumber(value)
1452
1635
  : value;
1453
1636
  }
1454
1637
  return map;
@@ -1692,7 +1875,7 @@ export const routerFactory: RouterFactory<Router, RouterOptions> = (
1692
1875
  };
1693
1876
  return factory({ createRouter });
1694
1877
  };
1695
- `,Ae=`import { join } from "node:path";
1878
+ `,Me=`import { join } from "node:path";
1696
1879
 
1697
1880
  import type { RouteSource } from "@kosmojs/core/api";
1698
1881
 
@@ -1733,13 +1916,11 @@ export const routeSources: Array<RouteSource<never>> = [
1733
1916
  file: "{{file}}",
1734
1917
  cascadingMiddleware: [ {{#each cascadingMiddleware}}{{id}}, {{/each}}].flat() as Array<never>,
1735
1918
  definitionItems: {{id}} as never,
1736
- params: [ {{#each params.schema}}"{{name}}", {{/each}}],
1737
- numericParams: [ {{#each numericParams}}"{{.}}", {{/each}}],
1738
1919
  validationSchemas: {{id}}_schemas,
1739
1920
  },
1740
1921
  {{/each}}
1741
1922
  ] as const;
1742
- `,je=`import { chmod, unlink } from "node:fs/promises";
1923
+ `,Ne=`import { chmod, unlink } from "node:fs/promises";
1743
1924
  import { parseArgs, styleText } from "node:util";
1744
1925
 
1745
1926
  import type { ServerFactory } from "@kosmojs/core/api";
@@ -1817,7 +1998,7 @@ process.on("unhandledRejection", (reason) => {
1817
1998
  process.exit(1);
1818
1999
  }
1819
2000
  });
1820
- `,Me=`import type { RouterContext } from "@koa/router";
2001
+ `,Pe=`import type { RouterContext } from "@koa/router";
1821
2002
  import type { Next } from "koa";
1822
2003
 
1823
2004
  import type { ValidationDefmap, ValidationOptmap } from "@kosmojs/core";
@@ -1979,13 +2160,13 @@ export const defineRoute: <
1979
2160
  use: use as never,
1980
2161
  });
1981
2162
  };
1982
- `,Ne=`export * from "./@api/app";
2163
+ `,Fe=`export * from "./@api/app";
1983
2164
  export * from "./@api/dev";
1984
2165
  export * from "./@api/errors";
1985
2166
  export * from "./@api/router";
1986
2167
  export * from "./@api/routes";
1987
2168
  export * from "./@api/server";
1988
- `,Pe=`import router from "./router";
2169
+ `,Ie=`import router from "./router";
1989
2170
 
1990
2171
  import { appFactory } from "{{ createImport 'lib' 'api:factory' }}";
1991
2172
 
@@ -1997,7 +2178,7 @@ export default appFactory(({ createApp }) => {
1997
2178
 
1998
2179
  return app;
1999
2180
  });
2000
- `,Fe=`import app from "./app";
2181
+ `,Le=`import app from "./app";
2001
2182
 
2002
2183
  import { devSetup } from "{{ createImport 'lib' 'api:factory' }}";
2003
2184
 
@@ -2009,11 +2190,11 @@ export default devSetup({
2009
2190
  // close db connections, server sockets etc.
2010
2191
  },
2011
2192
  });
2012
- `,Ie=`export declare module "{{ createImport 'libApi' }}" {
2193
+ `,Re=`export declare module "{{ createImport 'libApi' }}" {
2013
2194
  interface DefaultState {}
2014
2195
  interface DefaultContext {}
2015
2196
  }
2016
- `,Le=`import { HTTPError, ValidationError } from "@kosmojs/core/errors";
2197
+ `,ze=`import { HTTPError, ValidationError } from "@kosmojs/core/errors";
2017
2198
 
2018
2199
  import { errorHandlerFactory } from "{{ createImport 'lib' 'api:factory' }}";
2019
2200
 
@@ -2040,14 +2221,14 @@ export default errorHandlerFactory(
2040
2221
  }
2041
2222
  },
2042
2223
  );
2043
- `,Re=`import { defineRoute } from "{{ createImport 'libApi' }}";
2224
+ `,Be=`import { defineRoute } from "{{ createImport 'libApi' }}";
2044
2225
 
2045
2226
  export default defineRoute<"{{route.name}}">(({ GET }) => [
2046
2227
  GET(async (ctx) => {
2047
2228
  ctx.body = "Automatically generated route";
2048
2229
  }),
2049
2230
  ]);
2050
- `,ze=`import { use } from "{{ createImport 'libApi' }}";
2231
+ `,Ve=`import { use } from "{{ createImport 'libApi' }}";
2051
2232
 
2052
2233
  export type UseT = {};
2053
2234
 
@@ -2058,7 +2239,7 @@ export default [
2058
2239
  return next();
2059
2240
  }),
2060
2241
  ];
2061
- `,Be=`import { routerFactory, routes } from "{{ createImport 'lib' 'api:factory' }}";
2242
+ `,He=`import { routerFactory, routes } from "{{ createImport 'lib' 'api:factory' }}";
2062
2243
 
2063
2244
  export default routerFactory(({ createRouter }) => {
2064
2245
  const router = createRouter();
@@ -2069,14 +2250,14 @@ export default routerFactory(({ createRouter }) => {
2069
2250
 
2070
2251
  return router;
2071
2252
  });
2072
- `,Ve=`import app from "./app";
2253
+ `,Ue=`import app from "./app";
2073
2254
 
2074
2255
  import { serverFactory } from "{{ createImport 'lib' 'api:factory' }}";
2075
2256
 
2076
2257
  serverFactory(async ({ createServer }) => {
2077
2258
  await createServer(app);
2078
2259
  });
2079
- `,He=`import defaultErrorHandler from "./errors";
2260
+ `,We=`import defaultErrorHandler from "./errors";
2080
2261
 
2081
2262
  import { use } from "{{ createImport 'libApi' }}";
2082
2263
 
@@ -2087,17 +2268,17 @@ export default [
2087
2268
  * */
2088
2269
  use(defaultErrorHandler, { slot: "errorHandler" }),
2089
2270
  ];
2090
- `,Ue=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`}),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,Re),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),ze,{},{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`,Ae]])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`,Ne],[`@api/app.ts`,Te],[`@api/dev.ts`,Ee],[`@api/errors.ts`,De],[`@api/parsers.ts`,Oe],[`@api/router.ts`,ke],[`@api/server.ts`,je]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,Pe],[`dev.ts`,Fe],[`errors.ts`,Le],[`router.ts`,Be],[`server.ts`,Ve],[`use.ts`,He]])await c(r.api(e),t,{},{overwrite:l});await o(r.api(`env.d.ts`),Ie,{},{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)}}}),We=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:Ue}),U={type:`module`,private:!0,name:`@kosmojs/mdx-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@mdx-js/rollup":`^3.1.1`,vite:`^8.2.0`},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`}},Ge=()=>{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)]},Ke=(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,`
2091
2272
  if (import.meta.hot) {
2092
2273
  import.meta.hot.accept(() => {});
2093
2274
  }
2094
2275
  `].join(`
2095
- `)}}}},o=[ne({jsxImportSource:`preact`,providerImportSource:`@mdx-js/preact`,remarkPlugins:r,rehypePlugins:i})];return t===`serve`&&o.push(a()),o},qe=`import type { FunctionComponent } from "preact";
2276
+ `)}}}},o=[ne({jsxImportSource:`preact`,providerImportSource:`@mdx-js/preact`,remarkPlugins:r,rehypePlugins:i})];return t===`serve`&&o.push(a()),o},Ye=`import type { FunctionComponent } from "preact";
2096
2277
 
2097
2278
  export const AppProvider: FunctionComponent = (props) => {
2098
2279
  return props.children;
2099
2280
  };
2100
- `,Je=`import { render, hydrate as hydrateOrig } from "preact";
2281
+ `,Xe=`import { render, hydrate as hydrateOrig } from "preact";
2101
2282
  import type { RouterFactoryReturn } from "@kosmojs/core";
2102
2283
  import { clientRenderFactory } from "@kosmojs/core/generators";
2103
2284
 
@@ -2138,7 +2319,7 @@ export const mount = async (
2138
2319
  }
2139
2320
 
2140
2321
  export default clientRenderFactory();
2141
- `,Ye=`import { renderToString as renderToStringOrig } from "preact-render-to-string";
2322
+ `,Ze=`import { renderToString as renderToStringOrig } from "preact-render-to-string";
2142
2323
 
2143
2324
  import type {
2144
2325
  RenderToStringWrapper,
@@ -2212,7 +2393,7 @@ export const renderToString: RenderToStringWrapper<
2212
2393
  }
2213
2394
 
2214
2395
  export default serverRenderFactory<false>();
2215
- `,Xe=`declare module "*.mdx" {
2396
+ `,Qe=`declare module "*.mdx" {
2216
2397
  import type { ComponentType } from "preact";
2217
2398
  export const frontmatter: Record<string, unknown>;
2218
2399
  const component: ComponentType;
@@ -2225,10 +2406,12 @@ declare module "*.md" {
2225
2406
  const component: ComponentType;
2226
2407
  export default component;
2227
2408
  }
2228
- `,Ze=`import { MDXProvider } from "@mdx-js/preact";
2409
+ `,$e=`import { MDXProvider } from "@mdx-js/preact";
2229
2410
  import { match, pathToRegexp } from "path-to-regexp";
2230
2411
  import { type ComponentType, createContext, h, type VNode } from "preact";
2231
2412
 
2413
+ import { parseSearchParams } from "@kosmojs/core";
2414
+
2232
2415
  import { paramNames } from "{{ createImport 'lib' 'params' }}";
2233
2416
  import { base } from "{{ createImport 'libCore' }}";
2234
2417
 
@@ -2242,7 +2425,7 @@ export type RawRoute = {
2242
2425
  };
2243
2426
 
2244
2427
  type Loader = (
2245
- route: Pick<Route, "name" | "params" | "paramsEntries">,
2428
+ route: Pick<Route, "name" | "params" | "paramsEntries" | "searchParams">,
2246
2429
  ) => Promise<unknown> | undefined;
2247
2430
 
2248
2431
  type LayoutModule = {
@@ -2262,6 +2445,7 @@ export type Route = {
2262
2445
  name: string;
2263
2446
  params: Record<string, string | Array<string>>;
2264
2447
  paramsEntries: [keys: Array<string>, values: Array<unknown>];
2448
+ searchParams: Record<string, unknown>;
2265
2449
  frontmatter: Record<string, unknown>;
2266
2450
  loaderData: Record<string, unknown>;
2267
2451
  };
@@ -2270,6 +2454,7 @@ export const RouterContext = createContext<Route>({
2270
2454
  name: "",
2271
2455
  params: {},
2272
2456
  paramsEntries: [[], []],
2457
+ searchParams: {},
2273
2458
  frontmatter: {},
2274
2459
  loaderData: {},
2275
2460
  });
@@ -2299,6 +2484,7 @@ export const createRouter = (
2299
2484
 
2300
2485
  return {
2301
2486
  async resolve(url: URL = new URL(window.location.href)) {
2487
+ const searchParams = parseSearchParams(url);
2302
2488
  const urlSegments = url.pathname.split("/").filter(Boolean).length;
2303
2489
 
2304
2490
  // 1: use lightweight \`RegExp.test()\` on linear scan - no capture allocation
@@ -2343,7 +2529,7 @@ export const createRouter = (
2343
2529
 
2344
2530
  loaderData[name] = await runLoader(name, () => {
2345
2531
  return routeModule.loader
2346
- ? routeModule.loader({ name, params, paramsEntries })
2532
+ ? routeModule.loader({ name, params, paramsEntries, searchParams })
2347
2533
  : undefined; // should not survive serialization if no loader defined
2348
2534
  });
2349
2535
 
@@ -2358,7 +2544,7 @@ export const createRouter = (
2358
2544
  const key = \`\${name}/layout\`;
2359
2545
  loaderData[key] = await runLoader(key, () => {
2360
2546
  return layoutModule.loader
2361
- ? layoutModule.loader({ name, params, paramsEntries })
2547
+ ? layoutModule.loader({ name, params, paramsEntries, searchParams })
2362
2548
  : undefined; // should not survive serialization if no loader defined
2363
2549
  });
2364
2550
  }
@@ -2367,6 +2553,7 @@ export const createRouter = (
2367
2553
  name,
2368
2554
  params,
2369
2555
  paramsEntries,
2556
+ searchParams,
2370
2557
  frontmatter,
2371
2558
  loaderData,
2372
2559
  };
@@ -2415,7 +2602,7 @@ export const createRoute = (
2415
2602
  layouts,
2416
2603
  };
2417
2604
  };
2418
- `,Qe=`/* @jsxImportSource preact */
2605
+ `,et=`/* @jsxImportSource preact */
2419
2606
 
2420
2607
  import styles from "./styles.module.css";
2421
2608
 
@@ -2456,7 +2643,7 @@ export default function PageSample(props: {
2456
2643
  </div>
2457
2644
  );
2458
2645
  }
2459
- `,$e=`/* @jsxImportSource preact */
2646
+ `,tt=`/* @jsxImportSource preact */
2460
2647
 
2461
2648
  import styles from "./styles.module.css";
2462
2649
 
@@ -2508,7 +2695,7 @@ export default function PageSample(props: {
2508
2695
  </div>
2509
2696
  );
2510
2697
  }
2511
- `,et=`* {
2698
+ `,nt=`* {
2512
2699
  margin: 0;
2513
2700
  padding: 0;
2514
2701
  box-sizing: border-box;
@@ -2643,7 +2830,7 @@ export default function PageSample(props: {
2643
2830
  align-items: center;
2644
2831
  gap: 0.25rem;
2645
2832
  }
2646
- `,tt=`/* @jsxImportSource preact */
2833
+ `,rt=`/* @jsxImportSource preact */
2647
2834
 
2648
2835
  import styles from "./styles.module.css";
2649
2836
 
@@ -2709,7 +2896,7 @@ export default function WelcomePage() {
2709
2896
  </div>
2710
2897
  );
2711
2898
  }
2712
- `,nt=`export type ParamsMap = {
2899
+ `,it=`export type ParamsMap = {
2713
2900
  {{#each pageRoutes}}"{{name}}": {{serializeParamsLiteral .}};
2714
2901
  {{/each}}
2715
2902
  };
@@ -2718,7 +2905,7 @@ export const paramNames = {
2718
2905
  {{#each pageRoutes}}"{{name}}": [ {{#each params.schema}}"{{name}}", {{/each}}],
2719
2906
  {{/each}}
2720
2907
  } as const;
2721
- `,rt=`import type { ComponentType } from "preact";
2908
+ `,at=`import type { ComponentType } from "preact";
2722
2909
 
2723
2910
  import type { RouterFactoryReturn } from "@kosmojs/core";
2724
2911
  import { createRouterFactory } from "@kosmojs/core/generators";
@@ -2762,7 +2949,7 @@ export default createRouterFactory<
2762
2949
  Promise<RouteComponent>,
2763
2950
  { server: { route: Route } }
2764
2951
  >();
2765
- `,it=`import { join } from "node:path";
2952
+ `,ot=`import { join } from "node:path";
2766
2953
 
2767
2954
  import { compile } from "path-to-regexp";
2768
2955
 
@@ -2808,7 +2995,7 @@ export default Object.entries(routes)
2808
2995
  return [];
2809
2996
  })
2810
2997
  .map((path) => join(base, path));
2811
- `,at=`import type { PageRoute } from "@kosmojs/core";
2998
+ `,st=`import type { PageRoute } from "@kosmojs/core";
2812
2999
 
2813
3000
  {{#each pageRoutes}}
2814
3001
  import * as {{id}} from "{{ createImport 'pages' file }}";
@@ -2832,18 +3019,18 @@ const routeMap: Record<
2832
3019
  }
2833
3020
 
2834
3021
  export default routeMap;
2835
- `,ot=`import { useContext } from "preact/hooks";
3022
+ `,ct=`import { useContext } from "preact/hooks";
2836
3023
 
2837
3024
  import { RouterContext } from "./mdx";
2838
3025
 
2839
3026
  import type { ParamsMap, paramNames } from "{{ createImport 'lib' 'params' }}";
2840
3027
 
2841
3028
  export function useRoute() {
2842
- return useContext(RouterContext);
3029
+ return structuredClone(useContext(RouterContext));
2843
3030
  }
2844
3031
 
2845
3032
  export function useParams<T extends keyof ParamsMap>(): ParamsMap[T] {
2846
- return useContext(RouterContext).params as ParamsMap[T];
3033
+ return useRoute().params as ParamsMap[T];
2847
3034
  }
2848
3035
 
2849
3036
  type SameLengthTuple<T extends readonly unknown[], U> = { [K in keyof T]: U };
@@ -2852,7 +3039,11 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
2852
3039
  (typeof paramNames)[T],
2853
3040
  SameLengthTuple<(typeof paramNames)[T], unknown>,
2854
3041
  ] {
2855
- return useContext(RouterContext).paramsEntries as never;
3042
+ return useRoute().paramsEntries as never;
3043
+ }
3044
+
3045
+ export function useSearchParams() {
3046
+ return useRoute().searchParams;
2856
3047
  }
2857
3048
 
2858
3049
  /**
@@ -2862,7 +3053,7 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
2862
3053
  * a hook can't tell which layout it runs in.
2863
3054
  * */
2864
3055
  export const useLoaderData = <T>(key?: string): T | undefined => {
2865
- const route = useContext(RouterContext);
3056
+ const route = useRoute();
2866
3057
  return route.loaderData?.[key || route.name] as T;
2867
3058
  };
2868
3059
 
@@ -2872,12 +3063,12 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
2872
3063
  export const useFrontmatter = <
2873
3064
  T extends Record<string, unknown> = Record<string, unknown>,
2874
3065
  >(): T => {
2875
- return useContext(RouterContext).frontmatter as T;
3066
+ return useRoute().frontmatter as T;
2876
3067
  };
2877
- `,st=`import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3068
+ `,lt=`import { AppProvider } from "{{ createImport 'lib' 'app' }}";
2878
3069
 
2879
3070
  <AppProvider>{props.children}</AppProvider>
2880
- `,ct=`import { h, type JSX } from "preact";
3071
+ `,ut=`import { h, type JSX } from "preact";
2881
3072
 
2882
3073
  import { pageRouteMap, type LinkProps } from "{{ createImport 'libCore' }}";
2883
3074
 
@@ -2894,7 +3085,7 @@ export default function Link(
2894
3085
 
2895
3086
  return h("a", { ...restProps, href }, children);
2896
3087
  }
2897
- `,lt=`/**
3088
+ `,dt=`/**
2898
3089
  * MDX component overrides.
2899
3090
  *
2900
3091
  * Every standard markdown element (headings, links, code blocks, etc.)
@@ -2917,7 +3108,7 @@ export const components = {
2917
3108
  declare global {
2918
3109
  type MDXProvidedComponents = typeof components;
2919
3110
  }
2920
- `,ut=`import renderFactory, {
3111
+ `,ft=`import renderFactory, {
2921
3112
  createRoutes,
2922
3113
  hydrate,
2923
3114
  mount,
@@ -2944,7 +3135,7 @@ if (root) {
2944
3135
  } else {
2945
3136
  console.error("❌ Root element not found!");
2946
3137
  }
2947
- `,dt=`import renderFactory, {
3138
+ `,pt=`import renderFactory, {
2948
3139
  createRoutes,
2949
3140
  renderToString,
2950
3141
  // no renderToStream on MDX folders
@@ -2965,7 +3156,7 @@ export default renderFactory(() => {
2965
3156
  },
2966
3157
  };
2967
3158
  });
2968
- `,ft=`<!doctype html>
3159
+ `,mt=`<!doctype html>
2969
3160
  <html lang="en">
2970
3161
  <head>
2971
3162
  <meta charset="UTF-8" />
@@ -2977,13 +3168,13 @@ export default renderFactory(() => {
2977
3168
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
2978
3169
  </body>
2979
3170
  </html>
2980
- `,pt=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3171
+ `,ht=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
2981
3172
 
2982
3173
  export default function Page() {
2983
3174
  return <PageSample />;
2984
3175
  }
2985
- `,mt=`{props.children}
2986
- `,ht=`---
3176
+ `,gt=`{props.children}
3177
+ `,_t=`---
2987
3178
  title: "{{title}}"
2988
3179
  ---
2989
3180
 
@@ -3000,7 +3191,7 @@ export const pathMap = {
3000
3191
  routeName="{{route.name}}"
3001
3192
  pathMap={pathMap}
3002
3193
  />
3003
- `,gt=`---
3194
+ `,vt=`---
3004
3195
  title: Welcome to KosmoJS
3005
3196
  description: Content-first development with MDX and Vite
3006
3197
  ---
@@ -3008,7 +3199,7 @@ description: Content-first development with MDX and Vite
3008
3199
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}"
3009
3200
 
3010
3201
  <WelcomePage />
3011
- `,_t=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3202
+ `,yt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3012
3203
 
3013
3204
  import app from "./app.mdx";
3014
3205
  import { components } from "./components/mdx"
@@ -3024,12 +3215,12 @@ export default routerFactory((routes) => {
3024
3215
  },
3025
3216
  };
3026
3217
  });
3027
- `,vt=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,ht),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?gt:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:Ge()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),mt,{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`,Je],[`server.ts`,Ye]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,nt],[`router.ts`,rt],[`ssg:routes.ts`,at]])await i(n.lib(e),t,{pageRoutes:r})};return{config({command:n}){return{oxc:{jsx:{importSource:`preact`}},plugins:Ke(e,n,t)}},async start(){for(let[e,t]of[[`env.d.ts`,Xe],[`app.ts`,qe],[`mdx.ts`,Ze],[`use.ts`,ot],[`ssg.ts`,it],[`pageSamples/styles.module.css`,et],[`pageSamples/welcome.tsx`,tt],[`pageSamples/page.tsx`,$e],[`pageSamples/404.tsx`,Qe]])await i(n.lib(e),t,{});for(let[e,t]of[[`pages/404.mdx`,pt],[`components/Link.tsx`,ct],[`components/mdx.ts`,lt],[`app.mdx`,st],[`router.ts`,_t]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),ft,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,ut],[`server.ts`,dt]])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)}}}),yt=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:vt}),bt={json:`application/json`,form:[`application/x-www-form-urlencoded`,`multipart/form-data`],raw:void 0},xt=()=>{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.nameLiteral}\\*?\\}`).test(t)?[{$ref:r(`parameters`,e,e.params.id,n.nameLiteral)}]:[]);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]=St(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.nameLiteral);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.nameLiteral)]={name:i.nameLiteral,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.nameLiteral,in:`query`,required:!t.optional,schema:{$ref:r(`schemas`,e,d.schema.id,t.nameLiteral)}});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=bt[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}}}},St=(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]},Ct=f((e,t)=>{let{outfile:n=``,...r}={...t},{createPath:i}=h(e),{generateOpenAPISchema:a}=xt(),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)}}}),wt=d({meta:{name:`OpenAPI`,resolveTypes:!0},factory:Ct}),W={type:`module`,private:!0,name:`@kosmojs/react-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,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`}},Tt=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(`/`)},Et=()=>{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=Tt(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},Dt=()=>{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)]},Ot=`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";
3028
3219
 
3029
3220
  export const AppProvider = ({ children }: { children: ReactNode }) => {
3030
3221
  return children;
3031
3222
  }
3032
- `,kt=`import { type QueryClient, QueryClientProvider } from "@tanstack/react-query";
3223
+ `,jt=`import { type QueryClient, QueryClientProvider } from "@tanstack/react-query";
3033
3224
  import type { ReactNode } from "react";
3034
3225
 
3035
3226
  import { getQueryClient } from "./query";
@@ -3048,7 +3239,7 @@ export const AppProvider = ({
3048
3239
  </QueryClientProvider>
3049
3240
  );
3050
3241
  }
3051
- `,At=`import { lazy, type JSX } from "react";
3242
+ `,Mt=`import { lazy, type JSX } from "react";
3052
3243
 
3053
3244
  import {
3054
3245
  createRoot,
@@ -3102,7 +3293,7 @@ export const mount = async (
3102
3293
  }
3103
3294
 
3104
3295
  export default clientRenderFactory();
3105
- `,jt=`{
3296
+ `,Nt=`{
3106
3297
  {{#if name}}
3107
3298
  id: "{{name}}",
3108
3299
  {{/if}}
@@ -3120,7 +3311,7 @@ export default clientRenderFactory();
3120
3311
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
3121
3312
  {{/if}}
3122
3313
  }
3123
- `,Mt=`import type { JSX } from "react";
3314
+ `,Pt=`import type { JSX } from "react";
3124
3315
 
3125
3316
  import {
3126
3317
  renderToString as renderToStringOrig,
@@ -3186,7 +3377,7 @@ export const renderToStream: RenderToStreamWrapper<
3186
3377
  };
3187
3378
 
3188
3379
  export default serverRenderFactory();
3189
- `,Nt=`/* @jsxImportSource react */
3380
+ `,Ft=`/* @jsxImportSource react */
3190
3381
 
3191
3382
  import styles from "./styles.module.css";
3192
3383
 
@@ -3227,7 +3418,7 @@ export default function PageSample(props: {
3227
3418
  </div>
3228
3419
  );
3229
3420
  }
3230
- `,Pt=`/* @jsxImportSource react */
3421
+ `,It=`/* @jsxImportSource react */
3231
3422
 
3232
3423
  import styles from "./styles.module.css";
3233
3424
 
@@ -3279,7 +3470,7 @@ export default function PageSample(props: {
3279
3470
  </div>
3280
3471
  );
3281
3472
  }
3282
- `,Ft=`* {
3473
+ `,Lt=`* {
3283
3474
  margin: 0;
3284
3475
  padding: 0;
3285
3476
  box-sizing: border-box;
@@ -3414,7 +3605,7 @@ export default function PageSample(props: {
3414
3605
  align-items: center;
3415
3606
  gap: 0.25rem;
3416
3607
  }
3417
- `,It=`/* @jsxImportSource react */
3608
+ `,Rt=`/* @jsxImportSource react */
3418
3609
 
3419
3610
  import styles from "./styles.module.css";
3420
3611
 
@@ -3480,7 +3671,7 @@ export default function WelcomePage() {
3480
3671
  </div>
3481
3672
  );
3482
3673
  }
3483
- `,Lt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3674
+ `,zt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3484
3675
 
3485
3676
  let client: QueryClient | undefined;
3486
3677
 
@@ -3495,7 +3686,7 @@ export const getQueryClient = (): QueryClient => {
3495
3686
  }
3496
3687
  return client;
3497
3688
  };
3498
- `,Rt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3689
+ `,Bt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3499
3690
 
3500
3691
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
3501
3692
 
@@ -3518,40 +3709,27 @@ export const getQueryClient = (): QueryClient => {
3518
3709
  }
3519
3710
  return ctx.tsqClient as QueryClient;
3520
3711
  };
3521
- `,zt=`export type ComponentLoader = () => Promise<{
3712
+ `,Vt=`export type ComponentLoader = () => Promise<{
3522
3713
  loader?: (arg: unknown) => Promise<unknown>;
3523
3714
  }>;
3524
3715
 
3525
3716
  export const loaderFactory = (opt?: { withPreload?: boolean }) => {
3526
3717
  return (componentLoader: ComponentLoader) => {
3527
3718
  const loader = async (arg: unknown) => {
3528
- try {
3529
- const component = await componentLoader();
3530
- // Return null, not undefined, when a route has no loader. RR keys
3531
- // hydration data by route id; an undefined value is dropped by
3532
- // JSON.stringify during serialization, leaving the id absent, which
3533
- // makes RR re-run the loader on the client and double-render. null
3534
- // survives serialization, so the id stays present and RR skips it.
3535
- return typeof component.loader === "function"
3536
- ? await component.loader(arg)
3537
- : null;
3538
- } catch (error) {
3539
- // TODO: swallowing loader errors is wrong. Returning null hydrates the
3540
- // route as "loaded, value null" - RR never sees the failure, so no
3541
- // errorElement/ErrorBoundary fires on server or client, and this
3542
- // console.error runs server-side during SSR so the client sees nothing.
3543
- // Proper fix: let the error reach RR's \`context.errors\` (rethrow, or
3544
- // return a Response/data() with an error status) so it serializes into
3545
- // __staticRouterHydrationData.errors and renders the route boundary
3546
- // isomorphically.
3547
- console.error(error);
3548
- return null;
3549
- }
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;
3550
3728
  };
3551
3729
  return opt?.withPreload ? { loader } : {};
3552
3730
  };
3553
3731
  };
3554
- `,Bt=`import type { JSX, ComponentType } from "react";
3732
+ `,Ht=`import type { JSX, ComponentType } from "react";
3555
3733
 
3556
3734
  import {
3557
3735
  type RouteObject,
@@ -3609,7 +3787,7 @@ export const createRouters = (
3609
3787
  }
3610
3788
 
3611
3789
  export default createRouterFactory<RouteObject, Promise<JSX.Element>>();
3612
- `,Vt=`import { Outlet } from "react-router";
3790
+ `,Ut=`import { Outlet } from "react-router";
3613
3791
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3614
3792
 
3615
3793
  export default function App() {
@@ -3619,7 +3797,7 @@ export default function App() {
3619
3797
  </AppProvider>
3620
3798
  );
3621
3799
  }
3622
- `,Ht=`import {
3800
+ `,Wt=`import {
3623
3801
  type LinkProps as RouterLinkProps,
3624
3802
  Link as RouterLink,
3625
3803
  } from "react-router";
@@ -3647,7 +3825,7 @@ export default function Link(
3647
3825
  </RouterLink>
3648
3826
  );
3649
3827
  }
3650
- `,Ut=`import renderFactory, {
3828
+ `,Gt=`import renderFactory, {
3651
3829
  createRoutes,
3652
3830
  hydrate,
3653
3831
  mount,
@@ -3674,7 +3852,7 @@ if (root) {
3674
3852
  } else {
3675
3853
  console.error("❌ Root element not found!");
3676
3854
  }
3677
- `,Wt=`import renderFactory, {
3855
+ `,Kt=`import renderFactory, {
3678
3856
  createRoutes,
3679
3857
  renderToStream,
3680
3858
  renderToString,
@@ -3701,7 +3879,7 @@ export default renderFactory(() => {
3701
3879
  },
3702
3880
  };
3703
3881
  });
3704
- `,Gt=`<!doctype html>
3882
+ `,qt=`<!doctype html>
3705
3883
  <html lang="en">
3706
3884
  <head>
3707
3885
  <meta charset="UTF-8" />
@@ -3713,17 +3891,17 @@ export default renderFactory(() => {
3713
3891
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
3714
3892
  </body>
3715
3893
  </html>
3716
- `,Kt=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3894
+ `,Jt=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3717
3895
 
3718
3896
  export default function Page() {
3719
3897
  return <PageSample />;
3720
3898
  }
3721
- `,qt=`import { Outlet } from "react-router";
3899
+ `,Yt=`import { Outlet } from "react-router";
3722
3900
 
3723
3901
  export default function Layout() {
3724
3902
  return <Outlet />;
3725
3903
  }
3726
- `,Jt=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
3904
+ `,Xt=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
3727
3905
 
3728
3906
  export default function Page() {
3729
3907
  return PageSample({
@@ -3736,8 +3914,8 @@ export default function Page() {
3736
3914
  },
3737
3915
  });
3738
3916
  }
3739
- `,Yt=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
3740
- `,Xt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3917
+ `,Zt=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
3918
+ `,Qt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3741
3919
 
3742
3920
  import app from "./app";
3743
3921
 
@@ -3752,12 +3930,12 @@ export default routerFactory((routes) => {
3752
3930
  },
3753
3931
  };
3754
3932
  });
3755
- `,Zt=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()},partials:{routePartial:jt}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=Et(),l=e=>!e?.trim().length,u=s(t?.templates,Jt),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Yt:u(r.name,r),{route:r,message:Dt()},{overwrite:l}):t===`pageLayout`&&await a(n.pages(r.file),qt,{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`,At],[`server.ts`,Mt]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a});await i(n.lib(`router.tsx`),Bt,{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`,zt],[`pageSamples/styles.module.css`,Ft],[`pageSamples/welcome.tsx`,It],[`pageSamples/page.tsx`,Pt],[`pageSamples/404.tsx`,Nt],...t?.tanstack?.query?[[`app.tsx`,kt],[`query.ts`,Lt]]:[[`app.tsx`,Ot],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.tsx`,Kt],[`components/Link.tsx`,Ht],[`app.tsx`,Vt],[`router.ts`,Xt]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:l});await a(n.src(`index.html`),Gt,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Ut],[`server.ts`,Wt]])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?Rt:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),Qt=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:Zt}),G={type:`module`,private:!0,name:`@kosmojs/solid-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,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`}},$t=()=>{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(`/`)},en=()=>{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)]},tn=`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";
3756
3934
 
3757
3935
  export const AppProvider: ParentComponent = (props) => {
3758
3936
  return props.children;
3759
3937
  };
3760
- `,nn=`import type { ParentComponent } from "solid-js";
3938
+ `,an=`import type { ParentComponent } from "solid-js";
3761
3939
  import { type QueryClient, QueryClientProvider } from "@tanstack/solid-query";
3762
3940
 
3763
3941
  import { getQueryClient } from "./query";
@@ -3769,7 +3947,7 @@ export const AppProvider: ParentComponent<{ client?: QueryClient }> = (props) =>
3769
3947
  </QueryClientProvider>
3770
3948
  );
3771
3949
  };
3772
- `,rn=`import { lazy, type JSX } from "solid-js";
3950
+ `,on=`import { lazy, type JSX } from "solid-js";
3773
3951
  import { hydrate as hydrateOrig, render } from "solid-js/web";
3774
3952
  import type { RouterFactoryReturn } from "@kosmojs/core";
3775
3953
  import { clientRenderFactory } from "@kosmojs/core/generators";
@@ -3814,7 +3992,7 @@ export const mount = async (
3814
3992
  }
3815
3993
 
3816
3994
  export default clientRenderFactory();
3817
- `,an=`{
3995
+ `,sn=`{
3818
3996
  path: "{{path}}",
3819
3997
  {{#if component}}
3820
3998
  component: {{component}}_component,
@@ -3824,7 +4002,7 @@ export default clientRenderFactory();
3824
4002
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
3825
4003
  {{/if}}
3826
4004
  }
3827
- `,on=`import type { JSX } from "solid-js";
4005
+ `,cn=`import type { JSX } from "solid-js";
3828
4006
 
3829
4007
  import {
3830
4008
  generateHydrationScript,
@@ -3892,7 +4070,12 @@ export const renderToStream: RenderToStreamWrapper<
3892
4070
  > = async (resolver, { headerTags = [], ...options } = {}) => {
3893
4071
  const stream = renderToStreamOrig(() => resolver().component, options);
3894
4072
  const { readable, writable } = new TransformStream<string, string>();
3895
- 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(() => {});
3896
4079
  return {
3897
4080
  head: [...headerTags, generateHydrationScript()].join("\\n"),
3898
4081
  html: readable,
@@ -3900,7 +4083,7 @@ export const renderToStream: RenderToStreamWrapper<
3900
4083
  };
3901
4084
 
3902
4085
  export default serverRenderFactory<true>();
3903
- `,sn=`/* @jsxImportSource solid-js */
4086
+ `,ln=`/* @jsxImportSource solid-js */
3904
4087
 
3905
4088
  import styles from "./styles.module.css";
3906
4089
 
@@ -3941,7 +4124,7 @@ export default function PageSample(props: {
3941
4124
  </div>
3942
4125
  );
3943
4126
  }
3944
- `,cn=`/* @jsxImportSource solid-js */
4127
+ `,un=`/* @jsxImportSource solid-js */
3945
4128
 
3946
4129
  import styles from "./styles.module.css";
3947
4130
 
@@ -3993,7 +4176,7 @@ export default function PageSample(props: {
3993
4176
  </div>
3994
4177
  );
3995
4178
  }
3996
- `,ln=`* {
4179
+ `,dn=`* {
3997
4180
  margin: 0;
3998
4181
  padding: 0;
3999
4182
  box-sizing: border-box;
@@ -4128,7 +4311,7 @@ export default function PageSample(props: {
4128
4311
  align-items: center;
4129
4312
  gap: 0.25rem;
4130
4313
  }
4131
- `,un=`/* @jsxImportSource solid-js */
4314
+ `,fn=`/* @jsxImportSource solid-js */
4132
4315
 
4133
4316
  import styles from "./styles.module.css";
4134
4317
 
@@ -4194,7 +4377,7 @@ export default function WelcomePage() {
4194
4377
  </div>
4195
4378
  );
4196
4379
  }
4197
- `,dn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4380
+ `,pn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4198
4381
 
4199
4382
  let client: QueryClient | undefined;
4200
4383
 
@@ -4209,7 +4392,7 @@ export const getQueryClient = (): QueryClient => {
4209
4392
  }
4210
4393
  return client;
4211
4394
  };
4212
- `,fn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4395
+ `,mn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4213
4396
 
4214
4397
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
4215
4398
 
@@ -4232,7 +4415,7 @@ export const getQueryClient = (): QueryClient => {
4232
4415
  }
4233
4416
  return ctx.tsqClient as QueryClient;
4234
4417
  };
4235
- `,pn=`import type { JSX, ParentComponent } from "solid-js";
4418
+ `,hn=`import type { JSX, ParentComponent } from "solid-js";
4236
4419
  import { Router, type RouteDefinition } from "@solidjs/router";
4237
4420
  import type { RouterFactoryReturn } from "@kosmojs/core";
4238
4421
  import { createRouterFactory } from "@kosmojs/core/generators";
@@ -4257,7 +4440,7 @@ export const createRouters = (
4257
4440
 
4258
4441
  const serverRouter = (url: URL) => {
4259
4442
  const component = (
4260
- <Router root={app} base={base} url={url.pathname}>
4443
+ <Router root={app} base={base} url={url.pathname + url.search}>
4261
4444
  {routes}
4262
4445
  </Router>
4263
4446
  );
@@ -4268,30 +4451,25 @@ export const createRouters = (
4268
4451
  }
4269
4452
 
4270
4453
  export default createRouterFactory<RouteDefinition, JSX.Element>();
4271
- `,mn=`export type ComponentLoader = () => Promise<{
4454
+ `,gn=`export type ComponentLoader = () => Promise<{
4272
4455
  preload?: () => Promise<unknown>;
4273
4456
  }>;
4274
4457
 
4275
4458
  export const loaderFactory = (opt?: { withPreload?: boolean }) => {
4276
4459
  return (componentLoader: ComponentLoader) => {
4277
4460
  const preload = async () => {
4278
- try {
4279
- const component = await componentLoader();
4280
- return typeof component.preload === "function"
4281
- ? component.preload
4282
- : undefined;
4283
- } catch (error) {
4284
- console.error(error);
4285
- return;
4286
- }
4461
+ const component = await componentLoader();
4462
+ return typeof component.preload === "function"
4463
+ ? component.preload
4464
+ : undefined;
4287
4465
  };
4288
4466
  return opt?.withPreload ? { preload } : {};
4289
4467
  };
4290
4468
  };
4291
- `,hn=`export type MaybeWrapped<T> = import("solid-js/store").Store<T> | T;
4469
+ `,_n=`export type MaybeWrapped<T> = import("solid-js/store").Store<T> | T;
4292
4470
 
4293
4471
  export { unwrap } from "solid-js/store";
4294
- `,gn=`import type { ParentComponent } from "solid-js";
4472
+ `,vn=`import type { ParentComponent } from "solid-js";
4295
4473
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
4296
4474
 
4297
4475
  const App: ParentComponent = (props) => {
@@ -4299,7 +4477,7 @@ const App: ParentComponent = (props) => {
4299
4477
  };
4300
4478
 
4301
4479
  export default App;
4302
- `,_n=`import { A, type AnchorProps } from "@solidjs/router";
4480
+ `,yn=`import { A, type AnchorProps } from "@solidjs/router";
4303
4481
  import { type JSXElement, splitProps } from "solid-js";
4304
4482
 
4305
4483
  import { pageRouteMap, type LinkProps } from "{{ createImport 'libCore' }}";
@@ -4324,7 +4502,7 @@ export default function Link(
4324
4502
 
4325
4503
  return <A {...{ ...restProps, href: href() }}>{knownProps.children}</A>;
4326
4504
  }
4327
- `,vn=`import renderFactory, {
4505
+ `,bn=`import renderFactory, {
4328
4506
  createRoutes,
4329
4507
  hydrate,
4330
4508
  mount,
@@ -4351,7 +4529,7 @@ if (root) {
4351
4529
  } else {
4352
4530
  console.error("❌ Root element not found!");
4353
4531
  }
4354
- `,yn=`import renderFactory, {
4532
+ `,xn=`import renderFactory, {
4355
4533
  createRoutes,
4356
4534
  renderToStream,
4357
4535
  renderToString,
@@ -4378,7 +4556,7 @@ export default renderFactory(() => {
4378
4556
  },
4379
4557
  };
4380
4558
  });
4381
- `,bn=`<!doctype html>
4559
+ `,Sn=`<!doctype html>
4382
4560
  <html lang="en">
4383
4561
  <head>
4384
4562
  <meta charset="UTF-8" />
@@ -4390,19 +4568,19 @@ export default renderFactory(() => {
4390
4568
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
4391
4569
  </body>
4392
4570
  </html>
4393
- `,xn=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
4571
+ `,Cn=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
4394
4572
 
4395
4573
  export default function Page() {
4396
4574
  return <PageSample />;
4397
4575
  }
4398
- `,Sn=`import type { ParentComponent } from "solid-js";
4576
+ `,wn=`import type { ParentComponent } from "solid-js";
4399
4577
 
4400
4578
  const Layout: ParentComponent = (props) => {
4401
4579
  return props.children;
4402
4580
  };
4403
4581
 
4404
4582
  export default Layout;
4405
- `,Cn=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
4583
+ `,Tn=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
4406
4584
 
4407
4585
  export default function Page() {
4408
4586
  return PageSample({
@@ -4415,8 +4593,8 @@ export default function Page() {
4415
4593
  },
4416
4594
  });
4417
4595
  }
4418
- `,wn=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
4419
- `,Tn=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
4596
+ `,En=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
4597
+ `,Dn=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
4420
4598
 
4421
4599
  import app from "./app";
4422
4600
 
@@ -4431,16 +4609,19 @@ export default routerFactory((routes) => {
4431
4609
  },
4432
4610
  };
4433
4611
  });
4434
- `,En=f((e,t)=>{let{generators:n=[]}=e.config,{createPath:r,createImportHelpers:i}=h(e),{renderToFile:a}=_({helpers:{...i({origin:`lib`}),...b()},partials:{routePartial:an}}),{renderToFile:o}=_({helpers:i({origin:`src`})}),l=$t(),u=e=>!e?.trim().length,d=s(t?.templates,Cn),f=async e=>{for(let{kind:t,entry:n}of e)t===`pageRoute`?await o(r.pages(n.file),n.name===`index`?wn:d(n.name,n),{route:n,message:en()},{overwrite:u}):t===`pageLayout`&&await o(r.pages(n.file),Sn,{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`,rn],[`server.ts`,on]])await a(r.libEntry(e),t,{pageEntries:n,nestedRoutes:i});await a(r.lib(`router.tsx`),pn,{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`,mn],[`unwrap.ts`,hn],[`pageSamples/styles.module.css`,ln],[`pageSamples/welcome.tsx`,un],[`pageSamples/page.tsx`,cn],[`pageSamples/404.tsx`,sn],...t?.tanstack?.query?[[`app.tsx`,nn],[`query.ts`,dn]]:[[`app.tsx`,tn],[`query.ts`,`/** tanstack query disabled */`]]])await a(r.lib(e),n,{});for(let[e,t]of[[`pages/404.tsx`,xn],[`components/Link.tsx`,_n],[`app.tsx`,gn],[`router.ts`,Tn]])await o(r.src(e),t,{entryDir:c.entryDir},{overwrite:u});await o(r.src(`index.html`),bn,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,vn],[`server.ts`,yn]])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?fn:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),Dn=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:En}),On=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 kn(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`)}}}}),kn=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}},An=d({meta:{name:`SSG`,slot:`ssg`},factory:On}),q={type:`module`,private:!0,name:`@kosmojs/ssr-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,vite:`^8.2.0`},devDependencies:{"@hono/node-server":`^2.1.0`,hono:`^4.13.0`,"light-my-request":`^6.6.0`,tinyglobby:`^0.2.17`}},jn=`{{#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}}
4435
4613
  export { default as apiApp } from "{{ createImport 'api' 'app' }}";
4436
4614
  {{else}}
4437
4615
  export const apiApp = undefined;
4438
4616
  {{/if}}
4439
- `,Mn=`import { AsyncLocalStorage } from "node:async_hooks";
4617
+ `,Pn=`import { AsyncLocalStorage } from "node:async_hooks";
4618
+
4619
+ import type { FetchApp, NodeApp } from "@kosmojs/core";
4440
4620
 
4441
4621
  export type RequestContext = {
4442
4622
  headers?: HeadersInit;
4443
4623
  tsqClient?: unknown;
4624
+ error?: unknown;
4444
4625
  };
4445
4626
 
4446
4627
  export const redirectCodes = [
@@ -4473,7 +4654,11 @@ export const maxRedirects = 5;
4473
4654
  * Server-only module - never reaches browser bundles.
4474
4655
  * */
4475
4656
  export const store = new AsyncLocalStorage<RequestContext>();
4476
- `,Nn=`import { type RequestContext, store } from "./base";
4657
+
4658
+ export const isFetchApp = (app: FetchApp | NodeApp): app is FetchApp => {
4659
+ return typeof (app as FetchApp).fetch === "function";
4660
+ };
4661
+ `,Fn=`import { type RequestContext, store } from "./base";
4477
4662
 
4478
4663
  import { renderWrapper } from "{{ createImport 'libEntry' 'server' }}";
4479
4664
 
@@ -4491,12 +4676,22 @@ export const withSsrContext = <T>(
4491
4676
  ): T => {
4492
4677
  return store.run(context, () => renderWrapper(context, render));
4493
4678
  };
4494
- `,Pn=`import { inject } from "light-my-request";
4495
4679
 
4496
- import { type FetchApp, isFetchApp, type NodeApp } from "@kosmojs/core";
4680
+ export const errorProvider = () => {
4681
+ return store.getStore()?.error;
4682
+ };
4683
+ `,In=`import { inject } from "light-my-request";
4684
+
4685
+ import type { FetchApp, NodeApp } from "@kosmojs/core";
4497
4686
  import type { Transport } from "@kosmojs/core/fetch";
4498
4687
 
4499
- import { maxRedirects, redirectCodes, ssrOrigin, store } from "./base";
4688
+ import {
4689
+ isFetchApp,
4690
+ maxRedirects,
4691
+ redirectCodes,
4692
+ ssrOrigin,
4693
+ store,
4694
+ } from "./base";
4500
4695
 
4501
4696
  import { apiApp } from "{{ createImport 'lib' '@ssr/api' }}";
4502
4697
 
@@ -4507,16 +4702,61 @@ const headersProvider = (): HeadersInit | undefined => {
4507
4702
  return store.getStore()?.headers;
4508
4703
  };
4509
4704
 
4510
- /**
4511
- * Builds a fetch-compatible transport that dispatches requests
4512
- * directly into the given app - no sockets, no interception.
4513
- * Redirects are followed in-process, including the 303 and 301/302 method rewrite to GET.
4514
- * */
4515
- const createTransport = (app: FetchApp | NodeApp): Transport => {
4516
- const dispatch = isFetchApp(app) //
4705
+ const createDispatch = (app: FetchApp | NodeApp) => {
4706
+ return isFetchApp(app)
4517
4707
  ? app.fetch
4518
- : 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();
4519
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);
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
+ * */
4520
4760
  return async (input, init) => {
4521
4761
  /**
4522
4762
  * Request-scoped headers act as defaults: anything set explicitly
@@ -4584,58 +4824,71 @@ const createTransport = (app: FetchApp | NodeApp): Transport => {
4584
4824
  };
4585
4825
  };
4586
4826
 
4587
- /**
4588
- * Node dispatch: serializes the web Request into light-my-request's
4589
- * injection format and lifts the injected response back into a web Response.
4590
- * */
4591
- const createNodeDispatch = (app: NodeApp) => {
4592
- return async (request: Request): Promise<Response> => {
4593
- const url = new URL(request.url);
4827
+ const ssrTransport = apiApp ? createTransport(apiApp) : undefined;
4594
4828
 
4595
- const payload = ["GET", "HEAD"].includes(request.method)
4596
- ? undefined
4597
- : Buffer.from(await request.arrayBuffer());
4598
-
4599
- const result = await inject(app.callback() as never, {
4600
- method: request.method as never,
4601
- url: url.pathname + url.search,
4602
- headers: Object.fromEntries(request.headers),
4603
- ...(payload?.length ? { payload } : {}),
4604
- });
4605
-
4606
- const headers = new Headers();
4607
-
4608
- for (const [key, value] of Object.entries(result.headers)) {
4609
- for (const entry of Array.isArray(value) ? value : [value]) {
4610
- if (entry !== undefined) {
4611
- 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;
4612
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;
4853
+ }
4854
+ throw error;
4613
4855
  }
4614
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
+ }
4615
4871
 
4616
- /**
4617
- * 204/304 responses must not carry a body per the Response
4618
- * constructor contract.
4619
- * */
4620
- const body = [204, 304].includes(result.statusCode)
4621
- ? null
4622
- : new Uint8Array(result.rawPayload);
4623
-
4624
- return new Response(body, {
4625
- status: result.statusCode,
4626
- statusText: result.statusMessage,
4627
- headers,
4628
- });
4629
- };
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);
4630
4885
  };
4631
-
4632
- export const transport = apiApp ? createTransport(apiApp) : globalThis.fetch;
4633
- `,Fn=`export const routeMap = [
4886
+ `,Ln=`export const routeMap = [
4634
4887
  {{#each pageRoutes}}
4635
4888
  { pathPattern: "{{honoPattern}}", renderMode: "{{renderMode}}" },
4636
4889
  {{/each}}
4637
4890
  ];
4638
- `,In=`import { access, chmod, constants, readFile, unlink } from "node:fs/promises";
4891
+ `,Rn=`import { access, chmod, constants, readFile, unlink } from "node:fs/promises";
4639
4892
  import {
4640
4893
  createServer,
4641
4894
  type IncomingMessage,
@@ -4651,14 +4904,9 @@ import { HTTPException } from "hono/http-exception";
4651
4904
  import { stream } from "hono/streaming";
4652
4905
  import { glob } from "tinyglobby";
4653
4906
 
4654
- import {
4655
- type FetchApp,
4656
- isFetchApp,
4657
- type NodeApp,
4658
- type SSRSetup,
4659
- } from "@kosmojs/core";
4907
+ import type { FetchApp, NodeApp, SSRSetup } from "@kosmojs/core";
4660
4908
 
4661
- import { redirectCodes, ssrOrigin } from "./@ssr/base";
4909
+ import { isFetchApp, redirectCodes, ssrOrigin } from "./@ssr/base";
4662
4910
 
4663
4911
  import { routeMap } from "{{ createImport 'lib' '@ssr/routes' }}";
4664
4912
  import { apiBase, base } from "{{ createImport 'libCore' }}";
@@ -4680,12 +4928,14 @@ export const createApp = async () => {
4680
4928
  const {
4681
4929
  ssrApp,
4682
4930
  withSsrContext,
4931
+ errorProvider,
4683
4932
  }: {
4684
4933
  ssrApp: SSRSetup;
4685
4934
  withSsrContext: <T>(
4686
4935
  context: { headers?: Record<string, string>; url?: string },
4687
4936
  render: () => T,
4688
4937
  ) => Promise<T>;
4938
+ errorProvider: () => Error | undefined;
4689
4939
  } = await import(\`\${ROOT}/app.js\`);
4690
4940
 
4691
4941
  // Read the client index.html that includes <!--app-head--> and <!--app-html-->
@@ -4745,13 +4995,47 @@ export const createApp = async () => {
4745
4995
  };
4746
4996
 
4747
4997
  const renderPage = async (url: URL, ctx: Context) => {
4748
- const { head = "", html } = await withSsrContext(
4998
+ const {
4999
+ head = "",
5000
+ html,
5001
+ error,
5002
+ } = await withSsrContext(
4749
5003
  {
4750
5004
  headers: Object.fromEntries(ctx.req.raw.headers),
4751
5005
  url: ctx.req.url,
4752
5006
  },
4753
- () => 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
+ },
4754
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
+
4755
5039
  return [
4756
5040
  htmlStart.replace("<!--app-head-->", head),
4757
5041
  html ?? "",
@@ -5020,14 +5304,14 @@ if (isMain) {
5020
5304
  process.exit(1);
5021
5305
  }
5022
5306
  }
5023
- `,Ln=`string`,Rn=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`):()=>Ln,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`,In],[`@ssr/api.ts`,jn],[`@ssr/__kosmo_ssr_bundle.ts`,Nn],[`@ssr/base.ts`,Mn],[`@ssr/fetch.ts`,Pn],[`@ssr/routes.ts`,Fn]])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})}}}),zn=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:Rn}),J={type:`module`,private:!0,name:`@kosmojs/svelte-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,"@sveltejs/vite-plugin-svelte":`^7.2.0`,vite:`^8.2.0`},devDependencies:{"@tanstack/svelte-query":`^6.1.38`,"path-to-regexp":`^8.4.2`,svelte:`^5.56.8`}},Bn=()=>{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">
5024
5308
  import type { Snippet } from "svelte";
5025
5309
 
5026
5310
  let { children }: { children: Snippet } = $props();
5027
5311
  <\/script>
5028
5312
 
5029
5313
  {@render children()}
5030
- `,Vn=`<script lang="ts">
5314
+ `,Un=`<script lang="ts">
5031
5315
  import { type QueryClient, QueryClientProvider } from "@tanstack/svelte-query";
5032
5316
  import type { Snippet } from "svelte";
5033
5317
 
@@ -5044,7 +5328,7 @@ if (isMain) {
5044
5328
  <QueryClientProvider client={queryClient}>
5045
5329
  {@render children()}
5046
5330
  </QueryClientProvider>
5047
- `,Hn=`import { hydrate as hydrateOrig, mount as mountOrig } from "svelte";
5331
+ `,Wn=`import { hydrate as hydrateOrig, mount as mountOrig } from "svelte";
5048
5332
  import type { RouterFactoryReturn } from "@kosmojs/core";
5049
5333
  import { clientRenderFactory } from "@kosmojs/core/generators";
5050
5334
 
@@ -5085,7 +5369,7 @@ export const mount = async (
5085
5369
  }
5086
5370
 
5087
5371
  export default clientRenderFactory();
5088
- `,Un=`import { render as renderOrig } from "svelte/server";
5372
+ `,Gn=`import { render as renderOrig } from "svelte/server";
5089
5373
 
5090
5374
  import type {
5091
5375
  RenderToStringWrapper,
@@ -5151,12 +5435,12 @@ export const renderToString: RenderToStringWrapper<
5151
5435
  // svelte/server exposes only render() - no web-stream renderer -
5152
5436
  // so this folder is string-only SSR.
5153
5437
  export default serverRenderFactory<false>();
5154
- `,Wn=`declare module "*.svelte" {
5438
+ `,Kn=`declare module "*.svelte" {
5155
5439
  import type { Component } from "svelte";
5156
5440
  const component: Component;
5157
5441
  export default component;
5158
5442
  }
5159
- `,Gn=`<script lang="ts">
5443
+ `,qn=`<script lang="ts">
5160
5444
  /**
5161
5445
  * Folds [app, ...layouts] around the page component.
5162
5446
  *
@@ -5190,7 +5474,7 @@ export default serverRenderFactory<false>();
5190
5474
  {/snippet}
5191
5475
 
5192
5476
  {@render layer(0)}
5193
- `,Kn=`<script lang="ts">
5477
+ `,Jn=`<script lang="ts">
5194
5478
  import styles from "./styles.module.css";
5195
5479
 
5196
5480
  let { headline }: { headline?: string } = $props();
@@ -5222,7 +5506,7 @@ export default serverRenderFactory<false>();
5222
5506
  </div>
5223
5507
  </div>
5224
5508
  </div>
5225
- `,qn=`<script lang="ts">
5509
+ `,Yn=`<script lang="ts">
5226
5510
  import styles from "./styles.module.css";
5227
5511
 
5228
5512
  let {
@@ -5267,7 +5551,7 @@ export default serverRenderFactory<false>();
5267
5551
  </div>
5268
5552
  </div>
5269
5553
  </div>
5270
- `,Jn=`* {
5554
+ `,Xn=`* {
5271
5555
  margin: 0;
5272
5556
  padding: 0;
5273
5557
  box-sizing: border-box;
@@ -5402,7 +5686,7 @@ export default serverRenderFactory<false>();
5402
5686
  align-items: center;
5403
5687
  gap: 0.25rem;
5404
5688
  }
5405
- `,Yn=`<script lang="ts">
5689
+ `,Zn=`<script lang="ts">
5406
5690
  import styles from "./styles.module.css";
5407
5691
  <\/script>
5408
5692
 
@@ -5460,7 +5744,7 @@ export default serverRenderFactory<false>();
5460
5744
  </div>
5461
5745
  </div>
5462
5746
  </div>
5463
- `,Xn=`export type ParamsMap = {
5747
+ `,Qn=`export type ParamsMap = {
5464
5748
  {{#each pageRoutes}}"{{name}}": {{serializeParamsLiteral .}};
5465
5749
  {{/each}}
5466
5750
  };
@@ -5469,7 +5753,7 @@ export const paramNames = {
5469
5753
  {{#each pageRoutes}}"{{name}}": [ {{#each params.schema}}"{{name}}", {{/each}}],
5470
5754
  {{/each}}
5471
5755
  } as const;
5472
- `,Zn=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5756
+ `,$n=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5473
5757
 
5474
5758
  let client: QueryClient | undefined;
5475
5759
 
@@ -5484,7 +5768,7 @@ export const getQueryClient = (): QueryClient => {
5484
5768
  }
5485
5769
  return client;
5486
5770
  };
5487
- `,Qn=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5771
+ `,er=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5488
5772
 
5489
5773
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
5490
5774
 
@@ -5507,7 +5791,7 @@ export const getQueryClient = (): QueryClient => {
5507
5791
  }
5508
5792
  return ctx.tsqClient as QueryClient;
5509
5793
  };
5510
- `,$n=`import type { RouterFactoryReturn } from "@kosmojs/core";
5794
+ `,tr=`import type { RouterFactoryReturn } from "@kosmojs/core";
5511
5795
  import { createRouterFactory } from "@kosmojs/core/generators";
5512
5796
 
5513
5797
  import Layouts from "./Layouts.svelte";
@@ -5547,9 +5831,11 @@ export default createRouterFactory<
5547
5831
  Promise<RouteComponent>,
5548
5832
  { server: { route: Route } }
5549
5833
  >();
5550
- `,er=`import { match, pathToRegexp } from "path-to-regexp";
5834
+ `,nr=`import { match, pathToRegexp } from "path-to-regexp";
5551
5835
  import { type Component, createContext } from "svelte";
5552
5836
 
5837
+ import { parseSearchParams } from "@kosmojs/core";
5838
+
5553
5839
  import { paramNames } from "{{ createImport 'lib' 'params' }}";
5554
5840
  import { base } from "{{ createImport 'libCore' }}";
5555
5841
 
@@ -5573,7 +5859,7 @@ export type RawRoute = {
5573
5859
  };
5574
5860
 
5575
5861
  type Loader = (
5576
- route: Pick<Route, "name" | "params" | "paramsEntries">,
5862
+ route: Pick<Route, "name" | "params" | "paramsEntries" | "searchParams">,
5577
5863
  ) => Promise<unknown> | undefined;
5578
5864
 
5579
5865
  /**
@@ -5615,6 +5901,7 @@ export type Route = {
5615
5901
  name: string;
5616
5902
  params: Record<string, string | Array<string>>;
5617
5903
  paramsEntries: [keys: Array<string>, values: Array<unknown>];
5904
+ searchParams: Record<string, unknown>;
5618
5905
  loaderData: Record<string, unknown>;
5619
5906
  };
5620
5907
 
@@ -5654,6 +5941,7 @@ export const createRouter = (
5654
5941
 
5655
5942
  return {
5656
5943
  async resolve(url: URL = new URL(window.location.href)) {
5944
+ const searchParams = parseSearchParams(url);
5657
5945
  const urlSegments = url.pathname.split("/").filter(Boolean).length;
5658
5946
 
5659
5947
  // 1: use lightweight \`RegExp.test()\` on linear scan - no capture allocation
@@ -5696,7 +5984,7 @@ export const createRouter = (
5696
5984
 
5697
5985
  loaderData[name] = await runLoader(name, () => {
5698
5986
  return routeModule.loader
5699
- ? routeModule.loader({ name, params, paramsEntries })
5987
+ ? routeModule.loader({ name, params, paramsEntries, searchParams })
5700
5988
  : undefined; // should not survive serialization if no loader defined
5701
5989
  });
5702
5990
 
@@ -5708,7 +5996,12 @@ export const createRouter = (
5708
5996
  const key = \`\${layoutName}/layout\`;
5709
5997
  loaderData[key] = await runLoader(key, () => {
5710
5998
  return layoutModule.loader
5711
- ? layoutModule.loader({ name: layoutName, params, paramsEntries })
5999
+ ? layoutModule.loader({
6000
+ name: layoutName,
6001
+ params,
6002
+ paramsEntries,
6003
+ searchParams,
6004
+ })
5712
6005
  : undefined; // should not survive serialization if no loader defined
5713
6006
  });
5714
6007
  }
@@ -5717,6 +6010,7 @@ export const createRouter = (
5717
6010
  name,
5718
6011
  params,
5719
6012
  paramsEntries,
6013
+ searchParams,
5720
6014
  loaderData,
5721
6015
  };
5722
6016
 
@@ -5758,7 +6052,7 @@ export const createRoute = (
5758
6052
  layouts,
5759
6053
  };
5760
6054
  };
5761
- `,tr=`import { getRouteContext } from "./svelte";
6055
+ `,rr=`import { getRouteContext } from "./svelte";
5762
6056
 
5763
6057
  import type { ParamsMap, paramNames } from "{{ createImport 'lib' 'params' }}";
5764
6058
 
@@ -5784,6 +6078,10 @@ export function useParamsEntries<T extends keyof ParamsMap>(): [
5784
6078
  return useRoute().paramsEntries as never;
5785
6079
  }
5786
6080
 
6081
+ export function useSearchParams() {
6082
+ return useRoute().searchParams;
6083
+ }
6084
+
5787
6085
  /**
5788
6086
  * Reads loader data for the current page or one of its layouts.
5789
6087
  * Without a key, returns the page's own data.
@@ -5794,7 +6092,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
5794
6092
  const route = useRoute();
5795
6093
  return route.loaderData?.[key || route.name] as T;
5796
6094
  };
5797
- `,nr=`<script lang="ts">
6095
+ `,ir=`<script lang="ts">
5798
6096
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
5799
6097
  import type { Snippet } from "svelte";
5800
6098
 
@@ -5804,7 +6102,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
5804
6102
  <AppProvider>
5805
6103
  {@render children()}
5806
6104
  </AppProvider>
5807
- `,rr=`<script lang="ts">
6105
+ `,ar=`<script lang="ts">
5808
6106
  import type { Snippet } from "svelte";
5809
6107
  import type { HTMLAnchorAttributes } from "svelte/elements";
5810
6108
 
@@ -5828,7 +6126,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
5828
6126
  <\/script>
5829
6127
 
5830
6128
  <a {href} {...rest}>{@render children?.()}</a>
5831
- `,ir=`import renderFactory, {
6129
+ `,or=`import renderFactory, {
5832
6130
  createRoutes,
5833
6131
  hydrate,
5834
6132
  mount,
@@ -5855,7 +6153,7 @@ if (root) {
5855
6153
  } else {
5856
6154
  console.error("❌ Root element not found!");
5857
6155
  }
5858
- `,ar=`import renderFactory, {
6156
+ `,sr=`import renderFactory, {
5859
6157
  createRoutes,
5860
6158
  renderToString,
5861
6159
  // no renderToStream on Svelte folders
@@ -5876,7 +6174,7 @@ export default renderFactory(() => {
5876
6174
  },
5877
6175
  };
5878
6176
  });
5879
- `,or=`<!doctype html>
6177
+ `,cr=`<!doctype html>
5880
6178
  <html lang="en">
5881
6179
  <head>
5882
6180
  <meta charset="UTF-8" />
@@ -5888,19 +6186,19 @@ export default renderFactory(() => {
5888
6186
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
5889
6187
  </body>
5890
6188
  </html>
5891
- `,sr=`<script lang="ts">
6189
+ `,lr=`<script lang="ts">
5892
6190
  import PageSample from "{{ createImport 'lib' 'pageSamples/404.svelte' }}";
5893
6191
  <\/script>
5894
6192
 
5895
6193
  <PageSample />
5896
- `,cr=`<script lang="ts">
6194
+ `,ur=`<script lang="ts">
5897
6195
  import type { Snippet } from "svelte";
5898
6196
 
5899
6197
  let { children }: { children: Snippet } = $props();
5900
6198
  <\/script>
5901
6199
 
5902
6200
  {@render children()}
5903
- `,lr=`<script lang="ts">
6201
+ `,dr=`<script lang="ts">
5904
6202
  import PageSample from "{{ createImport 'lib' 'pageSamples/page.svelte' }}";
5905
6203
 
5906
6204
  const pathMap = {
@@ -5919,7 +6217,7 @@ export default renderFactory(() => {
5919
6217
  routeName={"{{route.name}}"}
5920
6218
  {pathMap}
5921
6219
  />
5922
- `,ur=`<script lang="ts">
6220
+ `,fr=`<script lang="ts">
5923
6221
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.svelte' }}";
5924
6222
  <\/script>
5925
6223
 
@@ -5932,7 +6230,7 @@ export default renderFactory(() => {
5932
6230
  </svelte:head>
5933
6231
 
5934
6232
  <WelcomePage />
5935
- `,dr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
6233
+ `,pr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
5936
6234
 
5937
6235
  import app from "./app.svelte";
5938
6236
 
@@ -5947,7 +6245,7 @@ export default routerFactory((routes) => {
5947
6245
  },
5948
6246
  };
5949
6247
  });
5950
- `,fr=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,lr),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?ur:l(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:Bn()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),cr,{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`,Hn],[`server.ts`,Un]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,Xn],[`router.ts`,$n]])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`,Wn],[`svelte.ts`,er],[`Layouts.svelte`,Gn],[`use.ts`,tr],[`pageSamples/styles.module.css`,Jn],[`pageSamples/welcome.svelte`,Yn],[`pageSamples/page.svelte`,qn],[`pageSamples/404.svelte`,Kn],...t?.tanstack?.query?[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,Vn],[`app/index.ts`,`export { default as AppProvider } from "./app-tsq.svelte";`],[`query.ts`,Zn]]:[[`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`,sr],[`components/Link.svelte`,rr],[`app.svelte`,nr],[`router.ts`,dr]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:o});await a(n.src(`index.html`),or,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,ir],[`server.ts`,ar]])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?Qn:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),pr=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:fr}),mr={type:`module`,private:!0,name:`@kosmojs/typebox-generator`,version:`0.2.9`,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.10`}},hr=`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";
5951
6249
 
5952
6250
  /**
5953
6251
  * Custom types for JavaScript constructs that have no JSON Schema
@@ -6019,7 +6317,7 @@ export default {
6019
6317
  Buffer: TBuffer(),
6020
6318
  ArrayBuffer: TArrayBuffer(),
6021
6319
  };
6022
- `,gr=`import type { TValidationError } from "typebox/error";
6320
+ `,vr=`import type { TValidationError } from "typebox/error";
6023
6321
 
6024
6322
  import type { ValidationErrorEntry } from "@kosmojs/core";
6025
6323
 
@@ -7203,7 +7501,7 @@ const format = (fmt: string, ...args: unknown[]): string => {
7203
7501
 
7204
7502
  return str;
7205
7503
  };
7206
- `,_r=`import Type from "typebox";
7504
+ `,yr=`import Type from "typebox";
7207
7505
  import { Compile } from "typebox/compile";
7208
7506
  import Value from "typebox/value";
7209
7507
 
@@ -7255,14 +7553,14 @@ export const validationSchemaFactory = (
7255
7553
  },
7256
7554
  };
7257
7555
  };
7258
- `,vr=`import { Settings } from "typebox/system";
7556
+ `,br=`import { Settings } from "typebox/system";
7259
7557
 
7260
7558
  Settings.Set({{settings}});
7261
7559
 
7262
7560
  export { default as customTypes } from "{{customTypesImport}}";
7263
7561
 
7264
7562
  export const validationMessages = {{validationMessages}};
7265
- `,yr=`import type { ValidationSchemas } from "@kosmojs/core";
7563
+ `,xr=`import type { ValidationSchemas } from "@kosmojs/core";
7266
7564
 
7267
7565
  import { validationSchemaFactory } from "{{ createImport 'lib' '@typebox' }}";
7268
7566
 
@@ -7323,14 +7621,14 @@ export const validationSchemas: ValidationSchemas = {
7323
7621
  {{/each}}
7324
7622
  },
7325
7623
  };
7326
- `,br={exactOptionalPropertyTypes:!0},xr=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`),yr,{route:r,resolvedTypes:e,requestSchemas:i,responseSchemas:s})}};return{async start(){for(let[e,t]of[[`custom-types.ts`,hr],[`error-handler.ts`,gr],[`index.ts`,_r],[`setup.ts`,vr]])await o(n.lib(`@typebox`,e),t,{validationMessages:JSON.stringify(s),customTypesImport:c,settings:JSON.stringify({...br,...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 Sr=d({meta:{name:`TypeBox`,resolveTypes:!0},dependencies:{typebox:mr.devDependencies.typebox},factory:xr}),Z={type:`module`,private:!0,name:`@kosmojs/vue-generator`,version:`0.2.9`,author:`Slee Woo`,license:`MIT`,files:[`pkg/*`],exports:{".":{types:`./pkg/index.d.ts`,default:`./pkg/index.js`}},scripts:{build:`wsbuild src/index.ts`,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(`/`)},Cr=()=>{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},wr=()=>{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)]},Tr=`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";
7327
7625
 
7328
7626
  export { default as AppProvider } from "./provider.vue";
7329
7627
 
7330
7628
  export const appProvider: Plugin = {
7331
7629
  install() {},
7332
7630
  };
7333
- `,Er=`import { VueQueryPlugin } from "@tanstack/vue-query";
7631
+ `,Or=`import { VueQueryPlugin } from "@tanstack/vue-query";
7334
7632
  import type { Plugin } from "vue";
7335
7633
 
7336
7634
  import { getQueryClient } from "../query";
@@ -7342,10 +7640,10 @@ export const appProvider: Plugin = {
7342
7640
  app.use(VueQueryPlugin, { queryClient: getQueryClient() });
7343
7641
  },
7344
7642
  };
7345
- `,Dr=`<template>
7643
+ `,kr=`<template>
7346
7644
  <slot />
7347
7645
  </template>
7348
- `,Or=`import type { App } from "vue";
7646
+ `,Ar=`import type { App } from "vue";
7349
7647
  import type { RouterFactoryReturn } from "@kosmojs/core";
7350
7648
  import { clientRenderFactory } from "@kosmojs/core/generators";
7351
7649
 
@@ -7385,7 +7683,7 @@ export const mount = async (
7385
7683
  }
7386
7684
 
7387
7685
  export default clientRenderFactory();
7388
- `,kr=`{
7686
+ `,jr=`{
7389
7687
  path: "{{path}}",
7390
7688
  {{#if name}}
7391
7689
  name: "{{name}}",
@@ -7403,7 +7701,7 @@ export default clientRenderFactory();
7403
7701
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
7404
7702
  {{/if}}
7405
7703
  }
7406
- `,Ar=`import type { App } from "vue";
7704
+ `,Mr=`import type { App } from "vue";
7407
7705
 
7408
7706
  import {
7409
7707
  renderToString as renderToStringOrig,
@@ -7479,31 +7777,27 @@ export const renderToStream: RenderToStreamWrapper<
7479
7777
  Parameters<typeof renderToWebStream>[1]
7480
7778
  > = async (resolver, { headerTags = [], context = {} } = {}) => {
7481
7779
  const { component, loaderData } = await resolver();
7482
- const source = renderToWebStream(component, context);
7483
-
7484
- const appendScript = new TransformStream<Uint8Array, Uint8Array>({
7485
- flush(controller) {
7486
- // runs once, after \`source\` has fully flushed and closed
7487
- const script = createHydrationScript(loaderData);
7488
- if (script) {
7489
- controller.enqueue(new TextEncoder().encode(script));
7490
- }
7491
- },
7492
- });
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);
7493
7787
 
7494
7788
  return {
7495
- head: [...headerTags].join("\\n"),
7496
- html: source.pipeThrough(appendScript),
7789
+ head: [...headerTags, ...script ? [script] : []].join("\\n"),
7790
+ html: renderToWebStream(component, context),
7497
7791
  };
7498
7792
  }
7499
7793
 
7500
7794
  export default serverRenderFactory();
7501
- `,jr=`declare module "*.vue" {
7795
+ `,$=`declare module "*.vue" {
7502
7796
  import type { DefineComponent } from "vue";
7503
7797
  const component: DefineComponent<{}, {}, any>;
7504
7798
  export default component;
7505
7799
  }
7506
- `,Mr=`<script setup lang="ts">
7800
+ `,Nr=`<script setup lang="ts">
7507
7801
  import styles from "./styles.module.css";
7508
7802
  defineProps<{
7509
7803
  headline?: string;
@@ -7542,7 +7836,7 @@ defineProps<{
7542
7836
  </div>
7543
7837
  </div>
7544
7838
  </template>
7545
- `,$=`<script setup lang="ts">
7839
+ `,Pr=`<script setup lang="ts">
7546
7840
  import styles from "./styles.module.css";
7547
7841
  defineProps<{
7548
7842
  message: string;
@@ -7591,7 +7885,7 @@ defineProps<{
7591
7885
  </div>
7592
7886
  </div>
7593
7887
  </template>
7594
- `,Nr=`* {
7888
+ `,Fr=`* {
7595
7889
  margin: 0;
7596
7890
  padding: 0;
7597
7891
  box-sizing: border-box;
@@ -7724,7 +8018,7 @@ defineProps<{
7724
8018
  align-items: center;
7725
8019
  gap: 0.25rem;
7726
8020
  }
7727
- `,Pr=`<script setup lang="ts">
8021
+ `,Ir=`<script setup lang="ts">
7728
8022
  import styles from "./styles.module.css";
7729
8023
  <\/script>
7730
8024
 
@@ -7788,7 +8082,7 @@ import styles from "./styles.module.css";
7788
8082
  </div>
7789
8083
  </div>
7790
8084
  </template>
7791
- `,Fr=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8085
+ `,Lr=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
7792
8086
 
7793
8087
  let client: QueryClient | undefined;
7794
8088
 
@@ -7803,7 +8097,7 @@ export const getQueryClient = (): QueryClient => {
7803
8097
  }
7804
8098
  return client;
7805
8099
  };
7806
- `,Ir=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8100
+ `,Rr=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
7807
8101
 
7808
8102
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
7809
8103
 
@@ -7826,7 +8120,7 @@ export const getQueryClient = (): QueryClient => {
7826
8120
  }
7827
8121
  return ctx.tsqClient as QueryClient;
7828
8122
  };
7829
- `,Lr=`import {
8123
+ `,zr=`import {
7830
8124
  type App,
7831
8125
  type Component,
7832
8126
  createApp,
@@ -7955,7 +8249,7 @@ export const createRouters = (
7955
8249
  // would otherwise skip the guard
7956
8250
  installLoaderGuard(router);
7957
8251
 
7958
- await router.push(url.pathname.replace(base, ""));
8252
+ await router.push(url.pathname + url.search);
7959
8253
 
7960
8254
  await router.isReady();
7961
8255
 
@@ -7977,14 +8271,14 @@ export default createRouterFactory<
7977
8271
  Promise<App>,
7978
8272
  { server: { loaderData: Record<string, unknown> } }
7979
8273
  >();
7980
- `,Rr=`import { type Ref, unref } from "vue";
8274
+ `,Br=`import { type Ref, unref } from "vue";
7981
8275
 
7982
8276
  export type MaybeWrapped<T> = Ref<T> | T;
7983
8277
 
7984
8278
  export function unwrap<T>(value: MaybeWrapped<T>): T {
7985
8279
  return unref(value);
7986
8280
  }
7987
- `,zr=`import { useRoute, useRouter } from "vue-router";
8281
+ `,Vr=`import { useRoute, useRouter } from "vue-router";
7988
8282
 
7989
8283
  import type { RouterWithLoaderData } from "./router";
7990
8284
 
@@ -7999,7 +8293,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
7999
8293
  const route = useRoute();
8000
8294
  return router.__loaderData?.[key || (route.name as string)] as T;
8001
8295
  };
8002
- `,Br=`<script setup lang="ts">
8296
+ `,Hr=`<script setup lang="ts">
8003
8297
  import { AppProvider } from "_/app";
8004
8298
  <\/script>
8005
8299
 
@@ -8008,7 +8302,7 @@ import { AppProvider } from "_/app";
8008
8302
  <RouterView />
8009
8303
  </AppProvider>
8010
8304
  </template>
8011
- `,Vr=`<script setup lang="ts" generic="T extends LinkProps">
8305
+ `,Ur=`<script setup lang="ts" generic="T extends LinkProps">
8012
8306
  import { computed } from "vue";
8013
8307
  import { RouterLink } from "vue-router";
8014
8308
 
@@ -8040,7 +8334,7 @@ const href = computed(() => {
8040
8334
  <slot />
8041
8335
  </RouterLink>
8042
8336
  </template>
8043
- `,Hr=`import renderFactory, {
8337
+ `,Wr=`import renderFactory, {
8044
8338
  createRoutes,
8045
8339
  hydrate,
8046
8340
  mount,
@@ -8067,7 +8361,7 @@ if (root) {
8067
8361
  } else {
8068
8362
  console.error("❌ Root element not found!");
8069
8363
  }
8070
- `,Ur=`import renderFactory, {
8364
+ `,Gr=`import renderFactory, {
8071
8365
  createRoutes,
8072
8366
  renderToStream,
8073
8367
  renderToString,
@@ -8094,7 +8388,7 @@ export default renderFactory(() => {
8094
8388
  },
8095
8389
  };
8096
8390
  });
8097
- `,Wr=`<!doctype html>
8391
+ `,Kr=`<!doctype html>
8098
8392
  <html lang="en">
8099
8393
  <head>
8100
8394
  <meta charset="UTF-8" />
@@ -8106,17 +8400,17 @@ export default renderFactory(() => {
8106
8400
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
8107
8401
  </body>
8108
8402
  </html>
8109
- `,Gr=`<script setup lang="ts">
8403
+ `,qr=`<script setup lang="ts">
8110
8404
  import PageSample from "{{ createImport 'lib' 'pageSamples/404.vue' }}";
8111
8405
  <\/script>
8112
8406
 
8113
8407
  <template>
8114
8408
  <PageSample />
8115
8409
  </template>
8116
- `,Kr=`<template>
8410
+ `,Jr=`<template>
8117
8411
  <router-view />
8118
8412
  </template>
8119
- `,qr=`<script setup lang="ts">
8413
+ `,Yr=`<script setup lang="ts">
8120
8414
  import PageSample from "{{ createImport 'lib' 'pageSamples/page.vue' }}";
8121
8415
  <\/script>
8122
8416
 
@@ -8131,14 +8425,14 @@ import PageSample from "{{ createImport 'lib' 'pageSamples/page.vue' }}";
8131
8425
  }"
8132
8426
  />
8133
8427
  </template>
8134
- `,Jr=`<script setup lang="ts">
8428
+ `,Xr=`<script setup lang="ts">
8135
8429
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.vue' }}";
8136
8430
  <\/script>
8137
8431
 
8138
8432
  <template>
8139
8433
  <WelcomePage />
8140
8434
  </template>
8141
- `,Yr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
8435
+ `,Zr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
8142
8436
  import { appProvider } from "{{ createImport 'lib' 'app' }}";
8143
8437
 
8144
8438
  import app from "./app.vue";
@@ -8157,5 +8451,5 @@ export default routerFactory((routes) => {
8157
8451
  },
8158
8452
  };
8159
8453
  });
8160
- `,Xr=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()},partials:{routePartial:kr}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=Cr(),l=e=>!e?.trim().length,u=s(t?.templates,qr),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Jr:u(r.name,r),{route:r,message:wr()},{overwrite:l}):t===`pageLayout`&&await a(n.pages(r.file),Kr,{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`,Or],[`server.ts`,Ar]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a,lazyLoad:e===`client.ts`});await i(n.lib(`router.ts`),Lr,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[fe(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,jr],[`unwrap.ts`,Rr],[`use.ts`,zr],[`pageSamples/styles.module.css`,Nr],[`pageSamples/welcome.vue`,Pr],[`pageSamples/page.vue`,$],[`pageSamples/404.vue`,Mr],[`app/provider.vue`,Dr],...t?.tanstack?.query?[[`app/index.ts`,Er],[`query.ts`,Fr]]:[[`app/index.ts`,Tr],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.vue`,Gr],[`components/Link.vue`,Vr],[`app.vue`,Br],[`router.ts`,Yr]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:l});await a(n.src(`index.html`),Wr,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Hr],[`server.ts`,Ur]])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?Ir:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),Zr=d({meta:{name:`Vue`,jsxImportSource:`vue`},dependencies(e){return{vue:Z.devDependencies.vue,"vue-router":Z.devDependencies[`vue-router`],"path-to-regexp":Z.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/vue-query":Z.devDependencies[`@tanstack/vue-query`]}:{}}},factory:Xr}),Qr=t=>{let i=process.env.NODE_ENV||`development`,a=typeof t.base==`string`?t.base:t.base[i];if(!a?.trim())throw Error(n([`red`],`ERROR: Invalid Config - no base provided`));return{...t,base:e(`/`,a),apiBase:e(`/`,t.apiBase||r)}};export{Qr as defineConfig,M as fetchGenerator,we as honoGenerator,We as koaGenerator,yt as mdxGenerator,wt as openapiGenerator,Qt as reactGenerator,Dn as solidGenerator,An as ssgGenerator,zn as ssrGenerator,pr as svelteGenerator,Sr as typeboxGenerator,Zr as vueGenerator};
8454
+ `,Qr=f((e,t)=>{let{createPath:n,createImportHelpers:r}=h(e),{renderToFile:i}=_({helpers:{...r({origin:`lib`}),...b()},partials:{routePartial:jr}}),{renderToFile:a}=_({helpers:r({origin:`src`})}),o=Tr(),l=e=>!e?.trim().length,u=s(t?.templates,Yr),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Xr:u(r.name,r),{route:r,message:Er()},{overwrite:l}):t===`pageLayout`&&await a(n.pages(r.file),Jr,{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`,Ar],[`server.ts`,Mr]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a,lazyLoad:e===`client.ts`});await i(n.lib(`router.ts`),zr,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[fe(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,$],[`unwrap.ts`,Br],[`use.ts`,Vr],[`pageSamples/styles.module.css`,Fr],[`pageSamples/welcome.vue`,Ir],[`pageSamples/page.vue`,Pr],[`pageSamples/404.vue`,Nr],[`app/provider.vue`,kr],...t?.tanstack?.query?[[`app/index.ts`,Or],[`query.ts`,Lr]]:[[`app/index.ts`,Dr],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.vue`,qr],[`components/Link.vue`,Ur],[`app.vue`,Hr],[`router.ts`,Zr]])await a(n.src(e),t,{entryDir:c.entryDir},{overwrite:l});await a(n.src(`index.html`),Kr,{entryDir:c.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Wr],[`server.ts`,Gr]])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?Rr:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),$r=d({meta:{name:`Vue`,jsxImportSource:`vue`},dependencies(e){return{vue:Z.devDependencies.vue,"vue-router":Z.devDependencies[`vue-router`],"path-to-regexp":Z.devDependencies[`path-to-regexp`],...e?.tanstack?.query?{"@tanstack/vue-query":Z.devDependencies[`@tanstack/vue-query`]}:{}}},factory:Qr}),ei=t=>{let i=process.env.NODE_ENV||`development`,a=typeof t.base==`string`?t.base:t.base[i];if(!a?.trim())throw Error(n([`red`],`ERROR: Invalid Config - no base provided`));return{...t,base:e(`/`,a),apiBase:e(`/`,t.apiBase||r)}};export{ei as defineConfig,P as fetchGenerator,Ee as honoGenerator,Ke as koaGenerator,xt as mdxGenerator,Et as openapiGenerator,en as reactGenerator,kn as solidGenerator,Mn as ssgGenerator,Vn as ssrGenerator,hr as svelteGenerator,wr as typeboxGenerator,$r as vueGenerator};
8161
8455
  //# sourceMappingURL=index.js.map