@riverbankcms/sdk 0.6.0 → 0.7.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.
Files changed (84) hide show
  1. package/README.md +239 -0
  2. package/dist/cli/index.js +22 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/client.js +1 -1
  5. package/dist/client/client.js.map +1 -1
  6. package/dist/client/client.mjs +1 -1
  7. package/dist/client/client.mjs.map +1 -1
  8. package/dist/server/{Layout-BClXUTsd.d.mts → Layout-B7cvis7r.d.mts} +3 -3
  9. package/dist/server/{Layout-UXGjXv8M.d.ts → Layout-wBtJLTVX.d.ts} +3 -3
  10. package/dist/server/{chunk-Z5ZA6Q4D.mjs → chunk-74XUVNOO.mjs} +5 -3
  11. package/dist/server/chunk-74XUVNOO.mjs.map +1 -0
  12. package/dist/server/{chunk-PHS2KWJX.js → chunk-7BVRA5MY.js} +7 -52
  13. package/dist/server/chunk-7BVRA5MY.js.map +1 -0
  14. package/dist/server/{chunk-SQMGHEJM.mjs → chunk-7FIJSGHU.mjs} +2 -2
  15. package/dist/server/{chunk-SQMGHEJM.mjs.map → chunk-7FIJSGHU.mjs.map} +1 -1
  16. package/dist/server/chunk-ARNCLSQT.mjs +52 -0
  17. package/dist/server/chunk-ARNCLSQT.mjs.map +1 -0
  18. package/dist/server/chunk-BNQV3PXP.js +69 -0
  19. package/dist/server/chunk-BNQV3PXP.js.map +1 -0
  20. package/dist/server/{chunk-SSS7CCRR.js → chunk-EIVISR62.js} +15 -57
  21. package/dist/server/chunk-EIVISR62.js.map +1 -0
  22. package/dist/server/{chunk-I2D7KOEA.js → chunk-JWRNMNWI.js} +5 -3
  23. package/dist/server/chunk-JWRNMNWI.js.map +1 -0
  24. package/dist/server/{chunk-EOWGKCUZ.js → chunk-P7UVAMK6.js} +2 -2
  25. package/dist/server/{chunk-EOWGKCUZ.js.map → chunk-P7UVAMK6.js.map} +1 -1
  26. package/dist/server/{chunk-2HXHFSMI.mjs → chunk-RBJFXNDM.mjs} +6 -51
  27. package/dist/server/chunk-RBJFXNDM.mjs.map +1 -0
  28. package/dist/server/chunk-SWYWZT3L.mjs +69 -0
  29. package/dist/server/chunk-SWYWZT3L.mjs.map +1 -0
  30. package/dist/server/chunk-T26N3P26.js +52 -0
  31. package/dist/server/chunk-T26N3P26.js.map +1 -0
  32. package/dist/server/{chunk-PMHLZ3FW.mjs → chunk-YXA4GAAQ.mjs} +15 -57
  33. package/dist/server/chunk-YXA4GAAQ.mjs.map +1 -0
  34. package/dist/server/{components-DppHY5oD.d.ts → components-CICSJyp_.d.ts} +1 -1
  35. package/dist/server/{components-BmaJxgCV.d.mts → components-CMMwDXTW.d.mts} +1 -1
  36. package/dist/server/components.d.mts +2 -2
  37. package/dist/server/components.d.ts +2 -2
  38. package/dist/server/components.js +5 -3
  39. package/dist/server/components.js.map +1 -1
  40. package/dist/server/components.mjs +5 -3
  41. package/dist/server/index-BTwWvSBu.d.ts +130 -0
  42. package/dist/server/index-DI_qlYx3.d.mts +130 -0
  43. package/dist/server/index.js +2 -2
  44. package/dist/server/index.mjs +1 -1
  45. package/dist/server/{loadContent-BS-3wesN.d.mts → loadContent-C-YYUKQa.d.mts} +10 -2
  46. package/dist/server/{loadContent-Buvmudee.d.ts → loadContent-DmgpFcFC.d.ts} +10 -2
  47. package/dist/server/metadata.d.mts +8 -135
  48. package/dist/server/metadata.d.ts +8 -135
  49. package/dist/server/metadata.js +5 -65
  50. package/dist/server/metadata.js.map +1 -1
  51. package/dist/server/metadata.mjs +4 -64
  52. package/dist/server/metadata.mjs.map +1 -1
  53. package/dist/server/navigation.d.mts +80 -145
  54. package/dist/server/navigation.d.ts +80 -145
  55. package/dist/server/navigation.js +2 -10
  56. package/dist/server/navigation.js.map +1 -1
  57. package/dist/server/navigation.mjs +7 -15
  58. package/dist/server/next.d.mts +274 -0
  59. package/dist/server/next.d.ts +274 -0
  60. package/dist/server/next.js +150 -0
  61. package/dist/server/next.js.map +1 -0
  62. package/dist/server/next.mjs +150 -0
  63. package/dist/server/next.mjs.map +1 -0
  64. package/dist/server/rendering/server.d.mts +1 -1
  65. package/dist/server/rendering/server.d.ts +1 -1
  66. package/dist/server/rendering/server.js +5 -3
  67. package/dist/server/rendering/server.js.map +1 -1
  68. package/dist/server/rendering/server.mjs +5 -3
  69. package/dist/server/rendering.d.mts +4 -4
  70. package/dist/server/rendering.d.ts +4 -4
  71. package/dist/server/rendering.js +6 -4
  72. package/dist/server/rendering.js.map +1 -1
  73. package/dist/server/rendering.mjs +6 -4
  74. package/dist/server/server.d.mts +1 -1
  75. package/dist/server/server.d.ts +1 -1
  76. package/dist/server/server.js +3 -3
  77. package/dist/server/server.mjs +2 -2
  78. package/package.json +13 -1
  79. package/dist/server/chunk-2HXHFSMI.mjs.map +0 -1
  80. package/dist/server/chunk-I2D7KOEA.js.map +0 -1
  81. package/dist/server/chunk-PHS2KWJX.js.map +0 -1
  82. package/dist/server/chunk-PMHLZ3FW.mjs.map +0 -1
  83. package/dist/server/chunk-SSS7CCRR.js.map +0 -1
  84. package/dist/server/chunk-Z5ZA6Q4D.mjs.map +0 -1
