@kosmojs/dev 0.3.0 → 0.4.1

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,120 +1,6 @@
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}}
1
+ import{t as e}from"./assets/pkg-BhfEyKpY.js";import{join as t,resolve as n}from"node:path";import{styleText as r}from"node:util";import{DEFAULT_APIBASE as i,RequestBodyTargets as a,RequestValidationTargets as o,createRouteResolver as s,createTemplateResolver as c,defaults as l}from"@kosmojs/core";import{createH3Pattern as u,createHonoPattern as d,createPathPattern as f,createWatchedApiRouteEntriesFilter as p,createWatchedPageRouteEntriesFilter as m,defineGenerator as h,defineGeneratorFactory as g,mergeConfigs as _,nestedRoutesFactory as v,pathResolver as y,pathTokensFactory as b,renderFactory as x,renderToFile as ee,sortRoutes as S,spinnerFactory as te,vitePlugins as C}from"@kosmojs/lib";import{routeRenderHelpers as w}from"@kosmojs/core/generators";import T from"crc/crc32";import ne from"@mdx-js/rollup";import{build as E,createFilter as re}from"vite";import ie from"yaml";import{parse as ae}from"path-to-regexp";import oe from"typebox";import se from"@vitejs/plugin-react";import D from"vite-plugin-solid";import{access as ce,constants as le,cp as O,mkdir as ue,rm as k,writeFile as de}from"node:fs/promises";import{svelte as fe}from"@sveltejs/vite-plugin-svelte";import pe from"@vitejs/plugin-vue";var A=`export * from "./transport";
2
+ `,j=`export const transport = undefined;
3
+ `,M=`{{#each routes}}
118
4
  import {{id}} from "{{ createImport 'libApi' name 'fetch' }}";
119
5
  {{/each}}
120
6
 
@@ -132,10 +18,10 @@ export default {
132
18
  {{/each}}
133
19
  {{/each}}
134
20
  }
135
- `,j=`import fetchFactory, { join } from "@kosmojs/core/fetch";
21
+ `,N=`import fetchFactory, { join } from "@kosmojs/core/fetch";
136
22
 
137
23
  import { base, apiBase, apiRouteMap } from "{{ createImport 'libCore' }}";
138
- import { transport, fetchHelpers } from "{{ createImport 'lib' '@fetch' }}";
24
+ import { transport } from "{{ createImport 'lib' '@fetch' }}";
139
25
 
140
26
  import {
141
27
  type MaybeWrapped,
@@ -175,10 +61,7 @@ const {
175
61
  payloadResolver,
176
62
  path,
177
63
  href,
178
- } = fetchHelpers<[{{serializeParamsTupleElements route}}]>(
179
- apiBase,
180
- apiRouteMap["{{route.name}}"],
181
- );
64
+ } = apiRouteMap["{{route.name}}"];
182
65
 
183
66
  const fetchApi = fetchFactory(
184
67
  join(base, apiBase),
@@ -235,11 +118,858 @@ export default {
235
118
  href,
236
119
  validationSchemas,
237
120
  };
238
- `,M=`export type MaybeWrapped<T> = T;
121
+ `,P=`export type MaybeWrapped<T> = T;
239
122
  export const unwrap = <T>(data: T) => data;
240
- `,N=f(e=>{let{createPath:t,createImportHelpers:n}=h(e),{renderToFile:r}=_({helpers:{...n({origin:`lib`}),...b()}}),i=async(e,n)=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]).sort(v);await r(t.lib(`fetch.ts`),A,{routes:i});for(let{kind:e,entry:i}of n)if(e===`apiRoute`){let e=[];for(let t of i.validationDefinitions)if(t.target===`response`)for(let{id:n,body:r,resolvedType:i}of t.variants)r&&e.push({id:n,target:t.target,method:t.method,resolvedType:i});else{let{id:n,resolvedType:r}=t.schema;e.push({id:n,target:t.target,method:t.method,resolvedType:r})}let n=i.methods.map(t=>({method:t,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";
123
+ `,F=g(e=>{let{createPath:t,createImportHelpers:n}=y(e),{renderToFile:r}=x({helpers:{...n({origin:`lib`}),...w()}}),i=async(e,n)=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiRoute`?[t]:[]).sort(S);await r(t.lib(`fetch.ts`),M,{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`),N,{route:i,validationTypes:e,routeMethods:n,responseTypes:a})}};return{async start(){for(let[e,n]of[[`unwrap.ts`,P],[`@fetch/transport.ts`,j],[`@fetch/index.ts`,A]])await r(t.lib(e),n,{})},async watch(e,t){await i(e,e.filter(p(t,[`create`,`update`])))},async build(e){await i(e,e)},async ssrBuild(){for(let[e,n]of[[`@fetch/transport.ts`,`export { transport } from "${l.libPrefix}/@ssr/fetch";`]])await r(t.lib(e),n,{})}}}),I=h({meta:{name:`Fetch`,slot:`fetch`},factory:F}),L={type:`module`,private:!0,name:`@kosmojs/h3-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/h3-generator`},dependencies:{"@kosmojs/core":`workspace:^`,"@kosmojs/lib":`workspace:^`,crc:`^4.3.2`},devDependencies:{h3:`2.0.1-rc.29`,vite:`^8.2.2`}},R=`import { H3, type Middleware } from "h3";
124
+
125
+ import type { Route, RouteDebugOption } from "@kosmojs/core/api";
126
+
127
+ export type App = H3;
128
+
129
+ export type AppOptions = ConstructorParameters<typeof H3>[0] & {
130
+ debug?: RouteDebugOption;
131
+ };
132
+
133
+ export function appFactory(
134
+ routes: Array<Route<Middleware>>,
135
+ options: AppOptions,
136
+ ): App;
137
+
138
+ export function appFactory(
139
+ routes: Array<Route<Middleware>>,
140
+ fn: (a: { app: App }) => void,
141
+ ): App;
142
+
143
+ export function appFactory(
144
+ routes: Array<Route<Middleware>>,
145
+ options: AppOptions,
146
+ fn: (a: { app: App }) => void,
147
+ ): App;
148
+
149
+ export function appFactory(
150
+ routes: Array<Route<Middleware>>,
151
+ ...rest: Array<unknown>
152
+ ): App {
153
+ const [options, fn] = typeof rest[0] === "function" ? [{}, rest[0]] : rest;
154
+
155
+ const { debug = undefined, ...appOptions } = {
156
+ ...(options ? { ...options } : {}),
157
+ };
158
+
159
+ const app = new H3(appOptions);
160
+
161
+ if (typeof fn === "function") {
162
+ fn({ app });
163
+ }
164
+
165
+ for (const route of routes) {
166
+ if (typeof debug === "function") {
167
+ (debug as Function)(route.debug, route);
168
+ } else if (debug) {
169
+ console.log(route.debug[typeof debug === "string" ? debug : "full"]);
170
+ }
171
+ for (const method of route.methods) {
172
+ // last middleware is the handler
173
+ const handler = route.middleware.at(-1);
174
+ if (handler) {
175
+ app.on(method, route.path, handler as never, {
176
+ middleware: route.middleware.slice(0, -1),
177
+ });
178
+ }
179
+ }
180
+ }
181
+
182
+ return app;
183
+ }
184
+ `,z=`import type { DevSetup } from "@kosmojs/core/api";
185
+
186
+ export const devSetup = (setup: DevSetup) => setup;
187
+ `,B=`import { type H3Event, HTTPError } from "h3";
188
+
189
+ import { ValidationError } from "@kosmojs/core/errors";
190
+
191
+ type ErrorHandler = (
192
+ error: any,
193
+ event: H3Event,
194
+ ) => Promise<Response> | Response;
195
+
196
+ export type ErrorHandlerFactory = (handler: ErrorHandler) => ErrorHandler;
197
+
198
+ export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
199
+ // H3 wraps errors in its own HTTPError with the original error as \`cause\`
200
+ return (error, event) => {
201
+ return handler(
202
+ error instanceof HTTPError
203
+ ? error.cause instanceof ValidationError
204
+ ? error.cause
205
+ : error
206
+ : error,
207
+ event,
208
+ );
209
+ };
210
+ };
211
+ `,me=`import { type H3Event, readBody } from "h3";
212
+
213
+ import {
214
+ parseCookies,
215
+ parseSearchParams,
216
+ type RequestBodyTarget,
217
+ type RequestMetadataTarget,
218
+ } from "@kosmojs/core";
219
+
220
+ export const metaparsers: {
221
+ [T in RequestMetadataTarget]: (event: H3Event) => unknown;
222
+ } = {
223
+ query(event) {
224
+ return parseSearchParams(event.url);
225
+ },
226
+
227
+ headers(event) {
228
+ return Object.fromEntries(event.req.headers);
229
+ },
230
+
231
+ cookies(event) {
232
+ return parseCookies(Object.fromEntries(event.req.headers));
233
+ },
234
+ };
235
+
236
+ export const bodyparsers: {
237
+ [T in RequestBodyTarget]: (event: H3Event) => Promise<unknown>;
238
+ } = {
239
+ json(event) {
240
+ return event.req.json();
241
+ },
242
+
243
+ form(event) {
244
+ return readBody(event, { type: "formData" });
245
+ },
246
+
247
+ raw(event) {
248
+ return event.req.text();
249
+ },
250
+ };
251
+ `,he=`import type { Middleware } from "h3";
252
+
253
+ import type {
254
+ RequestBodyTarget,
255
+ RequestMetadataTarget,
256
+ RequestValidationTarget,
257
+ ValidationErrorEntry,
258
+ } from "@kosmojs/core";
259
+ import {
260
+ type CreateRouteMiddleware,
261
+ createRoutes,
262
+ type HTTPMethod,
263
+ StateKey,
264
+ } from "@kosmojs/core/api";
265
+ import { ValidationError } from "@kosmojs/core/errors";
266
+
267
+ import {
268
+ type DefaultContext,
269
+ type ParameterizedEvent,
270
+ type ParameterizedMiddleware,
271
+ use,
272
+ } from "../api";
273
+ import { bodyparsers, metaparsers } from "./parsers";
274
+ import { routeSources } from "./routes";
275
+
276
+ import globalMiddleware from "{{ createImport 'api' 'use' }}";
277
+
278
+ /**
279
+ * Create route-level middleware stack that handles:
280
+ * 1. Context extension - adds \`event.bodyparser\` (lazy, cached) and \`event.validated\` accessors
281
+ * 2. Params validation - normalizes and validates URL params (including splat/numeric params)
282
+ * 3. Request validation - validates query, headers, cookies, and body against schemas
283
+ * 4. Response validation - validates outgoing response against defined variants
284
+ *
285
+ * Middleware are assigned named slots (e.g. "validate:params", "validate:json")
286
+ * so they can be replaced by user-defined middleware in the stack.
287
+ *
288
+ * All validation errors are thrown as \`ValidationError\` instances,
289
+ * caught and formatted by the global error handler middleware upstream.
290
+ * */
291
+ export const createRouteMiddleware: CreateRouteMiddleware<
292
+ ParameterizedMiddleware
293
+ > = ({ name, validationSchemas, normalizeParams, normalizeSearchParams }) => {
294
+ const validationMiddleware = [
295
+ /**
296
+ * Extends H3 event with:
297
+ *
298
+ * - \`event.metaparser[target]()\` - lazy, cached meta parsers.
299
+ * Each parser (query, headers, cookies) runs at most once per request;
300
+ * subsequent calls return the cached result.
301
+ *
302
+ * - \`event.bodyparser[target](opts?)\` - lazy, cached body parsers.
303
+ * Each parser (json, form, raw) runs at most once per request;
304
+ * subsequent calls return the cached result.
305
+ * This allows both user middleware/handlers and validators
306
+ * to call the same parser without re-consuming the request stream.
307
+ *
308
+ * - \`event.validated\` - getter that returns all validated data collected so far
309
+ * (params, query, headers, cookies, json etc.) as a plain object.
310
+ *
311
+ * Cache is stored on \`event[StateKey]\` (a Symbol-keyed Map) to keep it
312
+ * hidden from public API surface and serialization.
313
+ * */
314
+ use(
315
+ function useExtendContext(event, next) {
316
+ if (!event[StateKey]) {
317
+ // initialize per-request cache with empty params
318
+ // (later populated by useValidateParams)
319
+ event[StateKey] = new Map([["params", {}]]);
320
+
321
+ Object.defineProperty(event, "metaparser", {
322
+ value: Object.entries(metaparsers).reduce<{
323
+ [T in RequestMetadataTarget]?: () => unknown;
324
+ }>((map, entry) => {
325
+ const [target, parser] = entry as [
326
+ RequestMetadataTarget,
327
+ Function,
328
+ ];
329
+ map[target] = () => {
330
+ if (!event[StateKey].has(target)) {
331
+ event[StateKey].set(
332
+ target,
333
+ target === "query"
334
+ ? normalizeSearchParams(
335
+ parser(event),
336
+ event.req.method as never,
337
+ )
338
+ : parser(event),
339
+ );
340
+ }
341
+ return event[StateKey].get(target);
342
+ };
343
+ return map;
344
+ }, {}),
345
+ enumerable: true,
346
+ });
347
+
348
+ Object.defineProperty(event, "bodyparser", {
349
+ value: Object.entries(bodyparsers).reduce<{
350
+ [T in RequestBodyTarget]?: () => Promise<unknown>;
351
+ }>((map, entry) => {
352
+ const [target, parser] = entry as [RequestBodyTarget, Function];
353
+ map[target] = async () => {
354
+ if (!event[StateKey].has(target)) {
355
+ event[StateKey].set(target, await parser(event));
356
+ }
357
+ return event[StateKey].get(target);
358
+ };
359
+ return map;
360
+ }, {}),
361
+ enumerable: true,
362
+ });
363
+
364
+ Object.defineProperty(event, "validated", {
365
+ get() {
366
+ return Object.fromEntries(event[StateKey]);
367
+ },
368
+ enumerable: true,
369
+ });
370
+ }
371
+ return next();
372
+ },
373
+ { slot: "@extendContext" },
374
+ ) as never,
375
+
376
+ /**
377
+ * Normalize and validate URL params:
378
+ * - Splat params (e.g. \`/files{/*path}\`) are split into arrays by "/"
379
+ * - Numeric params are cast to Number (or array of Numbers for splat params)
380
+ * - Non-splat, non-numeric params pass through as strings
381
+ *
382
+ * Validated params are stored in the cache so \`event.validated.params\`
383
+ * reflects the normalized (and validated) values.
384
+ * */
385
+ use(
386
+ function useValidateParams(event, next) {
387
+ const normalizedParams = normalizeParams(event.url.pathname);
388
+ validationSchemas.params?.validate(normalizedParams);
389
+ event[StateKey].set("params", normalizedParams);
390
+ return next();
391
+ },
392
+ { slot: "validate:params" },
393
+ ) as never,
394
+
395
+ /**
396
+ * Response validation - runs AFTER the handler (post-\`next()\`).
397
+ *
398
+ * Each response schema defines one or more variants, each with:
399
+ * - expected status code
400
+ * - optional content-type
401
+ * - optional body schema
402
+ *
403
+ * All variants are checked; if at least one passes, validation succeeds.
404
+ * If none pass, a ValidationError is thrown with collected errors from all variants.
405
+ *
406
+ * Activation rules:
407
+ * - In dev/test mode: runs unless \`runtimeValidation\` is explicitly \`false\`
408
+ * - In production: runs only if \`runtimeValidation\` is explicitly \`true\`
409
+ *
410
+ * Only attached to HTTP methods that have response schemas defined.
411
+ * */
412
+ use(
413
+ async function useValidateResponse(event, next) {
414
+ const variants = validationSchemas.response?.[event.req.method] || [];
415
+
416
+ if (!Array.isArray(variants) || !variants.length) {
417
+ return next();
418
+ }
419
+
420
+ // options are same for all variants
421
+ const { runtimeValidation, customErrors } = variants[0];
422
+
423
+ if (KOSMO_PRODUCTION_BUILD) {
424
+ // skip if undefined or explicitly set to false
425
+ if (runtimeValidation === undefined || runtimeValidation === false) {
426
+ return next();
427
+ }
428
+ } else {
429
+ // skip only if explicitly set to false
430
+ if (runtimeValidation === false) {
431
+ return next();
432
+ }
433
+ }
434
+
435
+ // run all downstream middleware (including the route handler)
436
+ const body = await next();
437
+
438
+ /**
439
+ * H3 builds the actual Response AFTER the middleware chain completes,
440
+ * so at this point event.res only reflects what handlers set explicitly.
441
+ * Reconstruct what will be sent instead: a returned Response is authoritative;
442
+ * otherwise an unset status means 200, and the content type follows H3's
443
+ * serialization rules for the returned value (string -> text, object -> JSON).
444
+ * */
445
+ const rawResponse = body instanceof Response ? body : undefined;
446
+
447
+ const response: {
448
+ status: number;
449
+ contentType: string | null;
450
+ body?: unknown;
451
+ } = {
452
+ status: rawResponse?.status ?? event.res.status ?? 200,
453
+ contentType:
454
+ rawResponse?.headers.get("Content-Type") ??
455
+ event.res.headers.get("Content-Type") ??
456
+ (typeof body === "string"
457
+ ? "text/plain"
458
+ : body === undefined || body === null
459
+ ? null
460
+ : "application/json"),
461
+ };
462
+
463
+ // Validate body only for JSON variants
464
+ if (variants.some((e) => e.contentType?.includes("json"))) {
465
+ response.body = rawResponse
466
+ ? await rawResponse
467
+ .clone()
468
+ .json()
469
+ .catch(() => undefined)
470
+ : body;
471
+ }
472
+
473
+ /**
474
+ * Returns an array of validator functions for a single response variant.
475
+ * Each validator checks one aspect (status, content-type, body)
476
+ * and returns an error entry or undefined if the check passes.
477
+ * */
478
+ const variantValidators: (
479
+ v: (typeof variants)[number],
480
+ ) => Array<(i: number) => ValidationErrorEntry | undefined> = (
481
+ schema,
482
+ ) => {
483
+ return [
484
+ (i) => {
485
+ return schema.status === response.status
486
+ ? undefined
487
+ : {
488
+ keyword: "Status",
489
+ path: \`Variant #\${i}\`,
490
+ message: \`expected: \${schema.status}; actual: \${response.status}\`,
491
+ };
492
+ },
493
+ (i) => {
494
+ if (
495
+ !schema.contentType ||
496
+ schema.contentType === response.contentType
497
+ ) {
498
+ return undefined;
499
+ }
500
+ return {
501
+ keyword: "ContentType",
502
+ path: \`Variant #\${i}\`,
503
+ message: \`expected: \${schema.contentType}; actual: \${response.contentType}\`,
504
+ };
505
+ },
506
+ (i) => {
507
+ if (!schema.check || "body" in response === false) {
508
+ // no body schema or contentType is not JSON
509
+ return;
510
+ }
511
+ return schema.check(response.body)
512
+ ? undefined
513
+ : {
514
+ keyword: "Body",
515
+ path: \`Variant #\${i}\`,
516
+ message: schema.errorMessage(response.body),
517
+ };
518
+ },
519
+ ];
520
+ };
521
+
522
+ // collect errors across all variants; exit early if any variant passes
523
+ const errors: Array<ValidationErrorEntry> = [];
524
+
525
+ for (const [i, variant] of variants.entries()) {
526
+ const variantErrors = variantValidators(variant).flatMap(
527
+ (validator) => {
528
+ const error = validator(i);
529
+ return error ? [error] : [];
530
+ },
531
+ );
532
+ if (!variantErrors.length) {
533
+ // variant fully matched - response is valid
534
+ return;
535
+ }
536
+ errors.push(...variantErrors);
537
+ }
538
+
539
+ const errorMessage = \`The response did not match any of the expected formats\`;
540
+ const errorSummary = \`\${variants.length} variants checked, none valid\`;
541
+
542
+ // no variant passed validation
543
+ throw new ValidationError([
544
+ "response",
545
+ {
546
+ errors,
547
+ errorMessage: customErrors?.error || errorMessage,
548
+ errorSummary,
549
+ route: name,
550
+ data: response,
551
+ },
552
+ ]);
553
+ },
554
+ {
555
+ slot: "validate:response",
556
+ on: Object.keys(validationSchemas.response || {}) as Array<HTTPMethod>,
557
+ },
558
+ ) as never,
559
+ ];
560
+
561
+ /**
562
+ * Request validation - dynamically creates one middleware per target
563
+ * (query, headers, cookies, json, form, multipart, raw).
564
+ *
565
+ * Each middleware:
566
+ * 1. Checks if a schema exists for the current HTTP method
567
+ * 2. Skips if \`runtimeValidation\` is explicitly disabled
568
+ * 3. Loads data via the appropriate source (event.query, event.headers, or event.bodyparser)
569
+ * 4. Validates via \`schema.validate()\` which throws on failure
570
+ *
571
+ * Body targets (json, form, raw) go through \`event.bodyparser[target]()\`,
572
+ * benefiting from the lazy parsing and caching set up by slot:extendContext middleware.
573
+ *
574
+ * All request validators are active on any HTTP method that has at least one
575
+ * schema defined across any target - this is intentionally broad to avoid
576
+ * silently skipping validation when methods overlap.
577
+ * */
578
+ const requestTargets: Record<
579
+ RequestValidationTarget,
580
+ (
581
+ event: ParameterizedEvent<Record<string, string>, DefaultContext>,
582
+ ) => Promise<unknown>
583
+ > = {
584
+ query: async (event) => event.metaparser.query(),
585
+ headers: async (event) => event.metaparser.headers(),
586
+ cookies: async (event) => event.metaparser.cookies(),
587
+ json: async (event) => event.bodyparser.json(),
588
+ form: async (event) => event.bodyparser.form(),
589
+ raw: async (event) => event.bodyparser.raw(),
590
+ };
591
+
592
+ const requestEntries = Object.entries(requestTargets) as Array<
593
+ [RequestValidationTarget, (typeof requestTargets)[RequestValidationTarget]]
594
+ >;
595
+
596
+ for (const [target, loadData] of requestEntries) {
597
+ validationMiddleware.push(
598
+ use(
599
+ async (event, next) => {
600
+ const schema = {
601
+ ...validationSchemas[target]?.[event.req.method],
602
+ };
603
+ if (schema.validate && schema.runtimeValidation !== false) {
604
+ schema.validate(await loadData(event as never));
605
+ }
606
+ return next();
607
+ },
608
+ {
609
+ slot: \`validate:\${target}\`,
610
+ // duplicates not an issue here
611
+ on: requestEntries.flatMap(([target]) => {
612
+ return Object.keys(
613
+ validationSchemas[target] || {},
614
+ ) as Array<HTTPMethod>;
615
+ }),
616
+ },
617
+ ) as never,
618
+ );
619
+ }
620
+
621
+ return validationMiddleware;
622
+ };
623
+
624
+ export const routes = createRoutes<ParameterizedMiddleware, Middleware>(
625
+ routeSources,
626
+ {
627
+ globalMiddleware: globalMiddleware as never,
628
+ createRouteMiddleware,
629
+ },
630
+ );
631
+ `,ge=`import { join } from "node:path";
632
+
633
+ import type { RouteSource } from "@kosmojs/core/api";
634
+
635
+ import { base, apiBase, apiRouteMap, apiRouteMapper } from "{{ createImport 'libCore' }}";
636
+
637
+ {{#each routes}}
638
+ import {{id}} from "{{ createImport 'api' file }}";
639
+ import { validationSchemas as {{id}}_schemas } from "{{ createImport 'libApi' basename 'schemas' }}";
640
+ {{/each}}
641
+
642
+ {{#each cascadingMiddleware}}
643
+ import {{id}}, { type UseT as UseT{{id}} } from "{{ createImport 'api' file }}";
644
+ {{/each}}
645
+
646
+ export type RouteMap = {
647
+ {{#each routes}}
648
+ "{{name}}": {
649
+ paramsDefaults: {{paramsDefaults .}},
650
+ paramsMappings: {{paramsMappings .}},
651
+ cascadingState: {{cascadingState .}},
652
+ },
653
+ {{/each}}
654
+ }
655
+
656
+ export const routeSources: Array<RouteSource<never>> = [
657
+ {{#each routes}}
658
+ {
659
+ {{#if alias}}
660
+ ...apiRouteMapper(apiBase, { ...{{serializeApiRoute .}}, pathPattern: "{{alias}}" }),
661
+ path: "{{alias}}",
662
+ pathPattern: "{{alias}}",
663
+ {{else}}
664
+ ...apiRouteMap["{{name}}"],
665
+ path: join(base, apiBase, "{{path}}"),
666
+ pathPattern: join(base, apiBase, "{{pathPattern}}"),
667
+ {{/if}}
668
+ name: "{{name}}",
669
+ file: "{{file}}",
670
+ cascadingMiddleware: [ {{#each cascadingMiddleware}}{{id}}, {{/each}}].flat() as Array<never>,
671
+ definitionItems: {{id}} as never,
672
+ validationSchemas: {{id}}_schemas,
673
+ },
674
+ {{/each}}
675
+ ];
676
+ `,_e=`import { parseArgs, styleText } from "node:util";
677
+
678
+ import { serve as h3serve } from "h3";
679
+
680
+ import type { App } from "./app";
681
+
682
+ type Handles = {
683
+ port?: number | undefined;
684
+ onListen?: () => Promise<void>;
685
+ };
686
+
687
+ const getListenHandles = async (opt?: Handles) => {
688
+ const { port } = opt
689
+ ? opt
690
+ : parseArgs({
691
+ options: {
692
+ port: {
693
+ type: "string",
694
+ short: "p",
695
+ },
696
+ },
697
+ }).values;
698
+
699
+ if (![port].some(Boolean)) {
700
+ throw new Error("Please provide -p/--port number");
701
+ }
702
+
703
+ const onListen = async () => {
704
+ console.log(
705
+ \`\\n ✨ Server Started \${styleText(["dim"], "[ %s ]")}\`,
706
+ \`port: \${port}\`,
707
+ );
708
+ };
709
+
710
+ return {
711
+ port: Number(port),
712
+ onListen: opt?.onListen || onListen,
713
+ };
714
+ };
715
+
716
+ export const serve = async <T extends App>(app: T, opt?: Handles) => {
717
+ const { port, onListen } = await getListenHandles(opt);
718
+
719
+ const server = h3serve(app, { port });
720
+ await server.ready().then(onListen);
721
+
722
+ return server as never;
723
+ };
724
+ `,ve=`import type { H3Event, H3EventContext } from "h3";
725
+
726
+ import type { ValidationDefmap, ValidationOptmap } from "@kosmojs/core";
727
+ import {
728
+ use as createUse,
729
+ type ExtendContext,
730
+ type HandlerDefinition,
731
+ type HTTPMethod,
732
+ type MiddlewareDefinition,
733
+ type RouteDefinitionItem,
734
+ type UseOptions,
735
+ } from "@kosmojs/core/api";
736
+
737
+ import type { RouteMap } from "./@api/routes";
738
+
739
+ export interface DefaultContext extends H3EventContext {}
740
+
741
+ type MaybePromise<T = unknown> = T | Promise<T>;
742
+
743
+ type Next = () => MaybePromise<unknown | undefined>;
744
+
745
+ type ExtractBodies<R> = R extends [number, string, infer Body] ? Body : never;
746
+
747
+ type ValidatedResponseBodies<VDefs extends ValidationDefmap> = [
748
+ ExtractBodies<VDefs["response"]>,
749
+ ] extends [never]
750
+ ? unknown // No bodies extracted at all - fallback to unknown
751
+ : ExtractBodies<VDefs["response"]>;
752
+
753
+ export type ParameterizedEvent<
754
+ ParamsT,
755
+ ContextT,
756
+ VDefs extends ValidationDefmap = {},
757
+ VOpts extends ValidationOptmap = {},
758
+ > = H3Event & { context: DefaultContext } & ContextT &
759
+ ExtendContext<ParamsT, VDefs, VOpts>;
760
+
761
+ export type ParameterizedMiddleware<
762
+ ParamsT = Record<string, string>,
763
+ ContextT = Record<string, unknown>,
764
+ > = (
765
+ event: ParameterizedEvent<ParamsT, ContextT>,
766
+ next: Next,
767
+ ) => MaybePromise<unknown>;
768
+
769
+ export type RouteHandler<
770
+ ParamsT,
771
+ ContextT,
772
+ VDefs extends ValidationDefmap,
773
+ VOpts extends ValidationOptmap = {},
774
+ > = (
775
+ event: ParameterizedEvent<ParamsT, ContextT, VDefs, VOpts>,
776
+ ) => MaybePromise<ValidatedResponseBodies<VDefs>>;
777
+
778
+ export type DefineRouteFactory<ParamsT, ContextT> = (
779
+ a: {
780
+ // NOTE: The \`use\` helper intentionally does not accept validation types.
781
+ // Allowing these type parameters on \`use\` would be misleading,
782
+ // since middleware operates across multiple request methods with varying types.
783
+ use: (
784
+ middleware:
785
+ | ParameterizedMiddleware<ParamsT, ContextT>
786
+ | Array<ParameterizedMiddleware<ParamsT, ContextT>>,
787
+ options?: UseOptions,
788
+ ) => MiddlewareDefinition<ParameterizedMiddleware<ParamsT, ContextT>>;
789
+ } & {
790
+ [M in HTTPMethod]: <
791
+ VDefs extends ValidationDefmap,
792
+ VOpts extends ValidationOptmap = {},
793
+ >(
794
+ handler:
795
+ | RouteHandler<ParamsT, ContextT, VDefs, VOpts>
796
+ | Array<RouteHandler<ParamsT, ContextT, VDefs, VOpts>>,
797
+ ) => HandlerDefinition<ParameterizedMiddleware<ParamsT, ContextT>>;
798
+ },
799
+ ) => Array<RouteDefinitionItem<ParameterizedMiddleware<ParamsT, ContextT>>>;
800
+
801
+ type ParamsMap<
802
+ Mappings extends Array<[string, unknown, boolean]>,
803
+ Refinements extends Array<unknown>,
804
+ > = {
805
+ [I in Extract<keyof Mappings, \`\${number}\`> as Mappings[I] extends [
806
+ infer ParamName extends string,
807
+ ...Array<unknown>,
808
+ ]
809
+ ? ParamName
810
+ : never]: Mappings[I] extends [string, infer Default, true]
811
+ ? I extends keyof Refinements
812
+ ? Refinements[I]
813
+ : Default
814
+ : Mappings[I] extends [string, infer Default, false]
815
+ ? I extends keyof Refinements
816
+ ? Refinements[I] | undefined
817
+ : Default | undefined
818
+ : never;
819
+ };
820
+
821
+ export const use = <ContextT = DefaultContext>(
822
+ middleware:
823
+ | ParameterizedMiddleware<Record<string, string>, ContextT>
824
+ | Array<ParameterizedMiddleware<Record<string, string>, ContextT>>,
825
+ options?: UseOptions,
826
+ ) => {
827
+ return createUse<ParameterizedMiddleware<Record<string, string>, ContextT>>(
828
+ middleware,
829
+ options,
830
+ );
831
+ };
832
+
833
+ export const defineRoute: <
834
+ R extends keyof RouteMap,
835
+ ParamsD extends RouteMap[R]["paramsDefaults"] = RouteMap[R]["paramsDefaults"],
836
+ ContextT extends object = object,
837
+ >(
838
+ factory: DefineRouteFactory<
839
+ ParamsMap<RouteMap[R]["paramsMappings"], ParamsD>,
840
+ ContextT & RouteMap[R]["cascadingState"]
841
+ >,
842
+ ) => Array<
843
+ RouteDefinitionItem<
844
+ ParameterizedMiddleware<
845
+ ParamsMap<RouteMap[R]["paramsMappings"], ParamsD>,
846
+ ContextT & RouteMap[R]["cascadingState"]
847
+ >
848
+ >
849
+ > = (factory) => {
850
+ const createHandler = <MiddlewareT>(method: HTTPMethod) => {
851
+ return (middleware: MiddlewareT | Array<MiddlewareT>) => {
852
+ return {
853
+ kind: "handler",
854
+ method,
855
+ middleware: [middleware].flat(),
856
+ };
857
+ };
858
+ };
859
+ return factory({
860
+ HEAD: createHandler("HEAD") as never,
861
+ OPTIONS: createHandler("OPTIONS") as never,
862
+ GET: createHandler("GET") as never,
863
+ POST: createHandler("POST") as never,
864
+ PUT: createHandler("PUT") as never,
865
+ PATCH: createHandler("PATCH") as never,
866
+ DELETE: createHandler("DELETE") as never,
867
+ // route-specific \`use\`, contains types for current route
868
+ use: use as never,
869
+ });
870
+ };
871
+ `,ye=`export * from "./@api/app";
872
+ export { appFactory as default } from "./@api/app";
873
+ export * from "./@api/dev";
874
+ export * from "./@api/errors";
875
+ export * from "./@api/router";
876
+ export * from "./@api/routes";
877
+ export * from "./@api/server";
878
+ `,be=`import { onError } from "h3";
879
+
880
+ import appFactory, { routes, type App } from "{{ createImport 'lib' 'api:factory' }}";
881
+ import defaultErrorHandler from "./errors";
882
+
883
+ export default appFactory(routes, ({ app }) => {
884
+ app.use(onError(defaultErrorHandler));
885
+ }) as App;
886
+ `,xe=`import { toNodeHandler } from "h3/node";
887
+
888
+ import app from "./app";
889
+
890
+ import { devSetup } from "{{ createImport 'lib' 'api:factory' }}";
891
+
892
+ export default devSetup({
893
+ requestHandler() {
894
+ return toNodeHandler(app);
895
+ },
896
+ teardownHandler() {
897
+ // close db connections, server sockets etc.
898
+ },
899
+ });
900
+
901
+ process.on("unhandledRejection", (reason) => {
902
+ console.error("💥 UNHANDLED REJECTION");
903
+ console.error("Reason:", reason);
904
+ process.exit(1);
905
+ });
906
+ `,Se=`export declare module "{{ createImport 'libApi' }}" {
907
+ interface DefaultContext {}
908
+ }
909
+ `,Ce=`import { ValidationError } from "@kosmojs/core/errors";
910
+ import { HTTPError } from "h3";
911
+
912
+ import { errorHandlerFactory } from "{{ createImport 'lib' 'api:factory' }}";
913
+
914
+ export default errorHandlerFactory(async (error, event) => {
915
+ const [status, message = "Unknown error occurred"] = Array.isArray(error)
916
+ ? error
917
+ : error instanceof HTTPError
918
+ ? [error.status, error.message]
919
+ : error instanceof ValidationError
920
+ ? [400, \`\${error.target}: \${error.errorMessage}\`]
921
+ : [error.statusCode || 500, error.message];
922
+
923
+ const accept = event.req.headers.get("accept");
924
+
925
+ return accept?.includes("application/json")
926
+ ? new Response(JSON.stringify({ error: message }), {
927
+ status,
928
+ headers: { "Content-Type": "application/json" },
929
+ })
930
+ : new Response(message, {
931
+ status,
932
+ headers: { "Content-Type": "text/plain" },
933
+ });
934
+ });
935
+ `,we=`import { defineRoute } from "{{ createImport 'libApi' }}";
936
+
937
+ export default defineRoute<"{{route.name}}">(({ GET }) => [
938
+ GET(async (event) => {
939
+ return "Automatically generated route";
940
+ }),
941
+ ]);
942
+ `,Te=`import { use } from "{{ createImport 'libApi' }}";
943
+
944
+ export type UseT = {};
945
+
946
+ export default [
947
+ use<UseT>(async (event, next) => {
948
+ return next();
949
+ }),
950
+ ];
951
+ `,Ee=`import { serve } from "{{ createImport 'lib' 'api:factory' }}";
952
+ import app from "./app";
953
+
954
+ await serve(app);
955
+ `,De=`import { use } from "{{ createImport 'libApi' }}";
956
+
957
+ /**
958
+ * Define global middleware applied to all routes.
959
+ * Can be overridden on a per-route basis using the slot key.
960
+ * */
961
+ export default [
962
+ use(async function useExample(event, next) {
963
+ return next();
964
+ }),
965
+ ];
966
+ `,Oe=g((e,n)=>{let{createPath:r,createImportHelpers:i}=y(e),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=x({helpers:{...i({origin:`lib`}),...w(),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:s}=x({helpers:i({origin:`src`})}),l=e=>e?.trim().length===0,d=c(n?.templates,we),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await s(r.api(n.file),d(n.name,n),{route:n},{overwrite:l}):t===`apiUse`&&await s(r.api(n.file),Te,{},{overwrite:l})},m=async e=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=e.flatMap(({kind:e,entry:r})=>{if(e!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((e,n)=>{let r=e[e.length-1];return e.push(r?t(r,n):n),e},[]),o={...r,path:r.h3Pattern,basename:r.name,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=b(e);return t===r.name?[{...o,name:e,basename:r.name,id:`${o.id}_${T(e)}`,alias:u(n),pathTokens:n}]:[]})]}).sort(S);for(let[e,t]of[[`@api/routes.ts`,ge]])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`,ve],[`api:factory.ts`,ye],[`@api/app.ts`,R],[`@api/parsers.ts`,me],[`@api/dev.ts`,z],[`@api/errors.ts`,B],[`@api/router.ts`,he],[`@api/server.ts`,_e]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,be],[`dev.ts`,xe],[`errors.ts`,Ce],[`server.ts`,Ee],[`use.ts`,De],[`env.d.ts`,Se]])await s(r.api(e),t,{},{overwrite:l})},async watch(e,t){await f(e.filter(p(t,[`create`]))),await m(e)},async build(e){await f(e),await m(e)}}}),ke=h({meta:{name:`H3`,slot:`backend`},dependencies:{h3:L.devDependencies.h3},factory:Oe}),V={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.1`,hono:`^4.13.3`,vite:`^8.2.2`}},Ae=`import { Hono, type MiddlewareHandler } from "hono";
967
+ import type { Router } from "hono/router";
968
+ import { RegExpRouter } from "hono/router/reg-exp-router";
969
+ import { SmartRouter } from "hono/router/smart-router";
970
+ import { TrieRouter } from "hono/router/trie-router";
241
971
 
242
- import type { AppFactory } from "@kosmojs/core/api";
972
+ import type { Route, RouteDebugOption } from "@kosmojs/core/api";
243
973
 
244
974
  import type { DefaultBindings, DefaultVariables } from "../api";
245
975
 
@@ -250,18 +980,65 @@ export type AppEnv = {
250
980
 
251
981
  export type App = Hono<AppEnv>;
252
982
 
253
- export type AppOptions = ConstructorParameters<typeof Hono<AppEnv>>[0];
983
+ export type AppOptions = ConstructorParameters<typeof Hono<AppEnv>>[0] & {
984
+ debug?: RouteDebugOption;
985
+ };
254
986
 
255
- export const appFactory: AppFactory<App, AppOptions> = (factory) => {
256
- const createApp = (options?: AppOptions) => {
257
- return new Hono({ strict: false, ...options });
987
+ export function appFactory(
988
+ routes: Array<Route<MiddlewareHandler>>,
989
+ options: AppOptions,
990
+ ): App;
991
+
992
+ export function appFactory(
993
+ routes: Array<Route<MiddlewareHandler>>,
994
+ fn: (a: { app: App; router: Router<never> }) => void,
995
+ ): App;
996
+
997
+ export function appFactory(
998
+ routes: Array<Route<MiddlewareHandler>>,
999
+ options: AppOptions,
1000
+ fn: (a: { app: App; router: Router<never> }) => void,
1001
+ ): App;
1002
+
1003
+ export function appFactory(
1004
+ routes: Array<Route<MiddlewareHandler>>,
1005
+ ...rest: Array<unknown>
1006
+ ): App {
1007
+ const [options, fn] = typeof rest[0] === "function" ? [{}, rest[0]] : rest;
1008
+
1009
+ const router = new SmartRouter({
1010
+ routers: [new RegExpRouter(), new TrieRouter()],
1011
+ }) as Router<never>;
1012
+
1013
+ const { debug = undefined, ...appOptions } = {
1014
+ ...(options ? { ...options } : {}),
258
1015
  };
259
- return factory({ createApp });
260
- };
261
- `,L=`import type { DevSetup } from "@kosmojs/core/api";
1016
+
1017
+ const app = new Hono({
1018
+ strict: false,
1019
+ router,
1020
+ ...appOptions,
1021
+ });
1022
+
1023
+ if (typeof fn === "function") {
1024
+ fn({ app, router });
1025
+ }
1026
+
1027
+ for (const route of routes) {
1028
+ if (typeof debug === "function") {
1029
+ (debug as Function)(route.debug, route);
1030
+ } else if (debug) {
1031
+ console.log(route.debug[typeof debug === "string" ? debug : "full"]);
1032
+ }
1033
+ app.on(route.methods, [route.path], ...route.middleware);
1034
+ }
1035
+
1036
+ return app as never;
1037
+ }
1038
+ `,je=`import type { DevSetup } from "@kosmojs/core/api";
262
1039
 
263
1040
  export const devSetup = (setup: DevSetup) => setup;
264
- `,R=`import type { Context } from "hono";
1041
+ `,Me=`import type { Context } from "hono";
265
1042
 
266
1043
  import type { AppEnv } from "./app";
267
1044
 
@@ -275,7 +1052,7 @@ export type ErrorHandlerFactory = (handler: ErrorHandler) => ErrorHandler;
275
1052
  export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
276
1053
  return handler;
277
1054
  };
278
- `,z=`import type { Context } from "hono";
1055
+ `,Ne=`import type { Context } from "hono";
279
1056
 
280
1057
  import {
281
1058
  parseCookies,
@@ -324,12 +1101,7 @@ export const bodyparsers: {
324
1101
  return ctx.req[as]();
325
1102
  },
326
1103
  };
327
- `,B=`import type { MiddlewareHandler } from "hono";
328
- import type { Router } from "hono/router";
329
- import { RegExpRouter } from "hono/router/reg-exp-router";
330
- import { SmartRouter } from "hono/router/smart-router";
331
- import { TrieRouter } from "hono/router/trie-router";
332
- import { match } from "path-to-regexp";
1104
+ `,Pe=`import type { MiddlewareHandler } from "hono";
333
1105
 
334
1106
  import type {
335
1107
  RequestBodyTarget,
@@ -341,7 +1113,6 @@ import {
341
1113
  type CreateRouteMiddleware,
342
1114
  createRoutes,
343
1115
  type HTTPMethod,
344
- type RouterFactory,
345
1116
  StateKey,
346
1117
  } from "@kosmojs/core/api";
347
1118
  import { ValidationError } from "@kosmojs/core/errors";
@@ -357,7 +1128,6 @@ import { type BodyparserOptions, bodyparsers, metaparsers } from "./parsers";
357
1128
  import { routeSources } from "./routes";
358
1129
 
359
1130
  import globalMiddleware from "{{ createImport 'api' 'use' }}";
360
- import { apiRouteMap } from "{{ createImport 'libCore' }}";
361
1131
 
362
1132
  /**
363
1133
  * Create route-level middleware stack that handles:
@@ -374,33 +1144,7 @@ import { apiRouteMap } from "{{ createImport 'libCore' }}";
374
1144
  * */
375
1145
  export const createRouteMiddleware: CreateRouteMiddleware<
376
1146
  ParameterizedMiddleware
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
-
386
- const pathMatcher = match(pathPattern);
387
-
388
- const matchPath = (path: string) => {
389
- try {
390
- return pathMatcher(path);
391
- } catch (_e) {
392
- return undefined;
393
- }
394
- };
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
-
1147
+ > = ({ name, validationSchemas, normalizeParams, normalizeSearchParams }) => {
404
1148
  const validationMiddleware = [
405
1149
  /**
406
1150
  * Extends Hono context with:
@@ -441,15 +1185,9 @@ export const createRouteMiddleware: CreateRouteMiddleware<
441
1185
  ctx[StateKey].set(
442
1186
  target,
443
1187
  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
- ]),
1188
+ ? normalizeSearchParams(
1189
+ parser(ctx),
1190
+ ctx.req.method as never,
453
1191
  )
454
1192
  : parser(ctx),
455
1193
  );
@@ -502,23 +1240,7 @@ export const createRouteMiddleware: CreateRouteMiddleware<
502
1240
  * */
503
1241
  use(
504
1242
  function useValidateParams(ctx, next) {
505
- const matched = matchPath(ctx.req.path);
506
- const normalizedParams = params.reduce(
507
- (map: Record<string, unknown>, name) => {
508
- const value = matched ? matched.params[name] : undefined;
509
- if (Array.isArray(value)) {
510
- map[name] = numericProperties.params.includes(name)
511
- ? value.map((e) => maybeNumber(e))
512
- : value;
513
- } else if (value) {
514
- map[name] = numericProperties.params.includes(name)
515
- ? maybeNumber(value)
516
- : value;
517
- }
518
- return map;
519
- },
520
- {},
521
- );
1243
+ const normalizedParams = normalizeParams(ctx.req.path);
522
1244
  validationSchemas.params?.validate(normalizedParams);
523
1245
  ctx[StateKey].set("params", normalizedParams);
524
1246
  return next();
@@ -746,32 +1468,21 @@ export const routes = createRoutes<ParameterizedMiddleware, MiddlewareHandler>(
746
1468
  createRouteMiddleware,
747
1469
  },
748
1470
  );
749
-
750
- export const routerFactory: RouterFactory<Router<never>, never> = (factory) => {
751
- const createRouter = () => {
752
- return new SmartRouter({
753
- routers: [new RegExpRouter(), new TrieRouter()],
754
- }) as Router<never>;
755
- };
756
- return factory({ createRouter });
757
- };
758
- `,V=`import { join } from "node:path";
1471
+ `,Fe=`import { join } from "node:path";
759
1472
 
760
1473
  import type { RouteSource } from "@kosmojs/core/api";
761
1474
 
762
- import { base, apiBase } from "{{ createImport 'libCore' }}";
1475
+ import { base, apiBase, apiRouteMap, apiRouteMapper } from "{{ createImport 'libCore' }}";
763
1476
 
764
1477
  {{#each routes}}
765
1478
  import {{id}} from "{{ createImport 'api' file }}";
766
- import { validationSchemas as {{id}}_schemas } from "{{ createImport 'libApi' name 'schemas' }}";
1479
+ import { validationSchemas as {{id}}_schemas } from "{{ createImport 'libApi' basename 'schemas' }}";
767
1480
  {{/each}}
768
1481
 
769
1482
  {{#each cascadingMiddleware}}
770
1483
  import {{id}}, { type UseT as UseT{{id}} } from "{{ createImport 'api' file }}";
771
1484
  {{/each}}
772
1485
 
773
- type Override<A, B> = Omit<A, keyof B> & B;
774
-
775
1486
  export type RouteMap = {
776
1487
  {{#each routes}}
777
1488
  "{{name}}": {
@@ -785,14 +1496,16 @@ export type RouteMap = {
785
1496
  export const routeSources: Array<RouteSource<never>> = [
786
1497
  {{#each routes}}
787
1498
  {
788
- name: "{{name}}",
789
- {{#if fullpath}}
790
- path: "{{fullpath}}",
791
- pathPattern: "{{fullpath}}",
1499
+ {{#if alias}}
1500
+ ...apiRouteMapper(apiBase, { ...{{serializeApiRoute .}}, pathPattern: "{{alias}}" }),
1501
+ path: "{{alias}}",
1502
+ pathPattern: "{{alias}}",
792
1503
  {{else}}
1504
+ ...apiRouteMap["{{name}}"],
793
1505
  path: join(base, apiBase, "{{path}}"),
794
1506
  pathPattern: join(base, apiBase, "{{pathPattern}}"),
795
1507
  {{/if}}
1508
+ name: "{{name}}",
796
1509
  file: "{{file}}",
797
1510
  cascadingMiddleware: [ {{#each cascadingMiddleware}}{{id}}, {{/each}}].flat() as Array<never>,
798
1511
  definitionItems: {{id}} as never,
@@ -800,52 +1513,48 @@ export const routeSources: Array<RouteSource<never>> = [
800
1513
  },
801
1514
  {{/each}}
802
1515
  ];
803
- `,pe=`import { chmod, unlink } from "node:fs/promises";
1516
+ `,Ie=`import { chmod, unlink } from "node:fs/promises";
804
1517
  import { parseArgs, styleText } from "node:util";
805
1518
 
806
1519
  import { createAdaptorServer } from "@hono/node-server";
807
1520
 
808
- import type { ServerFactory } from "@kosmojs/core/api";
809
-
810
1521
  import type { App } from "./app";
811
1522
 
812
- export const serverFactory: ServerFactory<App> = (factory) => {
813
- const { values } = parseArgs({
814
- options: {
815
- port: {
816
- type: "string",
817
- short: "p",
818
- },
819
- sock: {
820
- type: "string",
821
- short: "s",
822
- },
823
- },
824
- });
825
-
826
- const getListenHandles = async () => {
827
- const { port, sock } = { ...values };
1523
+ type Handles = {
1524
+ port?: number | undefined;
1525
+ sock?: string | undefined;
1526
+ onListen?: () => Promise<void>;
1527
+ };
828
1528
 
829
- if (![port, sock].some(Boolean)) {
830
- console.error("Please provide either -p/--port number or -s/--sock path");
831
- process.exit(1);
832
- }
1529
+ const getListenHandles = async (opt?: Handles) => {
1530
+ const { port, sock } = opt
1531
+ ? opt
1532
+ : parseArgs({
1533
+ options: {
1534
+ port: {
1535
+ type: "string",
1536
+ short: "p",
1537
+ },
1538
+ sock: {
1539
+ type: "string",
1540
+ short: "s",
1541
+ },
1542
+ },
1543
+ }).values;
833
1544
 
834
- if (sock) {
835
- await unlink(sock).catch((error) => {
836
- if (error.code === "ENOENT") {
837
- return;
838
- }
839
- console.error(error.message);
840
- process.exit(1);
841
- });
842
- }
1545
+ if (![port, sock].some(Boolean)) {
1546
+ throw new Error("Please provide either -p/--port number or -s/--sock path");
1547
+ }
843
1548
 
844
- return { port, sock };
845
- };
1549
+ if (sock) {
1550
+ await unlink(sock).catch((error) => {
1551
+ if (error.code !== "ENOENT") {
1552
+ throw error;
1553
+ }
1554
+ });
1555
+ }
846
1556
 
847
1557
  const onListen = async () => {
848
- const { port, sock } = await getListenHandles();
849
1558
  if (sock) {
850
1559
  // Make Unix socket world-writable so other processes (e.g. a reverse proxy)
851
1560
  // can connect without permission issues.
@@ -857,50 +1566,39 @@ export const serverFactory: ServerFactory<App> = (factory) => {
857
1566
  );
858
1567
  };
859
1568
 
860
- return factory({
861
- async createServer(app) {
862
- const { port, sock } = await getListenHandles();
863
-
864
- if (typeof Bun !== "undefined") {
865
- const server = Bun.serve(
866
- sock
867
- ? { unix: sock, fetch: app.fetch }
868
- : { port: Number(port), fetch: app.fetch },
869
- );
870
- await onListen();
871
- return server as never;
872
- }
873
-
874
- if (typeof Deno !== "undefined") {
875
- const server = sock
876
- ? Deno.serve({ path: sock, onListen }, app.fetch)
877
- : Deno.serve({ port: Number(port), onListen }, app.fetch);
878
- return server as never;
879
- }
1569
+ return {
1570
+ port: Number(port),
1571
+ sock,
1572
+ onListen: opt?.onListen || onListen,
1573
+ };
1574
+ };
880
1575
 
881
- const server = createAdaptorServer(app);
882
- server.listen(sock || port, onListen);
1576
+ export const serve = async <T extends App>(app: T, opt?: Handles) => {
1577
+ const { port, sock, onListen } = await getListenHandles(opt);
883
1578
 
884
- return server as never;
885
- },
886
- getListenHandles,
887
- onListen,
888
- });
889
- };
1579
+ if (typeof Bun !== "undefined") {
1580
+ const server = Bun.serve(
1581
+ sock
1582
+ ? { unix: sock, fetch: app.fetch }
1583
+ : { port: Number(port), fetch: app.fetch },
1584
+ );
1585
+ await onListen();
1586
+ return server as never;
1587
+ }
890
1588
 
891
- process.on("unhandledRejection", (reason) => {
892
- console.error("💥 UNHANDLED REJECTION - This is likely caused by:");
893
- console.error(" - Middleware not awaiting next()");
894
- console.error(" - Middleware not returning next()");
895
- console.error("");
896
- console.error("Reason:", reason);
897
- console.error("");
898
- // In development, crash hard
899
- if (process.env.NODE_ENV === "development") {
900
- process.exit(1);
1589
+ if (typeof Deno !== "undefined") {
1590
+ const server = sock
1591
+ ? Deno.serve({ path: sock, onListen }, app.fetch)
1592
+ : Deno.serve({ port: Number(port), onListen }, app.fetch);
1593
+ return server as never;
901
1594
  }
902
- });
903
- `,me=`import type { Context, Next } from "hono";
1595
+
1596
+ const server = createAdaptorServer(app);
1597
+ server.listen(sock || port, onListen);
1598
+
1599
+ return server as never;
1600
+ };
1601
+ `,Le=`import type { Context, Next } from "hono";
904
1602
 
905
1603
  import type { ValidationDefmap, ValidationOptmap } from "@kosmojs/core";
906
1604
  import {
@@ -1083,29 +1781,20 @@ export const defineRoute: <
1083
1781
  use: use as never,
1084
1782
  });
1085
1783
  };
1086
- `,he=`export * from "./@api/app";
1784
+ `,Re=`export * from "./@api/app";
1785
+ export { appFactory as default } from "./@api/app";
1087
1786
  export * from "./@api/dev";
1088
1787
  export * from "./@api/errors";
1089
1788
  export * from "./@api/router";
1090
1789
  export * from "./@api/routes";
1091
1790
  export * from "./@api/server";
1092
- `,ge=`import defaultErrorHandler from "./errors";
1093
- import router from "./router";
1094
-
1095
- import { appFactory, routes } from "{{ createImport 'lib' 'api:factory' }}";
1096
-
1097
- export default appFactory(({ createApp }) => {
1098
- const app = createApp({ router });
1791
+ `,ze=`import appFactory, { routes } from "{{ createImport 'lib' 'api:factory' }}";
1792
+ import defaultErrorHandler from "./errors";
1099
1793
 
1794
+ export default appFactory(routes, ({ app }) => {
1100
1795
  app.onError(defaultErrorHandler);
1101
-
1102
- for (const { path, methods, middleware } of routes) {
1103
- app.on(methods, [path], ...middleware);
1104
- }
1105
-
1106
- return app;
1107
- });
1108
- `,_e=`import { getRequestListener } from "@hono/node-server";
1796
+ })
1797
+ `,Be=`import { getRequestListener } from "@hono/node-server";
1109
1798
 
1110
1799
  import app from "./app";
1111
1800
 
@@ -1119,45 +1808,50 @@ export default devSetup({
1119
1808
  // close db connections, server sockets etc.
1120
1809
  },
1121
1810
  });
1122
- `,ve=`export declare module "{{ createImport 'libApi' }}" {
1811
+
1812
+ process.on("unhandledRejection", (reason) => {
1813
+ console.error("💥 UNHANDLED REJECTION");
1814
+ console.error("Reason:", reason);
1815
+ process.exit(1);
1816
+ });
1817
+
1818
+ `,Ve=`export declare module "{{ createImport 'libApi' }}" {
1123
1819
  interface DefaultVariables {}
1124
1820
  interface DefaultBindings {}
1125
1821
  }
1126
- `,ye=`import { accepts } from "hono/accepts";
1822
+ `,He=`import { accepts } from "hono/accepts";
1127
1823
  import { HTTPException } from "hono/http-exception";
1128
1824
 
1129
1825
  import { ValidationError, HTTPError } from "@kosmojs/core/errors";
1130
1826
 
1131
1827
  import { errorHandlerFactory } from "{{ createImport 'lib' 'api:factory' }}";
1132
1828
 
1133
- export default errorHandlerFactory(
1134
- async function defaultErrorHandler(error, ctx) {
1135
- // Let Hono's HTTPException handle its own response
1136
- if (error instanceof HTTPException) {
1137
- return error.getResponse();
1138
- }
1829
+ export default errorHandlerFactory(async (error, ctx) => {
1830
+ // Let Hono's HTTPException handle its own response
1831
+ if (error instanceof HTTPException) {
1832
+ return error.getResponse();
1833
+ }
1139
1834
 
1140
- const [status, message] = Array.isArray(error)
1141
- ? error
1142
- : error instanceof HTTPError
1143
- ? [error.status, error.message]
1144
- : error instanceof ValidationError
1145
- ? [400, \`\${error.target}: \${error.errorMessage}\`]
1146
- : [error.statusCode || 500, error.message];
1147
-
1148
- // Respond based on what the client accepts
1149
- const type = accepts(ctx, {
1150
- header: "Accept",
1151
- supports: ["application/json", "text/plain"],
1152
- default: "text/plain",
1153
- });
1835
+ const [status, message] = Array.isArray(error)
1836
+ ? error
1837
+ : error instanceof HTTPError
1838
+ ? [error.status, error.message]
1839
+ : error instanceof ValidationError
1840
+ ? [400, \`\${error.target}: \${error.errorMessage}\`]
1841
+ : [error.statusCode || 500, error.message];
1842
+
1843
+ // Respond based on what the client accepts
1844
+ const type = accepts(ctx, {
1845
+ header: "Accept",
1846
+ supports: ["application/json", "text/plain"],
1847
+ default: "text/plain",
1848
+ });
1154
1849
 
1155
- return type === "application/json"
1156
- ? ctx.json({ error: message }, status)
1157
- : ctx.text(message, status);
1158
- },
1159
- );
1160
- `,be=`import { defineRoute } from "{{ createImport 'libApi' }}";
1850
+ return type === "application/json"
1851
+ ? ctx.json({ error: message }, status)
1852
+ : ctx.text(message, status);
1853
+ });
1854
+ `,Ue=`import { defineRoute } from "{{ createImport 'libApi' }}";
1161
1855
 
1162
1856
  export default defineRoute<"{{route.name}}">(({ GET }) => [
1163
1857
  GET(async (ctx) => {
@@ -1166,7 +1860,7 @@ export default defineRoute<"{{route.name}}">(({ GET }) => [
1166
1860
  return ctx.text("Automatically generated route");
1167
1861
  }),
1168
1862
  ]);
1169
- `,xe=`import { use } from "{{ createImport 'libApi' }}";
1863
+ `,We=`import { use } from "{{ createImport 'libApi' }}";
1170
1864
 
1171
1865
  export type UseT = {};
1172
1866
 
@@ -1177,20 +1871,11 @@ export default [
1177
1871
  return next();
1178
1872
  }),
1179
1873
  ];
1180
- `,Se=`import { routerFactory } from "{{ createImport 'lib' 'api:factory' }}";
1181
-
1182
- export default routerFactory(({ createRouter }) => {
1183
- const router = createRouter();
1184
- return router;
1185
- });
1186
- `,Ce=`import app from "./app";
1187
-
1188
- import { serverFactory } from "{{ createImport 'lib' 'api:factory' }}";
1874
+ `,Ge=`import { serve } from "{{ createImport 'lib' 'api:factory' }}";
1875
+ import app from "./app";
1189
1876
 
1190
- serverFactory(async ({ createServer }) => {
1191
- await createServer(app);
1192
- });
1193
- `,we=`import { use } from "{{ createImport 'libApi' }}";
1877
+ await serve(app);
1878
+ `,Ke=`import { use } from "{{ createImport 'libApi' }}";
1194
1879
 
1195
1880
  /**
1196
1881
  * Define global middleware applied to all routes.
@@ -1201,9 +1886,10 @@ export default [
1201
1886
  return next();
1202
1887
  }),
1203
1888
  ];
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";
1889
+ `,qe=g((e,n)=>{let{createPath:r,createImportHelpers:i}=y(e),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=x({helpers:{...i({origin:`lib`}),...w(),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:s}=x({helpers:i({origin:`src`})}),l=e=>e?.trim().length===0,u=c(n?.templates,Ue),f=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await s(r.api(n.file),u(n.name,n),{route:n},{overwrite:l}):t===`apiUse`&&await s(r.api(n.file),We,{},{overwrite:l})},m=async e=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=e.flatMap(({kind:e,entry:r})=>{if(e!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((e,n)=>{let r=e[e.length-1];return e.push(r?t(r,n):n),e},[]),o={...r,path:r.honoPattern,basename:r.name,cascadingMiddleware:i.flatMap(e=>a.some(t=>e.name===t)?[e]:[])};return[o,...Object.entries({...n?.alias}).flatMap(([e,t])=>{let n=b(e);return t===r.name?[{...o,name:e,basename:r.name,id:`${o.id}_${T(e)}`,alias:d(n),pathTokens:n}]:[]})]}).sort(S);for(let[e,t]of[[`@api/routes.ts`,Fe]])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`,Le],[`api:factory.ts`,Re],[`@api/app.ts`,Ae],[`@api/parsers.ts`,Ne],[`@api/dev.ts`,je],[`@api/errors.ts`,Me],[`@api/router.ts`,Pe],[`@api/server.ts`,Ie]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,ze],[`dev.ts`,Be],[`errors.ts`,He],[`server.ts`,Ge],[`use.ts`,Ke],[`env.d.ts`,Ve]])await s(r.api(e),t,{},{overwrite:l})},async watch(e,t){await f(e.filter(p(t,[`create`]))),await m(e)},async build(e){await f(e),await m(e)}}}),Je=h({meta:{name:`Hono`,slot:`backend`},dependencies:{hono:V.devDependencies.hono,"@hono/node-server":V.devDependencies[`@hono/node-server`]},factory:qe}),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`,"raw-body":`^4.0.0`,vite:`^8.2.2`}},Ye=`import Router, { type RouterMiddleware } from "@koa/router";
1890
+ import Koa from "koa";
1205
1891
 
1206
- import type { AppFactory } from "@kosmojs/core/api";
1892
+ import type { Route, RouteDebugOption } from "@kosmojs/core/api";
1207
1893
 
1208
1894
  import type { DefaultContext, DefaultState } from "../api";
1209
1895
 
@@ -1211,27 +1897,75 @@ export type App = Koa<DefaultState, DefaultContext>;
1211
1897
 
1212
1898
  export type AppOptions = ConstructorParameters<
1213
1899
  typeof Koa<DefaultState, DefaultContext>
1214
- >[0];
1900
+ >[0] & { router?: Router; debug?: RouteDebugOption };
1901
+
1902
+ export function appFactory(
1903
+ routes: Array<Route<RouterMiddleware>>,
1904
+ options: AppOptions,
1905
+ ): App;
1906
+
1907
+ export function appFactory(
1908
+ routes: Array<Route<RouterMiddleware>>,
1909
+ fn: (a: { app: App; router: Router<never> }) => void,
1910
+ ): App;
1911
+
1912
+ export function appFactory(
1913
+ routes: Array<Route<RouterMiddleware>>,
1914
+ options: AppOptions,
1915
+ fn: (a: { app: App; router: Router<never> }) => void,
1916
+ ): App;
1917
+
1918
+ export function appFactory(
1919
+ routes: Array<Route<RouterMiddleware>>,
1920
+ ...rest: Array<unknown>
1921
+ ): App {
1922
+ const [options, fn] = typeof rest[0] === "function" ? [{}, rest[0]] : rest;
1215
1923
 
1216
- export const appFactory: AppFactory<App, AppOptions> = (factory) => {
1217
- const createApp = (options?: AppOptions) => {
1218
- return new Koa(options);
1924
+ const {
1925
+ router = new Router(),
1926
+ debug = undefined,
1927
+ ...appOptions
1928
+ } = {
1929
+ ...(options ? { ...options } : {}),
1219
1930
  };
1220
- return factory({ createApp });
1221
- };
1222
- `,Oe=`import type { DevSetup } from "@kosmojs/core/api";
1931
+
1932
+ for (const route of routes) {
1933
+ if (typeof debug === "function") {
1934
+ (debug as Function)(route.debug, route);
1935
+ } else if (debug) {
1936
+ console.log(route.debug[typeof debug === "string" ? debug : "full"]);
1937
+ }
1938
+ router.register(route.path, route.methods, route.middleware, route);
1939
+ }
1940
+
1941
+ const app = new Koa(appOptions);
1942
+
1943
+ if (typeof fn === "function") {
1944
+ fn({ app, router });
1945
+ }
1946
+
1947
+ return app;
1948
+ }
1949
+ `,Xe=`import type { DevSetup } from "@kosmojs/core/api";
1223
1950
 
1224
1951
  export const devSetup = (setup: DevSetup) => setup;
1225
- `,ke=`import type { ParameterizedMiddleware } from "../api";
1952
+ `,Ze=`import type {
1953
+ DefaultContext,
1954
+ DefaultState,
1955
+ ParameterizedContext,
1956
+ } from "../api";
1226
1957
 
1227
- export type ErrorHandlerFactory = (
1228
- h: ParameterizedMiddleware,
1229
- ) => ParameterizedMiddleware;
1958
+ type ErrorHandler = (
1959
+ error: any,
1960
+ ctx: ParameterizedContext<unknown, DefaultState, DefaultContext>,
1961
+ ) => Promise<void> | void;
1962
+
1963
+ export type ErrorHandlerFactory = (handler: ErrorHandler) => ErrorHandler;
1230
1964
 
1231
1965
  export const errorHandlerFactory: ErrorHandlerFactory = (handler) => {
1232
1966
  return handler;
1233
1967
  };
1234
- `,Ae=`import zlib from "node:zlib";
1968
+ `,Qe=`import zlib from "node:zlib";
1235
1969
 
1236
1970
  import type { RouterContext } from "@koa/router";
1237
1971
  import Formidable, { type Options as FormidableOptions } from "formidable";
@@ -1444,8 +2178,7 @@ export const bodyparsers: {
1444
2178
  return rawParser(stream, rawParserOptions);
1445
2179
  },
1446
2180
  };
1447
- `,je=`import KoaRouter, { type RouterMiddleware } from "@koa/router";
1448
- import { match } from "path-to-regexp";
2181
+ `,$e=`import type { RouterMiddleware } from "@koa/router";
1449
2182
 
1450
2183
  import type {
1451
2184
  RequestBodyTarget,
@@ -1457,7 +2190,6 @@ import {
1457
2190
  type CreateRouteMiddleware,
1458
2191
  createRoutes,
1459
2192
  type HTTPMethod,
1460
- type RouterFactory,
1461
2193
  StateKey,
1462
2194
  } from "@kosmojs/core/api";
1463
2195
  import { ValidationError } from "@kosmojs/core/errors";
@@ -1473,10 +2205,6 @@ import { type BodyparserOptions, bodyparsers, metaparsers } from "./parsers";
1473
2205
  import { routeSources } from "./routes";
1474
2206
 
1475
2207
  import globalMiddleware from "{{ createImport 'api' 'use' }}";
1476
- import { apiRouteMap } from "{{ createImport 'libCore' }}";
1477
-
1478
- export type Router = import("@koa/router").Router<DefaultState, DefaultContext>;
1479
- export type RouterOptions = import("@koa/router").RouterOptions;
1480
2208
 
1481
2209
  /**
1482
2210
  * Create route-level middleware stack that handles:
@@ -1493,33 +2221,7 @@ export type RouterOptions = import("@koa/router").RouterOptions;
1493
2221
  * */
1494
2222
  export const createRouteMiddleware: CreateRouteMiddleware<
1495
2223
  ParameterizedMiddleware
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
-
1505
- const pathMatcher = match(pathPattern);
1506
-
1507
- const matchPath = (path: string) => {
1508
- try {
1509
- return pathMatcher(path);
1510
- } catch (e) {
1511
- return undefined;
1512
- }
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
-
2224
+ > = ({ name, validationSchemas, normalizeParams, normalizeSearchParams }) => {
1523
2225
  const validationMiddleware = [
1524
2226
  /**
1525
2227
  * Extends Koa context with:
@@ -1560,16 +2262,7 @@ export const createRouteMiddleware: CreateRouteMiddleware<
1560
2262
  ctx[StateKey].set(
1561
2263
  target,
1562
2264
  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
- )
2265
+ ? normalizeSearchParams(parser(ctx), ctx.method as never)
1573
2266
  : parser(ctx),
1574
2267
  );
1575
2268
  }
@@ -1621,23 +2314,7 @@ export const createRouteMiddleware: CreateRouteMiddleware<
1621
2314
  * */
1622
2315
  use(
1623
2316
  function useValidateParams(ctx, next) {
1624
- const matched = matchPath(ctx.path);
1625
- const normalizedParams = params.reduce(
1626
- (map: Record<string, unknown>, name) => {
1627
- const value = matched ? matched.params[name] : undefined;
1628
- if (Array.isArray(value)) {
1629
- map[name] = numericProperties.params.includes(name)
1630
- ? value.map((e) => maybeNumber(e))
1631
- : value;
1632
- } else if (value) {
1633
- map[name] = numericProperties.params.includes(name)
1634
- ? maybeNumber(value)
1635
- : value;
1636
- }
1637
- return map;
1638
- },
1639
- {},
1640
- );
2317
+ const normalizedParams = normalizeParams(ctx.path);
1641
2318
  validationSchemas.params?.validate(normalizedParams);
1642
2319
  ctx[StateKey].set("params", normalizedParams);
1643
2320
  return next();
@@ -1866,32 +2543,21 @@ export const routes = createRoutes<ParameterizedMiddleware, RouterMiddleware>(
1866
2543
  createRouteMiddleware,
1867
2544
  },
1868
2545
  );
1869
-
1870
- export const routerFactory: RouterFactory<Router, RouterOptions> = (
1871
- factory,
1872
- ) => {
1873
- const createRouter = (options?: RouterOptions): Router => {
1874
- return new KoaRouter(options);
1875
- };
1876
- return factory({ createRouter });
1877
- };
1878
- `,Me=`import { join } from "node:path";
2546
+ `,et=`import { join } from "node:path";
1879
2547
 
1880
2548
  import type { RouteSource } from "@kosmojs/core/api";
1881
2549
 
1882
- import { base, apiBase } from "{{ createImport 'libCore' }}";
2550
+ import { base, apiBase, apiRouteMap, apiRouteMapper } from "{{ createImport 'libCore' }}";
1883
2551
 
1884
2552
  {{#each routes}}
1885
2553
  import {{id}} from "{{ createImport 'api' file }}";
1886
- import { validationSchemas as {{id}}_schemas } from "{{ createImport 'libApi' name 'schemas' }}";
2554
+ import { validationSchemas as {{id}}_schemas } from "{{ createImport 'libApi' basename 'schemas' }}";
1887
2555
  {{/each}}
1888
2556
 
1889
2557
  {{#each cascadingMiddleware}}
1890
2558
  import {{id}}, { type UseT as UseT{{id}} } from "{{ createImport 'api' file }}";
1891
2559
  {{/each}}
1892
2560
 
1893
- type Override<A, B> = Omit<A, keyof B> & B;
1894
-
1895
2561
  export type RouteMap = {
1896
2562
  {{#each routes}}
1897
2563
  "{{name}}": {
@@ -1905,65 +2571,63 @@ export type RouteMap = {
1905
2571
  export const routeSources: Array<RouteSource<never>> = [
1906
2572
  {{#each routes}}
1907
2573
  {
1908
- name: "{{name}}",
1909
- {{#if fullpath}}
1910
- path: "{{fullpath}}",
1911
- pathPattern: "{{fullpath}}",
2574
+ {{#if alias}}
2575
+ ...apiRouteMapper(apiBase, { ...{{serializeApiRoute .}}, pathPattern: "{{alias}}" }),
2576
+ path: "{{alias}}",
2577
+ pathPattern: "{{alias}}",
1912
2578
  {{else}}
2579
+ ...apiRouteMap["{{name}}"],
1913
2580
  path: join(base, apiBase, "{{path}}"),
1914
2581
  pathPattern: join(base, apiBase, "{{pathPattern}}"),
1915
2582
  {{/if}}
2583
+ name: "{{name}}",
1916
2584
  file: "{{file}}",
1917
2585
  cascadingMiddleware: [ {{#each cascadingMiddleware}}{{id}}, {{/each}}].flat() as Array<never>,
1918
2586
  definitionItems: {{id}} as never,
1919
2587
  validationSchemas: {{id}}_schemas,
1920
2588
  },
1921
2589
  {{/each}}
1922
- ] as const;
1923
- `,Ne=`import { chmod, unlink } from "node:fs/promises";
2590
+ ];
2591
+ `,tt=`import { chmod, unlink } from "node:fs/promises";
1924
2592
  import { parseArgs, styleText } from "node:util";
1925
2593
 
1926
- import type { ServerFactory } from "@kosmojs/core/api";
1927
-
1928
2594
  import type { App } from "./app";
1929
2595
 
1930
- export const serverFactory: ServerFactory<App> = (factory) => {
1931
- const { values } = parseArgs({
1932
- options: {
1933
- port: {
1934
- type: "string",
1935
- short: "p",
1936
- },
1937
- sock: {
1938
- type: "string",
1939
- short: "s",
1940
- },
1941
- },
1942
- });
1943
-
1944
- const getListenHandles = async () => {
1945
- const { port, sock } = { ...values };
2596
+ type Handles = {
2597
+ port?: number | undefined;
2598
+ sock?: string | undefined;
2599
+ onListen?: () => Promise<void>;
2600
+ };
1946
2601
 
1947
- if (![port, sock].some(Boolean)) {
1948
- console.error("Please provide either -p/--port number or -s/--sock path");
1949
- process.exit(1);
1950
- }
2602
+ const getListenHandles = async (opt?: Handles): Promise<Handles> => {
2603
+ const { port, sock } = opt
2604
+ ? opt
2605
+ : parseArgs({
2606
+ options: {
2607
+ port: {
2608
+ type: "string",
2609
+ short: "p",
2610
+ },
2611
+ sock: {
2612
+ type: "string",
2613
+ short: "s",
2614
+ },
2615
+ },
2616
+ }).values;
1951
2617
 
1952
- if (sock) {
1953
- await unlink(sock).catch((error) => {
1954
- if (error.code === "ENOENT") {
1955
- return;
1956
- }
1957
- console.error(error.message);
1958
- process.exit(1);
1959
- });
1960
- }
2618
+ if (![port, sock].some(Boolean)) {
2619
+ throw new Error("Please provide either -p/--port number or -s/--sock path");
2620
+ }
1961
2621
 
1962
- return { port, sock };
1963
- };
2622
+ if (sock) {
2623
+ await unlink(sock).catch((error) => {
2624
+ if (error.code !== "ENOENT") {
2625
+ throw error;
2626
+ }
2627
+ });
2628
+ }
1964
2629
 
1965
2630
  const onListen = async () => {
1966
- const { port, sock } = await getListenHandles();
1967
2631
  if (sock) {
1968
2632
  // Make Unix socket world-writable so other processes (e.g. a reverse proxy)
1969
2633
  // can connect without permission issues.
@@ -1975,30 +2639,19 @@ export const serverFactory: ServerFactory<App> = (factory) => {
1975
2639
  );
1976
2640
  };
1977
2641
 
1978
- return factory({
1979
- async createServer(app) {
1980
- const { port, sock } = await getListenHandles();
1981
- const server = app.listen(port || sock, onListen);
1982
- return server as never;
1983
- },
1984
- getListenHandles,
1985
- onListen,
1986
- });
2642
+ return {
2643
+ port: port ? Number(port) : undefined,
2644
+ sock,
2645
+ onListen: opt?.onListen || onListen,
2646
+ };
1987
2647
  };
1988
2648
 
1989
- process.on("unhandledRejection", (reason) => {
1990
- console.error("💥 UNHANDLED REJECTION - This is likely caused by:");
1991
- console.error(" - Middleware not awaiting next()");
1992
- console.error(" - Middleware not returning next()");
1993
- console.error("");
1994
- console.error("Reason:", reason);
1995
- console.error("");
1996
- // In development, crash hard
1997
- if (process.env.NODE_ENV === "development") {
1998
- process.exit(1);
1999
- }
2000
- });
2001
- `,Pe=`import type { RouterContext } from "@koa/router";
2649
+ export const serve = async <T extends App>(app: T, opt?: Handles) => {
2650
+ const { port, sock, onListen } = await getListenHandles(opt);
2651
+ const server = app.listen(port || sock, onListen);
2652
+ return server as never;
2653
+ };
2654
+ `,nt=`import type { RouterContext } from "@koa/router";
2002
2655
  import type { Next } from "koa";
2003
2656
 
2004
2657
  import type { ValidationDefmap, ValidationOptmap } from "@kosmojs/core";
@@ -2160,25 +2813,25 @@ export const defineRoute: <
2160
2813
  use: use as never,
2161
2814
  });
2162
2815
  };
2163
- `,Fe=`export * from "./@api/app";
2816
+ `,rt=`export * from "./@api/app";
2817
+ export { appFactory as default } from "./@api/app";
2164
2818
  export * from "./@api/dev";
2165
2819
  export * from "./@api/errors";
2166
2820
  export * from "./@api/router";
2167
2821
  export * from "./@api/routes";
2168
2822
  export * from "./@api/server";
2169
- `,Ie=`import router from "./router";
2823
+ `,it=`import appFactory, { routes } from "{{ createImport 'lib' 'api:factory' }}";
2824
+ import defaultErrorHandler from "./errors";
2170
2825
 
2171
- import { appFactory } from "{{ createImport 'lib' 'api:factory' }}";
2826
+ export default appFactory(routes, ({ app, router }) => {
2172
2827
 
2173
- export default appFactory(({ createApp }) => {
2174
- const app = createApp();
2828
+ app.on("error", defaultErrorHandler);
2175
2829
 
2176
2830
  // NOTE: Routes should be added last, after any middleware
2177
2831
  app.use(router.routes());
2178
2832
 
2179
- return app;
2180
2833
  });
2181
- `,Le=`import app from "./app";
2834
+ `,at=`import app from "./app";
2182
2835
 
2183
2836
  import { devSetup } from "{{ createImport 'lib' 'api:factory' }}";
2184
2837
 
@@ -2190,45 +2843,45 @@ export default devSetup({
2190
2843
  // close db connections, server sockets etc.
2191
2844
  },
2192
2845
  });
2193
- `,Re=`export declare module "{{ createImport 'libApi' }}" {
2846
+
2847
+ process.on("unhandledRejection", (reason) => {
2848
+ console.error("💥 UNHANDLED REJECTION");
2849
+ console.error("Reason:", reason);
2850
+ process.exit(1);
2851
+ });
2852
+ `,ot=`export declare module "{{ createImport 'libApi' }}" {
2194
2853
  interface DefaultState {}
2195
2854
  interface DefaultContext {}
2196
2855
  }
2197
- `,ze=`import { HTTPError, ValidationError } from "@kosmojs/core/errors";
2856
+ `,st=`import { HTTPError, ValidationError } from "@kosmojs/core/errors";
2198
2857
 
2199
2858
  import { errorHandlerFactory } from "{{ createImport 'lib' 'api:factory' }}";
2200
2859
 
2201
- export default errorHandlerFactory(
2202
- async function defaultErrorHandler(ctx, next) {
2203
- try {
2204
- await next();
2205
- } catch (error: any) {
2206
- const [status, message] = Array.isArray(error)
2207
- ? error
2208
- : error instanceof HTTPError
2209
- ? [error.status, error.message]
2210
- : error instanceof ValidationError
2211
- ? [400, \`\${error.target}: \${error.errorMessage}\`]
2212
- : [error.statusCode || 500, error.message];
2213
-
2214
- ctx.status = status;
2215
-
2216
- if (ctx.accepts("json")) {
2217
- ctx.body = { error: message };
2218
- } else {
2219
- ctx.body = message;
2220
- }
2221
- }
2222
- },
2223
- );
2224
- `,Be=`import { defineRoute } from "{{ createImport 'libApi' }}";
2860
+ export default errorHandlerFactory(async (error, ctx) => {
2861
+ const [status, message] = Array.isArray(error)
2862
+ ? error
2863
+ : error instanceof HTTPError
2864
+ ? [error.status, error.message]
2865
+ : error instanceof ValidationError
2866
+ ? [400, \`\${error.target}: \${error.errorMessage}\`]
2867
+ : [error.statusCode || 500, error.message];
2868
+
2869
+ ctx.status = status;
2870
+
2871
+ if (ctx.accepts("json")) {
2872
+ ctx.body = { error: message };
2873
+ } else {
2874
+ ctx.body = message;
2875
+ }
2876
+ });
2877
+ `,ct=`import { defineRoute } from "{{ createImport 'libApi' }}";
2225
2878
 
2226
2879
  export default defineRoute<"{{route.name}}">(({ GET }) => [
2227
2880
  GET(async (ctx) => {
2228
2881
  ctx.body = "Automatically generated route";
2229
2882
  }),
2230
2883
  ]);
2231
- `,Ve=`import { use } from "{{ createImport 'libApi' }}";
2884
+ `,lt=`import { use } from "{{ createImport 'libApi' }}";
2232
2885
 
2233
2886
  export type UseT = {};
2234
2887
 
@@ -2239,46 +2892,32 @@ export default [
2239
2892
  return next();
2240
2893
  }),
2241
2894
  ];
2242
- `,He=`import { routerFactory, routes } from "{{ createImport 'lib' 'api:factory' }}";
2243
-
2244
- export default routerFactory(({ createRouter }) => {
2245
- const router = createRouter();
2246
-
2247
- for (const { name, path, methods, middleware } of routes) {
2248
- router.register(path, methods, middleware, { name });
2249
- }
2250
-
2251
- return router;
2252
- });
2253
- `,Ue=`import app from "./app";
2254
-
2255
- import { serverFactory } from "{{ createImport 'lib' 'api:factory' }}";
2256
-
2257
- serverFactory(async ({ createServer }) => {
2258
- await createServer(app);
2259
- });
2260
- `,We=`import defaultErrorHandler from "./errors";
2895
+ `,ut=`import { serve } from "{{ createImport 'lib' 'api:factory' }}";
2896
+ import app from "./app";
2261
2897
 
2262
- import { use } from "{{ createImport 'libApi' }}";
2898
+ await serve(app);
2899
+ `,dt=`import { use } from "{{ createImport 'libApi' }}";
2263
2900
 
2901
+ /**
2902
+ * Define global middleware applied to all routes.
2903
+ * Can be overridden on a per-route basis using the slot key.
2904
+ * */
2264
2905
  export default [
2265
- /**
2266
- * Define global middleware applied to all routes.
2267
- * Can be overridden on a per-route basis using the slot key.
2268
- * */
2269
- use(defaultErrorHandler, { slot: "errorHandler" }),
2906
+ use(async function useExample(ctx, next) {
2907
+ return next();
2908
+ }),
2270
2909
  ];
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,`
2910
+ `,ft=g((e,n)=>{let{createPath:r,createImportHelpers:i}=y(e),a=e=>e.length===0?`{}`:e.length===1?e[0]:`Override<${e[0]}, ${a(e.slice(1))}>`,{renderToFile:o}=x({helpers:{...i({origin:`lib`}),...w(),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:s}=x({helpers:i({origin:`src`})}),l=e=>e?.trim().length===0,u=c(n?.templates,ct),d=async e=>{for(let{kind:t,entry:n}of e)t===`apiRoute`?await s(r.api(n.file),u(n.name,n),{route:n},{overwrite:l}):t===`apiUse`&&await s(r.api(n.file),lt,{},{overwrite:l})},m=async e=>{let i=e.flatMap(({kind:e,entry:t})=>e===`apiUse`?[t]:[]),a=e.flatMap(({kind:e,entry:r})=>{if(e!==`apiRoute`)return[];let a=r.name.split(`/`).reduce((e,n)=>{let r=e[e.length-1];return e.push(r?t(r,n):n),e},[]),o={...r,basename:r.name,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=b(e);return t===r.name?[{...o,name:e,basename:r.name,id:`${o.id}_${T(e)}`,alias:f(n),pathTokens:n}]:[]})]}).sort(S);for(let[e,t]of[[`@api/routes.ts`,et]])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`,nt],[`api:factory.ts`,rt],[`@api/app.ts`,Ye],[`@api/dev.ts`,Xe],[`@api/errors.ts`,Ze],[`@api/parsers.ts`,Qe],[`@api/router.ts`,$e],[`@api/server.ts`,tt]])await o(r.lib(e),t,{});for(let[e,t]of[[`app.ts`,it],[`dev.ts`,at],[`errors.ts`,st],[`server.ts`,ut],[`use.ts`,dt],[`env.d.ts`,ot]])await s(r.api(e),t,{},{overwrite:l})},async watch(e,t){await d(e.filter(p(t,[`create`]))),await m(e)},async build(e){await d(e),await m(e)}}}),pt=h({meta:{name:`Koa`,slot:`backend`,types:[`@types/koa`]},dependencies:{koa:H.devDependencies.koa,"@koa/router":H.devDependencies[`@koa/router`],formidable:H.devDependencies.formidable,"raw-body":H.devDependencies[`raw-body`]},devDependencies:{"@types/koa":H.devDependencies[`@types/koa`],"@types/formidable":H.devDependencies[`@types/formidable`]},factory:ft}),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.2`},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`}},mt=()=>{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)]},ht=(e,t,n)=>{let{remarkPlugins:r=[],rehypePlugins:i=[]}={...n},a=()=>{let t=[`${l.srcDir}/${e.name}/${l.entryDir}/client.ts`].map(e=>re(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,`
2272
2911
  if (import.meta.hot) {
2273
2912
  import.meta.hot.accept(() => {});
2274
2913
  }
2275
2914
  `].join(`
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";
2915
+ `)}}}},o=[ne({jsxImportSource:`preact`,providerImportSource:`@mdx-js/preact`,remarkPlugins:r,rehypePlugins:i})];return t===`serve`&&o.push(a()),o},gt=`import type { FunctionComponent } from "preact";
2277
2916
 
2278
2917
  export const AppProvider: FunctionComponent = (props) => {
2279
2918
  return props.children;
2280
2919
  };
2281
- `,Xe=`import { render, hydrate as hydrateOrig } from "preact";
2920
+ `,_t=`import { render, hydrate as hydrateOrig } from "preact";
2282
2921
  import type { RouterFactoryReturn } from "@kosmojs/core";
2283
2922
  import { clientRenderFactory } from "@kosmojs/core/generators";
2284
2923
 
@@ -2319,7 +2958,7 @@ export const mount = async (
2319
2958
  }
2320
2959
 
2321
2960
  export default clientRenderFactory();
2322
- `,Ze=`import { renderToString as renderToStringOrig } from "preact-render-to-string";
2961
+ `,vt=`import { renderToString as renderToStringOrig } from "preact-render-to-string";
2323
2962
 
2324
2963
  import type {
2325
2964
  RenderToStringWrapper,
@@ -2393,7 +3032,7 @@ export const renderToString: RenderToStringWrapper<
2393
3032
  }
2394
3033
 
2395
3034
  export default serverRenderFactory<false>();
2396
- `,Qe=`declare module "*.mdx" {
3035
+ `,yt=`declare module "*.mdx" {
2397
3036
  import type { ComponentType } from "preact";
2398
3037
  export const frontmatter: Record<string, unknown>;
2399
3038
  const component: ComponentType;
@@ -2406,7 +3045,7 @@ declare module "*.md" {
2406
3045
  const component: ComponentType;
2407
3046
  export default component;
2408
3047
  }
2409
- `,$e=`import { MDXProvider } from "@mdx-js/preact";
3048
+ `,bt=`import { MDXProvider } from "@mdx-js/preact";
2410
3049
  import { match, pathToRegexp } from "path-to-regexp";
2411
3050
  import { type ComponentType, createContext, h, type VNode } from "preact";
2412
3051
 
@@ -2583,7 +3222,11 @@ export const createRoute = (
2583
3222
  loader: RawRoute["loader"],
2584
3223
  layouts: RawRoute["layouts"],
2585
3224
  ): RawRoute => {
2586
- const path = \`\${base}/\${pathPattern}\`.replace(/\\/+/g, "/");
3225
+ // strip trailing slash (keeping a sole "/") so the base-joined index route
3226
+ // matches both with and without it - "/docs/" as a pattern rejects "/docs"
3227
+ const path = \`\${base}/\${pathPattern}\`
3228
+ .replace(/\\/+/g, "/")
3229
+ .replace(/(.+)\\/$/, "$1");
2587
3230
 
2588
3231
  const { regexp } = pathToRegexp(path, { sensitive: true });
2589
3232
  const matcher = match<Route["params"]>(path);
@@ -2591,9 +3234,11 @@ export const createRoute = (
2591
3234
  return {
2592
3235
  name,
2593
3236
  regexp,
3237
+ // count segments of the same base-joined path the regexp matches against;
3238
+ // resolve() compares this against the full url pathname's segment count
2594
3239
  pathSegments: name.includes("...")
2595
3240
  ? undefined
2596
- : name.replace(/^index(\\/?|$)/, "").split("/").length,
3241
+ : path.split("/").filter(Boolean).length,
2597
3242
  extractParams: (path) => {
2598
3243
  const match = matcher(path);
2599
3244
  return match ? match.params : {};
@@ -2602,7 +3247,7 @@ export const createRoute = (
2602
3247
  layouts,
2603
3248
  };
2604
3249
  };
2605
- `,et=`/* @jsxImportSource preact */
3250
+ `,xt=`/* @jsxImportSource preact */
2606
3251
 
2607
3252
  import styles from "./styles.module.css";
2608
3253
 
@@ -2643,7 +3288,7 @@ export default function PageSample(props: {
2643
3288
  </div>
2644
3289
  );
2645
3290
  }
2646
- `,tt=`/* @jsxImportSource preact */
3291
+ `,St=`/* @jsxImportSource preact */
2647
3292
 
2648
3293
  import styles from "./styles.module.css";
2649
3294
 
@@ -2695,7 +3340,7 @@ export default function PageSample(props: {
2695
3340
  </div>
2696
3341
  );
2697
3342
  }
2698
- `,nt=`* {
3343
+ `,Ct=`* {
2699
3344
  margin: 0;
2700
3345
  padding: 0;
2701
3346
  box-sizing: border-box;
@@ -2830,7 +3475,7 @@ export default function PageSample(props: {
2830
3475
  align-items: center;
2831
3476
  gap: 0.25rem;
2832
3477
  }
2833
- `,rt=`/* @jsxImportSource preact */
3478
+ `,wt=`/* @jsxImportSource preact */
2834
3479
 
2835
3480
  import styles from "./styles.module.css";
2836
3481
 
@@ -2896,7 +3541,7 @@ export default function WelcomePage() {
2896
3541
  </div>
2897
3542
  );
2898
3543
  }
2899
- `,it=`export type ParamsMap = {
3544
+ `,Tt=`export type ParamsMap = {
2900
3545
  {{#each pageRoutes}}"{{name}}": {{serializeParamsLiteral .}};
2901
3546
  {{/each}}
2902
3547
  };
@@ -2905,7 +3550,7 @@ export const paramNames = {
2905
3550
  {{#each pageRoutes}}"{{name}}": [ {{#each params.schema}}"{{name}}", {{/each}}],
2906
3551
  {{/each}}
2907
3552
  } as const;
2908
- `,at=`import type { ComponentType } from "preact";
3553
+ `,Et=`import type { ComponentType } from "preact";
2909
3554
 
2910
3555
  import type { RouterFactoryReturn } from "@kosmojs/core";
2911
3556
  import { createRouterFactory } from "@kosmojs/core/generators";
@@ -2949,7 +3594,7 @@ export default createRouterFactory<
2949
3594
  Promise<RouteComponent>,
2950
3595
  { server: { route: Route } }
2951
3596
  >();
2952
- `,ot=`import { join } from "node:path";
3597
+ `,Dt=`import { join } from "node:path";
2953
3598
 
2954
3599
  import { compile } from "path-to-regexp";
2955
3600
 
@@ -2995,7 +3640,7 @@ export default Object.entries(routes)
2995
3640
  return [];
2996
3641
  })
2997
3642
  .map((path) => join(base, path));
2998
- `,st=`import type { PageRoute } from "@kosmojs/core";
3643
+ `,Ot=`import type { PageRoute } from "@kosmojs/core";
2999
3644
 
3000
3645
  {{#each pageRoutes}}
3001
3646
  import * as {{id}} from "{{ createImport 'pages' file }}";
@@ -3019,7 +3664,7 @@ const routeMap: Record<
3019
3664
  }
3020
3665
 
3021
3666
  export default routeMap;
3022
- `,ct=`import { useContext } from "preact/hooks";
3667
+ `,kt=`import { useContext } from "preact/hooks";
3023
3668
 
3024
3669
  import { RouterContext } from "./mdx";
3025
3670
 
@@ -3065,10 +3710,10 @@ export const useFrontmatter = <
3065
3710
  >(): T => {
3066
3711
  return useRoute().frontmatter as T;
3067
3712
  };
3068
- `,lt=`import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3713
+ `,At=`import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3069
3714
 
3070
3715
  <AppProvider>{props.children}</AppProvider>
3071
- `,ut=`import { h, type JSX } from "preact";
3716
+ `,jt=`import { h, type JSX } from "preact";
3072
3717
 
3073
3718
  import { pageRouteMap, type LinkProps } from "{{ createImport 'libCore' }}";
3074
3719
 
@@ -3081,11 +3726,11 @@ export default function Link(
3081
3726
  const { to, query, children, ...restProps } = props;
3082
3727
 
3083
3728
  const [key, ...params] = to;
3084
- const href = pageRouteMap[key]?.base(params as never, query);
3729
+ const href = pageRouteMap[key]?.path(params as never, query);
3085
3730
 
3086
3731
  return h("a", { ...restProps, href }, children);
3087
3732
  }
3088
- `,dt=`/**
3733
+ `,Mt=`/**
3089
3734
  * MDX component overrides.
3090
3735
  *
3091
3736
  * Every standard markdown element (headings, links, code blocks, etc.)
@@ -3108,7 +3753,7 @@ export const components = {
3108
3753
  declare global {
3109
3754
  type MDXProvidedComponents = typeof components;
3110
3755
  }
3111
- `,ft=`import renderFactory, {
3756
+ `,Nt=`import renderFactory, {
3112
3757
  createRoutes,
3113
3758
  hydrate,
3114
3759
  mount,
@@ -3135,7 +3780,7 @@ if (root) {
3135
3780
  } else {
3136
3781
  console.error("❌ Root element not found!");
3137
3782
  }
3138
- `,pt=`import renderFactory, {
3783
+ `,Pt=`import renderFactory, {
3139
3784
  createRoutes,
3140
3785
  renderToString,
3141
3786
  // no renderToStream on MDX folders
@@ -3156,7 +3801,7 @@ export default renderFactory(() => {
3156
3801
  },
3157
3802
  };
3158
3803
  });
3159
- `,mt=`<!doctype html>
3804
+ `,Ft=`<!doctype html>
3160
3805
  <html lang="en">
3161
3806
  <head>
3162
3807
  <meta charset="UTF-8" />
@@ -3168,13 +3813,13 @@ export default renderFactory(() => {
3168
3813
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
3169
3814
  </body>
3170
3815
  </html>
3171
- `,ht=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3816
+ `,It=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3172
3817
 
3173
3818
  export default function Page() {
3174
3819
  return <PageSample />;
3175
3820
  }
3176
- `,gt=`{props.children}
3177
- `,_t=`---
3821
+ `,Lt=`{props.children}
3822
+ `,Rt=`---
3178
3823
  title: "{{title}}"
3179
3824
  ---
3180
3825
 
@@ -3191,7 +3836,7 @@ export const pathMap = {
3191
3836
  routeName="{{route.name}}"
3192
3837
  pathMap={pathMap}
3193
3838
  />
3194
- `,vt=`---
3839
+ `,zt=`---
3195
3840
  title: Welcome to KosmoJS
3196
3841
  description: Content-first development with MDX and Vite
3197
3842
  ---
@@ -3199,7 +3844,7 @@ description: Content-first development with MDX and Vite
3199
3844
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}"
3200
3845
 
3201
3846
  <WelcomePage />
3202
- `,yt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3847
+ `,Bt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3203
3848
 
3204
3849
  import app from "./app.mdx";
3205
3850
  import { components } from "./components/mdx"
@@ -3215,12 +3860,12 @@ export default routerFactory((routes) => {
3215
3860
  },
3216
3861
  };
3217
3862
  });
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";
3863
+ `,Vt=g((e,t)=>{let{createPath:n,createImportHelpers:r}=y(e),{renderToFile:i}=x({helpers:{...r({origin:`lib`}),...w(),serializeParams(e){return JSON.stringify(e.params)}}}),{renderToFile:a}=x({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,s=c(t?.templates,Rt),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?zt:s(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:mt()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),Lt,{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(S)}]}return[]}).sort(S);for(let[e,a]of[[`client.ts`,_t],[`server.ts`,vt]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,Tt],[`router.ts`,Et],[`ssg:routes.ts`,Ot]])await i(n.lib(e),t,{pageRoutes:r})};return{config({command:n}){return{oxc:{jsx:{importSource:`preact`}},plugins:ht(e,n,t)}},async start(){for(let[e,t]of[[`env.d.ts`,yt],[`app.ts`,gt],[`mdx.ts`,bt],[`use.ts`,kt],[`ssg.ts`,Dt],[`pageSamples/styles.module.css`,Ct],[`pageSamples/welcome.tsx`,wt],[`pageSamples/page.tsx`,St],[`pageSamples/404.tsx`,xt]])await i(n.lib(e),t,{});for(let[e,t]of[[`pages/404.mdx`,It],[`components/Link.tsx`,jt],[`components/mdx.ts`,Mt],[`app.mdx`,At],[`router.ts`,Bt]])await a(n.src(e),t,{entryDir:l.entryDir},{overwrite:o});await a(n.src(`index.html`),Ft,{entryDir:l.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Nt],[`server.ts`,Pt]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){await u(e.filter(m(t,[`create`]))),await d(e)},async build(e){await u(e),await d(e)}}}),Ht=h({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}),Ut={json:`application/json`,form:[`application/x-www-form-urlencoded`,`multipart/form-data`],raw:void 0},Wt=()=>{let e=e=>[`Buffer`,`ArrayBuffer`,`Blob`].includes(e)?{type:`string`,format:`binary`}:oe.Script(e),n=(e,t,n)=>{let r=n?`${t}_${n.replace(/[^\w.-]/g,`_`)}${T(n)}`:t;return`${e.id}_${r}`},r=(e,t,r,i)=>[`#`,`components`,e,n(t,r,i)].join(`/`),i=e=>e.split(`/`).reduce((e,t)=>e+ +!t.includes(`{`),0),o=e=>{if(e.name===`index`)return[`/`];let{tokens:n}=ae(e.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[]}}),a=(e,t)=>{if(!e.length)return[t];let[n,...i]=e;switch(n.type){case`text`:return a(i,{path:`${t.path}${n.value}`,params:t.params});case`param`:return a(i,{path:`${t.path}{${n.name}}`,params:[...t.params,n.name]});case`wildcard`:return a(i,{path:`${t.path}{${n.name}*}`,params:[...t.params,n.name]});case`group`:{let e=a(i,t),o=a([...n.tokens,...i],t),s=r(n.tokens),c=o.filter(e=>s.some(t=>e.params.includes(t)));return[...e,...c]}}},o=a(n,{path:``,params:[]}),s=e.params.schema.reduce((e,{name:t},n)=>(e[n]=t,e),{});return o.reduce((e,n)=>{let r=t(`/`,n.path);return e.includes(r)||n.params.every((e,t)=>e===s[t])&&e.push(r),e},[]).sort((e,t)=>i(t)-i(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]=Gt(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=t=>{let{parameters:r,schemas:i}={parameters:{},schemas:{}};for(let r of t.validationDefinitions)if(r.target===`response`)for(let{id:a,resolvedType:o}of r.variants)o?.typeboxSchema&&(i[n(t,a)]=e(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(t,a,r.name);i[o]=e(r.typeboxSchema)}}else{let{id:a,resolvedType:o}=r.schema;o?.typeboxSchema&&(i[n(t,a)]=e(o.typeboxSchema))}if(t.params.resolvedType)for(let i of t.params.resolvedType.properties||[])i?.typeboxSchema&&(r[n(t,t.params.id,i.name)]={name:i.name,in:`path`,required:!0,schema:e(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 i of o(e))for(let o of e.methods){let l={responses:c(e,o)},u=s(e,i);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(a).includes(e.target));f.length&&(l.requestBody={required:!0,content:f.reduce((t,n)=>{let{contentType:i=Ut[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[i]||(t[i]={}),t[i][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(S).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}}}},Gt=(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]},Kt=g((e,t)=>{let{outfile:n=``,...r}={...t},{createPath:i}=y(e),{generateOpenAPISchema:a}=Wt(),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)?ie.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)}}}),qt=h({meta:{name:`OpenAPI`,resolveTypes:!0},factory:Kt}),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.1.0`},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`}},Jt=e=>{let t=e.map(e=>e.orig).join(`/`),n=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`?[n(e.parts[0])]:(/\.\w+$/.test(e.orig)||(console.warn(`❗${r([`red`,`bold`],`WARN`)}: React Router v7 only supports dot-suffix mixed segments (e.g. :param.html).`),console.warn(` ${r([`magenta`],e.orig)} in ${r([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:n(e)).join(``)])).join(`/`)},Yt=()=>{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=Jt(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},Xt=()=>{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)]},Zt=`import type { ReactNode } from "react";
3219
3864
 
3220
3865
  export const AppProvider = ({ children }: { children: ReactNode }) => {
3221
3866
  return children;
3222
3867
  }
3223
- `,jt=`import { type QueryClient, QueryClientProvider } from "@tanstack/react-query";
3868
+ `,Qt=`import { type QueryClient, QueryClientProvider } from "@tanstack/react-query";
3224
3869
  import type { ReactNode } from "react";
3225
3870
 
3226
3871
  import { getQueryClient } from "./query";
@@ -3239,7 +3884,7 @@ export const AppProvider = ({
3239
3884
  </QueryClientProvider>
3240
3885
  );
3241
3886
  }
3242
- `,Mt=`import { lazy, type JSX } from "react";
3887
+ `,$t=`import { lazy, type JSX } from "react";
3243
3888
 
3244
3889
  import {
3245
3890
  createRoot,
@@ -3293,7 +3938,7 @@ export const mount = async (
3293
3938
  }
3294
3939
 
3295
3940
  export default clientRenderFactory();
3296
- `,Nt=`{
3941
+ `,en=`{
3297
3942
  {{#if name}}
3298
3943
  id: "{{name}}",
3299
3944
  {{/if}}
@@ -3311,7 +3956,7 @@ export default clientRenderFactory();
3311
3956
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
3312
3957
  {{/if}}
3313
3958
  }
3314
- `,Pt=`import type { JSX } from "react";
3959
+ `,tn=`import type { JSX } from "react";
3315
3960
 
3316
3961
  import {
3317
3962
  renderToString as renderToStringOrig,
@@ -3377,7 +4022,7 @@ export const renderToStream: RenderToStreamWrapper<
3377
4022
  };
3378
4023
 
3379
4024
  export default serverRenderFactory();
3380
- `,Ft=`/* @jsxImportSource react */
4025
+ `,nn=`/* @jsxImportSource react */
3381
4026
 
3382
4027
  import styles from "./styles.module.css";
3383
4028
 
@@ -3418,7 +4063,7 @@ export default function PageSample(props: {
3418
4063
  </div>
3419
4064
  );
3420
4065
  }
3421
- `,It=`/* @jsxImportSource react */
4066
+ `,rn=`/* @jsxImportSource react */
3422
4067
 
3423
4068
  import styles from "./styles.module.css";
3424
4069
 
@@ -3470,7 +4115,7 @@ export default function PageSample(props: {
3470
4115
  </div>
3471
4116
  );
3472
4117
  }
3473
- `,Lt=`* {
4118
+ `,an=`* {
3474
4119
  margin: 0;
3475
4120
  padding: 0;
3476
4121
  box-sizing: border-box;
@@ -3605,7 +4250,7 @@ export default function PageSample(props: {
3605
4250
  align-items: center;
3606
4251
  gap: 0.25rem;
3607
4252
  }
3608
- `,Rt=`/* @jsxImportSource react */
4253
+ `,on=`/* @jsxImportSource react */
3609
4254
 
3610
4255
  import styles from "./styles.module.css";
3611
4256
 
@@ -3671,7 +4316,7 @@ export default function WelcomePage() {
3671
4316
  </div>
3672
4317
  );
3673
4318
  }
3674
- `,zt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
4319
+ `,sn=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3675
4320
 
3676
4321
  let client: QueryClient | undefined;
3677
4322
 
@@ -3686,7 +4331,7 @@ export const getQueryClient = (): QueryClient => {
3686
4331
  }
3687
4332
  return client;
3688
4333
  };
3689
- `,Bt=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
4334
+ `,cn=`import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
3690
4335
 
