@riverbankcms/sdk 0.1.0 → 0.2.1

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 (176) hide show
  1. package/dist/cli/index.js +4840 -9
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/client/bookings.d.mts +82 -2
  4. package/dist/client/bookings.d.ts +82 -2
  5. package/dist/client/bookings.js +1623 -3
  6. package/dist/client/bookings.js.map +1 -1
  7. package/dist/client/bookings.mjs +1610 -5
  8. package/dist/client/bookings.mjs.map +1 -1
  9. package/dist/client/client.d.mts +8 -5
  10. package/dist/client/client.d.ts +8 -5
  11. package/dist/client/client.js +16856 -322
  12. package/dist/client/client.js.map +1 -1
  13. package/dist/client/client.mjs +16838 -307
  14. package/dist/client/client.mjs.map +1 -1
  15. package/dist/client/hooks.d.mts +10 -7
  16. package/dist/client/hooks.d.ts +10 -7
  17. package/dist/client/hooks.js +5074 -4
  18. package/dist/client/hooks.js.map +1 -1
  19. package/dist/client/hooks.mjs +5074 -4
  20. package/dist/client/hooks.mjs.map +1 -1
  21. package/dist/client/rendering/client.d.mts +7 -1
  22. package/dist/client/rendering/client.d.ts +7 -1
  23. package/dist/client/rendering/client.js +17388 -2
  24. package/dist/client/rendering/client.js.map +1 -1
  25. package/dist/client/rendering/client.mjs +17382 -2
  26. package/dist/client/rendering/client.mjs.map +1 -1
  27. package/dist/client/resolver-BhueZVxZ.d.mts +61 -0
  28. package/dist/client/resolver-BhueZVxZ.d.ts +61 -0
  29. package/dist/client/usePage-BBcFCxOU.d.ts +6297 -0
  30. package/dist/client/usePage-BydHcMYB.d.mts +6297 -0
  31. package/dist/server/Layout-CLg8oH_S.d.ts +44 -0
  32. package/dist/server/Layout-DK_9OOgb.d.mts +44 -0
  33. package/dist/server/chunk-3J46ILMJ.mjs +2111 -0
  34. package/dist/server/chunk-3J46ILMJ.mjs.map +1 -0
  35. package/dist/server/{chunk-JB4LIEFS.js → chunk-5R4NMVXA.js} +15 -8
  36. package/dist/server/chunk-5R4NMVXA.js.map +1 -0
  37. package/dist/server/{chunk-ADREPXFU.js → chunk-62ZJI564.js} +3 -3
  38. package/dist/server/{chunk-ADREPXFU.js.map → chunk-62ZJI564.js.map} +1 -1
  39. package/dist/server/chunk-7DS4Q3GA.mjs +333 -0
  40. package/dist/server/chunk-7DS4Q3GA.mjs.map +1 -0
  41. package/dist/server/chunk-BJTO5JO5.mjs +11 -0
  42. package/dist/server/{chunk-4Z5FBFRL.mjs → chunk-BPKYRPCQ.mjs} +7 -3
  43. package/dist/server/{chunk-4Z5FBFRL.mjs.map → chunk-BPKYRPCQ.mjs.map} +1 -1
  44. package/dist/server/chunk-DGUM43GV.js +11 -0
  45. package/dist/server/chunk-DGUM43GV.js.map +1 -0
  46. package/dist/server/chunk-EGTDJ4PL.js +5461 -0
  47. package/dist/server/chunk-EGTDJ4PL.js.map +1 -0
  48. package/dist/server/chunk-FK64TZBT.mjs +831 -0
  49. package/dist/server/chunk-FK64TZBT.mjs.map +1 -0
  50. package/dist/server/chunk-GKYNDDJS.js +2111 -0
  51. package/dist/server/chunk-GKYNDDJS.js.map +1 -0
  52. package/dist/server/chunk-HOY77YBF.js +333 -0
  53. package/dist/server/chunk-HOY77YBF.js.map +1 -0
  54. package/dist/server/chunk-INWKF3IC.js +831 -0
  55. package/dist/server/chunk-INWKF3IC.js.map +1 -0
  56. package/dist/server/{chunk-2RW5HAQQ.mjs → chunk-JTAERCX2.mjs} +2 -2
  57. package/dist/server/chunk-O5DC7MYW.mjs +9606 -0
  58. package/dist/server/chunk-O5DC7MYW.mjs.map +1 -0
  59. package/dist/server/{chunk-PEAXKTDU.mjs → chunk-OP2GHK27.mjs} +2 -2
  60. package/dist/server/{chunk-WKG57P2H.mjs → chunk-PN3CHDVX.mjs} +10 -3
  61. package/dist/server/{chunk-WKG57P2H.mjs.map → chunk-PN3CHDVX.mjs.map} +1 -1
  62. package/dist/server/chunk-SF63XAX7.js +9606 -0
  63. package/dist/server/chunk-SF63XAX7.js.map +1 -0
  64. package/dist/server/{chunk-F472SMKX.js → chunk-TO7FD6TQ.js} +4 -4
  65. package/dist/server/{chunk-F472SMKX.js.map → chunk-TO7FD6TQ.js.map} +1 -1
  66. package/dist/server/chunk-USQF2XTU.mjs +5461 -0
  67. package/dist/server/chunk-USQF2XTU.mjs.map +1 -0
  68. package/dist/server/{chunk-SW7LE4M3.js → chunk-XLVL5WPH.js} +12 -8
  69. package/dist/server/chunk-XLVL5WPH.js.map +1 -0
  70. package/dist/server/components-BzdA6NAc.d.mts +305 -0
  71. package/dist/server/components-DhIcstww.d.ts +305 -0
  72. package/dist/server/components.d.mts +13 -49
  73. package/dist/server/components.d.ts +13 -49
  74. package/dist/server/components.js +7 -4
  75. package/dist/server/components.js.map +1 -1
  76. package/dist/server/components.mjs +9 -6
  77. package/dist/server/components.mjs.map +1 -1
  78. package/dist/server/config-validation.d.mts +2 -2
  79. package/dist/server/config-validation.d.ts +2 -2
  80. package/dist/server/config-validation.js +6 -3
  81. package/dist/server/config-validation.js.map +1 -1
  82. package/dist/server/config-validation.mjs +5 -2
  83. package/dist/server/config.d.mts +3 -3
  84. package/dist/server/config.d.ts +3 -3
  85. package/dist/server/config.js +6 -3
  86. package/dist/server/config.js.map +1 -1
  87. package/dist/server/config.mjs +5 -2
  88. package/dist/server/config.mjs.map +1 -1
  89. package/dist/server/data.d.mts +9 -8
  90. package/dist/server/data.d.ts +9 -8
  91. package/dist/server/data.js +4 -2
  92. package/dist/server/data.js.map +1 -1
  93. package/dist/server/data.mjs +3 -1
  94. package/dist/server/{index-C6M0Wfjq.d.ts → index-BB28KAui.d.ts} +1 -1
  95. package/dist/server/{index-B0yI_V6Z.d.mts → index-C_FVup_o.d.mts} +1 -1
  96. package/dist/server/index.d.mts +1554 -5
  97. package/dist/server/index.d.ts +1554 -5
  98. package/dist/server/index.js +4 -4
  99. package/dist/server/index.js.map +1 -1
  100. package/dist/server/index.mjs +4 -4
  101. package/dist/server/index.mjs.map +1 -1
  102. package/dist/server/{loadContent-CJcbYF3J.d.ts → loadContent-AQOBf_gP.d.ts} +4 -4
  103. package/dist/server/{loadContent-zhlL4YSE.d.mts → loadContent-DBmprsB4.d.mts} +4 -4
  104. package/dist/server/loadPage-3ECPF426.js +11 -0
  105. package/dist/server/loadPage-3ECPF426.js.map +1 -0
  106. package/dist/server/{loadPage-CCf15nt8.d.mts → loadPage-BMg8PJxJ.d.ts} +146 -5
  107. package/dist/server/loadPage-LW273NYO.mjs +11 -0
  108. package/dist/server/loadPage-LW273NYO.mjs.map +1 -0
  109. package/dist/server/{loadPage-BYmVMk0V.d.ts → loadPage-pg4HimlK.d.mts} +146 -5
  110. package/dist/server/metadata.d.mts +9 -6
  111. package/dist/server/metadata.d.ts +9 -6
  112. package/dist/server/metadata.js +3 -1
  113. package/dist/server/metadata.js.map +1 -1
  114. package/dist/server/metadata.mjs +2 -0
  115. package/dist/server/metadata.mjs.map +1 -1
  116. package/dist/server/rendering/server.d.mts +9 -7
  117. package/dist/server/rendering/server.d.ts +9 -7
  118. package/dist/server/rendering/server.js +7 -4
  119. package/dist/server/rendering/server.js.map +1 -1
  120. package/dist/server/rendering/server.mjs +6 -3
  121. package/dist/server/rendering.d.mts +172 -9
  122. package/dist/server/rendering.d.ts +172 -9
  123. package/dist/server/rendering.js +12 -9
  124. package/dist/server/rendering.js.map +1 -1
  125. package/dist/server/rendering.mjs +14 -11
  126. package/dist/server/rendering.mjs.map +1 -1
  127. package/dist/server/routing.d.mts +9 -6
  128. package/dist/server/routing.d.ts +9 -6
  129. package/dist/server/routing.js +4 -2
  130. package/dist/server/routing.js.map +1 -1
  131. package/dist/server/routing.mjs +3 -1
  132. package/dist/server/routing.mjs.map +1 -1
  133. package/dist/server/schema-Bpy9N5ZI.d.mts +1870 -0
  134. package/dist/server/schema-Bpy9N5ZI.d.ts +1870 -0
  135. package/dist/server/server.d.mts +11 -8
  136. package/dist/server/server.d.ts +11 -8
  137. package/dist/server/server.js +7 -5
  138. package/dist/server/server.js.map +1 -1
  139. package/dist/server/server.mjs +6 -4
  140. package/dist/server/theme-bridge.js +13 -10
  141. package/dist/server/theme-bridge.js.map +1 -1
  142. package/dist/server/theme-bridge.mjs +10 -7
  143. package/dist/server/theme-bridge.mjs.map +1 -1
  144. package/dist/server/theme.js +3 -1
  145. package/dist/server/theme.js.map +1 -1
  146. package/dist/server/theme.mjs +2 -0
  147. package/dist/server/theme.mjs.map +1 -1
  148. package/dist/server/{types-BCeqWtI2.d.ts → types--u4GLCAY.d.ts} +1 -1
  149. package/dist/server/types-BprgZt-t.d.ts +4149 -0
  150. package/dist/server/types-C0G9IxWO.d.mts +4149 -0
  151. package/dist/server/{types-Bbo01M7P.d.mts → types-_nDnPHpv.d.mts} +27 -1
  152. package/dist/server/{types-Bbo01M7P.d.ts → types-_nDnPHpv.d.ts} +27 -1
  153. package/dist/server/{types-BCeqWtI2.d.mts → types-_zWJTgv0.d.mts} +1 -1
  154. package/package.json +15 -15
  155. package/dist/server/chunk-3KKZVGH4.mjs +0 -179
  156. package/dist/server/chunk-3KKZVGH4.mjs.map +0 -1
  157. package/dist/server/chunk-4Z3GPTCS.js +0 -179
  158. package/dist/server/chunk-4Z3GPTCS.js.map +0 -1
  159. package/dist/server/chunk-JB4LIEFS.js.map +0 -1
  160. package/dist/server/chunk-QQ6U4QX6.js +0 -120
  161. package/dist/server/chunk-QQ6U4QX6.js.map +0 -1
  162. package/dist/server/chunk-R5YGLRUG.mjs +0 -122
  163. package/dist/server/chunk-R5YGLRUG.mjs.map +0 -1
  164. package/dist/server/chunk-SW7LE4M3.js.map +0 -1
  165. package/dist/server/chunk-W3K7LVPS.mjs +0 -120
  166. package/dist/server/chunk-W3K7LVPS.mjs.map +0 -1
  167. package/dist/server/chunk-YHEZMVTS.js +0 -122
  168. package/dist/server/chunk-YHEZMVTS.js.map +0 -1
  169. package/dist/server/loadPage-DVH3DW6E.js +0 -9
  170. package/dist/server/loadPage-DVH3DW6E.js.map +0 -1
  171. package/dist/server/loadPage-PHQZ6XQZ.mjs +0 -9
  172. package/dist/server/types-C6gmRHLe.d.mts +0 -150
  173. package/dist/server/types-C6gmRHLe.d.ts +0 -150
  174. /package/dist/server/{loadPage-PHQZ6XQZ.mjs.map → chunk-BJTO5JO5.mjs.map} +0 -0
  175. /package/dist/server/{chunk-2RW5HAQQ.mjs.map → chunk-JTAERCX2.mjs.map} +0 -0
  176. /package/dist/server/{chunk-PEAXKTDU.mjs.map → chunk-OP2GHK27.mjs.map} +0 -0
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Data loading types for block prefetching.
3
+ * Shared between frontend and SDK implementations.
4
+ */
5
+
6
+ /**
7
+ * Context for prefetching block data
8
+ */
9
+ type PrefetchContext = {
10
+ siteId?: string;
11
+ pageId?: string;
12
+ previewStage?: 'published' | 'preview';
13
+ };
14
+ /**
15
+ * Resolved block data keyed by block ID and loader key
16
+ *
17
+ * Example:
18
+ * {
19
+ * 'block-123': {
20
+ * 'posts': [...],
21
+ * 'categories': [...]
22
+ * }
23
+ * }
24
+ */
25
+ type ResolvedBlockData = Record<string, Record<string, unknown>>;
26
+
1
27
  /**
2
28
  * Code-based data loader types for SDK custom blocks.
3
29
  *
@@ -73,4 +99,4 @@ type BlockLoaderMap = Record<string, DataLoaderFn>;
73
99
  */
