@json-render/next 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server.d.mts +118 -29
- package/dist/server.d.ts +118 -29
- package/dist/server.js +40 -33
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +40 -33
- package/dist/server.mjs.map +1 -1
- package/package.json +3 -3
package/dist/server.d.mts
CHANGED
|
@@ -230,15 +230,52 @@ declare function createNextApp(options: CreateNextAppOptions): NextAppExports;
|
|
|
230
230
|
declare const schema: _json_render_core.Schema<{
|
|
231
231
|
spec: _json_render_core.SchemaType<"object", {
|
|
232
232
|
/** Root-level metadata applied as defaults */
|
|
233
|
-
metadata:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
233
|
+
metadata: {
|
|
234
|
+
optional: true;
|
|
235
|
+
kind: "object";
|
|
236
|
+
inner?: {
|
|
237
|
+
title: {
|
|
238
|
+
optional: true;
|
|
239
|
+
kind: "any";
|
|
240
|
+
inner?: unknown;
|
|
241
|
+
};
|
|
242
|
+
description: {
|
|
243
|
+
optional: true;
|
|
244
|
+
kind: "string";
|
|
245
|
+
inner?: unknown;
|
|
246
|
+
};
|
|
247
|
+
keywords: {
|
|
248
|
+
optional: true;
|
|
249
|
+
kind: "array";
|
|
250
|
+
inner?: _json_render_core.SchemaType<"string", unknown> | undefined;
|
|
251
|
+
};
|
|
252
|
+
openGraph: {
|
|
253
|
+
optional: true;
|
|
254
|
+
kind: "any";
|
|
255
|
+
inner?: unknown;
|
|
256
|
+
};
|
|
257
|
+
twitter: {
|
|
258
|
+
optional: true;
|
|
259
|
+
kind: "any";
|
|
260
|
+
inner?: unknown;
|
|
261
|
+
};
|
|
262
|
+
robots: {
|
|
263
|
+
optional: true;
|
|
264
|
+
kind: "any";
|
|
265
|
+
inner?: unknown;
|
|
266
|
+
};
|
|
267
|
+
alternates: {
|
|
268
|
+
optional: true;
|
|
269
|
+
kind: "any";
|
|
270
|
+
inner?: unknown;
|
|
271
|
+
};
|
|
272
|
+
icons: {
|
|
273
|
+
optional: true;
|
|
274
|
+
kind: "any";
|
|
275
|
+
inner?: unknown;
|
|
276
|
+
};
|
|
277
|
+
} | undefined;
|
|
278
|
+
};
|
|
242
279
|
/** Route definitions keyed by URL pattern */
|
|
243
280
|
routes: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
244
281
|
/** Page element tree */
|
|
@@ -248,38 +285,90 @@ declare const schema: _json_render_core.Schema<{
|
|
|
248
285
|
type: _json_render_core.SchemaType<"ref", string>;
|
|
249
286
|
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
250
287
|
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
251
|
-
visible:
|
|
288
|
+
visible: {
|
|
289
|
+
optional: true;
|
|
290
|
+
kind: "any";
|
|
291
|
+
inner?: unknown;
|
|
292
|
+
};
|
|
252
293
|
}>>;
|
|
253
|
-
state:
|
|
294
|
+
state: {
|
|
295
|
+
optional: true;
|
|
296
|
+
kind: "any";
|
|
297
|
+
inner?: unknown;
|
|
298
|
+
};
|
|
254
299
|
}>;
|
|
255
300
|
/** Per-route metadata */
|
|
256
|
-
metadata:
|
|
301
|
+
metadata: {
|
|
302
|
+
optional: true;
|
|
303
|
+
kind: "any";
|
|
304
|
+
inner?: unknown;
|
|
305
|
+
};
|
|
257
306
|
/** Layout key */
|
|
258
|
-
layout:
|
|
307
|
+
layout: {
|
|
308
|
+
optional: true;
|
|
309
|
+
kind: "string";
|
|
310
|
+
inner?: unknown;
|
|
311
|
+
};
|
|
259
312
|
/** Loading state element tree */
|
|
260
|
-
loading:
|
|
313
|
+
loading: {
|
|
314
|
+
optional: true;
|
|
315
|
+
kind: "any";
|
|
316
|
+
inner?: unknown;
|
|
317
|
+
};
|
|
261
318
|
/** Error state element tree */
|
|
262
|
-
error:
|
|
319
|
+
error: {
|
|
320
|
+
optional: true;
|
|
321
|
+
kind: "any";
|
|
322
|
+
inner?: unknown;
|
|
323
|
+
};
|
|
263
324
|
/** Not-found element tree */
|
|
264
|
-
notFound:
|
|
325
|
+
notFound: {
|
|
326
|
+
optional: true;
|
|
327
|
+
kind: "any";
|
|
328
|
+
inner?: unknown;
|
|
329
|
+
};
|
|
265
330
|
/** Server-side data loader name */
|
|
266
|
-
loader:
|
|
331
|
+
loader: {
|
|
332
|
+
optional: true;
|
|
333
|
+
kind: "string";
|
|
334
|
+
inner?: unknown;
|
|
335
|
+
};
|
|
267
336
|
/** Static params for SSG */
|
|
268
|
-
staticParams:
|
|
337
|
+
staticParams: {
|
|
338
|
+
optional: true;
|
|
339
|
+
kind: "any";
|
|
340
|
+
inner?: unknown;
|
|
341
|
+
};
|
|
269
342
|
}>>;
|
|
270
343
|
/** Reusable layout element trees */
|
|
271
|
-
layouts:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
344
|
+
layouts: {
|
|
345
|
+
optional: true;
|
|
346
|
+
kind: "record";
|
|
347
|
+
inner?: _json_render_core.SchemaType<"object", {
|
|
348
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
349
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
350
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
351
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
352
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
353
|
+
visible: {
|
|
354
|
+
optional: true;
|
|
355
|
+
kind: "any";
|
|
356
|
+
inner?: unknown;
|
|
357
|
+
};
|
|
358
|
+
}>>;
|
|
359
|
+
state: {
|
|
360
|
+
optional: true;
|
|
361
|
+
kind: "any";
|
|
362
|
+
inner?: unknown;
|
|
363
|
+
};
|
|
364
|
+
}> | undefined;
|
|
365
|
+
};
|
|
281
366
|
/** Global initial state */
|
|
282
|
-
state:
|
|
367
|
+
state: {
|
|
368
|
+
optional: true;
|
|
369
|
+
kind: "any";
|
|
370
|
+
inner?: unknown;
|
|
371
|
+
};
|
|
283
372
|
}>;
|
|
284
373
|
catalog: _json_render_core.SchemaType<"object", {
|
|
285
374
|
/** Component definitions */
|
package/dist/server.d.ts
CHANGED
|
@@ -230,15 +230,52 @@ declare function createNextApp(options: CreateNextAppOptions): NextAppExports;
|
|
|
230
230
|
declare const schema: _json_render_core.Schema<{
|
|
231
231
|
spec: _json_render_core.SchemaType<"object", {
|
|
232
232
|
/** Root-level metadata applied as defaults */
|
|
233
|
-
metadata:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
233
|
+
metadata: {
|
|
234
|
+
optional: true;
|
|
235
|
+
kind: "object";
|
|
236
|
+
inner?: {
|
|
237
|
+
title: {
|
|
238
|
+
optional: true;
|
|
239
|
+
kind: "any";
|
|
240
|
+
inner?: unknown;
|
|
241
|
+
};
|
|
242
|
+
description: {
|
|
243
|
+
optional: true;
|
|
244
|
+
kind: "string";
|
|
245
|
+
inner?: unknown;
|
|
246
|
+
};
|
|
247
|
+
keywords: {
|
|
248
|
+
optional: true;
|
|
249
|
+
kind: "array";
|
|
250
|
+
inner?: _json_render_core.SchemaType<"string", unknown> | undefined;
|
|
251
|
+
};
|
|
252
|
+
openGraph: {
|
|
253
|
+
optional: true;
|
|
254
|
+
kind: "any";
|
|
255
|
+
inner?: unknown;
|
|
256
|
+
};
|
|
257
|
+
twitter: {
|
|
258
|
+
optional: true;
|
|
259
|
+
kind: "any";
|
|
260
|
+
inner?: unknown;
|
|
261
|
+
};
|
|
262
|
+
robots: {
|
|
263
|
+
optional: true;
|
|
264
|
+
kind: "any";
|
|
265
|
+
inner?: unknown;
|
|
266
|
+
};
|
|
267
|
+
alternates: {
|
|
268
|
+
optional: true;
|
|
269
|
+
kind: "any";
|
|
270
|
+
inner?: unknown;
|
|
271
|
+
};
|
|
272
|
+
icons: {
|
|
273
|
+
optional: true;
|
|
274
|
+
kind: "any";
|
|
275
|
+
inner?: unknown;
|
|
276
|
+
};
|
|
277
|
+
} | undefined;
|
|
278
|
+
};
|
|
242
279
|
/** Route definitions keyed by URL pattern */
|
|
243
280
|
routes: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
244
281
|
/** Page element tree */
|
|
@@ -248,38 +285,90 @@ declare const schema: _json_render_core.Schema<{
|
|
|
248
285
|
type: _json_render_core.SchemaType<"ref", string>;
|
|
249
286
|
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
250
287
|
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
251
|
-
visible:
|
|
288
|
+
visible: {
|
|
289
|
+
optional: true;
|
|
290
|
+
kind: "any";
|
|
291
|
+
inner?: unknown;
|
|
292
|
+
};
|
|
252
293
|
}>>;
|
|
253
|
-
state:
|
|
294
|
+
state: {
|
|
295
|
+
optional: true;
|
|
296
|
+
kind: "any";
|
|
297
|
+
inner?: unknown;
|
|
298
|
+
};
|
|
254
299
|
}>;
|
|
255
300
|
/** Per-route metadata */
|
|
256
|
-
metadata:
|
|
301
|
+
metadata: {
|
|
302
|
+
optional: true;
|
|
303
|
+
kind: "any";
|
|
304
|
+
inner?: unknown;
|
|
305
|
+
};
|
|
257
306
|
/** Layout key */
|
|
258
|
-
layout:
|
|
307
|
+
layout: {
|
|
308
|
+
optional: true;
|
|
309
|
+
kind: "string";
|
|
310
|
+
inner?: unknown;
|
|
311
|
+
};
|
|
259
312
|
/** Loading state element tree */
|
|
260
|
-
loading:
|
|
313
|
+
loading: {
|
|
314
|
+
optional: true;
|
|
315
|
+
kind: "any";
|
|
316
|
+
inner?: unknown;
|
|
317
|
+
};
|
|
261
318
|
/** Error state element tree */
|
|
262
|
-
error:
|
|
319
|
+
error: {
|
|
320
|
+
optional: true;
|
|
321
|
+
kind: "any";
|
|
322
|
+
inner?: unknown;
|
|
323
|
+
};
|
|
263
324
|
/** Not-found element tree */
|
|
264
|
-
notFound:
|
|
325
|
+
notFound: {
|
|
326
|
+
optional: true;
|
|
327
|
+
kind: "any";
|
|
328
|
+
inner?: unknown;
|
|
329
|
+
};
|
|
265
330
|
/** Server-side data loader name */
|
|
266
|
-
loader:
|
|
331
|
+
loader: {
|
|
332
|
+
optional: true;
|
|
333
|
+
kind: "string";
|
|
334
|
+
inner?: unknown;
|
|
335
|
+
};
|
|
267
336
|
/** Static params for SSG */
|
|
268
|
-
staticParams:
|
|
337
|
+
staticParams: {
|
|
338
|
+
optional: true;
|
|
339
|
+
kind: "any";
|
|
340
|
+
inner?: unknown;
|
|
341
|
+
};
|
|
269
342
|
}>>;
|
|
270
343
|
/** Reusable layout element trees */
|
|
271
|
-
layouts:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
344
|
+
layouts: {
|
|
345
|
+
optional: true;
|
|
346
|
+
kind: "record";
|
|
347
|
+
inner?: _json_render_core.SchemaType<"object", {
|
|
348
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
349
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
350
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
351
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
352
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
353
|
+
visible: {
|
|
354
|
+
optional: true;
|
|
355
|
+
kind: "any";
|
|
356
|
+
inner?: unknown;
|
|
357
|
+
};
|
|
358
|
+
}>>;
|
|
359
|
+
state: {
|
|
360
|
+
optional: true;
|
|
361
|
+
kind: "any";
|
|
362
|
+
inner?: unknown;
|
|
363
|
+
};
|
|
364
|
+
}> | undefined;
|
|
365
|
+
};
|
|
281
366
|
/** Global initial state */
|
|
282
|
-
state:
|
|
367
|
+
state: {
|
|
368
|
+
optional: true;
|
|
369
|
+
kind: "any";
|
|
370
|
+
inner?: unknown;
|
|
371
|
+
};
|
|
283
372
|
}>;
|
|
284
373
|
catalog: _json_render_core.SchemaType<"object", {
|
|
285
374
|
/** Component definitions */
|
package/dist/server.js
CHANGED
|
@@ -430,15 +430,19 @@ var schema = (0, import_core.defineSchema)(
|
|
|
430
430
|
(s) => ({
|
|
431
431
|
spec: s.object({
|
|
432
432
|
/** Root-level metadata applied as defaults */
|
|
433
|
-
metadata:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
433
|
+
metadata: {
|
|
434
|
+
...s.object({
|
|
435
|
+
title: { ...s.any(), ...s.optional() },
|
|
436
|
+
description: { ...s.string(), ...s.optional() },
|
|
437
|
+
keywords: { ...s.array(s.string()), ...s.optional() },
|
|
438
|
+
openGraph: { ...s.any(), ...s.optional() },
|
|
439
|
+
twitter: { ...s.any(), ...s.optional() },
|
|
440
|
+
robots: { ...s.any(), ...s.optional() },
|
|
441
|
+
alternates: { ...s.any(), ...s.optional() },
|
|
442
|
+
icons: { ...s.any(), ...s.optional() }
|
|
443
|
+
}),
|
|
444
|
+
...s.optional()
|
|
445
|
+
},
|
|
442
446
|
/** Route definitions keyed by URL pattern */
|
|
443
447
|
routes: s.record(
|
|
444
448
|
s.object({
|
|
@@ -450,44 +454,47 @@ var schema = (0, import_core.defineSchema)(
|
|
|
450
454
|
type: s.ref("catalog.components"),
|
|
451
455
|
props: s.propsOf("catalog.components"),
|
|
452
456
|
children: s.array(s.string()),
|
|
453
|
-
visible: s.any()
|
|
457
|
+
visible: { ...s.any(), ...s.optional() }
|
|
454
458
|
})
|
|
455
459
|
),
|
|
456
|
-
state: s.any()
|
|
460
|
+
state: { ...s.any(), ...s.optional() }
|
|
457
461
|
}),
|
|
458
462
|
/** Per-route metadata */
|
|
459
|
-
metadata: s.any(),
|
|
463
|
+
metadata: { ...s.any(), ...s.optional() },
|
|
460
464
|
/** Layout key */
|
|
461
|
-
layout: s.string(),
|
|
465
|
+
layout: { ...s.string(), ...s.optional() },
|
|
462
466
|
/** Loading state element tree */
|
|
463
|
-
loading: s.any(),
|
|
467
|
+
loading: { ...s.any(), ...s.optional() },
|
|
464
468
|
/** Error state element tree */
|
|
465
|
-
error: s.any(),
|
|
469
|
+
error: { ...s.any(), ...s.optional() },
|
|
466
470
|
/** Not-found element tree */
|
|
467
|
-
notFound: s.any(),
|
|
471
|
+
notFound: { ...s.any(), ...s.optional() },
|
|
468
472
|
/** Server-side data loader name */
|
|
469
|
-
loader: s.string(),
|
|
473
|
+
loader: { ...s.string(), ...s.optional() },
|
|
470
474
|
/** Static params for SSG */
|
|
471
|
-
staticParams: s.any()
|
|
475
|
+
staticParams: { ...s.any(), ...s.optional() }
|
|
472
476
|
})
|
|
473
477
|
),
|
|
474
478
|
/** Reusable layout element trees */
|
|
475
|
-
layouts:
|
|
476
|
-
s.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
s.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
479
|
+
layouts: {
|
|
480
|
+
...s.record(
|
|
481
|
+
s.object({
|
|
482
|
+
root: s.string(),
|
|
483
|
+
elements: s.record(
|
|
484
|
+
s.object({
|
|
485
|
+
type: s.ref("catalog.components"),
|
|
486
|
+
props: s.propsOf("catalog.components"),
|
|
487
|
+
children: s.array(s.string()),
|
|
488
|
+
visible: { ...s.any(), ...s.optional() }
|
|
489
|
+
})
|
|
490
|
+
),
|
|
491
|
+
state: { ...s.any(), ...s.optional() }
|
|
492
|
+
})
|
|
493
|
+
),
|
|
494
|
+
...s.optional()
|
|
495
|
+
},
|
|
489
496
|
/** Global initial state */
|
|
490
|
-
state: s.any()
|
|
497
|
+
state: { ...s.any(), ...s.optional() }
|
|
491
498
|
}),
|
|
492
499
|
catalog: s.object({
|
|
493
500
|
/** Component definitions */
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/router.ts","../src/metadata.ts","../src/create-app.ts","../src/schema.ts"],"sourcesContent":["/**\n * @json-render/next/server — Server-safe exports\n *\n * This entry point does not import any client components or React hooks.\n * Safe to use in:\n * - Server Components\n * - API routes\n * - Build scripts\n * - Server Actions\n *\n * @example\n * ```ts\n * import { createNextApp, schema } from \"@json-render/next/server\";\n * ```\n */\n\n// createNextApp (main API)\nexport { createNextApp } from \"./create-app\";\n\n// Schema (Next.js app spec format)\nexport { schema, type NextSchema, type NextSpec } from \"./schema\";\n\n// Router utilities\nexport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\n\n// Metadata resolution\nexport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n// Types\nexport type {\n NextAppSpec,\n NextRouteSpec,\n NextMetadata,\n MatchedRoute,\n LoaderFn,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\n\n// Catalog types (type-only, no runtime)\nexport type {\n EventHandle,\n BaseComponentProps,\n SetState,\n StateModel,\n ComponentContext,\n ComponentFn,\n Components,\n ActionFn,\n Actions,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec, StateStore } from \"@json-render/core\";\n","import type { NextAppSpec, MatchedRoute } from \"./types\";\n\ninterface CompiledRoute {\n pattern: string;\n regex: RegExp;\n paramNames: string[];\n /** Whether the last segment is catch-all or optional catch-all */\n catchAll: boolean;\n optionalCatchAll: boolean;\n /** Number of static segments (higher = more specific) */\n specificity: number;\n}\n\n/**\n * Compile a Next.js route pattern into a regex matcher.\n *\n * Supports:\n * - Static segments: `/about`, `/blog`\n * - Dynamic segments: `/blog/[slug]`\n * - Catch-all segments: `/docs/[...path]`\n * - Optional catch-all segments: `/settings/[[...path]]`\n */\nfunction compileRoute(pattern: string): CompiledRoute {\n const paramNames: string[] = [];\n let catchAll = false;\n let optionalCatchAll = false;\n let specificity = 0;\n\n const segments = pattern === \"/\" ? [\"\"] : pattern.split(\"/\").slice(1);\n const regexParts: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n paramNames.push(paramName);\n optionalCatchAll = true;\n regexParts.push(\"(?:/(.+))?\");\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n paramNames.push(paramName);\n catchAll = true;\n regexParts.push(\"/(.+)\");\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n paramNames.push(paramName);\n regexParts.push(\"/([^/]+)\");\n } else {\n specificity++;\n regexParts.push(`/${escapeRegExp(segment)}`);\n }\n }\n\n const regexStr = pattern === \"/\" ? \"^/$\" : `^${regexParts.join(\"\")}$`;\n\n return {\n pattern,\n regex: new RegExp(regexStr),\n paramNames,\n catchAll,\n optionalCatchAll,\n specificity,\n };\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Match a pathname against a spec's routes.\n *\n * Routes are matched in order of specificity:\n * 1. Exact/static matches first (most specific)\n * 2. Dynamic segment matches\n * 3. Catch-all matches (least specific)\n * 4. Optional catch-all matches (fallback)\n *\n * @returns The matched route with extracted params, or null if no match.\n */\nexport function matchRoute(\n spec: NextAppSpec,\n pathname: string,\n): MatchedRoute | null {\n const normalizedPath = pathname === \"\" ? \"/\" : pathname;\n\n const compiled = Object.keys(spec.routes).map(compileRoute);\n\n compiled.sort((a, b) => {\n if (a.optionalCatchAll !== b.optionalCatchAll) {\n return a.optionalCatchAll ? 1 : -1;\n }\n if (a.catchAll !== b.catchAll) {\n return a.catchAll ? 1 : -1;\n }\n if (a.specificity !== b.specificity) {\n return b.specificity - a.specificity;\n }\n return a.paramNames.length - b.paramNames.length;\n });\n\n for (const route of compiled) {\n const match = route.regex.exec(normalizedPath);\n if (!match) continue;\n\n const params: Record<string, string | string[]> = {};\n for (let i = 0; i < route.paramNames.length; i++) {\n const value = match[i + 1];\n const name = route.paramNames[i]!;\n\n if (route.catchAll || route.optionalCatchAll) {\n params[name] = value ? value.split(\"/\") : [];\n } else {\n params[name] = value ?? \"\";\n }\n }\n\n return {\n route: spec.routes[route.pattern]!,\n pattern: route.pattern,\n params,\n };\n }\n\n return null;\n}\n\n/**\n * Convert a Next.js catch-all slug array to a pathname.\n *\n * @example\n * slugToPath(undefined) // \"/\"\n * slugToPath([]) // \"/\"\n * slugToPath([\"blog\"]) // \"/blog\"\n * slugToPath([\"blog\",\"hi\"]) // \"/blog/hi\"\n */\nexport function slugToPath(slug: string[] | undefined): string {\n if (!slug || slug.length === 0) return \"/\";\n return \"/\" + slug.join(\"/\");\n}\n\n/**\n * Collect all static params from the spec for generateStaticParams.\n * Returns params suitable for Next.js [[...slug]] catch-all routes.\n */\nexport function collectStaticParams(spec: NextAppSpec): { slug: string[] }[] {\n const results: { slug: string[] }[] = [];\n\n for (const [pattern, route] of Object.entries(spec.routes)) {\n if (route.staticParams) {\n for (const paramSet of route.staticParams) {\n const slug = buildSlugFromPattern(pattern, paramSet);\n if (slug) results.push({ slug });\n }\n } else if (!pattern.includes(\"[\")) {\n const slug = pattern === \"/\" ? [] : pattern.slice(1).split(\"/\");\n results.push({ slug });\n }\n }\n\n return results;\n}\n\n/**\n * Build a slug array from a route pattern and a set of params.\n */\nfunction buildSlugFromPattern(\n pattern: string,\n params: Record<string, string>,\n): string[] | null {\n if (pattern === \"/\") return [];\n\n const segments = pattern.split(\"/\").slice(1);\n const result: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n const value = params[paramName];\n if (value) result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(value);\n } else {\n result.push(segment);\n }\n }\n\n return result;\n}\n","import type { NextMetadata, NextAppSpec, NextRouteSpec } from \"./types\";\n\n/**\n * Metadata result compatible with Next.js's Metadata type.\n * Uses plain objects to avoid importing Next.js types at runtime.\n */\nexport type ResolvedMetadata = Record<string, unknown>;\n\n/**\n * Resolve metadata for a route by merging global spec metadata\n * with route-specific metadata.\n *\n * Follows Next.js metadata merging semantics:\n * - Route metadata overrides global metadata for scalar fields\n * - Title templates from global metadata apply to route titles\n * - OpenGraph and Twitter fields are shallow-merged\n */\nexport function resolveMetadata(\n spec: NextAppSpec,\n route?: NextRouteSpec | null,\n): ResolvedMetadata {\n const globalMeta = spec.metadata;\n const routeMeta = route?.metadata;\n\n if (!globalMeta && !routeMeta) return {};\n\n const result: ResolvedMetadata = {};\n\n const mergedTitle = resolveTitle(globalMeta?.title, routeMeta?.title);\n if (mergedTitle !== undefined) result.title = mergedTitle;\n\n const description = routeMeta?.description ?? globalMeta?.description;\n if (description) result.description = description;\n\n const keywords = routeMeta?.keywords ?? globalMeta?.keywords;\n if (keywords) result.keywords = keywords;\n\n const openGraph = mergeObject(globalMeta?.openGraph, routeMeta?.openGraph);\n if (openGraph) result.openGraph = openGraph;\n\n const twitter = mergeObject(globalMeta?.twitter, routeMeta?.twitter);\n if (twitter) result.twitter = twitter;\n\n const robots = routeMeta?.robots ?? globalMeta?.robots;\n if (robots) result.robots = robots;\n\n const alternates = routeMeta?.alternates ?? globalMeta?.alternates;\n if (alternates) result.alternates = alternates;\n\n const icons = routeMeta?.icons ?? globalMeta?.icons;\n if (icons) result.icons = icons;\n\n return result;\n}\n\n/**\n * Resolve a title value considering templates.\n *\n * If global metadata defines a title template (e.g. \"%s | My App\"),\n * route titles are interpolated into it.\n */\nfunction resolveTitle(\n globalTitle: NextMetadata[\"title\"],\n routeTitle: NextMetadata[\"title\"],\n): unknown {\n if (!routeTitle && !globalTitle) return undefined;\n\n if (!routeTitle) {\n if (typeof globalTitle === \"string\") return globalTitle;\n if (typeof globalTitle === \"object\" && globalTitle !== null) {\n return globalTitle.default ?? undefined;\n }\n return undefined;\n }\n\n if (typeof routeTitle === \"object\" && routeTitle !== null) {\n if (routeTitle.absolute) return routeTitle.absolute;\n if (routeTitle.template || routeTitle.default) return routeTitle;\n return routeTitle;\n }\n\n if (\n typeof globalTitle === \"object\" &&\n globalTitle !== null &&\n globalTitle.template\n ) {\n return globalTitle.template.replace(\"%s\", routeTitle as string);\n }\n\n return routeTitle;\n}\n\nfunction mergeObject(\n base: Record<string, unknown> | undefined,\n override: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !override) return undefined;\n if (!base) return override;\n if (!override) return base;\n return { ...base, ...override };\n}\n","import { notFound } from \"next/navigation\";\nimport type {\n NextAppSpec,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\nimport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\nimport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n/**\n * Resolve the spec from the options — supports both static specs\n * and factory functions that return specs (sync or async).\n */\nasync function resolveSpec(\n specOrFn: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>),\n): Promise<NextAppSpec> {\n if (typeof specOrFn === \"function\") {\n return await specOrFn();\n }\n return specOrFn;\n}\n\n/**\n * Merge state from multiple sources: global state, page state, and loader data.\n * Later sources override earlier ones.\n */\nfunction mergeState(\n ...sources: (Record<string, unknown> | undefined | null)[]\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const source of sources) {\n if (source) {\n Object.assign(result, source);\n }\n }\n return result;\n}\n\n/**\n * Create a fully wired Next.js application from a json-render spec.\n *\n * Returns `getPageData`, `generateMetadata`, and `generateStaticParams`\n * ready to be used in Next.js `[[...slug]]` catch-all routes.\n *\n * @example\n * ```typescript\n * // lib/app.ts\n * import { createNextApp } from \"@json-render/next/server\";\n *\n * export const { getPageData, generateMetadata, generateStaticParams } =\n * createNextApp({ spec });\n *\n * // app/[[...slug]]/page.tsx (Server Component)\n * import { notFound } from \"next/navigation\";\n * import { getPageData, generateMetadata, generateStaticParams } from \"@/lib/app\";\n * import { SiteRenderer } from \"./renderer\";\n *\n * export { generateMetadata, generateStaticParams };\n *\n * export default async function Page({ params }) {\n * const data = await getPageData({ params });\n * if (!data) notFound();\n * return <SiteRenderer {...data} />;\n * }\n *\n * // app/[[...slug]]/renderer.tsx (\"use client\")\n * import { PageRenderer } from \"@json-render/next\";\n * export function SiteRenderer(props) {\n * return <PageRenderer {...props} />;\n * }\n * ```\n */\nexport function createNextApp(options: CreateNextAppOptions): NextAppExports {\n const { spec: specOrFn, loaders } = options;\n\n /**\n * Resolve page data for a given set of route params.\n * Returns null when no route matches.\n */\n async function getPageData({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<PageData | null> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n\n const matched = matchRoute(spec, pathname);\n\n if (!matched) {\n return null;\n }\n\n const { route } = matched;\n\n let loaderData: Record<string, unknown> | undefined;\n if (route.loader && loaders?.[route.loader]) {\n loaderData = await loaders[route.loader]!(matched.params);\n }\n\n const initialState = mergeState(\n spec.state,\n route.page.state as Record<string, unknown> | undefined,\n loaderData,\n );\n\n const layoutSpec =\n route.layout && spec.layouts\n ? (spec.layouts[route.layout] ?? null)\n : null;\n\n return {\n spec: route.page,\n initialState:\n Object.keys(initialState).length > 0 ? initialState : undefined,\n layoutSpec,\n };\n }\n\n /**\n * Generate metadata for the matched route.\n * Merges global spec metadata with route-specific metadata.\n */\n async function generateMetadata({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<ResolvedMetadata> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n const matched = matchRoute(spec, pathname);\n return resolveMetadata(spec, matched?.route ?? null);\n }\n\n /**\n * Generate static params for all statically-known routes.\n * Used by Next.js to pre-render pages at build time.\n */\n async function generateStaticParams(): Promise<{ slug: string[] }[]> {\n const spec = await resolveSpec(specOrFn);\n return collectStaticParams(spec);\n }\n\n return { getPageData, generateMetadata, generateStaticParams };\n}\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Next.js app generation.\n *\n * Teaches the AI to generate multi-page applications with routes,\n * layouts, metadata, and page content using JSONL patches.\n */\nfunction nextAppPromptTemplate(context: PromptContext): string {\n const { catalog, options, formatZodType } = context;\n const {\n system = \"You are a Next.js application generator.\",\n customRules = [],\n } = options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with RFC 6902 JSON Patch operations to build a Next.js application spec.\",\n );\n lines.push(\n \"The spec defines routes (pages), layouts, metadata, and state for a full Next.js app.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(\n `{\"op\":\"add\",\"path\":\"/metadata\",\"value\":{\"title\":{\"default\":\"My App\",\"template\":\"%s | My App\"},\"description\":\"A full Next.js application\"}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/layouts\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/layouts/main\",\"value\":{\"root\":\"shell\",\"elements\":{\"shell\":{\"type\":\"AppShell\",\"props\":{},\"children\":[\"nav\",\"slot\"]},\"nav\":{\"type\":\"NavBar\",\"props\":{\"links\":[{\"href\":\"/\",\"label\":\"Home\"},{\"href\":\"/about\",\"label\":\"About\"}]},\"children\":[]},\"slot\":{\"type\":\"Slot\",\"props\":{},\"children\":[]}}}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/routes\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"Home\"},\"page\":{\"root\":\"hero\",\"elements\":{\"hero\":{\"type\":\"Card\",\"props\":{\"title\":\"Welcome\"},\"children\":[]}}}}}`,\n );\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1about\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"About\"},\"page\":{\"root\":\"content\",\"elements\":{\"content\":{\"type\":\"Card\",\"props\":{\"title\":\"About Us\"},\"children\":[]}}}}}`,\n );\n lines.push(\"\");\n\n lines.push(\"SPEC STRUCTURE:\");\n lines.push(\"The top-level spec has these fields:\");\n lines.push(\n \" - metadata: Root-level SEO metadata (title template, description, openGraph, twitter)\",\n );\n lines.push(\n \" - layouts: Reusable layout element trees. Each layout MUST include a { type: 'Slot' } element where page content will be injected.\",\n );\n lines.push(\" - routes: Route definitions keyed by URL pattern\");\n lines.push(\" - state: Global initial state shared across all routes\");\n lines.push(\"\");\n\n lines.push(\"ROUTES:\");\n lines.push(\"Route keys use Next.js URL patterns:\");\n lines.push(\" - '/' - home page\");\n lines.push(\" - '/about' - static route\");\n lines.push(\" - '/blog/[slug]' - dynamic segment\");\n lines.push(\" - '/docs/[...path]' - catch-all segment\");\n lines.push(\" - '/settings/[[...path]]' - optional catch-all segment\");\n lines.push(\"\");\n lines.push(\n \"IMPORTANT: In JSON Patch paths, forward slashes in route keys must be escaped as ~1.\",\n );\n lines.push(\" - Route '/' becomes path '/routes/~1'\");\n lines.push(\" - Route '/about' becomes path '/routes/~1about'\");\n lines.push(\" - Route '/blog/[slug]' becomes path '/routes/~1blog~1[slug]'\");\n lines.push(\"\");\n\n lines.push(\"Each route has:\");\n lines.push(\n \" - page: Element tree (root + elements + optional state) — the page content\",\n );\n lines.push(\n \" - metadata: Per-route SEO metadata (title, description, openGraph)\",\n );\n lines.push(\" - layout: Layout key referencing an entry in the layouts map\");\n lines.push(\" - loading: Optional loading state element tree\");\n lines.push(\" - error: Optional error state element tree\");\n lines.push(\" - loader: Optional server-side data loader name\");\n lines.push(\"\");\n\n lines.push(\"LAYOUTS:\");\n lines.push(\n \"Layouts wrap page content. A layout element tree MUST include a component with type 'Slot' — this is where the page content will be rendered.\",\n );\n lines.push(\n \"Layouts are defined once and reused across routes via the layout field.\",\n );\n lines.push(\"\");\n\n lines.push(\"METADATA:\");\n lines.push(\"Root metadata sets defaults. Route metadata overrides per page.\");\n lines.push(\n \" - title: string or { default, template } (use %s for page title in template)\",\n );\n lines.push(\" - description: string\");\n lines.push(\" - openGraph: { title, description, images, type }\");\n lines.push(\" - twitter: { card, title, description }\");\n lines.push(\"\");\n\n lines.push(\"PAGE CONTENT:\");\n lines.push(\n \"Each page uses the standard json-render element tree format: root, elements, optional state.\",\n );\n lines.push(\n \"Elements have type, props, children, and optionally visible, on, repeat, watch fields.\",\n );\n lines.push(\"\");\n\n const catalogData = catalog as {\n components?: Record<\n string,\n {\n description?: string;\n props?: unknown;\n slots?: string[];\n events?: string[];\n }\n >;\n actions?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const propsStr = def.props ? formatZodType(def.props as any) : \"{}\";\n const hasChildren = def.slots && def.slots.length > 0;\n const childrenStr = hasChildren ? \" [accepts children]\" : \"\";\n const eventsStr =\n def.events && def.events.length > 0\n ? ` [events: ${def.events.join(\", \")}]`\n : \"\";\n const descStr = def.description ? ` - ${def.description}` : \"\";\n lines.push(`- ${name}: ${propsStr}${descStr}${childrenStr}${eventsStr}`);\n }\n lines.push(\"\");\n lines.push(\"Built-in components (always available):\");\n lines.push(\n \"- Slot: {} - Placeholder in layouts where page content is rendered. Required in every layout.\",\n );\n lines.push(\n \"- Link: { href: string } [accepts children] - Client-side navigation link (renders as next/link).\",\n );\n lines.push(\"\");\n }\n\n if (catalogData.actions && Object.keys(catalogData.actions).length > 0) {\n lines.push(\"AVAILABLE ACTIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.actions)) {\n lines.push(`- ${name}${def.description ? `: ${def.description}` : \"\"}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"BUILT-IN ACTIONS:\");\n lines.push(\n \"- setState: Update a value in the state model. Params: { statePath: string, value: any }\",\n );\n lines.push(\n \"- pushState: Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }\",\n );\n lines.push(\n \"- removeState: Remove an item from an array by index. Params: { statePath: string, index: number }\",\n );\n lines.push(\"- navigate: Navigate to a route. Params: { href: string }\");\n lines.push(\"\");\n\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n \"First add /metadata with the app-level metadata including title template\",\n \"Then add /layouts with reusable layout definitions (each must have a Slot component)\",\n \"Then add /routes with each route's page, metadata, and layout reference\",\n \"Every layout MUST include a { type: 'Slot' } element where page content is injected\",\n \"ONLY use components listed in AVAILABLE COMPONENTS (plus built-in Slot and Link)\",\n \"Each element needs: type, props, children (array of child keys)\",\n \"Use unique keys for element map entries\",\n \"Escape forward slashes in route keys as ~1 in JSON Patch paths\",\n \"Include realistic sample data in state for data-driven pages\",\n \"Use Link component for navigation between routes\",\n \"Create a cohesive multi-page app with consistent layouts and navigation\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/next.\n *\n * Defines a multi-page Next.js application structure:\n * - Spec: Routes with pages, layouts, metadata, loading/error states\n * - Catalog: Components with props schemas, and optional actions\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's page-based, designed for full Next.js applications with SSR,\n * routing, and metadata generation.\n */\nexport const schema = defineSchema(\n (s) => ({\n spec: s.object({\n /** Root-level metadata applied as defaults */\n metadata: s.object({\n title: s.any(),\n description: s.string(),\n keywords: s.array(s.string()),\n openGraph: s.any(),\n twitter: s.any(),\n robots: s.any(),\n icons: s.any(),\n }),\n\n /** Route definitions keyed by URL pattern */\n routes: s.record(\n s.object({\n /** Page element tree */\n page: s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: s.any(),\n }),\n ),\n state: s.any(),\n }),\n /** Per-route metadata */\n metadata: s.any(),\n /** Layout key */\n layout: s.string(),\n /** Loading state element tree */\n loading: s.any(),\n /** Error state element tree */\n error: s.any(),\n /** Not-found element tree */\n notFound: s.any(),\n /** Server-side data loader name */\n loader: s.string(),\n /** Static params for SSG */\n staticParams: s.any(),\n }),\n ),\n\n /** Reusable layout element trees */\n layouts: s.record(\n s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: s.any(),\n }),\n ),\n state: s.any(),\n }),\n ),\n\n /** Global initial state */\n state: s.any(),\n }),\n\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n props: s.zod(),\n slots: s.array(s.string()),\n description: s.string(),\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n params: s.zod(),\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: nextAppPromptTemplate,\n builtInActions: [\n {\n name: \"setState\",\n description:\n \"Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\",\n },\n {\n name: \"pushState\",\n description:\n 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.',\n },\n {\n name: \"removeState\",\n description:\n \"Remove an item from an array in state by index. Params: { statePath: string, index: number }\",\n },\n {\n name: \"navigate\",\n description:\n \"Navigate to a route within the app. Params: { href: string }\",\n },\n ],\n },\n);\n\n/**\n * Type for the Next.js schema\n */\nexport type NextSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type NextSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/router.ts","../src/metadata.ts","../src/create-app.ts","../src/schema.ts"],"sourcesContent":["/**\n * @json-render/next/server — Server-safe exports\n *\n * This entry point does not import any client components or React hooks.\n * Safe to use in:\n * - Server Components\n * - API routes\n * - Build scripts\n * - Server Actions\n *\n * @example\n * ```ts\n * import { createNextApp, schema } from \"@json-render/next/server\";\n * ```\n */\n\n// createNextApp (main API)\nexport { createNextApp } from \"./create-app\";\n\n// Schema (Next.js app spec format)\nexport { schema, type NextSchema, type NextSpec } from \"./schema\";\n\n// Router utilities\nexport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\n\n// Metadata resolution\nexport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n// Types\nexport type {\n NextAppSpec,\n NextRouteSpec,\n NextMetadata,\n MatchedRoute,\n LoaderFn,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\n\n// Catalog types (type-only, no runtime)\nexport type {\n EventHandle,\n BaseComponentProps,\n SetState,\n StateModel,\n ComponentContext,\n ComponentFn,\n Components,\n ActionFn,\n Actions,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec, StateStore } from \"@json-render/core\";\n","import type { NextAppSpec, MatchedRoute } from \"./types\";\n\ninterface CompiledRoute {\n pattern: string;\n regex: RegExp;\n paramNames: string[];\n /** Whether the last segment is catch-all or optional catch-all */\n catchAll: boolean;\n optionalCatchAll: boolean;\n /** Number of static segments (higher = more specific) */\n specificity: number;\n}\n\n/**\n * Compile a Next.js route pattern into a regex matcher.\n *\n * Supports:\n * - Static segments: `/about`, `/blog`\n * - Dynamic segments: `/blog/[slug]`\n * - Catch-all segments: `/docs/[...path]`\n * - Optional catch-all segments: `/settings/[[...path]]`\n */\nfunction compileRoute(pattern: string): CompiledRoute {\n const paramNames: string[] = [];\n let catchAll = false;\n let optionalCatchAll = false;\n let specificity = 0;\n\n const segments = pattern === \"/\" ? [\"\"] : pattern.split(\"/\").slice(1);\n const regexParts: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n paramNames.push(paramName);\n optionalCatchAll = true;\n regexParts.push(\"(?:/(.+))?\");\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n paramNames.push(paramName);\n catchAll = true;\n regexParts.push(\"/(.+)\");\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n paramNames.push(paramName);\n regexParts.push(\"/([^/]+)\");\n } else {\n specificity++;\n regexParts.push(`/${escapeRegExp(segment)}`);\n }\n }\n\n const regexStr = pattern === \"/\" ? \"^/$\" : `^${regexParts.join(\"\")}$`;\n\n return {\n pattern,\n regex: new RegExp(regexStr),\n paramNames,\n catchAll,\n optionalCatchAll,\n specificity,\n };\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Match a pathname against a spec's routes.\n *\n * Routes are matched in order of specificity:\n * 1. Exact/static matches first (most specific)\n * 2. Dynamic segment matches\n * 3. Catch-all matches (least specific)\n * 4. Optional catch-all matches (fallback)\n *\n * @returns The matched route with extracted params, or null if no match.\n */\nexport function matchRoute(\n spec: NextAppSpec,\n pathname: string,\n): MatchedRoute | null {\n const normalizedPath = pathname === \"\" ? \"/\" : pathname;\n\n const compiled = Object.keys(spec.routes).map(compileRoute);\n\n compiled.sort((a, b) => {\n if (a.optionalCatchAll !== b.optionalCatchAll) {\n return a.optionalCatchAll ? 1 : -1;\n }\n if (a.catchAll !== b.catchAll) {\n return a.catchAll ? 1 : -1;\n }\n if (a.specificity !== b.specificity) {\n return b.specificity - a.specificity;\n }\n return a.paramNames.length - b.paramNames.length;\n });\n\n for (const route of compiled) {\n const match = route.regex.exec(normalizedPath);\n if (!match) continue;\n\n const params: Record<string, string | string[]> = {};\n for (let i = 0; i < route.paramNames.length; i++) {\n const value = match[i + 1];\n const name = route.paramNames[i]!;\n\n if (route.catchAll || route.optionalCatchAll) {\n params[name] = value ? value.split(\"/\") : [];\n } else {\n params[name] = value ?? \"\";\n }\n }\n\n return {\n route: spec.routes[route.pattern]!,\n pattern: route.pattern,\n params,\n };\n }\n\n return null;\n}\n\n/**\n * Convert a Next.js catch-all slug array to a pathname.\n *\n * @example\n * slugToPath(undefined) // \"/\"\n * slugToPath([]) // \"/\"\n * slugToPath([\"blog\"]) // \"/blog\"\n * slugToPath([\"blog\",\"hi\"]) // \"/blog/hi\"\n */\nexport function slugToPath(slug: string[] | undefined): string {\n if (!slug || slug.length === 0) return \"/\";\n return \"/\" + slug.join(\"/\");\n}\n\n/**\n * Collect all static params from the spec for generateStaticParams.\n * Returns params suitable for Next.js [[...slug]] catch-all routes.\n */\nexport function collectStaticParams(spec: NextAppSpec): { slug: string[] }[] {\n const results: { slug: string[] }[] = [];\n\n for (const [pattern, route] of Object.entries(spec.routes)) {\n if (route.staticParams) {\n for (const paramSet of route.staticParams) {\n const slug = buildSlugFromPattern(pattern, paramSet);\n if (slug) results.push({ slug });\n }\n } else if (!pattern.includes(\"[\")) {\n const slug = pattern === \"/\" ? [] : pattern.slice(1).split(\"/\");\n results.push({ slug });\n }\n }\n\n return results;\n}\n\n/**\n * Build a slug array from a route pattern and a set of params.\n */\nfunction buildSlugFromPattern(\n pattern: string,\n params: Record<string, string>,\n): string[] | null {\n if (pattern === \"/\") return [];\n\n const segments = pattern.split(\"/\").slice(1);\n const result: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n const value = params[paramName];\n if (value) result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(value);\n } else {\n result.push(segment);\n }\n }\n\n return result;\n}\n","import type { NextMetadata, NextAppSpec, NextRouteSpec } from \"./types\";\n\n/**\n * Metadata result compatible with Next.js's Metadata type.\n * Uses plain objects to avoid importing Next.js types at runtime.\n */\nexport type ResolvedMetadata = Record<string, unknown>;\n\n/**\n * Resolve metadata for a route by merging global spec metadata\n * with route-specific metadata.\n *\n * Follows Next.js metadata merging semantics:\n * - Route metadata overrides global metadata for scalar fields\n * - Title templates from global metadata apply to route titles\n * - OpenGraph and Twitter fields are shallow-merged\n */\nexport function resolveMetadata(\n spec: NextAppSpec,\n route?: NextRouteSpec | null,\n): ResolvedMetadata {\n const globalMeta = spec.metadata;\n const routeMeta = route?.metadata;\n\n if (!globalMeta && !routeMeta) return {};\n\n const result: ResolvedMetadata = {};\n\n const mergedTitle = resolveTitle(globalMeta?.title, routeMeta?.title);\n if (mergedTitle !== undefined) result.title = mergedTitle;\n\n const description = routeMeta?.description ?? globalMeta?.description;\n if (description) result.description = description;\n\n const keywords = routeMeta?.keywords ?? globalMeta?.keywords;\n if (keywords) result.keywords = keywords;\n\n const openGraph = mergeObject(globalMeta?.openGraph, routeMeta?.openGraph);\n if (openGraph) result.openGraph = openGraph;\n\n const twitter = mergeObject(globalMeta?.twitter, routeMeta?.twitter);\n if (twitter) result.twitter = twitter;\n\n const robots = routeMeta?.robots ?? globalMeta?.robots;\n if (robots) result.robots = robots;\n\n const alternates = routeMeta?.alternates ?? globalMeta?.alternates;\n if (alternates) result.alternates = alternates;\n\n const icons = routeMeta?.icons ?? globalMeta?.icons;\n if (icons) result.icons = icons;\n\n return result;\n}\n\n/**\n * Resolve a title value considering templates.\n *\n * If global metadata defines a title template (e.g. \"%s | My App\"),\n * route titles are interpolated into it.\n */\nfunction resolveTitle(\n globalTitle: NextMetadata[\"title\"],\n routeTitle: NextMetadata[\"title\"],\n): unknown {\n if (!routeTitle && !globalTitle) return undefined;\n\n if (!routeTitle) {\n if (typeof globalTitle === \"string\") return globalTitle;\n if (typeof globalTitle === \"object\" && globalTitle !== null) {\n return globalTitle.default ?? undefined;\n }\n return undefined;\n }\n\n if (typeof routeTitle === \"object\" && routeTitle !== null) {\n if (routeTitle.absolute) return routeTitle.absolute;\n if (routeTitle.template || routeTitle.default) return routeTitle;\n return routeTitle;\n }\n\n if (\n typeof globalTitle === \"object\" &&\n globalTitle !== null &&\n globalTitle.template\n ) {\n return globalTitle.template.replace(\"%s\", routeTitle as string);\n }\n\n return routeTitle;\n}\n\nfunction mergeObject(\n base: Record<string, unknown> | undefined,\n override: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !override) return undefined;\n if (!base) return override;\n if (!override) return base;\n return { ...base, ...override };\n}\n","import { notFound } from \"next/navigation\";\nimport type {\n NextAppSpec,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\nimport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\nimport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n/**\n * Resolve the spec from the options — supports both static specs\n * and factory functions that return specs (sync or async).\n */\nasync function resolveSpec(\n specOrFn: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>),\n): Promise<NextAppSpec> {\n if (typeof specOrFn === \"function\") {\n return await specOrFn();\n }\n return specOrFn;\n}\n\n/**\n * Merge state from multiple sources: global state, page state, and loader data.\n * Later sources override earlier ones.\n */\nfunction mergeState(\n ...sources: (Record<string, unknown> | undefined | null)[]\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const source of sources) {\n if (source) {\n Object.assign(result, source);\n }\n }\n return result;\n}\n\n/**\n * Create a fully wired Next.js application from a json-render spec.\n *\n * Returns `getPageData`, `generateMetadata`, and `generateStaticParams`\n * ready to be used in Next.js `[[...slug]]` catch-all routes.\n *\n * @example\n * ```typescript\n * // lib/app.ts\n * import { createNextApp } from \"@json-render/next/server\";\n *\n * export const { getPageData, generateMetadata, generateStaticParams } =\n * createNextApp({ spec });\n *\n * // app/[[...slug]]/page.tsx (Server Component)\n * import { notFound } from \"next/navigation\";\n * import { getPageData, generateMetadata, generateStaticParams } from \"@/lib/app\";\n * import { SiteRenderer } from \"./renderer\";\n *\n * export { generateMetadata, generateStaticParams };\n *\n * export default async function Page({ params }) {\n * const data = await getPageData({ params });\n * if (!data) notFound();\n * return <SiteRenderer {...data} />;\n * }\n *\n * // app/[[...slug]]/renderer.tsx (\"use client\")\n * import { PageRenderer } from \"@json-render/next\";\n * export function SiteRenderer(props) {\n * return <PageRenderer {...props} />;\n * }\n * ```\n */\nexport function createNextApp(options: CreateNextAppOptions): NextAppExports {\n const { spec: specOrFn, loaders } = options;\n\n /**\n * Resolve page data for a given set of route params.\n * Returns null when no route matches.\n */\n async function getPageData({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<PageData | null> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n\n const matched = matchRoute(spec, pathname);\n\n if (!matched) {\n return null;\n }\n\n const { route } = matched;\n\n let loaderData: Record<string, unknown> | undefined;\n if (route.loader && loaders?.[route.loader]) {\n loaderData = await loaders[route.loader]!(matched.params);\n }\n\n const initialState = mergeState(\n spec.state,\n route.page.state as Record<string, unknown> | undefined,\n loaderData,\n );\n\n const layoutSpec =\n route.layout && spec.layouts\n ? (spec.layouts[route.layout] ?? null)\n : null;\n\n return {\n spec: route.page,\n initialState:\n Object.keys(initialState).length > 0 ? initialState : undefined,\n layoutSpec,\n };\n }\n\n /**\n * Generate metadata for the matched route.\n * Merges global spec metadata with route-specific metadata.\n */\n async function generateMetadata({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<ResolvedMetadata> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n const matched = matchRoute(spec, pathname);\n return resolveMetadata(spec, matched?.route ?? null);\n }\n\n /**\n * Generate static params for all statically-known routes.\n * Used by Next.js to pre-render pages at build time.\n */\n async function generateStaticParams(): Promise<{ slug: string[] }[]> {\n const spec = await resolveSpec(specOrFn);\n return collectStaticParams(spec);\n }\n\n return { getPageData, generateMetadata, generateStaticParams };\n}\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Next.js app generation.\n *\n * Teaches the AI to generate multi-page applications with routes,\n * layouts, metadata, and page content using JSONL patches.\n */\nfunction nextAppPromptTemplate(context: PromptContext): string {\n const { catalog, options, formatZodType } = context;\n const {\n system = \"You are a Next.js application generator.\",\n customRules = [],\n } = options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with RFC 6902 JSON Patch operations to build a Next.js application spec.\",\n );\n lines.push(\n \"The spec defines routes (pages), layouts, metadata, and state for a full Next.js app.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(\n `{\"op\":\"add\",\"path\":\"/metadata\",\"value\":{\"title\":{\"default\":\"My App\",\"template\":\"%s | My App\"},\"description\":\"A full Next.js application\"}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/layouts\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/layouts/main\",\"value\":{\"root\":\"shell\",\"elements\":{\"shell\":{\"type\":\"AppShell\",\"props\":{},\"children\":[\"nav\",\"slot\"]},\"nav\":{\"type\":\"NavBar\",\"props\":{\"links\":[{\"href\":\"/\",\"label\":\"Home\"},{\"href\":\"/about\",\"label\":\"About\"}]},\"children\":[]},\"slot\":{\"type\":\"Slot\",\"props\":{},\"children\":[]}}}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/routes\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"Home\"},\"page\":{\"root\":\"hero\",\"elements\":{\"hero\":{\"type\":\"Card\",\"props\":{\"title\":\"Welcome\"},\"children\":[]}}}}}`,\n );\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1about\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"About\"},\"page\":{\"root\":\"content\",\"elements\":{\"content\":{\"type\":\"Card\",\"props\":{\"title\":\"About Us\"},\"children\":[]}}}}}`,\n );\n lines.push(\"\");\n\n lines.push(\"SPEC STRUCTURE:\");\n lines.push(\"The top-level spec has these fields:\");\n lines.push(\n \" - metadata: Root-level SEO metadata (title template, description, openGraph, twitter)\",\n );\n lines.push(\n \" - layouts: Reusable layout element trees. Each layout MUST include a { type: 'Slot' } element where page content will be injected.\",\n );\n lines.push(\" - routes: Route definitions keyed by URL pattern\");\n lines.push(\" - state: Global initial state shared across all routes\");\n lines.push(\"\");\n\n lines.push(\"ROUTES:\");\n lines.push(\"Route keys use Next.js URL patterns:\");\n lines.push(\" - '/' - home page\");\n lines.push(\" - '/about' - static route\");\n lines.push(\" - '/blog/[slug]' - dynamic segment\");\n lines.push(\" - '/docs/[...path]' - catch-all segment\");\n lines.push(\" - '/settings/[[...path]]' - optional catch-all segment\");\n lines.push(\"\");\n lines.push(\n \"IMPORTANT: In JSON Patch paths, forward slashes in route keys must be escaped as ~1.\",\n );\n lines.push(\" - Route '/' becomes path '/routes/~1'\");\n lines.push(\" - Route '/about' becomes path '/routes/~1about'\");\n lines.push(\" - Route '/blog/[slug]' becomes path '/routes/~1blog~1[slug]'\");\n lines.push(\"\");\n\n lines.push(\"Each route has:\");\n lines.push(\n \" - page: Element tree (root + elements + optional state) — the page content\",\n );\n lines.push(\n \" - metadata: Per-route SEO metadata (title, description, openGraph)\",\n );\n lines.push(\" - layout: Layout key referencing an entry in the layouts map\");\n lines.push(\" - loading: Optional loading state element tree\");\n lines.push(\" - error: Optional error state element tree\");\n lines.push(\" - loader: Optional server-side data loader name\");\n lines.push(\"\");\n\n lines.push(\"LAYOUTS:\");\n lines.push(\n \"Layouts wrap page content. A layout element tree MUST include a component with type 'Slot' — this is where the page content will be rendered.\",\n );\n lines.push(\n \"Layouts are defined once and reused across routes via the layout field.\",\n );\n lines.push(\"\");\n\n lines.push(\"METADATA:\");\n lines.push(\"Root metadata sets defaults. Route metadata overrides per page.\");\n lines.push(\n \" - title: string or { default, template } (use %s for page title in template)\",\n );\n lines.push(\" - description: string\");\n lines.push(\" - openGraph: { title, description, images, type }\");\n lines.push(\" - twitter: { card, title, description }\");\n lines.push(\"\");\n\n lines.push(\"PAGE CONTENT:\");\n lines.push(\n \"Each page uses the standard json-render element tree format: root, elements, optional state.\",\n );\n lines.push(\n \"Elements have type, props, children, and optionally visible, on, repeat, watch fields.\",\n );\n lines.push(\"\");\n\n const catalogData = catalog as {\n components?: Record<\n string,\n {\n description?: string;\n props?: unknown;\n slots?: string[];\n events?: string[];\n }\n >;\n actions?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const propsStr = def.props ? formatZodType(def.props as any) : \"{}\";\n const hasChildren = def.slots && def.slots.length > 0;\n const childrenStr = hasChildren ? \" [accepts children]\" : \"\";\n const eventsStr =\n def.events && def.events.length > 0\n ? ` [events: ${def.events.join(\", \")}]`\n : \"\";\n const descStr = def.description ? ` - ${def.description}` : \"\";\n lines.push(`- ${name}: ${propsStr}${descStr}${childrenStr}${eventsStr}`);\n }\n lines.push(\"\");\n lines.push(\"Built-in components (always available):\");\n lines.push(\n \"- Slot: {} - Placeholder in layouts where page content is rendered. Required in every layout.\",\n );\n lines.push(\n \"- Link: { href: string } [accepts children] - Client-side navigation link (renders as next/link).\",\n );\n lines.push(\"\");\n }\n\n if (catalogData.actions && Object.keys(catalogData.actions).length > 0) {\n lines.push(\"AVAILABLE ACTIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.actions)) {\n lines.push(`- ${name}${def.description ? `: ${def.description}` : \"\"}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"BUILT-IN ACTIONS:\");\n lines.push(\n \"- setState: Update a value in the state model. Params: { statePath: string, value: any }\",\n );\n lines.push(\n \"- pushState: Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }\",\n );\n lines.push(\n \"- removeState: Remove an item from an array by index. Params: { statePath: string, index: number }\",\n );\n lines.push(\"- navigate: Navigate to a route. Params: { href: string }\");\n lines.push(\"\");\n\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n \"First add /metadata with the app-level metadata including title template\",\n \"Then add /layouts with reusable layout definitions (each must have a Slot component)\",\n \"Then add /routes with each route's page, metadata, and layout reference\",\n \"Every layout MUST include a { type: 'Slot' } element where page content is injected\",\n \"ONLY use components listed in AVAILABLE COMPONENTS (plus built-in Slot and Link)\",\n \"Each element needs: type, props, children (array of child keys)\",\n \"Use unique keys for element map entries\",\n \"Escape forward slashes in route keys as ~1 in JSON Patch paths\",\n \"Include realistic sample data in state for data-driven pages\",\n \"Use Link component for navigation between routes\",\n \"Create a cohesive multi-page app with consistent layouts and navigation\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/next.\n *\n * Defines a multi-page Next.js application structure:\n * - Spec: Routes with pages, layouts, metadata, loading/error states\n * - Catalog: Components with props schemas, and optional actions\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's page-based, designed for full Next.js applications with SSR,\n * routing, and metadata generation.\n */\nexport const schema = defineSchema(\n (s) => ({\n spec: s.object({\n /** Root-level metadata applied as defaults */\n metadata: {\n ...s.object({\n title: { ...s.any(), ...s.optional() },\n description: { ...s.string(), ...s.optional() },\n keywords: { ...s.array(s.string()), ...s.optional() },\n openGraph: { ...s.any(), ...s.optional() },\n twitter: { ...s.any(), ...s.optional() },\n robots: { ...s.any(), ...s.optional() },\n alternates: { ...s.any(), ...s.optional() },\n icons: { ...s.any(), ...s.optional() },\n }),\n ...s.optional(),\n },\n\n /** Route definitions keyed by URL pattern */\n routes: s.record(\n s.object({\n /** Page element tree */\n page: s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: { ...s.any(), ...s.optional() },\n }),\n ),\n state: { ...s.any(), ...s.optional() },\n }),\n /** Per-route metadata */\n metadata: { ...s.any(), ...s.optional() },\n /** Layout key */\n layout: { ...s.string(), ...s.optional() },\n /** Loading state element tree */\n loading: { ...s.any(), ...s.optional() },\n /** Error state element tree */\n error: { ...s.any(), ...s.optional() },\n /** Not-found element tree */\n notFound: { ...s.any(), ...s.optional() },\n /** Server-side data loader name */\n loader: { ...s.string(), ...s.optional() },\n /** Static params for SSG */\n staticParams: { ...s.any(), ...s.optional() },\n }),\n ),\n\n /** Reusable layout element trees */\n layouts: {\n ...s.record(\n s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: { ...s.any(), ...s.optional() },\n }),\n ),\n state: { ...s.any(), ...s.optional() },\n }),\n ),\n ...s.optional(),\n },\n\n /** Global initial state */\n state: { ...s.any(), ...s.optional() },\n }),\n\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n props: s.zod(),\n slots: s.array(s.string()),\n description: s.string(),\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n params: s.zod(),\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: nextAppPromptTemplate,\n builtInActions: [\n {\n name: \"setState\",\n description:\n \"Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\",\n },\n {\n name: \"pushState\",\n description:\n 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.',\n },\n {\n name: \"removeState\",\n description:\n \"Remove an item from an array in state by index. Params: { statePath: string, index: number }\",\n },\n {\n name: \"navigate\",\n description:\n \"Navigate to a route within the app. Params: { href: string }\",\n },\n ],\n },\n);\n\n/**\n * Type for the Next.js schema\n */\nexport type NextSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type NextSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsBA,SAAS,aAAa,SAAgC;AACpD,QAAM,aAAuB,CAAC;AAC9B,MAAI,WAAW;AACf,MAAI,mBAAmB;AACvB,MAAI,cAAc;AAElB,QAAM,WAAW,YAAY,MAAM,CAAC,EAAE,IAAI,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC;AACpE,QAAM,aAAuB,CAAC;AAE9B,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,WAAW,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AACzD,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,yBAAmB;AACnB,iBAAW,KAAK,YAAY;AAAA,IAC9B,WAAW,QAAQ,WAAW,MAAM,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC9D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,iBAAW;AACX,iBAAW,KAAK,OAAO;AAAA,IACzB,WAAW,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC3D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,iBAAW,KAAK,UAAU;AAAA,IAC5B,OAAO;AACL;AACA,iBAAW,KAAK,IAAI,aAAa,OAAO,CAAC,EAAE;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,WAAW,YAAY,MAAM,QAAQ,IAAI,WAAW,KAAK,EAAE,CAAC;AAElE,SAAO;AAAA,IACL;AAAA,IACA,OAAO,IAAI,OAAO,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;AAaO,SAAS,WACd,MACA,UACqB;AACrB,QAAM,iBAAiB,aAAa,KAAK,MAAM;AAE/C,QAAM,WAAW,OAAO,KAAK,KAAK,MAAM,EAAE,IAAI,YAAY;AAE1D,WAAS,KAAK,CAAC,GAAG,MAAM;AACtB,QAAI,EAAE,qBAAqB,EAAE,kBAAkB;AAC7C,aAAO,EAAE,mBAAmB,IAAI;AAAA,IAClC;AACA,QAAI,EAAE,aAAa,EAAE,UAAU;AAC7B,aAAO,EAAE,WAAW,IAAI;AAAA,IAC1B;AACA,QAAI,EAAE,gBAAgB,EAAE,aAAa;AACnC,aAAO,EAAE,cAAc,EAAE;AAAA,IAC3B;AACA,WAAO,EAAE,WAAW,SAAS,EAAE,WAAW;AAAA,EAC5C,CAAC;AAED,aAAW,SAAS,UAAU;AAC5B,UAAM,QAAQ,MAAM,MAAM,KAAK,cAAc;AAC7C,QAAI,CAAC,MAAO;AAEZ,UAAM,SAA4C,CAAC;AACnD,aAAS,IAAI,GAAG,IAAI,MAAM,WAAW,QAAQ,KAAK;AAChD,YAAM,QAAQ,MAAM,IAAI,CAAC;AACzB,YAAM,OAAO,MAAM,WAAW,CAAC;AAE/B,UAAI,MAAM,YAAY,MAAM,kBAAkB;AAC5C,eAAO,IAAI,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC;AAAA,MAC7C,OAAO;AACL,eAAO,IAAI,IAAI,SAAS;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,KAAK,OAAO,MAAM,OAAO;AAAA,MAChC,SAAS,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,WAAW,MAAoC;AAC7D,MAAI,CAAC,QAAQ,KAAK,WAAW,EAAG,QAAO;AACvC,SAAO,MAAM,KAAK,KAAK,GAAG;AAC5B;AAMO,SAAS,oBAAoB,MAAyC;AAC3E,QAAM,UAAgC,CAAC;AAEvC,aAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AAC1D,QAAI,MAAM,cAAc;AACtB,iBAAW,YAAY,MAAM,cAAc;AACzC,cAAM,OAAO,qBAAqB,SAAS,QAAQ;AACnD,YAAI,KAAM,SAAQ,KAAK,EAAE,KAAK,CAAC;AAAA,MACjC;AAAA,IACF,WAAW,CAAC,QAAQ,SAAS,GAAG,GAAG;AACjC,YAAM,OAAO,YAAY,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,EAAE,MAAM,GAAG;AAC9D,cAAQ,KAAK,EAAE,KAAK,CAAC;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,qBACP,SACA,QACiB;AACjB,MAAI,YAAY,IAAK,QAAO,CAAC;AAE7B,QAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC;AAC3C,QAAM,SAAmB,CAAC;AAE1B,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,WAAW,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AACzD,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,MAAO,QAAO,KAAK,GAAG,MAAM,MAAM,GAAG,CAAC;AAAA,IAC5C,WAAW,QAAQ,WAAW,MAAM,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC9D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,KAAK,GAAG,MAAM,MAAM,GAAG,CAAC;AAAA,IACjC,WAAW,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC3D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,KAAK,KAAK;AAAA,IACnB,OAAO;AACL,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;;;AClLO,SAAS,gBACd,MACA,OACkB;AAClB,QAAM,aAAa,KAAK;AACxB,QAAM,YAAY,OAAO;AAEzB,MAAI,CAAC,cAAc,CAAC,UAAW,QAAO,CAAC;AAEvC,QAAM,SAA2B,CAAC;AAElC,QAAM,cAAc,aAAa,YAAY,OAAO,WAAW,KAAK;AACpE,MAAI,gBAAgB,OAAW,QAAO,QAAQ;AAE9C,QAAM,cAAc,WAAW,eAAe,YAAY;AAC1D,MAAI,YAAa,QAAO,cAAc;AAEtC,QAAM,WAAW,WAAW,YAAY,YAAY;AACpD,MAAI,SAAU,QAAO,WAAW;AAEhC,QAAM,YAAY,YAAY,YAAY,WAAW,WAAW,SAAS;AACzE,MAAI,UAAW,QAAO,YAAY;AAElC,QAAM,UAAU,YAAY,YAAY,SAAS,WAAW,OAAO;AACnE,MAAI,QAAS,QAAO,UAAU;AAE9B,QAAM,SAAS,WAAW,UAAU,YAAY;AAChD,MAAI,OAAQ,QAAO,SAAS;AAE5B,QAAM,aAAa,WAAW,cAAc,YAAY;AACxD,MAAI,WAAY,QAAO,aAAa;AAEpC,QAAM,QAAQ,WAAW,SAAS,YAAY;AAC9C,MAAI,MAAO,QAAO,QAAQ;AAE1B,SAAO;AACT;AAQA,SAAS,aACP,aACA,YACS;AACT,MAAI,CAAC,cAAc,CAAC,YAAa,QAAO;AAExC,MAAI,CAAC,YAAY;AACf,QAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,QAAI,OAAO,gBAAgB,YAAY,gBAAgB,MAAM;AAC3D,aAAO,YAAY,WAAW;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,eAAe,YAAY,eAAe,MAAM;AACzD,QAAI,WAAW,SAAU,QAAO,WAAW;AAC3C,QAAI,WAAW,YAAY,WAAW,QAAS,QAAO;AACtD,WAAO;AAAA,EACT;AAEA,MACE,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,YAAY,UACZ;AACA,WAAO,YAAY,SAAS,QAAQ,MAAM,UAAoB;AAAA,EAChE;AAEA,SAAO;AACT;AAEA,SAAS,YACP,MACA,UACqC;AACrC,MAAI,CAAC,QAAQ,CAAC,SAAU,QAAO;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,EAAE,GAAG,MAAM,GAAG,SAAS;AAChC;;;ACtFA,eAAe,YACb,UACsB;AACtB,MAAI,OAAO,aAAa,YAAY;AAClC,WAAO,MAAM,SAAS;AAAA,EACxB;AACA,SAAO;AACT;AAMA,SAAS,cACJ,SACsB;AACzB,QAAM,SAAkC,CAAC;AACzC,aAAW,UAAU,SAAS;AAC5B,QAAI,QAAQ;AACV,aAAO,OAAO,QAAQ,MAAM;AAAA,IAC9B;AAAA,EACF;AACA,SAAO;AACT;AAoCO,SAAS,cAAc,SAA+C;AAC3E,QAAM,EAAE,MAAM,UAAU,QAAQ,IAAI;AAMpC,iBAAe,YAAY;AAAA,IACzB;AAAA,EACF,GAE6B;AAC3B,UAAM,EAAE,KAAK,IAAI,MAAM;AACvB,UAAM,WAAW,WAAW,IAAI;AAChC,UAAM,OAAO,MAAM,YAAY,QAAQ;AAEvC,UAAM,UAAU,WAAW,MAAM,QAAQ;AAEzC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,MAAM,IAAI;AAElB,QAAI;AACJ,QAAI,MAAM,UAAU,UAAU,MAAM,MAAM,GAAG;AAC3C,mBAAa,MAAM,QAAQ,MAAM,MAAM,EAAG,QAAQ,MAAM;AAAA,IAC1D;AAEA,UAAM,eAAe;AAAA,MACnB,KAAK;AAAA,MACL,MAAM,KAAK;AAAA,MACX;AAAA,IACF;AAEA,UAAM,aACJ,MAAM,UAAU,KAAK,UAChB,KAAK,QAAQ,MAAM,MAAM,KAAK,OAC/B;AAEN,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,cACE,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAMA,iBAAe,iBAAiB;AAAA,IAC9B;AAAA,EACF,GAE8B;AAC5B,UAAM,EAAE,KAAK,IAAI,MAAM;AACvB,UAAM,WAAW,WAAW,IAAI;AAChC,UAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,UAAM,UAAU,WAAW,MAAM,QAAQ;AACzC,WAAO,gBAAgB,MAAM,SAAS,SAAS,IAAI;AAAA,EACrD;AAMA,iBAAe,uBAAsD;AACnE,UAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,WAAO,oBAAoB,IAAI;AAAA,EACjC;AAEA,SAAO,EAAE,aAAa,kBAAkB,qBAAqB;AAC/D;;;ACnJA,kBAAiD;AAQjD,SAAS,sBAAsB,SAAgC;AAC7D,QAAM,EAAE,SAAS,SAAS,cAAc,IAAI;AAC5C,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,cAAc,CAAC;AAAA,EACjB,IAAI;AAEJ,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,gBAAgB;AAC3B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uDAAuD;AAClE,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,2CAA2C;AACtD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,0CAA0C;AACrD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,sCAAsC;AACjD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,oDAAoD;AAC/D,QAAM,KAAK,0DAA0D;AACrE,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,qBAAqB;AAChC,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,2CAA2C;AACtD,QAAM,KAAK,0DAA0D;AACrE,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,yCAAyC;AACpD,QAAM,KAAK,mDAAmD;AAC9D,QAAM,KAAK,gEAAgE;AAC3E,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAiB;AAC5B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,gEAAgE;AAC3E,QAAM,KAAK,kDAAkD;AAC7D,QAAM,KAAK,8CAA8C;AACzD,QAAM,KAAK,mDAAmD;AAC9D,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,UAAU;AACrB,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,iEAAiE;AAC5E,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,yBAAyB;AACpC,QAAM,KAAK,qDAAqD;AAChE,QAAM,KAAK,2CAA2C;AACtD,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,eAAe;AAC1B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,cAAc;AAapB,MAAI,YAAY,YAAY;AAC1B,UAAM;AAAA,MACJ,yBAAyB,OAAO,KAAK,YAAY,UAAU,EAAE,MAAM;AAAA,IACrE;AACA,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,YAAY,UAAU,GAAG;AAChE,YAAM,WAAW,IAAI,QAAQ,cAAc,IAAI,KAAY,IAAI;AAC/D,YAAM,cAAc,IAAI,SAAS,IAAI,MAAM,SAAS;AACpD,YAAM,cAAc,cAAc,wBAAwB;AAC1D,YAAM,YACJ,IAAI,UAAU,IAAI,OAAO,SAAS,IAC9B,aAAa,IAAI,OAAO,KAAK,IAAI,CAAC,MAClC;AACN,YAAM,UAAU,IAAI,cAAc,MAAM,IAAI,WAAW,KAAK;AAC5D,YAAM,KAAK,KAAK,IAAI,KAAK,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,EAAE;AAAA,IACzE;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,yCAAyC;AACpD,UAAM;AAAA,MACJ;AAAA,IACF;AACA,UAAM;AAAA,MACJ;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,YAAY,WAAW,OAAO,KAAK,YAAY,OAAO,EAAE,SAAS,GAAG;AACtE,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,YAAY,OAAO,GAAG;AAC7D,YAAM,KAAK,KAAK,IAAI,GAAG,IAAI,cAAc,KAAK,IAAI,WAAW,KAAK,EAAE,EAAE;AAAA,IACxE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,mBAAmB;AAC9B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,2DAA2D;AACtE,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,QAAQ;AACnB,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,WAAW,CAAC,GAAG,WAAW,GAAG,WAAW;AAC9C,WAAS,QAAQ,CAAC,MAAM,MAAM;AAC5B,UAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE;AAAA,EAChC,CAAC;AAED,SAAO,MAAM,KAAK,IAAI;AACxB;AAaO,IAAM,aAAS;AAAA,EACpB,CAAC,OAAO;AAAA,IACN,MAAM,EAAE,OAAO;AAAA;AAAA,MAEb,UAAU;AAAA,QACR,GAAG,EAAE,OAAO;AAAA,UACV,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACrC,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UAC9C,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACpD,WAAW,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACzC,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACtC,YAAY,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UAC1C,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,QACvC,CAAC;AAAA,QACD,GAAG,EAAE,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,QAAQ,EAAE;AAAA,QACR,EAAE,OAAO;AAAA;AAAA,UAEP,MAAM,EAAE,OAAO;AAAA,YACb,MAAM,EAAE,OAAO;AAAA,YACf,UAAU,EAAE;AAAA,cACV,EAAE,OAAO;AAAA,gBACP,MAAM,EAAE,IAAI,oBAAoB;AAAA,gBAChC,OAAO,EAAE,QAAQ,oBAAoB;AAAA,gBACrC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,gBAC5B,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,cACzC,CAAC;AAAA,YACH;AAAA,YACA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,CAAC;AAAA;AAAA,UAED,UAAU,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAExC,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEzC,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEvC,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAErC,UAAU,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAExC,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEzC,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA;AAAA,MAGA,SAAS;AAAA,QACP,GAAG,EAAE;AAAA,UACH,EAAE,OAAO;AAAA,YACP,MAAM,EAAE,OAAO;AAAA,YACf,UAAU,EAAE;AAAA,cACV,EAAE,OAAO;AAAA,gBACP,MAAM,EAAE,IAAI,oBAAoB;AAAA,gBAChC,OAAO,EAAE,QAAQ,oBAAoB;AAAA,gBACrC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,gBAC5B,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,cACzC,CAAC;AAAA,YACH;AAAA,YACA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,CAAC;AAAA,QACH;AAAA,QACA,GAAG,EAAE,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,IACvC,CAAC;AAAA,IAED,SAAS,EAAE,OAAO;AAAA;AAAA,MAEhB,YAAY,EAAE,IAAI;AAAA,QAChB,OAAO,EAAE,IAAI;AAAA,QACb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QACzB,aAAa,EAAE,OAAO;AAAA,QACtB,SAAS,EAAE,IAAI;AAAA,MACjB,CAAC;AAAA;AAAA,MAED,SAAS,EAAE,IAAI;AAAA,QACb,QAAQ,EAAE,IAAI;AAAA,QACd,aAAa,EAAE,OAAO;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,MACd;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/dist/server.mjs
CHANGED
|
@@ -399,15 +399,19 @@ var schema = defineSchema(
|
|
|
399
399
|
(s) => ({
|
|
400
400
|
spec: s.object({
|
|
401
401
|
/** Root-level metadata applied as defaults */
|
|
402
|
-
metadata:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
402
|
+
metadata: {
|
|
403
|
+
...s.object({
|
|
404
|
+
title: { ...s.any(), ...s.optional() },
|
|
405
|
+
description: { ...s.string(), ...s.optional() },
|
|
406
|
+
keywords: { ...s.array(s.string()), ...s.optional() },
|
|
407
|
+
openGraph: { ...s.any(), ...s.optional() },
|
|
408
|
+
twitter: { ...s.any(), ...s.optional() },
|
|
409
|
+
robots: { ...s.any(), ...s.optional() },
|
|
410
|
+
alternates: { ...s.any(), ...s.optional() },
|
|
411
|
+
icons: { ...s.any(), ...s.optional() }
|
|
412
|
+
}),
|
|
413
|
+
...s.optional()
|
|
414
|
+
},
|
|
411
415
|
/** Route definitions keyed by URL pattern */
|
|
412
416
|
routes: s.record(
|
|
413
417
|
s.object({
|
|
@@ -419,44 +423,47 @@ var schema = defineSchema(
|
|
|
419
423
|
type: s.ref("catalog.components"),
|
|
420
424
|
props: s.propsOf("catalog.components"),
|
|
421
425
|
children: s.array(s.string()),
|
|
422
|
-
visible: s.any()
|
|
426
|
+
visible: { ...s.any(), ...s.optional() }
|
|
423
427
|
})
|
|
424
428
|
),
|
|
425
|
-
state: s.any()
|
|
429
|
+
state: { ...s.any(), ...s.optional() }
|
|
426
430
|
}),
|
|
427
431
|
/** Per-route metadata */
|
|
428
|
-
metadata: s.any(),
|
|
432
|
+
metadata: { ...s.any(), ...s.optional() },
|
|
429
433
|
/** Layout key */
|
|
430
|
-
layout: s.string(),
|
|
434
|
+
layout: { ...s.string(), ...s.optional() },
|
|
431
435
|
/** Loading state element tree */
|
|
432
|
-
loading: s.any(),
|
|
436
|
+
loading: { ...s.any(), ...s.optional() },
|
|
433
437
|
/** Error state element tree */
|
|
434
|
-
error: s.any(),
|
|
438
|
+
error: { ...s.any(), ...s.optional() },
|
|
435
439
|
/** Not-found element tree */
|
|
436
|
-
notFound: s.any(),
|
|
440
|
+
notFound: { ...s.any(), ...s.optional() },
|
|
437
441
|
/** Server-side data loader name */
|
|
438
|
-
loader: s.string(),
|
|
442
|
+
loader: { ...s.string(), ...s.optional() },
|
|
439
443
|
/** Static params for SSG */
|
|
440
|
-
staticParams: s.any()
|
|
444
|
+
staticParams: { ...s.any(), ...s.optional() }
|
|
441
445
|
})
|
|
442
446
|
),
|
|
443
447
|
/** Reusable layout element trees */
|
|
444
|
-
layouts:
|
|
445
|
-
s.
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
s.
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
448
|
+
layouts: {
|
|
449
|
+
...s.record(
|
|
450
|
+
s.object({
|
|
451
|
+
root: s.string(),
|
|
452
|
+
elements: s.record(
|
|
453
|
+
s.object({
|
|
454
|
+
type: s.ref("catalog.components"),
|
|
455
|
+
props: s.propsOf("catalog.components"),
|
|
456
|
+
children: s.array(s.string()),
|
|
457
|
+
visible: { ...s.any(), ...s.optional() }
|
|
458
|
+
})
|
|
459
|
+
),
|
|
460
|
+
state: { ...s.any(), ...s.optional() }
|
|
461
|
+
})
|
|
462
|
+
),
|
|
463
|
+
...s.optional()
|
|
464
|
+
},
|
|
458
465
|
/** Global initial state */
|
|
459
|
-
state: s.any()
|
|
466
|
+
state: { ...s.any(), ...s.optional() }
|
|
460
467
|
}),
|
|
461
468
|
catalog: s.object({
|
|
462
469
|
/** Component definitions */
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/router.ts","../src/metadata.ts","../src/create-app.ts","../src/schema.ts"],"sourcesContent":["import type { NextAppSpec, MatchedRoute } from \"./types\";\n\ninterface CompiledRoute {\n pattern: string;\n regex: RegExp;\n paramNames: string[];\n /** Whether the last segment is catch-all or optional catch-all */\n catchAll: boolean;\n optionalCatchAll: boolean;\n /** Number of static segments (higher = more specific) */\n specificity: number;\n}\n\n/**\n * Compile a Next.js route pattern into a regex matcher.\n *\n * Supports:\n * - Static segments: `/about`, `/blog`\n * - Dynamic segments: `/blog/[slug]`\n * - Catch-all segments: `/docs/[...path]`\n * - Optional catch-all segments: `/settings/[[...path]]`\n */\nfunction compileRoute(pattern: string): CompiledRoute {\n const paramNames: string[] = [];\n let catchAll = false;\n let optionalCatchAll = false;\n let specificity = 0;\n\n const segments = pattern === \"/\" ? [\"\"] : pattern.split(\"/\").slice(1);\n const regexParts: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n paramNames.push(paramName);\n optionalCatchAll = true;\n regexParts.push(\"(?:/(.+))?\");\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n paramNames.push(paramName);\n catchAll = true;\n regexParts.push(\"/(.+)\");\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n paramNames.push(paramName);\n regexParts.push(\"/([^/]+)\");\n } else {\n specificity++;\n regexParts.push(`/${escapeRegExp(segment)}`);\n }\n }\n\n const regexStr = pattern === \"/\" ? \"^/$\" : `^${regexParts.join(\"\")}$`;\n\n return {\n pattern,\n regex: new RegExp(regexStr),\n paramNames,\n catchAll,\n optionalCatchAll,\n specificity,\n };\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Match a pathname against a spec's routes.\n *\n * Routes are matched in order of specificity:\n * 1. Exact/static matches first (most specific)\n * 2. Dynamic segment matches\n * 3. Catch-all matches (least specific)\n * 4. Optional catch-all matches (fallback)\n *\n * @returns The matched route with extracted params, or null if no match.\n */\nexport function matchRoute(\n spec: NextAppSpec,\n pathname: string,\n): MatchedRoute | null {\n const normalizedPath = pathname === \"\" ? \"/\" : pathname;\n\n const compiled = Object.keys(spec.routes).map(compileRoute);\n\n compiled.sort((a, b) => {\n if (a.optionalCatchAll !== b.optionalCatchAll) {\n return a.optionalCatchAll ? 1 : -1;\n }\n if (a.catchAll !== b.catchAll) {\n return a.catchAll ? 1 : -1;\n }\n if (a.specificity !== b.specificity) {\n return b.specificity - a.specificity;\n }\n return a.paramNames.length - b.paramNames.length;\n });\n\n for (const route of compiled) {\n const match = route.regex.exec(normalizedPath);\n if (!match) continue;\n\n const params: Record<string, string | string[]> = {};\n for (let i = 0; i < route.paramNames.length; i++) {\n const value = match[i + 1];\n const name = route.paramNames[i]!;\n\n if (route.catchAll || route.optionalCatchAll) {\n params[name] = value ? value.split(\"/\") : [];\n } else {\n params[name] = value ?? \"\";\n }\n }\n\n return {\n route: spec.routes[route.pattern]!,\n pattern: route.pattern,\n params,\n };\n }\n\n return null;\n}\n\n/**\n * Convert a Next.js catch-all slug array to a pathname.\n *\n * @example\n * slugToPath(undefined) // \"/\"\n * slugToPath([]) // \"/\"\n * slugToPath([\"blog\"]) // \"/blog\"\n * slugToPath([\"blog\",\"hi\"]) // \"/blog/hi\"\n */\nexport function slugToPath(slug: string[] | undefined): string {\n if (!slug || slug.length === 0) return \"/\";\n return \"/\" + slug.join(\"/\");\n}\n\n/**\n * Collect all static params from the spec for generateStaticParams.\n * Returns params suitable for Next.js [[...slug]] catch-all routes.\n */\nexport function collectStaticParams(spec: NextAppSpec): { slug: string[] }[] {\n const results: { slug: string[] }[] = [];\n\n for (const [pattern, route] of Object.entries(spec.routes)) {\n if (route.staticParams) {\n for (const paramSet of route.staticParams) {\n const slug = buildSlugFromPattern(pattern, paramSet);\n if (slug) results.push({ slug });\n }\n } else if (!pattern.includes(\"[\")) {\n const slug = pattern === \"/\" ? [] : pattern.slice(1).split(\"/\");\n results.push({ slug });\n }\n }\n\n return results;\n}\n\n/**\n * Build a slug array from a route pattern and a set of params.\n */\nfunction buildSlugFromPattern(\n pattern: string,\n params: Record<string, string>,\n): string[] | null {\n if (pattern === \"/\") return [];\n\n const segments = pattern.split(\"/\").slice(1);\n const result: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n const value = params[paramName];\n if (value) result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(value);\n } else {\n result.push(segment);\n }\n }\n\n return result;\n}\n","import type { NextMetadata, NextAppSpec, NextRouteSpec } from \"./types\";\n\n/**\n * Metadata result compatible with Next.js's Metadata type.\n * Uses plain objects to avoid importing Next.js types at runtime.\n */\nexport type ResolvedMetadata = Record<string, unknown>;\n\n/**\n * Resolve metadata for a route by merging global spec metadata\n * with route-specific metadata.\n *\n * Follows Next.js metadata merging semantics:\n * - Route metadata overrides global metadata for scalar fields\n * - Title templates from global metadata apply to route titles\n * - OpenGraph and Twitter fields are shallow-merged\n */\nexport function resolveMetadata(\n spec: NextAppSpec,\n route?: NextRouteSpec | null,\n): ResolvedMetadata {\n const globalMeta = spec.metadata;\n const routeMeta = route?.metadata;\n\n if (!globalMeta && !routeMeta) return {};\n\n const result: ResolvedMetadata = {};\n\n const mergedTitle = resolveTitle(globalMeta?.title, routeMeta?.title);\n if (mergedTitle !== undefined) result.title = mergedTitle;\n\n const description = routeMeta?.description ?? globalMeta?.description;\n if (description) result.description = description;\n\n const keywords = routeMeta?.keywords ?? globalMeta?.keywords;\n if (keywords) result.keywords = keywords;\n\n const openGraph = mergeObject(globalMeta?.openGraph, routeMeta?.openGraph);\n if (openGraph) result.openGraph = openGraph;\n\n const twitter = mergeObject(globalMeta?.twitter, routeMeta?.twitter);\n if (twitter) result.twitter = twitter;\n\n const robots = routeMeta?.robots ?? globalMeta?.robots;\n if (robots) result.robots = robots;\n\n const alternates = routeMeta?.alternates ?? globalMeta?.alternates;\n if (alternates) result.alternates = alternates;\n\n const icons = routeMeta?.icons ?? globalMeta?.icons;\n if (icons) result.icons = icons;\n\n return result;\n}\n\n/**\n * Resolve a title value considering templates.\n *\n * If global metadata defines a title template (e.g. \"%s | My App\"),\n * route titles are interpolated into it.\n */\nfunction resolveTitle(\n globalTitle: NextMetadata[\"title\"],\n routeTitle: NextMetadata[\"title\"],\n): unknown {\n if (!routeTitle && !globalTitle) return undefined;\n\n if (!routeTitle) {\n if (typeof globalTitle === \"string\") return globalTitle;\n if (typeof globalTitle === \"object\" && globalTitle !== null) {\n return globalTitle.default ?? undefined;\n }\n return undefined;\n }\n\n if (typeof routeTitle === \"object\" && routeTitle !== null) {\n if (routeTitle.absolute) return routeTitle.absolute;\n if (routeTitle.template || routeTitle.default) return routeTitle;\n return routeTitle;\n }\n\n if (\n typeof globalTitle === \"object\" &&\n globalTitle !== null &&\n globalTitle.template\n ) {\n return globalTitle.template.replace(\"%s\", routeTitle as string);\n }\n\n return routeTitle;\n}\n\nfunction mergeObject(\n base: Record<string, unknown> | undefined,\n override: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !override) return undefined;\n if (!base) return override;\n if (!override) return base;\n return { ...base, ...override };\n}\n","import { notFound } from \"next/navigation\";\nimport type {\n NextAppSpec,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\nimport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\nimport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n/**\n * Resolve the spec from the options — supports both static specs\n * and factory functions that return specs (sync or async).\n */\nasync function resolveSpec(\n specOrFn: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>),\n): Promise<NextAppSpec> {\n if (typeof specOrFn === \"function\") {\n return await specOrFn();\n }\n return specOrFn;\n}\n\n/**\n * Merge state from multiple sources: global state, page state, and loader data.\n * Later sources override earlier ones.\n */\nfunction mergeState(\n ...sources: (Record<string, unknown> | undefined | null)[]\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const source of sources) {\n if (source) {\n Object.assign(result, source);\n }\n }\n return result;\n}\n\n/**\n * Create a fully wired Next.js application from a json-render spec.\n *\n * Returns `getPageData`, `generateMetadata`, and `generateStaticParams`\n * ready to be used in Next.js `[[...slug]]` catch-all routes.\n *\n * @example\n * ```typescript\n * // lib/app.ts\n * import { createNextApp } from \"@json-render/next/server\";\n *\n * export const { getPageData, generateMetadata, generateStaticParams } =\n * createNextApp({ spec });\n *\n * // app/[[...slug]]/page.tsx (Server Component)\n * import { notFound } from \"next/navigation\";\n * import { getPageData, generateMetadata, generateStaticParams } from \"@/lib/app\";\n * import { SiteRenderer } from \"./renderer\";\n *\n * export { generateMetadata, generateStaticParams };\n *\n * export default async function Page({ params }) {\n * const data = await getPageData({ params });\n * if (!data) notFound();\n * return <SiteRenderer {...data} />;\n * }\n *\n * // app/[[...slug]]/renderer.tsx (\"use client\")\n * import { PageRenderer } from \"@json-render/next\";\n * export function SiteRenderer(props) {\n * return <PageRenderer {...props} />;\n * }\n * ```\n */\nexport function createNextApp(options: CreateNextAppOptions): NextAppExports {\n const { spec: specOrFn, loaders } = options;\n\n /**\n * Resolve page data for a given set of route params.\n * Returns null when no route matches.\n */\n async function getPageData({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<PageData | null> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n\n const matched = matchRoute(spec, pathname);\n\n if (!matched) {\n return null;\n }\n\n const { route } = matched;\n\n let loaderData: Record<string, unknown> | undefined;\n if (route.loader && loaders?.[route.loader]) {\n loaderData = await loaders[route.loader]!(matched.params);\n }\n\n const initialState = mergeState(\n spec.state,\n route.page.state as Record<string, unknown> | undefined,\n loaderData,\n );\n\n const layoutSpec =\n route.layout && spec.layouts\n ? (spec.layouts[route.layout] ?? null)\n : null;\n\n return {\n spec: route.page,\n initialState:\n Object.keys(initialState).length > 0 ? initialState : undefined,\n layoutSpec,\n };\n }\n\n /**\n * Generate metadata for the matched route.\n * Merges global spec metadata with route-specific metadata.\n */\n async function generateMetadata({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<ResolvedMetadata> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n const matched = matchRoute(spec, pathname);\n return resolveMetadata(spec, matched?.route ?? null);\n }\n\n /**\n * Generate static params for all statically-known routes.\n * Used by Next.js to pre-render pages at build time.\n */\n async function generateStaticParams(): Promise<{ slug: string[] }[]> {\n const spec = await resolveSpec(specOrFn);\n return collectStaticParams(spec);\n }\n\n return { getPageData, generateMetadata, generateStaticParams };\n}\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Next.js app generation.\n *\n * Teaches the AI to generate multi-page applications with routes,\n * layouts, metadata, and page content using JSONL patches.\n */\nfunction nextAppPromptTemplate(context: PromptContext): string {\n const { catalog, options, formatZodType } = context;\n const {\n system = \"You are a Next.js application generator.\",\n customRules = [],\n } = options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with RFC 6902 JSON Patch operations to build a Next.js application spec.\",\n );\n lines.push(\n \"The spec defines routes (pages), layouts, metadata, and state for a full Next.js app.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(\n `{\"op\":\"add\",\"path\":\"/metadata\",\"value\":{\"title\":{\"default\":\"My App\",\"template\":\"%s | My App\"},\"description\":\"A full Next.js application\"}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/layouts\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/layouts/main\",\"value\":{\"root\":\"shell\",\"elements\":{\"shell\":{\"type\":\"AppShell\",\"props\":{},\"children\":[\"nav\",\"slot\"]},\"nav\":{\"type\":\"NavBar\",\"props\":{\"links\":[{\"href\":\"/\",\"label\":\"Home\"},{\"href\":\"/about\",\"label\":\"About\"}]},\"children\":[]},\"slot\":{\"type\":\"Slot\",\"props\":{},\"children\":[]}}}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/routes\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"Home\"},\"page\":{\"root\":\"hero\",\"elements\":{\"hero\":{\"type\":\"Card\",\"props\":{\"title\":\"Welcome\"},\"children\":[]}}}}}`,\n );\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1about\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"About\"},\"page\":{\"root\":\"content\",\"elements\":{\"content\":{\"type\":\"Card\",\"props\":{\"title\":\"About Us\"},\"children\":[]}}}}}`,\n );\n lines.push(\"\");\n\n lines.push(\"SPEC STRUCTURE:\");\n lines.push(\"The top-level spec has these fields:\");\n lines.push(\n \" - metadata: Root-level SEO metadata (title template, description, openGraph, twitter)\",\n );\n lines.push(\n \" - layouts: Reusable layout element trees. Each layout MUST include a { type: 'Slot' } element where page content will be injected.\",\n );\n lines.push(\" - routes: Route definitions keyed by URL pattern\");\n lines.push(\" - state: Global initial state shared across all routes\");\n lines.push(\"\");\n\n lines.push(\"ROUTES:\");\n lines.push(\"Route keys use Next.js URL patterns:\");\n lines.push(\" - '/' - home page\");\n lines.push(\" - '/about' - static route\");\n lines.push(\" - '/blog/[slug]' - dynamic segment\");\n lines.push(\" - '/docs/[...path]' - catch-all segment\");\n lines.push(\" - '/settings/[[...path]]' - optional catch-all segment\");\n lines.push(\"\");\n lines.push(\n \"IMPORTANT: In JSON Patch paths, forward slashes in route keys must be escaped as ~1.\",\n );\n lines.push(\" - Route '/' becomes path '/routes/~1'\");\n lines.push(\" - Route '/about' becomes path '/routes/~1about'\");\n lines.push(\" - Route '/blog/[slug]' becomes path '/routes/~1blog~1[slug]'\");\n lines.push(\"\");\n\n lines.push(\"Each route has:\");\n lines.push(\n \" - page: Element tree (root + elements + optional state) — the page content\",\n );\n lines.push(\n \" - metadata: Per-route SEO metadata (title, description, openGraph)\",\n );\n lines.push(\" - layout: Layout key referencing an entry in the layouts map\");\n lines.push(\" - loading: Optional loading state element tree\");\n lines.push(\" - error: Optional error state element tree\");\n lines.push(\" - loader: Optional server-side data loader name\");\n lines.push(\"\");\n\n lines.push(\"LAYOUTS:\");\n lines.push(\n \"Layouts wrap page content. A layout element tree MUST include a component with type 'Slot' — this is where the page content will be rendered.\",\n );\n lines.push(\n \"Layouts are defined once and reused across routes via the layout field.\",\n );\n lines.push(\"\");\n\n lines.push(\"METADATA:\");\n lines.push(\"Root metadata sets defaults. Route metadata overrides per page.\");\n lines.push(\n \" - title: string or { default, template } (use %s for page title in template)\",\n );\n lines.push(\" - description: string\");\n lines.push(\" - openGraph: { title, description, images, type }\");\n lines.push(\" - twitter: { card, title, description }\");\n lines.push(\"\");\n\n lines.push(\"PAGE CONTENT:\");\n lines.push(\n \"Each page uses the standard json-render element tree format: root, elements, optional state.\",\n );\n lines.push(\n \"Elements have type, props, children, and optionally visible, on, repeat, watch fields.\",\n );\n lines.push(\"\");\n\n const catalogData = catalog as {\n components?: Record<\n string,\n {\n description?: string;\n props?: unknown;\n slots?: string[];\n events?: string[];\n }\n >;\n actions?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const propsStr = def.props ? formatZodType(def.props as any) : \"{}\";\n const hasChildren = def.slots && def.slots.length > 0;\n const childrenStr = hasChildren ? \" [accepts children]\" : \"\";\n const eventsStr =\n def.events && def.events.length > 0\n ? ` [events: ${def.events.join(\", \")}]`\n : \"\";\n const descStr = def.description ? ` - ${def.description}` : \"\";\n lines.push(`- ${name}: ${propsStr}${descStr}${childrenStr}${eventsStr}`);\n }\n lines.push(\"\");\n lines.push(\"Built-in components (always available):\");\n lines.push(\n \"- Slot: {} - Placeholder in layouts where page content is rendered. Required in every layout.\",\n );\n lines.push(\n \"- Link: { href: string } [accepts children] - Client-side navigation link (renders as next/link).\",\n );\n lines.push(\"\");\n }\n\n if (catalogData.actions && Object.keys(catalogData.actions).length > 0) {\n lines.push(\"AVAILABLE ACTIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.actions)) {\n lines.push(`- ${name}${def.description ? `: ${def.description}` : \"\"}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"BUILT-IN ACTIONS:\");\n lines.push(\n \"- setState: Update a value in the state model. Params: { statePath: string, value: any }\",\n );\n lines.push(\n \"- pushState: Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }\",\n );\n lines.push(\n \"- removeState: Remove an item from an array by index. Params: { statePath: string, index: number }\",\n );\n lines.push(\"- navigate: Navigate to a route. Params: { href: string }\");\n lines.push(\"\");\n\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n \"First add /metadata with the app-level metadata including title template\",\n \"Then add /layouts with reusable layout definitions (each must have a Slot component)\",\n \"Then add /routes with each route's page, metadata, and layout reference\",\n \"Every layout MUST include a { type: 'Slot' } element where page content is injected\",\n \"ONLY use components listed in AVAILABLE COMPONENTS (plus built-in Slot and Link)\",\n \"Each element needs: type, props, children (array of child keys)\",\n \"Use unique keys for element map entries\",\n \"Escape forward slashes in route keys as ~1 in JSON Patch paths\",\n \"Include realistic sample data in state for data-driven pages\",\n \"Use Link component for navigation between routes\",\n \"Create a cohesive multi-page app with consistent layouts and navigation\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/next.\n *\n * Defines a multi-page Next.js application structure:\n * - Spec: Routes with pages, layouts, metadata, loading/error states\n * - Catalog: Components with props schemas, and optional actions\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's page-based, designed for full Next.js applications with SSR,\n * routing, and metadata generation.\n */\nexport const schema = defineSchema(\n (s) => ({\n spec: s.object({\n /** Root-level metadata applied as defaults */\n metadata: s.object({\n title: s.any(),\n description: s.string(),\n keywords: s.array(s.string()),\n openGraph: s.any(),\n twitter: s.any(),\n robots: s.any(),\n icons: s.any(),\n }),\n\n /** Route definitions keyed by URL pattern */\n routes: s.record(\n s.object({\n /** Page element tree */\n page: s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: s.any(),\n }),\n ),\n state: s.any(),\n }),\n /** Per-route metadata */\n metadata: s.any(),\n /** Layout key */\n layout: s.string(),\n /** Loading state element tree */\n loading: s.any(),\n /** Error state element tree */\n error: s.any(),\n /** Not-found element tree */\n notFound: s.any(),\n /** Server-side data loader name */\n loader: s.string(),\n /** Static params for SSG */\n staticParams: s.any(),\n }),\n ),\n\n /** Reusable layout element trees */\n layouts: s.record(\n s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: s.any(),\n }),\n ),\n state: s.any(),\n }),\n ),\n\n /** Global initial state */\n state: s.any(),\n }),\n\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n props: s.zod(),\n slots: s.array(s.string()),\n description: s.string(),\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n params: s.zod(),\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: nextAppPromptTemplate,\n builtInActions: [\n {\n name: \"setState\",\n description:\n \"Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\",\n },\n {\n name: \"pushState\",\n description:\n 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.',\n },\n {\n name: \"removeState\",\n description:\n \"Remove an item from an array in state by index. Params: { statePath: string, index: number }\",\n },\n {\n name: \"navigate\",\n description:\n \"Navigate to a route within the app. Params: { href: string }\",\n },\n ],\n },\n);\n\n/**\n * Type for the Next.js schema\n */\nexport type NextSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type NextSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/router.ts","../src/metadata.ts","../src/create-app.ts","../src/schema.ts"],"sourcesContent":["import type { NextAppSpec, MatchedRoute } from \"./types\";\n\ninterface CompiledRoute {\n pattern: string;\n regex: RegExp;\n paramNames: string[];\n /** Whether the last segment is catch-all or optional catch-all */\n catchAll: boolean;\n optionalCatchAll: boolean;\n /** Number of static segments (higher = more specific) */\n specificity: number;\n}\n\n/**\n * Compile a Next.js route pattern into a regex matcher.\n *\n * Supports:\n * - Static segments: `/about`, `/blog`\n * - Dynamic segments: `/blog/[slug]`\n * - Catch-all segments: `/docs/[...path]`\n * - Optional catch-all segments: `/settings/[[...path]]`\n */\nfunction compileRoute(pattern: string): CompiledRoute {\n const paramNames: string[] = [];\n let catchAll = false;\n let optionalCatchAll = false;\n let specificity = 0;\n\n const segments = pattern === \"/\" ? [\"\"] : pattern.split(\"/\").slice(1);\n const regexParts: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n paramNames.push(paramName);\n optionalCatchAll = true;\n regexParts.push(\"(?:/(.+))?\");\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n paramNames.push(paramName);\n catchAll = true;\n regexParts.push(\"/(.+)\");\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n paramNames.push(paramName);\n regexParts.push(\"/([^/]+)\");\n } else {\n specificity++;\n regexParts.push(`/${escapeRegExp(segment)}`);\n }\n }\n\n const regexStr = pattern === \"/\" ? \"^/$\" : `^${regexParts.join(\"\")}$`;\n\n return {\n pattern,\n regex: new RegExp(regexStr),\n paramNames,\n catchAll,\n optionalCatchAll,\n specificity,\n };\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Match a pathname against a spec's routes.\n *\n * Routes are matched in order of specificity:\n * 1. Exact/static matches first (most specific)\n * 2. Dynamic segment matches\n * 3. Catch-all matches (least specific)\n * 4. Optional catch-all matches (fallback)\n *\n * @returns The matched route with extracted params, or null if no match.\n */\nexport function matchRoute(\n spec: NextAppSpec,\n pathname: string,\n): MatchedRoute | null {\n const normalizedPath = pathname === \"\" ? \"/\" : pathname;\n\n const compiled = Object.keys(spec.routes).map(compileRoute);\n\n compiled.sort((a, b) => {\n if (a.optionalCatchAll !== b.optionalCatchAll) {\n return a.optionalCatchAll ? 1 : -1;\n }\n if (a.catchAll !== b.catchAll) {\n return a.catchAll ? 1 : -1;\n }\n if (a.specificity !== b.specificity) {\n return b.specificity - a.specificity;\n }\n return a.paramNames.length - b.paramNames.length;\n });\n\n for (const route of compiled) {\n const match = route.regex.exec(normalizedPath);\n if (!match) continue;\n\n const params: Record<string, string | string[]> = {};\n for (let i = 0; i < route.paramNames.length; i++) {\n const value = match[i + 1];\n const name = route.paramNames[i]!;\n\n if (route.catchAll || route.optionalCatchAll) {\n params[name] = value ? value.split(\"/\") : [];\n } else {\n params[name] = value ?? \"\";\n }\n }\n\n return {\n route: spec.routes[route.pattern]!,\n pattern: route.pattern,\n params,\n };\n }\n\n return null;\n}\n\n/**\n * Convert a Next.js catch-all slug array to a pathname.\n *\n * @example\n * slugToPath(undefined) // \"/\"\n * slugToPath([]) // \"/\"\n * slugToPath([\"blog\"]) // \"/blog\"\n * slugToPath([\"blog\",\"hi\"]) // \"/blog/hi\"\n */\nexport function slugToPath(slug: string[] | undefined): string {\n if (!slug || slug.length === 0) return \"/\";\n return \"/\" + slug.join(\"/\");\n}\n\n/**\n * Collect all static params from the spec for generateStaticParams.\n * Returns params suitable for Next.js [[...slug]] catch-all routes.\n */\nexport function collectStaticParams(spec: NextAppSpec): { slug: string[] }[] {\n const results: { slug: string[] }[] = [];\n\n for (const [pattern, route] of Object.entries(spec.routes)) {\n if (route.staticParams) {\n for (const paramSet of route.staticParams) {\n const slug = buildSlugFromPattern(pattern, paramSet);\n if (slug) results.push({ slug });\n }\n } else if (!pattern.includes(\"[\")) {\n const slug = pattern === \"/\" ? [] : pattern.slice(1).split(\"/\");\n results.push({ slug });\n }\n }\n\n return results;\n}\n\n/**\n * Build a slug array from a route pattern and a set of params.\n */\nfunction buildSlugFromPattern(\n pattern: string,\n params: Record<string, string>,\n): string[] | null {\n if (pattern === \"/\") return [];\n\n const segments = pattern.split(\"/\").slice(1);\n const result: string[] = [];\n\n for (const segment of segments) {\n if (segment.startsWith(\"[[...\") && segment.endsWith(\"]]\")) {\n const paramName = segment.slice(5, -2);\n const value = params[paramName];\n if (value) result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(...value.split(\"/\"));\n } else if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(1, -1);\n const value = params[paramName];\n if (!value) return null;\n result.push(value);\n } else {\n result.push(segment);\n }\n }\n\n return result;\n}\n","import type { NextMetadata, NextAppSpec, NextRouteSpec } from \"./types\";\n\n/**\n * Metadata result compatible with Next.js's Metadata type.\n * Uses plain objects to avoid importing Next.js types at runtime.\n */\nexport type ResolvedMetadata = Record<string, unknown>;\n\n/**\n * Resolve metadata for a route by merging global spec metadata\n * with route-specific metadata.\n *\n * Follows Next.js metadata merging semantics:\n * - Route metadata overrides global metadata for scalar fields\n * - Title templates from global metadata apply to route titles\n * - OpenGraph and Twitter fields are shallow-merged\n */\nexport function resolveMetadata(\n spec: NextAppSpec,\n route?: NextRouteSpec | null,\n): ResolvedMetadata {\n const globalMeta = spec.metadata;\n const routeMeta = route?.metadata;\n\n if (!globalMeta && !routeMeta) return {};\n\n const result: ResolvedMetadata = {};\n\n const mergedTitle = resolveTitle(globalMeta?.title, routeMeta?.title);\n if (mergedTitle !== undefined) result.title = mergedTitle;\n\n const description = routeMeta?.description ?? globalMeta?.description;\n if (description) result.description = description;\n\n const keywords = routeMeta?.keywords ?? globalMeta?.keywords;\n if (keywords) result.keywords = keywords;\n\n const openGraph = mergeObject(globalMeta?.openGraph, routeMeta?.openGraph);\n if (openGraph) result.openGraph = openGraph;\n\n const twitter = mergeObject(globalMeta?.twitter, routeMeta?.twitter);\n if (twitter) result.twitter = twitter;\n\n const robots = routeMeta?.robots ?? globalMeta?.robots;\n if (robots) result.robots = robots;\n\n const alternates = routeMeta?.alternates ?? globalMeta?.alternates;\n if (alternates) result.alternates = alternates;\n\n const icons = routeMeta?.icons ?? globalMeta?.icons;\n if (icons) result.icons = icons;\n\n return result;\n}\n\n/**\n * Resolve a title value considering templates.\n *\n * If global metadata defines a title template (e.g. \"%s | My App\"),\n * route titles are interpolated into it.\n */\nfunction resolveTitle(\n globalTitle: NextMetadata[\"title\"],\n routeTitle: NextMetadata[\"title\"],\n): unknown {\n if (!routeTitle && !globalTitle) return undefined;\n\n if (!routeTitle) {\n if (typeof globalTitle === \"string\") return globalTitle;\n if (typeof globalTitle === \"object\" && globalTitle !== null) {\n return globalTitle.default ?? undefined;\n }\n return undefined;\n }\n\n if (typeof routeTitle === \"object\" && routeTitle !== null) {\n if (routeTitle.absolute) return routeTitle.absolute;\n if (routeTitle.template || routeTitle.default) return routeTitle;\n return routeTitle;\n }\n\n if (\n typeof globalTitle === \"object\" &&\n globalTitle !== null &&\n globalTitle.template\n ) {\n return globalTitle.template.replace(\"%s\", routeTitle as string);\n }\n\n return routeTitle;\n}\n\nfunction mergeObject(\n base: Record<string, unknown> | undefined,\n override: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !override) return undefined;\n if (!base) return override;\n if (!override) return base;\n return { ...base, ...override };\n}\n","import { notFound } from \"next/navigation\";\nimport type {\n NextAppSpec,\n CreateNextAppOptions,\n NextAppExports,\n PageData,\n} from \"./types\";\nimport { matchRoute, slugToPath, collectStaticParams } from \"./router\";\nimport { resolveMetadata, type ResolvedMetadata } from \"./metadata\";\n\n/**\n * Resolve the spec from the options — supports both static specs\n * and factory functions that return specs (sync or async).\n */\nasync function resolveSpec(\n specOrFn: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>),\n): Promise<NextAppSpec> {\n if (typeof specOrFn === \"function\") {\n return await specOrFn();\n }\n return specOrFn;\n}\n\n/**\n * Merge state from multiple sources: global state, page state, and loader data.\n * Later sources override earlier ones.\n */\nfunction mergeState(\n ...sources: (Record<string, unknown> | undefined | null)[]\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const source of sources) {\n if (source) {\n Object.assign(result, source);\n }\n }\n return result;\n}\n\n/**\n * Create a fully wired Next.js application from a json-render spec.\n *\n * Returns `getPageData`, `generateMetadata`, and `generateStaticParams`\n * ready to be used in Next.js `[[...slug]]` catch-all routes.\n *\n * @example\n * ```typescript\n * // lib/app.ts\n * import { createNextApp } from \"@json-render/next/server\";\n *\n * export const { getPageData, generateMetadata, generateStaticParams } =\n * createNextApp({ spec });\n *\n * // app/[[...slug]]/page.tsx (Server Component)\n * import { notFound } from \"next/navigation\";\n * import { getPageData, generateMetadata, generateStaticParams } from \"@/lib/app\";\n * import { SiteRenderer } from \"./renderer\";\n *\n * export { generateMetadata, generateStaticParams };\n *\n * export default async function Page({ params }) {\n * const data = await getPageData({ params });\n * if (!data) notFound();\n * return <SiteRenderer {...data} />;\n * }\n *\n * // app/[[...slug]]/renderer.tsx (\"use client\")\n * import { PageRenderer } from \"@json-render/next\";\n * export function SiteRenderer(props) {\n * return <PageRenderer {...props} />;\n * }\n * ```\n */\nexport function createNextApp(options: CreateNextAppOptions): NextAppExports {\n const { spec: specOrFn, loaders } = options;\n\n /**\n * Resolve page data for a given set of route params.\n * Returns null when no route matches.\n */\n async function getPageData({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<PageData | null> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n\n const matched = matchRoute(spec, pathname);\n\n if (!matched) {\n return null;\n }\n\n const { route } = matched;\n\n let loaderData: Record<string, unknown> | undefined;\n if (route.loader && loaders?.[route.loader]) {\n loaderData = await loaders[route.loader]!(matched.params);\n }\n\n const initialState = mergeState(\n spec.state,\n route.page.state as Record<string, unknown> | undefined,\n loaderData,\n );\n\n const layoutSpec =\n route.layout && spec.layouts\n ? (spec.layouts[route.layout] ?? null)\n : null;\n\n return {\n spec: route.page,\n initialState:\n Object.keys(initialState).length > 0 ? initialState : undefined,\n layoutSpec,\n };\n }\n\n /**\n * Generate metadata for the matched route.\n * Merges global spec metadata with route-specific metadata.\n */\n async function generateMetadata({\n params,\n }: {\n params: Promise<{ slug?: string[] }>;\n }): Promise<ResolvedMetadata> {\n const { slug } = await params;\n const pathname = slugToPath(slug);\n const spec = await resolveSpec(specOrFn);\n const matched = matchRoute(spec, pathname);\n return resolveMetadata(spec, matched?.route ?? null);\n }\n\n /**\n * Generate static params for all statically-known routes.\n * Used by Next.js to pre-render pages at build time.\n */\n async function generateStaticParams(): Promise<{ slug: string[] }[]> {\n const spec = await resolveSpec(specOrFn);\n return collectStaticParams(spec);\n }\n\n return { getPageData, generateMetadata, generateStaticParams };\n}\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Next.js app generation.\n *\n * Teaches the AI to generate multi-page applications with routes,\n * layouts, metadata, and page content using JSONL patches.\n */\nfunction nextAppPromptTemplate(context: PromptContext): string {\n const { catalog, options, formatZodType } = context;\n const {\n system = \"You are a Next.js application generator.\",\n customRules = [],\n } = options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with RFC 6902 JSON Patch operations to build a Next.js application spec.\",\n );\n lines.push(\n \"The spec defines routes (pages), layouts, metadata, and state for a full Next.js app.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(\n `{\"op\":\"add\",\"path\":\"/metadata\",\"value\":{\"title\":{\"default\":\"My App\",\"template\":\"%s | My App\"},\"description\":\"A full Next.js application\"}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/layouts\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/layouts/main\",\"value\":{\"root\":\"shell\",\"elements\":{\"shell\":{\"type\":\"AppShell\",\"props\":{},\"children\":[\"nav\",\"slot\"]},\"nav\":{\"type\":\"NavBar\",\"props\":{\"links\":[{\"href\":\"/\",\"label\":\"Home\"},{\"href\":\"/about\",\"label\":\"About\"}]},\"children\":[]},\"slot\":{\"type\":\"Slot\",\"props\":{},\"children\":[]}}}}`,\n );\n lines.push(`{\"op\":\"add\",\"path\":\"/routes\",\"value\":{}}`);\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"Home\"},\"page\":{\"root\":\"hero\",\"elements\":{\"hero\":{\"type\":\"Card\",\"props\":{\"title\":\"Welcome\"},\"children\":[]}}}}}`,\n );\n lines.push(\n `{\"op\":\"add\",\"path\":\"/routes/~1about\",\"value\":{\"layout\":\"main\",\"metadata\":{\"title\":\"About\"},\"page\":{\"root\":\"content\",\"elements\":{\"content\":{\"type\":\"Card\",\"props\":{\"title\":\"About Us\"},\"children\":[]}}}}}`,\n );\n lines.push(\"\");\n\n lines.push(\"SPEC STRUCTURE:\");\n lines.push(\"The top-level spec has these fields:\");\n lines.push(\n \" - metadata: Root-level SEO metadata (title template, description, openGraph, twitter)\",\n );\n lines.push(\n \" - layouts: Reusable layout element trees. Each layout MUST include a { type: 'Slot' } element where page content will be injected.\",\n );\n lines.push(\" - routes: Route definitions keyed by URL pattern\");\n lines.push(\" - state: Global initial state shared across all routes\");\n lines.push(\"\");\n\n lines.push(\"ROUTES:\");\n lines.push(\"Route keys use Next.js URL patterns:\");\n lines.push(\" - '/' - home page\");\n lines.push(\" - '/about' - static route\");\n lines.push(\" - '/blog/[slug]' - dynamic segment\");\n lines.push(\" - '/docs/[...path]' - catch-all segment\");\n lines.push(\" - '/settings/[[...path]]' - optional catch-all segment\");\n lines.push(\"\");\n lines.push(\n \"IMPORTANT: In JSON Patch paths, forward slashes in route keys must be escaped as ~1.\",\n );\n lines.push(\" - Route '/' becomes path '/routes/~1'\");\n lines.push(\" - Route '/about' becomes path '/routes/~1about'\");\n lines.push(\" - Route '/blog/[slug]' becomes path '/routes/~1blog~1[slug]'\");\n lines.push(\"\");\n\n lines.push(\"Each route has:\");\n lines.push(\n \" - page: Element tree (root + elements + optional state) — the page content\",\n );\n lines.push(\n \" - metadata: Per-route SEO metadata (title, description, openGraph)\",\n );\n lines.push(\" - layout: Layout key referencing an entry in the layouts map\");\n lines.push(\" - loading: Optional loading state element tree\");\n lines.push(\" - error: Optional error state element tree\");\n lines.push(\" - loader: Optional server-side data loader name\");\n lines.push(\"\");\n\n lines.push(\"LAYOUTS:\");\n lines.push(\n \"Layouts wrap page content. A layout element tree MUST include a component with type 'Slot' — this is where the page content will be rendered.\",\n );\n lines.push(\n \"Layouts are defined once and reused across routes via the layout field.\",\n );\n lines.push(\"\");\n\n lines.push(\"METADATA:\");\n lines.push(\"Root metadata sets defaults. Route metadata overrides per page.\");\n lines.push(\n \" - title: string or { default, template } (use %s for page title in template)\",\n );\n lines.push(\" - description: string\");\n lines.push(\" - openGraph: { title, description, images, type }\");\n lines.push(\" - twitter: { card, title, description }\");\n lines.push(\"\");\n\n lines.push(\"PAGE CONTENT:\");\n lines.push(\n \"Each page uses the standard json-render element tree format: root, elements, optional state.\",\n );\n lines.push(\n \"Elements have type, props, children, and optionally visible, on, repeat, watch fields.\",\n );\n lines.push(\"\");\n\n const catalogData = catalog as {\n components?: Record<\n string,\n {\n description?: string;\n props?: unknown;\n slots?: string[];\n events?: string[];\n }\n >;\n actions?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const propsStr = def.props ? formatZodType(def.props as any) : \"{}\";\n const hasChildren = def.slots && def.slots.length > 0;\n const childrenStr = hasChildren ? \" [accepts children]\" : \"\";\n const eventsStr =\n def.events && def.events.length > 0\n ? ` [events: ${def.events.join(\", \")}]`\n : \"\";\n const descStr = def.description ? ` - ${def.description}` : \"\";\n lines.push(`- ${name}: ${propsStr}${descStr}${childrenStr}${eventsStr}`);\n }\n lines.push(\"\");\n lines.push(\"Built-in components (always available):\");\n lines.push(\n \"- Slot: {} - Placeholder in layouts where page content is rendered. Required in every layout.\",\n );\n lines.push(\n \"- Link: { href: string } [accepts children] - Client-side navigation link (renders as next/link).\",\n );\n lines.push(\"\");\n }\n\n if (catalogData.actions && Object.keys(catalogData.actions).length > 0) {\n lines.push(\"AVAILABLE ACTIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.actions)) {\n lines.push(`- ${name}${def.description ? `: ${def.description}` : \"\"}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"BUILT-IN ACTIONS:\");\n lines.push(\n \"- setState: Update a value in the state model. Params: { statePath: string, value: any }\",\n );\n lines.push(\n \"- pushState: Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }\",\n );\n lines.push(\n \"- removeState: Remove an item from an array by index. Params: { statePath: string, index: number }\",\n );\n lines.push(\"- navigate: Navigate to a route. Params: { href: string }\");\n lines.push(\"\");\n\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n \"First add /metadata with the app-level metadata including title template\",\n \"Then add /layouts with reusable layout definitions (each must have a Slot component)\",\n \"Then add /routes with each route's page, metadata, and layout reference\",\n \"Every layout MUST include a { type: 'Slot' } element where page content is injected\",\n \"ONLY use components listed in AVAILABLE COMPONENTS (plus built-in Slot and Link)\",\n \"Each element needs: type, props, children (array of child keys)\",\n \"Use unique keys for element map entries\",\n \"Escape forward slashes in route keys as ~1 in JSON Patch paths\",\n \"Include realistic sample data in state for data-driven pages\",\n \"Use Link component for navigation between routes\",\n \"Create a cohesive multi-page app with consistent layouts and navigation\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/next.\n *\n * Defines a multi-page Next.js application structure:\n * - Spec: Routes with pages, layouts, metadata, loading/error states\n * - Catalog: Components with props schemas, and optional actions\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's page-based, designed for full Next.js applications with SSR,\n * routing, and metadata generation.\n */\nexport const schema = defineSchema(\n (s) => ({\n spec: s.object({\n /** Root-level metadata applied as defaults */\n metadata: {\n ...s.object({\n title: { ...s.any(), ...s.optional() },\n description: { ...s.string(), ...s.optional() },\n keywords: { ...s.array(s.string()), ...s.optional() },\n openGraph: { ...s.any(), ...s.optional() },\n twitter: { ...s.any(), ...s.optional() },\n robots: { ...s.any(), ...s.optional() },\n alternates: { ...s.any(), ...s.optional() },\n icons: { ...s.any(), ...s.optional() },\n }),\n ...s.optional(),\n },\n\n /** Route definitions keyed by URL pattern */\n routes: s.record(\n s.object({\n /** Page element tree */\n page: s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: { ...s.any(), ...s.optional() },\n }),\n ),\n state: { ...s.any(), ...s.optional() },\n }),\n /** Per-route metadata */\n metadata: { ...s.any(), ...s.optional() },\n /** Layout key */\n layout: { ...s.string(), ...s.optional() },\n /** Loading state element tree */\n loading: { ...s.any(), ...s.optional() },\n /** Error state element tree */\n error: { ...s.any(), ...s.optional() },\n /** Not-found element tree */\n notFound: { ...s.any(), ...s.optional() },\n /** Server-side data loader name */\n loader: { ...s.string(), ...s.optional() },\n /** Static params for SSG */\n staticParams: { ...s.any(), ...s.optional() },\n }),\n ),\n\n /** Reusable layout element trees */\n layouts: {\n ...s.record(\n s.object({\n root: s.string(),\n elements: s.record(\n s.object({\n type: s.ref(\"catalog.components\"),\n props: s.propsOf(\"catalog.components\"),\n children: s.array(s.string()),\n visible: { ...s.any(), ...s.optional() },\n }),\n ),\n state: { ...s.any(), ...s.optional() },\n }),\n ),\n ...s.optional(),\n },\n\n /** Global initial state */\n state: { ...s.any(), ...s.optional() },\n }),\n\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n props: s.zod(),\n slots: s.array(s.string()),\n description: s.string(),\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n params: s.zod(),\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: nextAppPromptTemplate,\n builtInActions: [\n {\n name: \"setState\",\n description:\n \"Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\",\n },\n {\n name: \"pushState\",\n description:\n 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.',\n },\n {\n name: \"removeState\",\n description:\n \"Remove an item from an array in state by index. Params: { statePath: string, index: number }\",\n },\n {\n name: \"navigate\",\n description:\n \"Navigate to a route within the app. Params: { href: string }\",\n },\n ],\n },\n);\n\n/**\n * Type for the Next.js schema\n */\nexport type NextSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type NextSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n"],"mappings":";AAsBA,SAAS,aAAa,SAAgC;AACpD,QAAM,aAAuB,CAAC;AAC9B,MAAI,WAAW;AACf,MAAI,mBAAmB;AACvB,MAAI,cAAc;AAElB,QAAM,WAAW,YAAY,MAAM,CAAC,EAAE,IAAI,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC;AACpE,QAAM,aAAuB,CAAC;AAE9B,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,WAAW,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AACzD,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,yBAAmB;AACnB,iBAAW,KAAK,YAAY;AAAA,IAC9B,WAAW,QAAQ,WAAW,MAAM,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC9D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,iBAAW;AACX,iBAAW,KAAK,OAAO;AAAA,IACzB,WAAW,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC3D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,iBAAW,KAAK,SAAS;AACzB,iBAAW,KAAK,UAAU;AAAA,IAC5B,OAAO;AACL;AACA,iBAAW,KAAK,IAAI,aAAa,OAAO,CAAC,EAAE;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,WAAW,YAAY,MAAM,QAAQ,IAAI,WAAW,KAAK,EAAE,CAAC;AAElE,SAAO;AAAA,IACL;AAAA,IACA,OAAO,IAAI,OAAO,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;AAaO,SAAS,WACd,MACA,UACqB;AACrB,QAAM,iBAAiB,aAAa,KAAK,MAAM;AAE/C,QAAM,WAAW,OAAO,KAAK,KAAK,MAAM,EAAE,IAAI,YAAY;AAE1D,WAAS,KAAK,CAAC,GAAG,MAAM;AACtB,QAAI,EAAE,qBAAqB,EAAE,kBAAkB;AAC7C,aAAO,EAAE,mBAAmB,IAAI;AAAA,IAClC;AACA,QAAI,EAAE,aAAa,EAAE,UAAU;AAC7B,aAAO,EAAE,WAAW,IAAI;AAAA,IAC1B;AACA,QAAI,EAAE,gBAAgB,EAAE,aAAa;AACnC,aAAO,EAAE,cAAc,EAAE;AAAA,IAC3B;AACA,WAAO,EAAE,WAAW,SAAS,EAAE,WAAW;AAAA,EAC5C,CAAC;AAED,aAAW,SAAS,UAAU;AAC5B,UAAM,QAAQ,MAAM,MAAM,KAAK,cAAc;AAC7C,QAAI,CAAC,MAAO;AAEZ,UAAM,SAA4C,CAAC;AACnD,aAAS,IAAI,GAAG,IAAI,MAAM,WAAW,QAAQ,KAAK;AAChD,YAAM,QAAQ,MAAM,IAAI,CAAC;AACzB,YAAM,OAAO,MAAM,WAAW,CAAC;AAE/B,UAAI,MAAM,YAAY,MAAM,kBAAkB;AAC5C,eAAO,IAAI,IAAI,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC;AAAA,MAC7C,OAAO;AACL,eAAO,IAAI,IAAI,SAAS;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,KAAK,OAAO,MAAM,OAAO;AAAA,MAChC,SAAS,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,WAAW,MAAoC;AAC7D,MAAI,CAAC,QAAQ,KAAK,WAAW,EAAG,QAAO;AACvC,SAAO,MAAM,KAAK,KAAK,GAAG;AAC5B;AAMO,SAAS,oBAAoB,MAAyC;AAC3E,QAAM,UAAgC,CAAC;AAEvC,aAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AAC1D,QAAI,MAAM,cAAc;AACtB,iBAAW,YAAY,MAAM,cAAc;AACzC,cAAM,OAAO,qBAAqB,SAAS,QAAQ;AACnD,YAAI,KAAM,SAAQ,KAAK,EAAE,KAAK,CAAC;AAAA,MACjC;AAAA,IACF,WAAW,CAAC,QAAQ,SAAS,GAAG,GAAG;AACjC,YAAM,OAAO,YAAY,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,EAAE,MAAM,GAAG;AAC9D,cAAQ,KAAK,EAAE,KAAK,CAAC;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,qBACP,SACA,QACiB;AACjB,MAAI,YAAY,IAAK,QAAO,CAAC;AAE7B,QAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC;AAC3C,QAAM,SAAmB,CAAC;AAE1B,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,WAAW,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AACzD,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,MAAO,QAAO,KAAK,GAAG,MAAM,MAAM,GAAG,CAAC;AAAA,IAC5C,WAAW,QAAQ,WAAW,MAAM,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC9D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,KAAK,GAAG,MAAM,MAAM,GAAG,CAAC;AAAA,IACjC,WAAW,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC3D,YAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AACrC,YAAM,QAAQ,OAAO,SAAS;AAC9B,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,KAAK,KAAK;AAAA,IACnB,OAAO;AACL,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;;;AClLO,SAAS,gBACd,MACA,OACkB;AAClB,QAAM,aAAa,KAAK;AACxB,QAAM,YAAY,OAAO;AAEzB,MAAI,CAAC,cAAc,CAAC,UAAW,QAAO,CAAC;AAEvC,QAAM,SAA2B,CAAC;AAElC,QAAM,cAAc,aAAa,YAAY,OAAO,WAAW,KAAK;AACpE,MAAI,gBAAgB,OAAW,QAAO,QAAQ;AAE9C,QAAM,cAAc,WAAW,eAAe,YAAY;AAC1D,MAAI,YAAa,QAAO,cAAc;AAEtC,QAAM,WAAW,WAAW,YAAY,YAAY;AACpD,MAAI,SAAU,QAAO,WAAW;AAEhC,QAAM,YAAY,YAAY,YAAY,WAAW,WAAW,SAAS;AACzE,MAAI,UAAW,QAAO,YAAY;AAElC,QAAM,UAAU,YAAY,YAAY,SAAS,WAAW,OAAO;AACnE,MAAI,QAAS,QAAO,UAAU;AAE9B,QAAM,SAAS,WAAW,UAAU,YAAY;AAChD,MAAI,OAAQ,QAAO,SAAS;AAE5B,QAAM,aAAa,WAAW,cAAc,YAAY;AACxD,MAAI,WAAY,QAAO,aAAa;AAEpC,QAAM,QAAQ,WAAW,SAAS,YAAY;AAC9C,MAAI,MAAO,QAAO,QAAQ;AAE1B,SAAO;AACT;AAQA,SAAS,aACP,aACA,YACS;AACT,MAAI,CAAC,cAAc,CAAC,YAAa,QAAO;AAExC,MAAI,CAAC,YAAY;AACf,QAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,QAAI,OAAO,gBAAgB,YAAY,gBAAgB,MAAM;AAC3D,aAAO,YAAY,WAAW;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,eAAe,YAAY,eAAe,MAAM;AACzD,QAAI,WAAW,SAAU,QAAO,WAAW;AAC3C,QAAI,WAAW,YAAY,WAAW,QAAS,QAAO;AACtD,WAAO;AAAA,EACT;AAEA,MACE,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,YAAY,UACZ;AACA,WAAO,YAAY,SAAS,QAAQ,MAAM,UAAoB;AAAA,EAChE;AAEA,SAAO;AACT;AAEA,SAAS,YACP,MACA,UACqC;AACrC,MAAI,CAAC,QAAQ,CAAC,SAAU,QAAO;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,EAAE,GAAG,MAAM,GAAG,SAAS;AAChC;;;ACtFA,eAAe,YACb,UACsB;AACtB,MAAI,OAAO,aAAa,YAAY;AAClC,WAAO,MAAM,SAAS;AAAA,EACxB;AACA,SAAO;AACT;AAMA,SAAS,cACJ,SACsB;AACzB,QAAM,SAAkC,CAAC;AACzC,aAAW,UAAU,SAAS;AAC5B,QAAI,QAAQ;AACV,aAAO,OAAO,QAAQ,MAAM;AAAA,IAC9B;AAAA,EACF;AACA,SAAO;AACT;AAoCO,SAAS,cAAc,SAA+C;AAC3E,QAAM,EAAE,MAAM,UAAU,QAAQ,IAAI;AAMpC,iBAAe,YAAY;AAAA,IACzB;AAAA,EACF,GAE6B;AAC3B,UAAM,EAAE,KAAK,IAAI,MAAM;AACvB,UAAM,WAAW,WAAW,IAAI;AAChC,UAAM,OAAO,MAAM,YAAY,QAAQ;AAEvC,UAAM,UAAU,WAAW,MAAM,QAAQ;AAEzC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,MAAM,IAAI;AAElB,QAAI;AACJ,QAAI,MAAM,UAAU,UAAU,MAAM,MAAM,GAAG;AAC3C,mBAAa,MAAM,QAAQ,MAAM,MAAM,EAAG,QAAQ,MAAM;AAAA,IAC1D;AAEA,UAAM,eAAe;AAAA,MACnB,KAAK;AAAA,MACL,MAAM,KAAK;AAAA,MACX;AAAA,IACF;AAEA,UAAM,aACJ,MAAM,UAAU,KAAK,UAChB,KAAK,QAAQ,MAAM,MAAM,KAAK,OAC/B;AAEN,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,cACE,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAMA,iBAAe,iBAAiB;AAAA,IAC9B;AAAA,EACF,GAE8B;AAC5B,UAAM,EAAE,KAAK,IAAI,MAAM;AACvB,UAAM,WAAW,WAAW,IAAI;AAChC,UAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,UAAM,UAAU,WAAW,MAAM,QAAQ;AACzC,WAAO,gBAAgB,MAAM,SAAS,SAAS,IAAI;AAAA,EACrD;AAMA,iBAAe,uBAAsD;AACnE,UAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,WAAO,oBAAoB,IAAI;AAAA,EACjC;AAEA,SAAO,EAAE,aAAa,kBAAkB,qBAAqB;AAC/D;;;ACnJA,SAAS,oBAAwC;AAQjD,SAAS,sBAAsB,SAAgC;AAC7D,QAAM,EAAE,SAAS,SAAS,cAAc,IAAI;AAC5C,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,cAAc,CAAC;AAAA,EACjB,IAAI;AAEJ,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,gBAAgB;AAC3B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uDAAuD;AAClE,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,2CAA2C;AACtD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,0CAA0C;AACrD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,sCAAsC;AACjD,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,oDAAoD;AAC/D,QAAM,KAAK,0DAA0D;AACrE,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,qBAAqB;AAChC,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,2CAA2C;AACtD,QAAM,KAAK,0DAA0D;AACrE,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,yCAAyC;AACpD,QAAM,KAAK,mDAAmD;AAC9D,QAAM,KAAK,gEAAgE;AAC3E,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAiB;AAC5B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,gEAAgE;AAC3E,QAAM,KAAK,kDAAkD;AAC7D,QAAM,KAAK,8CAA8C;AACzD,QAAM,KAAK,mDAAmD;AAC9D,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,UAAU;AACrB,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,iEAAiE;AAC5E,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,yBAAyB;AACpC,QAAM,KAAK,qDAAqD;AAChE,QAAM,KAAK,2CAA2C;AACtD,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,eAAe;AAC1B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,cAAc;AAapB,MAAI,YAAY,YAAY;AAC1B,UAAM;AAAA,MACJ,yBAAyB,OAAO,KAAK,YAAY,UAAU,EAAE,MAAM;AAAA,IACrE;AACA,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,YAAY,UAAU,GAAG;AAChE,YAAM,WAAW,IAAI,QAAQ,cAAc,IAAI,KAAY,IAAI;AAC/D,YAAM,cAAc,IAAI,SAAS,IAAI,MAAM,SAAS;AACpD,YAAM,cAAc,cAAc,wBAAwB;AAC1D,YAAM,YACJ,IAAI,UAAU,IAAI,OAAO,SAAS,IAC9B,aAAa,IAAI,OAAO,KAAK,IAAI,CAAC,MAClC;AACN,YAAM,UAAU,IAAI,cAAc,MAAM,IAAI,WAAW,KAAK;AAC5D,YAAM,KAAK,KAAK,IAAI,KAAK,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,EAAE;AAAA,IACzE;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,yCAAyC;AACpD,UAAM;AAAA,MACJ;AAAA,IACF;AACA,UAAM;AAAA,MACJ;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,YAAY,WAAW,OAAO,KAAK,YAAY,OAAO,EAAE,SAAS,GAAG;AACtE,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,YAAY,OAAO,GAAG;AAC7D,YAAM,KAAK,KAAK,IAAI,GAAG,IAAI,cAAc,KAAK,IAAI,WAAW,KAAK,EAAE,EAAE;AAAA,IACxE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,mBAAmB;AAC9B,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,2DAA2D;AACtE,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,QAAQ;AACnB,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,WAAW,CAAC,GAAG,WAAW,GAAG,WAAW;AAC9C,WAAS,QAAQ,CAAC,MAAM,MAAM;AAC5B,UAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE;AAAA,EAChC,CAAC;AAED,SAAO,MAAM,KAAK,IAAI;AACxB;AAaO,IAAM,SAAS;AAAA,EACpB,CAAC,OAAO;AAAA,IACN,MAAM,EAAE,OAAO;AAAA;AAAA,MAEb,UAAU;AAAA,QACR,GAAG,EAAE,OAAO;AAAA,UACV,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACrC,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UAC9C,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACpD,WAAW,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACzC,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACtC,YAAY,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UAC1C,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,QACvC,CAAC;AAAA,QACD,GAAG,EAAE,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,QAAQ,EAAE;AAAA,QACR,EAAE,OAAO;AAAA;AAAA,UAEP,MAAM,EAAE,OAAO;AAAA,YACb,MAAM,EAAE,OAAO;AAAA,YACf,UAAU,EAAE;AAAA,cACV,EAAE,OAAO;AAAA,gBACP,MAAM,EAAE,IAAI,oBAAoB;AAAA,gBAChC,OAAO,EAAE,QAAQ,oBAAoB;AAAA,gBACrC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,gBAC5B,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,cACzC,CAAC;AAAA,YACH;AAAA,YACA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,CAAC;AAAA;AAAA,UAED,UAAU,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAExC,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEzC,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEvC,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAErC,UAAU,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAExC,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEzC,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA;AAAA,MAGA,SAAS;AAAA,QACP,GAAG,EAAE;AAAA,UACH,EAAE,OAAO;AAAA,YACP,MAAM,EAAE,OAAO;AAAA,YACf,UAAU,EAAE;AAAA,cACV,EAAE,OAAO;AAAA,gBACP,MAAM,EAAE,IAAI,oBAAoB;AAAA,gBAChC,OAAO,EAAE,QAAQ,oBAAoB;AAAA,gBACrC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,gBAC5B,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,cACzC,CAAC;AAAA,YACH;AAAA,YACA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,UACvC,CAAC;AAAA,QACH;AAAA,QACA,GAAG,EAAE,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,IACvC,CAAC;AAAA,IAED,SAAS,EAAE,OAAO;AAAA;AAAA,MAEhB,YAAY,EAAE,IAAI;AAAA,QAChB,OAAO,EAAE,IAAI;AAAA,QACb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QACzB,aAAa,EAAE,OAAO;AAAA,QACtB,SAAS,EAAE,IAAI;AAAA,MACjB,CAAC;AAAA;AAAA,MAED,SAAS,EAAE,IAAI;AAAA,QACb,QAAQ,EAAE,IAAI;AAAA,QACd,aAAa,EAAE,OAAO;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,MACd;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-render/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Next.js renderer for @json-render/core. JSON becomes full Next.js applications with routes, layouts, metadata, and SSR.",
|
|
6
6
|
"keywords": [
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"dist"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@json-render/core": "0.
|
|
52
|
-
"@json-render/react": "0.
|
|
51
|
+
"@json-render/core": "0.20.0",
|
|
52
|
+
"@json-render/react": "0.20.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/react": "19.2.14",
|