3691
4336
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
3692
4337
 
@@ -3709,7 +4354,7 @@ export const getQueryClient = (): QueryClient => {
3709
4354
  }
3710
4355
  return ctx.tsqClient as QueryClient;
3711
4356
  };
3712
- `,Vt=`export type ComponentLoader = () => Promise<{
4357
+ `,ln=`export type ComponentLoader = () => Promise<{
3713
4358
  loader?: (arg: unknown) => Promise<unknown>;
3714
4359
  }>;
3715
4360
 
@@ -3729,7 +4374,7 @@ export const loaderFactory = (opt?: { withPreload?: boolean }) => {
3729
4374
  return opt?.withPreload ? { loader } : {};
3730
4375
  };
3731
4376
  };
3732
- `,Ht=`import type { JSX, ComponentType } from "react";
4377
+ `,un=`import type { JSX, ComponentType } from "react";
3733
4378
 
3734
4379
  import {
3735
4380
  type RouteObject,
@@ -3787,7 +4432,7 @@ export const createRouters = (
3787
4432
  }
3788
4433
 
3789
4434
  export default createRouterFactory<RouteObject, Promise<JSX.Element>>();
3790
- `,Ut=`import { Outlet } from "react-router";
4435
+ `,dn=`import { Outlet } from "react-router";
3791
4436
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
3792
4437
 
3793
4438
  export default function App() {
@@ -3797,7 +4442,7 @@ export default function App() {
3797
4442
  </AppProvider>
3798
4443
  );
3799
4444
  }
3800
- `,Wt=`import {
4445
+ `,fn=`import {
3801
4446
  type LinkProps as RouterLinkProps,
3802
4447
  Link as RouterLink,
3803
4448
  } from "react-router";
@@ -3816,7 +4461,7 @@ export default function Link(
3816
4461
 
3817
4462
  const href = () => {
3818
4463
  const [key, ...params] = to;
3819
- return pageRouteMap[key]?.base(params as never, query);
4464
+ return pageRouteMap[key]?.path(params as never, query, { prefix: false });
3820
4465
  };
3821
4466
 
3822
4467
  return (
@@ -3825,7 +4470,7 @@ export default function Link(
3825
4470
  </RouterLink>
3826
4471
  );
3827
4472
  }
3828
- `,Gt=`import renderFactory, {
4473
+ `,pn=`import renderFactory, {
3829
4474
  createRoutes,
3830
4475
  hydrate,
3831
4476
  mount,
@@ -3852,7 +4497,7 @@ if (root) {
3852
4497
  } else {
3853
4498
  console.error("❌ Root element not found!");
3854
4499
  }
3855
- `,Kt=`import renderFactory, {
4500
+ `,mn=`import renderFactory, {
3856
4501
  createRoutes,
3857
4502
  renderToStream,
3858
4503
  renderToString,
@@ -3879,7 +4524,7 @@ export default renderFactory(() => {
3879
4524
  },
3880
4525
  };
3881
4526
  });
3882
- `,qt=`<!doctype html>
4527
+ `,hn=`<!doctype html>
3883
4528
  <html lang="en">
3884
4529
  <head>
3885
4530
  <meta charset="UTF-8" />
@@ -3891,17 +4536,17 @@ export default renderFactory(() => {
3891
4536
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
3892
4537
  </body>
3893
4538
  </html>
3894
- `,Jt=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
4539
+ `,gn=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
3895
4540
 
3896
4541
  export default function Page() {
3897
4542
  return <PageSample />;
3898
4543
  }
3899
- `,Yt=`import { Outlet } from "react-router";
4544
+ `,_n=`import { Outlet } from "react-router";
3900
4545
 
3901
4546
  export default function Layout() {
3902
4547
  return <Outlet />;
3903
4548
  }
3904
- `,Xt=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
4549
+ `,vn=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
3905
4550
 
3906
4551
  export default function Page() {
3907
4552
  return PageSample({
@@ -3914,8 +4559,8 @@ export default function Page() {
3914
4559
  },
3915
4560
  });
3916
4561
  }
3917
- `,Zt=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
3918
- `,Qt=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
4562
+ `,yn=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
4563
+ `,bn=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
3919
4564
 
3920
4565
  import app from "./app";
3921
4566
 
@@ -3930,12 +4575,12 @@ export default routerFactory((routes) => {
3930
4575
  },
3931
4576
  };
3932
4577
  });
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";
4578
+ `,xn=g((e,t)=>{let{createPath:n,createImportHelpers:r}=y(e),{renderToFile:i}=x({helpers:{...r({origin:`lib`}),...w()},partials:{routePartial:en}}),{renderToFile:a}=x({helpers:r({origin:`src`})}),o=Yt(),s=e=>!e?.trim().length,u=c(t?.templates,vn),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?yn:u(r.name,r),{route:r,message:Xt()},{overwrite:s}):t===`pageLayout`&&await a(n.pages(r.file),_n,{route:r},{overwrite:s})},f=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(S),r=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),a=o(v(r));for(let[e,t]of[[`client.ts`,$t],[`server.ts`,tn]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a});await i(n.lib(`router.tsx`),un,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[se(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,``],[`react.ts`,ln],[`pageSamples/styles.module.css`,an],[`pageSamples/welcome.tsx`,on],[`pageSamples/page.tsx`,rn],[`pageSamples/404.tsx`,nn],...t?.tanstack?.query?[[`app.tsx`,Qt],[`query.ts`,sn]]:[[`app.tsx`,Zt],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.tsx`,gn],[`components/Link.tsx`,fn],[`app.tsx`,dn],[`router.ts`,bn]])await a(n.src(e),t,{entryDir:l.entryDir},{overwrite:s});await a(n.src(`index.html`),hn,{entryDir:l.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,pn],[`server.ts`,mn]])await a(n.entry(e),t,{},{overwrite:s})},async watch(e,t){await d(e.filter(m(t,[`create`]))),await f(e)},async build(e){await d(e),await f(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?cn:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),Sn=h({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:xn}),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.15`}},Cn=()=>{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(`/`),n=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`?[n(e.parts[0])]:(e.parts.length&&(console.warn(`❗${r([`red`,`bold`],`WARN`)}: At the moment Solid Router does not support mixed path segments.`),console.warn(` ${r([`magenta`],e.orig)} segment in ${r([`blue`],t)} route won't match as expected.`),console.warn()),[e.parts.map(e=>e.type===`static`?e.value:n(e)).join(``)])).join(`/`)},wn=()=>{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";
3934
4579
 
3935
4580
  export const AppProvider: ParentComponent = (props) => {
3936
4581
  return props.children;
3937
4582
  };
3938
- `,an=`import type { ParentComponent } from "solid-js";
4583
+ `,En=`import type { ParentComponent } from "solid-js";
3939
4584
  import { type QueryClient, QueryClientProvider } from "@tanstack/solid-query";
3940
4585
 
3941
4586
  import { getQueryClient } from "./query";
@@ -3947,7 +4592,7 @@ export const AppProvider: ParentComponent<{ client?: QueryClient }> = (props) =>
3947
4592
  </QueryClientProvider>
3948
4593
  );
