@riverbankcms/sdk 0.7.0 → 0.7.3

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 (184) hide show
  1. package/README.md +229 -0
  2. package/dist/cli/index.js +42 -95
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/init-docs/content/agents-section.md +50 -0
  5. package/dist/cli/init-docs/content/cli-reference.md +574 -0
  6. package/dist/cli/init-docs/content/content-management.md +384 -0
  7. package/dist/cli/init-docs/content/context-brand.md +125 -0
  8. package/dist/cli/init-docs/content/context-brief.md +77 -0
  9. package/dist/cli/init-docs/content/context-knowledge.md +111 -0
  10. package/dist/cli/init-docs/content/getting-started.md +130 -0
  11. package/dist/cli/init-docs/content/site-workflows-readme.md +96 -0
  12. package/dist/cli/init-docs/content/workflow-add-block.md +228 -0
  13. package/dist/cli/init-docs/content/workflow-create-page.md +193 -0
  14. package/dist/cli/init-docs/content/workflow-publish.md +280 -0
  15. package/dist/client/bookings.d.mts +2 -0
  16. package/dist/client/bookings.d.ts +2 -0
  17. package/dist/client/bookings.js +2956 -104
  18. package/dist/client/bookings.js.map +1 -1
  19. package/dist/client/bookings.mjs +2929 -70
  20. package/dist/client/bookings.mjs.map +1 -1
  21. package/dist/client/client.d.mts +2 -2
  22. package/dist/client/client.d.ts +2 -2
  23. package/dist/client/client.js +602 -68
  24. package/dist/client/client.js.map +1 -1
  25. package/dist/client/client.mjs +602 -68
  26. package/dist/client/client.mjs.map +1 -1
  27. package/dist/client/hooks.d.mts +2 -2
  28. package/dist/client/hooks.d.ts +2 -2
  29. package/dist/client/rendering/client.js +3070 -259
  30. package/dist/client/rendering/client.js.map +1 -1
  31. package/dist/client/rendering/client.mjs +3212 -395
  32. package/dist/client/rendering/client.mjs.map +1 -1
  33. package/dist/client/spam-protection.d.mts +55 -0
  34. package/dist/client/spam-protection.d.ts +55 -0
  35. package/dist/client/spam-protection.js +2915 -0
  36. package/dist/client/spam-protection.js.map +1 -0
  37. package/dist/client/spam-protection.mjs +2893 -0
  38. package/dist/client/spam-protection.mjs.map +1 -0
  39. package/dist/client/{usePage-BiOReg0_.d.ts → usePage-BYmJCCm1.d.ts} +132 -11
  40. package/dist/client/{usePage-BXjk8BhD.d.mts → usePage-DZtrWajy.d.mts} +132 -11
  41. package/dist/server/{Layout-wBtJLTVX.d.ts → Layout-Yluyb6sK.d.ts} +1 -1
  42. package/dist/server/{Layout-B7cvis7r.d.mts → Layout-qWLdVm5-.d.mts} +1 -1
  43. package/dist/server/chunk-2IZ6S225.js +122 -0
  44. package/dist/server/chunk-2IZ6S225.js.map +1 -0
  45. package/dist/server/chunk-4CV4JOE5.js +27 -0
  46. package/dist/server/chunk-4CV4JOE5.js.map +1 -0
  47. package/dist/server/chunk-5LRR64Y6.mjs +72 -0
  48. package/dist/server/chunk-5LRR64Y6.mjs.map +1 -0
  49. package/dist/server/chunk-NBTRDLCM.js +72 -0
  50. package/dist/server/chunk-NBTRDLCM.js.map +1 -0
  51. package/dist/server/chunk-NFEGQTCC.mjs +27 -0
  52. package/dist/server/{chunk-7FIJSGHU.mjs → chunk-NFQLH5IA.mjs} +856 -74
  53. package/dist/server/chunk-NFQLH5IA.mjs.map +1 -0
  54. package/dist/server/chunk-PPHZV6YD.mjs +122 -0
  55. package/dist/server/chunk-PPHZV6YD.mjs.map +1 -0
  56. package/dist/server/{chunk-P7UVAMK6.js → chunk-VLXTNB2C.js} +866 -84
  57. package/dist/server/chunk-VLXTNB2C.js.map +1 -0
  58. package/dist/server/{components-CMMwDXTW.d.mts → components-DNHfSCML.d.mts} +3 -3
  59. package/dist/server/{components-CICSJyp_.d.ts → components-Di5ME6He.d.ts} +3 -3
  60. package/dist/server/components.d.mts +5 -5
  61. package/dist/server/components.d.ts +5 -5
  62. package/dist/server/components.js +1 -1
  63. package/dist/server/components.mjs +1 -1
  64. package/dist/server/config-validation.js +1 -1
  65. package/dist/server/config-validation.mjs +1 -1
  66. package/dist/server/config.js +1 -1
  67. package/dist/server/config.mjs +1 -1
  68. package/dist/server/data.d.mts +2 -2
  69. package/dist/server/data.d.ts +2 -2
  70. package/dist/server/data.js +1 -1
  71. package/dist/server/data.mjs +1 -1
  72. package/dist/server/env.d.mts +109 -0
  73. package/dist/server/env.d.ts +109 -0
  74. package/dist/server/env.js +14 -0
  75. package/dist/server/env.js.map +1 -0
  76. package/dist/server/env.mjs +14 -0
  77. package/dist/server/{index-DI_qlYx3.d.mts → index--Oyunk_B.d.mts} +2 -2
  78. package/dist/server/{index-BTwWvSBu.d.ts → index-C9Ra8dza.d.ts} +2 -2
  79. package/dist/server/{index-Bucs6UqG.d.mts → index-Clm3skz_.d.mts} +1 -1
  80. package/dist/server/{index-Cp7tJuRt.d.ts → index-DLvNddi-.d.ts} +1 -1
  81. package/dist/server/index.d.mts +216 -5
  82. package/dist/server/index.d.ts +216 -5
  83. package/dist/server/index.js +301 -4
  84. package/dist/server/index.js.map +1 -1
  85. package/dist/server/index.mjs +301 -4
  86. package/dist/server/index.mjs.map +1 -1
  87. package/dist/server/{loadContent-DmgpFcFC.d.ts → loadContent-D7LQwI0o.d.ts} +3 -3
  88. package/dist/server/{loadContent-C-YYUKQa.d.mts → loadContent-DVfuBLiZ.d.mts} +3 -3
  89. package/dist/server/{loadPage-IDGVDFBB.js → loadPage-AXNAERDS.js} +2 -2
  90. package/dist/server/{loadPage-IDGVDFBB.js.map → loadPage-AXNAERDS.js.map} +1 -1
  91. package/dist/server/{loadPage-DP3nrHBi.d.ts → loadPage-BmYJCe_V.d.ts} +2 -2
  92. package/dist/server/{loadPage-B8mQUUSo.d.mts → loadPage-BucnLHmE.d.mts} +2 -2
  93. package/dist/server/{loadPage-DNQTTRHL.mjs → loadPage-XR7ORQ2E.mjs} +2 -2
  94. package/dist/server/loadPage-XR7ORQ2E.mjs.map +1 -0
  95. package/dist/server/metadata.d.mts +4 -4
  96. package/dist/server/metadata.d.ts +4 -4
  97. package/dist/server/metadata.js +1 -1
  98. package/dist/server/metadata.mjs +1 -1
  99. package/dist/server/navigation.d.mts +2 -2
  100. package/dist/server/navigation.d.ts +2 -2
  101. package/dist/server/navigation.js +1 -1
  102. package/dist/server/navigation.mjs +1 -1
  103. package/dist/server/next/revalidate.d.mts +66 -0
  104. package/dist/server/next/revalidate.d.ts +66 -0
  105. package/dist/server/next/revalidate.js +60 -0
  106. package/dist/server/next/revalidate.js.map +1 -0
  107. package/dist/server/next/revalidate.mjs +60 -0
  108. package/dist/server/next/revalidate.mjs.map +1 -0
  109. package/dist/server/next/tags.d.mts +81 -0
  110. package/dist/server/next/tags.d.ts +81 -0
  111. package/dist/server/next/tags.js +36 -0
  112. package/dist/server/next/tags.js.map +1 -0
  113. package/dist/server/next/tags.mjs +36 -0
  114. package/dist/server/next/tags.mjs.map +1 -0
  115. package/dist/server/next.d.mts +164 -6
  116. package/dist/server/next.d.ts +164 -6
  117. package/dist/server/next.js +79 -11
  118. package/dist/server/next.js.map +1 -1
  119. package/dist/server/next.mjs +76 -8
  120. package/dist/server/next.mjs.map +1 -1
  121. package/dist/server/rendering/server.d.mts +4 -4
  122. package/dist/server/rendering/server.d.ts +4 -4
  123. package/dist/server/rendering/server.js +1 -1
  124. package/dist/server/rendering/server.mjs +1 -1
  125. package/dist/server/rendering.d.mts +7 -7
  126. package/dist/server/rendering.d.ts +7 -7
  127. package/dist/server/rendering.js +3 -3
  128. package/dist/server/rendering.js.map +1 -1
  129. package/dist/server/rendering.mjs +4 -4
  130. package/dist/server/routing.d.mts +3 -3
  131. package/dist/server/routing.d.ts +3 -3
  132. package/dist/server/routing.js +2 -2
  133. package/dist/server/routing.mjs +2 -2
  134. package/dist/server/server.d.mts +5 -5
  135. package/dist/server/server.d.ts +5 -5
  136. package/dist/server/server.js +5 -5
  137. package/dist/server/server.js.map +1 -1
  138. package/dist/server/server.mjs +5 -5
  139. package/dist/server/theme-bridge.js +1 -1
  140. package/dist/server/theme-bridge.mjs +1 -1
  141. package/dist/server/theme.js +1 -1
  142. package/dist/server/theme.mjs +1 -1
  143. package/dist/server/{types-BvcJU7zk.d.ts → types-BRQyLrQU.d.ts} +132 -11
  144. package/dist/server/{types-Dsu9wsUh.d.mts → types-BSV6Vc-P.d.mts} +2 -2
  145. package/dist/server/{types-1cLz0vnq.d.mts → types-C-LShyIg.d.mts} +132 -11
  146. package/dist/server/{types-CVykEqXN.d.ts → types-Dt98DeYa.d.ts} +2 -2
  147. package/dist/server/webhooks.d.mts +81 -0
  148. package/dist/server/webhooks.d.ts +81 -0
  149. package/dist/server/webhooks.js +12 -0
  150. package/dist/server/webhooks.js.map +1 -0
  151. package/dist/server/webhooks.mjs +12 -0
  152. package/dist/server/webhooks.mjs.map +1 -0
  153. package/package.json +29 -3
  154. package/dist/client/resolver-BhueZVxZ.d.mts +0 -61
  155. package/dist/client/resolver-BhueZVxZ.d.ts +0 -61
  156. package/dist/client/usePage--fGlyrgj.d.mts +0 -6439
  157. package/dist/client/usePage-BBcFCxOU.d.ts +0 -6297
  158. package/dist/client/usePage-BC8Q2E3t.d.mts +0 -6431
  159. package/dist/client/usePage-BTPnCuWC.d.mts +0 -6511
  160. package/dist/client/usePage-BafOS9UT.d.mts +0 -6512
  161. package/dist/client/usePage-BcjWPXvh.d.mts +0 -6388
  162. package/dist/client/usePage-Bnx-kA6x.d.mts +0 -6670
  163. package/dist/client/usePage-BvKAa3Zw.d.mts +0 -366
  164. package/dist/client/usePage-BvKAa3Zw.d.ts +0 -366
  165. package/dist/client/usePage-BydHcMYB.d.mts +0 -6297
  166. package/dist/client/usePage-C3ZKNwY7.d.mts +0 -6393
  167. package/dist/client/usePage-CE7X5NcN.d.ts +0 -6439
  168. package/dist/client/usePage-CHEybPMD.d.ts +0 -6429
  169. package/dist/client/usePage-CrKw1H6Y.d.ts +0 -6338
  170. package/dist/client/usePage-CyYpOJud.d.ts +0 -6388
  171. package/dist/client/usePage-D4fxZbRR.d.mts +0 -6429
  172. package/dist/client/usePage-DMI8ImsU.d.mts +0 -6338
  173. package/dist/client/usePage-DoPI6b8V.d.ts +0 -6511
  174. package/dist/client/usePage-DpRNZUtP.d.ts +0 -6431
  175. package/dist/client/usePage-QNWArrVO.d.ts +0 -6670
  176. package/dist/client/usePage-fBgPB6Oq.d.ts +0 -6512
  177. package/dist/client/usePage-gpVaeWDy.d.ts +0 -6393
  178. package/dist/server/chunk-7FIJSGHU.mjs.map +0 -1
  179. package/dist/server/chunk-BJTO5JO5.mjs +0 -11
  180. package/dist/server/chunk-DGUM43GV.js +0 -11
  181. package/dist/server/chunk-DGUM43GV.js.map +0 -1
  182. package/dist/server/chunk-P7UVAMK6.js.map +0 -1
  183. /package/dist/server/{chunk-BJTO5JO5.mjs.map → chunk-NFEGQTCC.mjs.map} +0 -0
  184. /package/dist/server/{loadPage-DNQTTRHL.mjs.map → env.mjs.map} +0 -0