@@ -0,0 +1,274 @@
1
+ import { ReactNode, ComponentType } from 'react';
2
+ import { R as RiverbankClient } from './types-1cLz0vnq.mjs';
3
+ import { R as RiverbankSiteConfig } from './types-BjgZt8xJ.mjs';
4
+ import { B as BlockOverrides } from './loadPage-B8mQUUSo.mjs';
5
+ import './schema-Z6-afHJG.mjs';
6
+ import { M as Metadata } from './index-DI_qlYx3.mjs';
7
+ import { b as LoadContentResult } from './loadContent-C-YYUKQa.mjs';
8
+ import './types-Dsu9wsUh.mjs';
9
+ import '@riverbankcms/ai';
10
+ import 'zod';
11
+ import './link-DjxLyC82.mjs';
12
+ import '@riverbankcms/media-storage-supabase';
13
+ import '@riverbankcms/db';
14
+ import './blockKinds-B6MWzNWp.mjs';
15
+ import 'react/jsx-runtime';
16
+ import './core-DsNWrl3o.mjs';
17
+ import './types-CbagRQ_7.mjs';
18
+
19
+ /**
20
+ * Type definitions for Next.js integration helpers.
21
+ *
22
+ * These types define the options and props for the `createCatchAllPage()` factory,
23
+ * which simplifies catch-all routing for Riverbank CMS sites.
24
+ */
25
+
26
+ /**
27
+ * Context passed to escape hatch callbacks.
28
+ */
29
+ interface CatchAllContext {
30
+ /** Loaded content (page or entry) */
31
+ content: LoadContentResult;
32
+ /** Resolved URL path (e.g., '/about', '/blog/my-post') */
33
+ path: string;
34
+ /** Whether preview mode is enabled */
35
+ preview: boolean;
36
+ /** Search parameters from the URL (for filtering, pagination, etc.) */
37
+ searchParams: Record<string, string | string[] | undefined>;
38
+ }
39
+ /**
40
+ * Options for the `createCatchAllPage()` factory.
41
+ *
42
+ * @example Basic usage
43
+ * ```tsx
44
+ * const { Page, generateMetadata } = createCatchAllPage({
45
+ * getClient: getRiverbankClient,
46
+ * config,
47
+ * blockOverrides: { hero: MyCustomHero },
48
+ * });
49
+ * ```
50
+ *
51
+ * @example With maintenance mode
52
+ * ```tsx
53
+ * const { Page, generateMetadata } = createCatchAllPage({
54
+ * getClient,
55
+ * config,
56
+ * beforeRender: async () => {
57
+ * if (process.env.MAINTENANCE_MODE === 'true') {
58
+ * return <MaintenancePage />;
59
+ * }
60
+ * return null; // Continue with normal rendering
61
+ * },
62
+ * });
63
+ * ```
64
+ */
65
+ interface CreateCatchAllPageOptions {
66
+ /**
67
+ * Function that returns the Riverbank client.
68
+ * Called fresh on each request to support different caching strategies.
69
+ */
70
+ getClient: () => RiverbankClient;
71
+ /**
72
+ * Site configuration from `defineConfig()`.
73
+ * Provides siteId and content type routing information.
74
+ */
75
+ config: RiverbankSiteConfig;
76
+ /**
77
+ * Custom block component overrides for rendering.
78
+ * Keys can be full block kind ("block.hero") or short form ("hero").
79
+ */
80
+ blockOverrides?: BlockOverrides;
81
+ /**
82
+ * Override site URL for metadata generation.
83
+ * Defaults to `config.liveUrl` or `config.previewUrl` based on preview mode.
84
+ */
85
+ siteUrl?: string;
86
+ /**
87
+ * Intercept before rendering to implement maintenance mode, access control, etc.
88
+ *
89
+ * Return a React node to short-circuit rendering, or `null` to continue
90
+ * with normal page/entry rendering.
91
+ *
92
+ * @example Maintenance mode
93
+ * ```tsx
94
+ * beforeRender: async () => {
95
+ * if (process.env.MAINTENANCE_MODE === 'true') {
96
+ * return <MaintenancePage />;
97
+ * }
98
+ * return null;
99
+ * }
100
+ * ```
101
+ *
102
+ * @example Access control
103
+ * ```tsx
104
+ * beforeRender: async ({ path }) => {
105
+ * if (path.startsWith('/members')) {
106
+ * const session = await getSession();
107
+ * if (!session) return <LoginPage redirect={path} />;
108
+ * }
109
+ * return null;
110
+ * }
111
+ * ```
112
+ */
113
+ beforeRender?: (context: CatchAllContext) => ReactNode | null | Promise<ReactNode | null>;
114
+ /**
115
+ * Custom metadata generator. If provided, replaces default metadata generation.
116
+ *
117
+ * Use this when you need full control over SEO metadata, such as adding
118
+ * product-specific Open Graph tags for e-commerce sites.
119
+ *
120
+ * @example Custom product metadata
121
+ * ```tsx
122
+ * customMetadata: async ({ content }) => {
123
+ * if (isEntryContent(content) && content.entry.type === 'product') {
124
+ * return {
125
+ * title: `${content.entry.title} | Shop`,
126
+ * openGraph: { type: 'product' },
127
+ * };
128
+ * }
129
+ * // Use default for other content types
130
+ * return generatePageMetadata({ page, site, path, siteUrl });
131
+ * }
132
+ * ```
133
+ */
134
+ customMetadata?: (context: CatchAllContext) => Metadata | Promise<Metadata>;
135
+ /**
136
+ * Wrapper component around rendered content.
137
+ *
138
+ * Useful for adding analytics scripts, error boundaries, or layout wrappers
139
+ * that should wrap all page content.
140
+ *
141
+ * @example Analytics wrapper
142
+ * ```tsx
143
+ * wrapper: ({ children }) => (
144
+ * <>
145
+ * {children}
146
+ * <AnalyticsScript siteId={config.siteId} />
147
+ * </>
148
+ * )
149
+ * ```
150
+ */
151
+ wrapper?: ComponentType<{
152
+ children: ReactNode;
153
+ }>;
154
+ }
155
+ /**
156
+ * Next.js page props for catch-all routes.
157
+ *
158
+ * This matches the signature expected by Next.js 15+ App Router pages
159
+ * with the `[[...slug]]` pattern.
160
+ */
161
+ interface CatchAllPageProps {
162
+ /** Route parameters containing the slug segments */
163
+ params: Promise<{
164
+ slug?: string[];
165
+ }>;
166
+ /** Optional search parameters from the URL */
167
+ searchParams?: Promise<Record<string, string | string[] | undefined>>;
168
+ }
169
+ /**
170
+ * Result of the `createCatchAllPage()` factory.
171
+ */
172
+ interface CreateCatchAllPageResult {
173
+ /**
174
+ * React component to use as the default export of your catch-all page.
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * const { Page, generateMetadata } = createCatchAllPage({ ... });
179
+ * export default Page;
180
+ * ```
181
+ */
182
+ Page: (props: CatchAllPageProps) => Promise<ReactNode>;
183
+ /**
184
+ * Metadata generation function for Next.js `generateMetadata`.
185
+ *
186
+ * @example
187
+ * ```tsx
188
+ * const { Page, generateMetadata } = createCatchAllPage({ ... });
189
+ * export { generateMetadata };
190
+ * ```
191
+ */
192
+ generateMetadata: (props: CatchAllPageProps) => Promise<Metadata>;
193
+ }
194
+
195
+ /**
196
+ * Next.js catch-all page factory for Riverbank CMS.
197
+ *
198
+ * Provides a simple, opinionated way to render CMS content in Next.js catch-all routes.
199
+ * Reduces typical page.tsx boilerplate from ~160 lines to ~10 lines.
200
+ *
201
+ * @example
202
+ * ```tsx
203
+ * // src/app/[[...slug]]/page.tsx
204
+ * import { createCatchAllPage } from '@riverbankcms/sdk/next';
205
+ * import { getRiverbankClient } from '@/lib/builder-client';
206
+ * import config from '@/riverbank.config';
207
+ *
208
+ * const { Page, generateMetadata } = createCatchAllPage({
209
+ * getClient: getRiverbankClient,
210
+ * config,
211
+ * blockOverrides: { hero: MyCustomHero },
212
+ * });
213
+ *
214
+ * export default Page;
215
+ * export { generateMetadata };
216
+ * ```
217
+ */
218
+
219
+ /**
220
+ * Factory function to create a Next.js catch-all page component and metadata generator.
221
+ *
222
+ * This provides a simple, opinionated setup for rendering Riverbank CMS content
223
+ * in external SDK sites. It handles:
224
+ *
225
+ * - Page and content entry routing
226
+ * - Preview mode detection (via `RIVERBANK_PREVIEW_MODE` env var)
227
+ * - SEO metadata generation
228
+ * - Block overrides for custom components
229
+ * - 404 handling for missing content
230
+ *
231
+ * ## Escape Hatches
232
+ *
233
+ * For customization beyond the defaults, use these options:
234
+ *
235
+ * - `beforeRender`: Intercept before rendering (maintenance mode, access control)
236
+ * - `customMetadata`: Full control over SEO metadata
237
+ * - `wrapper`: Wrap all content (analytics, error boundaries)
238
+ *
239
+ * For maximum control, use the lower-level helpers directly:
240
+ * - `loadContent()` from `@riverbankcms/sdk/rendering`
241
+ * - `Page` component from `@riverbankcms/sdk/rendering`
242
+ * - `generatePageMetadata()` from `@riverbankcms/sdk/metadata`
243
+ *
244
+ * @param options - Configuration options
245
+ * @returns Object with `Page` component and `generateMetadata` function
246
+ *
247
+ * @example Basic usage
248
+ * ```tsx
249
+ * const { Page, generateMetadata } = createCatchAllPage({
250
+ * getClient: getRiverbankClient,
251
+ * config,
252
+ * });
253
+ *
254
+ * export default Page;
255
+ * export { generateMetadata };
256
+ * ```
257
+ *
258
+ * @example With maintenance mode
259
+ * ```tsx
260
+ * const { Page, generateMetadata } = createCatchAllPage({
261
+ * getClient,
262
+ * config,
263
+ * beforeRender: async () => {
264
+ * if (process.env.MAINTENANCE_MODE === 'true') {
265
+ * return <MaintenancePage />;
266
+ * }
267
+ * return null;
268
+ * },
269
+ * });
270
+ * ```
271
+ */
272
+ declare function createCatchAllPage(options: CreateCatchAllPageOptions): CreateCatchAllPageResult;
273
+
274
+ export { type CatchAllContext, type CatchAllPageProps, type CreateCatchAllPageOptions, type CreateCatchAllPageResult, createCatchAllPage };
@@ -0,0 +1,274 @@
1
+ import { ReactNode, ComponentType } from 'react';
2
+ import { R as RiverbankClient } from './types-BvcJU7zk.js';
3
+ import { R as RiverbankSiteConfig } from './types-DLBhEPSt.js';
4
+ import { B as BlockOverrides } from './loadPage-DP3nrHBi.js';
5
+ import './schema-Z6-afHJG.js';
6
+ import { M as Metadata } from './index-BTwWvSBu.js';
7
+ import { b as LoadContentResult } from './loadContent-DmgpFcFC.js';
8
+ import './types-CVykEqXN.js';
9
+ import '@riverbankcms/ai';
10
+ import 'zod';
11
+ import './link-DjxLyC82.js';
12
+ import '@riverbankcms/media-storage-supabase';
13
+ import '@riverbankcms/db';
14
+ import './blockKinds-B6MWzNWp.js';
15
+ import 'react/jsx-runtime';
16
+ import './core-DsNWrl3o.js';
17
+ import './types-DuQCNVV0.js';
18
+
19
+ /**
20
+ * Type definitions for Next.js integration helpers.
21
+ *
22
+ * These types define the options and props for the `createCatchAllPage()` factory,
23
+ * which simplifies catch-all routing for Riverbank CMS sites.
24
+ */
25
+
26
+ /**
27
+ * Context passed to escape hatch callbacks.
28
+ */
29
+ interface CatchAllContext {
30
+ /** Loaded content (page or entry) */
31
+ content: LoadContentResult;
32
+ /** Resolved URL path (e.g., '/about', '/blog/my-post') */
33
+ path: string;
34
+ /** Whether preview mode is enabled */
35
+ preview: boolean;
36
+ /** Search parameters from the URL (for filtering, pagination, etc.) */
37
+ searchParams: Record<string, string | string[] | undefined>;
38
+ }
39
+ /**
40
+ * Options for the `createCatchAllPage()` factory.
41
+ *
42
+ * @example Basic usage
43
+ * ```tsx
44
+ * const { Page, generateMetadata } = createCatchAllPage({
45
+ * getClient: getRiverbankClient,
46
+ * config,
47
+ * blockOverrides: { hero: MyCustomHero },
48
+ * });
49
+ * ```
50
+ *
51
+ * @example With maintenance mode
52
+ * ```tsx
53
+ * const { Page, generateMetadata } = createCatchAllPage({
54
+ * getClient,
55
+ * config,
56
+ * beforeRender: async () => {
57
+ * if (process.env.MAINTENANCE_MODE === 'true') {
58
+ * return <MaintenancePage />;
59
+ * }
60
+ * return null; // Continue with normal rendering
61
+ * },
62
+ * });
63
+ * ```
64
+ */
65
+ interface CreateCatchAllPageOptions {
66
+ /**
67
+ * Function that returns the Riverbank client.
68
+ * Called fresh on each request to support different caching strategies.
69
+ */
70
+ getClient: () => RiverbankClient;
71
+ /**
72
+ * Site configuration from `defineConfig()`.
73
+ * Provides siteId and content type routing information.
74
+ */
75
+ config: RiverbankSiteConfig;
76
+ /**
77
+ * Custom block component overrides for rendering.
78
+ * Keys can be full block kind ("block.hero") or short form ("hero").
79
+ */
80
+ blockOverrides?: BlockOverrides;
81
+ /**
82
+ * Override site URL for metadata generation.
83
+ * Defaults to `config.liveUrl` or `config.previewUrl` based on preview mode.
84
+ */
85
+ siteUrl?: string;
86
+ /**
87
+ * Intercept before rendering to implement maintenance mode, access control, etc.
88
+ *
89
+ * Return a React node to short-circuit rendering, or `null` to continue
90
+ * with normal page/entry rendering.
91
+ *
92
+ * @example Maintenance mode
93
+ * ```tsx
94
+ * beforeRender: async () => {
95
+ * if (process.env.MAINTENANCE_MODE === 'true') {
96
+ * return <MaintenancePage />;
97
+ * }
98
+ * return null;
99
+ * }
100
+ * ```
101
+ *
102
+ * @example Access control
103
+ * ```tsx
104
+ * beforeRender: async ({ path }) => {
105
+ * if (path.startsWith('/members')) {
106
+ * const session = await getSession();
107
+ * if (!session) return <LoginPage redirect={path} />;
108
+ * }
109
+ * return null;
110
+ * }
111
+ * ```
112
+ */
113
+ beforeRender?: (context: CatchAllContext) => ReactNode | null | Promise<ReactNode | null>;
114
+ /**
115
+ * Custom metadata generator. If provided, replaces default metadata generation.
116
+ *
117
+ * Use this when you need full control over SEO metadata, such as adding
118
+ * product-specific Open Graph tags for e-commerce sites.
119
+ *
120
+ * @example Custom product metadata
121
+ * ```tsx
122
+ * customMetadata: async ({ content }) => {
123
+ * if (isEntryContent(content) && content.entry.type === 'product') {
124
+ * return {
125
+ * title: `${content.entry.title} | Shop`,
126
+ * openGraph: { type: 'product' },
127
+ * };
128
+ * }
129
+ * // Use default for other content types
130
+ * return generatePageMetadata({ page, site, path, siteUrl });
131
+ * }
132
+ * ```
133
+ */
134
+ customMetadata?: (context: CatchAllContext) => Metadata | Promise<Metadata>;
135
+ /**
136
+ * Wrapper component around rendered content.
137
+ *
138
+ * Useful for adding analytics scripts, error boundaries, or layout wrappers
139
+ * that should wrap all page content.
140
+ *
141
+ * @example Analytics wrapper
142
+ * ```tsx
143
+ * wrapper: ({ children }) => (
144
+ * <>
145
+ * {children}
146
+ * <AnalyticsScript siteId={config.siteId} />
147
+ * </>
148
+ * )
149
+ * ```
150
+ */
151
+ wrapper?: ComponentType<{
152
+ children: ReactNode;
153
+ }>;
154
+ }
155
+ /**
156
+ * Next.js page props for catch-all routes.
157
+ *
158
+ * This matches the signature expected by Next.js 15+ App Router pages
159
+ * with the `[[...slug]]` pattern.
160
+ */
161
+ interface CatchAllPageProps {
162
+ /** Route parameters containing the slug segments */
163
+ params: Promise<{
164
+ slug?: string[];
165
+ }>;
166
+ /** Optional search parameters from the URL */
167
+ searchParams?: Promise<Record<string, string | string[] | undefined>>;
168
+ }
169
+ /**
170
+ * Result of the `createCatchAllPage()` factory.
171
+ */
172
+ interface CreateCatchAllPageResult {
173
+ /**
174
+ * React component to use as the default export of your catch-all page.
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * const { Page, generateMetadata } = createCatchAllPage({ ... });
179
+ * export default Page;
180
+ * ```
181
+ */
182
+ Page: (props: CatchAllPageProps) => Promise<ReactNode>;
183
+ /**
184
+ * Metadata generation function for Next.js `generateMetadata`.
185
+ *
186
+ * @example
187
+ * ```tsx
188
+ * const { Page, generateMetadata } = createCatchAllPage({ ... });
189
+ * export { generateMetadata };
190
+ * ```
191
+ */
192
+ generateMetadata: (props: CatchAllPageProps) => Promise<Metadata>;
193
+ }
194
+
195
+ /**
196
+ * Next.js catch-all page factory for Riverbank CMS.
197
+ *
198
+ * Provides a simple, opinionated way to render CMS content in Next.js catch-all routes.
199
+ * Reduces typical page.tsx boilerplate from ~160 lines to ~10 lines.
200
+ *
201
+ * @example
202
+ * ```tsx
203
+ * // src/app/[[...slug]]/page.tsx
204
+ * import { createCatchAllPage } from '@riverbankcms/sdk/next';
205
+ * import { getRiverbankClient } from '@/lib/builder-client';
206
+ * import config from '@/riverbank.config';
207
+ *
208
+ * const { Page, generateMetadata } = createCatchAllPage({
209
+ * getClient: getRiverbankClient,
210
+ * config,
211
+ * blockOverrides: { hero: MyCustomHero },
212
+ * });
213
+ *
214
+ * export default Page;
215
+ * export { generateMetadata };
216
+ * ```
217
+ */
218
+
219
+ /**
220
+ * Factory function to create a Next.js catch-all page component and metadata generator.
221
+ *
222
+ * This provides a simple, opinionated setup for rendering Riverbank CMS content
223
+ * in external SDK sites. It handles:
224
+ *
225
+ * - Page and content entry routing
226
+ * - Preview mode detection (via `RIVERBANK_PREVIEW_MODE` env var)
227
+ * - SEO metadata generation
228
+ * - Block overrides for custom components
229
+ * - 404 handling for missing content
230
+ *
231
+ * ## Escape Hatches
232
+ *
233
+ * For customization beyond the defaults, use these options:
234
+ *
235
+ * - `beforeRender`: Intercept before rendering (maintenance mode, access control)
236
+ * - `customMetadata`: Full control over SEO metadata
237
+ * - `wrapper`: Wrap all content (analytics, error boundaries)
238
+ *
239
+ * For maximum control, use the lower-level helpers directly:
240
+ * - `loadContent()` from `@riverbankcms/sdk/rendering`
241
+ * - `Page` component from `@riverbankcms/sdk/rendering`
242
+ * - `generatePageMetadata()` from `@riverbankcms/sdk/metadata`
243
+ *
244
+ * @param options - Configuration options
245
+ * @returns Object with `Page` component and `generateMetadata` function
246
+ *
247
+ * @example Basic usage
248
+ * ```tsx
249
+ * const { Page, generateMetadata } = createCatchAllPage({
250
+ * getClient: getRiverbankClient,
251
+ * config,
252
+ * });
253
+ *
254
+ * export default Page;
255
+ * export { generateMetadata };
256
+ * ```
257
+ *
258
+ * @example With maintenance mode
259
+ * ```tsx
260
+ * const { Page, generateMetadata } = createCatchAllPage({
261
+ * getClient,
262
+ * config,
263
+ * beforeRender: async () => {
264
+ * if (process.env.MAINTENANCE_MODE === 'true') {
265
+ * return <MaintenancePage />;
266
+ * }
267
+ * return null;
268
+ * },
269
+ * });
270
+ * ```
271
+ */
272
+ declare function createCatchAllPage(options: CreateCatchAllPageOptions): CreateCatchAllPageResult;
273
+
274
+ export { type CatchAllContext, type CatchAllPageProps, type CreateCatchAllPageOptions, type CreateCatchAllPageResult, createCatchAllPage };
@@ -0,0 +1,150 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+
4
+ var _chunkBNQV3PXPjs = require('./chunk-BNQV3PXP.js');
5
+
6
+
7
+
8
+
9
+ var _chunkJWRNMNWIjs = require('./chunk-JWRNMNWI.js');
10
+
11
+
12
+ var _chunkT26N3P26js = require('./chunk-T26N3P26.js');
13
+ require('./chunk-7UPVCT3K.js');
14
+ require('./chunk-RVDS7VSP.js');
15
+ require('./chunk-YYO3RIFO.js');
16
+
17
+
18
+ var _chunkDGUM43GVjs = require('./chunk-DGUM43GV.js');
19
+
20
+ // src/next/catch-all.tsx
21
+ var _jsxruntime = require('react/jsx-runtime');
22
+ var { notFound } = _chunkDGUM43GVjs.__require.call(void 0, "next/navigation");
23
+ function isPreviewMode() {
24
+ return process.env.RIVERBANK_PREVIEW_MODE === "true";
25
+ }
26
+ function slugToPath(slug) {
27
+ if (!slug || slug.length === 0) return "/";
28
+ return "/" + slug.join("/");
29
+ }
30
+ function createCatchAllPage(options) {
31
+ const {
32
+ getClient,
33
+ config,
34
+ blockOverrides,
35
+ siteUrl,
36
+ beforeRender,
37
+ customMetadata,
38
+ wrapper: Wrapper
39
+ } = options;
40
+ async function Page2({ params, searchParams: searchParamsPromise }) {
41
+ const [{ slug }, searchParams] = await Promise.all([
42
+ params,
43
+ _nullishCoalesce(searchParamsPromise, () => ( Promise.resolve({})))
44
+ ]);
45
+ const path = slugToPath(slug);
46
+ const preview = isPreviewMode();
47
+ const client = getClient();
48
+ let content;
49
+ try {
50
+ content = await _chunkJWRNMNWIjs.loadContent.call(void 0, {
51
+ client,
52
+ siteId: config.siteId,
53
+ path,
54
+ preview
55
+ });
56
+ } catch (error) {
57
+ console.debug("[createCatchAllPage] Failed to load content for path:", path, error);
58
+ return notFound();
59
+ }
60
+ if (beforeRender) {
61
+ const intercepted = await beforeRender({ content, path, preview, searchParams });
62
+ if (intercepted !== null) {
63
+ return Wrapper ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Wrapper, { children: intercepted }) : intercepted;
64
+ }
65
+ }
66
+ let rendered;
67
+ if (_chunkJWRNMNWIjs.isPageContent.call(void 0, content)) {
68
+ rendered = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
69
+ _chunkT26N3P26js.Page,
70
+ {
71
+ page: content.page,
72
+ theme: content.theme,
73
+ siteId: content.siteId,
74
+ resolvedData: content.resolvedData,
75
+ blockOverrides
76
+ }
77
+ );
78
+ } else if (_chunkJWRNMNWIjs.isEntryContent.call(void 0, content)) {
79
+ if (!content.templatePage) {
80
+ return notFound();
81
+ }
82
+ rendered = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
83
+ _chunkT26N3P26js.Page,
84
+ {
85
+ page: content.templatePage,
86
+ theme: content.theme,
87
+ siteId: content.siteId,
88
+ resolvedData: content.resolvedData,
89
+ blockOverrides,
90
+ dataContext: {
91
+ contentEntry: content.dataContext.contentEntry
92
+ }
93
+ }
94
+ );
95
+ } else {
96
+ return notFound();
97
+ }
98
+ return Wrapper ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Wrapper, { children: rendered }) : rendered;
99
+ }
100
+ async function generateMetadataFn({ params, searchParams: searchParamsPromise }) {
101
+ const [{ slug }, searchParams] = await Promise.all([
102
+ params,
103
+ _nullishCoalesce(searchParamsPromise, () => ( Promise.resolve({})))
104
+ ]);
105
+ const path = slugToPath(slug);
106
+ const preview = isPreviewMode();
107
+ try {
108
+ const content = await _chunkJWRNMNWIjs.loadContent.call(void 0, {
109
+ client: getClient(),
110
+ siteId: config.siteId,
111
+ path,
112
+ preview
113
+ });
114
+ if (customMetadata) {
115
+ return customMetadata({ content, path, preview, searchParams });
116
+ }
117
+ const resolvedUrl = _nullishCoalesce(_nullishCoalesce(siteUrl, () => ( (preview ? config.previewUrl : config.liveUrl))), () => ( ""));
118
+ if (!resolvedUrl) {
119
+ console.warn(
120
+ "[createCatchAllPage] No siteUrl configured. OpenGraph and Twitter tags will have relative URLs which may cause social sharing previews to fail. Set siteUrl option, or config.liveUrl/config.previewUrl in your riverbank.config."
121
+ );
122
+ }
123
+ const page = _chunkJWRNMNWIjs.isPageContent.call(void 0, content) ? content.page : _chunkJWRNMNWIjs.isEntryContent.call(void 0, content) ? {
124
+ name: _nullishCoalesce(content.entry.metaTitle, () => ( content.entry.title)),
125
+ purpose: _nullishCoalesce(content.entry.metaDescription, () => ( void 0))
126
+ } : { name: "Page" };
127
+ const metadataGenerator = preview ? _chunkBNQV3PXPjs.generatePreviewMetadata : _chunkBNQV3PXPjs.generatePageMetadata;
128
+ return metadataGenerator({
129
+ page,
130
+ site: content.site,
131
+ path,
132
+ siteUrl: resolvedUrl
133
+ });
134
+ } catch (error) {
135
+ console.debug("[createCatchAllPage] Failed to generate metadata for path:", path, error);
136
+ return {
137
+ title: "Page Not Found",
138
+ robots: { index: false, follow: false }
139
+ };
140
+ }
141
+ }
142
+ return {
143
+ Page: Page2,
144
+ generateMetadata: generateMetadataFn
145
+ };
146
+ }
147
+
148
+
149
+ exports.createCatchAllPage = createCatchAllPage;
150
+ //# sourceMappingURL=next.js.map