3949
4594
  };
3950
- `,on=`import { lazy, type JSX } from "solid-js";
4595
+ `,Dn=`import { lazy, type JSX } from "solid-js";
3951
4596
  import { hydrate as hydrateOrig, render } from "solid-js/web";
3952
4597
  import type { RouterFactoryReturn } from "@kosmojs/core";
3953
4598
  import { clientRenderFactory } from "@kosmojs/core/generators";
@@ -3992,7 +4637,7 @@ export const mount = async (
3992
4637
  }
3993
4638
 
3994
4639
  export default clientRenderFactory();
3995
- `,sn=`{
4640
+ `,On=`{
3996
4641
  path: "{{path}}",
3997
4642
  {{#if component}}
3998
4643
  component: {{component}}_component,
@@ -4002,7 +4647,7 @@ export default clientRenderFactory();
4002
4647
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
4003
4648
  {{/if}}
4004
4649
  }
4005
- `,cn=`import type { JSX } from "solid-js";
4650
+ `,kn=`import type { JSX } from "solid-js";
4006
4651
 
4007
4652
  import {
4008
4653
  generateHydrationScript,
@@ -4083,7 +4728,7 @@ export const renderToStream: RenderToStreamWrapper<
4083
4728
  };
4084
4729
 
4085
4730
  export default serverRenderFactory<true>();
4086
- `,ln=`/* @jsxImportSource solid-js */
4731
+ `,An=`/* @jsxImportSource solid-js */
4087
4732
 
4088
4733
  import styles from "./styles.module.css";
4089
4734
 
@@ -4124,7 +4769,7 @@ export default function PageSample(props: {
4124
4769
  </div>
4125
4770
  );
4126
4771
  }
4127
- `,un=`/* @jsxImportSource solid-js */
4772
+ `,jn=`/* @jsxImportSource solid-js */
4128
4773
 
4129
4774
  import styles from "./styles.module.css";
4130
4775
 
@@ -4176,7 +4821,7 @@ export default function PageSample(props: {
4176
4821
  </div>
4177
4822
  );
4178
4823
  }
4179
- `,dn=`* {
4824
+ `,Mn=`* {
4180
4825
  margin: 0;
4181
4826
  padding: 0;
4182
4827
  box-sizing: border-box;
@@ -4311,7 +4956,7 @@ export default function PageSample(props: {
4311
4956
  align-items: center;
4312
4957
  gap: 0.25rem;
4313
4958
  }
4314
- `,fn=`/* @jsxImportSource solid-js */
4959
+ `,Nn=`/* @jsxImportSource solid-js */
4315
4960
 
4316
4961
  import styles from "./styles.module.css";
4317
4962
 
@@ -4377,7 +5022,7 @@ export default function WelcomePage() {
4377
5022
  </div>
4378
5023
  );
4379
5024
  }
4380
- `,pn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
5025
+ `,Pn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4381
5026
 
4382
5027
  let client: QueryClient | undefined;
4383
5028
 
@@ -4392,7 +5037,7 @@ export const getQueryClient = (): QueryClient => {
4392
5037
  }
4393
5038
  return client;
4394
5039
  };
4395
- `,mn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
5040
+ `,Fn=`import { QueryClient, type QueryClientConfig } from "@tanstack/solid-query";
4396
5041
 
4397
5042
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
4398
5043
 
@@ -4415,7 +5060,7 @@ export const getQueryClient = (): QueryClient => {
4415
5060
  }
4416
5061
  return ctx.tsqClient as QueryClient;
4417
5062
  };
4418
- `,hn=`import type { JSX, ParentComponent } from "solid-js";
5063
+ `,In=`import type { JSX, ParentComponent } from "solid-js";
4419
5064
  import { Router, type RouteDefinition } from "@solidjs/router";
4420
5065
  import type { RouterFactoryReturn } from "@kosmojs/core";
4421
5066
  import { createRouterFactory } from "@kosmojs/core/generators";
@@ -4451,7 +5096,7 @@ export const createRouters = (
4451
5096
  }
4452
5097
 
4453
5098
  export default createRouterFactory<RouteDefinition, JSX.Element>();
4454
- `,gn=`export type ComponentLoader = () => Promise<{
5099
+ `,Ln=`export type ComponentLoader = () => Promise<{
4455
5100
  preload?: () => Promise<unknown>;
4456
5101
  }>;
4457
5102
 
@@ -4466,10 +5111,10 @@ export const loaderFactory = (opt?: { withPreload?: boolean }) => {
4466
5111
  return opt?.withPreload ? { preload } : {};
4467
5112
  };
4468
5113
  };
4469
- `,_n=`export type MaybeWrapped<T> = import("solid-js/store").Store<T> | T;
5114
+ `,Rn=`export type MaybeWrapped<T> = import("solid-js/store").Store<T> | T;
4470
5115
 
4471
5116
  export { unwrap } from "solid-js/store";
4472
- `,vn=`import type { ParentComponent } from "solid-js";
5117
+ `,zn=`import type { ParentComponent } from "solid-js";
4473
5118
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
4474
5119
 
4475
5120
  const App: ParentComponent = (props) => {
@@ -4477,7 +5122,7 @@ const App: ParentComponent = (props) => {
4477
5122
  };
4478
5123
 
4479
5124
  export default App;
4480
- `,yn=`import { A, type AnchorProps } from "@solidjs/router";
5125
+ `,Bn=`import { A, type AnchorProps } from "@solidjs/router";
4481
5126
  import { type JSXElement, splitProps } from "solid-js";
4482
5127
 
4483
5128
  import { pageRouteMap, type LinkProps } from "{{ createImport 'libCore' }}";
@@ -4497,12 +5142,12 @@ export default function Link(
4497
5142
 
4498
5143
  const href = () => {
4499
5144
  const [key, ...params] = knownProps.to;
4500
- return pageRouteMap[key]?.base(params as never, knownProps.query);
5145
+ return pageRouteMap[key]?.path(params as never, knownProps.query, { prefix: false });
4501
5146
  };
4502
5147
 
4503
5148
  return <A {...{ ...restProps, href: href() }}>{knownProps.children}</A>;
4504
5149
  }
4505
- `,bn=`import renderFactory, {
5150
+ `,Vn=`import renderFactory, {
4506
5151
  createRoutes,
4507
5152
  hydrate,
4508
5153
  mount,
@@ -4529,7 +5174,7 @@ if (root) {
4529
5174
  } else {
4530
5175
  console.error("❌ Root element not found!");
4531
5176
  }
4532
- `,xn=`import renderFactory, {
5177
+ `,Hn=`import renderFactory, {
4533
5178
  createRoutes,
4534
5179
  renderToStream,
4535
5180
  renderToString,
@@ -4556,7 +5201,7 @@ export default renderFactory(() => {
4556
5201
  },
4557
5202
  };
4558
5203
  });
4559
- `,Sn=`<!doctype html>
5204
+ `,Un=`<!doctype html>
4560
5205
  <html lang="en">
4561
5206
  <head>
4562
5207
  <meta charset="UTF-8" />
@@ -4568,19 +5213,19 @@ export default renderFactory(() => {
4568
5213
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
4569
5214
  </body>
4570
5215
  </html>
4571
- `,Cn=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
5216
+ `,Wn=`import PageSample from "{{ createImport 'lib' 'pageSamples/404.tsx' }}";
4572
5217
 
4573
5218
  export default function Page() {
4574
5219
  return <PageSample />;
4575
5220
  }
4576
- `,wn=`import type { ParentComponent } from "solid-js";
5221
+ `,Gn=`import type { ParentComponent } from "solid-js";
4577
5222
 
4578
5223
  const Layout: ParentComponent = (props) => {
4579
5224
  return props.children;
4580
5225
  };
4581
5226
 
4582
5227
  export default Layout;
4583
- `,Tn=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
5228
+ `,Kn=`import PageSample from "{{ createImport 'lib' 'pageSamples/page.tsx' }}";
4584
5229
 
4585
5230
  export default function Page() {
4586
5231
  return PageSample({
@@ -4593,8 +5238,8 @@ export default function Page() {
4593
5238
  },
4594
5239
  });
4595
5240
  }
4596
- `,En=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
4597
- `,Dn=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
5241
+ `,qn=`export { default } from "{{ createImport 'lib' 'pageSamples/welcome.tsx' }}";
5242
+ `,Jn=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
4598
5243
 
4599
5244
  import app from "./app";
4600
5245
 
@@ -4609,12 +5254,12 @@ export default routerFactory((routes) => {
4609
5254
  },
4610
5255
  };
4611
5256
  });
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}}
5257
+ `,Yn=g((e,t)=>{let{generators:n=[]}=e.config,{createPath:r,createImportHelpers:i}=y(e),{renderToFile:a}=x({helpers:{...i({origin:`lib`}),...w()},partials:{routePartial:On}}),{renderToFile:o}=x({helpers:i({origin:`src`})}),s=Cn(),u=e=>!e?.trim().length,d=c(t?.templates,Kn),f=async e=>{for(let{kind:t,entry:n}of e)t===`pageRoute`?await o(r.pages(n.file),n.name===`index`?qn:d(n.name,n),{route:n,message:wn()},{overwrite:u}):t===`pageLayout`&&await o(r.pages(n.file),Gn,{route:n},{overwrite:u})},p=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(S),n=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),i=s(v(n));for(let[e,t]of[[`client.ts`,Dn],[`server.ts`,kn]])await a(r.libEntry(e),t,{pageEntries:n,nestedRoutes:i});await a(r.lib(`router.tsx`),In,{entries:e,indexRoutes:t})};return{config({command:e}){let{templates:r,...i}={...t};return{oxc:{jsx:{importSource:`solid-js`}},plugins:e===`build`?[D({...i,...n.some(e=>e.meta.slot===`ssr`)?{ssr:!0,solid:{...i?.solid,hydratable:!0}}:{}})]:[D({...i,dev:!0,hot:!0})]}},async start(){for(let[e,n]of[[`env.d.ts`,``],[`solid.ts`,Ln],[`unwrap.ts`,Rn],[`pageSamples/styles.module.css`,Mn],[`pageSamples/welcome.tsx`,Nn],[`pageSamples/page.tsx`,jn],[`pageSamples/404.tsx`,An],...t?.tanstack?.query?[[`app.tsx`,En],[`query.ts`,Pn]]:[[`app.tsx`,Tn],[`query.ts`,`/** tanstack query disabled */`]]])await a(r.lib(e),n,{});for(let[e,t]of[[`pages/404.tsx`,Wn],[`components/Link.tsx`,Bn],[`app.tsx`,zn],[`router.ts`,Jn]])await o(r.src(e),t,{entryDir:l.entryDir},{overwrite:u});await o(r.src(`index.html`),Un,{entryDir:l.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Vn],[`server.ts`,Hn]])await o(r.entry(e),t,{},{overwrite:u})},async watch(e,t){await f(e.filter(m(t,[`create`]))),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})}}}),Xn=h({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:Yn}),Zn=g(e=>{let{generators:i=[],refineTypeName:a,...o}={...e.config},{createPath:s}=y(e);return{async postBuild(){let a=s.distDir(`ssg`),c=n(a,`../ssr/server.js`);if(!await ce(c,le.F_OK).then(()=>!0,()=>!1)){console.error(),console.error(r(`red`,`❗Please enable ssrGenerator in ${e.name}/kosmo.config.ts`)),console.error(` SSG generator can not run without SSR server`),console.error();return}let l=te(`${e.name}: SSG`);l.append(`preparing...`);let{createDisposableServer:u}=await import(c);await O(n(a,`../client/assets`),t(a,`assets`),{recursive:!0}),l.append(`bundling routes...`),await E(_(o,...i.map(({factory:t})=>t(e).config?.({kind:`client`,command:`build`})),{root:s.lib(),appType:`custom`,plugins:[C.tsconfigPaths(e),C.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 e=await import(t(a,`routes.js`)).then(e=>e.default);u(async n=>{for(let[r,i]of e.entries()){l.append(`[ ${r+1} of ${e.length} ] ${i}`);let o=await Qn(n,i);o!==void 0&&(await ue(t(a,i),{recursive:!0}),await de(t(a,t(i,`index.html`)),o,`utf8`))}l.succeed(`done ✨`)})}finally{await k(`${a}/routes.js`)}}}}),Qn=async(e,t)=>{try{let n=`http://localhost:${e}${t}`;return await(await fetch(n)).text()}catch(e){console.error(r(`red`,`✗ SSG: Failed generating ${t} route: ${e.message}`));return}},$n=h({meta:{name:`SSG`,slot:`ssg`},factory:Zn}),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.2`},devDependencies:{"@hono/node-server":`^2.1.1`,hono:`^4.13.3`,"light-my-request":`^6.6.0`,tinyglobby:`^0.2.17`}},er=`{{#if apiGenerator}}
4613
5258
  export { default as apiApp } from "{{ createImport 'api' 'app' }}";