74
100
  type DataLoaderOverrides = Record<string, BlockLoaderMap>;
75
101
 
76
- export type { BlockLoaderMap as B, DataLoaderOverrides as D, DataLoaderContext as a, DataLoaderFn as b };
102
+ export type { BlockLoaderMap as B, DataLoaderOverrides as D, PrefetchContext as P, ResolvedBlockData as R, DataLoaderContext as a, DataLoaderFn as b };
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Data loading types for block prefetching.
3
+ * Shared between frontend and SDK implementations.
4
+ */
5
+
6
+ /**
7
+ * Context for prefetching block data
8
+ */
9
+ type PrefetchContext = {
10
+ siteId?: string;
11
+ pageId?: string;
12
+ previewStage?: 'published' | 'preview';
13
+ };
14
+ /**
15
+ * Resolved block data keyed by block ID and loader key
16
+ *
17
+ * Example:
18
+ * {
19
+ * 'block-123': {
20
+ * 'posts': [...],
21
+ * 'categories': [...]
22
+ * }
23
+ * }
24
+ */
25
+ type ResolvedBlockData = Record<string, Record<string, unknown>>;
26
+
1
27
  /**
2
28
  * Code-based data loader types for SDK custom blocks.
3
29
  *
@@ -73,4 +99,4 @@ type BlockLoaderMap = Record<string, DataLoaderFn>;
73
99
  */
