@json-render/next 0.15.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/LICENSE +201 -0
- package/README.md +103 -0
- package/dist/chunk-37T7IDU5.js +104 -0
- package/dist/chunk-37T7IDU5.js.map +1 -0
- package/dist/chunk-KWYBSJZC.mjs +104 -0
- package/dist/chunk-KWYBSJZC.mjs.map +1 -0
- package/dist/index.d.mts +314 -0
- package/dist/index.d.ts +314 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +135 -0
- package/dist/index.mjs.map +1 -0
- package/dist/page-renderer-client.d.mts +25 -0
- package/dist/page-renderer-client.d.ts +25 -0
- package/dist/page-renderer-client.js +9 -0
- package/dist/page-renderer-client.js.map +1 -0
- package/dist/page-renderer-client.mjs +9 -0
- package/dist/page-renderer-client.mjs.map +1 -0
- package/dist/server.d.mts +358 -0
- package/dist/server.d.ts +358 -0
- package/dist/server.js +538 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +506 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import * as _json_render_core from '@json-render/core';
|
|
2
|
+
import { Spec } from '@json-render/core';
|
|
3
|
+
export { Spec, StateStore } from '@json-render/core';
|
|
4
|
+
export { ActionFn, Actions, BaseComponentProps, ComponentContext, ComponentFn, Components, EventHandle, SetState, StateModel } from '@json-render/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for Next.js pages and layouts.
|
|
8
|
+
* Maps to Next.js's Metadata type.
|
|
9
|
+
*/
|
|
10
|
+
interface NextMetadata {
|
|
11
|
+
/** Page title — string or template config */
|
|
12
|
+
title?: string | {
|
|
13
|
+
/** Default title when no child overrides */
|
|
14
|
+
default: string;
|
|
15
|
+
/** Template string, use %s for the page title (e.g. "%s | My App") */
|
|
16
|
+
template?: string;
|
|
17
|
+
/** Absolute title that ignores parent templates */
|
|
18
|
+
absolute?: string;
|
|
19
|
+
};
|
|
20
|
+
/** Meta description */
|
|
21
|
+
description?: string;
|
|
22
|
+
/** Keywords for SEO */
|
|
23
|
+
keywords?: string[];
|
|
24
|
+
/** Open Graph metadata */
|
|
25
|
+
openGraph?: {
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
images?: string | string[];
|
|
29
|
+
type?: string;
|
|
30
|
+
url?: string;
|
|
31
|
+
siteName?: string;
|
|
32
|
+
locale?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Twitter card metadata */
|
|
35
|
+
twitter?: {
|
|
36
|
+
card?: "summary" | "summary_large_image" | "app" | "player";
|
|
37
|
+
title?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
images?: string | string[];
|
|
40
|
+
creator?: string;
|
|
41
|
+
site?: string;
|
|
42
|
+
};
|
|
43
|
+
/** Robots directives */
|
|
44
|
+
robots?: string | {
|
|
45
|
+
index?: boolean;
|
|
46
|
+
follow?: boolean;
|
|
47
|
+
};
|
|
48
|
+
/** Canonical URL */
|
|
49
|
+
alternates?: {
|
|
50
|
+
canonical?: string;
|
|
51
|
+
};
|
|
52
|
+
/** Favicon and icons */
|
|
53
|
+
icons?: string | {
|
|
54
|
+
icon?: string;
|
|
55
|
+
apple?: string;
|
|
56
|
+
shortcut?: string;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A route definition within a NextAppSpec.
|
|
61
|
+
*/
|
|
62
|
+
interface NextRouteSpec {
|
|
63
|
+
/** Page content — standard json-render element tree */
|
|
64
|
+
page: Spec;
|
|
65
|
+
/** Per-route metadata for SEO */
|
|
66
|
+
metadata?: NextMetadata;
|
|
67
|
+
/** Layout key referencing an entry in NextAppSpec.layouts */
|
|
68
|
+
layout?: string;
|
|
69
|
+
/** Loading state element tree (rendered during Suspense) */
|
|
70
|
+
loading?: Spec;
|
|
71
|
+
/** Error state element tree */
|
|
72
|
+
error?: Spec;
|
|
73
|
+
/** Not-found element tree (for dynamic routes that don't match data) */
|
|
74
|
+
notFound?: Spec;
|
|
75
|
+
/** Server-side data loader name (references loaders in createNextApp) */
|
|
76
|
+
loader?: string;
|
|
77
|
+
/** Static params for generateStaticParams */
|
|
78
|
+
staticParams?: Record<string, string>[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The full application spec for @json-render/next.
|
|
82
|
+
*
|
|
83
|
+
* Describes an entire Next.js application: routes, pages, layouts,
|
|
84
|
+
* metadata, and server-side data loading.
|
|
85
|
+
*
|
|
86
|
+
* Routes are keyed by URL patterns using Next.js conventions:
|
|
87
|
+
* - `"/"` — exact match
|
|
88
|
+
* - `"/blog/[slug]"` — dynamic segment
|
|
89
|
+
* - `"/docs/[...path]"` — catch-all segment
|
|
90
|
+
* - `"/settings/[[...path]]"` — optional catch-all segment
|
|
91
|
+
*/
|
|
92
|
+
interface NextAppSpec {
|
|
93
|
+
/** Root-level metadata applied to all routes (layouts can override) */
|
|
94
|
+
metadata?: NextMetadata;
|
|
95
|
+
/** Route definitions keyed by URL pattern */
|
|
96
|
+
routes: Record<string, NextRouteSpec>;
|
|
97
|
+
/**
|
|
98
|
+
* Reusable layout element trees. Each layout spec must include a
|
|
99
|
+
* `Slot` component type where page content will be injected.
|
|
100
|
+
*/
|
|
101
|
+
layouts?: Record<string, Spec>;
|
|
102
|
+
/** Global initial state shared across all routes */
|
|
103
|
+
state?: Record<string, unknown>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Result of matching a pathname against the spec's routes.
|
|
107
|
+
*/
|
|
108
|
+
interface MatchedRoute {
|
|
109
|
+
/** The matched route spec */
|
|
110
|
+
route: NextRouteSpec;
|
|
111
|
+
/** The URL pattern that matched (e.g. "/blog/[slug]") */
|
|
112
|
+
pattern: string;
|
|
113
|
+
/** Extracted route parameters (e.g. { slug: "hello-world" }) */
|
|
114
|
+
params: Record<string, string | string[]>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Server-side data loader function signature.
|
|
118
|
+
* Receives route params and returns data to merge into initial state.
|
|
119
|
+
*/
|
|
120
|
+
type LoaderFn = (params: Record<string, string | string[]>) => Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
121
|
+
/**
|
|
122
|
+
* Options for createNextApp.
|
|
123
|
+
*/
|
|
124
|
+
interface CreateNextAppOptions {
|
|
125
|
+
/** The application spec */
|
|
126
|
+
spec: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>);
|
|
127
|
+
/** Server-side data loaders keyed by name */
|
|
128
|
+
loaders?: Record<string, LoaderFn>;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Data returned by getPageData for client-side rendering.
|
|
132
|
+
*/
|
|
133
|
+
interface PageData {
|
|
134
|
+
/** Page element tree spec */
|
|
135
|
+
spec: Spec;
|
|
136
|
+
/** Initial state (merged from spec.state, global state, and loader data) */
|
|
137
|
+
initialState?: Record<string, unknown>;
|
|
138
|
+
/** Optional layout element tree spec */
|
|
139
|
+
layoutSpec?: Spec | null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The result of createNextApp — exports for Next.js route files.
|
|
143
|
+
*/
|
|
144
|
+
interface NextAppExports {
|
|
145
|
+
/**
|
|
146
|
+
* Resolve page data for a given set of params.
|
|
147
|
+
* Returns null if no route matches (caller should call notFound()).
|
|
148
|
+
*
|
|
149
|
+
* Use this in your Server Component page.tsx alongside a client wrapper
|
|
150
|
+
* that renders PageRenderer:
|
|
151
|
+
*
|
|
152
|
+
* ```tsx
|
|
153
|
+
* // app/[[...slug]]/page.tsx
|
|
154
|
+
* import { getPageData, generateMetadata, generateStaticParams } from "@/lib/app";
|
|
155
|
+
* import { WebsiteRenderer } from "./renderer";
|
|
156
|
+
*
|
|
157
|
+
* export { generateMetadata, generateStaticParams };
|
|
158
|
+
*
|
|
159
|
+
* export default async function Page({ params }) {
|
|
160
|
+
* const data = await getPageData({ params });
|
|
161
|
+
* if (!data) notFound();
|
|
162
|
+
* return <WebsiteRenderer {...data} />;
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
getPageData: (props: {
|
|
167
|
+
params: Promise<{
|
|
168
|
+
slug?: string[];
|
|
169
|
+
}>;
|
|
170
|
+
}) => Promise<PageData | null>;
|
|
171
|
+
/** generateMetadata function for page.tsx */
|
|
172
|
+
generateMetadata: (props: {
|
|
173
|
+
params: Promise<{
|
|
174
|
+
slug?: string[];
|
|
175
|
+
}>;
|
|
176
|
+
}) => Promise<Record<string, unknown>>;
|
|
177
|
+
/** generateStaticParams function for page.tsx */
|
|
178
|
+
generateStaticParams: () => Promise<{
|
|
179
|
+
slug: string[];
|
|
180
|
+
}[]>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Create a fully wired Next.js application from a json-render spec.
|
|
185
|
+
*
|
|
186
|
+
* Returns `getPageData`, `generateMetadata`, and `generateStaticParams`
|
|
187
|
+
* ready to be used in Next.js `[[...slug]]` catch-all routes.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* // lib/app.ts
|
|
192
|
+
* import { createNextApp } from "@json-render/next/server";
|
|
193
|
+
*
|
|
194
|
+
* export const { getPageData, generateMetadata, generateStaticParams } =
|
|
195
|
+
* createNextApp({ spec });
|
|
196
|
+
*
|
|
197
|
+
* // app/[[...slug]]/page.tsx (Server Component)
|
|
198
|
+
* import { notFound } from "next/navigation";
|
|
199
|
+
* import { getPageData, generateMetadata, generateStaticParams } from "@/lib/app";
|
|
200
|
+
* import { SiteRenderer } from "./renderer";
|
|
201
|
+
*
|
|
202
|
+
* export { generateMetadata, generateStaticParams };
|
|
203
|
+
*
|
|
204
|
+
* export default async function Page({ params }) {
|
|
205
|
+
* const data = await getPageData({ params });
|
|
206
|
+
* if (!data) notFound();
|
|
207
|
+
* return <SiteRenderer {...data} />;
|
|
208
|
+
* }
|
|
209
|
+
*
|
|
210
|
+
* // app/[[...slug]]/renderer.tsx ("use client")
|
|
211
|
+
* import { PageRenderer } from "@json-render/next";
|
|
212
|
+
* export function SiteRenderer(props) {
|
|
213
|
+
* return <PageRenderer {...props} />;
|
|
214
|
+
* }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
declare function createNextApp(options: CreateNextAppOptions): NextAppExports;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The schema for @json-render/next.
|
|
221
|
+
*
|
|
222
|
+
* Defines a multi-page Next.js application structure:
|
|
223
|
+
* - Spec: Routes with pages, layouts, metadata, loading/error states
|
|
224
|
+
* - Catalog: Components with props schemas, and optional actions
|
|
225
|
+
*
|
|
226
|
+
* This schema is fundamentally different from the React element tree schema.
|
|
227
|
+
* It's page-based, designed for full Next.js applications with SSR,
|
|
228
|
+
* routing, and metadata generation.
|
|
229
|
+
*/
|
|
230
|
+
declare const schema: _json_render_core.Schema<{
|
|
231
|
+
spec: _json_render_core.SchemaType<"object", {
|
|
232
|
+
/** Root-level metadata applied as defaults */
|
|
233
|
+
metadata: _json_render_core.SchemaType<"object", {
|
|
234
|
+
title: _json_render_core.SchemaType<"any", unknown>;
|
|
235
|
+
description: _json_render_core.SchemaType<"string", unknown>;
|
|
236
|
+
keywords: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
237
|
+
openGraph: _json_render_core.SchemaType<"any", unknown>;
|
|
238
|
+
twitter: _json_render_core.SchemaType<"any", unknown>;
|
|
239
|
+
robots: _json_render_core.SchemaType<"any", unknown>;
|
|
240
|
+
icons: _json_render_core.SchemaType<"any", unknown>;
|
|
241
|
+
}>;
|
|
242
|
+
/** Route definitions keyed by URL pattern */
|
|
243
|
+
routes: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
244
|
+
/** Page element tree */
|
|
245
|
+
page: _json_render_core.SchemaType<"object", {
|
|
246
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
247
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
248
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
249
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
250
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
251
|
+
visible: _json_render_core.SchemaType<"any", unknown>;
|
|
252
|
+
}>>;
|
|
253
|
+
state: _json_render_core.SchemaType<"any", unknown>;
|
|
254
|
+
}>;
|
|
255
|
+
/** Per-route metadata */
|
|
256
|
+
metadata: _json_render_core.SchemaType<"any", unknown>;
|
|
257
|
+
/** Layout key */
|
|
258
|
+
layout: _json_render_core.SchemaType<"string", unknown>;
|
|
259
|
+
/** Loading state element tree */
|
|
260
|
+
loading: _json_render_core.SchemaType<"any", unknown>;
|
|
261
|
+
/** Error state element tree */
|
|
262
|
+
error: _json_render_core.SchemaType<"any", unknown>;
|
|
263
|
+
/** Not-found element tree */
|
|
264
|
+
notFound: _json_render_core.SchemaType<"any", unknown>;
|
|
265
|
+
/** Server-side data loader name */
|
|
266
|
+
loader: _json_render_core.SchemaType<"string", unknown>;
|
|
267
|
+
/** Static params for SSG */
|
|
268
|
+
staticParams: _json_render_core.SchemaType<"any", unknown>;
|
|
269
|
+
}>>;
|
|
270
|
+
/** Reusable layout element trees */
|
|
271
|
+
layouts: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
272
|
+
root: _json_render_core.SchemaType<"string", unknown>;
|
|
273
|
+
elements: _json_render_core.SchemaType<"record", _json_render_core.SchemaType<"object", {
|
|
274
|
+
type: _json_render_core.SchemaType<"ref", string>;
|
|
275
|
+
props: _json_render_core.SchemaType<"propsOf", string>;
|
|
276
|
+
children: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
277
|
+
visible: _json_render_core.SchemaType<"any", unknown>;
|
|
278
|
+
}>>;
|
|
279
|
+
state: _json_render_core.SchemaType<"any", unknown>;
|
|
280
|
+
}>>;
|
|
281
|
+
/** Global initial state */
|
|
282
|
+
state: _json_render_core.SchemaType<"any", unknown>;
|
|
283
|
+
}>;
|
|
284
|
+
catalog: _json_render_core.SchemaType<"object", {
|
|
285
|
+
/** Component definitions */
|
|
286
|
+
components: _json_render_core.SchemaType<"map", {
|
|
287
|
+
props: _json_render_core.SchemaType<"zod", unknown>;
|
|
288
|
+
slots: _json_render_core.SchemaType<"array", _json_render_core.SchemaType<"string", unknown>>;
|
|
289
|
+
description: _json_render_core.SchemaType<"string", unknown>;
|
|
290
|
+
example: _json_render_core.SchemaType<"any", unknown>;
|
|
291
|
+
}>;
|
|
292
|
+
/** Action definitions (optional) */
|
|
293
|
+
actions: _json_render_core.SchemaType<"map", {
|
|
294
|
+
params: _json_render_core.SchemaType<"zod", unknown>;
|
|
295
|
+
description: _json_render_core.SchemaType<"string", unknown>;
|
|
296
|
+
}>;
|
|
297
|
+
}>;
|
|
298
|
+
}>;
|
|
299
|
+
/**
|
|
300
|
+
* Type for the Next.js schema
|
|
301
|
+
*/
|
|
302
|
+
type NextSchema = typeof schema;
|
|
303
|
+
/**
|
|
304
|
+
* Infer the spec type from a catalog
|
|
305
|
+
*/
|
|
306
|
+
type NextSpec<TCatalog> = typeof schema extends {
|
|
307
|
+
createCatalog: (catalog: TCatalog) => {
|
|
308
|
+
_specType: infer S;
|
|
309
|
+
};
|
|
310
|
+
} ? S : never;
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Match a pathname against a spec's routes.
|
|
314
|
+
*
|
|
315
|
+
* Routes are matched in order of specificity:
|
|
316
|
+
* 1. Exact/static matches first (most specific)
|
|
317
|
+
* 2. Dynamic segment matches
|
|
318
|
+
* 3. Catch-all matches (least specific)
|
|
319
|
+
* 4. Optional catch-all matches (fallback)
|
|
320
|
+
*
|
|
321
|
+
* @returns The matched route with extracted params, or null if no match.
|
|
322
|
+
*/
|
|
323
|
+
declare function matchRoute(spec: NextAppSpec, pathname: string): MatchedRoute | null;
|
|
324
|
+
/**
|
|
325
|
+
* Convert a Next.js catch-all slug array to a pathname.
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* slugToPath(undefined) // "/"
|
|
329
|
+
* slugToPath([]) // "/"
|
|
330
|
+
* slugToPath(["blog"]) // "/blog"
|
|
331
|
+
* slugToPath(["blog","hi"]) // "/blog/hi"
|
|
332
|
+
*/
|
|
333
|
+
declare function slugToPath(slug: string[] | undefined): string;
|
|
334
|
+
/**
|
|
335
|
+
* Collect all static params from the spec for generateStaticParams.
|
|
336
|
+
* Returns params suitable for Next.js [[...slug]] catch-all routes.
|
|
337
|
+
*/
|
|
338
|
+
declare function collectStaticParams(spec: NextAppSpec): {
|
|
339
|
+
slug: string[];
|
|
340
|
+
}[];
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Metadata result compatible with Next.js's Metadata type.
|
|
344
|
+
* Uses plain objects to avoid importing Next.js types at runtime.
|
|
345
|
+
*/
|
|
346
|
+
type ResolvedMetadata = Record<string, unknown>;
|
|
347
|
+
/**
|
|
348
|
+
* Resolve metadata for a route by merging global spec metadata
|
|
349
|
+
* with route-specific metadata.
|
|
350
|
+
*
|
|
351
|
+
* Follows Next.js metadata merging semantics:
|
|
352
|
+
* - Route metadata overrides global metadata for scalar fields
|
|
353
|
+
* - Title templates from global metadata apply to route titles
|
|
354
|
+
* - OpenGraph and Twitter fields are shallow-merged
|
|
355
|
+
*/
|
|
356
|
+
declare function resolveMetadata(spec: NextAppSpec, route?: NextRouteSpec | null): ResolvedMetadata;
|
|
357
|
+
|
|
358
|
+
export { type CreateNextAppOptions, type LoaderFn, type MatchedRoute, type NextAppExports, type NextAppSpec, type NextMetadata, type NextRouteSpec, type NextSchema, type NextSpec, type PageData, type ResolvedMetadata, collectStaticParams, createNextApp, matchRoute, resolveMetadata, schema, slugToPath };
|