4614
5259
  {{else}}
4615
5260
  export const apiApp = undefined;
4616
5261
  {{/if}}
4617
- `,Pn=`import { AsyncLocalStorage } from "node:async_hooks";
5262
+ `,tr=`import { AsyncLocalStorage } from "node:async_hooks";
4618
5263
 
4619
5264
  import type { FetchApp, NodeApp } from "@kosmojs/core";
4620
5265
 
@@ -4658,7 +5303,7 @@ export const store = new AsyncLocalStorage<RequestContext>();
4658
5303
  export const isFetchApp = (app: FetchApp | NodeApp): app is FetchApp => {
4659
5304
  return typeof (app as FetchApp).fetch === "function";
4660
5305
  };
4661
- `,Fn=`import { type RequestContext, store } from "./base";
5306
+ `,nr=`import { type RequestContext, store } from "./base";
4662
5307
 
4663
5308
  import { renderWrapper } from "{{ createImport 'libEntry' 'server' }}";
4664
5309
 
@@ -4680,9 +5325,7 @@ export const withSsrContext = <T>(
4680
5325
  export const errorProvider = () => {
4681
5326
  return store.getStore()?.error;
4682
5327
  };
4683
- `,In=`import { inject } from "light-my-request";
4684
-
4685
- import type { FetchApp, NodeApp } from "@kosmojs/core";
5328
+ `,rr=`import type { FetchApp, NodeApp } from "@kosmojs/core";
4686
5329
  import type { Transport } from "@kosmojs/core/fetch";
4687
5330
 
4688
5331
  import {
@@ -4706,6 +5349,8 @@ const createDispatch = (app: FetchApp | NodeApp) => {
4706
5349
  return isFetchApp(app)
4707
5350
  ? app.fetch
4708
5351
  : async (request: Request): Promise<Response> => {
5352
+ const { inject } = await import("light-my-request");
5353
+
4709
5354
  /**
4710
5355
  * Node dispatch: serializes the web Request into light-my-request's
4711
5356
  * injection format and lifts the injected response back into a web Response.
@@ -4824,7 +5469,7 @@ const createTransport = (app: FetchApp | NodeApp): Transport => {
4824
5469
  };
4825
5470
  };
4826
5471
 
4827
- const ssrTransport = apiApp ? createTransport(apiApp) : undefined;
5472
+ const ssrTransport = apiApp ? createTransport(apiApp as never) : undefined;
4828
5473
 
4829
5474
  export const transport = ssrTransport
4830
5475
  ? async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -4883,12 +5528,12 @@ const pathnameOf = (input: RequestInfo | URL): string => {
4883
5528
  } catch {}
4884
5529
  return String(input);
4885
5530
  };
4886
- `,Ln=`export const routeMap = [
5531
+ `,ir=`export const routeMap = [
4887
5532
  {{#each pageRoutes}}
4888
5533
  { pathPattern: "{{honoPattern}}", renderMode: "{{renderMode}}" },
4889
5534
  {{/each}}
4890
5535
  ];
4891
- `,Rn=`import { access, chmod, constants, readFile, unlink } from "node:fs/promises";
5536
+ `,ar=`import { access, chmod, constants, readFile, unlink } from "node:fs/promises";
4892
5537
  import {
4893
5538
  createServer,
4894
5539
  type IncomingMessage,
@@ -5304,14 +5949,14 @@ if (isMain) {
5304
5949
  process.exit(1);
5305
5950
  }
5306
5951
  }
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">
5952
+ `,or=`string`,sr=g((e,r)=>{let{generators:i=[],refineTypeName:a,...o}=e.config,{createPath:c,createImportHelpers:l}=y(e),{renderToFile:u}=x({helpers:{...l({origin:`lib`})}});return{async build(e){let t=r?.renderMode?typeof r.renderMode==`string`?()=>r.renderMode:s(r?.renderMode,`string`):()=>or,n={renderMode:JSON.stringify(r?.renderMode||null),pageRoutes:e.flatMap(e=>e.kind===`pageRoute`?[{...e.entry,renderMode:t(e.entry.name)}]:[]).sort(S),apiGenerator:i.some(e=>e.meta.slot===`backend`)};for(let[e,t]of[[`ssr.ts`,ar],[`@ssr/api.ts`,er],[`@ssr/__kosmo_ssr_bundle.ts`,nr],[`@ssr/base.ts`,tr],[`@ssr/fetch.ts`,rr],[`@ssr/routes.ts`,ir]])await u(c.lib(e),t,n)},async postBuild(){let r=c.distDir(`ssr`),a=[C.tsconfigPaths(e),C.nodePrefix()];for(let t of i)await t.factory(e).ssrBuild?.();await E(_(o,...i.map(({factory:t})=>t(e).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 E({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:t(r,`server`),entryFileNames:`server.js`,format:`esm`}}}}),await O(n(r,`../client`),r,{recursive:!0});for(let e of[`server.js`,`server.js.map`])await O(`${r}/server/${e}`,`${r}/${e}`);await k(`${r}/server`,{recursive:!0,force:!0})}}}),cr=h({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:sr}),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.3.0`,vite:`^8.2.2`},devDependencies:{"@tanstack/svelte-query":`^6.1.38`,"path-to-regexp":`^8.4.2`,svelte:`^5.56.10`}},lr=()=>{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">
5308
5953
  import type { Snippet } from "svelte";
5309
5954
 
5310
5955
  let { children }: { children: Snippet } = $props();
5311
5956
  <\/script>
5312
5957
 
5313
5958
  {@render children()}
5314
- `,Un=`<script lang="ts">
5959
+ `,ur=`<script lang="ts">
5315
5960
  import { type QueryClient, QueryClientProvider } from "@tanstack/svelte-query";
5316
5961
  import type { Snippet } from "svelte";
5317
5962
 
@@ -5328,7 +5973,7 @@ if (isMain) {
5328
5973
  <QueryClientProvider client={queryClient}>
5329
5974
  {@render children()}
5330
5975
  </QueryClientProvider>
5331
- `,Wn=`import { hydrate as hydrateOrig, mount as mountOrig } from "svelte";
5976
+ `,dr=`import { hydrate as hydrateOrig, mount as mountOrig } from "svelte";
5332
5977
  import type { RouterFactoryReturn } from "@kosmojs/core";
5333
5978
  import { clientRenderFactory } from "@kosmojs/core/generators";
5334
5979
 
@@ -5369,7 +6014,7 @@ export const mount = async (
5369
6014
  }
5370
6015
 
5371
6016
  export default clientRenderFactory();
5372
- `,Gn=`import { render as renderOrig } from "svelte/server";
6017
+ `,fr=`import { render as renderOrig } from "svelte/server";
5373
6018
 
5374
6019
  import type {
5375
6020
  RenderToStringWrapper,
@@ -5435,12 +6080,12 @@ export const renderToString: RenderToStringWrapper<
5435
6080
  // svelte/server exposes only render() - no web-stream renderer -
5436
6081
  // so this folder is string-only SSR.
5437
6082
  export default serverRenderFactory<false>();
5438
- `,Kn=`declare module "*.svelte" {
6083
+ `,pr=`declare module "*.svelte" {
5439
6084
  import type { Component } from "svelte";
5440
6085
  const component: Component;
5441
6086
  export default component;
5442
6087
  }
5443
- `,qn=`<script lang="ts">
6088
+ `,mr=`<script lang="ts">
5444
6089
  /**
5445
6090
  * Folds [app, ...layouts] around the page component.
5446
6091
  *
@@ -5474,7 +6119,7 @@ export default serverRenderFactory<false>();
5474
6119
  {/snippet}
5475
6120
 
5476
6121
  {@render layer(0)}
5477
- `,Jn=`<script lang="ts">
6122
+ `,hr=`<script lang="ts">
5478
6123
  import styles from "./styles.module.css";
5479
6124
 
5480
6125
  let { headline }: { headline?: string } = $props();
@@ -5506,7 +6151,7 @@ export default serverRenderFactory<false>();
5506
6151
  </div>
5507
6152
  </div>
5508
6153
  </div>
5509
- `,Yn=`<script lang="ts">
6154
+ `,gr=`<script lang="ts">
5510
6155
  import styles from "./styles.module.css";
5511
6156
 
5512
6157
  let {
@@ -5551,7 +6196,7 @@ export default serverRenderFactory<false>();
5551
6196
  </div>
5552
6197
  </div>
5553
6198
  </div>
5554
- `,Xn=`* {
6199
+ `,_r=`* {
5555
6200
  margin: 0;
5556
6201
  padding: 0;
5557
6202
  box-sizing: border-box;
@@ -5686,7 +6331,7 @@ export default serverRenderFactory<false>();
5686
6331
  align-items: center;
5687
6332
  gap: 0.25rem;
5688
6333
  }
5689
- `,Zn=`<script lang="ts">
6334
+ `,vr=`<script lang="ts">
5690
6335
  import styles from "./styles.module.css";
5691
6336
  <\/script>
5692
6337
 
@@ -5744,7 +6389,7 @@ export default serverRenderFactory<false>();
5744
6389
  </div>
5745
6390
  </div>
5746
6391
  </div>
5747
- `,Qn=`export type ParamsMap = {
6392
+ `,yr=`export type ParamsMap = {
5748
6393
  {{#each pageRoutes}}"{{name}}": {{serializeParamsLiteral .}};
5749
6394
  {{/each}}
5750
6395
  };
@@ -5753,7 +6398,7 @@ export const paramNames = {
5753
6398
  {{#each pageRoutes}}"{{name}}": [ {{#each params.schema}}"{{name}}", {{/each}}],
5754
6399
  {{/each}}
5755
6400
  } as const;
5756
- `,$n=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
6401
+ `,br=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5757
6402
 
5758
6403
  let client: QueryClient | undefined;
5759
6404
 
@@ -5768,7 +6413,7 @@ export const getQueryClient = (): QueryClient => {
5768
6413
  }
5769
6414
  return client;
5770
6415
  };
5771
- `,er=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
6416
+ `,xr=`import { QueryClient, type QueryClientConfig } from "@tanstack/svelte-query";
5772
6417
 
5773
6418
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
5774
6419
 
@@ -5791,7 +6436,7 @@ export const getQueryClient = (): QueryClient => {
5791
6436
  }
5792
6437
  return ctx.tsqClient as QueryClient;
5793
6438
  };
5794
- `,tr=`import type { RouterFactoryReturn } from "@kosmojs/core";
6439
+ `,Sr=`import type { RouterFactoryReturn } from "@kosmojs/core";
5795
6440
  import { createRouterFactory } from "@kosmojs/core/generators";
5796
6441
 
5797
6442
  import Layouts from "./Layouts.svelte";
@@ -5831,7 +6476,7 @@ export default createRouterFactory<
5831
6476
  Promise<RouteComponent>,
5832
6477
  { server: { route: Route } }
5833
6478
  >();
5834
- `,nr=`import { match, pathToRegexp } from "path-to-regexp";
6479
+ `,Cr=`import { match, pathToRegexp } from "path-to-regexp";
5835
6480
  import { type Component, createContext } from "svelte";
5836
6481
 
5837
6482
  import { parseSearchParams } from "@kosmojs/core";
@@ -6033,7 +6678,11 @@ export const createRoute = (
6033
6678
  loader: RawRoute["loader"],
6034
6679
  layouts: RawRoute["layouts"],
6035
6680
  ): RawRoute => {
6036
- const path = \`\${base}/\${pathPattern}\`.replace(/\\/+/g, "/");
6681
+ // strip trailing slash (keeping a sole "/") so the base-joined index route
6682
+ // matches both with and without it - "/docs/" as a pattern rejects "/docs"
6683
+ const path = \`\${base}/\${pathPattern}\`
6684
+ .replace(/\\/+/g, "/")
6685
+ .replace(/(.+)\\/$/, "$1");
6037
6686
 
6038
6687
  const { regexp } = pathToRegexp(path, { sensitive: true });
6039
6688
  const matcher = match<Route["params"]>(path);
@@ -6041,9 +6690,11 @@ export const createRoute = (
6041
6690
  return {
6042
6691
  name,
6043
6692
  regexp,
6693
+ // count segments of the same base-joined path the regexp matches against;
6694
+ // resolve() compares this against the full url pathname's segment count
6044
6695
  pathSegments: name.includes("...")
6045
6696
  ? undefined
6046
- : name.replace(/^index(\\/?|$)/, "").split("/").length,
6697
+ : path.split("/").filter(Boolean).length,
6047
6698
  extractParams: (path) => {
6048
6699
  const match = matcher(path);
6049
6700
  return match ? match.params : {};
@@ -6052,7 +6703,7 @@ export const createRoute = (
6052
6703
  layouts,
6053
6704
  };
6054
6705
  };
6055
- `,rr=`import { getRouteContext } from "./svelte";
6706
+ `,wr=`import { getRouteContext } from "./svelte";
6056
6707
 
6057
6708
  import type { ParamsMap, paramNames } from "{{ createImport 'lib' 'params' }}";
6058
6709
 
@@ -6092,7 +6743,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
6092
6743
  const route = useRoute();
6093
6744
  return route.loaderData?.[key || route.name] as T;
6094
6745
  };
6095
- `,ir=`<script lang="ts">
6746
+ `,Tr=`<script lang="ts">
6096
6747
  import { AppProvider } from "{{ createImport 'lib' 'app' }}";
6097
6748
  import type { Snippet } from "svelte";
6098
6749
 
@@ -6102,7 +6753,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
6102
6753
  <AppProvider>
6103
6754
  {@render children()}
6104
6755
  </AppProvider>
6105
- `,ar=`<script lang="ts">
6756
+ `,Er=`<script lang="ts">
6106
6757
  import type { Snippet } from "svelte";
6107
6758
  import type { HTMLAnchorAttributes } from "svelte/elements";
6108
6759
 
@@ -6121,12 +6772,12 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
6121
6772
 
6122
6773
  const href = $derived.by(() => {
6123
6774
  const [key, ...params] = to;
6124
- return pageRouteMap[key]?.base(params as never, query);
6775
+ return pageRouteMap[key]?.path(params as never, query);
6125
6776
  });
6126
6777
  <\/script>
6127
6778
 
6128
6779
  <a {href} {...rest}>{@render children?.()}</a>
6129
- `,or=`import renderFactory, {
6780
+ `,Dr=`import renderFactory, {
6130
6781
  createRoutes,
6131
6782
  hydrate,
6132
6783
  mount,
@@ -6153,7 +6804,7 @@ if (root) {
6153
6804
  } else {
6154
6805
  console.error("❌ Root element not found!");
6155
6806
  }
6156
- `,sr=`import renderFactory, {
6807
+ `,Or=`import renderFactory, {
6157
6808
  createRoutes,
6158
6809
  renderToString,
6159
6810
  // no renderToStream on Svelte folders
@@ -6174,7 +6825,7 @@ export default renderFactory(() => {
6174
6825
  },
6175
6826
  };
6176
6827
  });
6177
- `,cr=`<!doctype html>
6828
+ `,kr=`<!doctype html>
6178
6829
  <html lang="en">
6179
6830
  <head>
6180
6831
  <meta charset="UTF-8" />
@@ -6186,19 +6837,19 @@ export default renderFactory(() => {
6186
6837
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
6187
6838
  </body>
6188
6839
  </html>
6189
- `,lr=`<script lang="ts">
6840
+ `,Ar=`<script lang="ts">
6190
6841
  import PageSample from "{{ createImport 'lib' 'pageSamples/404.svelte' }}";
6191
6842
  <\/script>
6192
6843
 
6193
6844
  <PageSample />
6194
- `,ur=`<script lang="ts">
6845
+ `,jr=`<script lang="ts">
6195
6846
  import type { Snippet } from "svelte";
6196
6847
 
6197
6848
  let { children }: { children: Snippet } = $props();
6198
6849
  <\/script>
6199
6850
 
6200
6851
  {@render children()}
6201
- `,dr=`<script lang="ts">
6852
+ `,Mr=`<script lang="ts">
6202
6853
  import PageSample from "{{ createImport 'lib' 'pageSamples/page.svelte' }}";
6203
6854
 
6204
6855
  const pathMap = {
@@ -6217,7 +6868,7 @@ export default renderFactory(() => {
6217
6868
  routeName={"{{route.name}}"}
6218
6869
  {pathMap}
6219
6870
  />
6220
- `,fr=`<script lang="ts">
6871
+ `,Nr=`<script lang="ts">
6221
6872
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.svelte' }}";
6222
6873
  <\/script>
6223
6874
 
@@ -6230,7 +6881,7 @@ export default renderFactory(() => {
6230
6881
  </svelte:head>
6231
6882
 
6232
6883
  <WelcomePage />
6233
- `,pr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
6884
+ `,Pr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
6234
6885
 
6235
6886
  import app from "./app.svelte";
6236
6887
 
@@ -6245,7 +6896,7 @@ export default routerFactory((routes) => {
6245
6896
  },
6246
6897
  };
6247
6898
  });
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";
6899
+ `,Fr=g((e,t)=>{let{createPath:n,createImportHelpers:r}=y(e),{renderToFile:i}=x({helpers:{...r({origin:`lib`}),...w()}}),{renderToFile:a}=x({helpers:r({origin:`src`})}),o=e=>!e?.trim().length,s=c(t?.templates,Mr),u=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?Nr:s(r.name,r),{route:r,title:r.name.replace(/\{([^}]+)\}/g,`$1`),message:lr()},{overwrite:o}):t===`pageLayout`&&await a(n.pages(r.file),jr,{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(S)}]}return[]}).sort(S);for(let[e,a]of[[`client.ts`,dr],[`server.ts`,fr]])await i(n.libEntry(e),a,{pageRoutes:r,layouts:t});for(let[e,t]of[[`params.ts`,yr],[`router.ts`,Sr]])await i(n.lib(e),t,{pageRoutes:r})};return{config(){let{templates:e,...n}={...t};return{plugins:fe(n)}},async start(){for(let[e,r]of[[`env.d.ts`,pr],[`svelte.ts`,Cr],[`Layouts.svelte`,mr],[`use.ts`,wr],[`pageSamples/styles.module.css`,_r],[`pageSamples/welcome.svelte`,vr],[`pageSamples/page.svelte`,gr],[`pageSamples/404.svelte`,hr],...t?.tanstack?.query?[[`app/app.svelte`,Y],[`app/app-tsq.svelte`,ur],[`app/index.ts`,`export { default as AppProvider } from "./app-tsq.svelte";`],[`query.ts`,br]]:[[`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`,Ar],[`components/Link.svelte`,Er],[`app.svelte`,Tr],[`router.ts`,Pr]])await a(n.src(e),t,{entryDir:l.entryDir},{overwrite:o});await a(n.src(`index.html`),kr,{entryDir:l.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,Dr],[`server.ts`,Or]])await a(n.entry(e),t,{},{overwrite:o})},async watch(e,t){await u(e.filter(m(t,[`create`]))),await d(e)},async build(e){await u(e),await d(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?xr:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),Ir=h({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}),Lr={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.16`}},Rr=`import Type from "typebox";
6249
6900
 
6250
6901
  /**
6251
6902
  * Custom types for JavaScript constructs that have no JSON Schema
@@ -6317,7 +6968,7 @@ export default {
6317
6968
  Buffer: TBuffer(),
6318
6969
  ArrayBuffer: TArrayBuffer(),
6319
6970
  };
6320
- `,vr=`import type { TValidationError } from "typebox/error";
6971
+ `,zr=`import type { TValidationError } from "typebox/error";
6321
6972
 
6322
6973
  import type { ValidationErrorEntry } from "@kosmojs/core";
6323
6974
 
@@ -7501,7 +8152,7 @@ const format = (fmt: string, ...args: unknown[]): string => {
7501
8152
 
7502
8153
  return str;
7503
8154
  };
7504
- `,yr=`import Type from "typebox";
8155
+ `,Br=`import Type from "typebox";
7505
8156
  import { Compile } from "typebox/compile";
7506
8157
  import Value from "typebox/value";
7507
8158
 
@@ -7553,14 +8204,14 @@ export const validationSchemaFactory = (
7553
8204
  },
7554
8205
  };
7555
8206
  };
7556
- `,br=`import { Settings } from "typebox/system";
8207
+ `,Vr=`import { Settings } from "typebox/system";
7557
8208
 
7558
8209
  Settings.Set({{settings}});
7559
8210
 
7560
8211
  export { default as customTypes } from "{{customTypesImport}}";
7561
8212
 
7562
8213
  export const validationMessages = {{validationMessages}};
7563
- `,xr=`import type { ValidationSchemas } from "@kosmojs/core";
8214
+ `,Hr=`import type { ValidationSchemas } from "@kosmojs/core";
7564
8215
 
7565
8216
  import { validationSchemaFactory } from "{{ createImport 'lib' '@typebox' }}";
7566
8217
 
@@ -7621,14 +8272,14 @@ export const validationSchemas: ValidationSchemas = {
7621
8272
  {{/each}}
7622
8273
  },
7623
8274
  };
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";
8275
+ `,Ur={exactOptionalPropertyTypes:!0},Wr=g((e,t)=>{let{createPath:n,createImport:r,createImportHelpers:i}=y(e),{renderToFile:a}=x({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(o).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 a(n.libApi(r.name,`schemas.ts`),Hr,{route:r,resolvedTypes:e,requestSchemas:i,responseSchemas:s})}};return{async start(){for(let[e,t]of[[`custom-types.ts`,Rr],[`error-handler.ts`,zr],[`index.ts`,Br],[`setup.ts`,Vr]])await a(n.lib(`@typebox`,e),t,{validationMessages:JSON.stringify(s),customTypesImport:c,settings:JSON.stringify({...Ur,...l})})},async watch(e,t){await u(e.filter(p(t,[`create`,`update`])))},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 Gr=h({meta:{name:`TypeBox`,resolveTypes:!0},dependencies:{typebox:Lr.devDependencies.typebox},factory:Wr}),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(`/`)},Kr=()=>{let e=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):t(`/`,Q(c)),d=c.at(-1);return e(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},qr=()=>{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)]},Jr=`import type { Plugin } from "vue";
7625
8276
 
7626
8277
  export { default as AppProvider } from "./provider.vue";
7627
8278
 
7628
8279
  export const appProvider: Plugin = {
7629
8280
  install() {},
7630
8281
  };
7631
- `,Or=`import { VueQueryPlugin } from "@tanstack/vue-query";
8282
+ `,Yr=`import { VueQueryPlugin } from "@tanstack/vue-query";
7632
8283
  import type { Plugin } from "vue";
7633
8284
 
7634
8285
  import { getQueryClient } from "../query";
@@ -7640,10 +8291,10 @@ export const appProvider: Plugin = {
7640
8291
  app.use(VueQueryPlugin, { queryClient: getQueryClient() });
7641
8292
  },
7642
8293
  };
7643
- `,kr=`<template>
8294
+ `,Xr=`<template>
7644
8295
  <slot />
7645
8296
  </template>
7646
- `,Ar=`import type { App } from "vue";
8297
+ `,Zr=`import type { App } from "vue";
7647
8298
  import type { RouterFactoryReturn } from "@kosmojs/core";
7648
8299
  import { clientRenderFactory } from "@kosmojs/core/generators";
7649
8300
 
@@ -7683,7 +8334,7 @@ export const mount = async (
7683
8334
  }
7684
8335
 
7685
8336
  export default clientRenderFactory();
7686
- `,jr=`{
8337
+ `,Qr=`{
7687
8338
  path: "{{path}}",
7688
8339
  {{#if name}}
7689
8340
  name: "{{name}}",
@@ -7701,7 +8352,7 @@ export default clientRenderFactory();
7701
8352
  children: [ {{#each children}}{{> routePartial}}, {{/each}}],
7702
8353
  {{/if}}
7703
8354
  }
7704
- `,Mr=`import type { App } from "vue";
8355
+ `,$r=`import type { App } from "vue";
7705
8356
 
7706
8357
  import {
7707
8358
  renderToString as renderToStringOrig,
@@ -7797,7 +8448,7 @@ export default serverRenderFactory();
7797
8448
  const component: DefineComponent<{}, {}, any>;
7798
8449
  export default component;
7799
8450
  }
7800
- `,Nr=`<script setup lang="ts">
8451
+ `,ei=`<script setup lang="ts">
7801
8452
  import styles from "./styles.module.css";
7802
8453
  defineProps<{
7803
8454
  headline?: string;
@@ -7836,7 +8487,7 @@ defineProps<{
7836
8487
  </div>
7837
8488
  </div>
7838
8489
  </template>
7839
- `,Pr=`<script setup lang="ts">
8490
+ `,ti=`<script setup lang="ts">
7840
8491
  import styles from "./styles.module.css";
7841
8492
  defineProps<{
7842
8493
  message: string;
@@ -7885,7 +8536,7 @@ defineProps<{
7885
8536
  </div>
7886
8537
  </div>
7887
8538
  </template>
7888
- `,Fr=`* {
8539
+ `,ni=`* {
7889
8540
  margin: 0;
7890
8541
  padding: 0;
7891
8542
  box-sizing: border-box;
@@ -8018,7 +8669,7 @@ defineProps<{
8018
8669
  align-items: center;
8019
8670
  gap: 0.25rem;
8020
8671
  }
8021
- `,Ir=`<script setup lang="ts">
8672
+ `,ri=`<script setup lang="ts">
8022
8673
  import styles from "./styles.module.css";
8023
8674
  <\/script>
8024
8675
 
@@ -8082,7 +8733,7 @@ import styles from "./styles.module.css";
8082
8733
  </div>
8083
8734
  </div>
8084
8735
  </template>
8085
- `,Lr=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8736
+ `,ii=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8086
8737
 
8087
8738
  let client: QueryClient | undefined;
8088
8739
 
@@ -8097,7 +8748,7 @@ export const getQueryClient = (): QueryClient => {
8097
8748
  }
8098
8749
  return client;
8099
8750
  };
8100
- `,Rr=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8751
+ `,ai=`import { QueryClient, type QueryClientConfig } from "@tanstack/vue-query";
8101
8752
 
8102
8753
  import { store } from "{{ createImport 'lib' '@ssr/base' }}";
8103
8754
 
@@ -8120,7 +8771,7 @@ export const getQueryClient = (): QueryClient => {
8120
8771
  }
8121
8772
  return ctx.tsqClient as QueryClient;
8122
8773
  };
8123
- `,zr=`import {
8774
+ `,oi=`import {
8124
8775
  type App,
8125
8776
  type Component,
8126
8777
  createApp,
@@ -8249,7 +8900,18 @@ export const createRouters = (
8249
8900
  // would otherwise skip the guard
8250
8901
  installLoaderGuard(router);
8251
8902
 
8252
- await router.push(url.pathname + url.search);
8903
+ let { pathname } = url;
8904
+
8905
+ if (base !== "/") {
8906
+ // strip the base from pushed paths
8907
+ if (pathname === base) {
8908
+ pathname = "/";
8909
+ } else if (pathname.startsWith(\`\${base}/\`)) {
8910
+ pathname = pathname.slice(base.length);
8911
+ }
8912
+ }
8913
+
8914
+ await router.push(pathname + url.search);
8253
8915
 
8254
8916
  await router.isReady();
8255
8917
 
@@ -8271,14 +8933,14 @@ export default createRouterFactory<
8271
8933
  Promise<App>,
8272
8934
  { server: { loaderData: Record<string, unknown> } }
8273
8935
  >();
8274
- `,Br=`import { type Ref, unref } from "vue";
8936
+ `,si=`import { type Ref, unref } from "vue";
8275
8937
 
8276
8938
  export type MaybeWrapped<T> = Ref<T> | T;
8277
8939
 
8278
8940
  export function unwrap<T>(value: MaybeWrapped<T>): T {
8279
8941
  return unref(value);
8280
8942
  }
8281
- `,Vr=`import { useRoute, useRouter } from "vue-router";
8943
+ `,ci=`import { useRoute, useRouter } from "vue-router";
8282
8944
 
8283
8945
  import type { RouterWithLoaderData } from "./router";
8284
8946
 
@@ -8293,7 +8955,7 @@ export const useLoaderData = <T>(key?: string): T | undefined => {
8293
8955
  const route = useRoute();
8294
8956
  return router.__loaderData?.[key || (route.name as string)] as T;
8295
8957
  };
8296
- `,Hr=`<script setup lang="ts">
8958
+ `,li=`<script setup lang="ts">
8297
8959
  import { AppProvider } from "_/app";
8298
8960
  <\/script>
8299
8961
 
@@ -8302,39 +8964,40 @@ import { AppProvider } from "_/app";
8302
8964
  <RouterView />
8303
8965
  </AppProvider>
8304
8966
  </template>
8305
- `,Ur=`<script setup lang="ts" generic="T extends LinkProps">
8967
+ `,ui=`<script setup lang="ts" generic="T extends LinkProps">
8306
8968
  import { computed } from "vue";
8307
8969
  import { RouterLink } from "vue-router";
8308
8970
 
8309
8971
  import { pageRouteMap, type LinkProps } from "{{ createImport 'libCore' }}";
8310
8972
 
8311
- interface Props {
8312
- to: T
8313
- query?: Record<string | number, unknown>
8314
- replace?: boolean
8315
- activeClass?: string
8316
- exactActiveClass?: string
8973
+ type Props = {
8974
+ to: T;
8975
+ query?: Record<string | number, unknown>;
8976
+ replace?: boolean;
8977
+ activeClass?: string;
8978
+ exactActiveClass?: string;
8317
8979
  }
8318
8980
 
8319
8981
  const props = defineProps<Props>();
8320
8982
 
8321
8983
  const href = computed(() => {
8322
- const [key, ...params] = props.to
8323
- return pageRouteMap[key]?.base(params as never, props.query)
8984
+ const [key, ...params] = props.to;
8985
+ return pageRouteMap[key]?.path(params as never, props.query, { prefix: false });
8324
8986
  })
8987
+
8988
+ const linkProps = computed(() => ({
8989
+ ...(props.replace !== undefined ? { replace: props.replace } : {}),
8990
+ ...(props.activeClass !== undefined ? { activeClass: props.activeClass } : {}),
8991
+ ...(props.exactActiveClass !== undefined ? { exactActiveClass: props.exactActiveClass } : {}),
8992
+ }))
8325
8993
  <\/script>
8326
8994
 
8327
8995
  <template>
8328
- <RouterLink
8329
- :to="href"
8330
- :replace="replace"
8331
- :active-class="activeClass"
8332
- :exact-active-class="exactActiveClass"
8333
- >
8996
+ <RouterLink :to="href" v-bind="linkProps">
8334
8997
  <slot />
8335
8998
  </RouterLink>
8336
8999
  </template>
8337
- `,Wr=`import renderFactory, {
9000
+ `,di=`import renderFactory, {
8338
9001
  createRoutes,
8339
9002
  hydrate,
8340
9003
  mount,
@@ -8361,7 +9024,7 @@ if (root) {
8361
9024
  } else {
8362
9025
  console.error("❌ Root element not found!");
8363
9026
  }
8364
- `,Gr=`import renderFactory, {
9027
+ `,fi=`import renderFactory, {
8365
9028
  createRoutes,
8366
9029
  renderToStream,
8367
9030
  renderToString,
@@ -8388,7 +9051,7 @@ export default renderFactory(() => {
8388
9051
  },
8389
9052
  };
8390
9053
  });
8391
- `,Kr=`<!doctype html>
9054
+ `,pi=`<!doctype html>
8392
9055
  <html lang="en">
8393
9056
  <head>
8394
9057
  <meta charset="UTF-8" />
@@ -8400,17 +9063,17 @@ export default renderFactory(() => {
8400
9063
  <script type="module" src="/{{ entryDir }}/client.ts"><\/script>
8401
9064
  </body>
8402
9065
  </html>
8403
- `,qr=`<script setup lang="ts">
9066
+ `,mi=`<script setup lang="ts">
8404
9067
  import PageSample from "{{ createImport 'lib' 'pageSamples/404.vue' }}";
8405
9068
  <\/script>
8406
9069
 
8407
9070
  <template>
8408
9071
  <PageSample />
8409
9072
  </template>
8410
- `,Jr=`<template>
9073
+ `,hi=`<template>
8411
9074
  <router-view />
8412
9075
  </template>
8413
- `,Yr=`<script setup lang="ts">
9076
+ `,gi=`<script setup lang="ts">
8414
9077
  import PageSample from "{{ createImport 'lib' 'pageSamples/page.vue' }}";
8415
9078
  <\/script>
8416
9079
 
@@ -8425,14 +9088,14 @@ import PageSample from "{{ createImport 'lib' 'pageSamples/page.vue' }}";
8425
9088
  }"
8426
9089
  />
8427
9090
  </template>
8428
- `,Xr=`<script setup lang="ts">
9091
+ `,_i=`<script setup lang="ts">
8429
9092
  import WelcomePage from "{{ createImport 'lib' 'pageSamples/welcome.vue' }}";
8430
9093
  <\/script>
8431
9094
 
8432
9095
  <template>
8433
9096
  <WelcomePage />
8434
9097
  </template>
8435
- `,Zr=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
9098
+ `,vi=`import routerFactory, { createRouters } from "{{ createImport 'lib' 'router' }}";
8436
9099
  import { appProvider } from "{{ createImport 'lib' 'app' }}";
8437
9100
 
8438
9101
  import app from "./app.vue";
@@ -8451,5 +9114,5 @@ export default routerFactory((routes) => {
8451
9114
  },
8452
9115
  };
8453
9116
  });
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};
9117
+ `,yi=g((e,t)=>{let{createPath:n,createImportHelpers:r}=y(e),{renderToFile:i}=x({helpers:{...r({origin:`lib`}),...w()},partials:{routePartial:Qr}}),{renderToFile:a}=x({helpers:r({origin:`src`})}),o=Kr(),s=e=>!e?.trim().length,u=c(t?.templates,gi),d=async e=>{for(let{kind:t,entry:r}of e)t===`pageRoute`?await a(n.pages(r.file),r.name===`index`?_i:u(r.name,r),{route:r,message:qr()},{overwrite:s}):t===`pageLayout`&&await a(n.pages(r.file),hi,{route:r},{overwrite:s})},f=async e=>{let t=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`?[t]:[]).sort(S),r=e.flatMap(({kind:e,entry:t})=>e===`pageRoute`||e===`pageLayout`?[t]:[]),a=o(v(r));for(let[e,t]of[[`client.ts`,Zr],[`server.ts`,$r]])await i(n.libEntry(e),t,{pageEntries:r,nestedRoutes:a,lazyLoad:e===`client.ts`});await i(n.lib(`router.ts`),oi,{entries:e,indexRoutes:t})};return{config(){let{templates:e,...n}={...t};return{plugins:[pe(n)]}},async start(){for(let[e,r]of[[`env.d.ts`,$],[`unwrap.ts`,si],[`use.ts`,ci],[`pageSamples/styles.module.css`,ni],[`pageSamples/welcome.vue`,ri],[`pageSamples/page.vue`,ti],[`pageSamples/404.vue`,ei],[`app/provider.vue`,Xr],...t?.tanstack?.query?[[`app/index.ts`,Yr],[`query.ts`,ii]]:[[`app/index.ts`,Jr],[`query.ts`,`/** tanstack query disabled */`]]])await i(n.lib(e),r,{});for(let[e,t]of[[`pages/404.vue`,mi],[`components/Link.vue`,ui],[`app.vue`,li],[`router.ts`,vi]])await a(n.src(e),t,{entryDir:l.entryDir},{overwrite:s});await a(n.src(`index.html`),pi,{entryDir:l.entryDir},{overwrite:e=>!e?.trim().length||!e.replace(/<!--[\s\S]*?-->/g,``).trim().length});for(let[e,t]of[[`client.ts`,di],[`server.ts`,fi]])await a(n.entry(e),t,{},{overwrite:s})},async watch(e,t){await d(e.filter(m(t,[`create`]))),await f(e)},async build(e){await d(e),await f(e)},async ssrBuild(){await i(n.lib(`query.ts`),t?.tanstack?.query?ai:`/** tanstack query disabled */`,{ssrBundle:!0})}}}),bi=h({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:yi}),xi=e=>{let n=process.env.NODE_ENV||`development`,a=typeof e.base==`string`?e.base:e.base[n];if(!a?.trim())throw Error(r([`red`],`ERROR: Invalid Config - no base provided`));return{...e,base:t(`/`,a),apiBase:t(`/`,e.apiBase||i)}};export{e as coreGenerator,xi as defineConfig,I as fetchGenerator,ke as h3Generator,Je as honoGenerator,pt as koaGenerator,Ht as mdxGenerator,qt as openapiGenerator,Sn as reactGenerator,Xn as solidGenerator,$n as ssgGenerator,cr as ssrGenerator,Ir as svelteGenerator,Gr as typeboxGenerator,bi as vueGenerator};
8455
9118
  //# sourceMappingURL=index.js.map