@riverbankcms/sdk 0.4.3 → 0.5.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 (178) hide show
  1. package/README.md +84 -0
  2. package/dist/cli/index.js +3463 -120
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/analytics.js +1 -1
  5. package/dist/client/analytics.js.map +1 -1
  6. package/dist/client/analytics.mjs +1 -1
  7. package/dist/client/analytics.mjs.map +1 -1
  8. package/dist/client/bookings.js +6 -6
  9. package/dist/client/bookings.js.map +1 -1
  10. package/dist/client/bookings.mjs +6 -6
  11. package/dist/client/bookings.mjs.map +1 -1
  12. package/dist/client/client.d.mts +2 -2
  13. package/dist/client/client.d.ts +2 -2
  14. package/dist/client/client.js +1379 -519
  15. package/dist/client/client.js.map +1 -1
  16. package/dist/client/client.mjs +1379 -519
  17. package/dist/client/client.mjs.map +1 -1
  18. package/dist/client/hooks.d.mts +2 -2
  19. package/dist/client/hooks.d.ts +2 -2
  20. package/dist/client/hooks.js +26 -11
  21. package/dist/client/hooks.js.map +1 -1
  22. package/dist/client/hooks.mjs +26 -11
  23. package/dist/client/hooks.mjs.map +1 -1
  24. package/dist/client/rendering/client.js +20 -14
  25. package/dist/client/rendering/client.js.map +1 -1
  26. package/dist/client/rendering/client.mjs +20 -14
  27. package/dist/client/rendering/client.mjs.map +1 -1
  28. package/dist/client/usePage-BTPnCuWC.d.mts +6511 -0
  29. package/dist/client/usePage-BXjk8BhD.d.mts +6704 -0
  30. package/dist/client/usePage-BafOS9UT.d.mts +6512 -0
  31. package/dist/client/usePage-BiOReg0_.d.ts +6704 -0
  32. package/dist/client/usePage-Bnx-kA6x.d.mts +6670 -0
  33. package/dist/client/usePage-DoPI6b8V.d.ts +6511 -0
  34. package/dist/client/usePage-QNWArrVO.d.ts +6670 -0
  35. package/dist/client/usePage-fBgPB6Oq.d.ts +6512 -0
  36. package/dist/server/{Layout-CXI_VkhN.d.ts → Layout-BClXUTsd.d.mts} +4 -4
  37. package/dist/server/{Layout-p6f3TLw9.d.mts → Layout-UXGjXv8M.d.ts} +4 -4
  38. package/dist/server/{chunk-6JBKKV3G.js → chunk-2KCF2DNK.js} +30 -10
  39. package/dist/server/chunk-2KCF2DNK.js.map +1 -0
  40. package/dist/server/chunk-5STV4MWD.js +189 -0
  41. package/dist/server/chunk-5STV4MWD.js.map +1 -0
  42. package/dist/server/{chunk-VHDDXCK6.js → chunk-7UPVCT3K.js} +1206 -496
  43. package/dist/server/chunk-7UPVCT3K.js.map +1 -0
  44. package/dist/server/{chunk-7DS4Q3GA.mjs → chunk-AEFWG657.mjs} +3 -3
  45. package/dist/server/chunk-AEFWG657.mjs.map +1 -0
  46. package/dist/server/{chunk-USQF2XTU.mjs → chunk-BYBJA6SP.mjs} +26 -11
  47. package/dist/server/chunk-BYBJA6SP.mjs.map +1 -0
  48. package/dist/server/{chunk-ES6QDZUX.mjs → chunk-C6FIJC7T.mjs} +2 -2
  49. package/dist/server/{chunk-N3PX76AP.mjs → chunk-CMABGYGI.mjs} +269 -135
  50. package/dist/server/chunk-CMABGYGI.mjs.map +1 -0
  51. package/dist/server/{chunk-TO7FD6TQ.js → chunk-I2D7KOEA.js} +4 -4
  52. package/dist/server/{chunk-TO7FD6TQ.js.map → chunk-I2D7KOEA.js.map} +1 -1
  53. package/dist/server/{chunk-R5B6IOFQ.js → chunk-KA74YRK6.js} +269 -135
  54. package/dist/server/chunk-KA74YRK6.js.map +1 -0
  55. package/dist/server/chunk-KFLZGNPO.mjs +189 -0
  56. package/dist/server/chunk-KFLZGNPO.mjs.map +1 -0
  57. package/dist/server/chunk-L5EA4FXU.mjs +134 -0
  58. package/dist/server/chunk-L5EA4FXU.mjs.map +1 -0
  59. package/dist/server/{chunk-U2NI3TS3.mjs → chunk-LNOUXALA.mjs} +1135 -425
  60. package/dist/server/chunk-LNOUXALA.mjs.map +1 -0
  61. package/dist/server/{chunk-24F6FTCI.mjs → chunk-OSF34JTQ.mjs} +4 -4
  62. package/dist/server/{chunk-G35R7N7B.js → chunk-P3NNN73G.js} +3 -3
  63. package/dist/server/{chunk-G35R7N7B.js.map → chunk-P3NNN73G.js.map} +1 -1
  64. package/dist/server/{chunk-I6K5REFT.mjs → chunk-P4K63SBZ.mjs} +24 -4
  65. package/dist/server/chunk-P4K63SBZ.mjs.map +1 -0
  66. package/dist/server/{chunk-HOY77YBF.js → chunk-RVDS7VSP.js} +5 -5
  67. package/dist/server/chunk-RVDS7VSP.js.map +1 -0
  68. package/dist/server/{chunk-2SSEBAHC.js → chunk-TT5JWA4X.js} +9 -9
  69. package/dist/server/{chunk-2SSEBAHC.js.map → chunk-TT5JWA4X.js.map} +1 -1
  70. package/dist/server/chunk-VSFQRHYZ.js +134 -0
  71. package/dist/server/chunk-VSFQRHYZ.js.map +1 -0
  72. package/dist/server/{chunk-EGTDJ4PL.js → chunk-YYO3RIFO.js} +26 -11
  73. package/dist/server/chunk-YYO3RIFO.js.map +1 -0
  74. package/dist/server/{chunk-OP2GHK27.mjs → chunk-Z5ZA6Q4D.mjs} +2 -2
  75. package/dist/server/{components-Dhiemsjd.d.ts → components-BmaJxgCV.d.mts} +20 -75
  76. package/dist/server/{components-C75e4poV.d.mts → components-DppHY5oD.d.ts} +20 -75
  77. package/dist/server/components.d.mts +11 -8
  78. package/dist/server/components.d.ts +11 -8
  79. package/dist/server/components.js +5 -4
  80. package/dist/server/components.js.map +1 -1
  81. package/dist/server/components.mjs +4 -3
  82. package/dist/server/config-validation.d.mts +3 -3
  83. package/dist/server/config-validation.d.ts +3 -3
  84. package/dist/server/config-validation.js +9 -5
  85. package/dist/server/config-validation.js.map +1 -1
  86. package/dist/server/config-validation.mjs +8 -4
  87. package/dist/server/config.d.mts +243 -5
  88. package/dist/server/config.d.ts +243 -5
  89. package/dist/server/config.js +72 -5
  90. package/dist/server/config.js.map +1 -1
  91. package/dist/server/config.mjs +72 -5
  92. package/dist/server/config.mjs.map +1 -1
  93. package/dist/server/core-DsNWrl3o.d.mts +44 -0
  94. package/dist/server/core-DsNWrl3o.d.ts +44 -0
  95. package/dist/server/data.d.mts +4 -3
  96. package/dist/server/data.d.ts +4 -3
  97. package/dist/server/data.js +3 -3
  98. package/dist/server/data.mjs +2 -2
  99. package/dist/server/{index-CAwBj3-A.d.ts → index-Bucs6UqG.d.mts} +2 -1
  100. package/dist/server/{index-C6o9LPvq.d.mts → index-Cp7tJuRt.d.ts} +2 -1
  101. package/dist/server/index.d.mts +84 -6
  102. package/dist/server/index.d.ts +84 -6
  103. package/dist/server/index.js +91 -2
  104. package/dist/server/index.js.map +1 -1
  105. package/dist/server/index.mjs +90 -1
  106. package/dist/server/index.mjs.map +1 -1
  107. package/dist/server/link-DjxLyC82.d.mts +23 -0
  108. package/dist/server/link-DjxLyC82.d.ts +23 -0
  109. package/dist/server/{loadContent-CdXfuCuE.d.mts → loadContent-BS-3wesN.d.mts} +4 -4
  110. package/dist/server/{loadContent-CsvQRoxb.d.ts → loadContent-Buvmudee.d.ts} +4 -4
  111. package/dist/server/{loadPage-p3AWwwrd.d.mts → loadPage-B8mQUUSo.d.mts} +5 -46
  112. package/dist/server/loadPage-DNQTTRHL.mjs +11 -0
  113. package/dist/server/{loadPage-BA0HiT-6.d.ts → loadPage-DP3nrHBi.d.ts} +5 -46
  114. package/dist/server/loadPage-IDGVDFBB.js +11 -0
  115. package/dist/server/{loadPage-DLC7DJZP.js.map → loadPage-IDGVDFBB.js.map} +1 -1
  116. package/dist/server/metadata.d.mts +6 -4
  117. package/dist/server/metadata.d.ts +6 -4
  118. package/dist/server/navigation.d.mts +199 -29
  119. package/dist/server/navigation.d.ts +199 -29
  120. package/dist/server/navigation.js +27 -43
  121. package/dist/server/navigation.js.map +1 -1
  122. package/dist/server/navigation.mjs +20 -36
  123. package/dist/server/navigation.mjs.map +1 -1
  124. package/dist/server/rendering/server.d.mts +8 -6
  125. package/dist/server/rendering/server.d.ts +8 -6
  126. package/dist/server/rendering/server.js +7 -6
  127. package/dist/server/rendering/server.js.map +1 -1
  128. package/dist/server/rendering/server.mjs +6 -5
  129. package/dist/server/rendering.d.mts +14 -10
  130. package/dist/server/rendering.d.ts +14 -10
  131. package/dist/server/rendering.js +9 -8
  132. package/dist/server/rendering.js.map +1 -1
  133. package/dist/server/rendering.mjs +8 -7
  134. package/dist/server/richTextSchema-DURiozvD.d.mts +62 -0
  135. package/dist/server/richTextSchema-DURiozvD.d.ts +62 -0
  136. package/dist/server/routing.d.mts +178 -11
  137. package/dist/server/routing.d.ts +178 -11
  138. package/dist/server/routing.js +95 -2
  139. package/dist/server/routing.js.map +1 -1
  140. package/dist/server/routing.mjs +94 -1
  141. package/dist/server/routing.mjs.map +1 -1
  142. package/dist/server/{schema-Bpy9N5ZI.d.mts → schema-Z6-afHJG.d.mts} +1 -1
  143. package/dist/server/{schema-Bpy9N5ZI.d.ts → schema-Z6-afHJG.d.ts} +1 -1
  144. package/dist/server/server.d.mts +9 -7
  145. package/dist/server/server.d.ts +9 -7
  146. package/dist/server/server.js +6 -6
  147. package/dist/server/server.mjs +5 -5
  148. package/dist/server/theme-bridge.js +8 -8
  149. package/dist/server/theme-bridge.mjs +2 -2
  150. package/dist/server/{types-Dj8B3QRb.d.ts → types-1cLz0vnq.d.mts} +55 -2
  151. package/dist/server/{types-txWsSxN7.d.mts → types-BjgZt8xJ.d.mts} +63 -2
  152. package/dist/server/{types-CdhKJrB0.d.mts → types-BvcJU7zk.d.ts} +55 -2
  153. package/dist/server/{types-BWQ-TohG.d.ts → types-CVykEqXN.d.ts} +289 -83
  154. package/dist/server/{types-CL916r6x.d.ts → types-DLBhEPSt.d.ts} +63 -2
  155. package/dist/server/{types-BLf-hE50.d.mts → types-Dsu9wsUh.d.mts} +289 -83
  156. package/dist/server/{validation-DzvDwwRo.d.mts → validation-BGuRo8P1.d.mts} +18 -5
  157. package/dist/server/{validation-CoU8uAiu.d.ts → validation-DU2YE7u5.d.ts} +18 -5
  158. package/package.json +5 -1
  159. package/dist/server/chunk-6JBKKV3G.js.map +0 -1
  160. package/dist/server/chunk-7DS4Q3GA.mjs.map +0 -1
  161. package/dist/server/chunk-EGTDJ4PL.js.map +0 -1
  162. package/dist/server/chunk-HOY77YBF.js.map +0 -1
  163. package/dist/server/chunk-I6K5REFT.mjs.map +0 -1
  164. package/dist/server/chunk-LCYGQDAB.mjs +0 -835
  165. package/dist/server/chunk-LCYGQDAB.mjs.map +0 -1
  166. package/dist/server/chunk-N3PX76AP.mjs.map +0 -1
  167. package/dist/server/chunk-R5B6IOFQ.js.map +0 -1
  168. package/dist/server/chunk-TNYU5EIO.js +0 -835
  169. package/dist/server/chunk-TNYU5EIO.js.map +0 -1
  170. package/dist/server/chunk-U2NI3TS3.mjs.map +0 -1
  171. package/dist/server/chunk-USQF2XTU.mjs.map +0 -1
  172. package/dist/server/chunk-VHDDXCK6.js.map +0 -1
  173. package/dist/server/loadPage-DLC7DJZP.js +0 -11
  174. package/dist/server/loadPage-GEGN4UAL.mjs +0 -11
  175. /package/dist/server/{chunk-ES6QDZUX.mjs.map → chunk-C6FIJC7T.mjs.map} +0 -0
  176. /package/dist/server/{chunk-24F6FTCI.mjs.map → chunk-OSF34JTQ.mjs.map} +0 -0
  177. /package/dist/server/{chunk-OP2GHK27.mjs.map → chunk-Z5ZA6Q4D.mjs.map} +0 -0
  178. /package/dist/server/{loadPage-GEGN4UAL.mjs.map → loadPage-DNQTTRHL.mjs.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bindingSchema,
3
3
  getBlockDefinition
4
- } from "./chunk-USQF2XTU.mjs";
4
+ } from "./chunk-BYBJA6SP.mjs";
5
5
 
