@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
@@ -0,0 +1,66 @@
1
+ import { WebhookPayload } from '../webhooks.js';
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 };
@@ -0,0 +1,60 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+ var _chunkNBTRDLCMjs = require('../chunk-NBTRDLCM.js');
5
+ require('../chunk-4CV4JOE5.js');
6
+
7
+ // src/next/revalidate.ts
8
+ var _cache = require('next/cache');
9
+ function createRevalidateHandler(options = {}) {
10
+ return async function handleRevalidateRequest(request) {
11
+ const secret = _nullishCoalesce(options.secret, () => ( process.env.RIVERBANK_WEBHOOK_SECRET));
12
+ if (!secret) {
13
+ console.error("[Riverbank] RIVERBANK_WEBHOOK_SECRET not configured");
14
+ return Response.json(
15
+ { error: "Webhook secret not configured" },
16
+ { status: 500 }
17
+ );
18
+ }
19
+ const body = await request.text();
20
+ const signature = request.headers.get("x-riverbank-signature");
21
+ if (!signature || !_chunkNBTRDLCMjs.verifyWebhookSignature.call(void 0, body, signature, secret)) {
22
+ return Response.json({ error: "Invalid signature" }, { status: 401 });
23
+ }
24
+ const parseResult = _chunkNBTRDLCMjs.parseWebhookPayload.call(void 0, body);
25
+ if (!parseResult.success) {
26
+ return Response.json({ error: parseResult.error }, { status: 400 });
27
+ }
28
+ const payload = parseResult.payload;
29
+ const revalidated = [];
30
+ if (_optionalChain([payload, 'access', _ => _.tags, 'optionalAccess', _2 => _2.length])) {
31
+ for (const tag of payload.tags) {
32
+ _cache.revalidateTag.call(void 0, tag);
33
+ revalidated.push(`tag:${tag}`);
34
+ }
35
+ }
36
+ const path = typeof _optionalChain([payload, 'access', _3 => _3.data, 'optionalAccess', _4 => _4.path]) === "string" ? payload.data.path : void 0;
37
+ if (path) {
38
+ _cache.revalidatePath.call(void 0, path);
39
+ revalidated.push(`path:${path}`);
40
+ }
41
+ if (revalidated.length > 0) {
42
+ console.log(
43
+ `[Riverbank] Revalidated: ${revalidated.join(", ")} (event: ${payload.event})`
44
+ );
45
+ }
46
+ if (options.onRevalidate) {
47
+ options.onRevalidate(payload, revalidated);
48
+ }
49
+ return Response.json({
50
+ revalidated: true,
51
+ items: revalidated,
52
+ event: payload.event,
53
+ timestamp: Date.now()
54
+ });
55
+ };
56
+ }
57
+
58
+
59
+ exports.createRevalidateHandler = createRevalidateHandler;
60
+ //# sourceMappingURL=revalidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/next/revalidate.js","../../../src/next/revalidate.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,uDAA6B;AAC7B,gCAA6B;AAC7B;AACA;ACoBA,mCAA8C;AA2CvC,SAAS,uBAAA,CACd,QAAA,EAAoC,CAAC,CAAA,EACI;AACzC,EAAA,OAAO,MAAA,SAAe,uBAAA,CAAwB,OAAA,EAAqC;AAEjF,IAAA,MAAM,OAAA,mBAAS,OAAA,CAAQ,MAAA,UAAU,OAAA,CAAQ,GAAA,CAAI,0BAAA;AAE7C,IAAA,GAAA,CAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAA,CAAQ,KAAA,CAAM,qDAAqD,CAAA;AACnE,MAAA,OAAO,QAAA,CAAS,IAAA;AAAA,QACd,EAAE,KAAA,EAAO,gCAAgC,CAAA;AAAA,QACzC,EAAE,MAAA,EAAQ,IAAI;AAAA,MAChB,CAAA;AAAA,IACF;AAGA,IAAA,MAAM,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAA;AAChC,IAAA,MAAM,UAAA,EAAY,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,uBAAuB,CAAA;AAG7D,IAAA,GAAA,CAAI,CAAC,UAAA,GAAa,CAAC,qDAAA,IAAuB,EAAM,SAAA,EAAW,MAAM,CAAA,EAAG;AAClE,MAAA,OAAO,QAAA,CAAS,IAAA,CAAK,EAAE,KAAA,EAAO,oBAAoB,CAAA,EAAG,EAAE,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IACtE;AAGA,IAAA,MAAM,YAAA,EAAc,kDAAA,IAAwB,CAAA;AAC5C,IAAA,GAAA,CAAI,CAAC,WAAA,CAAY,OAAA,EAAS;AACxB,MAAA,OAAO,QAAA,CAAS,IAAA,CAAK,EAAE,KAAA,EAAO,WAAA,CAAY,MAAM,CAAA,EAAG,EAAE,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IACpE;AACA,IAAA,MAAM,QAAA,EAAU,WAAA,CAAY,OAAA;AAC5B,IAAA,MAAM,YAAA,EAAwB,CAAC,CAAA;AAG/B,IAAA,GAAA,iBAAI,OAAA,mBAAQ,IAAA,6BAAM,QAAA,EAAQ;AACxB,MAAA,IAAA,CAAA,MAAW,IAAA,GAAO,OAAA,CAAQ,IAAA,EAAM;AAC9B,QAAA,kCAAA,GAAiB,CAAA;AACjB,QAAA,WAAA,CAAY,IAAA,CAAK,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA;AAC7B,MAAA;AACF,IAAA;AAG4B,IAAA;AAClB,IAAA;AACW,MAAA;AACU,MAAA;AAC/B,IAAA;AAG4B,IAAA;AAClB,MAAA;AACsB,QAAA;AAC9B,MAAA;AACF,IAAA;AAG0B,IAAA;AACM,MAAA;AAChC,IAAA;AAEqB,IAAA;AACN,MAAA;AACN,MAAA;AACQ,MAAA;AACK,MAAA;AACrB,IAAA;AACH,EAAA;AACF;AD/EoC;AACA;AACA","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/next/revalidate.js","sourcesContent":[null,"/**\n * Next.js revalidation handler for webhook-based cache invalidation\n *\n * This module provides a pre-built API route handler for processing\n * CMS webhooks and revalidating Next.js cache entries.\n *\n * @example One-line setup in consumer site\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n * export const POST = createRevalidateHandler();\n * ```\n *\n * @example With custom options\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n *\n * export const POST = createRevalidateHandler({\n * onRevalidate: (payload, items) => {\n * console.log(`Revalidated ${items.length} items for ${payload.event}`);\n * },\n * });\n * ```\n */\n\nimport { revalidateTag, revalidatePath } from 'next/cache';\nimport {\n verifyWebhookSignature,\n parseWebhookPayload,\n type WebhookPayload,\n} from '../webhooks/verify';\n\n/**\n * Options for the revalidation handler.\n */\nexport interface RevalidateHandlerOptions {\n /**\n * Override the webhook secret. Defaults to RIVERBANK_WEBHOOK_SECRET env var.\n */\n secret?: string;\n\n /**\n * Callback called after successful revalidation.\n * Useful for logging or analytics.\n */\n onRevalidate?: (payload: WebhookPayload, revalidatedItems: string[]) => void;\n}\n\n/**\n * Create a Next.js API route handler for webhook revalidation.\n *\n * The handler:\n * 1. Verifies the webhook signature using HMAC-SHA256\n * 2. Calls `revalidateTag()` for each tag in the payload\n * 3. Calls `revalidatePath()` if a path is included in the data\n * 4. Returns a JSON response with the revalidation results\n *\n * @param options - Configuration options\n * @returns A Next.js Route Handler function\n *\n * @example\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n *\n * export const POST = createRevalidateHandler();\n * ```\n */\nexport function createRevalidateHandler(\n options: RevalidateHandlerOptions = {}\n): (request: Request) => Promise<Response> {\n return async function handleRevalidateRequest(request: Request): Promise<Response> {\n // Get webhook secret\n const secret = options.secret ?? process.env.RIVERBANK_WEBHOOK_SECRET;\n\n if (!secret) {\n console.error('[Riverbank] RIVERBANK_WEBHOOK_SECRET not configured');\n return Response.json(\n { error: 'Webhook secret not configured' },\n { status: 500 }\n );\n }\n\n // Read request body\n const body = await request.text();\n const signature = request.headers.get('x-riverbank-signature');\n\n // Verify signature\n if (!signature || !verifyWebhookSignature(body, signature, secret)) {\n return Response.json({ error: 'Invalid signature' }, { status: 401 });\n }\n\n // Parse and validate payload\n const parseResult = parseWebhookPayload(body);\n if (!parseResult.success) {\n return Response.json({ error: parseResult.error }, { status: 400 });\n }\n const payload = parseResult.payload;\n const revalidated: string[] = [];\n\n // Tag-based revalidation (preferred)\n if (payload.tags?.length) {\n for (const tag of payload.tags) {\n revalidateTag(tag);\n revalidated.push(`tag:${tag}`);\n }\n }\n\n // Path-based fallback (from data.path if present)\n const path = typeof payload.data?.path === 'string' ? payload.data.path : undefined;\n if (path) {\n revalidatePath(path);\n revalidated.push(`path:${path}`);\n }\n\n // Log revalidation\n if (revalidated.length > 0) {\n console.log(\n `[Riverbank] Revalidated: ${revalidated.join(', ')} (event: ${payload.event})`\n );\n }\n\n // Call optional callback\n if (options.onRevalidate) {\n options.onRevalidate(payload, revalidated);\n }\n\n return Response.json({\n revalidated: true,\n items: revalidated,\n event: payload.event,\n timestamp: Date.now(),\n });\n };\n}\n"]}
@@ -0,0 +1,60 @@
1
+ import {
2
+ parseWebhookPayload,
3
+ verifyWebhookSignature
4
+ } from "../chunk-5LRR64Y6.mjs";
5
+ import "../chunk-NFEGQTCC.mjs";
6
+
7
+ // src/next/revalidate.ts
8
+ import { revalidateTag, revalidatePath } from "next/cache";
9
+ function createRevalidateHandler(options = {}) {
10
+ return async function handleRevalidateRequest(request) {
11
+ const secret = options.secret ?? process.env.RIVERBANK_WEBHOOK_SECRET;
12
+ if (!secret) {
13
+ console.error("[Riverbank] RIVERBANK_WEBHOOK_SECRET not configured");
14
+ return Response.json(
15
+ { error: "Webhook secret not configured" },
16
+ { status: 500 }
17
+ );
18
+ }
19
+ const body = await request.text();
20
+ const signature = request.headers.get("x-riverbank-signature");
21
+ if (!signature || !verifyWebhookSignature(body, signature, secret)) {
22
+ return Response.json({ error: "Invalid signature" }, { status: 401 });
23
+ }
24
+ const parseResult = parseWebhookPayload(body);
25
+ if (!parseResult.success) {
26
+ return Response.json({ error: parseResult.error }, { status: 400 });
27
+ }
28
+ const payload = parseResult.payload;
29
+ const revalidated = [];
30
+ if (payload.tags?.length) {
31
+ for (const tag of payload.tags) {
32
+ revalidateTag(tag);
33
+ revalidated.push(`tag:${tag}`);
34
+ }
35
+ }
36
+ const path = typeof payload.data?.path === "string" ? payload.data.path : void 0;
37
+ if (path) {
38
+ revalidatePath(path);
39
+ revalidated.push(`path:${path}`);
40
+ }
41
+ if (revalidated.length > 0) {
42
+ console.log(
43
+ `[Riverbank] Revalidated: ${revalidated.join(", ")} (event: ${payload.event})`
44
+ );
45
+ }
46
+ if (options.onRevalidate) {
47
+ options.onRevalidate(payload, revalidated);
48
+ }
49
+ return Response.json({
50
+ revalidated: true,
51
+ items: revalidated,
52
+ event: payload.event,
53
+ timestamp: Date.now()
54
+ });
55
+ };
56
+ }
57
+ export {
58
+ createRevalidateHandler
59
+ };
60
+ //# sourceMappingURL=revalidate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/next/revalidate.ts"],"sourcesContent":["/**\n * Next.js revalidation handler for webhook-based cache invalidation\n *\n * This module provides a pre-built API route handler for processing\n * CMS webhooks and revalidating Next.js cache entries.\n *\n * @example One-line setup in consumer site\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n * export const POST = createRevalidateHandler();\n * ```\n *\n * @example With custom options\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n *\n * export const POST = createRevalidateHandler({\n * onRevalidate: (payload, items) => {\n * console.log(`Revalidated ${items.length} items for ${payload.event}`);\n * },\n * });\n * ```\n */\n\nimport { revalidateTag, revalidatePath } from 'next/cache';\nimport {\n verifyWebhookSignature,\n parseWebhookPayload,\n type WebhookPayload,\n} from '../webhooks/verify';\n\n/**\n * Options for the revalidation handler.\n */\nexport interface RevalidateHandlerOptions {\n /**\n * Override the webhook secret. Defaults to RIVERBANK_WEBHOOK_SECRET env var.\n */\n secret?: string;\n\n /**\n * Callback called after successful revalidation.\n * Useful for logging or analytics.\n */\n onRevalidate?: (payload: WebhookPayload, revalidatedItems: string[]) => void;\n}\n\n/**\n * Create a Next.js API route handler for webhook revalidation.\n *\n * The handler:\n * 1. Verifies the webhook signature using HMAC-SHA256\n * 2. Calls `revalidateTag()` for each tag in the payload\n * 3. Calls `revalidatePath()` if a path is included in the data\n * 4. Returns a JSON response with the revalidation results\n *\n * @param options - Configuration options\n * @returns A Next.js Route Handler function\n *\n * @example\n * ```ts\n * // app/api/revalidate/route.ts\n * import { createRevalidateHandler } from '@riverbankcms/sdk/next/revalidate';\n *\n * export const POST = createRevalidateHandler();\n * ```\n */\nexport function createRevalidateHandler(\n options: RevalidateHandlerOptions = {}\n): (request: Request) => Promise<Response> {\n return async function handleRevalidateRequest(request: Request): Promise<Response> {\n // Get webhook secret\n const secret = options.secret ?? process.env.RIVERBANK_WEBHOOK_SECRET;\n\n if (!secret) {\n console.error('[Riverbank] RIVERBANK_WEBHOOK_SECRET not configured');\n return Response.json(\n { error: 'Webhook secret not configured' },\n { status: 500 }\n );\n }\n\n // Read request body\n const body = await request.text();\n const signature = request.headers.get('x-riverbank-signature');\n\n // Verify signature\n if (!signature || !verifyWebhookSignature(body, signature, secret)) {\n return Response.json({ error: 'Invalid signature' }, { status: 401 });\n }\n\n // Parse and validate payload\n const parseResult = parseWebhookPayload(body);\n if (!parseResult.success) {\n return Response.json({ error: parseResult.error }, { status: 400 });\n }\n const payload = parseResult.payload;\n const revalidated: string[] = [];\n\n // Tag-based revalidation (preferred)\n if (payload.tags?.length) {\n for (const tag of payload.tags) {\n revalidateTag(tag);\n revalidated.push(`tag:${tag}`);\n }\n }\n\n // Path-based fallback (from data.path if present)\n const path = typeof payload.data?.path === 'string' ? payload.data.path : undefined;\n if (path) {\n revalidatePath(path);\n revalidated.push(`path:${path}`);\n }\n\n // Log revalidation\n if (revalidated.length > 0) {\n console.log(\n `[Riverbank] Revalidated: ${revalidated.join(', ')} (event: ${payload.event})`\n );\n }\n\n // Call optional callback\n if (options.onRevalidate) {\n options.onRevalidate(payload, revalidated);\n }\n\n return Response.json({\n revalidated: true,\n items: revalidated,\n event: payload.event,\n timestamp: Date.now(),\n });\n };\n}\n"],"mappings":";;;;;;;AA0BA,SAAS,eAAe,sBAAsB;AA2CvC,SAAS,wBACd,UAAoC,CAAC,GACI;AACzC,SAAO,eAAe,wBAAwB,SAAqC;AAEjF,UAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,cAAQ,MAAM,qDAAqD;AACnE,aAAO,SAAS;AAAA,QACd,EAAE,OAAO,gCAAgC;AAAA,QACzC,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,OAAO,MAAM,QAAQ,KAAK;AAChC,UAAM,YAAY,QAAQ,QAAQ,IAAI,uBAAuB;AAG7D,QAAI,CAAC,aAAa,CAAC,uBAAuB,MAAM,WAAW,MAAM,GAAG;AAClE,aAAO,SAAS,KAAK,EAAE,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACtE;AAGA,UAAM,cAAc,oBAAoB,IAAI;AAC5C,QAAI,CAAC,YAAY,SAAS;AACxB,aAAO,SAAS,KAAK,EAAE,OAAO,YAAY,MAAM,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACpE;AACA,UAAM,UAAU,YAAY;AAC5B,UAAM,cAAwB,CAAC;AAG/B,QAAI,QAAQ,MAAM,QAAQ;AACxB,iBAAW,OAAO,QAAQ,MAAM;AAC9B,sBAAc,GAAG;AACjB,oBAAY,KAAK,OAAO,GAAG,EAAE;AAAA,MAC/B;AAAA,IACF;AAGA,UAAM,OAAO,OAAO,QAAQ,MAAM,SAAS,WAAW,QAAQ,KAAK,OAAO;AAC1E,QAAI,MAAM;AACR,qBAAe,IAAI;AACnB,kBAAY,KAAK,QAAQ,IAAI,EAAE;AAAA,IACjC;AAGA,QAAI,YAAY,SAAS,GAAG;AAC1B,cAAQ;AAAA,QACN,4BAA4B,YAAY,KAAK,IAAI,CAAC,YAAY,QAAQ,KAAK;AAAA,MAC7E;AAAA,IACF;AAGA,QAAI,QAAQ,cAAc;AACxB,cAAQ,aAAa,SAAS,WAAW;AAAA,IAC3C;AAEA,WAAO,SAAS,KAAK;AAAA,MACnB,aAAa;AAAA,MACb,OAAO;AAAA,MACP,OAAO,QAAQ;AAAA,MACf,WAAW,KAAK,IAAI;AAAA,IACtB,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Tag generation helpers for Next.js cache invalidation
3
+ *
4
+ * These helpers generate consistent cache tags for use with Next.js
5
+ * `unstable_cache` and `revalidateTag` APIs.
6
+ *
7
+ * Tag naming convention:
8
+ * - `riverbank` - Global tag that invalidates ALL Riverbank data
9
+ * - `riverbank:<resource>` - Collection tag (e.g., `riverbank:pages`)
10
+ * - `riverbank:<resource>:<id>` - Specific resource tag (e.g., `riverbank:page:page-123`)
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * // Consumer site: lib/cms-fetchers.ts
15
+ * import { unstable_cache } from 'next/cache';
16
+ * import { loadPage } from '@riverbankcms/sdk';
17
+ * import { getPageTags } from '@riverbankcms/sdk/next/tags';
18
+ *
19
+ * export const getCachedPage = unstable_cache(
20
+ * async (path: string) => loadPage({ client, siteId, path }),
21
+ * ['riverbank-page'],
22
+ * { tags: getPageTags(), revalidate: 300 }
23
+ * );
24
+ * ```
25
+ */
26
+ /**
27
+ * Global tag that invalidates ALL Riverbank data.
28
+ * Revalidating this tag will refresh everything.
29
+ *
30
+ * NOTE: This constant is also defined in apps/dashboard/src/lib/webhooks/dispatch.ts.
31
+ * If you change this value, update both locations.
32
+ */
33
+ declare const RIVERBANK_GLOBAL_TAG = "riverbank";
34
+ /**
35
+ * Generate tags for site-level data (settings, theme).
36
+ *
37
+ * @returns Array of tags: ['riverbank', 'riverbank:site']
38
+ */
39
+ declare function getSiteTags(): string[];
40
+ /**
41
+ * Generate tags for page data.
42
+ *
43
+ * @param pageId - Optional specific page ID to include
44
+ * @returns Array of tags including global, pages collection, and optionally page-specific
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * getPageTags() // ['riverbank', 'riverbank:pages']
49
+ * getPageTags('page-123') // ['riverbank', 'riverbank:pages', 'riverbank:page:page-123']
50
+ * ```
51
+ */
52
+ declare function getPageTags(pageId?: string): string[];
53
+ /**
54
+ * Generate tags for content entries.
55
+ *
56
+ * @param contentTypeSlug - The content type slug (e.g., 'blog-post', 'event')
57
+ * @param entryId - Optional specific entry ID to include
58
+ * @returns Array of tags including global, content-type, and optionally entry-specific
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * getEntryTags('blog-post') // ['riverbank', 'riverbank:content-type:blog-post']
63
+ * getEntryTags('blog-post', 'entry-456') // ['riverbank', 'riverbank:content-type:blog-post', 'riverbank:entry:entry-456']
64
+ * ```
65
+ */
66
+ declare function getEntryTags(contentTypeSlug: string, entryId?: string): string[];
67
+ /**
68
+ * Generate tags for navigation menus.
69
+ *
70
+ * @param menuKey - Optional specific menu key to include
71
+ * @returns Array of tags including global, navigation collection, and optionally menu-specific
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * getNavigationTags() // ['riverbank', 'riverbank:navigation']
76
+ * getNavigationTags('main') // ['riverbank', 'riverbank:navigation', 'riverbank:navigation:main']
77
+ * ```
78
+ */
79
+ declare function getNavigationTags(menuKey?: string): string[];
80
+
81
+ export { RIVERBANK_GLOBAL_TAG, getEntryTags, getNavigationTags, getPageTags, getSiteTags };
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Tag generation helpers for Next.js cache invalidation
3
+ *
4
+ * These helpers generate consistent cache tags for use with Next.js
5
+ * `unstable_cache` and `revalidateTag` APIs.
6
+ *
7
+ * Tag naming convention:
8
+ * - `riverbank` - Global tag that invalidates ALL Riverbank data
9
+ * - `riverbank:<resource>` - Collection tag (e.g., `riverbank:pages`)
10
+ * - `riverbank:<resource>:<id>` - Specific resource tag (e.g., `riverbank:page:page-123`)
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * // Consumer site: lib/cms-fetchers.ts
15
+ * import { unstable_cache } from 'next/cache';
16
+ * import { loadPage } from '@riverbankcms/sdk';
17
+ * import { getPageTags } from '@riverbankcms/sdk/next/tags';
18
+ *
19
+ * export const getCachedPage = unstable_cache(
20
+ * async (path: string) => loadPage({ client, siteId, path }),
21
+ * ['riverbank-page'],
22
+ * { tags: getPageTags(), revalidate: 300 }
23
+ * );
24
+ * ```
25
+ */
26
+ /**
27
+ * Global tag that invalidates ALL Riverbank data.
28
+ * Revalidating this tag will refresh everything.
29
+ *
30
+ * NOTE: This constant is also defined in apps/dashboard/src/lib/webhooks/dispatch.ts.
31
+ * If you change this value, update both locations.
32
+ */
33
+ declare const RIVERBANK_GLOBAL_TAG = "riverbank";
34
+ /**
35
+ * Generate tags for site-level data (settings, theme).
36
+ *
37
+ * @returns Array of tags: ['riverbank', 'riverbank:site']
38
+ */
39
+ declare function getSiteTags(): string[];
40
+ /**
41
+ * Generate tags for page data.
42
+ *
43
+ * @param pageId - Optional specific page ID to include
44
+ * @returns Array of tags including global, pages collection, and optionally page-specific
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * getPageTags() // ['riverbank', 'riverbank:pages']
49
+ * getPageTags('page-123') // ['riverbank', 'riverbank:pages', 'riverbank:page:page-123']
50
+ * ```
51
+ */
52
+ declare function getPageTags(pageId?: string): string[];
53
+ /**
54
+ * Generate tags for content entries.
55
+ *
56
+ * @param contentTypeSlug - The content type slug (e.g., 'blog-post', 'event')
57
+ * @param entryId - Optional specific entry ID to include
58
+ * @returns Array of tags including global, content-type, and optionally entry-specific
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * getEntryTags('blog-post') // ['riverbank', 'riverbank:content-type:blog-post']
63
+ * getEntryTags('blog-post', 'entry-456') // ['riverbank', 'riverbank:content-type:blog-post', 'riverbank:entry:entry-456']
64
+ * ```
65
+ */
66
+ declare function getEntryTags(contentTypeSlug: string, entryId?: string): string[];
67
+ /**
68
+ * Generate tags for navigation menus.
69
+ *
70
+ * @param menuKey - Optional specific menu key to include
71
+ * @returns Array of tags including global, navigation collection, and optionally menu-specific
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * getNavigationTags() // ['riverbank', 'riverbank:navigation']
76
+ * getNavigationTags('main') // ['riverbank', 'riverbank:navigation', 'riverbank:navigation:main']
77
+ * ```
78
+ */
79
+ declare function getNavigationTags(menuKey?: string): string[];
80
+
81
+ export { RIVERBANK_GLOBAL_TAG, getEntryTags, getNavigationTags, getPageTags, getSiteTags };
@@ -0,0 +1,36 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});require('../chunk-4CV4JOE5.js');
2
+
3
+ // src/next/tags.ts
4
+ var RIVERBANK_GLOBAL_TAG = "riverbank";
5
+ function getSiteTags() {
6
+ return [RIVERBANK_GLOBAL_TAG, "riverbank:site"];
7
+ }
8
+ function getPageTags(pageId) {
9
+ const tags = [RIVERBANK_GLOBAL_TAG, "riverbank:pages"];
10
+ if (pageId) {
11
+ tags.push(`riverbank:page:${pageId}`);
12
+ }
13
+ return tags;
14
+ }
15
+ function getEntryTags(contentTypeSlug, entryId) {
16
+ const tags = [RIVERBANK_GLOBAL_TAG, `riverbank:content-type:${contentTypeSlug}`];
17
+ if (entryId) {
18
+ tags.push(`riverbank:entry:${entryId}`);
19
+ }
20
+ return tags;
21
+ }
22
+ function getNavigationTags(menuKey) {
23
+ const tags = [RIVERBANK_GLOBAL_TAG, "riverbank:navigation"];
24
+ if (menuKey) {
25
+ tags.push(`riverbank:navigation:${menuKey}`);
26
+ }
27
+ return tags;
28
+ }
29
+
30
+
31
+
32
+
33
+
34
+
35
+ exports.RIVERBANK_GLOBAL_TAG = RIVERBANK_GLOBAL_TAG; exports.getEntryTags = getEntryTags; exports.getNavigationTags = getNavigationTags; exports.getPageTags = getPageTags; exports.getSiteTags = getSiteTags;
36
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/next/tags.js","../../../src/next/tags.ts"],"names":[],"mappings":"AAAA,yGAA6B;AAC7B;AACA;AC+BO,IAAM,qBAAA,EAAuB,WAAA;AAO7B,SAAS,WAAA,CAAA,EAAwB;AACtC,EAAA,OAAO,CAAC,oBAAA,EAAsB,gBAAgB,CAAA;AAChD;AAcO,SAAS,WAAA,CAAY,MAAA,EAA2B;AACrD,EAAA,MAAM,KAAA,EAAO,CAAC,oBAAA,EAAsB,iBAAiB,CAAA;AACrD,EAAA,GAAA,CAAI,MAAA,EAAQ;AACV,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,eAAA,EAAkB,MAAM,CAAA,CAAA;AACpC,EAAA;AACO,EAAA;AACT;AAesD;AAChB,EAAA;AACvB,EAAA;AACkB,IAAA;AAC/B,EAAA;AACO,EAAA;AACT;AAc8D;AACxB,EAAA;AACvB,EAAA;AACuB,IAAA;AACpC,EAAA;AACO,EAAA;AACT;AD3EuC;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/next/tags.js","sourcesContent":[null,"/**\n * Tag generation helpers for Next.js cache invalidation\n *\n * These helpers generate consistent cache tags for use with Next.js\n * `unstable_cache` and `revalidateTag` APIs.\n *\n * Tag naming convention:\n * - `riverbank` - Global tag that invalidates ALL Riverbank data\n * - `riverbank:<resource>` - Collection tag (e.g., `riverbank:pages`)\n * - `riverbank:<resource>:<id>` - Specific resource tag (e.g., `riverbank:page:page-123`)\n *\n * @example\n * ```tsx\n * // Consumer site: lib/cms-fetchers.ts\n * import { unstable_cache } from 'next/cache';\n * import { loadPage } from '@riverbankcms/sdk';\n * import { getPageTags } from '@riverbankcms/sdk/next/tags';\n *\n * export const getCachedPage = unstable_cache(\n * async (path: string) => loadPage({ client, siteId, path }),\n * ['riverbank-page'],\n * { tags: getPageTags(), revalidate: 300 }\n * );\n * ```\n */\n\n/**\n * Global tag that invalidates ALL Riverbank data.\n * Revalidating this tag will refresh everything.\n *\n * NOTE: This constant is also defined in apps/dashboard/src/lib/webhooks/dispatch.ts.\n * If you change this value, update both locations.\n */\nexport const RIVERBANK_GLOBAL_TAG = 'riverbank';\n\n/**\n * Generate tags for site-level data (settings, theme).\n *\n * @returns Array of tags: ['riverbank', 'riverbank:site']\n */\nexport function getSiteTags(): string[] {\n return [RIVERBANK_GLOBAL_TAG, 'riverbank:site'];\n}\n\n/**\n * Generate tags for page data.\n *\n * @param pageId - Optional specific page ID to include\n * @returns Array of tags including global, pages collection, and optionally page-specific\n *\n * @example\n * ```ts\n * getPageTags() // ['riverbank', 'riverbank:pages']\n * getPageTags('page-123') // ['riverbank', 'riverbank:pages', 'riverbank:page:page-123']\n * ```\n */\nexport function getPageTags(pageId?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, 'riverbank:pages'];\n if (pageId) {\n tags.push(`riverbank:page:${pageId}`);\n }\n return tags;\n}\n\n/**\n * Generate tags for content entries.\n *\n * @param contentTypeSlug - The content type slug (e.g., 'blog-post', 'event')\n * @param entryId - Optional specific entry ID to include\n * @returns Array of tags including global, content-type, and optionally entry-specific\n *\n * @example\n * ```ts\n * getEntryTags('blog-post') // ['riverbank', 'riverbank:content-type:blog-post']\n * getEntryTags('blog-post', 'entry-456') // ['riverbank', 'riverbank:content-type:blog-post', 'riverbank:entry:entry-456']\n * ```\n */\nexport function getEntryTags(contentTypeSlug: string, entryId?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, `riverbank:content-type:${contentTypeSlug}`];\n if (entryId) {\n tags.push(`riverbank:entry:${entryId}`);\n }\n return tags;\n}\n\n/**\n * Generate tags for navigation menus.\n *\n * @param menuKey - Optional specific menu key to include\n * @returns Array of tags including global, navigation collection, and optionally menu-specific\n *\n * @example\n * ```ts\n * getNavigationTags() // ['riverbank', 'riverbank:navigation']\n * getNavigationTags('main') // ['riverbank', 'riverbank:navigation', 'riverbank:navigation:main']\n * ```\n */\nexport function getNavigationTags(menuKey?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, 'riverbank:navigation'];\n if (menuKey) {\n tags.push(`riverbank:navigation:${menuKey}`);\n }\n return tags;\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import "../chunk-NFEGQTCC.mjs";
2
+
3
+ // src/next/tags.ts
4
+ var RIVERBANK_GLOBAL_TAG = "riverbank";
5
+ function getSiteTags() {
6
+ return [RIVERBANK_GLOBAL_TAG, "riverbank:site"];
7
+ }
8
+ function getPageTags(pageId) {
9
+ const tags = [RIVERBANK_GLOBAL_TAG, "riverbank:pages"];
10
+ if (pageId) {
11
+ tags.push(`riverbank:page:${pageId}`);
12
+ }
13
+ return tags;
14
+ }
15
+ function getEntryTags(contentTypeSlug, entryId) {
16
+ const tags = [RIVERBANK_GLOBAL_TAG, `riverbank:content-type:${contentTypeSlug}`];
17
+ if (entryId) {
18
+ tags.push(`riverbank:entry:${entryId}`);
19
+ }
20
+ return tags;
21
+ }
22
+ function getNavigationTags(menuKey) {
23
+ const tags = [RIVERBANK_GLOBAL_TAG, "riverbank:navigation"];
24
+ if (menuKey) {
25
+ tags.push(`riverbank:navigation:${menuKey}`);
26
+ }
27
+ return tags;
28
+ }
29
+ export {
30
+ RIVERBANK_GLOBAL_TAG,
31
+ getEntryTags,
32
+ getNavigationTags,
33
+ getPageTags,
34
+ getSiteTags
35
+ };
36
+ //# sourceMappingURL=tags.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/next/tags.ts"],"sourcesContent":["/**\n * Tag generation helpers for Next.js cache invalidation\n *\n * These helpers generate consistent cache tags for use with Next.js\n * `unstable_cache` and `revalidateTag` APIs.\n *\n * Tag naming convention:\n * - `riverbank` - Global tag that invalidates ALL Riverbank data\n * - `riverbank:<resource>` - Collection tag (e.g., `riverbank:pages`)\n * - `riverbank:<resource>:<id>` - Specific resource tag (e.g., `riverbank:page:page-123`)\n *\n * @example\n * ```tsx\n * // Consumer site: lib/cms-fetchers.ts\n * import { unstable_cache } from 'next/cache';\n * import { loadPage } from '@riverbankcms/sdk';\n * import { getPageTags } from '@riverbankcms/sdk/next/tags';\n *\n * export const getCachedPage = unstable_cache(\n * async (path: string) => loadPage({ client, siteId, path }),\n * ['riverbank-page'],\n * { tags: getPageTags(), revalidate: 300 }\n * );\n * ```\n */\n\n/**\n * Global tag that invalidates ALL Riverbank data.\n * Revalidating this tag will refresh everything.\n *\n * NOTE: This constant is also defined in apps/dashboard/src/lib/webhooks/dispatch.ts.\n * If you change this value, update both locations.\n */\nexport const RIVERBANK_GLOBAL_TAG = 'riverbank';\n\n/**\n * Generate tags for site-level data (settings, theme).\n *\n * @returns Array of tags: ['riverbank', 'riverbank:site']\n */\nexport function getSiteTags(): string[] {\n return [RIVERBANK_GLOBAL_TAG, 'riverbank:site'];\n}\n\n/**\n * Generate tags for page data.\n *\n * @param pageId - Optional specific page ID to include\n * @returns Array of tags including global, pages collection, and optionally page-specific\n *\n * @example\n * ```ts\n * getPageTags() // ['riverbank', 'riverbank:pages']\n * getPageTags('page-123') // ['riverbank', 'riverbank:pages', 'riverbank:page:page-123']\n * ```\n */\nexport function getPageTags(pageId?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, 'riverbank:pages'];\n if (pageId) {\n tags.push(`riverbank:page:${pageId}`);\n }\n return tags;\n}\n\n/**\n * Generate tags for content entries.\n *\n * @param contentTypeSlug - The content type slug (e.g., 'blog-post', 'event')\n * @param entryId - Optional specific entry ID to include\n * @returns Array of tags including global, content-type, and optionally entry-specific\n *\n * @example\n * ```ts\n * getEntryTags('blog-post') // ['riverbank', 'riverbank:content-type:blog-post']\n * getEntryTags('blog-post', 'entry-456') // ['riverbank', 'riverbank:content-type:blog-post', 'riverbank:entry:entry-456']\n * ```\n */\nexport function getEntryTags(contentTypeSlug: string, entryId?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, `riverbank:content-type:${contentTypeSlug}`];\n if (entryId) {\n tags.push(`riverbank:entry:${entryId}`);\n }\n return tags;\n}\n\n/**\n * Generate tags for navigation menus.\n *\n * @param menuKey - Optional specific menu key to include\n * @returns Array of tags including global, navigation collection, and optionally menu-specific\n *\n * @example\n * ```ts\n * getNavigationTags() // ['riverbank', 'riverbank:navigation']\n * getNavigationTags('main') // ['riverbank', 'riverbank:navigation', 'riverbank:navigation:main']\n * ```\n */\nexport function getNavigationTags(menuKey?: string): string[] {\n const tags = [RIVERBANK_GLOBAL_TAG, 'riverbank:navigation'];\n if (menuKey) {\n tags.push(`riverbank:navigation:${menuKey}`);\n }\n return tags;\n}\n"],"mappings":";;;AAiCO,IAAM,uBAAuB;AAO7B,SAAS,cAAwB;AACtC,SAAO,CAAC,sBAAsB,gBAAgB;AAChD;AAcO,SAAS,YAAY,QAA2B;AACrD,QAAM,OAAO,CAAC,sBAAsB,iBAAiB;AACrD,MAAI,QAAQ;AACV,SAAK,KAAK,kBAAkB,MAAM,EAAE;AAAA,EACtC;AACA,SAAO;AACT;AAeO,SAAS,aAAa,iBAAyB,SAA4B;AAChF,QAAM,OAAO,CAAC,sBAAsB,0BAA0B,eAAe,EAAE;AAC/E,MAAI,SAAS;AACX,SAAK,KAAK,mBAAmB,OAAO,EAAE;AAAA,EACxC;AACA,SAAO;AACT;AAcO,SAAS,kBAAkB,SAA4B;AAC5D,QAAM,OAAO,CAAC,sBAAsB,sBAAsB;AAC1D,MAAI,SAAS;AACX,SAAK,KAAK,wBAAwB,OAAO,EAAE;AAAA,EAC7C;AACA,SAAO;AACT;","names":[]}
@@ -1,11 +1,11 @@
1
1
  import { ReactNode, ComponentType } from 'react';