@@ -3,10 +3,303 @@ import {
3
3
  } from "./chunk-D2QLTPUJ.mjs";
4
4
  import {
5
5
  API_ENDPOINTS,
6
+ DEFAULT_PREBUILD_DIR,
7
+ PREBUILD_PAGE_SIZE,
8
+ PrebuildLoader,
9
+ SDK_VERSION,
6
10
  buildEndpointURL,
7
- createRiverbankClient
8
- } from "./chunk-7FIJSGHU.mjs";
9
- import "./chunk-BJTO5JO5.mjs";
11
+ canUsePrebuild,
12
+ createPrebuildLoader,
13
+ createRiverbankClient,
14
+ init_constants,
15
+ init_loader
16
+ } from "./chunk-NFQLH5IA.mjs";
17
+ import "./chunk-NFEGQTCC.mjs";
18
+
19
+ // src/prebuild/index.ts
20
+ import * as fs from "fs";
21
+ import * as path from "path";
22
+ import * as crypto from "crypto";
23
+ init_constants();
24
+ var MANIFEST_VERSION = "1.0.0";
25
+ var MANIFEST_FILENAME = "manifest.json";
26
+ function pathToFilename(routePath) {
27
+ if (routePath === "/") return "_home.json";
28
+ return routePath.slice(1).replace(/[^a-zA-Z0-9\-\/]/g, "_").replace(/\//g, "-") + ".json";
29
+ }
30
+ function ensureDir(dirPath) {
31
+ if (!fs.existsSync(dirPath)) {
32
+ fs.mkdirSync(dirPath, { recursive: true });
33
+ }
34
+ }
35
+ function writeJsonFile(filePath, data) {
36
+ const content = JSON.stringify(data, null, 2);
37
+ fs.writeFileSync(filePath, content, "utf-8");
38
+ return Buffer.byteLength(content, "utf-8");
39
+ }
40
+ function calculateChecksum(data) {
41
+ const { checksum: _, ...rest } = data;
42
+ const content = JSON.stringify(rest);
43
+ return crypto.createHash("sha256").update(content).digest("hex");
44
+ }
45
+ async function fetchAllEntries(client, siteId, contentType, onProgress) {
46
+ const allEntries = [];
47
+ let offset = 0;
48
+ let hasMore = true;
49
+ while (hasMore) {
50
+ onProgress?.(`${contentType} (batch ${Math.floor(offset / PREBUILD_PAGE_SIZE) + 1})`);
51
+ const response = await client.getEntries({
52
+ siteId,
53
+ contentType,
54
+ limit: PREBUILD_PAGE_SIZE,
55
+ offset,
56
+ preview: false
57
+ // Published content only
58
+ });
59
+ allEntries.push(...response.entries);
60
+ offset += PREBUILD_PAGE_SIZE;
61
+ hasMore = response.entries.length === PREBUILD_PAGE_SIZE;
62
+ }
63
+ return allEntries;
64
+ }
65
+ async function prebuildSite(client, siteId, outputDir) {
66
+ const site = await client.getSite({ id: siteId });
67
+ const filename = "site.json";
68
+ const filePath = path.join(outputDir, filename);
69
+ const cacheFile = {
70
+ data: site,
71
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
72
+ };
73
+ const size = writeJsonFile(filePath, cacheFile);
74
+ return { files: [filename], size, siteData: site };
75
+ }
76
+ async function prebuildPages(client, siteId, routes, outputDir, onProgress) {
77
+ const pagesDir = path.join(outputDir, "pages");
78
+ ensureDir(pagesDir);
79
+ const files = [];
80
+ let totalSize = 0;
81
+ const publishedPaths = Object.entries(routes).filter(([_, route]) => route.status === "published").map(([_, route]) => route.path);
82
+ const pageIndex = [];
83
+ const total = publishedPaths.length;
84
+ let current = 0;
85
+ for (const pagePath of publishedPaths) {
86
+ current++;
87
+ onProgress?.({
88
+ current,
89
+ total,
90
+ item: `Page: ${pagePath}`,
91
+ contentType: "pages"
92
+ });
93
+ try {
94
+ const pageData = await client.getPage({ siteId, path: pagePath, preview: false });
95
+ const filename = pathToFilename(pagePath);
96
+ const filePath = path.join(pagesDir, filename);
97
+ const cacheFile = {
98
+ data: pageData,
99
+ path: pagePath,
100
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
101
+ };
102
+ totalSize += writeJsonFile(filePath, cacheFile);
103
+ files.push(`pages/${filename}`);
104
+ if ("page" in pageData) {
105
+ pageIndex.push({
106
+ path: pagePath,
107
+ pageId: pageData.page.routeId || "",
108
+ title: pageData.page.name || "Untitled"
109
+ });
110
+ }
111
+ } catch (error) {
112
+ console.warn(`[Prebuild] Failed to fetch page ${pagePath}:`, error.message);
113
+ }
114
+ }
115
+ const indexFile = {
116
+ pages: pageIndex,
117
+ totalCount: pageIndex.length,
118
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
119
+ };
120
+ const indexPath = path.join(pagesDir, "_index.json");
121
+ totalSize += writeJsonFile(indexPath, indexFile);
122
+ files.push("pages/_index.json");
123
+ return { files, size: totalSize };
124
+ }
125
+ async function prebuildEntries(client, siteId, contentTypes, outputDir, onProgress) {
126
+ const entriesDir = path.join(outputDir, "entries");
127
+ ensureDir(entriesDir);
128
+ const files = [];
129
+ let totalSize = 0;
130
+ const total = contentTypes.length;
131
+ let current = 0;
132
+ for (const contentType of contentTypes) {
133
+ current++;
134
+ const entries = await fetchAllEntries(
135
+ client,
136
+ siteId,
137
+ contentType,
138
+ (item) => {
139
+ onProgress?.({
140
+ current,
141
+ total,
142
+ item: `Entries: ${item}`,
143
+ contentType: "entries"
144
+ });
145
+ }
146
+ );
147
+ const typeDir = path.join(entriesDir, contentType);
148
+ ensureDir(typeDir);
149
+ const cacheFile = {
150
+ entries,
151
+ contentType,
152
+ totalCount: entries.length,
153
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
154
+ };
155
+ const filename = `entries/${contentType}/all.json`;
156
+ const filePath = path.join(entriesDir, contentType, "all.json");
157
+ totalSize += writeJsonFile(filePath, cacheFile);
158
+ files.push(filename);
159
+ }
160
+ return { files, size: totalSize };
161
+ }
162
+ async function prebuildNavigation(siteData, outputDir, onProgress) {
163
+ const navDir = path.join(outputDir, "navigation");
164
+ ensureDir(navDir);
165
+ const files = [];
166
+ let totalSize = 0;
167
+ const menus = siteData.navigation || [];
168
+ onProgress?.({
169
+ current: 1,
170
+ total: 1,
171
+ item: "Navigation menus",
172
+ contentType: "navigation"
173
+ });
174
+ const cacheFile = {
175
+ menus: menus.map((menu) => ({
176
+ identifier: menu.identifier,
177
+ id: menu.id,
178
+ name: menu.name,
179
+ items: menu.items
180
+ })),
181
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
182
+ };
183
+ const filename = "navigation/menus.json";
184
+ const filePath = path.join(navDir, "menus.json");
185
+ totalSize += writeJsonFile(filePath, cacheFile);
186
+ files.push(filename);
187
+ return { files, size: totalSize };
188
+ }
189
+ async function prebuildCache(options) {
190
+ const {
191
+ client,
192
+ siteId,
193
+ outputDir = DEFAULT_PREBUILD_DIR,
194
+ include = ["site", "pages", "entries", "navigation"],
195
+ contentTypes,
196
+ onProgress
197
+ } = options;
198
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
199
+ const files = [];
200
+ let totalSize = 0;
201
+ const errors = [];
202
+ let siteData = null;
203
+ ensureDir(outputDir);
204
+ if (include.includes("site") || include.includes("pages") || include.includes("navigation")) {
205
+ try {
206
+ const result = await prebuildSite(client, siteId, outputDir);
207
+ siteData = result.siteData;
208
+ if (include.includes("site")) {
209
+ files.push(...result.files);
210
+ totalSize += result.size;
211
+ }
212
+ onProgress?.({ current: 1, total: 4, item: "Site data", contentType: "site" });
213
+ } catch (error) {
214
+ errors.push(`Site prebuild failed: ${error.message}`);
215
+ }
216
+ }
217
+ if (include.includes("pages") && siteData) {
218
+ try {
219
+ const result = await prebuildPages(
220
+ client,
221
+ siteId,
222
+ siteData.routes,
223
+ outputDir,
224
+ onProgress
225
+ );
226
+ files.push(...result.files);
227
+ totalSize += result.size;
228
+ } catch (error) {
229
+ errors.push(`Pages prebuild failed: ${error.message}`);
230
+ }
231
+ }
232
+ if (include.includes("entries")) {
233
+ try {
234
+ const typesToPrebuild = contentTypes || [];
235
+ if (typesToPrebuild.length > 0) {
236
+ const result = await prebuildEntries(
237
+ client,
238
+ siteId,
239
+ typesToPrebuild,
240
+ outputDir,
241
+ onProgress
242
+ );
243
+ files.push(...result.files);
244
+ totalSize += result.size;
245
+ } else {
246
+ console.warn("[Prebuild] No contentTypes provided - skipping entries prebuild");
247
+ }
248
+ } catch (error) {
249
+ errors.push(`Entries prebuild failed: ${error.message}`);
250
+ }
251
+ }
252
+ if (include.includes("navigation") && siteData) {
253
+ try {
254
+ const result = await prebuildNavigation(siteData, outputDir, onProgress);
255
+ files.push(...result.files);
256
+ totalSize += result.size;
257
+ } catch (error) {
258
+ errors.push(`Navigation prebuild failed: ${error.message}`);
259
+ }
260
+ }
261
+ const keyToFile = {};
262
+ if (files.includes("site.json")) {
263
+ keyToFile[`site:${siteId}`] = "site.json";
264
+ }
265
+ for (const file of files) {
266
+ if (file.startsWith("pages/") && file !== "pages/_index.json") {
267
+ const filename = file.replace("pages/", "").replace(".json", "");
268
+ const pagePath = filename === "_home" ? "/" : "/" + filename.replace(/-/g, "/");
269
+ keyToFile[`page:${siteId}:${pagePath}:false`] = file;
270
+ }
271
+ if (file.startsWith("entries/") && file.endsWith("/all.json")) {
272
+ const contentType = file.split("/")[1];
273
+ keyToFile[`entries-all:${siteId}:${contentType}`] = file;
274
+ }
275
+ }
276
+ const manifest = {
277
+ version: MANIFEST_VERSION,
278
+ generatedAt,
279
+ siteId,
280
+ sdkVersion: SDK_VERSION,
281
+ keyToFile,
282
+ includedTypes: include,
283
+ fileCount: files.length,
284
+ totalSize
285
+ };
286
+ const checksum = calculateChecksum(manifest);
287
+ manifest.checksum = checksum;
288
+ const manifestPath = path.join(outputDir, MANIFEST_FILENAME);
289
+ writeJsonFile(manifestPath, manifest);
290
+ return {
291
+ success: errors.length === 0,
292
+ outputDir,
293
+ files,
294
+ totalSize,
295
+ generatedAt,
296
+ checksum,
297
+ errors: errors.length > 0 ? errors : void 0
298
+ };
299
+ }
300
+
301
+ // src/index.ts
302
+ init_loader();
10
303
 
11
304
  // ../api/src/aiPlayground.ts
12
305
  import { z } from "zod";
@@ -98,8 +391,12 @@ var MultiPageUpdateResponse = z.object({
98
391
  });
99
392
  export {
100
393
  API_ENDPOINTS,
394
+ PrebuildLoader,
101
395
  SYSTEM_BLOCK_KINDS,
102
396
  buildEndpointURL,
103
- createRiverbankClient
397
+ canUsePrebuild,
398
+ createPrebuildLoader,
399
+ createRiverbankClient,
400
+ prebuildCache
104
401
  };
105
402
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../api/src/aiPlayground.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * RFC-6902 JSON Patch Operations\n * Standard JSON Patch format for AI Playground content updates\n */\n\nexport const Rfc6902PatchOp = z.discriminatedUnion('op', [\n // Standard RFC-6902 operations\n z.object({\n op: z.literal('add'),\n path: z.string(),\n value: z.unknown(),\n }),\n z.object({\n op: z.literal('remove'),\n path: z.string(),\n }),\n z.object({\n op: z.literal('replace'),\n path: z.string(),\n value: z.unknown(),\n }),\n z.object({\n op: z.literal('move'),\n from: z.string(),\n path: z.string(),\n }),\n z.object({\n op: z.literal('copy'),\n from: z.string(),\n path: z.string(),\n }),\n // Block-level operations (Phase 2)\n z.object({\n op: z.literal('add_block'),\n blockKind: z.string(),\n afterBlockId: z.string().nullable(),\n content: z.record(z.string(), z.unknown()),\n rationale: z.string(),\n }),\n z.object({\n op: z.literal('delete_block'),\n blockId: z.string(),\n rationale: z.string(),\n }),\n z.object({\n op: z.literal('reorder_block'),\n blockId: z.string(),\n afterBlockId: z.string().nullable(),\n rationale: z.string(),\n }),\n]);\n\nexport const PatchEnvelope = z.object({\n blockId: z.string(),\n blockKind: z.string().optional(),\n blockPurpose: z.string().optional().nullable(),\n ops: z.array(Rfc6902PatchOp),\n rationale: z.string(),\n currentContent: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const ContentUpdateResponse = z.object({\n patches: z.array(PatchEnvelope),\n assistantMessage: z.string(),\n});\n\nexport const PlaygroundProposeRequest = z.object({\n request: z.string().min(1).max(2000),\n});\n\nexport const PlaygroundProposeResponse = z.object({\n patches: z.array(PatchEnvelope),\n assistantMessage: z.string(),\n validation: z.object({\n valid: z.boolean(),\n issues: z.array(z.string()),\n filtered: z.number(),\n }),\n});\n\n// Multi-page schemas (Phase 2)\nexport const MultiPagePatchEnvelope = z.object({\n pageId: z.string(),\n blockId: z.string().optional(), // Not present for page-level ops\n blockKind: z.string().optional(),\n blockPurpose: z.string().optional().nullable(),\n ops: z.array(Rfc6902PatchOp),\n rationale: z.string(),\n currentContent: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const MultiPageUpdateResponse = z.object({\n patches: z.array(MultiPagePatchEnvelope),\n assistantMessage: z.string(),\n pagesModified: z.number(),\n toolCallsUsed: z.number(),\n});\n\n// Stream event types for real-time updates\nexport type StreamEvent =\n | { type: 'status'; message: string; detail?: string }\n | { type: 'tool_call'; tool: string; args: unknown }\n | { type: 'tool_result'; tool: string; summary: string }\n | { type: 'patch_group'; envelope: MultiPagePatchEnvelope }\n | { type: 'complete'; response: MultiPageUpdateResponse };\n\n// Types - export both the schemas and the inferred types\nexport type Rfc6902PatchOp = z.infer<typeof Rfc6902PatchOp>;\nexport type PatchEnvelope = z.infer<typeof PatchEnvelope>;\nexport type ContentUpdateResponse = z.infer<typeof ContentUpdateResponse>;\nexport type PlaygroundProposeRequest = z.infer<typeof PlaygroundProposeRequest>;\nexport type PlaygroundProposeResponse = z.infer<typeof PlaygroundProposeResponse>;\nexport type MultiPagePatchEnvelope = z.infer<typeof MultiPagePatchEnvelope>;\nexport type MultiPageUpdateResponse = z.infer<typeof MultiPageUpdateResponse>;\n\n// Re-export schemas for runtime validation\nexport {\n Rfc6902PatchOp as Rfc6902PatchOpSchema,\n PatchEnvelope as PatchEnvelopeSchema,\n ContentUpdateResponse as ContentUpdateResponseSchema,\n PlaygroundProposeRequest as PlaygroundProposeRequestSchema,\n PlaygroundProposeResponse as PlaygroundProposeResponseSchema,\n MultiPagePatchEnvelope as MultiPagePatchEnvelopeSchema,\n MultiPageUpdateResponse as MultiPageUpdateResponseSchema,\n};\n\n// Page context types for building AI prompts\nexport type AllowedField = {\n path: string;\n type: 'richtext' | 'plaintext' | 'url' | 'number' | 'boolean';\n};\n\nexport type BlockContext = {\n id: string;\n kind: string;\n purpose: string | null;\n orderIndex: number;\n allowedPaths: string[]; // Legacy, kept for backward compat\n allowedFields?: AllowedField[]; // New structured format with types\n content: Record<string, unknown>;\n};\n\nexport type PageContext = {\n site: {\n id: string;\n title: string;\n primaryDomain: string | null;\n };\n page: {\n id: string;\n path: string;\n title: string;\n slug: string | null;\n metaTitle: string | null;\n metaDescription: string | null;\n blocks: BlockContext[];\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/prebuild/index.ts","../../src/index.ts","../../../api/src/aiPlayground.ts"],"sourcesContent":["/**\n * Prebuild cache generation\n *\n * Exports static content at build time for use as a last-resort fallback\n * when the CMS is unavailable.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport type {\n PrebuildOptions,\n PrebuildResult,\n PrebuildProgress,\n PrebuildManifest,\n SiteCacheFile,\n PageCacheFile,\n PageIndexFile,\n EntriesCacheFile,\n NavigationCacheFile,\n} from './types';\nimport type { RiverbankClient, SiteResponse, EntriesResponse } from '../client/types';\nimport { SDK_VERSION } from '../version';\nimport { PREBUILD_PAGE_SIZE, DEFAULT_PREBUILD_DIR } from '../constants';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst MANIFEST_VERSION = '1.0.0';\nconst MANIFEST_FILENAME = 'manifest.json';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Convert a URL path to a safe filename.\n * Sanitizes special characters that are invalid on some filesystems.\n * e.g., '/about/team' -> 'about-team.json'\n * e.g., '/api/users?id=1' -> 'api-users_id_1.json'\n * Note: '/' becomes '_home.json' to avoid collision with '_index.json' (page listing)\n */\nfunction pathToFilename(routePath: string): string {\n if (routePath === '/') return '_home.json';\n return (\n routePath\n .slice(1)\n // Replace special characters with underscores (?, *, :, etc.)\n .replace(/[^a-zA-Z0-9\\-\\/]/g, '_')\n // Replace slashes with dashes\n .replace(/\\//g, '-') + '.json'\n );\n}\n\n/**\n * Ensure a directory exists, creating it recursively if needed.\n */\nfunction ensureDir(dirPath: string): void {\n if (!fs.existsSync(dirPath)) {\n fs.mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * Write JSON data to a file.\n */\nfunction writeJsonFile(filePath: string, data: unknown): number {\n const content = JSON.stringify(data, null, 2);\n fs.writeFileSync(filePath, content, 'utf-8');\n return Buffer.byteLength(content, 'utf-8');\n}\n\n/**\n * Calculate SHA256 checksum of object (excluding checksum field).\n */\nfunction calculateChecksum(data: Record<string, unknown>): string {\n const { checksum: _, ...rest } = data;\n const content = JSON.stringify(rest);\n return crypto.createHash('sha256').update(content).digest('hex');\n}\n\n// ============================================================================\n// Entry Fetching\n// ============================================================================\n\n/**\n * Fetch all entries for a content type using pagination.\n * Loops until all entries are retrieved.\n */\nasync function fetchAllEntries(\n client: RiverbankClient,\n siteId: string,\n contentType: string,\n onProgress?: (item: string) => void\n): Promise<EntriesResponse['entries']> {\n const allEntries: EntriesResponse['entries'] = [];\n let offset = 0;\n let hasMore = true;\n\n while (hasMore) {\n onProgress?.(`${contentType} (batch ${Math.floor(offset / PREBUILD_PAGE_SIZE) + 1})`);\n\n const response = await client.getEntries({\n siteId,\n contentType,\n limit: PREBUILD_PAGE_SIZE,\n offset,\n preview: false, // Published content only\n });\n\n allEntries.push(...response.entries);\n offset += PREBUILD_PAGE_SIZE;\n hasMore = response.entries.length === PREBUILD_PAGE_SIZE;\n }\n\n return allEntries;\n}\n\n// ============================================================================\n// Content Type Prebuild Functions\n// ============================================================================\n\nasync function prebuildSite(\n client: RiverbankClient,\n siteId: string,\n outputDir: string\n): Promise<{ files: string[]; size: number; siteData: SiteResponse }> {\n const site = await client.getSite({ id: siteId });\n const filename = 'site.json';\n const filePath = path.join(outputDir, filename);\n\n const cacheFile: SiteCacheFile = {\n data: site,\n generatedAt: new Date().toISOString(),\n };\n\n const size = writeJsonFile(filePath, cacheFile);\n return { files: [filename], size, siteData: site };\n}\n\nasync function prebuildPages(\n client: RiverbankClient,\n siteId: string,\n routes: Record<string, { path: string; status: string | null }>,\n outputDir: string,\n onProgress?: (progress: PrebuildProgress) => void\n): Promise<{ files: string[]; size: number }> {\n const pagesDir = path.join(outputDir, 'pages');\n ensureDir(pagesDir);\n\n const files: string[] = [];\n let totalSize = 0;\n\n // Filter to published routes only\n const publishedPaths = Object.entries(routes)\n .filter(([_, route]) => route.status === 'published')\n .map(([_, route]) => route.path);\n\n // Create page index\n const pageIndex: PageIndexFile['pages'] = [];\n\n const total = publishedPaths.length;\n let current = 0;\n\n for (const pagePath of publishedPaths) {\n current++;\n onProgress?.({\n current,\n total,\n item: `Page: ${pagePath}`,\n contentType: 'pages',\n });\n\n try {\n const pageData = await client.getPage({ siteId, path: pagePath, preview: false });\n const filename = pathToFilename(pagePath);\n const filePath = path.join(pagesDir, filename);\n\n const cacheFile: PageCacheFile = {\n data: pageData,\n path: pagePath,\n generatedAt: new Date().toISOString(),\n };\n\n totalSize += writeJsonFile(filePath, cacheFile);\n files.push(`pages/${filename}`);\n\n // Add to index (only for page type responses)\n if ('page' in pageData) {\n pageIndex.push({\n path: pagePath,\n pageId: pageData.page.routeId || '',\n title: pageData.page.name || 'Untitled',\n });\n }\n } catch (error) {\n // Log but continue - partial prebuild is okay\n console.warn(`[Prebuild] Failed to fetch page ${pagePath}:`, (error as Error).message);\n }\n }\n\n // Write page index (uses _index.json to avoid collision with home page)\n const indexFile: PageIndexFile = {\n pages: pageIndex,\n totalCount: pageIndex.length,\n generatedAt: new Date().toISOString(),\n };\n const indexPath = path.join(pagesDir, '_index.json');\n totalSize += writeJsonFile(indexPath, indexFile);\n files.push('pages/_index.json');\n\n return { files, size: totalSize };\n}\n\nasync function prebuildEntries(\n client: RiverbankClient,\n siteId: string,\n contentTypes: string[],\n outputDir: string,\n onProgress?: (progress: PrebuildProgress) => void\n): Promise<{ files: string[]; size: number }> {\n const entriesDir = path.join(outputDir, 'entries');\n ensureDir(entriesDir);\n\n const files: string[] = [];\n let totalSize = 0;\n\n const total = contentTypes.length;\n let current = 0;\n\n for (const contentType of contentTypes) {\n current++;\n\n const entries = await fetchAllEntries(\n client,\n siteId,\n contentType,\n (item) => {\n onProgress?.({\n current,\n total,\n item: `Entries: ${item}`,\n contentType: 'entries',\n });\n }\n );\n\n // Create content type directory\n const typeDir = path.join(entriesDir, contentType);\n ensureDir(typeDir);\n\n const cacheFile: EntriesCacheFile = {\n entries,\n contentType,\n totalCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n\n const filename = `entries/${contentType}/all.json`;\n const filePath = path.join(entriesDir, contentType, 'all.json');\n totalSize += writeJsonFile(filePath, cacheFile);\n files.push(filename);\n }\n\n return { files, size: totalSize };\n}\n\nasync function prebuildNavigation(\n siteData: SiteResponse,\n outputDir: string,\n onProgress?: (progress: PrebuildProgress) => void\n): Promise<{ files: string[]; size: number }> {\n const navDir = path.join(outputDir, 'navigation');\n ensureDir(navDir);\n\n const files: string[] = [];\n let totalSize = 0;\n\n // Navigation data comes from site response\n const menus = siteData.navigation || [];\n\n onProgress?.({\n current: 1,\n total: 1,\n item: 'Navigation menus',\n contentType: 'navigation',\n });\n\n const cacheFile: NavigationCacheFile = {\n menus: menus.map((menu) => ({\n identifier: menu.identifier,\n id: menu.id,\n name: menu.name,\n items: menu.items,\n })),\n generatedAt: new Date().toISOString(),\n };\n\n const filename = 'navigation/menus.json';\n const filePath = path.join(navDir, 'menus.json');\n totalSize += writeJsonFile(filePath, cacheFile);\n files.push(filename);\n\n return { files, size: totalSize };\n}\n\n// ============================================================================\n// Main Prebuild Function\n// ============================================================================\n\n/**\n * Generate a prebuild cache for the specified site.\n *\n * The prebuild cache contains static JSON files that can serve as a\n * last-resort fallback when the CMS is unavailable.\n *\n * @param options - Prebuild configuration\n * @returns Result with generated files and metadata\n *\n * @example\n * ```typescript\n * import { createRiverbankClient, prebuildCache } from '@riverbankcms/sdk';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n *\n * const result = await prebuildCache({\n * client,\n * siteId: 'your-site-id',\n * outputDir: '.riverbank-cache',\n * onProgress: (p) => console.log(`${p.current}/${p.total}: ${p.item}`),\n * });\n *\n * console.log(`Generated ${result.files.length} files (${result.totalSize} bytes)`);\n * ```\n */\nexport async function prebuildCache(options: PrebuildOptions): Promise<PrebuildResult> {\n const {\n client,\n siteId,\n outputDir = DEFAULT_PREBUILD_DIR,\n include = ['site', 'pages', 'entries', 'navigation'],\n contentTypes,\n onProgress,\n } = options;\n\n const generatedAt = new Date().toISOString();\n const files: string[] = [];\n let totalSize = 0;\n const errors: string[] = [];\n let siteData: SiteResponse | null = null;\n\n // Ensure output directory exists\n ensureDir(outputDir);\n\n // -------------------------------------------------------------------------\n // 1. Prebuild site data (always needed for routes and navigation)\n // -------------------------------------------------------------------------\n if (include.includes('site') || include.includes('pages') || include.includes('navigation')) {\n try {\n const result = await prebuildSite(client, siteId, outputDir);\n siteData = result.siteData;\n if (include.includes('site')) {\n files.push(...result.files);\n totalSize += result.size;\n }\n onProgress?.({ current: 1, total: 4, item: 'Site data', contentType: 'site' });\n } catch (error) {\n errors.push(`Site prebuild failed: ${(error as Error).message}`);\n }\n }\n\n // -------------------------------------------------------------------------\n // 2. Prebuild pages\n // -------------------------------------------------------------------------\n if (include.includes('pages') && siteData) {\n try {\n const result = await prebuildPages(\n client,\n siteId,\n siteData.routes,\n outputDir,\n onProgress\n );\n files.push(...result.files);\n totalSize += result.size;\n } catch (error) {\n errors.push(`Pages prebuild failed: ${(error as Error).message}`);\n }\n }\n\n // -------------------------------------------------------------------------\n // 3. Prebuild entries\n // -------------------------------------------------------------------------\n if (include.includes('entries')) {\n try {\n // Content types must be explicitly provided via options.contentTypes\n // (The API's sdkConfig doesn't include content type definitions)\n const typesToPrebuild = contentTypes || [];\n\n if (typesToPrebuild.length > 0) {\n const result = await prebuildEntries(\n client,\n siteId,\n typesToPrebuild,\n outputDir,\n onProgress\n );\n files.push(...result.files);\n totalSize += result.size;\n } else {\n console.warn('[Prebuild] No contentTypes provided - skipping entries prebuild');\n }\n } catch (error) {\n errors.push(`Entries prebuild failed: ${(error as Error).message}`);\n }\n }\n\n // -------------------------------------------------------------------------\n // 4. Prebuild navigation\n // -------------------------------------------------------------------------\n if (include.includes('navigation') && siteData) {\n try {\n const result = await prebuildNavigation(siteData, outputDir, onProgress);\n files.push(...result.files);\n totalSize += result.size;\n } catch (error) {\n errors.push(`Navigation prebuild failed: ${(error as Error).message}`);\n }\n }\n\n // -------------------------------------------------------------------------\n // 5. Generate manifest\n // -------------------------------------------------------------------------\n const keyToFile: Record<string, string> = {};\n\n // Map cache keys to files\n if (files.includes('site.json')) {\n keyToFile[`site:${siteId}`] = 'site.json';\n }\n\n for (const file of files) {\n if (file.startsWith('pages/') && file !== 'pages/_index.json') {\n // Extract path from filename\n // _home.json -> '/', about.json -> '/about', about-team.json -> '/about/team'\n const filename = file.replace('pages/', '').replace('.json', '');\n const pagePath = filename === '_home' ? '/' : '/' + filename.replace(/-/g, '/');\n keyToFile[`page:${siteId}:${pagePath}:false`] = file;\n }\n\n if (file.startsWith('entries/') && file.endsWith('/all.json')) {\n // entries/{contentType}/all.json\n const contentType = file.split('/')[1];\n keyToFile[`entries-all:${siteId}:${contentType}`] = file;\n }\n }\n\n const manifest: Omit<PrebuildManifest, 'checksum'> & { checksum?: string } = {\n version: MANIFEST_VERSION,\n generatedAt,\n siteId,\n sdkVersion: SDK_VERSION,\n keyToFile,\n includedTypes: include,\n fileCount: files.length,\n totalSize,\n };\n\n // Calculate checksum\n const checksum = calculateChecksum(manifest as Record<string, unknown>);\n (manifest as PrebuildManifest).checksum = checksum;\n\n const manifestPath = path.join(outputDir, MANIFEST_FILENAME);\n writeJsonFile(manifestPath, manifest);\n\n return {\n success: errors.length === 0,\n outputDir,\n files,\n totalSize,\n generatedAt,\n checksum,\n errors: errors.length > 0 ? errors : undefined,\n };\n}\n\n// Re-export types\nexport type {\n PrebuildOptions,\n PrebuildResult,\n PrebuildProgress,\n PrebuildManifest,\n PrebuildContentType,\n} from './types';\n","/**\n * Riverbank CMS SDK\n *\n * A TypeScript SDK for consuming Riverbank CMS content in your own applications.\n *\n * @example\n * ```ts\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n *\n * const client = createRiverbankClient({\n * apiKey: process.env.RIVERBANK_API_KEY!,\n * baseUrl: `${process.env.NEXT_PUBLIC_DASHBOARD_URL}/api`,\n * });\n *\n * const site = await client.getSite({ slug: 'my-site' });\n * ```\n *\n * @packageDocumentation\n */\n\n// Client factory and types (server-safe)\nexport { createRiverbankClient } from './client/index';\nexport type {\n RiverbankClient,\n RiverbankClientConfig,\n SiteResponse,\n PageResponse,\n EntriesResponse,\n EntriesResponseWithMeta,\n PaginationMeta,\n EntryResponse,\n // Resilience types\n ResilienceConfig,\n ResilienceStatus,\n ResilienceSource,\n CircuitState,\n RetryConfig,\n CircuitBreakerConfig,\n} from './client/types';\n\n// Prebuild cache generation (for build-time static export)\nexport { prebuildCache } from './prebuild/index';\nexport type {\n PrebuildOptions,\n PrebuildResult,\n PrebuildProgress,\n PrebuildManifest,\n PrebuildContentType,\n} from './prebuild/types';\n\n// Prebuild loader (for runtime fallback)\nexport {\n PrebuildLoader,\n createPrebuildLoader,\n canUsePrebuild,\n} from './prebuild/loader';\nexport type { PrebuildLoaderConfig, LoadResult } from './prebuild/loader';\n\n// Re-export API client type for convenience\nexport type { ApiClient } from '@riverbankcms/api';\n\n// Re-export endpoint utilities for building API URLs\nexport { buildEndpointURL, API_ENDPOINTS } from '@riverbankcms/api';\n\n// Note: For loadPage, Page, Layout, Block, import from '@riverbankcms/sdk/rendering'\n// Note: For client-side hooks (usePage, useContent), import from '@riverbankcms/sdk/client'\n\n// Site configuration types (for SDK sites defining their own config)\nexport type {\n RiverbankSiteConfig,\n SiteStyleConfig,\n SectionBackground,\n SectionOptionsConfig,\n ContainerOptionsConfig,\n SectionSpacing,\n ContainerMaxWidth,\n ContainerAlignment,\n} from './config';\n\n// Block kind types (single source of truth from @riverbankcms/blocks)\nexport {\n SYSTEM_BLOCK_KINDS,\n type SystemBlockKind,\n type CustomBlockKind,\n type BlockKind,\n} from './types';\n","import { z } from 'zod';\n\n/**\n * RFC-6902 JSON Patch Operations\n * Standard JSON Patch format for AI Playground content updates\n */\n\nexport const Rfc6902PatchOp = z.discriminatedUnion('op', [\n // Standard RFC-6902 operations\n z.object({\n op: z.literal('add'),\n path: z.string(),\n value: z.unknown(),\n }),\n z.object({\n op: z.literal('remove'),\n path: z.string(),\n }),\n z.object({\n op: z.literal('replace'),\n path: z.string(),\n value: z.unknown(),\n }),\n z.object({\n op: z.literal('move'),\n from: z.string(),\n path: z.string(),\n }),\n z.object({\n op: z.literal('copy'),\n from: z.string(),\n path: z.string(),\n }),\n // Block-level operations (Phase 2)\n z.object({\n op: z.literal('add_block'),\n blockKind: z.string(),\n afterBlockId: z.string().nullable(),\n content: z.record(z.string(), z.unknown()),\n rationale: z.string(),\n }),\n z.object({\n op: z.literal('delete_block'),\n blockId: z.string(),\n rationale: z.string(),\n }),\n z.object({\n op: z.literal('reorder_block'),\n blockId: z.string(),\n afterBlockId: z.string().nullable(),\n rationale: z.string(),\n }),\n]);\n\nexport const PatchEnvelope = z.object({\n blockId: z.string(),\n blockKind: z.string().optional(),\n blockPurpose: z.string().optional().nullable(),\n ops: z.array(Rfc6902PatchOp),\n rationale: z.string(),\n currentContent: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const ContentUpdateResponse = z.object({\n patches: z.array(PatchEnvelope),\n assistantMessage: z.string(),\n});\n\nexport const PlaygroundProposeRequest = z.object({\n request: z.string().min(1).max(2000),\n});\n\nexport const PlaygroundProposeResponse = z.object({\n patches: z.array(PatchEnvelope),\n assistantMessage: z.string(),\n validation: z.object({\n valid: z.boolean(),\n issues: z.array(z.string()),\n filtered: z.number(),\n }),\n});\n\n// Multi-page schemas (Phase 2)\nexport const MultiPagePatchEnvelope = z.object({\n pageId: z.string(),\n blockId: z.string().optional(), // Not present for page-level ops\n blockKind: z.string().optional(),\n blockPurpose: z.string().optional().nullable(),\n ops: z.array(Rfc6902PatchOp),\n rationale: z.string(),\n currentContent: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const MultiPageUpdateResponse = z.object({\n patches: z.array(MultiPagePatchEnvelope),\n assistantMessage: z.string(),\n pagesModified: z.number(),\n toolCallsUsed: z.number(),\n});\n\n// Stream event types for real-time updates\nexport type StreamEvent =\n | { type: 'status'; message: string; detail?: string }\n | { type: 'tool_call'; tool: string; args: unknown }\n | { type: 'tool_result'; tool: string; summary: string }\n | { type: 'patch_group'; envelope: MultiPagePatchEnvelope }\n | { type: 'complete'; response: MultiPageUpdateResponse };\n\n// Types - export both the schemas and the inferred types\nexport type Rfc6902PatchOp = z.infer<typeof Rfc6902PatchOp>;\nexport type PatchEnvelope = z.infer<typeof PatchEnvelope>;\nexport type ContentUpdateResponse = z.infer<typeof ContentUpdateResponse>;\nexport type PlaygroundProposeRequest = z.infer<typeof PlaygroundProposeRequest>;\nexport type PlaygroundProposeResponse = z.infer<typeof PlaygroundProposeResponse>;\nexport type MultiPagePatchEnvelope = z.infer<typeof MultiPagePatchEnvelope>;\nexport type MultiPageUpdateResponse = z.infer<typeof MultiPageUpdateResponse>;\n\n// Re-export schemas for runtime validation\nexport {\n Rfc6902PatchOp as Rfc6902PatchOpSchema,\n PatchEnvelope as PatchEnvelopeSchema,\n ContentUpdateResponse as ContentUpdateResponseSchema,\n PlaygroundProposeRequest as PlaygroundProposeRequestSchema,\n PlaygroundProposeResponse as PlaygroundProposeResponseSchema,\n MultiPagePatchEnvelope as MultiPagePatchEnvelopeSchema,\n MultiPageUpdateResponse as MultiPageUpdateResponseSchema,\n};\n\n// Page context types for building AI prompts\nexport type AllowedField = {\n path: string;\n type: 'richtext' | 'plaintext' | 'url' | 'number' | 'boolean';\n};\n\nexport type BlockContext = {\n id: string;\n kind: string;\n purpose: string | null;\n orderIndex: number;\n allowedPaths: string[]; // Legacy, kept for backward compat\n allowedFields?: AllowedField[]; // New structured format with types\n content: Record<string, unknown>;\n};\n\nexport type PageContext = {\n site: {\n id: string;\n title: string;\n primaryDomain: string | null;\n };\n page: {\n id: string;\n path: string;\n title: string;\n slug: string | null;\n metaTitle: string | null;\n metaDescription: string | null;\n blocks: BlockContext[];\n };\n};\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
- import { T as Theme } from './types-CVykEqXN.js';
1
+ import { T as Theme } from './types-Dt98DeYa.js';
2
2
  import './schema-Z6-afHJG.js';
3
- import { R as RiverbankClient, S as SiteResponse } from './types-BvcJU7zk.js';
4
- import { P as PageProps } from './loadPage-DP3nrHBi.js';
3
+ import { R as RiverbankClient, S as SiteResponse } from './types-BRQyLrQU.js';
4
+ import { P as PageProps } from './loadPage-BmYJCe_V.js';
5
5
  import { R as ResolvedBlockData } from './types-DuQCNVV0.js';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
- import { T as Theme } from './types-Dsu9wsUh.mjs';
1
+ import { T as Theme } from './types-BSV6Vc-P.mjs';
2
2
  import './schema-Z6-afHJG.mjs';
3
- import { R as RiverbankClient, S as SiteResponse } from './types-1cLz0vnq.mjs';
4
- import { P as PageProps } from './loadPage-B8mQUUSo.mjs';
3
+ import { R as RiverbankClient, S as SiteResponse } from './types-C-LShyIg.mjs';
4
+ import { P as PageProps } from './loadPage-BucnLHmE.mjs';
5
5
  import { R as ResolvedBlockData } from './types-CbagRQ_7.mjs';
6
6
 
7
7
  /**
@@ -4,8 +4,8 @@ var _chunkP3NNN73Gjs = require('./chunk-P3NNN73G.js');
4
4
  require('./chunk-Y7347JMZ.js');
5
5
  require('./chunk-RVDS7VSP.js');
6
6
  require('./chunk-YYO3RIFO.js');
7
- require('./chunk-DGUM43GV.js');
7
+ require('./chunk-4CV4JOE5.js');
8
8
 
9
9
 
10
10
  exports.loadPage = _chunkP3NNN73Gjs.loadPage;
11
- //# sourceMappingURL=loadPage-IDGVDFBB.js.map
11
+ //# sourceMappingURL=loadPage-AXNAERDS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/loadPage-IDGVDFBB.js"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,6CAAC","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/loadPage-IDGVDFBB.js"}
1
+ {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/loadPage-AXNAERDS.js"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,6CAAC","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/loadPage-AXNAERDS.js"}
@@ -1,10 +1,10 @@
1
- import { R as RiverbankClient, S as SiteResponse } from './types-BvcJU7zk.js';
1
+ import { R as RiverbankClient, S as SiteResponse } from './types-BRQyLrQU.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as React$1 from 'react';
4
4
  import React__default from 'react';
5
5
  import { P as PageOutline, S as SdkCustomBlock } from './schema-Z6-afHJG.js';
6
6
  import { T as TransformRegistry, a as ThemeTokens, R as RouteMap } from './core-DsNWrl3o.js';
7
- import { T as Theme } from './types-CVykEqXN.js';
7
+ import { T as Theme } from './types-Dt98DeYa.js';
8
8
  import { R as ResolvedBlockData, D as DataLoaderOverrides } from './types-DuQCNVV0.js';
9
9
 
10
10
  type ViewModel = Record<string, unknown>;
@@ -1,10 +1,10 @@
1
- import { R as RiverbankClient, S as SiteResponse } from './types-1cLz0vnq.mjs';
1
+ import { R as RiverbankClient, S as SiteResponse } from './types-C-LShyIg.mjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as React$1 from 'react';
4
4
  import React__default from 'react';
5
5
  import { P as PageOutline, S as SdkCustomBlock } from './schema-Z6-afHJG.mjs';
6
6
  import { T as TransformRegistry, a as ThemeTokens, R as RouteMap } from './core-DsNWrl3o.mjs';
7
- import { T as Theme } from './types-Dsu9wsUh.mjs';
7
+ import { T as Theme } from './types-BSV6Vc-P.mjs';
8
8
  import { R as ResolvedBlockData, D as DataLoaderOverrides } from './types-CbagRQ_7.mjs';
9
9
 
10
10
  type ViewModel = Record<string, unknown>;
@@ -4,8 +4,8 @@ import {
4
4
  import "./chunk-A2FZMRDW.mjs";
5
5
  import "./chunk-AEFWG657.mjs";
6
6
  import "./chunk-BYBJA6SP.mjs";
7
- import "./chunk-BJTO5JO5.mjs";
7
+ import "./chunk-NFEGQTCC.mjs";
8
8
  export {
9
9
  loadPage
10
10
  };
11
- //# sourceMappingURL=loadPage-DNQTTRHL.mjs.map
11
+ //# sourceMappingURL=loadPage-XR7ORQ2E.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,7 +1,7 @@
1
- export { P as PageMetadataInput, g as generatePageMetadata, a as generatePreviewMetadata } from './index-DI_qlYx3.mjs';
2
- import './loadPage-B8mQUUSo.mjs';
3
- import './types-1cLz0vnq.mjs';
4
- import './types-Dsu9wsUh.mjs';
1
+ export { P as PageMetadataInput, g as generatePageMetadata, a as generatePreviewMetadata } from './index--Oyunk_B.mjs';
2
+ import './loadPage-BucnLHmE.mjs';
3
+ import './types-C-LShyIg.mjs';
4
+ import './types-BSV6Vc-P.mjs';
5
5
  import '@riverbankcms/ai';
6
6
  import './schema-Z6-afHJG.mjs';
7
7
  import 'zod';
@@ -1,7 +1,7 @@
1
- export { P as PageMetadataInput, g as generatePageMetadata, a as generatePreviewMetadata } from './index-BTwWvSBu.js';
2
- import './loadPage-DP3nrHBi.js';
3
- import './types-BvcJU7zk.js';
4
- import './types-CVykEqXN.js';
1
+ export { P as PageMetadataInput, g as generatePageMetadata, a as generatePreviewMetadata } from './index-C9Ra8dza.js';
2
+ import './loadPage-BmYJCe_V.js';
3
+ import './types-BRQyLrQU.js';
4
+ import './types-Dt98DeYa.js';
5
5
  import '@riverbankcms/ai';
6
6
  import './schema-Z6-afHJG.js';
7
7
  import 'zod';
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
  var _chunkBNQV3PXPjs = require('./chunk-BNQV3PXP.js');
5
- require('./chunk-DGUM43GV.js');
5
+ require('./chunk-4CV4JOE5.js');
6
6
 
7
7
 
8
8
 
@@ -2,7 +2,7 @@ import {
2
2
  generatePageMetadata,
3
3
  generatePreviewMetadata
4
4
  } from "./chunk-SWYWZT3L.mjs";
5
- import "./chunk-BJTO5JO5.mjs";
5
+ import "./chunk-NFEGQTCC.mjs";
6
6
  export {
7
7
  generatePageMetadata,
8
8
  generatePreviewMetadata
@@ -1,5 +1,5 @@
1
- import { N as NavigationMenuWithItems } from './types-Dsu9wsUh.mjs';
2
- export { L as LinkPayload, a as NavigationItemRecord } from './types-Dsu9wsUh.mjs';
1
+ import { N as NavigationMenuWithItems } from './types-BSV6Vc-P.mjs';
2
+ export { L as LinkPayload, a as NavigationItemRecord } from './types-BSV6Vc-P.mjs';
3
3
  import { R as RouteMap } from './core-DsNWrl3o.mjs';
4
4
  import './schema-Z6-afHJG.mjs';
5
5
  import '@riverbankcms/ai';
@@ -1,5 +1,5 @@
1
- import { N as NavigationMenuWithItems } from './types-CVykEqXN.js';
2
- export { L as LinkPayload, a as NavigationItemRecord } from './types-CVykEqXN.js';
1
+ import { N as NavigationMenuWithItems } from './types-Dt98DeYa.js';
2
+ export { L as LinkPayload, a as NavigationItemRecord } from './types-Dt98DeYa.js';
3
3
  import { R as RouteMap } from './core-DsNWrl3o.js';
4
4
  import './schema-Z6-afHJG.js';
5
5
  import '@riverbankcms/ai';
@@ -13,7 +13,7 @@
13
13
 
14
14
 
15
15
  var _chunkEIVISR62js = require('./chunk-EIVISR62.js');
16
- require('./chunk-DGUM43GV.js');
16
+ require('./chunk-4CV4JOE5.js');
17
17
 
18
18
 
19
19
 
@@ -13,7 +13,7 @@ import {
13
13
  isNavLink,
14
14
  transformToNavItems
15
15
  } from "./chunk-YXA4GAAQ.mjs";
16
- import "./chunk-BJTO5JO5.mjs";
16
+ import "./chunk-NFEGQTCC.mjs";
17
17
  export {
18
18
  buildLogo,
19
19
  buildLogoViewModel,
@@ -0,0 +1,66 @@
1
+ import { WebhookPayload } from '../webhooks.mjs';
2
+ import 'zod';
3
+
4
+ /**
5
+ * Next.js revalidation handler for webhook-based cache invalidation
6
+ *
7
+ * This module provides a pre-built API route handler for processing
8
+ * CMS webhooks and revalidating Next.js cache entries.
9
+ *
10
+ * @example One-line setup in consumer site
11
+ * ```ts
12
+ * // app/api/revalidate/route.ts
13
+ * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';
14
+ * export const POST = createRevalidateHandler();
15
+ * ```
16
+ *
17
+ * @example With custom options
18
+ * ```ts
19
+ * // app/api/revalidate/route.ts
20
+ * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';
21
+ *
22
+ * export const POST = createRevalidateHandler({
23
+ * onRevalidate: (payload, items) => {
24
+ * console.log(`Revalidated ${items.length} items for ${payload.event}`);
25
+ * },
26
+ * });
27
+ * ```
28
+ */
29
+
30
+ /**
31
+ * Options for the revalidation handler.
32
+ */
33
+ interface RevalidateHandlerOptions {
34
+ /**
35
+ * Override the webhook secret. Defaults to RIVERBANK_WEBHOOK_SECRET env var.
36
+ */
37
+ secret?: string;
38
+ /**
39
+ * Callback called after successful revalidation.
40
+ * Useful for logging or analytics.
41
+ */
42
+ onRevalidate?: (payload: WebhookPayload, revalidatedItems: string[]) => void;
43
+ }
44
+ /**
45
+ * Create a Next.js API route handler for webhook revalidation.
46
+ *
47
+ * The handler:
48
+ * 1. Verifies the webhook signature using HMAC-SHA256
49
+ * 2. Calls `revalidateTag()` for each tag in the payload
50
+ * 3. Calls `revalidatePath()` if a path is included in the data
51
+ * 4. Returns a JSON response with the revalidation results
52
+ *
53
+ * @param options - Configuration options
54
+ * @returns A Next.js Route Handler function
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // app/api/revalidate/route.ts
59
+ * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';
60
+ *
61
+ * export const POST = createRevalidateHandler();
62
+ * ```
63
+ */
64
+ declare function createRevalidateHandler(options?: RevalidateHandlerOptions): (request: Request) => Promise<Response>;
65
+
66
+ export { type RevalidateHandlerOptions, createRevalidateHandler };