6
6
  // ../blocks/src/system/runtime/bindings.ts
7
7
  var shouldLogWarnings = isNonProductionEnv();
@@ -60,7 +60,7 @@ function splitPath(path) {
60
60
  for (const raw of parts) {
61
61
  if (!raw) continue;
62
62
  const baseMatch = raw.match(/^([^\[]+)/);
63
- if (baseMatch) {
63
+ if (baseMatch && baseMatch[1]) {
64
64
  segments.push(baseMatch[1]);
65
65
  }
66
66
  const bracketMatches = raw.matchAll(BRACKET_ACCESS_REGEX);
@@ -330,4 +330,4 @@ export {
330
330
  SUPPORTED_LOADER_ENDPOINTS,
331
331
  prefetchBlockData2 as prefetchBlockData
332
332
  };
333
- //# sourceMappingURL=chunk-7DS4Q3GA.mjs.map
333
+ //# sourceMappingURL=chunk-AEFWG657.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../blocks/src/system/runtime/bindings.ts","../../../blocks/src/system/data/utils.ts","../../../blocks/src/system/data/prefetchBlockData.ts","../../src/data/prefetchBlockData.ts"],"sourcesContent":["import { bindingSchema } from \"../node\";\n\nconst shouldLogWarnings = isNonProductionEnv();\n\nexport function resolveParamsBindings(\n input: unknown,\n vm: { content: Record<string, unknown>; $root?: Record<string, unknown> },\n meta?: { blockKind?: string },\n): unknown {\n if (input === null || typeof input !== \"object\") return input;\n if (Array.isArray(input)) return input.map((v) => resolveParamsBindings(v, vm, meta));\n\n // Binding object: { $bind: { from: '...', fallback: ... } }\n const maybeBind = (input as any).$bind;\n if (maybeBind && typeof maybeBind === \"object\") {\n try {\n const binding = bindingSchema.parse(maybeBind);\n const value = resolveBinding(binding.from, vm);\n // Return fallback if value is undefined/null\n if (value === undefined || value === null) {\n return binding.fallback;\n }\n return value;\n } catch (err) {\n if (shouldLogWarnings) {\n console.warn(\n `bindings: failed to parse loader param binding for block \"${meta?.blockKind ?? 'unknown'}\"`,\n err,\n );\n }\n return undefined;\n }\n }\n\n // Recurse object\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n out[k] = resolveParamsBindings(v, vm, meta);\n }\n return out;\n}\n\nexport function resolveBinding(\n path: string,\n vm: { content: Record<string, unknown>; $root?: Record<string, unknown> },\n): unknown {\n const segments = splitPath(path);\n if (!segments.length) return undefined;\n const [first, ...rest] = segments;\n let source: unknown = vm;\n if (first === \"$root\") {\n source = vm;\n return readFromSource(source as any, [first, ...rest]);\n }\n if (first === \"content\") {\n source = vm.content;\n return readFromSource(source, rest);\n }\n // Fallback: look in content first, then vm\n const contentResult = readFromSource(vm.content, segments);\n if (contentResult !== undefined) {\n return contentResult;\n }\n return readFromSource(vm as any, segments);\n}\n\nexport function splitPath(path: string): Array<string | number> {\n const PATH_SEPARATOR_REGEX = /\\./g;\n const BRACKET_ACCESS_REGEX = /\\[(?<token>[^\\]]+)\\]/g;\n const segments: Array<string | number> = [];\n const parts = path.split(PATH_SEPARATOR_REGEX);\n for (const raw of parts) {\n if (!raw) continue;\n const baseMatch = raw.match(/^([^\\[]+)/);\n if (baseMatch && baseMatch[1]) {\n segments.push(baseMatch[1]);\n }\n const bracketMatches = raw.matchAll(BRACKET_ACCESS_REGEX);\n for (const match of bracketMatches) {\n const token = match.groups?.token ?? \"\";\n if (token.startsWith(\"\\\"\") || token.startsWith(\"'\")) {\n segments.push(token.slice(1, -1));\n } else if (/^\\d+$/.test(token)) {\n segments.push(Number(token));\n } else {\n segments.push(token);\n }\n }\n if (!baseMatch && !raw.includes(\"[\")) {\n segments.push(raw);\n }\n }\n return segments;\n}\n\nexport function readFromSource(source: unknown, segments: Array<string | number>): unknown {\n return segments.reduce<unknown>((current, segment) => {\n if (current === undefined || current === null) return undefined;\n if (typeof segment === \"number\") {\n if (Array.isArray(current)) return current[segment];\n return undefined;\n }\n if (\n typeof current === \"object\" &&\n current !== null &&\n segment in (current as Record<string, unknown>)\n ) {\n return (current as Record<string, unknown>)[segment];\n }\n return undefined;\n }, source);\n}\n\nfunction isNonProductionEnv(): boolean {\n if (typeof globalThis === \"undefined\") {\n return true;\n }\n const maybeProcess = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n const nodeEnv = maybeProcess?.env?.NODE_ENV;\n return nodeEnv !== \"production\";\n}\n\n","/**\n * Utility functions for block data loading.\n * Pure functions with no side effects.\n */\n\nimport type { BlockDataLoader } from '../registry';\nimport type { DataLoaderEntry } from './types';\n\n/**\n * Normalize data loaders from block definition\n */\nexport function normalizeDataLoaders(\n def: { dataLoaders?: Record<string, BlockDataLoader> } | null\n): DataLoaderEntry[] {\n if (!def?.dataLoaders) {\n return [];\n }\n return Object.entries(def.dataLoaders).map(([key, loader]) => ({ key, loader }));\n}\n\n/**\n * Normalize block content for data loading.\n * Priority: draftContent > content > publishedContent\n */\nexport function normalizeContent(block: {\n content?: unknown;\n draftContent?: unknown;\n publishedContent?: unknown;\n}): Record<string, unknown> {\n const source = block.draftContent ?? block.content ?? block.publishedContent ?? {};\n if (!isRecord(source)) return {};\n\n // Unwrap data wrapper if present and valid\n if ('data' in source) {\n const data = (source as { data?: unknown }).data;\n if (isRecord(data)) {\n return data;\n }\n // If data is null/undefined/non-record, treat as empty\n if (data === null || data === undefined) {\n return {};\n }\n }\n\n return source as Record<string, unknown>;\n}\n\n/**\n * Normalize params for API calls.\n * Converts all values to strings.\n */\nexport function normalizeParams(input: unknown): Record<string, string> {\n if (!input || typeof input !== 'object') return {};\n const entries = Object.entries(input as Record<string, unknown>).map(([key, value]) => [\n key,\n coerceToString(value),\n ]);\n return Object.fromEntries(entries);\n}\n\n/**\n * Coerce value to string for API params\n */\nexport function coerceToString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (Array.isArray(value)) return value.map(coerceToString).join(',');\n return String(value);\n}\n\n/**\n * Extract data from API response.\n * Unwraps common response wrappers: { data }, { form }, { entries }, { services }\n *\n * Note: We check that properties are NOT functions to avoid returning\n * built-in methods like Array.prototype.entries\n */\nexport function coercePayload(payload: unknown): unknown {\n if (payload && typeof payload === 'object' && !Array.isArray(payload)) {\n const record = payload as Record<string, unknown>;\n if ('data' in record && typeof record.data !== 'function') return record.data;\n if ('form' in record && typeof record.form !== 'function') return record.form;\n if ('entries' in record && typeof record.entries !== 'function') return record.entries;\n if ('services' in record && typeof record.services !== 'function') return record.services;\n }\n return payload;\n}\n\n/**\n * Type guard for record objects\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","/**\n * Core block data prefetching logic (framework-agnostic).\n *\n * This module provides the shared implementation for prefetching block data loaders.\n * It works with any API client by accepting it as a parameter (dependency injection).\n *\n * Usage:\n * - Frontend: provide internal API client\n * - SDK: provide SDK client with endpoint mapping\n */\n\nimport { getBlockDefinition, type BlockDataLoader } from '../registry';\nimport { resolveParamsBindings } from '../runtime/bindings';\nimport type { PageOutline } from '../../structure/schema';\nimport type { ApiClient, DataLoaderEntry, PrefetchContext, ResolvedBlockData } from './types';\nimport {\n normalizeDataLoaders,\n normalizeContent,\n normalizeParams,\n coercePayload,\n} from './utils';\n\nexport type PrefetchBlockDataOptions = {\n /**\n * API client function that makes the actual requests.\n * This allows the caller to provide their own client (internal or SDK).\n */\n apiClient: ApiClient;\n\n /**\n * Validation function to check if endpoint is valid.\n * Different environments have different endpoint registries.\n */\n isValidEndpoint?: (endpoint: string) => boolean;\n\n /**\n * Error handler for failed data fetches.\n * By default, errors are logged and suppressed (data loading is best-effort).\n */\n onError?: (error: unknown, context: { block: string; loader: string }) => void;\n\n /**\n * Custom block data loader lookup.\n *\n * Called for blocks that aren't found in the system registry.\n * Returns data loaders for SDK custom blocks.\n *\n * @param blockKind - The block's kind (e.g., 'custom.team-member')\n * @returns Record of data loaders, or undefined if not a custom block\n */\n getCustomBlockLoaders?: (blockKind: string) => Record<string, BlockDataLoader> | undefined;\n};\n\n/**\n * Core data prefetching logic (framework-agnostic).\n *\n * This function is shared between frontend and SDK implementations.\n * It handles:\n * - Extracting data loaders from block definitions\n * - Resolving loader params with block content\n * - Executing server-mode loaders in parallel\n * - Organizing results by block ID and loader key\n *\n * @example\n * ```typescript\n * const resolved = await prefetchBlockData(page, context, {\n * apiClient: async ({ endpoint, params }) => {\n * return await myApiClient({ endpoint, params });\n * },\n * isValidEndpoint: (endpoint) => endpoint in API_ENDPOINTS,\n * });\n * ```\n */\nexport async function prefetchBlockData(\n page: PageOutline,\n context: PrefetchContext,\n options: PrefetchBlockDataOptions\n): Promise<ResolvedBlockData> {\n const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders } = options;\n\n const results: ResolvedBlockData = {};\n const tasks: Array<Promise<void>> = [];\n\n for (const block of page.blocks) {\n const blockId = block.id;\n if (!blockId) continue;\n\n // Get loaders from system block definition OR custom block lookup\n let loaders: DataLoaderEntry[];\n const def = getBlockDefinition(block.kind);\n\n if (def) {\n // System block - use normalizeDataLoaders\n loaders = normalizeDataLoaders(def);\n } else if (getCustomBlockLoaders) {\n // Custom block - check callback\n const customLoaders = getCustomBlockLoaders(block.kind);\n loaders = customLoaders\n ? Object.entries(customLoaders).map(([key, loader]) => ({ key, loader }))\n : [];\n } else {\n loaders = [];\n }\n\n if (loaders.length === 0) continue;\n\n const root = {\n siteId: context.siteId,\n pageId: context.pageId,\n previewStage: context.previewStage,\n };\n const normalizedContent = normalizeContent(block as { content?: unknown; draftContent?: unknown; publishedContent?: unknown });\n const vm = { content: normalizedContent, $root: root };\n\n for (const { key, loader } of loaders) {\n // Skip client-mode loaders (they run in browser)\n if (loader.mode === 'client') {\n continue;\n }\n\n // Resolve params using block content\n const rawParams = resolveParamsBindings(loader.params, vm, {\n blockKind: block.kind,\n });\n const params = normalizeParams(rawParams);\n\n const endpoint = loader.endpoint;\n\n // Validate endpoint if validator provided\n if (isValidEndpoint && !isValidEndpoint(endpoint)) {\n continue;\n }\n\n tasks.push(\n (async () => {\n try {\n const payload = await apiClient({ endpoint, params });\n const data = coercePayload(payload);\n\n if (!results[blockId]) {\n results[blockId] = {};\n }\n results[blockId]![key] = data;\n } catch (error) {\n // Call error handler if provided, otherwise fail silently\n // Data loading is best-effort - failures shouldn't break the page\n if (onError) {\n onError(error, { block: block.kind, loader: key });\n }\n }\n })()\n );\n }\n }\n\n if (tasks.length > 0) {\n await Promise.all(tasks);\n }\n\n return results;\n}\n","/**\n * SDK wrapper for block data prefetching.\n * Uses the shared core implementation from @riverbankcms/blocks with the SDK client.\n */\n\nimport type { BlockDataLoader, PageOutline, SdkCustomBlock } from '@riverbankcms/blocks';\nimport { prefetchBlockData as prefetchBlockDataCore } from '@riverbankcms/blocks/system/data';\nimport type { PrefetchContext, ResolvedBlockData } from '@riverbankcms/blocks/system/data';\nimport type { RiverbankClient } from '../client/types';\n\nexport type { PrefetchContext, ResolvedBlockData };\n\n/**\n * Supported loader endpoints for SDK data fetching.\n * Only these endpoints can be used in block data loaders when using the SDK.\n *\n * This is the SINGLE SOURCE OF TRUTH for whitelisted endpoints.\n * - Zod validation schema derives from this array\n * - TypeScript types derive from this array\n * - Runtime validation uses this array\n */\nexport const SUPPORTED_LOADER_ENDPOINTS = [\n 'listPublishedEntries',\n 'getPublishedEntryPreview',\n 'listPublicEvents',\n 'getPublicFormById',\n 'getPublicBookingServices',\n] as const;\n\n/**\n * Union type of all supported loader endpoints.\n * Derived from SUPPORTED_LOADER_ENDPOINTS array.\n */\nexport type SupportedLoaderEndpoint = typeof SUPPORTED_LOADER_ENDPOINTS[number];\n\n/**\n * Options for SDK block data prefetching.\n */\nexport type SdkPrefetchOptions = {\n /**\n * SDK custom blocks from site config.\n * Used to look up data loaders for custom.* blocks.\n */\n customBlocks?: SdkCustomBlock[];\n};\n\n/**\n * Prefetch block data for SDK-based applications.\n * Maps loader endpoints to corresponding SDK client methods.\n *\n * Supports both system blocks and SDK custom blocks with data loaders.\n *\n * @example\n * ```typescript\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { prefetchBlockData } from '@riverbankcms/sdk/data';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n * const page = await client.getPage({ siteId, path: '/' });\n *\n * // Basic usage (system blocks only)\n * const blockData = await prefetchBlockData(page.outline, {\n * siteId: page.siteId,\n * pageId: page.id,\n * }, client);\n *\n * // With custom blocks from SDK config\n * const blockData = await prefetchBlockData(page.outline, context, client, {\n * customBlocks: site.sdkConfig?.customBlocks,\n * });\n * ```\n */\nexport async function prefetchBlockData(\n page: PageOutline,\n context: PrefetchContext,\n client: RiverbankClient,\n options?: SdkPrefetchOptions,\n): Promise<ResolvedBlockData> {\n const { customBlocks } = options ?? {};\n\n // Build lookup map for custom block loaders\n // Key is string (blockKind from page) matching block.id (custom.xxx)\n const customBlockMap = new Map<string, SdkCustomBlock>(\n (customBlocks ?? []).map((block) => [block.id as string, block])\n );\n\n return prefetchBlockDataCore(page, context, {\n apiClient: async ({ endpoint, params }) => {\n // Only support whitelisted loader endpoints\n if (!isSupportedEndpoint(endpoint)) {\n throw new Error(\n `Unsupported loader endpoint: ${endpoint}. ` +\n `SDK only supports: ${SUPPORTED_LOADER_ENDPOINTS.join(', ')}`\n );\n }\n\n // Map endpoint to SDK client method\n switch (endpoint) {\n case 'listPublishedEntries': {\n const { siteId, type, orderBy, limit, stage, mode, entryIds } = params ?? {};\n if (!siteId || !type) {\n throw new Error('listPublishedEntries requires siteId and type params');\n }\n\n // Parse limit if provided (can come as string from bindings)\n const parsedLimit = typeof limit === 'string'\n ? Number.parseInt(limit, 10)\n : typeof limit === 'number'\n ? limit\n : undefined;\n\n // Map orderBy to order param (matching embed block field values)\n const order = (orderBy === 'newest' || orderBy === 'oldest' || orderBy === 'title' || orderBy === 'order')\n ? orderBy as 'newest' | 'oldest' | 'title' | 'order'\n : undefined;\n\n // Extract entry IDs for manual mode\n // entryIds comes from binding to entries field which contains { entryId: \"uuid\" } objects\n let parsedEntryIds: string[] | undefined;\n if (mode === 'manual' && Array.isArray(entryIds)) {\n parsedEntryIds = entryIds\n .map((item: unknown) => {\n if (typeof item === 'object' && item !== null && 'entryId' in item) {\n return (item as { entryId: string }).entryId;\n }\n // Also support direct string IDs\n if (typeof item === 'string') {\n return item;\n }\n return null;\n })\n .filter((id): id is string => id !== null);\n }\n\n return await client.getEntries({\n siteId,\n contentType: type,\n limit: parsedLimit,\n order,\n preview: stage === 'preview',\n // Manual mode - pass entry IDs for hydration\n mode: mode === 'manual' ? 'manual' : undefined,\n entryIds: parsedEntryIds,\n });\n }\n\n case 'getPublishedEntryPreview': {\n const { siteId, type, slug } = params ?? {};\n if (!siteId || !type || !slug) {\n throw new Error('getPublishedEntryPreview requires siteId, type, and slug params');\n }\n return await client.getEntry({ siteId, contentType: type, slug });\n }\n case 'listPublicEvents': {\n const { siteId, limit, from, to, stage } = params ?? {};\n if (!siteId) {\n throw new Error('listPublicEvents requires siteId param');\n }\n const parsedLimit =\n typeof limit === 'string'\n ? Number.parseInt(limit, 10)\n : typeof limit === 'number'\n ? limit\n : undefined;\n return await client.listPublicEvents({ siteId, limit: parsedLimit, from, to, stage });\n }\n case 'getPublicFormById': {\n const { formId } = params ?? {};\n if (!formId) {\n throw new Error('getPublicFormById requires formId param');\n }\n return await client.getPublicFormById({ formId });\n }\n case 'getPublicBookingServices': {\n const { siteId, ids } = params ?? {};\n if (!siteId) {\n throw new Error('getPublicBookingServices requires siteId param');\n }\n return await client.getPublicBookingServices({ siteId, ids });\n }\n\n default: {\n // TypeScript should never reach here due to isSupportedEndpoint check\n const _exhaustive: never = endpoint;\n throw new Error(`Unhandled endpoint: ${_exhaustive}`);\n }\n }\n },\n isValidEndpoint: isSupportedEndpoint,\n onError: (error, { block, loader }) => {\n console.warn('[prefetchBlockData] failed to prefetch block data', {\n block,\n loader,\n error,\n });\n },\n // Provide custom block loader lookup for SDK custom blocks\n getCustomBlockLoaders: (blockKind): Record<string, BlockDataLoader> | undefined => {\n const customBlock = customBlockMap.get(blockKind);\n if (!customBlock?.dataLoaders) return undefined;\n\n // Convert SdkConfigLoader to BlockDataLoader\n // SdkConfigLoader.endpoint is SdkLoaderEndpoint (string union) -> string\n // SdkConfigLoader.params is Record<string, LoaderParamValue> -> Record<string, unknown>\n // Both are structurally compatible via covariance\n const loaders: Record<string, BlockDataLoader> = {};\n for (const [key, loader] of Object.entries(customBlock.dataLoaders)) {\n loaders[key] = {\n endpoint: loader.endpoint,\n params: loader.params,\n mode: loader.mode,\n };\n }\n return loaders;\n },\n });\n}\n\n/**\n * Type guard for supported loader endpoints\n */\nfunction isSupportedEndpoint(endpoint: string): endpoint is SupportedLoaderEndpoint {\n return SUPPORTED_LOADER_ENDPOINTS.includes(endpoint as SupportedLoaderEndpoint);\n}\n"],"mappings":"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","names":["prefetchBlockData"]}
@@ -599,7 +599,7 @@ function parseToken(source) {
599
599
  if (source.includes("/")) {
600
600
  const [token, opacity] = source.split("/");
601
601
  const alpha = Number(opacity) / 100;
602
- if (!Number.isNaN(alpha)) {
602
+ if (!Number.isNaN(alpha) && token) {
603
603
  return { token, alpha };
604
604
  }
605
605
  return { token: source };
@@ -639,7 +639,8 @@ function headingGroup(opts) {
639
639
  containerClass = "text-center",
640
640
  className,
641
641
  eyebrowClass = "heading-eyebrow text-sm font-semibold tracking-wide",
642
- titleClass = "heading-title text-3xl font-semibold sm:text-4xl",
642
+ // h2 now gets size/weight from theme typography CSS
643
+ titleClass = "heading-title",
643
644
  eyebrowStyle = textColorStyle("neutral-500"),
644
645
  titleStyle = textColorStyle("neutral-900")
645
646
  } = opts;
@@ -1220,6 +1221,8 @@ var bodyCopyFragment = defineFragment({
1220
1221
  text(
1221
1222
  {
1222
1223
  as: "h2",
1224
+ // h2 now gets size/weight from theme typography CSS
1225
+ // Only dynamic class here is for text alignment
1223
1226
  className: {
1224
1227
  $bind: {
1225
1228
  from: "content.alignment",
@@ -1227,11 +1230,11 @@ var bodyCopyFragment = defineFragment({
1227
1230
  {
1228
1231
  id: "ui.headingClassFromAlignment",
1229
1232
  options: {
1230
- base: "text-3xl font-semibold sm:text-4xl"
1233
+ base: ""
1231
1234
  }
1232
1235
  }
1233
1236
  ],
1234
- fallback: "text-3xl font-semibold sm:text-4xl"
1237
+ fallback: ""
1235
1238
  }
1236
1239
  },
1237
1240
  style: textColorStyle("neutral-900")
@@ -1304,7 +1307,9 @@ var heroCopyFragment = defineFragment({
1304
1307
  text(
1305
1308
  {
1306
1309
  as: "h1",
1307
- className: "hero-headline text-4xl font-semibold sm:text-5xl md:text-6xl",
1310
+ // heading-display: uses fluid typography from theme (--fs-h1-display-fluid)
1311
+ // Removes hardcoded text-4xl/5xl/6xl - size now controlled by theme
1312
+ className: "hero-headline heading-display",
1308
1313
  style: textColorStyle("neutral-900")
1309
1314
  },
1310
1315
  bind("content.headline")
@@ -1483,7 +1488,8 @@ var testimonialsHeadingFragment = defineFragment({
1483
1488
  { gap: "md", className: "mx-auto max-w-2xl text-center" },
1484
1489
  [
1485
1490
  text(
1486
- { as: "h2", className: "text-3xl font-semibold sm:text-4xl", style: textColorStyle("neutral-900") },
1491
+ // h2 now gets size/weight from theme typography CSS
1492
+ { as: "h2", style: textColorStyle("neutral-900") },
1487
1493
  when("content.heading"),
1488
1494
  bind("content.heading")
1489
1495
  ),
@@ -1855,7 +1861,7 @@ var blogFeaturedPostFragment = defineFragment({
1855
1861
  text(
1856
1862
  {
1857
1863
  as: "h2",
1858
- className: "text-2xl font-semibold md:text-3xl",
1864
+ // h2 now gets size/weight from theme typography CSS
1859
1865
  style: textColorStyle("neutral-900")
1860
1866
  },
1861
1867
  bind("title", { fallback: "Latest post" })
@@ -2252,7 +2258,8 @@ var faqHeadingFragment = defineFragment({
2252
2258
  text(
2253
2259
  {
2254
2260
  as: "h2",
2255
- className: "faq-title text-3xl font-semibold sm:text-4xl",
2261
+ // h2 now gets size/weight from theme typography CSS
2262
+ className: "faq-title",
2256
2263
  style: textColorStyle("neutral-900")
2257
2264
  },
2258
2265
  when("content.title"),
@@ -4151,7 +4158,11 @@ var simpleFooterLayout = stack(
4151
4158
  }
4152
4159
  },
4153
4160
  [
4154
- navRow({ align: "center", className: "flex flex-wrap justify-center gap-x-6 gap-y-3" }),
4161
+ navRow({
4162
+ align: "center",
4163
+ className: "flex flex-wrap justify-center gap-x-6 gap-y-3",
4164
+ linkClassName: "footer-nav-link inline-flex items-center px-4 py-2 text-sm font-medium transition-theme-standard"
4165
+ }),
4155
4166
  ...bottomTextLayout()
4156
4167
  ],
4157
4168
  when("$root.theme.footer.variant", { equals: "simple" })
@@ -4179,7 +4190,11 @@ var columnsFooterLayout = stack(
4179
4190
  { className: "flex w-full flex-wrap items-center justify-between gap-4" },
4180
4191
  [
4181
4192
  text({ as: "span", className: "text-sm font-semibold", style: textColorStyle("text") }, bind("site.title", { fallback: "Your Site" })),
4182
- navRow({ className: "flex flex-wrap justify-end gap-x-6 gap-y-3", align: "end" })
4193
+ navRow({
4194
+ className: "flex flex-wrap justify-end gap-x-6 gap-y-3",
4195
+ align: "end",
4196
+ linkClassName: "footer-nav-link inline-flex items-center px-4 py-2 text-sm font-medium transition-theme-standard"
4197
+ })
4183
4198
  ]
4184
4199
  ),
4185
4200
  ...bottomTextLayout()
@@ -5458,4 +5473,4 @@ export {
5458
5473
  siteFooterManifest,
5459
5474
  getBlockDefinition
5460
5475
  };
5461
- //# sourceMappingURL=chunk-USQF2XTU.mjs.map
5476
+ //# sourceMappingURL=chunk-BYBJA6SP.mjs.map