74
100
  type DataLoaderOverrides = Record<string, BlockLoaderMap>;
75
101
 
76
- export type { BlockLoaderMap as B, DataLoaderOverrides as D, DataLoaderContext as a, DataLoaderFn as b };
102
+ export type { BlockLoaderMap as B, DataLoaderOverrides as D, PrefetchContext as P, ResolvedBlockData as R, DataLoaderContext as a, DataLoaderFn as b };
@@ -1,4 +1,4 @@
1
- import { SdkCustomBlock, FieldDefinition } from '@riverbankcms/blocks';
1
+ import { S as SdkCustomBlock, F as FieldDefinition } from './schema-Bpy9N5ZI.mjs';
2
2
 
3
3
  /**
4
4
  * SDK Site Configuration Types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riverbankcms/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Riverbank CMS SDK for headless content consumption",
5
5
  "main": "./dist/server/index.js",
6
6
  "module": "./dist/server/index.mjs",
@@ -101,18 +101,7 @@
101
101
  "src/styles",
102
102
  "README.md"
103
103
  ],
104
- "scripts": {
105
- "build": "tsup",
106
- "dev": "tsup --watch",
107
- "typecheck": "tsc --noEmit",
108
- "lint": "eslint src",
109
- "test": "vitest run",
110
- "verify": "pnpm test"
111
- },
112
104
  "dependencies": {
113
- "@riverbankcms/api": "workspace:*",
114
- "@riverbankcms/blocks": "workspace:*",
115
- "@riverbankcms/site-renderer": "workspace:*",
116
105
  "commander": "^12.1.0",
117
106
  "jiti": "^2.6.1",
118
107
  "zod": "^4.1.1"
@@ -128,7 +117,10 @@
128
117
  "eslint": "^9.15.0",
129
118
  "tsup": "^8.3.5",
130
119
  "typescript": "^5.6.3",
131
- "vitest": "^1.6.1"
120
+ "vitest": "^1.6.1",
121
+ "@riverbankcms/api": "0.1.0",
122
+ "@riverbankcms/site-renderer": "0.1.0",
123
+ "@riverbankcms/blocks": "0.1.0"
132
124
  },
133
125
  "repository": {
134
126
  "type": "git",
@@ -143,5 +135,13 @@
143
135
  "sdk"
144
136
  ],
145
137
  "license": "MIT",
146
- "private": false
147
- }
138
+ "private": false,
139
+ "scripts": {
140
+ "build": "tsup",
141
+ "dev": "tsup --watch",
142
+ "typecheck": "tsc --noEmit",
143
+ "lint": "eslint src",
144
+ "test": "vitest run",
145
+ "verify": "pnpm test"
146
+ }
147
+ }
@@ -1,179 +0,0 @@
1
- // src/client/index.ts
2
- import { createBearerAPIClient } from "@riverbankcms/api";
3
-
4
- // src/client/cache.ts
5
- var SimpleCache = class {
6
- constructor(options = {}) {
7
- this.cache = /* @__PURE__ */ new Map();
8
- this.maxSize = options.maxSize ?? 100;
9
- this.ttl = options.ttl ?? 3e5;
10
- }
11
- get(key) {
12
- const entry = this.cache.get(key);
13
- if (!entry) return void 0;
14
- if (Date.now() > entry.expires) {
15
- this.cache.delete(key);
16
- return void 0;
17
- }
18
- return entry.value;
19
- }
20
- set(key, value) {
21
- if (this.cache.size >= this.maxSize) {
22
- const firstKey = this.cache.keys().next().value;
23
- if (firstKey) {
24
- this.cache.delete(firstKey);
25
- }
26
- }
27
- this.cache.set(key, {
28
- value,
29
- expires: Date.now() + this.ttl
30
- });
31
- }
32
- clear() {
33
- this.cache.clear();
34
- }
35
- has(key) {
36
- return this.get(key) !== void 0;
37
- }
38
- };
39
-
40
- // src/client/index.ts
41
- function createRiverbankClient(config) {
42
- if (!config.baseUrl) {
43
- throw new Error(
44
- "baseUrl is required when creating a Builder client. Expected format: https://dashboard.example.com/api (must include /api path)"
45
- );
46
- }
47
- if (!config.baseUrl.endsWith("/api")) {
48
- throw new Error(
49
- `baseUrl must end with '/api'. Received: ${config.baseUrl}. Expected format: https://dashboard.example.com/api`
50
- );
51
- }
52
- const cacheEnabled = config.cache?.enabled ?? true;
53
- const cacheTTL = (config.cache?.ttl ?? 300) * 1e3;
54
- const cacheMaxSize = config.cache?.maxSize ?? 100;
55
- const apiClient = createBearerAPIClient(config.apiKey, config.baseUrl);
56
- const cache = new SimpleCache({
57
- maxSize: cacheMaxSize,
58
- ttl: cacheTTL
59
- });
60
- async function cachedFetch(cacheKey, fetcher, options) {
61
- if (cacheEnabled && !options?.force) {
62
- const cached = cache.get(cacheKey);
63
- if (cached !== void 0) {
64
- return cached;
65
- }
66
- }
67
- const data = await fetcher();
68
- if (cacheEnabled) {
69
- cache.set(cacheKey, data);
70
- }
71
- return data;
72
- }
73
- return {
74
- async getSite(params) {
75
- const { slug, domain, id } = params;
76
- if (!slug && !domain && !id) {
77
- throw new Error(
78
- `getSite() requires at least one identifier: slug, domain, or id. Received: ${JSON.stringify(params)}`
79
- );
80
- }
81
- const cacheKey = `site:${slug || domain || id}`;
82
- return cachedFetch(cacheKey, async () => {
83
- const apiParams = {};
84
- if (params.slug) apiParams.slug = params.slug;
85
- if (params.domain) apiParams.domain = params.domain;
86
- if (params.id) apiParams.id = params.id;
87
- return await apiClient({ endpoint: "getSite", params: apiParams });
88
- });
89
- },
90
- async getPage(params) {
91
- const { siteId, path, preview = false } = params;
92
- const cacheKey = `page:${siteId}:${path}:${preview}`;
93
- return cachedFetch(cacheKey, async () => {
94
- return await apiClient({ endpoint: "getContentByPath", params: { siteId }, body: { path, preview } });
95
- });
96
- },
97
- async getEntries(params) {
98
- const { siteId, contentType, limit, order, preview = false, mode, entryIds } = params;
99
- const entryIdsCacheKey = mode === "manual" && entryIds?.length ? entryIds.join(",") : "";
100
- const cacheKey = `entries:${siteId}:${contentType}:${limit ?? ""}:${order ?? ""}:${preview}:${mode ?? ""}:${entryIdsCacheKey}`;
101
- return cachedFetch(cacheKey, async () => {
102
- const apiParams = {
103
- siteId,
104
- type: contentType
105
- };
106
- if (typeof limit === "number") {
107
- apiParams.limit = String(limit);
108
- }
109
- if (order === "newest") {
110
- apiParams.order = "published_at.desc";
111
- } else if (order === "oldest") {
112
- apiParams.order = "published_at.asc";
113
- } else if (order === "title") {
114
- apiParams.order = "title.asc";
115
- }
116
- if (preview) {
117
- apiParams.stage = "preview";
118
- }
119
- if (mode === "manual" && entryIds?.length) {
120
- apiParams.mode = "manual";
121
- apiParams.entryIds = JSON.stringify(entryIds);
122
- }
123
- return await apiClient({ endpoint: "listPublishedEntries", params: apiParams });
124
- });
125
- },
126
- async getEntry(params) {
127
- const { siteId, contentType, slug } = params;
128
- const cacheKey = `entry:${siteId}:${contentType}:${slug}`;
129
- return cachedFetch(cacheKey, async () => {
130
- return await apiClient({ endpoint: "getPublishedEntryPreview", params: { siteId, type: contentType, slug } });
131
- });
132
- },
133
- async getPublicFormById(params) {
134
- const { formId } = params;
135
- if (!formId) {
136
- throw new Error("getPublicFormById() requires formId");
137
- }
138
- const cacheKey = `public-form:${formId}`;
139
- return cachedFetch(cacheKey, async () => {
140
- return await apiClient({ endpoint: "getPublicFormById", params: { formId } });
141
- });
142
- },
143
- async getPublicBookingServices(params) {
144
- const { siteId, ids } = params;
145
- if (!siteId) {
146
- throw new Error("getPublicBookingServices() requires siteId");
147
- }
148
- const cacheKey = `public-booking-services:${siteId}:${ids ?? ""}`;
149
- return cachedFetch(cacheKey, async () => {
150
- const apiParams = { siteId };
151
- if (ids) apiParams.ids = ids;
152
- return await apiClient({ endpoint: "getPublicBookingServices", params: apiParams });
153
- });
154
- },
155
- async listPublicEvents(params) {
156
- const { siteId, limit, from, to, stage } = params;
157
- if (!siteId) {
158
- throw new Error("listPublicEvents() requires siteId");
159
- }
160
- const cacheKey = `public-events:${siteId}:${limit ?? ""}:${from ?? ""}:${to ?? ""}:${stage ?? ""}`;
161
- return cachedFetch(cacheKey, async () => {
162
- const apiParams = { siteId };
163
- if (typeof limit === "number") apiParams.limit = String(limit);
164
- if (from) apiParams.from = from;
165
- if (to) apiParams.to = to;
166
- if (stage) apiParams.stage = stage;
167
- return await apiClient({ endpoint: "listPublicEvents", params: apiParams });
168
- });
169
- },
170
- clearCache() {
171
- cache.clear();
172
- }
173
- };
174
- }
175
-
176
- export {
177
- createRiverbankClient
178
- };
179
- //# sourceMappingURL=chunk-3KKZVGH4.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/client/index.ts","../../src/client/cache.ts"],"sourcesContent":["import { createBearerAPIClient } from '@riverbankcms/api';\nimport type {\n RiverbankClient,\n RiverbankClientConfig,\n PublicBookingServicesResponse,\n PublicEventsResponse,\n PublicFormResponse,\n} from './types';\nimport { SimpleCache } from './cache';\n\n/**\n * Create a Riverbank CMS client for fetching content\n *\n * @example\n * ```ts\n * const client = createRiverbankClient({\n * apiKey: 'bld_live_sk_...',\n * baseUrl: 'https://dashboard.example.com/api',\n * });\n *\n * const site = await client.getSite({ slug: 'my-site' });\n * ```\n */\nexport function createRiverbankClient(config: RiverbankClientConfig): RiverbankClient {\n if (!config.baseUrl) {\n throw new Error(\n 'baseUrl is required when creating a Builder client. ' +\n 'Expected format: https://dashboard.example.com/api (must include /api path)'\n );\n }\n\n // Validate baseUrl format\n if (!config.baseUrl.endsWith('/api')) {\n throw new Error(\n `baseUrl must end with '/api'. Received: ${config.baseUrl}. ` +\n 'Expected format: https://dashboard.example.com/api'\n );\n }\n\n const cacheEnabled = config.cache?.enabled ?? true;\n const cacheTTL = (config.cache?.ttl ?? 300) * 1000; // Convert seconds to milliseconds\n const cacheMaxSize = config.cache?.maxSize ?? 100;\n\n // Create internal API client with Bearer token auth\n const apiClient = createBearerAPIClient(config.apiKey, config.baseUrl);\n\n // Create cache instance\n const cache = new SimpleCache<unknown>({\n maxSize: cacheMaxSize,\n ttl: cacheTTL,\n });\n\n /**\n * Helper to cache API calls\n */\n async function cachedFetch<T>(\n cacheKey: string,\n fetcher: () => Promise<T>,\n options?: { force?: boolean }\n ): Promise<T> {\n // Check cache unless force is true\n if (cacheEnabled && !options?.force) {\n const cached = cache.get(cacheKey) as T | undefined;\n if (cached !== undefined) {\n return cached;\n }\n }\n\n // Fetch fresh data\n const data = await fetcher();\n\n // Store in cache\n if (cacheEnabled) {\n cache.set(cacheKey, data);\n }\n\n return data;\n }\n\n return {\n async getSite(params) {\n const { slug, domain, id } = params;\n\n if (!slug && !domain && !id) {\n throw new Error(\n 'getSite() requires at least one identifier: slug, domain, or id. ' +\n `Received: ${JSON.stringify(params)}`\n );\n }\n\n const cacheKey = `site:${slug || domain || id}`;\n\n return cachedFetch(cacheKey, async () => {\n // Convert params to string record for API client\n const apiParams: Record<string, string> = {};\n if (params.slug) apiParams.slug = params.slug;\n if (params.domain) apiParams.domain = params.domain;\n if (params.id) apiParams.id = params.id;\n return await apiClient({ endpoint: 'getSite', params: apiParams });\n });\n },\n\n async getPage(params) {\n const { siteId, path, preview = false } = params;\n const cacheKey = `page:${siteId}:${path}:${preview}`;\n\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getContentByPath', params: { siteId }, body: { path, preview } });\n });\n },\n\n async getEntries(params) {\n const { siteId, contentType, limit, order, preview = false, mode, entryIds } = params;\n\n // Include all params in cache key to ensure different queries are cached separately\n const entryIdsCacheKey = mode === 'manual' && entryIds?.length ? entryIds.join(',') : '';\n const cacheKey = `entries:${siteId}:${contentType}:${limit ?? ''}:${order ?? ''}:${preview}:${mode ?? ''}:${entryIdsCacheKey}`;\n\n return cachedFetch(cacheKey, async () => {\n // Build API params\n const apiParams: Record<string, string> = {\n siteId,\n type: contentType,\n };\n\n // Add optional pagination\n if (typeof limit === 'number') {\n apiParams.limit = String(limit);\n }\n\n // Convert user-friendly order to API format\n // 'order' means custom ordering - we don't pass an order param (API default)\n if (order === 'newest') {\n apiParams.order = 'published_at.desc';\n } else if (order === 'oldest') {\n apiParams.order = 'published_at.asc';\n } else if (order === 'title') {\n apiParams.order = 'title.asc';\n }\n // 'order' or undefined: don't set order param, use API default\n\n // Add preview stage if enabled\n if (preview) {\n apiParams.stage = 'preview';\n }\n\n // Manual mode - pass entry IDs for hydration\n if (mode === 'manual' && entryIds?.length) {\n apiParams.mode = 'manual';\n apiParams.entryIds = JSON.stringify(entryIds);\n }\n\n return await apiClient({ endpoint: 'listPublishedEntries', params: apiParams });\n });\n },\n\n async getEntry(params) {\n const { siteId, contentType, slug } = params;\n const cacheKey = `entry:${siteId}:${contentType}:${slug}`;\n\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getPublishedEntryPreview', params: { siteId, type: contentType, slug } });\n });\n },\n\n async getPublicFormById(params) {\n const { formId } = params;\n if (!formId) {\n throw new Error('getPublicFormById() requires formId');\n }\n const cacheKey = `public-form:${formId}`;\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getPublicFormById', params: { formId } }) as PublicFormResponse;\n });\n },\n\n async getPublicBookingServices(params) {\n const { siteId, ids } = params;\n if (!siteId) {\n throw new Error('getPublicBookingServices() requires siteId');\n }\n const cacheKey = `public-booking-services:${siteId}:${ids ?? ''}`;\n return cachedFetch(cacheKey, async () => {\n const apiParams: Record<string, string> = { siteId };\n if (ids) apiParams.ids = ids;\n return await apiClient({ endpoint: 'getPublicBookingServices', params: apiParams }) as PublicBookingServicesResponse;\n });\n },\n\n async listPublicEvents(params) {\n const { siteId, limit, from, to, stage } = params;\n if (!siteId) {\n throw new Error('listPublicEvents() requires siteId');\n }\n const cacheKey = `public-events:${siteId}:${limit ?? ''}:${from ?? ''}:${to ?? ''}:${stage ?? ''}`;\n return cachedFetch(cacheKey, async () => {\n const apiParams: Record<string, string> = { siteId };\n if (typeof limit === 'number') apiParams.limit = String(limit);\n if (from) apiParams.from = from;\n if (to) apiParams.to = to;\n if (stage) apiParams.stage = stage;\n return await apiClient({ endpoint: 'listPublicEvents', params: apiParams }) as PublicEventsResponse;\n });\n },\n\n clearCache() {\n cache.clear();\n },\n };\n}\n\n// Re-export types\nexport type { RiverbankClient, RiverbankClientConfig } from './types';\n","/**\n * Simple in-memory cache with TTL support\n */\nexport class SimpleCache<T> {\n private cache = new Map<string, { value: T; expires: number }>();\n private maxSize: number;\n private ttl: number;\n\n constructor(options: { maxSize?: number; ttl?: number } = {}) {\n this.maxSize = options.maxSize ?? 100;\n this.ttl = options.ttl ?? 300000; // 5 minutes in milliseconds\n }\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n // Check if expired\n if (Date.now() > entry.expires) {\n this.cache.delete(key);\n return undefined;\n }\n\n return entry.value;\n }\n\n set(key: string, value: T): void {\n // Enforce max size with simple FIFO eviction\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expires: Date.now() + this.ttl,\n });\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n has(key: string): boolean {\n return this.get(key) !== undefined;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,179 +0,0 @@
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; }// src/client/index.ts
2
- var _api = require('@riverbankcms/api');
3
-
4
- // src/client/cache.ts
5
- var SimpleCache = class {
6
- constructor(options = {}) {
7
- this.cache = /* @__PURE__ */ new Map();
8
- this.maxSize = _nullishCoalesce(options.maxSize, () => ( 100));
9
- this.ttl = _nullishCoalesce(options.ttl, () => ( 3e5));
10
- }
11
- get(key) {
12
- const entry = this.cache.get(key);
13
- if (!entry) return void 0;
14
- if (Date.now() > entry.expires) {
15
- this.cache.delete(key);
16
- return void 0;
17
- }
18
- return entry.value;
19
- }
20
- set(key, value) {
21
- if (this.cache.size >= this.maxSize) {
22
- const firstKey = this.cache.keys().next().value;
23
- if (firstKey) {
24
- this.cache.delete(firstKey);
25
- }
26
- }
27
- this.cache.set(key, {
28
- value,
29
- expires: Date.now() + this.ttl
30
- });
31
- }
32
- clear() {
33
- this.cache.clear();
34
- }
35
- has(key) {
36
- return this.get(key) !== void 0;
37
- }
38
- };
39
-
40
- // src/client/index.ts
41
- function createRiverbankClient(config) {
42
- if (!config.baseUrl) {
43
- throw new Error(
44
- "baseUrl is required when creating a Builder client. Expected format: https://dashboard.example.com/api (must include /api path)"
45
- );
46
- }
47
- if (!config.baseUrl.endsWith("/api")) {
48
- throw new Error(
49
- `baseUrl must end with '/api'. Received: ${config.baseUrl}. Expected format: https://dashboard.example.com/api`
50
- );
51
- }
52
- const cacheEnabled = _nullishCoalesce(_optionalChain([config, 'access', _ => _.cache, 'optionalAccess', _2 => _2.enabled]), () => ( true));
53
- const cacheTTL = (_nullishCoalesce(_optionalChain([config, 'access', _3 => _3.cache, 'optionalAccess', _4 => _4.ttl]), () => ( 300))) * 1e3;
54
- const cacheMaxSize = _nullishCoalesce(_optionalChain([config, 'access', _5 => _5.cache, 'optionalAccess', _6 => _6.maxSize]), () => ( 100));
55
- const apiClient = _api.createBearerAPIClient.call(void 0, config.apiKey, config.baseUrl);
56
- const cache = new SimpleCache({
57
- maxSize: cacheMaxSize,
58
- ttl: cacheTTL
59
- });
60
- async function cachedFetch(cacheKey, fetcher, options) {
61
- if (cacheEnabled && !_optionalChain([options, 'optionalAccess', _7 => _7.force])) {
62
- const cached = cache.get(cacheKey);
63
- if (cached !== void 0) {
64
- return cached;
65
- }
66
- }
67
- const data = await fetcher();
68
- if (cacheEnabled) {
69
- cache.set(cacheKey, data);
70
- }
71
- return data;
72
- }
73
- return {
74
- async getSite(params) {
75
- const { slug, domain, id } = params;
76
- if (!slug && !domain && !id) {
77
- throw new Error(
78
- `getSite() requires at least one identifier: slug, domain, or id. Received: ${JSON.stringify(params)}`
79
- );
80
- }
81
- const cacheKey = `site:${slug || domain || id}`;
82
- return cachedFetch(cacheKey, async () => {
83
- const apiParams = {};
84
- if (params.slug) apiParams.slug = params.slug;
85
- if (params.domain) apiParams.domain = params.domain;
86
- if (params.id) apiParams.id = params.id;
87
- return await apiClient({ endpoint: "getSite", params: apiParams });
88
- });
89
- },
90
- async getPage(params) {
91
- const { siteId, path, preview = false } = params;
92
- const cacheKey = `page:${siteId}:${path}:${preview}`;
93
- return cachedFetch(cacheKey, async () => {
94
- return await apiClient({ endpoint: "getContentByPath", params: { siteId }, body: { path, preview } });
95
- });
96
- },
97
- async getEntries(params) {
98
- const { siteId, contentType, limit, order, preview = false, mode, entryIds } = params;
99
- const entryIdsCacheKey = mode === "manual" && _optionalChain([entryIds, 'optionalAccess', _8 => _8.length]) ? entryIds.join(",") : "";
100
- const cacheKey = `entries:${siteId}:${contentType}:${_nullishCoalesce(limit, () => ( ""))}:${_nullishCoalesce(order, () => ( ""))}:${preview}:${_nullishCoalesce(mode, () => ( ""))}:${entryIdsCacheKey}`;
101
- return cachedFetch(cacheKey, async () => {
102
- const apiParams = {
103
- siteId,
104
- type: contentType
105
- };
106
- if (typeof limit === "number") {
107
- apiParams.limit = String(limit);
108
- }
109
- if (order === "newest") {
110
- apiParams.order = "published_at.desc";
111
- } else if (order === "oldest") {
112
- apiParams.order = "published_at.asc";
113
- } else if (order === "title") {
114
- apiParams.order = "title.asc";
115
- }
116
- if (preview) {
117
- apiParams.stage = "preview";
118
- }
119
- if (mode === "manual" && _optionalChain([entryIds, 'optionalAccess', _9 => _9.length])) {
120
- apiParams.mode = "manual";
121
- apiParams.entryIds = JSON.stringify(entryIds);
122
- }
123
- return await apiClient({ endpoint: "listPublishedEntries", params: apiParams });
124
- });
125
- },
126
- async getEntry(params) {
127
- const { siteId, contentType, slug } = params;
128
- const cacheKey = `entry:${siteId}:${contentType}:${slug}`;
129
- return cachedFetch(cacheKey, async () => {
130
- return await apiClient({ endpoint: "getPublishedEntryPreview", params: { siteId, type: contentType, slug } });
131
- });
132
- },
133
- async getPublicFormById(params) {
134
- const { formId } = params;
135
- if (!formId) {
136
- throw new Error("getPublicFormById() requires formId");
137
- }
138
- const cacheKey = `public-form:${formId}`;
139
- return cachedFetch(cacheKey, async () => {
140
- return await apiClient({ endpoint: "getPublicFormById", params: { formId } });
141
- });
142
- },
143
- async getPublicBookingServices(params) {
144
- const { siteId, ids } = params;
145
- if (!siteId) {
146
- throw new Error("getPublicBookingServices() requires siteId");
147
- }
148
- const cacheKey = `public-booking-services:${siteId}:${_nullishCoalesce(ids, () => ( ""))}`;
149
- return cachedFetch(cacheKey, async () => {
150
- const apiParams = { siteId };
151
- if (ids) apiParams.ids = ids;
152
- return await apiClient({ endpoint: "getPublicBookingServices", params: apiParams });
153
- });
154
- },
155
- async listPublicEvents(params) {
156
- const { siteId, limit, from, to, stage } = params;
157
- if (!siteId) {
158
- throw new Error("listPublicEvents() requires siteId");
159
- }
160
- const cacheKey = `public-events:${siteId}:${_nullishCoalesce(limit, () => ( ""))}:${_nullishCoalesce(from, () => ( ""))}:${_nullishCoalesce(to, () => ( ""))}:${_nullishCoalesce(stage, () => ( ""))}`;
161
- return cachedFetch(cacheKey, async () => {
162
- const apiParams = { siteId };
163
- if (typeof limit === "number") apiParams.limit = String(limit);
164
- if (from) apiParams.from = from;
165
- if (to) apiParams.to = to;
166
- if (stage) apiParams.stage = stage;
167
- return await apiClient({ endpoint: "listPublicEvents", params: apiParams });
168
- });
169
- },
170
- clearCache() {
171
- cache.clear();
172
- }
173
- };
174
- }
175
-
176
-
177
-
178
- exports.createRiverbankClient = createRiverbankClient;
179
- //# sourceMappingURL=chunk-4Z3GPTCS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-4Z3GPTCS.js","../../src/client/index.ts","../../src/client/cache.ts"],"names":[],"mappings":"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","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-4Z3GPTCS.js","sourcesContent":[null,"import { createBearerAPIClient } from '@riverbankcms/api';\nimport type {\n RiverbankClient,\n RiverbankClientConfig,\n PublicBookingServicesResponse,\n PublicEventsResponse,\n PublicFormResponse,\n} from './types';\nimport { SimpleCache } from './cache';\n\n/**\n * Create a Riverbank CMS client for fetching content\n *\n * @example\n * ```ts\n * const client = createRiverbankClient({\n * apiKey: 'bld_live_sk_...',\n * baseUrl: 'https://dashboard.example.com/api',\n * });\n *\n * const site = await client.getSite({ slug: 'my-site' });\n * ```\n */\nexport function createRiverbankClient(config: RiverbankClientConfig): RiverbankClient {\n if (!config.baseUrl) {\n throw new Error(\n 'baseUrl is required when creating a Builder client. ' +\n 'Expected format: https://dashboard.example.com/api (must include /api path)'\n );\n }\n\n // Validate baseUrl format\n if (!config.baseUrl.endsWith('/api')) {\n throw new Error(\n `baseUrl must end with '/api'. Received: ${config.baseUrl}. ` +\n 'Expected format: https://dashboard.example.com/api'\n );\n }\n\n const cacheEnabled = config.cache?.enabled ?? true;\n const cacheTTL = (config.cache?.ttl ?? 300) * 1000; // Convert seconds to milliseconds\n const cacheMaxSize = config.cache?.maxSize ?? 100;\n\n // Create internal API client with Bearer token auth\n const apiClient = createBearerAPIClient(config.apiKey, config.baseUrl);\n\n // Create cache instance\n const cache = new SimpleCache<unknown>({\n maxSize: cacheMaxSize,\n ttl: cacheTTL,\n });\n\n /**\n * Helper to cache API calls\n */\n async function cachedFetch<T>(\n cacheKey: string,\n fetcher: () => Promise<T>,\n options?: { force?: boolean }\n ): Promise<T> {\n // Check cache unless force is true\n if (cacheEnabled && !options?.force) {\n const cached = cache.get(cacheKey) as T | undefined;\n if (cached !== undefined) {\n return cached;\n }\n }\n\n // Fetch fresh data\n const data = await fetcher();\n\n // Store in cache\n if (cacheEnabled) {\n cache.set(cacheKey, data);\n }\n\n return data;\n }\n\n return {\n async getSite(params) {\n const { slug, domain, id } = params;\n\n if (!slug && !domain && !id) {\n throw new Error(\n 'getSite() requires at least one identifier: slug, domain, or id. ' +\n `Received: ${JSON.stringify(params)}`\n );\n }\n\n const cacheKey = `site:${slug || domain || id}`;\n\n return cachedFetch(cacheKey, async () => {\n // Convert params to string record for API client\n const apiParams: Record<string, string> = {};\n if (params.slug) apiParams.slug = params.slug;\n if (params.domain) apiParams.domain = params.domain;\n if (params.id) apiParams.id = params.id;\n return await apiClient({ endpoint: 'getSite', params: apiParams });\n });\n },\n\n async getPage(params) {\n const { siteId, path, preview = false } = params;\n const cacheKey = `page:${siteId}:${path}:${preview}`;\n\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getContentByPath', params: { siteId }, body: { path, preview } });\n });\n },\n\n async getEntries(params) {\n const { siteId, contentType, limit, order, preview = false, mode, entryIds } = params;\n\n // Include all params in cache key to ensure different queries are cached separately\n const entryIdsCacheKey = mode === 'manual' && entryIds?.length ? entryIds.join(',') : '';\n const cacheKey = `entries:${siteId}:${contentType}:${limit ?? ''}:${order ?? ''}:${preview}:${mode ?? ''}:${entryIdsCacheKey}`;\n\n return cachedFetch(cacheKey, async () => {\n // Build API params\n const apiParams: Record<string, string> = {\n siteId,\n type: contentType,\n };\n\n // Add optional pagination\n if (typeof limit === 'number') {\n apiParams.limit = String(limit);\n }\n\n // Convert user-friendly order to API format\n // 'order' means custom ordering - we don't pass an order param (API default)\n if (order === 'newest') {\n apiParams.order = 'published_at.desc';\n } else if (order === 'oldest') {\n apiParams.order = 'published_at.asc';\n } else if (order === 'title') {\n apiParams.order = 'title.asc';\n }\n // 'order' or undefined: don't set order param, use API default\n\n // Add preview stage if enabled\n if (preview) {\n apiParams.stage = 'preview';\n }\n\n // Manual mode - pass entry IDs for hydration\n if (mode === 'manual' && entryIds?.length) {\n apiParams.mode = 'manual';\n apiParams.entryIds = JSON.stringify(entryIds);\n }\n\n return await apiClient({ endpoint: 'listPublishedEntries', params: apiParams });\n });\n },\n\n async getEntry(params) {\n const { siteId, contentType, slug } = params;\n const cacheKey = `entry:${siteId}:${contentType}:${slug}`;\n\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getPublishedEntryPreview', params: { siteId, type: contentType, slug } });\n });\n },\n\n async getPublicFormById(params) {\n const { formId } = params;\n if (!formId) {\n throw new Error('getPublicFormById() requires formId');\n }\n const cacheKey = `public-form:${formId}`;\n return cachedFetch(cacheKey, async () => {\n return await apiClient({ endpoint: 'getPublicFormById', params: { formId } }) as PublicFormResponse;\n });\n },\n\n async getPublicBookingServices(params) {\n const { siteId, ids } = params;\n if (!siteId) {\n throw new Error('getPublicBookingServices() requires siteId');\n }\n const cacheKey = `public-booking-services:${siteId}:${ids ?? ''}`;\n return cachedFetch(cacheKey, async () => {\n const apiParams: Record<string, string> = { siteId };\n if (ids) apiParams.ids = ids;\n return await apiClient({ endpoint: 'getPublicBookingServices', params: apiParams }) as PublicBookingServicesResponse;\n });\n },\n\n async listPublicEvents(params) {\n const { siteId, limit, from, to, stage } = params;\n if (!siteId) {\n throw new Error('listPublicEvents() requires siteId');\n }\n const cacheKey = `public-events:${siteId}:${limit ?? ''}:${from ?? ''}:${to ?? ''}:${stage ?? ''}`;\n return cachedFetch(cacheKey, async () => {\n const apiParams: Record<string, string> = { siteId };\n if (typeof limit === 'number') apiParams.limit = String(limit);\n if (from) apiParams.from = from;\n if (to) apiParams.to = to;\n if (stage) apiParams.stage = stage;\n return await apiClient({ endpoint: 'listPublicEvents', params: apiParams }) as PublicEventsResponse;\n });\n },\n\n clearCache() {\n cache.clear();\n },\n };\n}\n\n// Re-export types\nexport type { RiverbankClient, RiverbankClientConfig } from './types';\n","/**\n * Simple in-memory cache with TTL support\n */\nexport class SimpleCache<T> {\n private cache = new Map<string, { value: T; expires: number }>();\n private maxSize: number;\n private ttl: number;\n\n constructor(options: { maxSize?: number; ttl?: number } = {}) {\n this.maxSize = options.maxSize ?? 100;\n this.ttl = options.ttl ?? 300000; // 5 minutes in milliseconds\n }\n\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n // Check if expired\n if (Date.now() > entry.expires) {\n this.cache.delete(key);\n return undefined;\n }\n\n return entry.value;\n }\n\n set(key: string, value: T): void {\n // Enforce max size with simple FIFO eviction\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expires: Date.now() + this.ttl,\n });\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n has(key: string): boolean {\n return this.get(key) !== undefined;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-JB4LIEFS.js","../../src/rendering/components/Block.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACA;ACGA,8CAA8G;AAsGxG,+CAAA;AAhBN,MAAA,SAAsB,KAAA,CAAM;AAAA,EAC1B,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA,EAAiB,iBAAA,EAAmB,KAAA;AAAA,EACpC,QAAA,EAAU;AACZ,CAAA,EAAe;AAEb,EAAA,MAAM,WAAA,EAAa,wCAAA,SAA4B,CAAA;AAC/C,EAAA,GAAA,CAAI,CAAC,WAAA,GAAc,CAAC,iBAAA,EAAmB;AACrC,IAAA,uBACE,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,6CAAA,EACb,QAAA,kBAAA,8BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,MAAA,sBAAA;AAAA,MAAqB;AAAA,IAAA,EAAA,CAAU,EAAA,CAC3E,CAAA;AAAA,EAEJ;AAGA,EAAA,MAAM,aAAA,EAAe,uCAAA,KAAuB,CAAA;AAG5C,EAAA,IAAI,YAAA;AACJ,EAAA,GAAA,CAAI,OAAA,GAAU,QAAA,GAAW,UAAA,EAAY;AACnC,IAAA,MAAM,YAAA,EAAc;AAAA,MAClB,IAAA,EAAM,cAAA;AAAA,MACN,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,eAAA;AAAA,MACT,MAAA,EAAQ,CAAC;AAAA,QACP,EAAA,EAAI,OAAA;AAAA,QACJ,IAAA,EAAM,SAAA;AAAA,QACN,OAAA,EAAS;AAAA,MACX,CAAC;AAAA,IACH,CAAA;AAEA,IAAA,MAAM,gBAAA,EAAkB,MAAM,gDAAA;AAAA,MAC5B,WAAA;AAAA,MACA,EAAE,MAAA,EAAQ,MAAA,EAAQ,aAAa,CAAA;AAAA,MAC/B;AAAA,IACF,CAAA;AAEA,IAAA,aAAA,EAAe,eAAA,CAAgB,OAAO,CAAA;AAAA,EACxC;AAGA,EAAA,GAAA,CAAI,iBAAA,EAAmB;AACrB,IAAA,uBACE,6BAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,KAAA,EAAO,YAAA,CAAa,MAAA;AAAA,QACpB,WAAA,EAAa,KAAA;AAAA,QACb,IAAA,EAAM,YAAA;AAAA,QACN,OAAA,mBAAS,OAAA,UAAW,MAAA;AAAA,QACpB;AAAA,MAAA;AAAA,IACF,CAAA;AAAA,EAEJ;AAGA,EAAA,GAAA,CAAI,CAAC,UAAA,EAAY;AACf,IAAA,uBACE,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,6CAAA,EACb,QAAA,kBAAA,8BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,MAAA,sBAAA;AAAA,MAAqB;AAAA,IAAA,EAAA,CAAU,EAAA,CAC3E,CAAA;AAAA,EAEJ;AAGA,EAAA,MAAM,eAAA,EAAiB,+CAAA,EAA4B,QAAA,EAAU,UAAA,CAAW,SAAS,CAAC,CAAA;AAGlF,EAAA,MAAM,SAAA,EAAW,iDAAA,CAA4B;AAE7C,EAAA,uBACE,6BAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,OAAA,mBAAS,OAAA,UAAW,KAAA,GAAA;AAAA,MACpB,SAAA;AAAA,MACA,KAAA,EAAO,YAAA,CAAa,MAAA;AAAA,MACpB,WAAA,EAAa,KAAA;AAAA,MACb,OAAA;AAAA,MACA,IAAA,EAAM,YAAA;AAAA,MACN;AAAA,IAAA;AAAA,EACF,CAAA;AAEJ;ADrGA;AACA;AACE;AACF,sBAAC","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-JB4LIEFS.js","sourcesContent":[null,"/**\n * Block component for rendering individual CMS blocks\n *\n * Renders a single block with its content and data.\n */\n\nimport * as React from 'react';\nimport { getBlockDefinition, makeDefaultBlockComponent, buildThemeRuntime, getDefaultComponentRegistry } from '@riverbankcms/blocks';\nimport type { Theme } from '@riverbankcms/blocks';\nimport type { RiverbankClient } from '../../client/types';\nimport { prefetchBlockData } from '../../data/prefetchBlockData';\n\n/**\n * Override component for custom block rendering.\n * Receives the same props as default block components.\n */\nexport type BlockOverrideComponent = React.ComponentType<{\n content: Record<string, unknown>;\n theme?: Record<string, unknown>;\n themeConfig?: Theme;\n data?: Record<string, unknown>;\n blockId?: string | null;\n blockKind?: string;\n}>;\n\nexport type BlockProps = {\n // Block identification\n blockKind: string;\n blockId?: string | null;\n\n // Block content\n content: Record<string, unknown>;\n\n // Required styling\n theme: Theme;\n siteId: string;\n\n // Optional data context for loaders\n pageId?: string;\n previewStage?: 'published' | 'preview';\n client?: RiverbankClient;\n\n // Optional customization\n usePlaceholders?: boolean;\n\n /**\n * Custom component to override default block rendering.\n * When provided, renders this component instead of the manifest-based default.\n * This is SSR-safe - no context or hooks required.\n *\n * @example\n * ```tsx\n * <Block\n * blockKind=\"block.hero\"\n * content={heroContent}\n * theme={theme}\n * siteId={siteId}\n * override={MyCustomHero}\n * />\n * ```\n */\n override?: BlockOverrideComponent;\n};\n\n/**\n * Renders a single CMS block with optional data loading.\n *\n * Use this component when you want to render individual blocks outside of a full page context,\n * or when mixing CMS blocks with custom JSX.\n *\n * @example Basic usage\n * ```tsx\n * <Block\n * blockKind=\"block.hero\"\n * content={{ headline: 'Welcome', subheadline: 'To our site' }}\n * theme={theme}\n * siteId=\"site-123\"\n * />\n * ```\n *\n * @example With data loading\n * ```tsx\n * <Block\n * blockKind=\"block.blog-listing\"\n * blockId=\"block-456\"\n * content={blockContent}\n * theme={theme}\n * siteId=\"site-123\"\n * pageId=\"page-789\"\n * client={client}\n * />\n * ```\n */\nexport async function Block({\n blockKind,\n blockId,\n content,\n theme,\n siteId,\n pageId,\n previewStage,\n client,\n usePlaceholders: _usePlaceholders = false,\n override: OverrideComponent,\n}: BlockProps) {\n // Get block definition (needed for data loaders even if using override)\n const definition = getBlockDefinition(blockKind);\n if (!definition && !OverrideComponent) {\n return (\n <div className=\"p-4 border border-red-300 bg-red-50 rounded\">\n <p className=\"text-red-800 font-semibold\">Unknown block type: {blockKind}</p>\n </div>\n );\n }\n\n // Build theme tokens\n const themeRuntime = buildThemeRuntime(theme);\n\n // Prefetch block data if client is provided and block has an ID\n let resolvedData: Record<string, unknown> | undefined;\n if (client && blockId && definition) {\n const pageOutline = {\n name: 'Single Block',\n path: '/block',\n purpose: 'Block preview',\n blocks: [{\n id: blockId,\n kind: blockKind,\n purpose: 'preview',\n }],\n };\n\n const allResolvedData = await prefetchBlockData(\n pageOutline,\n { siteId, pageId, previewStage },\n client\n );\n\n resolvedData = allResolvedData[blockId];\n }\n\n // If override component provided, use it instead of manifest-based rendering\n if (OverrideComponent) {\n return (\n <OverrideComponent\n content={content}\n theme={themeRuntime.tokens}\n themeConfig={theme}\n data={resolvedData}\n blockId={blockId ?? null}\n blockKind={blockKind}\n />\n );\n }\n\n // Fallback to manifest-based rendering\n if (!definition) {\n return (\n <div className=\"p-4 border border-red-300 bg-red-50 rounded\">\n <p className=\"text-red-800 font-semibold\">Unknown block type: {blockKind}</p>\n </div>\n );\n }\n\n // Create block component from manifest\n const BlockComponent = makeDefaultBlockComponent({ manifest: definition.manifest });\n\n // Get default component registry\n const registry = getDefaultComponentRegistry();\n\n return (\n <BlockComponent\n blockId={blockId ?? undefined}\n blockKind={blockKind}\n theme={themeRuntime.tokens}\n themeConfig={theme}\n content={content}\n data={resolvedData}\n registry={registry}\n />\n );\n}\n"]}