2
- import { R as RiverbankClient } from './types-1cLz0vnq.mjs';
2
+ import { R as RiverbankClient } from './types-C-LShyIg.mjs';
3
3
  import { R as RiverbankSiteConfig } from './types-BjgZt8xJ.mjs';
4
- import { B as BlockOverrides } from './loadPage-B8mQUUSo.mjs';
4
+ import { B as BlockOverrides } from './loadPage-BucnLHmE.mjs';
5
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';
6
+ import { M as Metadata } from './index--Oyunk_B.mjs';
7
+ import { b as LoadContentResult } from './loadContent-DVfuBLiZ.mjs';
8
+ import './types-BSV6Vc-P.mjs';
9
9
  import '@riverbankcms/ai';
10
10
  import 'zod';
11
11
  import './link-DjxLyC82.mjs';
@@ -271,4 +271,162 @@ interface CreateCatchAllPageResult {
271
271
  */
272
272
  declare function createCatchAllPage(options: CreateCatchAllPageOptions): CreateCatchAllPageResult;
273
273
 
274
- export { type CatchAllContext, type CatchAllPageProps, type CreateCatchAllPageOptions, type CreateCatchAllPageResult, createCatchAllPage };
274
+ /**
275
+ * Static params generation for Next.js SSG
276
+ *
277
+ * Provides helpers for generating static params from published CMS routes.
278
+ *
279
+ * @example
280
+ * ```tsx
281
+ * // app/[[...slug]]/page.tsx
282
+ * import { generateAllStaticParams } from '@riverbankcms/sdk/next';
283
+ *
284
+ * export { generateAllStaticParams as generateStaticParams };
285
+ * ```
286
+ */
287
+ /**
288
+ * Environment variable validation result
289
+ */
290
+ type StaticParamsEnvResult = {
291
+ valid: true;
292
+ config: {
293
+ apiKey: string;
294
+ siteId: string;
295
+ baseUrl: string;
296
+ };
297
+ } | {
298
+ valid: false;
299
+ missingVars: string[];
300
+ };
301
+ /**
302
+ * Validate that all required environment variables are set.
303
+ *
304
+ * Required env vars:
305
+ * - RIVERBANK_API_KEY: API key for published content
306
+ * - RIVERBANK_SITE_ID: Site ID
307
+ * - NEXT_PUBLIC_DASHBOARD_URL: Dashboard API URL
308
+ *
309
+ * @returns Validation result with config or missing vars
310
+ */
311
+ declare function validateStaticParamsEnv(): StaticParamsEnvResult;
312
+ /**
313
+ * Convert a route path to a Next.js slug array.
314
+ *
315
+ * @param path - The route path (e.g., '/about', '/blog/post')
316
+ * @returns The slug array for Next.js catch-all route
317
+ *
318
+ * @example
319
+ * ```ts
320
+ * pathToSlugArray('/') // []
321
+ * pathToSlugArray('/about') // ['about']
322
+ * pathToSlugArray('/blog/post') // ['blog', 'post']
323
+ * ```
324
+ */
325
+ declare function pathToSlugArray(path: string): string[];
326
+ /**
327
+ * Generate static params for all published routes.
328
+ *
329
+ * This function fetches all published routes from the CMS and converts them
330
+ * to the static params format expected by Next.js catch-all routes.
331
+ *
332
+ * Requires environment variables:
333
+ * - RIVERBANK_API_KEY: API key for published content
334
+ * - RIVERBANK_SITE_ID: Site ID
335
+ * - NEXT_PUBLIC_DASHBOARD_URL: Dashboard API URL
336
+ *
337
+ * @throws Error if required env vars are missing (prevents silent empty SSG in CI)
338
+ * @returns Array of static params objects for Next.js
339
+ *
340
+ * @example
341
+ * ```tsx
342
+ * // app/[[...slug]]/page.tsx
343
+ * import { generateAllStaticParams } from '@riverbankcms/sdk/next';
344
+ *
345
+ * export { generateAllStaticParams as generateStaticParams };
346
+ *
347
+ * // Or with custom logic:
348
+ * export async function generateStaticParams() {
349
+ * const params = await generateAllStaticParams();
350
+ * // Filter or modify params as needed
351
+ * return params.filter(p => !p.slug.includes('private'));
352
+ * }
353
+ * ```
354
+ */
355
+ declare function generateAllStaticParams(): Promise<{
356
+ slug: string[];
357
+ }[]>;
358
+
359
+ /**
360
+ * Next.js integration helpers for Riverbank CMS SDK.
361
+ *
362
+ * Provides opinionated factories for common Next.js patterns, reducing
363
+ * boilerplate while maintaining full customizability through escape hatches.
364
+ *
365
+ * @example Basic catch-all page
366
+ * ```tsx
367
+ * // src/app/[[...slug]]/page.tsx
368
+ * import { createCatchAllPage } from '@riverbankcms/sdk/next';
369
+ * import { getRiverbankClient } from '@/lib/builder-client';
370
+ * import config from '@/riverbank.config';
371
+ *
372
+ * const { Page, generateMetadata } = createCatchAllPage({
373
+ * getClient: getRiverbankClient,
374
+ * config,
375
+ * });
376
+ *
377
+ * export default Page;
378
+ * export { generateMetadata };
379
+ * ```
380
+ *
381
+ * @example With customization
382
+ * ```tsx
383
+ * const { Page, generateMetadata } = createCatchAllPage({
384
+ * getClient,
385
+ * config,
386
+ * blockOverrides: { hero: MyCustomHero },
387
+ * beforeRender: async () => {
388
+ * if (process.env.MAINTENANCE_MODE === 'true') {
389
+ * return <MaintenancePage />;
390
+ * }
391
+ * return null;
392
+ * },
393
+ * });
394
+ * ```
395
+ *
396
+ * @packageDocumentation
397
+ */
398
+
399
+ /**
400
+ * ISR revalidation duration in seconds for production mode.
401
+ * 5 minutes provides a good balance between freshness and performance.
402
+ */
403
+ declare const ISR_REVALIDATE_SECONDS = 300;
404
+ interface ISRConfig {
405
+ /**
406
+ * Revalidation interval in seconds.
407
+ * - 0: Dynamic rendering (no caching) - used in preview mode
408
+ * - 300: 5 minute ISR - used in production mode
409
+ */
410
+ revalidate: number | false;
411
+ /**
412
+ * Whether the current environment is in preview mode.
413
+ * Useful for conditional rendering or data fetching behavior.
414
+ */
415
+ isPreview: boolean;
416
+ }
417
+ /**
418
+ * Get ISR configuration based on the current environment.
419
+ *
420
+ * @example
421
+ * ```tsx
422
+ * // app/[[...slug]]/page.tsx
423
+ * import { getISRConfig } from '@riverbankcms/sdk/next';
424
+ *
425
+ * export const revalidate = getISRConfig().revalidate;
426
+ * ```
427
+ *
428
+ * @returns ISR configuration with revalidate interval and preview flag
429
+ */
430
+ declare function getISRConfig(): ISRConfig;
431
+
432
+ export { type CatchAllContext, type CatchAllPageProps, type CreateCatchAllPageOptions, type CreateCatchAllPageResult, type ISRConfig, ISR_REVALIDATE_SECONDS, type StaticParamsEnvResult, createCatchAllPage, generateAllStaticParams, getISRConfig, pathToSlugArray, validateStaticParamsEnv };