@riverbankcms/sdk 0.4.1 → 0.4.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 (116) hide show
  1. package/README.md +73 -0
  2. package/dist/cli/index.js +46 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/client.d.mts +3 -3
  5. package/dist/client/client.d.ts +3 -3
  6. package/dist/client/client.js +90 -170
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/client.mjs +90 -170
  9. package/dist/client/client.mjs.map +1 -1
  10. package/dist/client/hooks.d.mts +3 -3
  11. package/dist/client/hooks.d.ts +3 -3
  12. package/dist/client/rendering/client.d.mts +1 -1
  13. package/dist/client/rendering/client.d.ts +1 -1
  14. package/dist/client/rendering/client.js +84 -142
  15. package/dist/client/rendering/client.js.map +1 -1
  16. package/dist/client/rendering/client.mjs +84 -142
  17. package/dist/client/rendering/client.mjs.map +1 -1
  18. package/dist/client/resolver-CYyfzTQ9.d.mts +61 -0
  19. package/dist/client/resolver-CYyfzTQ9.d.ts +61 -0
  20. package/dist/client/usePage--fGlyrgj.d.mts +6439 -0
  21. package/dist/client/usePage-BC8Q2E3t.d.mts +6431 -0
  22. package/dist/client/usePage-CE7X5NcN.d.ts +6439 -0
  23. package/dist/client/usePage-CHEybPMD.d.ts +6429 -0
  24. package/dist/client/usePage-D4fxZbRR.d.mts +6429 -0
  25. package/dist/client/usePage-DpRNZUtP.d.ts +6431 -0
  26. package/dist/server/{Layout-CHG77dhK.d.ts → Layout-CXI_VkhN.d.ts} +1 -1
  27. package/dist/server/{Layout-B_zUr9ci.d.mts → Layout-p6f3TLw9.d.mts} +1 -1
  28. package/dist/server/{chunk-XK2YIISA.mjs → chunk-24F6FTCI.mjs} +2 -2
  29. package/dist/server/{chunk-BUCJWG6G.js → chunk-2SSEBAHC.js} +5 -5
  30. package/dist/server/{chunk-BUCJWG6G.js.map → chunk-2SSEBAHC.js.map} +1 -1
  31. package/dist/server/{chunk-ZIM53VP6.js → chunk-6JBKKV3G.js} +27 -4
  32. package/dist/server/chunk-6JBKKV3G.js.map +1 -0
  33. package/dist/server/{chunk-ZEAJW6T3.mjs → chunk-ES6QDZUX.mjs} +3 -2
  34. package/dist/server/chunk-ES6QDZUX.mjs.map +1 -0
  35. package/dist/server/{chunk-SWPHIUVE.js → chunk-G35R7N7B.js} +3 -2
  36. package/dist/server/chunk-G35R7N7B.js.map +1 -0
  37. package/dist/server/{chunk-BOHTTHY5.mjs → chunk-I6K5REFT.mjs} +27 -4
  38. package/dist/server/chunk-I6K5REFT.mjs.map +1 -0
  39. package/dist/server/{chunk-SFQ7VF3G.mjs → chunk-LCYGQDAB.mjs} +10 -6
  40. package/dist/server/chunk-LCYGQDAB.mjs.map +1 -0
  41. package/dist/server/{chunk-P6CDRJN3.js → chunk-TNYU5EIO.js} +16 -12
  42. package/dist/server/chunk-TNYU5EIO.js.map +1 -0
  43. package/dist/server/{chunk-NKXS4TBK.mjs → chunk-U2NI3TS3.mjs} +87 -169
  44. package/dist/server/chunk-U2NI3TS3.mjs.map +1 -0
  45. package/dist/server/{chunk-IT5ICP43.js → chunk-VHDDXCK6.js} +94 -176
  46. package/dist/server/chunk-VHDDXCK6.js.map +1 -0
  47. package/dist/server/{components-Bo3LPpVb.d.mts → components-C75e4poV.d.mts} +20 -12
  48. package/dist/server/{components-ClFs4PUa.d.ts → components-Dhiemsjd.d.ts} +20 -12
  49. package/dist/server/components.d.mts +5 -5
  50. package/dist/server/components.d.ts +5 -5
  51. package/dist/server/components.js +3 -3
  52. package/dist/server/components.mjs +2 -2
  53. package/dist/server/config-validation.d.mts +2 -2
  54. package/dist/server/config-validation.d.ts +2 -2
  55. package/dist/server/config-validation.js +3 -3
  56. package/dist/server/config-validation.mjs +2 -2
  57. package/dist/server/config.d.mts +3 -3
  58. package/dist/server/config.d.ts +3 -3
  59. package/dist/server/config.js +3 -3
  60. package/dist/server/config.mjs +2 -2
  61. package/dist/server/data.d.mts +2 -2
  62. package/dist/server/data.d.ts +2 -2
  63. package/dist/server/{index-Dj7VKH34.d.mts → index-C6o9LPvq.d.mts} +1 -1
  64. package/dist/server/{index-DbSfrRA0.d.ts → index-CAwBj3-A.d.ts} +1 -1
  65. package/dist/server/index.d.mts +4 -4
  66. package/dist/server/index.d.ts +4 -4
  67. package/dist/server/{loadContent-C_FipaAC.d.mts → loadContent-CdXfuCuE.d.mts} +3 -3
  68. package/dist/server/{loadContent-C2SwqmXy.d.ts → loadContent-CsvQRoxb.d.ts} +3 -3
  69. package/dist/server/{loadPage-naVvoua8.d.ts → loadPage-BA0HiT-6.d.ts} +72 -28
  70. package/dist/server/{loadPage-DUHBXDEW.js → loadPage-DLC7DJZP.js} +3 -3
  71. package/dist/server/{loadPage-DUHBXDEW.js.map → loadPage-DLC7DJZP.js.map} +1 -1
  72. package/dist/server/{loadPage-LYVKY3WZ.mjs → loadPage-GEGN4UAL.mjs} +2 -2
  73. package/dist/server/{loadPage-mavT3Jae.d.mts → loadPage-p3AWwwrd.d.mts} +72 -28
  74. package/dist/server/metadata.d.mts +3 -3
  75. package/dist/server/metadata.d.ts +3 -3
  76. package/dist/server/navigation.d.mts +2 -2
  77. package/dist/server/navigation.d.ts +2 -2
  78. package/dist/server/rendering/server.d.mts +4 -4
  79. package/dist/server/rendering/server.d.ts +4 -4
  80. package/dist/server/rendering/server.js +4 -4
  81. package/dist/server/rendering/server.mjs +3 -3
  82. package/dist/server/rendering.d.mts +7 -7
  83. package/dist/server/rendering.d.ts +7 -7
  84. package/dist/server/rendering.js +5 -5
  85. package/dist/server/rendering.mjs +4 -4
  86. package/dist/server/routing.d.mts +78 -5
  87. package/dist/server/routing.d.ts +78 -5
  88. package/dist/server/routing.js +57 -3
  89. package/dist/server/routing.js.map +1 -1
  90. package/dist/server/routing.mjs +55 -1
  91. package/dist/server/routing.mjs.map +1 -1
  92. package/dist/server/server.d.mts +5 -5
  93. package/dist/server/server.d.ts +5 -5
  94. package/dist/server/server.js +2 -2
  95. package/dist/server/server.mjs +1 -1
  96. package/dist/server/theme-bridge.js +7 -7
  97. package/dist/server/theme-bridge.mjs +1 -1
  98. package/dist/server/{types-BA-J9K8r.d.mts → types-BLf-hE50.d.mts} +19 -6
  99. package/dist/server/{types-5XdVD2J1.d.ts → types-BWQ-TohG.d.ts} +19 -6
  100. package/dist/server/{types-CMqVHYLG.d.ts → types-CL916r6x.d.ts} +23 -1
  101. package/dist/server/{types-BC9eB2KH.d.mts → types-CdhKJrB0.d.mts} +1 -1
  102. package/dist/server/{types-CAnC529E.d.ts → types-Dj8B3QRb.d.ts} +1 -1
  103. package/dist/server/{types-CYfHxUhe.d.mts → types-txWsSxN7.d.mts} +23 -1
  104. package/dist/server/{validation-C7W2Fe0i.d.ts → validation-CoU8uAiu.d.ts} +1 -1
  105. package/dist/server/{validation-hg1sqhrt.d.mts → validation-DzvDwwRo.d.mts} +1 -1
  106. package/package.json +3 -3
  107. package/dist/server/chunk-BOHTTHY5.mjs.map +0 -1
  108. package/dist/server/chunk-IT5ICP43.js.map +0 -1
  109. package/dist/server/chunk-NKXS4TBK.mjs.map +0 -1
  110. package/dist/server/chunk-P6CDRJN3.js.map +0 -1
  111. package/dist/server/chunk-SFQ7VF3G.mjs.map +0 -1
  112. package/dist/server/chunk-SWPHIUVE.js.map +0 -1
  113. package/dist/server/chunk-ZEAJW6T3.mjs.map +0 -1
  114. package/dist/server/chunk-ZIM53VP6.js.map +0 -1
  115. /package/dist/server/{chunk-XK2YIISA.mjs.map → chunk-24F6FTCI.mjs.map} +0 -0
  116. /package/dist/server/{loadPage-LYVKY3WZ.mjs.map → loadPage-GEGN4UAL.mjs.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-P6CDRJN3.js","../../src/rendering/components/Page.tsx","../../../block-form/src/manifest/manifestFormAdapter.ts","../../../block-form/src/widgets/TextField/textFieldSchema.ts","../../../block-form/src/widgets/NumberField/numberFieldSchema.ts","../../../block-form/src/widgets/SelectField/selectFieldSchema.ts","../../../block-form/src/widgets/BooleanField/booleanFieldSchema.ts","../../../block-form/src/widgets/GroupField/groupFieldSchema.ts","../../../block-form/src/widgets/ModalGroupField/modalFieldSchema.ts","../../../block-form/src/widgets/RepeaterField/repeaterFieldSchema.ts","../../../block-form/src/widgets/UrlField/urlFieldSchema.ts","../../../block-form/src/widgets/TimeField/timeFieldSchema.ts","../../../block-form/src/widgets/DateField/dateFieldSchema.ts","../../../block-form/src/widgets/DateTimeField/dateTimeFieldSchema.ts","../../../block-form/src/widgets/SlugField/slugFieldSchema.ts","../../../block-form/src/widgets/LinkField/linkFieldSchema.ts","../../../block-form/src/widgets/MediaField/mediaFieldSchema.ts","../../../block-form/src/widgets/TabGroupField/tabGroupFieldSchema.ts","../../../block-form/src/widgets/PresetOrCustomField/presetOrCustomFieldSchema.ts","../../../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts","../../../block-form/src/widgets/TextField/textFieldDefaults.ts","../../../block-form/src/widgets/NumberField/numberFieldDefaults.ts","../../../block-form/src/widgets/SelectField/selectFieldDefaults.ts","../../../block-form/src/widgets/BooleanField/booleanFieldDefaults.ts","../../../block-form/src/widgets/GroupField/groupFieldDefaults.ts","../../../block-form/src/widgets/ModalGroupField/modalFieldDefaults.ts","../../../block-form/src/widgets/RepeaterField/repeaterFieldDefaults.ts","../../../block-form/src/widgets/UrlField/urlFieldDefaults.ts","../../../block-form/src/widgets/TimeField/timeFieldDefaults.ts","../../../block-form/src/widgets/DateField/dateFieldDefaults.ts","../../../block-form/src/widgets/DateTimeField/dateTimeFieldDefaults.ts","../../../block-form/src/widgets/SlugField/slugFieldDefaults.ts","../../../block-form/src/widgets/LinkField/linkFieldDefaults.ts","../../../block-form/src/widgets/RichTextField/richTextFieldSchema.ts","../../../block-form/src/widgets/RichTextField/richTextFieldDefaults.ts","../../../block-form/src/widgets/MediaField/mediaFieldDefaults.ts","../../../block-form/src/widgets/PresetOrCustomField/presetOrCustomFieldDefaults.ts","../../../block-form/src/widgets/ReferenceField/referenceFieldDefaults.ts","../../../block-form/src/registry/schemas.ts","../../../block-form/src/server/index.ts","../../../site-renderer/dist/index.mjs","../../src/rendering/components/Layout.tsx"],"names":["s","z","__require","children","rest"],"mappings":"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","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-P6CDRJN3.js","sourcesContent":[null,"/**\n * Pure Page renderer component for Riverbank CMS.\n *\n * This component expects all data to be provided via props.\n * For data fetching, use:\n * - Server-side: `await loadPage({ client, siteId, path })`\n * - Client-side: `usePage({ client, siteId, path })`\n */\n\nimport { PageRenderer, buildThemeRuntime } from '@riverbankcms/blocks';\nimport type { PageOutline, RouteMap, Theme, ThemeTokens, BlockOverrides, OccurrenceContextData } from '@riverbankcms/blocks';\nimport type { ResolvedBlockData } from '../../data';\nimport type { RuntimeSdkConfig } from '../helpers/loadPage';\n\n// Re-export OccurrenceContextData for SDK consumers\nexport type { OccurrenceContextData };\n\nexport type PageProps = {\n // Required data (must be provided by caller)\n page: PageOutline;\n theme: Theme;\n siteId: string;\n\n // Optional data\n themeTokens?: ThemeTokens; // If not provided, will be built from theme\n resolvedData?: ResolvedBlockData; // Pre-fetched block data\n routeMap?: RouteMap;\n /**\n * SDK site configuration containing theme palette overrides.\n * When provided, the SDK palette tokens are merged into the theme tokens,\n * allowing blocks to use SDK-defined color tokens for section backgrounds.\n */\n sdkConfig?: RuntimeSdkConfig | null;\n\n /**\n * Additional context data for content entry pages.\n * Used to pass occurrence context and content entry data to blocks.\n */\n dataContext?: {\n /** Occurrence context for event pages (from URL like /events/yoga/2025-01-15) */\n occurrenceContext?: OccurrenceContextData | null;\n /** Content entry data for template pages */\n contentEntry?: Record<string, unknown> | null;\n };\n\n // Customization\n wrapBlock?: (blockId: string, rendered: React.ReactNode) => React.ReactNode;\n registry?: Parameters<typeof PageRenderer>[0]['registry'];\n usePlaceholders?: boolean;\n /**\n * Custom components to override default block rendering.\n * Keys can be full block kind (\"block.hero\") or short form (\"hero\").\n *\n * This is SSR-safe - no context or hooks required.\n *\n * @example\n * ```tsx\n * <Page\n * {...pageData}\n * blockOverrides={{\n * 'hero': MyCustomHero,\n * 'block.testimonials': MyCustomTestimonials,\n * }}\n * />\n * ```\n */\n blockOverrides?: BlockOverrides;\n};\n\n/**\n * Pure renderer for Riverbank CMS pages.\n *\n * This component expects all data to be provided via props.\n * For data fetching, use:\n * - Server-side: `await loadPage({ client, siteId, path })`\n * - Client-side: `usePage({ client, siteId, path })`\n *\n * @example Server-side (Next.js App Router)\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { loadPage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n *\n * export default async function PageRoute({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-id',\n * path: `/${params.slug}`,\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Client-side\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { usePage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n *\n * function MyPage({ path }) {\n * const pageData = usePage({ client, siteId: 'site-id', path });\n *\n * if (pageData.loading) return <LoadingState />;\n * if (pageData.error) return <ErrorState error={pageData.error} />;\n * if (!pageData.page) return <NotFound />;\n *\n * return <Page {...pageData} />;\n * }\n * ```\n */\nexport function Page({\n page,\n theme,\n themeTokens: providedTokens,\n siteId,\n resolvedData,\n routeMap,\n wrapBlock,\n registry,\n usePlaceholders = false,\n blockOverrides,\n sdkConfig,\n dataContext,\n}: PageProps) {\n // Build theme tokens if not provided\n const baseTokens = providedTokens ?? buildThemeRuntime(theme).tokens;\n\n // Merge SDK palette tokens into theme tokens\n // This allows blocks to resolve SDK-defined color tokens (e.g., 'primary' -> '#6d28d9')\n const themeTokens = sdkConfig?.theme?.palette\n ? { ...baseTokens, palette: { ...baseTokens.palette, ...sdkConfig.theme.palette } }\n : baseTokens;\n\n return (\n <PageRenderer\n theme={theme}\n page={page}\n themeTokens={themeTokens}\n usePlaceholders={usePlaceholders}\n dataContext={{\n siteId,\n resolvedData,\n routes: routeMap,\n occurrenceContext: dataContext?.occurrenceContext ?? null,\n contentEntry: dataContext?.contentEntry ?? null,\n }}\n routeMap={routeMap}\n wrapBlock={wrapBlock}\n registry={registry}\n blockOverrides={blockOverrides}\n sdkConfig={sdkConfig}\n />\n );\n}\n","/**\n * Manifest Form Adapter\n *\n * Transforms BlockManifest field definitions into FieldConfigs for form rendering.\n * Handles role-based visibility filtering and structure normalization.\n *\n * This adapter is intentionally minimal - it only does what's truly manifest-specific:\n * 1. Filter fields by role visibility\n * 2. Flatten nested structure (schema.fields → fields)\n *\n * Everything else (validation, defaults, UI) is handled by the generic form system.\n */\n\nimport type { FieldDefinition, VisibilityLevel, BlockManifest } from '@riverbankcms/blocks'\nimport { z, type ZodTypeAny } from 'zod'\n\nimport type { FieldConfig, GroupFieldConfig, RepeaterFieldConfig } from '../fields/types'\nimport { buildFieldSchema as buildSchemaFromRegistry } from '../registry/schemas'\n\nexport interface ManifestAdapterOptions {\n role?: VisibilityLevel\n}\n\nexport interface ManifestAdapterResult {\n fields: FieldConfig[]\n schema: ZodTypeAny\n}\n\n/**\n * Union type for manifest form sources\n * Can be either a BlockManifest or null\n */\nexport type ManifestFormSource = BlockManifest | null\n\n/**\n * Options for manifest validation schema creation\n */\nexport interface ManifestSchemaOptions {\n role?: VisibilityLevel\n widgets?: any // Widget registry for custom validation (unused in new system)\n}\n\n/**\n * Result of createManifestValidation\n */\nexport interface ManifestValidationResult {\n schema: ZodTypeAny\n fields: FieldConfig[]\n}\n\nconst DEFAULT_ROLE: VisibilityLevel = 'author'\n\nconst rolePriority: Record<VisibilityLevel, number> = {\n author: 0,\n designer: 1,\n admin: 2,\n}\n\n/**\n * Transform a BlockManifest into form fields and validation schema\n */\nexport function createManifestFormAdapter(\n manifest: BlockManifest,\n options?: ManifestAdapterOptions,\n): ManifestAdapterResult {\n const role = options?.role ?? DEFAULT_ROLE\n\n const fields = (manifest.fields ?? [])\n .map((field) => transformField(field, role))\n .filter(Boolean) as FieldConfig[]\n\n const schema = buildValidationSchema(fields)\n\n return { fields, schema }\n}\n\n/**\n * Transform a single field, filtering by role and flattening nested structure\n */\nfunction transformField(field: FieldDefinition, role: VisibilityLevel): FieldConfig | undefined {\n // Filter by role visibility\n if (!isFieldVisible(field, role)) {\n return undefined\n }\n\n // For simple fields, pass through directly (types are structurally compatible)\n if (field.type !== 'group' && field.type !== 'repeater') {\n return field as FieldConfig\n }\n\n // For group fields: flatten schema.fields → fields\n if (field.type === 'group') {\n const children = (field.schema?.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (!children.length) {\n return undefined\n }\n\n const { schema: _schema, ...rest } = field as any\n return { ...rest, fields: children } as GroupFieldConfig\n }\n\n // For repeater fields: handle polymorphic vs monomorphic\n if (field.type === 'repeater') {\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: transform each item type's fields\n const itemTypes: Record<string, { label: string; icon?: string; fields: FieldConfig[] }> = {}\n\n for (const [typeKey, itemType] of Object.entries(field.itemTypes)) {\n const children = (itemType.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (children.length > 0) {\n itemTypes[typeKey] = {\n label: itemType.label,\n icon: itemType.icon,\n fields: children,\n }\n }\n }\n\n if (Object.keys(itemTypes).length === 0) {\n return undefined\n }\n\n const { schema: _schema2, ...rest } = field as any\n return { ...rest, itemTypes } as RepeaterFieldConfig\n }\n\n // Monomorphic: flatten schema.fields → fields\n const children = (field.schema?.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (!children.length) {\n return undefined\n }\n\n const { schema: _schema3, polymorphic: _polymorphic, itemTypes: _itemTypes, ...rest } = field as any\n return { ...rest, fields: children } as RepeaterFieldConfig\n }\n\n return undefined\n}\n\n/**\n * Check if a field is visible to the current role\n */\nfunction isFieldVisible(field: FieldDefinition, role: VisibilityLevel): boolean {\n // Admin can see everything\n if (role === 'admin') {\n return true\n }\n\n // No restrictions means everyone can see it\n const allowed = field.visibleRoles\n if (!allowed || allowed.length === 0) {\n return true\n }\n\n // Check if current role meets any of the allowed visibility levels\n return allowed.some((visibility) => rolePriority[role] >= rolePriority[visibility])\n}\n\n/**\n * Build a Zod validation schema from field configs using the schema registry\n */\nfunction buildValidationSchema(fields: FieldConfig[]): ZodTypeAny {\n const shape: Record<string, ZodTypeAny> = {}\n\n const ctx = {\n getFieldSchema: (field: FieldConfig) => buildSchemaFromRegistry(field, ctx),\n }\n\n for (const field of fields) {\n shape[field.id] = buildSchemaFromRegistry(field, ctx)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n\n/**\n * Create validation schema from a block manifest\n *\n * This is a convenience wrapper around createManifestFormAdapter for RHF validation.\n * Use this when you need a Zod schema for form validation (e.g., with zodResolver).\n *\n * @example\n * ```tsx\n * const validation = createManifestValidation(manifest, { role: 'author' })\n * const form = useForm({\n * resolver: zodResolver(validation.schema),\n * defaultValues: ...\n * })\n * ```\n */\nexport function createManifestValidation(\n manifest: BlockManifest,\n options?: ManifestSchemaOptions,\n): ManifestValidationResult {\n const { fields, schema } = createManifestFormAdapter(manifest, {\n role: options?.role,\n })\n\n return { schema, fields }\n}\n","/**\n * TextField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function buildTextFieldSchema(field: TextFieldConfig): z.ZodTypeAny {\n const ui = (field as any)?.ui ?? {}\n const inputType = ui?.inputType\n\n // Email validation\n if (inputType === 'email') {\n let s = z.string().email('Enter a valid email')\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n return s.optional().nullable().or(z.literal(''))\n }\n\n // Phone validation\n if (inputType === 'tel') {\n let s = z.string().regex(/^[+()0-9\\s\\-]{3,}$/, 'Enter a valid phone number')\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n return s.optional().nullable().or(z.literal(''))\n }\n\n // Standard text validation\n let s = z.string()\n\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n\n if (ui?.pattern) {\n try {\n const re = new RegExp(ui.pattern)\n s = s.regex(re)\n } catch {\n // Ignore invalid regex patterns\n }\n }\n\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n\n return s.optional().nullable().or(z.literal(''))\n}\n","/**\n * NumberField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function buildNumberFieldSchema(field: TextFieldConfig): z.ZodTypeAny {\n const ui = (field as any)?.ui ?? {}\n\n let s: z.ZodTypeAny = z.coerce.number()\n\n if (typeof ui?.min === 'number') {\n s = (s as z.ZodNumber).min(ui.min)\n }\n\n if (typeof ui?.max === 'number') {\n s = (s as z.ZodNumber).max(ui.max)\n }\n\n if (!field.required) {\n s = s.optional().nullable()\n }\n\n return s\n}\n","/**\n * SelectField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { SelectFieldConfig } from '../../fields/types'\n\nexport function buildSelectFieldSchema(field: SelectFieldConfig): z.ZodTypeAny {\n const validValues = field.options?.map((opt) => opt.value) ?? []\n\n if (validValues.length === 0) {\n // No options defined, accept any string\n return field.required ? z.string().min(1) : z.string().optional()\n }\n\n let schema = z.enum(validValues as [string, ...string[]])\n\n if (!field.required) {\n schema = schema.optional() as any\n }\n\n return schema\n}\n","/**\n * BooleanField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { BooleanFieldConfig } from '../../fields/types'\n\nexport function buildBooleanFieldSchema(field: BooleanFieldConfig): z.ZodTypeAny {\n return z.boolean()\n}\n","/**\n * GroupField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type SchemaContext = {\n getFieldSchema: (field: FieldConfig) => z.ZodTypeAny\n}\n\nexport function buildGroupFieldSchema(field: GroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n for (const child of field.fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n","/**\n * ModalGroupField validation schema builder\n * Server-safe - no React, no browser APIs\n *\n * Modal fields are structurally identical to group fields - they just render differently in the UI.\n */\n\nimport { z } from 'zod'\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type SchemaContext = {\n getFieldSchema: (field: FieldConfig) => z.ZodTypeAny\n}\n\nexport function buildModalFieldSchema(field: GroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n // Modal fields use the schema.fields property, not fields directly\n const fields = (field as any).schema?.fields ?? field.fields ?? []\n\n for (const child of fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n","/**\n * RepeaterField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { RepeaterFieldConfig } from '../../fields/types'\nimport type { SchemaContext } from '../GroupField/groupFieldSchema'\n\nexport function buildRepeaterFieldSchema(field: RepeaterFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n let itemSchema: z.ZodTypeAny\n\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: discriminated union based on _type\n const itemTypeSchemas: z.ZodTypeAny[] = []\n\n for (const [typeKey, itemType] of Object.entries(field.itemTypes)) {\n const childShape: Record<string, z.ZodTypeAny> = {\n _type: z.literal(typeKey),\n }\n\n for (const childField of itemType.fields) {\n childShape[childField.id] = ctx.getFieldSchema(childField)\n }\n\n itemTypeSchemas.push(z.object(childShape).catchall(z.unknown()).passthrough())\n }\n\n itemSchema =\n itemTypeSchemas.length > 1\n ? z.discriminatedUnion('_type', itemTypeSchemas as any)\n : itemTypeSchemas[0] ?? z.object({ _type: z.string() }).passthrough()\n } else if (!field.polymorphic && field.fields) {\n // Monomorphic: object with fixed fields\n const childShape: Record<string, z.ZodTypeAny> = {}\n\n for (const childField of field.fields) {\n childShape[childField.id] = ctx.getFieldSchema(childField)\n }\n\n itemSchema = z.object(childShape).catchall(z.unknown()).passthrough()\n } else {\n // Fallback\n itemSchema = z.any()\n }\n\n // If field has custom validation, use that instead of default array schema\n // This allows manifest to define complex validations (e.g., uniqueness constraints)\n if ((field as any).validation) {\n const customValidation = (field as any).validation\n // Apply required constraint\n if (field.required) {\n return customValidation\n }\n return customValidation.optional()\n }\n\n // Create default array schema\n let schema = z.array(itemSchema)\n\n // Apply array constraints\n const minItems = field.minItems ?? 0\n if (minItems > 0) {\n schema = schema.min(minItems, `Must have at least ${minItems} item(s)`)\n }\n\n if (field.maxItems !== undefined) {\n schema = schema.max(field.maxItems, `Must have at most ${field.maxItems} item(s)`)\n }\n\n // Apply required constraint\n if (field.required) {\n return schema\n }\n\n return schema.optional()\n}\n","/**\n * URL Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { UrlFieldConfig } from '../../fields/types'\n\nconst ALLOWED_PROTOCOLS = ['http:', 'https:']\n\n/**\n * Build Zod validation schema for URL field\n */\nexport function buildUrlFieldSchema(field: UrlFieldConfig): z.ZodTypeAny {\n const message = `${field.label} must be a valid URL`\n\n const validator = (value: string) => {\n if (!value) {\n return !field.required\n }\n if (field.allowRelative && value.startsWith('/')) {\n return true\n }\n try {\n const parsed = new URL(value)\n return ALLOWED_PROTOCOLS.includes(parsed.protocol)\n } catch {\n return false\n }\n }\n\n const base = z.string().trim().refine(validator, message)\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal('')]).optional().nullable()\n}\n","/**\n * Time Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { TimeFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for Time field\n */\nexport function buildTimeFieldSchema(field: TimeFieldConfig): z.ZodTypeAny {\n const base = z.string()\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * Date Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { DateFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for Date field\n */\nexport function buildDateFieldSchema(field: DateFieldConfig): z.ZodTypeAny {\n const base = z.string()\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * DateTime Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { DateTimeFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for DateTime field\n *\n * Validates ISO 8601 date-time strings\n */\nexport function buildDateTimeFieldSchema(field: DateTimeFieldConfig): z.ZodTypeAny {\n // ISO 8601 datetime string validation\n const base = z.string().refine(\n (val) => {\n if (!val) return true\n const date = new Date(val)\n return !isNaN(date.getTime())\n },\n { message: `${field.label} must be a valid date-time` },\n )\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * Slug Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { SlugFieldConfig } from '../../fields/types'\n\nconst SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/\n\n/**\n * Build Zod validation schema for Slug field\n *\n * Validates:\n * - Lowercase letters, numbers, and dashes only\n * - Optional slashes for paths (e.g., 'parent/child')\n * - Optional maxLength constraint\n */\nexport function buildSlugFieldSchema(field: SlugFieldConfig): z.ZodTypeAny {\n const base = z.string().regex(SLUG_PATTERN, `${field.label} must use lowercase letters, numbers, and dashes`)\n\n const withLength = field.maxLength\n ? base.max(field.maxLength, { message: `${field.label} must be at most ${field.maxLength} characters` })\n : base\n\n if (field.required) {\n return withLength.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([withLength, z.literal('')]).optional().nullable()\n}\n","/**\n * LinkField Validation Schema\n *\n * Server-safe validation for LinkValue discriminated union.\n * Matches the LinkValue types from @riverbankcms/blocks.\n */\n\nimport { z } from 'zod'\nimport type { LinkFieldConfig } from '../../fields/types'\n\n/**\n * Build validation schema for LinkField\n *\n * Validates a discriminated union of link types:\n * - internal: Links to pages/content within the site\n * - external: Links to external URLs\n * - url: Custom URL links\n */\nexport function buildLinkFieldSchema(field: LinkFieldConfig): z.ZodTypeAny {\n const nullableString = z.union([z.string().min(1), z.null()])\n\n // Internal link schema - links to site pages/content\n const internal = z\n .object({\n kind: z.literal('internal'),\n routeId: z.string().min(1),\n entityId: z.string().min(1).optional(),\n entityType: z.enum(['page', 'content']).optional(),\n href: nullableString.optional(),\n title: nullableString.optional(),\n typeLabel: nullableString.optional(),\n contentTypeKey: nullableString.optional(),\n contentTypeName: nullableString.optional(),\n updatedAt: nullableString.optional(),\n })\n .passthrough()\n\n // External link schema - standard URLs\n const external = z\n .object({\n kind: z.literal('external'),\n href: z.string().min(1),\n })\n .passthrough()\n\n // Custom URL link schema\n const custom = z\n .object({\n kind: z.literal('url'),\n href: z.string().min(1),\n })\n .passthrough()\n\n const linkSchema = z.union([internal, external, custom])\n\n if (field.required) {\n return linkSchema\n }\n\n return z.union([linkSchema, z.null()]).optional()\n}\n","import { z } from 'zod'\nimport type { MediaFieldConfig } from '../../fields/types'\n\n/**\n * Media value schema\n * Validates media object structure with required fields\n */\nconst MediaValueSchema = z.object({\n kind: z.enum(['image', 'video']),\n url: z.string().url(),\n alt: z.string().optional(),\n caption: z.string().optional(),\n credit: z.string().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n size: z.number().optional(),\n mimeType: z.string().optional(),\n})\n\n/**\n * Build Zod validation schema for media field\n * Validates media object structure or null\n */\nexport function buildMediaFieldSchema(config: MediaFieldConfig) {\n let schema = MediaValueSchema.nullable()\n\n if (config.required) {\n schema = schema.refine((val) => val !== null, {\n message: `${config.label} is required`,\n })\n }\n\n return schema\n}\n","/**\n * TabGroupField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TabGroupFieldConfig } from './types'\nimport type { SchemaContext, DefaultValueContext } from '../../registry/schemas'\n\n/**\n * Build validation schema for TabGroupField\n *\n * TabGroup is a UI container that organizes fields into tabs.\n * It validates all child fields across all tabs, and optionally\n * validates the activeTabField if one is specified.\n */\nexport function buildTabGroupFieldSchema(field: TabGroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n // Collect and validate fields from all tabs\n for (const tab of field.tabs) {\n for (const child of tab.fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n }\n\n // If there's an activeTabField, validate it as an enum of tab IDs\n if (field.activeTabField) {\n const tabIds = field.tabs.map((t: { id: string }) => t.id)\n if (tabIds.length > 0) {\n shape[field.activeTabField] = z.enum(tabIds as [string, ...string[]])\n }\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n\n/**\n * Get default value for TabGroupField\n *\n * Returns an object containing default values for all child fields\n * across all tabs, plus the activeTabField if specified.\n *\n * Follows the same pattern as GroupField - includes all fields\n * even if their default value is undefined.\n */\nexport function getTabGroupFieldDefault(field: TabGroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const defaults: Record<string, unknown> = {}\n\n // Collect default values from all tabs (matches GroupField pattern)\n for (const tab of field.tabs) {\n for (const child of tab.fields) {\n defaults[child.id] = ctx.resolve(child)\n }\n }\n\n // Set default active tab if activeTabField is specified\n // Default to first tab - provides a sensible starting point for the UI\n if (field.activeTabField && field.tabs.length > 0) {\n defaults[field.activeTabField] = field.tabs[0].id\n }\n\n return defaults\n}\n","import { z } from 'zod'\nimport type { PresetOrCustomFieldConfig } from './types'\nimport type { SchemaContext } from '../GroupField'\n\nexport function buildPresetOrCustomFieldSchema(\n field: PresetOrCustomFieldConfig,\n _ctx: SchemaContext\n): z.ZodTypeAny {\n // PresetOrCustom accepts either a preset value or a custom string\n const presetValues = field.presets.map((p) => p.value)\n \n return z.string()\n}\n","import { z } from 'zod'\nimport type { ReferenceFieldConfig } from '../../fields/types'\nimport type { SchemaContext } from '../GroupField'\n\nexport function buildReferenceFieldSchema(\n field: ReferenceFieldConfig,\n _ctx: SchemaContext\n): z.ZodTypeAny {\n // Reference field stores a string ID\n return z.string()\n}\n","/**\n * TextField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function getTextFieldDefault(field: TextFieldConfig): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n\n // For required fields, use label as placeholder to pass validation\n if (field.required) {\n return field.label\n }\n\n return ''\n}\n","/**\n * NumberField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function getNumberFieldDefault(field: TextFieldConfig): number | null {\n if (field.defaultValue !== undefined) {\n return typeof field.defaultValue === 'number' ? field.defaultValue : null\n }\n return null\n}\n","/**\n * SelectField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { SelectFieldConfig } from '../../fields/types'\n\nexport function getSelectFieldDefault(field: SelectFieldConfig): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n // Return first option value as fallback (empty string isn't a valid option)\n return field.options?.[0]?.value ?? ''\n}\n","/**\n * BooleanField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { BooleanFieldConfig } from '../../fields/types'\n\nexport function getBooleanFieldDefault(field: BooleanFieldConfig): boolean {\n if (field.defaultValue !== undefined) {\n return Boolean(field.defaultValue)\n }\n return false\n}\n","/**\n * GroupField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nexport function getGroupFieldDefault(field: GroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n\n for (const child of field.fields) {\n obj[child.id] = ctx.resolve(child)\n }\n\n return obj\n}\n","/**\n * ModalGroupField default value builder\n * Server-safe - no React, no browser APIs\n *\n * Modal fields are structurally identical to group fields - they just render differently in the UI.\n */\n\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nexport function getModalFieldDefault(field: GroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n\n // Modal fields use the schema.fields property, not fields directly\n const fields = (field as any).schema?.fields ?? field.fields ?? []\n\n for (const child of fields) {\n obj[child.id] = ctx.resolve(child)\n }\n\n return obj\n}\n","/**\n * RepeaterField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { RepeaterFieldConfig } from '../../fields/types'\nimport type { DefaultValueContext } from '../GroupField/groupFieldDefaults'\n\nexport function getRepeaterFieldDefault(\n field: RepeaterFieldConfig,\n ctx: DefaultValueContext,\n): Array<Record<string, unknown>> {\n // If field has explicit defaultValue, use it\n if (field.defaultValue !== undefined) {\n return Array.isArray(field.defaultValue) ? field.defaultValue : []\n }\n\n // Generate minItems number of empty items to satisfy validation\n const minItems = field.minItems ?? 0\n if (minItems > 0) {\n const items: Array<Record<string, unknown>> = []\n\n // Generate default items based on schema\n for (let i = 0; i < minItems; i++) {\n const item: Record<string, unknown> = {}\n\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: use first item type\n const firstType = Object.keys(field.itemTypes)[0]\n if (firstType) {\n item._type = firstType\n const typeSchema = field.itemTypes[firstType]\n if (typeSchema) {\n for (const childField of typeSchema.fields) {\n item[childField.id] = ctx.resolve(childField)\n }\n }\n }\n } else if (field.fields) {\n // Monomorphic: generate defaults for each field\n for (const childField of field.fields) {\n item[childField.id] = ctx.resolve(childField)\n }\n }\n\n items.push(item)\n }\n\n return items\n }\n\n // Otherwise return empty array\n return []\n}\n","/**\n * URL Field - Default Values\n */\n\nimport type { UrlFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for URL field\n */\nexport function getUrlFieldDefault(field: UrlFieldConfig): string {\n return (field.defaultValue ?? '') as string\n}\n","/**\n * Time Field - Default Values\n */\n\nimport type { TimeFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Time field\n */\nexport function getTimeFieldDefault(field: TimeFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * Date Field - Default Values\n */\n\nimport type { DateFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Date field\n */\nexport function getDateFieldDefault(field: DateFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * DateTime Field - Default Values\n */\n\nimport type { DateTimeFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for DateTime field\n */\nexport function getDateTimeFieldDefault(field: DateTimeFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * Slug Field - Default Values\n */\n\nimport type { SlugFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Slug field\n */\nexport function getSlugFieldDefault(field: SlugFieldConfig): string {\n return (field.defaultValue ?? '') as string\n}\n","/**\n * LinkField Default Value\n *\n * Server-safe default value builder for LinkField.\n */\n\nimport type { LinkFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for LinkField\n *\n * Link fields default to null (no link selected)\n */\nexport function getLinkFieldDefault(_field: LinkFieldConfig): null {\n return null\n}\n","import { buildRichTextSchema } from '@riverbankcms/blocks/system/manifest/richTextSchema'\nimport type { RichTextFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for rich text field\n *\n * Uses the shared rich text schema from @riverbankcms/blocks to ensure consistency\n * between the form editor and block rendering validation.\n *\n * @param config - Rich text field configuration\n * @returns Zod schema for rich text validation\n */\nexport function buildRichTextFieldSchema(config: RichTextFieldConfig) {\n return buildRichTextSchema({\n required: config.required,\n label: config.label,\n })\n}\n","import type { RichTextFieldConfig } from '../../fields/types'\n\n/**\n * Empty TipTap document structure\n */\nexport const EMPTY_RICH_TEXT_DOC = {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n },\n ],\n}\n\n/**\n * Get default value for rich text field\n * Returns empty TipTap document structure\n */\nexport function getRichTextFieldDefaultValue(_config: RichTextFieldConfig) {\n return EMPTY_RICH_TEXT_DOC\n}\n","import type { MediaFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for media field\n * Media fields default to null (no media selected)\n */\nexport function getMediaFieldDefaultValue(_config: MediaFieldConfig): null {\n return null\n}\n","import type { PresetOrCustomFieldConfig } from './types'\nimport type { DefaultValueContext } from '../GroupField'\n\nexport function getPresetOrCustomFieldDefault(\n field: PresetOrCustomFieldConfig,\n _ctx: DefaultValueContext\n): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n \n // Return first preset value as default\n return field.presets[0]?.value ?? ''\n}\n","import type { ReferenceFieldConfig } from '../../fields/types'\nimport type { DefaultValueContext } from '../GroupField'\n\nexport function getReferenceFieldDefault(\n field: ReferenceFieldConfig,\n _ctx: DefaultValueContext\n): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n\n // For required fields, use placeholder ID to pass validation\n if (field.required) {\n return `placeholder-${field.id}`\n }\n\n // Return empty string as default (no reference selected)\n return ''\n}\n","/**\n * Schema and Default Value Registry\n * Maps field types to validation schemas and default value builders\n *\n * Server-safe - no React, no browser APIs\n * Can be used in API routes, server components, and validation\n */\n\nimport { buildTextFieldSchema } from '../widgets/TextField/textFieldSchema'\nimport { getTextFieldDefault } from '../widgets/TextField/textFieldDefaults'\nimport { buildNumberFieldSchema } from '../widgets/NumberField/numberFieldSchema'\nimport { getNumberFieldDefault } from '../widgets/NumberField/numberFieldDefaults'\nimport { buildSelectFieldSchema } from '../widgets/SelectField/selectFieldSchema'\nimport { getSelectFieldDefault } from '../widgets/SelectField/selectFieldDefaults'\nimport { buildBooleanFieldSchema } from '../widgets/BooleanField/booleanFieldSchema'\nimport { getBooleanFieldDefault } from '../widgets/BooleanField/booleanFieldDefaults'\nimport {\n buildGroupFieldSchema,\n type SchemaContext,\n} from '../widgets/GroupField/groupFieldSchema'\nimport {\n getGroupFieldDefault,\n type DefaultValueContext,\n} from '../widgets/GroupField/groupFieldDefaults'\nimport { buildModalFieldSchema } from '../widgets/ModalGroupField/modalFieldSchema'\nimport { getModalFieldDefault } from '../widgets/ModalGroupField/modalFieldDefaults'\nimport { buildRepeaterFieldSchema } from '../widgets/RepeaterField/repeaterFieldSchema'\nimport { getRepeaterFieldDefault } from '../widgets/RepeaterField/repeaterFieldDefaults'\nimport { buildUrlFieldSchema } from '../widgets/UrlField/urlFieldSchema'\nimport { getUrlFieldDefault } from '../widgets/UrlField/urlFieldDefaults'\nimport { buildTimeFieldSchema } from '../widgets/TimeField/timeFieldSchema'\nimport { getTimeFieldDefault } from '../widgets/TimeField/timeFieldDefaults'\nimport { buildDateFieldSchema } from '../widgets/DateField/dateFieldSchema'\nimport { getDateFieldDefault } from '../widgets/DateField/dateFieldDefaults'\nimport { buildDateTimeFieldSchema } from '../widgets/DateTimeField/dateTimeFieldSchema'\nimport { getDateTimeFieldDefault } from '../widgets/DateTimeField/dateTimeFieldDefaults'\nimport { buildSlugFieldSchema } from '../widgets/SlugField/slugFieldSchema'\nimport { getSlugFieldDefault } from '../widgets/SlugField/slugFieldDefaults'\nimport { buildLinkFieldSchema } from '../widgets/LinkField/linkFieldSchema'\nimport { getLinkFieldDefault } from '../widgets/LinkField/linkFieldDefaults'\nimport { buildRichTextFieldSchema } from '../widgets/RichTextField/richTextFieldSchema'\nimport { getRichTextFieldDefaultValue } from '../widgets/RichTextField/richTextFieldDefaults'\nimport { buildMediaFieldSchema } from '../widgets/MediaField/mediaFieldSchema'\nimport { getMediaFieldDefaultValue } from '../widgets/MediaField/mediaFieldDefaults'\nimport { buildTabGroupFieldSchema, getTabGroupFieldDefault } from '../widgets/TabGroupField/tabGroupFieldSchema'\nimport { buildPresetOrCustomFieldSchema } from '../widgets/PresetOrCustomField/presetOrCustomFieldSchema'\nimport { getPresetOrCustomFieldDefault } from '../widgets/PresetOrCustomField/presetOrCustomFieldDefaults'\nimport { buildReferenceFieldSchema } from '../widgets/ReferenceField/referenceFieldSchema'\nimport { getReferenceFieldDefault } from '../widgets/ReferenceField/referenceFieldDefaults'\n\nimport type { FieldConfig } from '../fields/types'\nimport type { ZodTypeAny } from 'zod'\n\n// Re-export canonical context types for use by schema builders\nexport type { SchemaContext, DefaultValueContext }\n\n// Schema builders - require a context to recursively build child schemas\nexport const SCHEMA_BUILDERS = {\n text: buildTextFieldSchema,\n number: buildNumberFieldSchema,\n select: buildSelectFieldSchema,\n boolean: buildBooleanFieldSchema,\n group: buildGroupFieldSchema,\n modal: buildModalFieldSchema,\n repeater: buildRepeaterFieldSchema,\n url: buildUrlFieldSchema,\n time: buildTimeFieldSchema,\n date: buildDateFieldSchema,\n datetime: buildDateTimeFieldSchema,\n slug: buildSlugFieldSchema,\n link: buildLinkFieldSchema,\n richText: buildRichTextFieldSchema,\n media: buildMediaFieldSchema,\n tabGroup: buildTabGroupFieldSchema,\n presetOrCustom: buildPresetOrCustomFieldSchema,\n reference: buildReferenceFieldSchema,\n} as const\n\n// Default value builders - require a context to recursively resolve child defaults\nexport const DEFAULT_VALUE_BUILDERS = {\n text: getTextFieldDefault,\n number: getNumberFieldDefault,\n select: getSelectFieldDefault,\n boolean: getBooleanFieldDefault,\n group: getGroupFieldDefault,\n modal: getModalFieldDefault,\n repeater: getRepeaterFieldDefault,\n url: getUrlFieldDefault,\n time: getTimeFieldDefault,\n date: getDateFieldDefault,\n datetime: getDateTimeFieldDefault,\n slug: getSlugFieldDefault,\n link: getLinkFieldDefault,\n richText: getRichTextFieldDefaultValue,\n media: getMediaFieldDefaultValue,\n tabGroup: getTabGroupFieldDefault,\n presetOrCustom: getPresetOrCustomFieldDefault,\n reference: getReferenceFieldDefault,\n} as const\n\nexport type SchemaBuilderType = keyof typeof SCHEMA_BUILDERS\nexport type DefaultValueBuilderType = keyof typeof DEFAULT_VALUE_BUILDERS\n\n/**\n * Helper to build a validation schema for a single field\n * Recursively handles nested fields (group, repeater)\n */\nexport function buildFieldSchema(field: FieldConfig, ctx: SchemaContext): ZodTypeAny {\n const builder = SCHEMA_BUILDERS[field.type as SchemaBuilderType]\n\n if (!builder) {\n console.warn(`No schema builder registered for field type: ${field.type}`)\n // Return a passthrough schema for unknown types\n return require('zod').z.any()\n }\n\n return builder(field as any, ctx as any)\n}\n\n/**\n * Helper to get default value for a single field\n * Recursively handles nested fields (group, repeater)\n */\nexport function getFieldDefault(field: FieldConfig, ctx: DefaultValueContext): unknown {\n const getDefault = DEFAULT_VALUE_BUILDERS[field.type as DefaultValueBuilderType]\n\n if (!getDefault) {\n console.warn(`No default value builder registered for field type: ${field.type}`)\n return field.defaultValue\n }\n\n return getDefault(field as any, ctx as any)\n}\n","import type { FieldValues } from 'react-hook-form'\n\nimport type { BlockManifest, VisibilityLevel } from '@riverbankcms/blocks'\n\nimport { createManifestFormAdapter } from '../manifest/manifestFormAdapter'\nimport type { ManifestAdapterOptions } from '../manifest/manifestFormAdapter'\nimport type { FieldConfig } from '../fields/types'\nimport { getFieldDefault } from '../registry/schemas'\n\n// Re-export for external consumers\nexport type {\n ManifestAdapterOptions,\n ManifestAdapterResult,\n ManifestSchemaOptions,\n ManifestValidationResult,\n} from '../manifest/manifestFormAdapter'\nexport { createManifestValidation } from '../manifest/manifestFormAdapter'\n\n// Re-export field config types from the unified location\nexport type {\n FieldConfig,\n TextFieldConfig,\n RichTextFieldConfig,\n MediaFieldConfig,\n BooleanFieldConfig,\n DateFieldConfig,\n TimeFieldConfig,\n DateTimeFieldConfig,\n SlugFieldConfig,\n UrlFieldConfig,\n LinkFieldConfig,\n SelectFieldConfig,\n ReferenceFieldConfig,\n GroupFieldConfig,\n RepeaterFieldConfig,\n} from '../fields/types'\n\nexport { createManifestFormAdapter }\n\ntype ManifestDefaultValueOptions = {\n role?: VisibilityLevel\n adapterOptions?: ManifestAdapterOptions\n}\n\n/**\n * Create default values for a manifest's fields\n * Uses the new schema registry for default value resolution\n */\nexport function createManifestDefaultValues<TFieldValues extends FieldValues = FieldValues>(\n manifest: BlockManifest,\n data: Record<string, unknown> = {},\n options: ManifestDefaultValueOptions = {},\n): Partial<TFieldValues> {\n const { fields } = createManifestFormAdapter(manifest, {\n role: options.role,\n ...options.adapterOptions,\n })\n\n const ctx = {\n resolve: (field: FieldConfig) => getFieldDefault(field, ctx),\n }\n\n const result: Record<string, unknown> = {}\n for (const field of fields) {\n const rawValue = data[field.id]\n result[field.id] = ensureFieldValue(field, rawValue, ctx)\n }\n return result as Partial<TFieldValues>\n}\n\ntype DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nfunction ensureFieldValue(\n field: FieldConfig,\n rawValue: unknown,\n ctx: DefaultValueContext,\n): unknown {\n if (field.type === 'repeater') {\n // If no value provided, use default value generator\n if (rawValue === undefined) {\n rawValue = getFieldDefault(field, ctx)\n }\n\n const items = Array.isArray(rawValue) ? rawValue : []\n return items.map((item) => ensureRepeaterItem(field, item, ctx))\n }\n\n if (rawValue === undefined) {\n return getFieldDefault(field, ctx)\n }\n\n return rawValue\n}\n\nfunction ensureRepeaterItem(\n field: Extract<FieldConfig, { type: 'repeater' }>,\n value: unknown,\n ctx: DefaultValueContext,\n): Record<string, unknown> {\n const itemData: Record<string, unknown> =\n typeof value === 'object' && value !== null ? { ...(value as Record<string, unknown>) } : {}\n\n // Handle polymorphic repeaters\n if (field.polymorphic && field.itemTypes) {\n const itemType = typeof itemData._type === 'string' ? itemData._type : Object.keys(field.itemTypes)[0]\n const typeSchema = field.itemTypes[itemType]\n if (!typeSchema) return itemData\n\n for (const child of typeSchema.fields) {\n if ((child as any).type === 'group' && (child as any)?.ui?.flattenInRepeater) {\n const group = child as Extract<FieldConfig, { type: 'group' }>\n for (const gc of group.fields) {\n itemData[gc.id] = ensureFieldValue(gc, itemData[gc.id], ctx)\n }\n } else {\n itemData[child.id] = ensureFieldValue(child, itemData[child.id], ctx)\n }\n }\n return itemData\n }\n\n // Handle monomorphic repeaters\n if (!field.polymorphic && field.fields) {\n for (const child of field.fields) {\n if ((child as any).type === 'group' && (child as any)?.ui?.flattenInRepeater) {\n const group = child as Extract<FieldConfig, { type: 'group' }>\n for (const gc of group.fields) {\n itemData[gc.id] = ensureFieldValue(gc, itemData[gc.id], ctx)\n }\n } else {\n itemData[child.id] = ensureFieldValue(child, itemData[child.id], ctx)\n }\n }\n }\n\n return itemData\n}\n","// src/buildEntryPageOutline.ts\nvar TRANSFORMS = {\n RICHTEXT_FIRST_PARAGRAPH: \"richtext.firstParagraph\",\n DATE_FORMAT_SHORT: \"date.formatShort\",\n DATE_FORMAT_LONG: \"date.formatLong\"\n};\nvar BINDING_SOURCES = [\"field\", \"meta\", \"literal\", \"transform\", \"fallback\"];\nfunction buildEntryPageOutline({\n entry,\n template\n}) {\n if (!template.blocks.length) return null;\n const context = {\n fields: isRecord(entry.content) ? entry.content : {},\n meta: {\n id: entry.id,\n title: entry.title,\n slug: entry.slug,\n path: entry.path,\n publishAt: entry.publishAt,\n status: entry.status\n }\n };\n const outlineBlocks = template.blocks.map((block) => buildBlockFromTemplate(block, context)).filter((block) => Boolean(block));\n if (!outlineBlocks.length) return null;\n const pageName = entry.title || `Entry ${entry.id.slice(0, 8)}`;\n const pagePath = entry.path ?? (entry.slug ? `/${entry.slug}` : \"/\");\n return {\n name: pageName,\n path: pagePath,\n purpose: template.templateKey ?? \"content-entry\",\n blocks: outlineBlocks\n };\n}\nfunction buildBlockFromTemplate(block, context) {\n const base = {\n id: block.id,\n kind: block.blockKind,\n purpose: \"content\",\n content: {},\n bindings: void 0\n };\n if (block.scope === \"template\") {\n const rawContent = isRecord(block.content) ? { ...block.content } : {};\n base.content = normalizeBindingOutput(rawContent);\n return base;\n }\n const bindings = block.bindings ?? {};\n if (!isRecord(bindings)) {\n base.content = normalizeBindingOutput(base.content);\n return base;\n }\n const content = applyBindings(bindings, context);\n base.content = normalizeBindingOutput(content);\n base.bindings = bindings;\n return base;\n}\nfunction applyBindings(bindings, context) {\n const result = {};\n for (const [key, bindingSpec] of Object.entries(bindings)) {\n if (isBindingDescriptor(bindingSpec)) {\n const value = resolveBindingValue(bindingSpec, context);\n if (value !== void 0 && value !== null) {\n result[key] = value;\n }\n continue;\n }\n if (typeof bindingSpec === \"string\") {\n const value = resolveBindingValue({ source: \"field\", path: bindingSpec }, context);\n if (value !== void 0 && value !== null) {\n result[key] = value;\n }\n continue;\n }\n if (isRecord(bindingSpec)) {\n const nested = applyBindings(bindingSpec, context);\n if (Object.keys(nested).length > 0) {\n result[key] = nested;\n }\n }\n }\n return result;\n}\nfunction resolveBindingValue(descriptor, context) {\n switch (descriptor.source) {\n case \"field\":\n return descriptor.path ? getPath(context.fields, descriptor.path) : void 0;\n case \"meta\":\n return descriptor.path ? getPath(context.meta, descriptor.path) : void 0;\n case \"literal\":\n return descriptor.value;\n case \"transform\": {\n const inputDescriptor = descriptor.input && isBindingDescriptorLike(descriptor.input) ? normalizeBindingInput(descriptor.input) : descriptor.path ? normalizeBindingInput(descriptor.path) : null;\n const inputValue = inputDescriptor ? resolveBindingValue(inputDescriptor, context) : void 0;\n return applyTransform(descriptor.transform, inputValue);\n }\n case \"fallback\": {\n for (const option of descriptor.options ?? []) {\n const normalized = normalizeBindingInput(option);\n if (!normalized) continue;\n const value = resolveBindingValue(normalized, context);\n if (value !== void 0 && value !== null && value !== \"\") {\n return value;\n }\n }\n return null;\n }\n default:\n return null;\n }\n}\nfunction getPath(source, path) {\n const segments = path.split(\".\").map((segment) => segment.trim()).filter(Boolean);\n let current = source;\n for (const segment of segments) {\n if (!isRecord(current)) return void 0;\n current = current[segment];\n }\n return current;\n}\nfunction applyTransform(name, value) {\n if (!name) return value;\n switch (name) {\n case TRANSFORMS.RICHTEXT_FIRST_PARAGRAPH:\n return extractFirstParagraph(value);\n case TRANSFORMS.DATE_FORMAT_SHORT:\n return formatDate(value, { dateStyle: \"medium\" });\n case TRANSFORMS.DATE_FORMAT_LONG:\n return formatDate(value, { dateStyle: \"long\", timeStyle: \"short\" });\n default:\n return value;\n }\n}\nfunction extractFirstParagraph(value) {\n if (!isRecord(value)) return null;\n const doc = value;\n if (!Array.isArray(doc.content)) return null;\n for (const node of doc.content) {\n if (!isRecord(node)) continue;\n if (node.type !== \"paragraph\" || !Array.isArray(node.content)) continue;\n const text = node.content.filter((item) => isRecord(item) && item.type === \"text\").map((item) => typeof item.text === \"string\" ? item.text : \"\").join(\"\").trim();\n if (text.length > 0) {\n return text;\n }\n }\n return null;\n}\nfunction formatDate(value, options) {\n if (typeof value !== \"string\") return null;\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return null;\n return new Intl.DateTimeFormat(void 0, options).format(date);\n}\nfunction isBindingDescriptor(value) {\n return isRecord(value) && typeof value.source === \"string\" && BINDING_SOURCES.includes(value.source);\n}\nfunction isBindingDescriptorLike(value) {\n return isBindingDescriptor(value) || typeof value === \"string\" || isRecord(value) && typeof value.source === \"string\" && typeof value.path === \"string\";\n}\nfunction normalizeBindingInput(value) {\n if (isBindingDescriptor(value)) return value;\n if (typeof value === \"string\") {\n return { source: \"field\", path: value };\n }\n if (isRecord(value) && typeof value.source === \"string\") {\n return isBindingDescriptor(value) ? value : null;\n }\n return null;\n}\nfunction isRecord(value) {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction normalizeBindingOutput(value) {\n return normalizeValue(value);\n}\nfunction normalizeValue(value) {\n if (Array.isArray(value)) {\n return value.map((item) => normalizeValue(item));\n }\n if (!isRecord(value)) {\n return value;\n }\n if (isDocWrapper(value)) {\n return normalizeValue(value.doc);\n }\n const entries = Object.entries(value).map(([key, val]) => [key, normalizeValue(val)]);\n return Object.fromEntries(entries);\n}\nfunction isDocWrapper(value) {\n if (!(\"doc\" in value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 1) return false;\n const doc = value.doc;\n return isRecord(doc) && typeof doc.type === \"string\" && doc.type === \"doc\";\n}\n\n// src/siteChrome.ts\nfunction selectPrimaryMenu(menus) {\n if (!menus.length) {\n return null;\n }\n const primary = menus.find((menu) => menu.isPrimary);\n return primary ?? menus[0] ?? null;\n}\nfunction buildMenuViewModel(menu) {\n if (!menu) {\n return { items: [], ctaItem: null };\n }\n const flatItems = menu.items.filter((item) => item.parentId === null && item.urlType !== \"dropdown\").sort((a, b) => a.orderIndex - b.orderIndex);\n const items = [];\n let ctaItem = null;\n for (const item of flatItems) {\n const viewItem = {\n id: item.id,\n label: item.label,\n link: convertNavigationLink(item),\n target: null,\n rel: null,\n active: false\n // TODO: Compute active state based on current route\n };\n if (!ctaItem && Boolean(item.isCta)) {\n ctaItem = { ...viewItem, variant: \"primary\" };\n continue;\n }\n items.push(viewItem);\n }\n return { items, ctaItem };\n}\nfunction buildLogoViewModel(logo, fallbackTitle) {\n if (!logo) {\n return null;\n }\n if (!logo.url && !logo.assetId) {\n return null;\n }\n const alt = logo.alt && logo.alt.trim().length > 0 ? logo.alt : fallbackTitle ?? \"Site logo\";\n const viewModel = {\n type: \"image\",\n src: logo.url ?? \"\",\n // Empty string when url is null - media node uses assetId instead\n alt,\n assetId: logo.assetId ?? void 0,\n width: logo.width ?? void 0,\n height: logo.height ?? void 0\n };\n return viewModel;\n}\nfunction convertNavigationLink(item) {\n const payload = item.url ?? null;\n if (!payload) return null;\n const kind = typeof payload.kind === \"string\" ? payload.kind : null;\n if (kind === \"external\" || kind === \"url\") {\n const href = typeof payload.href === \"string\" ? payload.href : null;\n return href ? { kind, href } : null;\n }\n if (kind === \"internal\") {\n const routeId = typeof payload.routeId === \"string\" ? payload.routeId : null;\n const entityId = typeof payload.entityId === \"string\" ? payload.entityId : null;\n const entityType = typeof payload.entityType === \"string\" && (payload.entityType === \"page\" || payload.entityType === \"content\") ? payload.entityType : null;\n const href = typeof payload.href === \"string\" ? payload.href : null;\n const title = typeof payload.title === \"string\" ? payload.title : null;\n const typeLabel = typeof payload.typeLabel === \"string\" ? payload.typeLabel : null;\n if (!routeId || !entityId || !entityType || !href || !title || !typeLabel) {\n return null;\n }\n return {\n kind: \"internal\",\n routeId,\n entityId,\n entityType,\n href,\n title,\n typeLabel,\n contentTypeKey: typeof payload.contentTypeKey === \"string\" ? payload.contentTypeKey : null,\n contentTypeName: typeof payload.contentTypeName === \"string\" ? payload.contentTypeName : null,\n updatedAt: typeof payload.updatedAt === \"string\" ? payload.updatedAt : null\n };\n }\n return null;\n}\n\n// src/layout.ts\nimport { createManifestDefaultValues } from \"@riverbankcms/block-form/server\";\nimport {\n siteHeaderManifest,\n siteFooterManifest\n} from \"@riverbankcms/blocks\";\nvar HEADER_DEFAULTS = createManifestDefaultValues(siteHeaderManifest);\nvar FOOTER_DEFAULTS = createManifestDefaultValues(siteFooterManifest);\nfunction isRecord2(value) {\n return typeof value === \"object\" && value !== null;\n}\nfunction resolveString(value) {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n return null;\n}\nfunction resolveNumber(value) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n return null;\n}\nfunction normalizeLayout(input) {\n const record = isRecord2(input) ? input : {};\n const headerInput = isRecord2(record.header) ? record.header : {};\n const footerInput = isRecord2(record.footer) ? record.footer : {};\n const header = {\n ...HEADER_DEFAULTS,\n ...headerInput\n };\n const footer = {\n ...FOOTER_DEFAULTS,\n ...footerInput\n };\n const logoInput = isRecord2(record.logo) ? record.logo : {};\n const logoAssetId = resolveString(record.logoAssetId) ?? resolveString(logoInput.assetId) ?? null;\n return {\n logoAssetId,\n logo: {\n assetId: logoAssetId,\n url: resolveString(logoInput.url),\n alt: resolveString(logoInput.alt),\n width: resolveNumber(logoInput.width),\n height: resolveNumber(logoInput.height)\n },\n header,\n footer\n };\n}\nexport {\n buildEntryPageOutline,\n buildLogoViewModel,\n buildMenuViewModel,\n normalizeLayout,\n selectPrimaryMenu\n};\n","/**\n * Layout component with header and footer\n *\n * Renders site header and footer around content. Fetches site data if not provided.\n */\n\nimport { renderBlock, siteFooterManifest, siteHeaderManifest, buildThemeRuntime } from '@riverbankcms/blocks';\nimport { selectPrimaryMenu, buildMenuViewModel, buildLogoViewModel } from '@riverbankcms/site-renderer';\nimport type { RiverbankClient, SiteResponse } from '../../client/types';\n\nexport type HeaderData = {\n menu: ReturnType<typeof buildMenuViewModel>;\n logo: ReturnType<typeof buildLogoViewModel>;\n site: SiteResponse['site'];\n theme: SiteResponse['theme'];\n routes: SiteResponse['routes'];\n};\n\nexport type LayoutProps = {\n // Option 1: Pass pre-fetched site data\n siteData?: SiteResponse;\n\n // Option 2: Fetch site data (provide client + identifier)\n client?: RiverbankClient;\n siteId?: string;\n slug?: string;\n domain?: string;\n\n // Content\n children: React.ReactNode;\n\n // Control rendering\n header?: boolean | ((data: HeaderData) => React.ReactNode);\n footer?: boolean;\n\n // Header variant override (if using default header)\n headerVariant?: 'classic' | 'centered' | 'transparent' | 'floating' | 'editorial';\n};\n\n/**\n * Layout component that wraps content with site header and footer.\n *\n * @example With pre-fetched site data (recommended)\n * ```tsx\n * const site = await client.getSite({ slug: 'my-site' });\n *\n * <Layout siteData={site}>\n * <Page {...pageData} />\n * </Layout>\n * ```\n *\n * @example With automatic fetching\n * ```tsx\n * <Layout client={client} slug=\"my-site\">\n * <Page {...pageData} />\n * </Layout>\n * ```\n */\nexport async function Layout({\n siteData: providedSiteData,\n client,\n siteId,\n slug,\n domain,\n children,\n header = true,\n footer = true,\n headerVariant,\n}: LayoutProps) {\n // Fetch site data if not provided\n let siteData = providedSiteData;\n if (!siteData) {\n if (!client) {\n throw new Error('Layout: must provide either siteData or client');\n }\n if (!siteId && !slug && !domain) {\n throw new Error('Layout: must provide siteId, slug, or domain when using client');\n }\n\n siteData = await client.getSite({ id: siteId, slug, domain });\n }\n\n const { site, theme, navigation, layout, routes } = siteData;\n const themeRuntime = buildThemeRuntime(theme);\n\n // Build view models for header/footer using proper helpers from @riverbankcms/site-renderer\n const menu = selectPrimaryMenu(navigation);\n const menuViewModel = buildMenuViewModel(menu);\n const logoViewModel = buildLogoViewModel(layout.logo ?? null, site.title);\n\n // Prepare header data for custom headers\n const headerData: HeaderData = {\n menu: menuViewModel,\n logo: logoViewModel,\n site,\n theme,\n routes,\n };\n\n // Override header variant if specified\n const headerContent = headerVariant\n ? { ...layout.header, variant: headerVariant }\n : layout.header;\n\n // Override theme header variant if specified\n const themeWithVariant = headerVariant\n ? {\n ...theme,\n header: { ...theme.header, variant: headerVariant },\n }\n : theme;\n\n const viewModelOverrides = {\n $root: {\n siteId: site.id,\n routes,\n theme: themeWithVariant,\n },\n site,\n menu: menuViewModel,\n content: {\n logo: logoViewModel,\n },\n };\n\n // Render header based on type\n let headerElement: React.ReactNode = null;\n if (header === true) {\n // Default header rendering\n headerElement = renderBlock(siteHeaderManifest, headerContent, {\n theme: themeRuntime.tokens,\n themeConfig: themeWithVariant,\n viewModelOverrides,\n });\n } else if (typeof header === 'function') {\n // Custom header rendering\n headerElement = header(headerData);\n }\n\n return (\n <>\n {headerElement}\n\n {children}\n\n {footer && renderBlock(siteFooterManifest, layout.footer, {\n theme: themeRuntime.tokens,\n themeConfig: theme,\n viewModelOverrides,\n })}\n </>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/rendering/components/Page.tsx","../../../block-form/src/manifest/manifestFormAdapter.ts","../../../block-form/src/widgets/TextField/textFieldSchema.ts","../../../block-form/src/widgets/TextField/textFieldDefaults.ts","../../../block-form/src/widgets/NumberField/numberFieldSchema.ts","../../../block-form/src/widgets/NumberField/numberFieldDefaults.ts","../../../block-form/src/widgets/SelectField/selectFieldSchema.ts","../../../block-form/src/widgets/SelectField/selectFieldDefaults.ts","../../../block-form/src/widgets/BooleanField/booleanFieldSchema.ts","../../../block-form/src/widgets/BooleanField/booleanFieldDefaults.ts","../../../block-form/src/widgets/GroupField/groupFieldSchema.ts","../../../block-form/src/widgets/GroupField/groupFieldDefaults.ts","../../../block-form/src/widgets/ModalGroupField/modalFieldSchema.ts","../../../block-form/src/widgets/ModalGroupField/modalFieldDefaults.ts","../../../block-form/src/widgets/RepeaterField/repeaterFieldSchema.ts","../../../block-form/src/widgets/RepeaterField/repeaterFieldDefaults.ts","../../../block-form/src/widgets/UrlField/urlFieldSchema.ts","../../../block-form/src/widgets/UrlField/urlFieldDefaults.ts","../../../block-form/src/widgets/TimeField/timeFieldSchema.ts","../../../block-form/src/widgets/TimeField/timeFieldDefaults.ts","../../../block-form/src/widgets/DateField/dateFieldSchema.ts","../../../block-form/src/widgets/DateField/dateFieldDefaults.ts","../../../block-form/src/widgets/DateTimeField/dateTimeFieldSchema.ts","../../../block-form/src/widgets/DateTimeField/dateTimeFieldDefaults.ts","../../../block-form/src/widgets/SlugField/slugFieldSchema.ts","../../../block-form/src/widgets/SlugField/slugFieldDefaults.ts","../../../block-form/src/widgets/LinkField/linkFieldSchema.ts","../../../block-form/src/widgets/LinkField/linkFieldDefaults.ts","../../../block-form/src/widgets/RichTextField/richTextFieldSchema.ts","../../../block-form/src/widgets/RichTextField/richTextFieldDefaults.ts","../../../block-form/src/widgets/MediaField/mediaFieldSchema.ts","../../../block-form/src/widgets/MediaField/mediaFieldDefaults.ts","../../../block-form/src/widgets/TabGroupField/tabGroupFieldSchema.ts","../../../block-form/src/widgets/PresetOrCustomField/presetOrCustomFieldSchema.ts","../../../block-form/src/widgets/PresetOrCustomField/presetOrCustomFieldDefaults.ts","../../../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts","../../../block-form/src/widgets/ReferenceField/referenceFieldDefaults.ts","../../../block-form/src/registry/schemas.ts","../../../block-form/src/server/index.ts","../../../site-renderer/dist/index.mjs","../../src/rendering/components/Layout.tsx"],"sourcesContent":["/**\n * Pure Page renderer component for Riverbank CMS.\n *\n * This component expects all data to be provided via props.\n * For data fetching, use:\n * - Server-side: `await loadPage({ client, siteId, path })`\n * - Client-side: `usePage({ client, siteId, path })`\n */\n\nimport { PageRenderer, buildThemeRuntime } from '@riverbankcms/blocks';\nimport type { PageOutline, RouteMap, Theme, ThemeTokens, BlockOverrides, OccurrenceContextData } from '@riverbankcms/blocks';\nimport type { ResolvedBlockData } from '../../data';\nimport type { RuntimeSdkConfig } from '../helpers/loadPage';\n\n// Re-export OccurrenceContextData for SDK consumers\nexport type { OccurrenceContextData };\n\nexport type PageProps = {\n // Required data (must be provided by caller)\n page: PageOutline;\n theme: Theme;\n siteId: string;\n\n // Optional data\n themeTokens?: ThemeTokens; // If not provided, will be built from theme\n resolvedData?: ResolvedBlockData; // Pre-fetched block data\n routeMap?: RouteMap;\n /**\n * SDK site configuration containing theme palette overrides.\n * When provided, the SDK palette tokens are merged into the theme tokens,\n * allowing blocks to use SDK-defined color tokens for section backgrounds.\n */\n sdkConfig?: RuntimeSdkConfig | null;\n\n /**\n * Additional context data for content entry pages.\n * Used to pass occurrence context and content entry data to blocks.\n */\n dataContext?: {\n /** Occurrence context for event pages (from URL like /events/yoga/2025-01-15) */\n occurrenceContext?: OccurrenceContextData | null;\n /** Content entry data for template pages */\n contentEntry?: Record<string, unknown> | null;\n };\n\n // Customization\n wrapBlock?: (blockId: string, rendered: React.ReactNode) => React.ReactNode;\n registry?: Parameters<typeof PageRenderer>[0]['registry'];\n usePlaceholders?: boolean;\n /**\n * Custom components to override default block rendering.\n * Keys can be full block kind (\"block.hero\") or short form (\"hero\").\n *\n * This is SSR-safe - no context or hooks required.\n *\n * @example\n * ```tsx\n * <Page\n * {...pageData}\n * blockOverrides={{\n * 'hero': MyCustomHero,\n * 'block.testimonials': MyCustomTestimonials,\n * }}\n * />\n * ```\n */\n blockOverrides?: BlockOverrides;\n};\n\n/**\n * Pure renderer for Riverbank CMS pages.\n *\n * This component expects all data to be provided via props.\n * For data fetching, use:\n * - Server-side: `await loadPage({ client, siteId, path })`\n * - Client-side: `usePage({ client, siteId, path })`\n *\n * @example Server-side (Next.js App Router)\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { loadPage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n *\n * export default async function PageRoute({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-id',\n * path: `/${params.slug}`,\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Client-side\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { usePage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({ apiKey, baseUrl });\n *\n * function MyPage({ path }) {\n * const pageData = usePage({ client, siteId: 'site-id', path });\n *\n * if (pageData.loading) return <LoadingState />;\n * if (pageData.error) return <ErrorState error={pageData.error} />;\n * if (!pageData.page) return <NotFound />;\n *\n * return <Page {...pageData} />;\n * }\n * ```\n */\nexport function Page({\n page,\n theme,\n themeTokens: providedTokens,\n siteId,\n resolvedData,\n routeMap,\n wrapBlock,\n registry,\n usePlaceholders = false,\n blockOverrides,\n sdkConfig,\n dataContext,\n}: PageProps) {\n // Build theme tokens if not provided\n const baseTokens = providedTokens ?? buildThemeRuntime(theme).tokens;\n\n // Merge SDK palette tokens into theme tokens\n // This allows blocks to resolve SDK-defined color tokens (e.g., 'primary' -> '#6d28d9')\n const themeTokens = sdkConfig?.theme?.palette\n ? { ...baseTokens, palette: { ...baseTokens.palette, ...sdkConfig.theme.palette } }\n : baseTokens;\n\n return (\n <PageRenderer\n theme={theme}\n page={page}\n themeTokens={themeTokens}\n usePlaceholders={usePlaceholders}\n dataContext={{\n siteId,\n resolvedData,\n routes: routeMap,\n occurrenceContext: dataContext?.occurrenceContext ?? null,\n contentEntry: dataContext?.contentEntry ?? null,\n }}\n routeMap={routeMap}\n wrapBlock={wrapBlock}\n registry={registry}\n blockOverrides={blockOverrides}\n sdkConfig={sdkConfig}\n />\n );\n}\n","/**\n * Manifest Form Adapter\n *\n * Transforms BlockManifest field definitions into FieldConfigs for form rendering.\n * Handles role-based visibility filtering and structure normalization.\n *\n * This adapter is intentionally minimal - it only does what's truly manifest-specific:\n * 1. Filter fields by role visibility\n * 2. Flatten nested structure (schema.fields → fields)\n *\n * Everything else (validation, defaults, UI) is handled by the generic form system.\n */\n\nimport type { FieldDefinition, VisibilityLevel, BlockManifest } from '@riverbankcms/blocks'\nimport { z, type ZodTypeAny } from 'zod'\n\nimport type { FieldConfig, GroupFieldConfig, RepeaterFieldConfig } from '../fields/types'\nimport { buildFieldSchema as buildSchemaFromRegistry } from '../registry/schemas'\n\nexport interface ManifestAdapterOptions {\n role?: VisibilityLevel\n}\n\nexport interface ManifestAdapterResult {\n fields: FieldConfig[]\n schema: ZodTypeAny\n}\n\n/**\n * Union type for manifest form sources\n * Can be either a BlockManifest or null\n */\nexport type ManifestFormSource = BlockManifest | null\n\n/**\n * Options for manifest validation schema creation\n */\nexport interface ManifestSchemaOptions {\n role?: VisibilityLevel\n widgets?: any // Widget registry for custom validation (unused in new system)\n}\n\n/**\n * Result of createManifestValidation\n */\nexport interface ManifestValidationResult {\n schema: ZodTypeAny\n fields: FieldConfig[]\n}\n\nconst DEFAULT_ROLE: VisibilityLevel = 'author'\n\nconst rolePriority: Record<VisibilityLevel, number> = {\n author: 0,\n designer: 1,\n admin: 2,\n}\n\n/**\n * Transform a BlockManifest into form fields and validation schema\n */\nexport function createManifestFormAdapter(\n manifest: BlockManifest,\n options?: ManifestAdapterOptions,\n): ManifestAdapterResult {\n const role = options?.role ?? DEFAULT_ROLE\n\n const fields = (manifest.fields ?? [])\n .map((field) => transformField(field, role))\n .filter(Boolean) as FieldConfig[]\n\n const schema = buildValidationSchema(fields)\n\n return { fields, schema }\n}\n\n/**\n * Transform a single field, filtering by role and flattening nested structure\n */\nfunction transformField(field: FieldDefinition, role: VisibilityLevel): FieldConfig | undefined {\n // Filter by role visibility\n if (!isFieldVisible(field, role)) {\n return undefined\n }\n\n // For simple fields, pass through directly (types are structurally compatible)\n if (field.type !== 'group' && field.type !== 'repeater') {\n return field as FieldConfig\n }\n\n // For group fields: flatten schema.fields → fields\n if (field.type === 'group') {\n const children = (field.schema?.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (!children.length) {\n return undefined\n }\n\n const { schema: _schema, ...rest } = field as any\n return { ...rest, fields: children } as GroupFieldConfig\n }\n\n // For repeater fields: handle polymorphic vs monomorphic\n if (field.type === 'repeater') {\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: transform each item type's fields\n const itemTypes: Record<string, { label: string; icon?: string; fields: FieldConfig[] }> = {}\n\n for (const [typeKey, itemType] of Object.entries(field.itemTypes)) {\n const children = (itemType.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (children.length > 0) {\n itemTypes[typeKey] = {\n label: itemType.label,\n icon: itemType.icon,\n fields: children,\n }\n }\n }\n\n if (Object.keys(itemTypes).length === 0) {\n return undefined\n }\n\n const { schema: _schema2, ...rest } = field as any\n return { ...rest, itemTypes } as RepeaterFieldConfig\n }\n\n // Monomorphic: flatten schema.fields → fields\n const children = (field.schema?.fields ?? [])\n .map((child) => transformField(child, role))\n .filter(Boolean) as FieldConfig[]\n\n if (!children.length) {\n return undefined\n }\n\n const { schema: _schema3, polymorphic: _polymorphic, itemTypes: _itemTypes, ...rest } = field as any\n return { ...rest, fields: children } as RepeaterFieldConfig\n }\n\n return undefined\n}\n\n/**\n * Check if a field is visible to the current role\n */\nfunction isFieldVisible(field: FieldDefinition, role: VisibilityLevel): boolean {\n // Admin can see everything\n if (role === 'admin') {\n return true\n }\n\n // No restrictions means everyone can see it\n const allowed = field.visibleRoles\n if (!allowed || allowed.length === 0) {\n return true\n }\n\n // Check if current role meets any of the allowed visibility levels\n return allowed.some((visibility) => rolePriority[role] >= rolePriority[visibility])\n}\n\n/**\n * Build a Zod validation schema from field configs using the schema registry\n */\nfunction buildValidationSchema(fields: FieldConfig[]): ZodTypeAny {\n const shape: Record<string, ZodTypeAny> = {}\n\n const ctx = {\n getFieldSchema: (field: FieldConfig) => buildSchemaFromRegistry(field, ctx),\n }\n\n for (const field of fields) {\n shape[field.id] = buildSchemaFromRegistry(field, ctx)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n\n/**\n * Create validation schema from a block manifest\n *\n * This is a convenience wrapper around createManifestFormAdapter for RHF validation.\n * Use this when you need a Zod schema for form validation (e.g., with zodResolver).\n *\n * @example\n * ```tsx\n * const validation = createManifestValidation(manifest, { role: 'author' })\n * const form = useForm({\n * resolver: zodResolver(validation.schema),\n * defaultValues: ...\n * })\n * ```\n */\nexport function createManifestValidation(\n manifest: BlockManifest,\n options?: ManifestSchemaOptions,\n): ManifestValidationResult {\n const { fields, schema } = createManifestFormAdapter(manifest, {\n role: options?.role,\n })\n\n return { schema, fields }\n}\n","/**\n * TextField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function buildTextFieldSchema(field: TextFieldConfig): z.ZodTypeAny {\n const ui = (field as any)?.ui ?? {}\n const inputType = ui?.inputType\n\n // Email validation\n if (inputType === 'email') {\n let s = z.string().email('Enter a valid email')\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n return s.optional().nullable().or(z.literal(''))\n }\n\n // Phone validation\n if (inputType === 'tel') {\n let s = z.string().regex(/^[+()0-9\\s\\-]{3,}$/, 'Enter a valid phone number')\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n return s.optional().nullable().or(z.literal(''))\n }\n\n // Standard text validation\n let s = z.string()\n\n if (typeof field.maxLength === 'number') {\n s = s.max(field.maxLength)\n }\n\n if (ui?.pattern) {\n try {\n const re = new RegExp(ui.pattern)\n s = s.regex(re)\n } catch {\n // Ignore invalid regex patterns\n }\n }\n\n if (field.required) {\n return s.min(1, 'This field is required')\n }\n\n return s.optional().nullable().or(z.literal(''))\n}\n","/**\n * TextField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function getTextFieldDefault(field: TextFieldConfig): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n\n // For required fields, use label as placeholder to pass validation\n if (field.required) {\n return field.label\n }\n\n return ''\n}\n","/**\n * NumberField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function buildNumberFieldSchema(field: TextFieldConfig): z.ZodTypeAny {\n const ui = (field as any)?.ui ?? {}\n\n let s: z.ZodTypeAny = z.coerce.number()\n\n if (typeof ui?.min === 'number') {\n s = (s as z.ZodNumber).min(ui.min)\n }\n\n if (typeof ui?.max === 'number') {\n s = (s as z.ZodNumber).max(ui.max)\n }\n\n if (!field.required) {\n s = s.optional().nullable()\n }\n\n return s\n}\n","/**\n * NumberField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { TextFieldConfig } from '../../fields/types'\n\nexport function getNumberFieldDefault(field: TextFieldConfig): number | null {\n if (field.defaultValue !== undefined) {\n return typeof field.defaultValue === 'number' ? field.defaultValue : null\n }\n return null\n}\n","/**\n * SelectField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { SelectFieldConfig } from '../../fields/types'\n\nexport function buildSelectFieldSchema(field: SelectFieldConfig): z.ZodTypeAny {\n const validValues = field.options?.map((opt) => opt.value) ?? []\n\n if (validValues.length === 0) {\n // No options defined, accept any string\n return field.required ? z.string().min(1) : z.string().optional()\n }\n\n let schema = z.enum(validValues as [string, ...string[]])\n\n if (!field.required) {\n schema = schema.optional() as any\n }\n\n return schema\n}\n","/**\n * SelectField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { SelectFieldConfig } from '../../fields/types'\n\nexport function getSelectFieldDefault(field: SelectFieldConfig): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n // Return first option value as fallback (empty string isn't a valid option)\n return field.options?.[0]?.value ?? ''\n}\n","/**\n * BooleanField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { BooleanFieldConfig } from '../../fields/types'\n\nexport function buildBooleanFieldSchema(field: BooleanFieldConfig): z.ZodTypeAny {\n return z.boolean()\n}\n","/**\n * BooleanField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { BooleanFieldConfig } from '../../fields/types'\n\nexport function getBooleanFieldDefault(field: BooleanFieldConfig): boolean {\n if (field.defaultValue !== undefined) {\n return Boolean(field.defaultValue)\n }\n return false\n}\n","/**\n * GroupField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type SchemaContext = {\n getFieldSchema: (field: FieldConfig) => z.ZodTypeAny\n}\n\nexport function buildGroupFieldSchema(field: GroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n for (const child of field.fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n","/**\n * GroupField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nexport function getGroupFieldDefault(field: GroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n\n for (const child of field.fields) {\n obj[child.id] = ctx.resolve(child)\n }\n\n return obj\n}\n","/**\n * ModalGroupField validation schema builder\n * Server-safe - no React, no browser APIs\n *\n * Modal fields are structurally identical to group fields - they just render differently in the UI.\n */\n\nimport { z } from 'zod'\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type SchemaContext = {\n getFieldSchema: (field: FieldConfig) => z.ZodTypeAny\n}\n\nexport function buildModalFieldSchema(field: GroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n // Modal fields use the schema.fields property, not fields directly\n const fields = (field as any).schema?.fields ?? field.fields ?? []\n\n for (const child of fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n","/**\n * ModalGroupField default value builder\n * Server-safe - no React, no browser APIs\n *\n * Modal fields are structurally identical to group fields - they just render differently in the UI.\n */\n\nimport type { GroupFieldConfig, FieldConfig } from '../../fields/types'\n\nexport type DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nexport function getModalFieldDefault(field: GroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const obj: Record<string, unknown> = {}\n\n // Modal fields use the schema.fields property, not fields directly\n const fields = (field as any).schema?.fields ?? field.fields ?? []\n\n for (const child of fields) {\n obj[child.id] = ctx.resolve(child)\n }\n\n return obj\n}\n","/**\n * RepeaterField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { RepeaterFieldConfig } from '../../fields/types'\nimport type { SchemaContext } from '../GroupField/groupFieldSchema'\n\nexport function buildRepeaterFieldSchema(field: RepeaterFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n let itemSchema: z.ZodTypeAny\n\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: discriminated union based on _type\n const itemTypeSchemas: z.ZodTypeAny[] = []\n\n for (const [typeKey, itemType] of Object.entries(field.itemTypes)) {\n const childShape: Record<string, z.ZodTypeAny> = {\n _type: z.literal(typeKey),\n }\n\n for (const childField of itemType.fields) {\n childShape[childField.id] = ctx.getFieldSchema(childField)\n }\n\n itemTypeSchemas.push(z.object(childShape).catchall(z.unknown()).passthrough())\n }\n\n itemSchema =\n itemTypeSchemas.length > 1\n ? z.discriminatedUnion('_type', itemTypeSchemas as any)\n : itemTypeSchemas[0] ?? z.object({ _type: z.string() }).passthrough()\n } else if (!field.polymorphic && field.fields) {\n // Monomorphic: object with fixed fields\n const childShape: Record<string, z.ZodTypeAny> = {}\n\n for (const childField of field.fields) {\n childShape[childField.id] = ctx.getFieldSchema(childField)\n }\n\n itemSchema = z.object(childShape).catchall(z.unknown()).passthrough()\n } else {\n // Fallback\n itemSchema = z.any()\n }\n\n // If field has custom validation, use that instead of default array schema\n // This allows manifest to define complex validations (e.g., uniqueness constraints)\n if ((field as any).validation) {\n const customValidation = (field as any).validation\n // Apply required constraint\n if (field.required) {\n return customValidation\n }\n return customValidation.optional()\n }\n\n // Create default array schema\n let schema = z.array(itemSchema)\n\n // Apply array constraints\n const minItems = field.minItems ?? 0\n if (minItems > 0) {\n schema = schema.min(minItems, `Must have at least ${minItems} item(s)`)\n }\n\n if (field.maxItems !== undefined) {\n schema = schema.max(field.maxItems, `Must have at most ${field.maxItems} item(s)`)\n }\n\n // Apply required constraint\n if (field.required) {\n return schema\n }\n\n return schema.optional()\n}\n","/**\n * RepeaterField default value builder\n * Server-safe - no React, no browser APIs\n */\n\nimport type { RepeaterFieldConfig } from '../../fields/types'\nimport type { DefaultValueContext } from '../GroupField/groupFieldDefaults'\n\nexport function getRepeaterFieldDefault(\n field: RepeaterFieldConfig,\n ctx: DefaultValueContext,\n): Array<Record<string, unknown>> {\n // If field has explicit defaultValue, use it\n if (field.defaultValue !== undefined) {\n return Array.isArray(field.defaultValue) ? field.defaultValue : []\n }\n\n // Generate minItems number of empty items to satisfy validation\n const minItems = field.minItems ?? 0\n if (minItems > 0) {\n const items: Array<Record<string, unknown>> = []\n\n // Generate default items based on schema\n for (let i = 0; i < minItems; i++) {\n const item: Record<string, unknown> = {}\n\n if (field.polymorphic && field.itemTypes) {\n // Polymorphic: use first item type\n const firstType = Object.keys(field.itemTypes)[0]\n if (firstType) {\n item._type = firstType\n const typeSchema = field.itemTypes[firstType]\n if (typeSchema) {\n for (const childField of typeSchema.fields) {\n item[childField.id] = ctx.resolve(childField)\n }\n }\n }\n } else if (field.fields) {\n // Monomorphic: generate defaults for each field\n for (const childField of field.fields) {\n item[childField.id] = ctx.resolve(childField)\n }\n }\n\n items.push(item)\n }\n\n return items\n }\n\n // Otherwise return empty array\n return []\n}\n","/**\n * URL Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { UrlFieldConfig } from '../../fields/types'\n\nconst ALLOWED_PROTOCOLS = ['http:', 'https:']\n\n/**\n * Build Zod validation schema for URL field\n */\nexport function buildUrlFieldSchema(field: UrlFieldConfig): z.ZodTypeAny {\n const message = `${field.label} must be a valid URL`\n\n const validator = (value: string) => {\n if (!value) {\n return !field.required\n }\n if (field.allowRelative && value.startsWith('/')) {\n return true\n }\n try {\n const parsed = new URL(value)\n return ALLOWED_PROTOCOLS.includes(parsed.protocol)\n } catch {\n return false\n }\n }\n\n const base = z.string().trim().refine(validator, message)\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal('')]).optional().nullable()\n}\n","/**\n * URL Field - Default Values\n */\n\nimport type { UrlFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for URL field\n */\nexport function getUrlFieldDefault(field: UrlFieldConfig): string {\n return (field.defaultValue ?? '') as string\n}\n","/**\n * Time Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { TimeFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for Time field\n */\nexport function buildTimeFieldSchema(field: TimeFieldConfig): z.ZodTypeAny {\n const base = z.string()\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * Time Field - Default Values\n */\n\nimport type { TimeFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Time field\n */\nexport function getTimeFieldDefault(field: TimeFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * Date Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { DateFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for Date field\n */\nexport function buildDateFieldSchema(field: DateFieldConfig): z.ZodTypeAny {\n const base = z.string()\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * Date Field - Default Values\n */\n\nimport type { DateFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Date field\n */\nexport function getDateFieldDefault(field: DateFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * DateTime Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { DateTimeFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for DateTime field\n *\n * Validates ISO 8601 date-time strings\n */\nexport function buildDateTimeFieldSchema(field: DateTimeFieldConfig): z.ZodTypeAny {\n // ISO 8601 datetime string validation\n const base = z.string().refine(\n (val) => {\n if (!val) return true\n const date = new Date(val)\n return !isNaN(date.getTime())\n },\n { message: `${field.label} must be a valid date-time` },\n )\n\n if (field.required) {\n return base.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([base, z.literal(''), z.null()]).optional().nullable()\n}\n","/**\n * DateTime Field - Default Values\n */\n\nimport type { DateTimeFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for DateTime field\n */\nexport function getDateTimeFieldDefault(field: DateTimeFieldConfig): string | null {\n return (field.defaultValue ?? null) as string | null\n}\n","/**\n * Slug Field - Validation Schema\n */\n\nimport { z } from 'zod'\nimport type { SlugFieldConfig } from '../../fields/types'\n\nconst SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/\n\n/**\n * Build Zod validation schema for Slug field\n *\n * Validates:\n * - Lowercase letters, numbers, and dashes only\n * - Optional slashes for paths (e.g., 'parent/child')\n * - Optional maxLength constraint\n */\nexport function buildSlugFieldSchema(field: SlugFieldConfig): z.ZodTypeAny {\n const base = z.string().regex(SLUG_PATTERN, `${field.label} must use lowercase letters, numbers, and dashes`)\n\n const withLength = field.maxLength\n ? base.max(field.maxLength, { message: `${field.label} must be at most ${field.maxLength} characters` })\n : base\n\n if (field.required) {\n return withLength.min(1, { message: `${field.label} is required` })\n }\n\n return z.union([withLength, z.literal('')]).optional().nullable()\n}\n","/**\n * Slug Field - Default Values\n */\n\nimport type { SlugFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for Slug field\n */\nexport function getSlugFieldDefault(field: SlugFieldConfig): string {\n return (field.defaultValue ?? '') as string\n}\n","/**\n * LinkField Validation Schema\n *\n * Server-safe validation for LinkValue discriminated union.\n * Matches the LinkValue types from @riverbankcms/blocks.\n */\n\nimport { z } from 'zod'\nimport type { LinkFieldConfig } from '../../fields/types'\n\n/**\n * Build validation schema for LinkField\n *\n * Validates a discriminated union of link types:\n * - internal: Links to pages/content within the site\n * - external: Links to external URLs\n * - url: Custom URL links\n */\nexport function buildLinkFieldSchema(field: LinkFieldConfig): z.ZodTypeAny {\n const nullableString = z.union([z.string().min(1), z.null()])\n\n // Internal link schema - links to site pages/content\n const internal = z\n .object({\n kind: z.literal('internal'),\n routeId: z.string().min(1),\n entityId: z.string().min(1).optional(),\n entityType: z.enum(['page', 'content']).optional(),\n href: nullableString.optional(),\n title: nullableString.optional(),\n typeLabel: nullableString.optional(),\n contentTypeKey: nullableString.optional(),\n contentTypeName: nullableString.optional(),\n updatedAt: nullableString.optional(),\n })\n .passthrough()\n\n // External link schema - standard URLs\n const external = z\n .object({\n kind: z.literal('external'),\n href: z.string().min(1),\n })\n .passthrough()\n\n // Custom URL link schema\n const custom = z\n .object({\n kind: z.literal('url'),\n href: z.string().min(1),\n })\n .passthrough()\n\n const linkSchema = z.union([internal, external, custom])\n\n if (field.required) {\n return linkSchema\n }\n\n return z.union([linkSchema, z.null()]).optional()\n}\n","/**\n * LinkField Default Value\n *\n * Server-safe default value builder for LinkField.\n */\n\nimport type { LinkFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for LinkField\n *\n * Link fields default to null (no link selected)\n */\nexport function getLinkFieldDefault(_field: LinkFieldConfig): null {\n return null\n}\n","import { buildRichTextSchema } from '@riverbankcms/blocks/system/manifest/richTextSchema'\nimport type { RichTextFieldConfig } from '../../fields/types'\n\n/**\n * Build Zod validation schema for rich text field\n *\n * Uses the shared rich text schema from @riverbankcms/blocks to ensure consistency\n * between the form editor and block rendering validation.\n *\n * @param config - Rich text field configuration\n * @returns Zod schema for rich text validation\n */\nexport function buildRichTextFieldSchema(config: RichTextFieldConfig) {\n return buildRichTextSchema({\n required: config.required,\n label: config.label,\n })\n}\n","import type { RichTextFieldConfig } from '../../fields/types'\n\n/**\n * Empty TipTap document structure\n */\nexport const EMPTY_RICH_TEXT_DOC = {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n },\n ],\n}\n\n/**\n * Get default value for rich text field\n * Returns empty TipTap document structure\n */\nexport function getRichTextFieldDefaultValue(_config: RichTextFieldConfig) {\n return EMPTY_RICH_TEXT_DOC\n}\n","import { z } from 'zod'\nimport type { MediaFieldConfig } from '../../fields/types'\n\n/**\n * Media value schema\n * Validates media object structure with required fields\n */\nconst MediaValueSchema = z.object({\n kind: z.enum(['image', 'video']),\n url: z.string().url(),\n alt: z.string().optional(),\n caption: z.string().optional(),\n credit: z.string().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n size: z.number().optional(),\n mimeType: z.string().optional(),\n})\n\n/**\n * Build Zod validation schema for media field\n * Validates media object structure or null\n */\nexport function buildMediaFieldSchema(config: MediaFieldConfig) {\n let schema = MediaValueSchema.nullable()\n\n if (config.required) {\n schema = schema.refine((val) => val !== null, {\n message: `${config.label} is required`,\n })\n }\n\n return schema\n}\n","import type { MediaFieldConfig } from '../../fields/types'\n\n/**\n * Get default value for media field\n * Media fields default to null (no media selected)\n */\nexport function getMediaFieldDefaultValue(_config: MediaFieldConfig): null {\n return null\n}\n","/**\n * TabGroupField validation schema builder\n * Server-safe - no React, no browser APIs\n */\n\nimport { z } from 'zod'\nimport type { TabGroupFieldConfig } from './types'\nimport type { SchemaContext, DefaultValueContext } from '../../registry/schemas'\n\n/**\n * Build validation schema for TabGroupField\n *\n * TabGroup is a UI container that organizes fields into tabs.\n * It validates all child fields across all tabs, and optionally\n * validates the activeTabField if one is specified.\n */\nexport function buildTabGroupFieldSchema(field: TabGroupFieldConfig, ctx: SchemaContext): z.ZodTypeAny {\n const shape: Record<string, any> = {}\n\n // Collect and validate fields from all tabs\n for (const tab of field.tabs) {\n for (const child of tab.fields) {\n shape[child.id] = ctx.getFieldSchema(child)\n }\n }\n\n // If there's an activeTabField, validate it as an enum of tab IDs\n if (field.activeTabField) {\n const tabIds = field.tabs.map((t: { id: string }) => t.id)\n if (tabIds.length > 0) {\n shape[field.activeTabField] = z.enum(tabIds as [string, ...string[]])\n }\n }\n\n return z.object(shape).catchall(z.unknown()).passthrough()\n}\n\n/**\n * Get default value for TabGroupField\n *\n * Returns an object containing default values for all child fields\n * across all tabs, plus the activeTabField if specified.\n *\n * Follows the same pattern as GroupField - includes all fields\n * even if their default value is undefined.\n */\nexport function getTabGroupFieldDefault(field: TabGroupFieldConfig, ctx: DefaultValueContext): Record<string, unknown> {\n const defaults: Record<string, unknown> = {}\n\n // Collect default values from all tabs (matches GroupField pattern)\n for (const tab of field.tabs) {\n for (const child of tab.fields) {\n defaults[child.id] = ctx.resolve(child)\n }\n }\n\n // Set default active tab if activeTabField is specified\n // Default to first tab - provides a sensible starting point for the UI\n if (field.activeTabField && field.tabs.length > 0) {\n defaults[field.activeTabField] = field.tabs[0].id\n }\n\n return defaults\n}\n","import { z } from 'zod'\nimport type { PresetOrCustomFieldConfig } from './types'\nimport type { SchemaContext } from '../GroupField'\n\nexport function buildPresetOrCustomFieldSchema(\n field: PresetOrCustomFieldConfig,\n _ctx: SchemaContext\n): z.ZodTypeAny {\n // PresetOrCustom accepts either a preset value or a custom string\n const presetValues = field.presets.map((p) => p.value)\n \n return z.string()\n}\n","import type { PresetOrCustomFieldConfig } from './types'\nimport type { DefaultValueContext } from '../GroupField'\n\nexport function getPresetOrCustomFieldDefault(\n field: PresetOrCustomFieldConfig,\n _ctx: DefaultValueContext\n): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n \n // Return first preset value as default\n return field.presets[0]?.value ?? ''\n}\n","import { z } from 'zod'\nimport type { ReferenceFieldConfig } from '../../fields/types'\nimport type { SchemaContext } from '../GroupField'\n\nexport function buildReferenceFieldSchema(\n field: ReferenceFieldConfig,\n _ctx: SchemaContext\n): z.ZodTypeAny {\n // Reference field stores a string ID\n return z.string()\n}\n","import type { ReferenceFieldConfig } from '../../fields/types'\nimport type { DefaultValueContext } from '../GroupField'\n\nexport function getReferenceFieldDefault(\n field: ReferenceFieldConfig,\n _ctx: DefaultValueContext\n): string {\n if (field.defaultValue !== undefined && field.defaultValue !== null) {\n return String(field.defaultValue)\n }\n\n // For required fields, use placeholder ID to pass validation\n if (field.required) {\n return `placeholder-${field.id}`\n }\n\n // Return empty string as default (no reference selected)\n return ''\n}\n","/**\n * Schema and Default Value Registry\n * Maps field types to validation schemas and default value builders\n *\n * Server-safe - no React, no browser APIs\n * Can be used in API routes, server components, and validation\n */\n\nimport { buildTextFieldSchema } from '../widgets/TextField/textFieldSchema'\nimport { getTextFieldDefault } from '../widgets/TextField/textFieldDefaults'\nimport { buildNumberFieldSchema } from '../widgets/NumberField/numberFieldSchema'\nimport { getNumberFieldDefault } from '../widgets/NumberField/numberFieldDefaults'\nimport { buildSelectFieldSchema } from '../widgets/SelectField/selectFieldSchema'\nimport { getSelectFieldDefault } from '../widgets/SelectField/selectFieldDefaults'\nimport { buildBooleanFieldSchema } from '../widgets/BooleanField/booleanFieldSchema'\nimport { getBooleanFieldDefault } from '../widgets/BooleanField/booleanFieldDefaults'\nimport {\n buildGroupFieldSchema,\n type SchemaContext,\n} from '../widgets/GroupField/groupFieldSchema'\nimport {\n getGroupFieldDefault,\n type DefaultValueContext,\n} from '../widgets/GroupField/groupFieldDefaults'\nimport { buildModalFieldSchema } from '../widgets/ModalGroupField/modalFieldSchema'\nimport { getModalFieldDefault } from '../widgets/ModalGroupField/modalFieldDefaults'\nimport { buildRepeaterFieldSchema } from '../widgets/RepeaterField/repeaterFieldSchema'\nimport { getRepeaterFieldDefault } from '../widgets/RepeaterField/repeaterFieldDefaults'\nimport { buildUrlFieldSchema } from '../widgets/UrlField/urlFieldSchema'\nimport { getUrlFieldDefault } from '../widgets/UrlField/urlFieldDefaults'\nimport { buildTimeFieldSchema } from '../widgets/TimeField/timeFieldSchema'\nimport { getTimeFieldDefault } from '../widgets/TimeField/timeFieldDefaults'\nimport { buildDateFieldSchema } from '../widgets/DateField/dateFieldSchema'\nimport { getDateFieldDefault } from '../widgets/DateField/dateFieldDefaults'\nimport { buildDateTimeFieldSchema } from '../widgets/DateTimeField/dateTimeFieldSchema'\nimport { getDateTimeFieldDefault } from '../widgets/DateTimeField/dateTimeFieldDefaults'\nimport { buildSlugFieldSchema } from '../widgets/SlugField/slugFieldSchema'\nimport { getSlugFieldDefault } from '../widgets/SlugField/slugFieldDefaults'\nimport { buildLinkFieldSchema } from '../widgets/LinkField/linkFieldSchema'\nimport { getLinkFieldDefault } from '../widgets/LinkField/linkFieldDefaults'\nimport { buildRichTextFieldSchema } from '../widgets/RichTextField/richTextFieldSchema'\nimport { getRichTextFieldDefaultValue } from '../widgets/RichTextField/richTextFieldDefaults'\nimport { buildMediaFieldSchema } from '../widgets/MediaField/mediaFieldSchema'\nimport { getMediaFieldDefaultValue } from '../widgets/MediaField/mediaFieldDefaults'\nimport { buildTabGroupFieldSchema, getTabGroupFieldDefault } from '../widgets/TabGroupField/tabGroupFieldSchema'\nimport { buildPresetOrCustomFieldSchema } from '../widgets/PresetOrCustomField/presetOrCustomFieldSchema'\nimport { getPresetOrCustomFieldDefault } from '../widgets/PresetOrCustomField/presetOrCustomFieldDefaults'\nimport { buildReferenceFieldSchema } from '../widgets/ReferenceField/referenceFieldSchema'\nimport { getReferenceFieldDefault } from '../widgets/ReferenceField/referenceFieldDefaults'\n\nimport type { FieldConfig } from '../fields/types'\nimport type { ZodTypeAny } from 'zod'\n\n// Re-export canonical context types for use by schema builders\nexport type { SchemaContext, DefaultValueContext }\n\n// Schema builders - require a context to recursively build child schemas\nexport const SCHEMA_BUILDERS = {\n text: buildTextFieldSchema,\n number: buildNumberFieldSchema,\n select: buildSelectFieldSchema,\n boolean: buildBooleanFieldSchema,\n group: buildGroupFieldSchema,\n modal: buildModalFieldSchema,\n repeater: buildRepeaterFieldSchema,\n url: buildUrlFieldSchema,\n time: buildTimeFieldSchema,\n date: buildDateFieldSchema,\n datetime: buildDateTimeFieldSchema,\n slug: buildSlugFieldSchema,\n link: buildLinkFieldSchema,\n richText: buildRichTextFieldSchema,\n media: buildMediaFieldSchema,\n tabGroup: buildTabGroupFieldSchema,\n presetOrCustom: buildPresetOrCustomFieldSchema,\n reference: buildReferenceFieldSchema,\n} as const\n\n// Default value builders - require a context to recursively resolve child defaults\nexport const DEFAULT_VALUE_BUILDERS = {\n text: getTextFieldDefault,\n number: getNumberFieldDefault,\n select: getSelectFieldDefault,\n boolean: getBooleanFieldDefault,\n group: getGroupFieldDefault,\n modal: getModalFieldDefault,\n repeater: getRepeaterFieldDefault,\n url: getUrlFieldDefault,\n time: getTimeFieldDefault,\n date: getDateFieldDefault,\n datetime: getDateTimeFieldDefault,\n slug: getSlugFieldDefault,\n link: getLinkFieldDefault,\n richText: getRichTextFieldDefaultValue,\n media: getMediaFieldDefaultValue,\n tabGroup: getTabGroupFieldDefault,\n presetOrCustom: getPresetOrCustomFieldDefault,\n reference: getReferenceFieldDefault,\n} as const\n\nexport type SchemaBuilderType = keyof typeof SCHEMA_BUILDERS\nexport type DefaultValueBuilderType = keyof typeof DEFAULT_VALUE_BUILDERS\n\n/**\n * Helper to build a validation schema for a single field\n * Recursively handles nested fields (group, repeater)\n */\nexport function buildFieldSchema(field: FieldConfig, ctx: SchemaContext): ZodTypeAny {\n const builder = SCHEMA_BUILDERS[field.type as SchemaBuilderType]\n\n if (!builder) {\n console.warn(`No schema builder registered for field type: ${field.type}`)\n // Return a passthrough schema for unknown types\n return require('zod').z.any()\n }\n\n return builder(field as any, ctx as any)\n}\n\n/**\n * Helper to get default value for a single field\n * Recursively handles nested fields (group, repeater)\n */\nexport function getFieldDefault(field: FieldConfig, ctx: DefaultValueContext): unknown {\n const getDefault = DEFAULT_VALUE_BUILDERS[field.type as DefaultValueBuilderType]\n\n if (!getDefault) {\n console.warn(`No default value builder registered for field type: ${field.type}`)\n return field.defaultValue\n }\n\n return getDefault(field as any, ctx as any)\n}\n","import type { FieldValues } from 'react-hook-form'\n\nimport type { BlockManifest, VisibilityLevel } from '@riverbankcms/blocks'\n\nimport { createManifestFormAdapter } from '../manifest/manifestFormAdapter'\nimport type { ManifestAdapterOptions } from '../manifest/manifestFormAdapter'\nimport type { FieldConfig } from '../fields/types'\nimport { getFieldDefault } from '../registry/schemas'\n\n// Re-export for external consumers\nexport type {\n ManifestAdapterOptions,\n ManifestAdapterResult,\n ManifestSchemaOptions,\n ManifestValidationResult,\n} from '../manifest/manifestFormAdapter'\nexport { createManifestValidation } from '../manifest/manifestFormAdapter'\n\n// Re-export field config types from the unified location\nexport type {\n FieldConfig,\n TextFieldConfig,\n RichTextFieldConfig,\n MediaFieldConfig,\n BooleanFieldConfig,\n DateFieldConfig,\n TimeFieldConfig,\n DateTimeFieldConfig,\n SlugFieldConfig,\n UrlFieldConfig,\n LinkFieldConfig,\n SelectFieldConfig,\n ReferenceFieldConfig,\n GroupFieldConfig,\n RepeaterFieldConfig,\n} from '../fields/types'\n\nexport { createManifestFormAdapter }\n\ntype ManifestDefaultValueOptions = {\n role?: VisibilityLevel\n adapterOptions?: ManifestAdapterOptions\n}\n\n/**\n * Create default values for a manifest's fields\n * Uses the new schema registry for default value resolution\n */\nexport function createManifestDefaultValues<TFieldValues extends FieldValues = FieldValues>(\n manifest: BlockManifest,\n data: Record<string, unknown> = {},\n options: ManifestDefaultValueOptions = {},\n): Partial<TFieldValues> {\n const { fields } = createManifestFormAdapter(manifest, {\n role: options.role,\n ...options.adapterOptions,\n })\n\n const ctx = {\n resolve: (field: FieldConfig) => getFieldDefault(field, ctx),\n }\n\n const result: Record<string, unknown> = {}\n for (const field of fields) {\n const rawValue = data[field.id]\n result[field.id] = ensureFieldValue(field, rawValue, ctx)\n }\n return result as Partial<TFieldValues>\n}\n\ntype DefaultValueContext = {\n resolve: (field: FieldConfig) => unknown\n}\n\nfunction ensureFieldValue(\n field: FieldConfig,\n rawValue: unknown,\n ctx: DefaultValueContext,\n): unknown {\n if (field.type === 'repeater') {\n // If no value provided, use default value generator\n if (rawValue === undefined) {\n rawValue = getFieldDefault(field, ctx)\n }\n\n const items = Array.isArray(rawValue) ? rawValue : []\n return items.map((item) => ensureRepeaterItem(field, item, ctx))\n }\n\n if (rawValue === undefined) {\n return getFieldDefault(field, ctx)\n }\n\n return rawValue\n}\n\nfunction ensureRepeaterItem(\n field: Extract<FieldConfig, { type: 'repeater' }>,\n value: unknown,\n ctx: DefaultValueContext,\n): Record<string, unknown> {\n const itemData: Record<string, unknown> =\n typeof value === 'object' && value !== null ? { ...(value as Record<string, unknown>) } : {}\n\n // Handle polymorphic repeaters\n if (field.polymorphic && field.itemTypes) {\n const itemType = typeof itemData._type === 'string' ? itemData._type : Object.keys(field.itemTypes)[0]\n const typeSchema = field.itemTypes[itemType]\n if (!typeSchema) return itemData\n\n for (const child of typeSchema.fields) {\n if ((child as any).type === 'group' && (child as any)?.ui?.flattenInRepeater) {\n const group = child as Extract<FieldConfig, { type: 'group' }>\n for (const gc of group.fields) {\n itemData[gc.id] = ensureFieldValue(gc, itemData[gc.id], ctx)\n }\n } else {\n itemData[child.id] = ensureFieldValue(child, itemData[child.id], ctx)\n }\n }\n return itemData\n }\n\n // Handle monomorphic repeaters\n if (!field.polymorphic && field.fields) {\n for (const child of field.fields) {\n if ((child as any).type === 'group' && (child as any)?.ui?.flattenInRepeater) {\n const group = child as Extract<FieldConfig, { type: 'group' }>\n for (const gc of group.fields) {\n itemData[gc.id] = ensureFieldValue(gc, itemData[gc.id], ctx)\n }\n } else {\n itemData[child.id] = ensureFieldValue(child, itemData[child.id], ctx)\n }\n }\n }\n\n return itemData\n}\n","// src/buildEntryPageOutline.ts\nvar TRANSFORMS = {\n RICHTEXT_FIRST_PARAGRAPH: \"richtext.firstParagraph\",\n DATE_FORMAT_SHORT: \"date.formatShort\",\n DATE_FORMAT_LONG: \"date.formatLong\"\n};\nvar BINDING_SOURCES = [\"field\", \"meta\", \"literal\", \"transform\", \"fallback\"];\nfunction buildEntryPageOutline({\n entry,\n template\n}) {\n if (!template.blocks.length) return null;\n const context = {\n fields: isRecord(entry.content) ? entry.content : {},\n meta: {\n id: entry.id,\n title: entry.title,\n slug: entry.slug,\n path: entry.path,\n publishAt: entry.publishAt,\n status: entry.status\n }\n };\n const outlineBlocks = template.blocks.map((block) => buildBlockFromTemplate(block, context)).filter((block) => Boolean(block));\n if (!outlineBlocks.length) return null;\n const pageName = entry.title || `Entry ${entry.id.slice(0, 8)}`;\n const pagePath = entry.path ?? (entry.slug ? `/${entry.slug}` : \"/\");\n return {\n name: pageName,\n path: pagePath,\n purpose: template.templateKey ?? \"content-entry\",\n blocks: outlineBlocks\n };\n}\nfunction buildBlockFromTemplate(block, context) {\n const base = {\n id: block.id,\n kind: block.blockKind,\n purpose: \"content\",\n content: {},\n bindings: void 0\n };\n if (block.scope === \"template\") {\n const rawContent = isRecord(block.content) ? { ...block.content } : {};\n base.content = normalizeBindingOutput(rawContent);\n return base;\n }\n const bindings = block.bindings ?? {};\n if (!isRecord(bindings)) {\n base.content = normalizeBindingOutput(base.content);\n return base;\n }\n const content = applyBindings(bindings, context);\n base.content = normalizeBindingOutput(content);\n base.bindings = bindings;\n return base;\n}\nfunction applyBindings(bindings, context) {\n const result = {};\n for (const [key, bindingSpec] of Object.entries(bindings)) {\n if (isBindingDescriptor(bindingSpec)) {\n const value = resolveBindingValue(bindingSpec, context);\n if (value !== void 0 && value !== null) {\n result[key] = value;\n }\n continue;\n }\n if (typeof bindingSpec === \"string\") {\n const value = resolveBindingValue({ source: \"field\", path: bindingSpec }, context);\n if (value !== void 0 && value !== null) {\n result[key] = value;\n }\n continue;\n }\n if (isRecord(bindingSpec)) {\n const nested = applyBindings(bindingSpec, context);\n if (Object.keys(nested).length > 0) {\n result[key] = nested;\n }\n }\n }\n return result;\n}\nfunction resolveBindingValue(descriptor, context) {\n switch (descriptor.source) {\n case \"field\":\n return descriptor.path ? getPath(context.fields, descriptor.path) : void 0;\n case \"meta\":\n return descriptor.path ? getPath(context.meta, descriptor.path) : void 0;\n case \"literal\":\n return descriptor.value;\n case \"transform\": {\n const inputDescriptor = descriptor.input && isBindingDescriptorLike(descriptor.input) ? normalizeBindingInput(descriptor.input) : descriptor.path ? normalizeBindingInput(descriptor.path) : null;\n const inputValue = inputDescriptor ? resolveBindingValue(inputDescriptor, context) : void 0;\n return applyTransform(descriptor.transform, inputValue);\n }\n case \"fallback\": {\n for (const option of descriptor.options ?? []) {\n const normalized = normalizeBindingInput(option);\n if (!normalized) continue;\n const value = resolveBindingValue(normalized, context);\n if (value !== void 0 && value !== null && value !== \"\") {\n return value;\n }\n }\n return null;\n }\n default:\n return null;\n }\n}\nfunction getPath(source, path) {\n const segments = path.split(\".\").map((segment) => segment.trim()).filter(Boolean);\n let current = source;\n for (const segment of segments) {\n if (!isRecord(current)) return void 0;\n current = current[segment];\n }\n return current;\n}\nfunction applyTransform(name, value) {\n if (!name) return value;\n switch (name) {\n case TRANSFORMS.RICHTEXT_FIRST_PARAGRAPH:\n return extractFirstParagraph(value);\n case TRANSFORMS.DATE_FORMAT_SHORT:\n return formatDate(value, { dateStyle: \"medium\" });\n case TRANSFORMS.DATE_FORMAT_LONG:\n return formatDate(value, { dateStyle: \"long\", timeStyle: \"short\" });\n default:\n return value;\n }\n}\nfunction extractFirstParagraph(value) {\n if (!isRecord(value)) return null;\n const doc = value;\n if (!Array.isArray(doc.content)) return null;\n for (const node of doc.content) {\n if (!isRecord(node)) continue;\n if (node.type !== \"paragraph\" || !Array.isArray(node.content)) continue;\n const text = node.content.filter((item) => isRecord(item) && item.type === \"text\").map((item) => typeof item.text === \"string\" ? item.text : \"\").join(\"\").trim();\n if (text.length > 0) {\n return text;\n }\n }\n return null;\n}\nfunction formatDate(value, options) {\n if (typeof value !== \"string\") return null;\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return null;\n return new Intl.DateTimeFormat(void 0, options).format(date);\n}\nfunction isBindingDescriptor(value) {\n return isRecord(value) && typeof value.source === \"string\" && BINDING_SOURCES.includes(value.source);\n}\nfunction isBindingDescriptorLike(value) {\n return isBindingDescriptor(value) || typeof value === \"string\" || isRecord(value) && typeof value.source === \"string\" && typeof value.path === \"string\";\n}\nfunction normalizeBindingInput(value) {\n if (isBindingDescriptor(value)) return value;\n if (typeof value === \"string\") {\n return { source: \"field\", path: value };\n }\n if (isRecord(value) && typeof value.source === \"string\") {\n return isBindingDescriptor(value) ? value : null;\n }\n return null;\n}\nfunction isRecord(value) {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction normalizeBindingOutput(value) {\n return normalizeValue(value);\n}\nfunction normalizeValue(value) {\n if (Array.isArray(value)) {\n return value.map((item) => normalizeValue(item));\n }\n if (!isRecord(value)) {\n return value;\n }\n if (isDocWrapper(value)) {\n return normalizeValue(value.doc);\n }\n const entries = Object.entries(value).map(([key, val]) => [key, normalizeValue(val)]);\n return Object.fromEntries(entries);\n}\nfunction isDocWrapper(value) {\n if (!(\"doc\" in value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 1) return false;\n const doc = value.doc;\n return isRecord(doc) && typeof doc.type === \"string\" && doc.type === \"doc\";\n}\n\n// src/siteChrome.ts\nfunction selectPrimaryMenu(menus) {\n if (!menus.length) {\n return null;\n }\n const primary = menus.find((menu) => menu.isPrimary);\n return primary ?? menus[0] ?? null;\n}\nfunction buildMenuViewModel(menu) {\n if (!menu) {\n return { items: [], ctaItem: null };\n }\n const flatItems = menu.items.filter((item) => item.parentId === null && item.urlType !== \"dropdown\").sort((a, b) => a.orderIndex - b.orderIndex);\n const items = [];\n let ctaItem = null;\n for (const item of flatItems) {\n const viewItem = {\n id: item.id,\n label: item.label,\n link: convertNavigationLink(item),\n target: null,\n rel: null,\n active: false\n // TODO: Compute active state based on current route\n };\n if (!ctaItem && Boolean(item.isCta)) {\n ctaItem = { ...viewItem, variant: \"primary\" };\n continue;\n }\n items.push(viewItem);\n }\n return { items, ctaItem };\n}\nfunction buildLogoViewModel(logo, fallbackTitle) {\n if (!logo) {\n return null;\n }\n if (!logo.url && !logo.assetId) {\n return null;\n }\n const alt = logo.alt && logo.alt.trim().length > 0 ? logo.alt : fallbackTitle ?? \"Site logo\";\n const viewModel = {\n type: \"image\",\n src: logo.url ?? \"\",\n // Empty string when url is null - media node uses assetId instead\n alt,\n assetId: logo.assetId ?? void 0,\n width: logo.width ?? void 0,\n height: logo.height ?? void 0\n };\n return viewModel;\n}\nfunction convertNavigationLink(item) {\n const payload = item.url ?? null;\n if (!payload) return null;\n const kind = typeof payload.kind === \"string\" ? payload.kind : null;\n if (kind === \"external\" || kind === \"url\") {\n const href = typeof payload.href === \"string\" ? payload.href : null;\n return href ? { kind, href } : null;\n }\n if (kind === \"internal\") {\n const routeId = typeof payload.routeId === \"string\" ? payload.routeId : null;\n const entityId = typeof payload.entityId === \"string\" ? payload.entityId : null;\n const entityType = typeof payload.entityType === \"string\" && (payload.entityType === \"page\" || payload.entityType === \"content\") ? payload.entityType : null;\n const href = typeof payload.href === \"string\" ? payload.href : null;\n const title = typeof payload.title === \"string\" ? payload.title : null;\n const typeLabel = typeof payload.typeLabel === \"string\" ? payload.typeLabel : null;\n if (!routeId || !entityId || !entityType || !href || !title || !typeLabel) {\n return null;\n }\n return {\n kind: \"internal\",\n routeId,\n entityId,\n entityType,\n href,\n title,\n typeLabel,\n contentTypeKey: typeof payload.contentTypeKey === \"string\" ? payload.contentTypeKey : null,\n contentTypeName: typeof payload.contentTypeName === \"string\" ? payload.contentTypeName : null,\n updatedAt: typeof payload.updatedAt === \"string\" ? payload.updatedAt : null\n };\n }\n return null;\n}\n\n// src/layout.ts\nimport { createManifestDefaultValues } from \"@riverbankcms/block-form/server\";\nimport {\n siteHeaderManifest,\n siteFooterManifest\n} from \"@riverbankcms/blocks\";\nvar HEADER_DEFAULTS = createManifestDefaultValues(siteHeaderManifest);\nvar FOOTER_DEFAULTS = createManifestDefaultValues(siteFooterManifest);\nfunction isRecord2(value) {\n return typeof value === \"object\" && value !== null;\n}\nfunction resolveString(value) {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n return null;\n}\nfunction resolveNumber(value) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n return null;\n}\nfunction normalizeLayout(input) {\n const record = isRecord2(input) ? input : {};\n const headerInput = isRecord2(record.header) ? record.header : {};\n const footerInput = isRecord2(record.footer) ? record.footer : {};\n const header = {\n ...HEADER_DEFAULTS,\n ...headerInput\n };\n const footer = {\n ...FOOTER_DEFAULTS,\n ...footerInput\n };\n const logoInput = isRecord2(record.logo) ? record.logo : {};\n const logoAssetId = resolveString(record.logoAssetId) ?? resolveString(logoInput.assetId) ?? null;\n return {\n logoAssetId,\n logo: {\n assetId: logoAssetId,\n url: resolveString(logoInput.url),\n alt: resolveString(logoInput.alt),\n width: resolveNumber(logoInput.width),\n height: resolveNumber(logoInput.height)\n },\n header,\n footer\n };\n}\nexport {\n buildEntryPageOutline,\n buildLogoViewModel,\n buildMenuViewModel,\n normalizeLayout,\n selectPrimaryMenu\n};\n","/**\n * Layout component with header and footer\n *\n * Renders site header and footer around content. Fetches site data if not provided.\n */\n\nimport { renderBlock, siteFooterManifest, siteHeaderManifest, buildThemeRuntime } from '@riverbankcms/blocks';\nimport { selectPrimaryMenu, buildMenuViewModel, buildLogoViewModel } from '@riverbankcms/site-renderer';\nimport type { RiverbankClient, SiteResponse } from '../../client/types';\n\nexport type HeaderData = {\n menu: ReturnType<typeof buildMenuViewModel>;\n logo: ReturnType<typeof buildLogoViewModel>;\n site: SiteResponse['site'];\n theme: SiteResponse['theme'];\n routes: SiteResponse['routes'];\n};\n\nexport type LayoutProps = {\n // Option 1: Pass pre-fetched site data\n siteData?: SiteResponse;\n\n // Option 2: Fetch site data (provide client + identifier)\n client?: RiverbankClient;\n siteId?: string;\n slug?: string;\n domain?: string;\n\n // Content\n children: React.ReactNode;\n\n // Control rendering\n header?: boolean | ((data: HeaderData) => React.ReactNode);\n footer?: boolean;\n\n // Header variant override (if using default header)\n headerVariant?: 'classic' | 'centered' | 'transparent' | 'floating' | 'editorial';\n};\n\n/**\n * Layout component that wraps content with site header and footer.\n *\n * @example With pre-fetched site data (recommended)\n * ```tsx\n * const site = await client.getSite({ slug: 'my-site' });\n *\n * <Layout siteData={site}>\n * <Page {...pageData} />\n * </Layout>\n * ```\n *\n * @example With automatic fetching\n * ```tsx\n * <Layout client={client} slug=\"my-site\">\n * <Page {...pageData} />\n * </Layout>\n * ```\n */\nexport async function Layout({\n siteData: providedSiteData,\n client,\n siteId,\n slug,\n domain,\n children,\n header = true,\n footer = true,\n headerVariant,\n}: LayoutProps) {\n // Fetch site data if not provided\n let siteData = providedSiteData;\n if (!siteData) {\n if (!client) {\n throw new Error('Layout: must provide either siteData or client');\n }\n if (!siteId && !slug && !domain) {\n throw new Error('Layout: must provide siteId, slug, or domain when using client');\n }\n\n siteData = await client.getSite({ id: siteId, slug, domain });\n }\n\n const { site, theme, navigation, layout, routes } = siteData;\n const themeRuntime = buildThemeRuntime(theme);\n\n // Build view models for header/footer using proper helpers from @riverbankcms/site-renderer\n const menu = selectPrimaryMenu(navigation);\n const menuViewModel = buildMenuViewModel(menu);\n const logoViewModel = buildLogoViewModel(layout.logo ?? null, site.title);\n\n // Prepare header data for custom headers\n const headerData: HeaderData = {\n menu: menuViewModel,\n logo: logoViewModel,\n site,\n theme,\n routes,\n };\n\n // Override header variant if specified\n const headerContent = headerVariant\n ? { ...layout.header, variant: headerVariant }\n : layout.header;\n\n // Override theme header variant if specified\n const themeWithVariant = headerVariant\n ? {\n ...theme,\n header: { ...theme.header, variant: headerVariant },\n }\n : theme;\n\n const viewModelOverrides = {\n $root: {\n siteId: site.id,\n routes,\n theme: themeWithVariant,\n },\n site,\n menu: menuViewModel,\n content: {\n logo: logoViewModel,\n },\n };\n\n // Render header based on type\n let headerElement: React.ReactNode = null;\n if (header === true) {\n // Default header rendering\n headerElement = renderBlock(siteHeaderManifest, headerContent, {\n theme: themeRuntime.tokens,\n themeConfig: themeWithVariant,\n viewModelOverrides,\n });\n } else if (typeof header === 'function') {\n // Custom header rendering\n headerElement = header(headerData);\n }\n\n return (\n <>\n {headerElement}\n\n {children}\n\n {footer && renderBlock(siteFooterManifest, layout.footer, {\n theme: themeRuntime.tokens,\n themeConfig: theme,\n viewModelOverrides,\n })}\n </>\n );\n}\n"],"mappings":"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","names":["z","z","s","z","__require","children","rest"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-SWPHIUVE.js","../../src/rendering/helpers/loadPage.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACwIA,MAAA,SAAsB,QAAA,CAAS,MAAA,EAAiD;AAC9E,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,mBAAA,EAAqB,aAAa,EAAA,EAAI,MAAA;AAG7F,EAAA,MAAM,CAAC,IAAA,EAAM,YAAY,EAAA,EAAI,MAAM,OAAA,CAAQ,GAAA,CAAI;AAAA,IAC7C,MAAA,CAAO,OAAA,CAAQ,EAAE,EAAA,EAAI,OAAO,CAAC,CAAA;AAAA,IAC7B,MAAA,CAAO,OAAA,CAAQ,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAC;AAAA,EAC1C,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,QAAA,GAAW,YAAA,EAAc;AAC3B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,IAGF,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,SAAS,EAAA,EAAI,YAAA;AAI3B,EAAA,MAAM,OAAA,EAAS,QAAA,CAAS,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAA,GAAU;AAC5C,IAAA,GAAA,CAAI,CAAC,MAAA,GAAS,OAAO,MAAA,IAAU,QAAA,EAAU;AACvC,MAAA,MAAM,IAAI,KAAA,CAAM,sCAAsC,CAAA;AAAA,IACxD;AACA,IAAA,GAAA,CAAI,OAAO,KAAA,CAAM,GAAA,IAAO,SAAA,GAAY,KAAA,CAAM,GAAA,IAAO,IAAA,EAAM;AACrD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+CAAA,EAAkD,OAAO,KAAA,CAAM,EAAE,CAAA,CAAA;AACnF,IAAA;AACoC,IAAA;AAC6C,MAAA;AACjF,IAAA;AACuC,IAAA;AACuC,MAAA;AAC9E,IAAA;AAKmB,IAAA;AAQZ,IAAA;AACU,MAAA;AACE,MAAA;AACG,MAAA;AAAA;AAEY,MAAA;AAAA;AAEe,MAAA;AACjD,IAAA;AACD,EAAA;AAEmB,EAAA;AACH,IAAA;AACA,IAAA;AACG,IAAA;AAClB,IAAA;AACF,EAAA;AAQI,EAAA;AACF,IAAA;AAC2B,IAAA;AACS,IAAA;AACpC,IAAA;AACF,EAAA;AAOyB,EAAA;AACvB,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AAAA;AAEgC,MAAA;AAChC,IAAA;AACF,EAAA;AAGmB,EAAA;AACqD,EAAA;AACE,IAAA;AAClB,IAAA;AACxD,EAAA;AAEO,EAAA;AACC,IAAA;AACM,IAAA;AACiB,IAAA;AAC7B,IAAA;AACA,IAAA;AAAA;AAAA;AAAA;AAIF,EAAA;AACF;AD5KwF;AACA;AACA;AACA","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-SWPHIUVE.js","sourcesContent":[null,"/**\n * Server-side helper to fetch all data needed for <Page> component.\n *\n * Use this in server components, getServerSideProps, or API routes.\n */\n\nimport type { RiverbankClient, SiteResponse } from '../../client/types';\nimport type { PageProps } from '../components/Page';\nimport { prefetchBlockData } from '../../data/prefetchBlockData';\nimport { executeCodeLoaders, mergeLoaderResults } from '../../data/executeCodeLoaders';\nimport type { DataLoaderOverrides } from '../../data/types';\n\n/**\n * SDK config from API response (without siteId which is stripped at storage).\n * This is the runtime representation - for defining configs, use RiverbankSiteConfig.\n */\nexport type RuntimeSdkConfig = NonNullable<SiteResponse['sdkConfig']>;\n\nexport type LoadPageParams = {\n client: RiverbankClient;\n siteId: string;\n path: string;\n pageId?: string;\n /**\n * If true, fetches draft/unpublished content instead of published content.\n * This affects both the page structure and block data loaders.\n * Requires API key with site access.\n *\n * @default false\n */\n preview?: boolean;\n /**\n * Code-based data loaders for custom blocks.\n *\n * Use this to fetch data from external APIs (not just whitelisted CMS endpoints).\n * Keys are block kinds (e.g., 'custom.featured-products').\n *\n * Config-based loaders (defined in riverbank.config.ts) run first.\n * Code loaders run second and take precedence on key conflicts.\n *\n * @example\n * ```typescript\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: '/',\n * dataLoaderOverrides: {\n * 'custom.featured-products': {\n * products: async (ctx) => {\n * const res = await fetch(`https://api.shop.com/products?category=${ctx.content.categoryId}`);\n * return res.json();\n * },\n * },\n * },\n * });\n * ```\n */\n dataLoaderOverrides?: DataLoaderOverrides;\n /**\n * URL search parameters from the page request.\n * Passed to code-based data loaders for pagination, filtering, etc.\n *\n * @example\n * ```typescript\n * // In Next.js App Router\n * export default async function Page({ params, searchParams }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * searchParams: await searchParams,\n * });\n * return <Page {...pageData} />;\n * }\n * ```\n */\n searchParams?: Record<string, string | string[] | undefined>;\n};\n\nexport type LoadPageResult = Omit<PageProps, 'registry' | 'wrapBlock' | 'usePlaceholders' | 'blockOverrides'> & {\n /**\n * SDK site configuration, if available.\n * Contains SDK-defined theme palette, section backgrounds, and style options.\n */\n sdkConfig: RuntimeSdkConfig | null;\n};\n\n/**\n * Server-side helper to fetch all data needed for <Page> component.\n *\n * Fetches site data, page data, and prefetches block data loaders in parallel.\n *\n * @example Next.js App Router (published content)\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { loadPage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({\n * apiKey: process.env.RIVERBANK_API_KEY!,\n * baseUrl: process.env.NEXT_PUBLIC_DASHBOARD_URL + '/api',\n * });\n *\n * export default async function PageRoute({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Next.js App Router (preview/draft content)\n * ```tsx\n * export default async function PreviewRoute({ params, searchParams }) {\n * const pageData = await loadPage({\n * client,\n * siteId: searchParams.siteId,\n * path: `/${params.slug || ''}`,\n * preview: true, // Fetch draft content\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Next.js Pages Router (getServerSideProps)\n * ```tsx\n * export async function getServerSideProps({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * });\n *\n * return { props: pageData };\n * }\n *\n * export default function PageRoute(props) {\n * return <Page {...props} />;\n * }\n * ```\n */\nexport async function loadPage(params: LoadPageParams): Promise<LoadPageResult> {\n const { client, siteId, path, pageId, preview = false, dataLoaderOverrides, searchParams } = params;\n\n // Fetch site and page data in parallel\n const [site, pageResponse] = await Promise.all([\n client.getSite({ id: siteId }),\n client.getPage({ siteId, path, preview }),\n ]);\n\n // Extract page data (getContentByPath can return page or entry)\n if ('entry' in pageResponse) {\n throw new Error(\n 'This path resolves to a content entry, not a page. ' +\n 'Use loadContent() instead, which handles both pages and entries. ' +\n 'For entries, loadContent() returns the raw entry data for custom rendering.'\n );\n }\n\n const { page: pageData } = pageResponse;\n\n // Convert API response blocks to PageOutline format with content\n // API returns blocks with full content - PageRenderer needs the content field for rendering\n const blocks = pageData.blocks.map((block) => {\n if (!block || typeof block !== 'object') {\n throw new Error('Invalid block format in API response');\n }\n if (typeof block.id !== 'string' && block.id !== null) {\n throw new Error(`Invalid block id: expected string or null, got ${typeof block.id}`);\n }\n if (typeof block.kind !== 'string') {\n throw new Error(`Invalid block kind: expected string, got ${typeof block.kind}`);\n }\n if (typeof block.purpose !== 'string') {\n throw new Error(`Invalid block purpose: expected string, got ${typeof block.purpose}`);\n }\n\n // Include content for rendering\n // API provides `content` (active content for the requested stage)\n // and optionally `draftContent` for preview mode\n const typedBlock = block as {\n id: string | null;\n kind: string;\n purpose: string;\n content?: Record<string, unknown>;\n draftContent?: { data: Record<string, unknown> } | null;\n };\n\n return {\n id: typedBlock.id,\n kind: typedBlock.kind,\n purpose: typedBlock.purpose,\n // Include content for PageRenderer's getRenderableContent()\n content: typedBlock.content ?? {},\n // Include draftContent if available (for preview mode)\n draftContent: typedBlock.draftContent?.data ?? null,\n };\n });\n\n const pageOutline = {\n name: pageData.name,\n path: pageData.path,\n purpose: pageData.purpose,\n blocks,\n };\n\n // Build prefetch context\n const prefetchContext: {\n siteId: string;\n pageId: string;\n previewStage: 'published' | 'preview';\n searchParams?: Record<string, string | string[] | undefined>;\n } = {\n siteId,\n pageId: pageId ?? pageData.id,\n previewStage: preview ? 'preview' : 'published',\n searchParams,\n };\n\n // Prefetch block data loaders (config-based loaders for CMS endpoints)\n // Note: searchParams is intentionally NOT passed to config-based loaders.\n // Config loaders call CMS endpoints which don't need URL params.\n // Only code-based loaders (dataLoaderOverrides) receive searchParams for\n // custom pagination, filtering, and sorting via external APIs.\n const configData = await prefetchBlockData(\n pageOutline,\n prefetchContext,\n client,\n {\n // Pass custom blocks so their config-based loaders are discovered\n customBlocks: site.sdkConfig?.customBlocks,\n }\n );\n\n // Execute code-based loaders (external APIs) and merge results\n let resolvedData = configData;\n if (dataLoaderOverrides && Object.keys(dataLoaderOverrides).length > 0) {\n const codeData = await executeCodeLoaders(pageOutline, prefetchContext, dataLoaderOverrides);\n resolvedData = mergeLoaderResults(configData, codeData);\n }\n\n return {\n page: pageOutline,\n theme: site.theme,\n sdkConfig: site.sdkConfig ?? null,\n siteId,\n resolvedData,\n // Note: routeMap is optional and can be built from site data if needed for internal links.\n // Consumers can construct it from site.pages and pass explicitly via Page component props.\n // Example: const routeMap = site.pages.reduce((map, p) => ({ ...map, [p.id]: p.path }), {});\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/rendering/helpers/loadPage.ts"],"sourcesContent":["/**\n * Server-side helper to fetch all data needed for <Page> component.\n *\n * Use this in server components, getServerSideProps, or API routes.\n */\n\nimport type { RiverbankClient, SiteResponse } from '../../client/types';\nimport type { PageProps } from '../components/Page';\nimport { prefetchBlockData } from '../../data/prefetchBlockData';\nimport { executeCodeLoaders, mergeLoaderResults } from '../../data/executeCodeLoaders';\nimport type { DataLoaderOverrides } from '../../data/types';\n\n/**\n * SDK config from API response (without siteId which is stripped at storage).\n * This is the runtime representation - for defining configs, use RiverbankSiteConfig.\n */\nexport type RuntimeSdkConfig = NonNullable<SiteResponse['sdkConfig']>;\n\nexport type LoadPageParams = {\n client: RiverbankClient;\n siteId: string;\n path: string;\n pageId?: string;\n /**\n * If true, fetches draft/unpublished content instead of published content.\n * This affects both the page structure and block data loaders.\n * Requires API key with site access.\n *\n * @default false\n */\n preview?: boolean;\n /**\n * Code-based data loaders for custom blocks.\n *\n * Use this to fetch data from external APIs (not just whitelisted CMS endpoints).\n * Keys are block kinds (e.g., 'custom.featured-products').\n *\n * Config-based loaders (defined in riverbank.config.ts) run first.\n * Code loaders run second and take precedence on key conflicts.\n *\n * @example\n * ```typescript\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: '/',\n * dataLoaderOverrides: {\n * 'custom.featured-products': {\n * products: async (ctx) => {\n * const res = await fetch(`https://api.shop.com/products?category=${ctx.content.categoryId}`);\n * return res.json();\n * },\n * },\n * },\n * });\n * ```\n */\n dataLoaderOverrides?: DataLoaderOverrides;\n /**\n * URL search parameters from the page request.\n * Passed to code-based data loaders for pagination, filtering, etc.\n *\n * @example\n * ```typescript\n * // In Next.js App Router\n * export default async function Page({ params, searchParams }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * searchParams: await searchParams,\n * });\n * return <Page {...pageData} />;\n * }\n * ```\n */\n searchParams?: Record<string, string | string[] | undefined>;\n};\n\nexport type LoadPageResult = Omit<PageProps, 'registry' | 'wrapBlock' | 'usePlaceholders' | 'blockOverrides'> & {\n /**\n * SDK site configuration, if available.\n * Contains SDK-defined theme palette, section backgrounds, and style options.\n */\n sdkConfig: RuntimeSdkConfig | null;\n};\n\n/**\n * Server-side helper to fetch all data needed for <Page> component.\n *\n * Fetches site data, page data, and prefetches block data loaders in parallel.\n *\n * @example Next.js App Router (published content)\n * ```tsx\n * import { createRiverbankClient } from '@riverbankcms/sdk';\n * import { loadPage, Page } from '@riverbankcms/sdk/rendering';\n *\n * const client = createRiverbankClient({\n * apiKey: process.env.RIVERBANK_API_KEY!,\n * baseUrl: process.env.NEXT_PUBLIC_DASHBOARD_URL + '/api',\n * });\n *\n * export default async function PageRoute({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Next.js App Router (preview/draft content)\n * ```tsx\n * export default async function PreviewRoute({ params, searchParams }) {\n * const pageData = await loadPage({\n * client,\n * siteId: searchParams.siteId,\n * path: `/${params.slug || ''}`,\n * preview: true, // Fetch draft content\n * });\n *\n * return <Page {...pageData} />;\n * }\n * ```\n *\n * @example Next.js Pages Router (getServerSideProps)\n * ```tsx\n * export async function getServerSideProps({ params }) {\n * const pageData = await loadPage({\n * client,\n * siteId: 'site-123',\n * path: `/${params.slug || ''}`,\n * });\n *\n * return { props: pageData };\n * }\n *\n * export default function PageRoute(props) {\n * return <Page {...props} />;\n * }\n * ```\n */\nexport async function loadPage(params: LoadPageParams): Promise<LoadPageResult> {\n const { client, siteId, path, pageId, preview = false, dataLoaderOverrides, searchParams } = params;\n\n // Fetch site and page data in parallel\n const [site, pageResponse] = await Promise.all([\n client.getSite({ id: siteId }),\n client.getPage({ siteId, path, preview }),\n ]);\n\n // Extract page data (getContentByPath can return page or entry)\n if ('entry' in pageResponse) {\n throw new Error(\n 'This path resolves to a content entry, not a page. ' +\n 'Use loadContent() instead, which handles both pages and entries. ' +\n 'For entries, loadContent() returns the raw entry data for custom rendering.'\n );\n }\n\n const { page: pageData } = pageResponse;\n\n // Convert API response blocks to PageOutline format with content\n // API returns blocks with full content - PageRenderer needs the content field for rendering\n const blocks = pageData.blocks.map((block) => {\n if (!block || typeof block !== 'object') {\n throw new Error('Invalid block format in API response');\n }\n if (typeof block.id !== 'string' && block.id !== null) {\n throw new Error(`Invalid block id: expected string or null, got ${typeof block.id}`);\n }\n if (typeof block.kind !== 'string') {\n throw new Error(`Invalid block kind: expected string, got ${typeof block.kind}`);\n }\n if (typeof block.purpose !== 'string') {\n throw new Error(`Invalid block purpose: expected string, got ${typeof block.purpose}`);\n }\n\n // Include content for rendering\n // API provides `content` (active content for the requested stage)\n // and optionally `draftContent` for preview mode\n const typedBlock = block as {\n id: string | null;\n kind: string;\n purpose: string;\n content?: Record<string, unknown>;\n draftContent?: { data: Record<string, unknown> } | null;\n };\n\n return {\n id: typedBlock.id,\n kind: typedBlock.kind,\n purpose: typedBlock.purpose,\n // Include content for PageRenderer's getRenderableContent()\n content: typedBlock.content ?? {},\n // Include draftContent if available (for preview mode)\n draftContent: typedBlock.draftContent?.data ?? null,\n };\n });\n\n const pageOutline = {\n name: pageData.name,\n path: pageData.path,\n purpose: pageData.purpose,\n blocks,\n };\n\n // Build prefetch context\n const prefetchContext: {\n siteId: string;\n pageId: string;\n previewStage: 'published' | 'preview';\n searchParams?: Record<string, string | string[] | undefined>;\n } = {\n siteId,\n pageId: pageId ?? pageData.id,\n previewStage: preview ? 'preview' : 'published',\n searchParams,\n };\n\n // Prefetch block data loaders (config-based loaders for CMS endpoints)\n // Note: searchParams is intentionally NOT passed to config-based loaders.\n // Config loaders call CMS endpoints which don't need URL params.\n // Only code-based loaders (dataLoaderOverrides) receive searchParams for\n // custom pagination, filtering, and sorting via external APIs.\n const configData = await prefetchBlockData(\n pageOutline,\n prefetchContext,\n client,\n {\n // Pass custom blocks so their config-based loaders are discovered\n customBlocks: site.sdkConfig?.customBlocks,\n }\n );\n\n // Execute code-based loaders (external APIs) and merge results\n let resolvedData = configData;\n if (dataLoaderOverrides && Object.keys(dataLoaderOverrides).length > 0) {\n const codeData = await executeCodeLoaders(pageOutline, prefetchContext, dataLoaderOverrides);\n resolvedData = mergeLoaderResults(configData, codeData);\n }\n\n return {\n page: pageOutline,\n theme: site.theme,\n sdkConfig: site.sdkConfig ?? null,\n siteId,\n resolvedData,\n // Note: routeMap is optional and can be built from site data if needed for internal links.\n // Consumers can construct it from site.pages and pass explicitly via Page component props.\n // Example: const routeMap = site.pages.reduce((map, p) => ({ ...map, [p.id]: p.path }), {});\n };\n}\n"],"mappings":";;;;;;;;;AAgJA,eAAsB,SAAS,QAAiD;AAC9E,QAAM,EAAE,QAAQ,QAAQ,MAAM,QAAQ,UAAU,OAAO,qBAAqB,aAAa,IAAI;AAG7F,QAAM,CAAC,MAAM,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC7C,OAAO,QAAQ,EAAE,IAAI,OAAO,CAAC;AAAA,IAC7B,OAAO,QAAQ,EAAE,QAAQ,MAAM,QAAQ,CAAC;AAAA,EAC1C,CAAC;AAGD,MAAI,WAAW,cAAc;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,SAAS,IAAI;AAI3B,QAAM,SAAS,SAAS,OAAO,IAAI,CAAC,UAAU;AAC5C,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,QAAI,OAAO,MAAM,OAAO,YAAY,MAAM,OAAO,MAAM;AACrD,YAAM,IAAI,MAAM,kDAAkD,OAAO,MAAM,EAAE,EAAE;AAAA,IACrF;AACA,QAAI,OAAO,MAAM,SAAS,UAAU;AAClC,YAAM,IAAI,MAAM,4CAA4C,OAAO,MAAM,IAAI,EAAE;AAAA,IACjF;AACA,QAAI,OAAO,MAAM,YAAY,UAAU;AACrC,YAAM,IAAI,MAAM,+CAA+C,OAAO,MAAM,OAAO,EAAE;AAAA,IACvF;AAKA,UAAM,aAAa;AAQnB,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM,WAAW;AAAA,MACjB,SAAS,WAAW;AAAA;AAAA,MAEpB,SAAS,WAAW,WAAW,CAAC;AAAA;AAAA,MAEhC,cAAc,WAAW,cAAc,QAAQ;AAAA,IACjD;AAAA,EACF,CAAC;AAED,QAAM,cAAc;AAAA,IAClB,MAAM,SAAS;AAAA,IACf,MAAM,SAAS;AAAA,IACf,SAAS,SAAS;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,kBAKF;AAAA,IACF;AAAA,IACA,QAAQ,UAAU,SAAS;AAAA,IAC3B,cAAc,UAAU,YAAY;AAAA,IACpC;AAAA,EACF;AAOA,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,MAEE,cAAc,KAAK,WAAW;AAAA,IAChC;AAAA,EACF;AAGA,MAAI,eAAe;AACnB,MAAI,uBAAuB,OAAO,KAAK,mBAAmB,EAAE,SAAS,GAAG;AACtE,UAAM,WAAW,MAAM,mBAAmB,aAAa,iBAAiB,mBAAmB;AAC3F,mBAAe,mBAAmB,YAAY,QAAQ;AAAA,EACxD;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK,aAAa;AAAA,IAC7B;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,EAIF;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-ZIM53VP6.js","../../src/config/validation.ts","../../src/config/content-validation.ts"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACA;ACLA,0BAAkB;ADOlB;AACA;AETA;AAKA,IAAM,eAAA,EAAiB,MAAA,CAAE,MAAA,CAAO,MAAA,CAAE,MAAA,CAAO,CAAA,EAAG,MAAA,CAAE,GAAA,CAAI,CAAC,CAAA;AAUnD,IAAM,qBAAA,EAAuB,MAAA,CAC1B,MAAA,CAAO,CAAA,CACP,GAAA,CAAI,CAAC,CAAA,CACL,KAAA;AAAA,EACC,mBAAA;AAAA,EACA;AACF,CAAA;AAKK,IAAM,wBAAA,EAAwD,MAAA,CAClE,MAAA,CAAO;AAAA,EACN,GAAA,EAAK,oBAAA;AAAA,EACL,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA;AAAA,EACtB,WAAA,EAAa,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EACjC,QAAA,EAAU,MAAA,CAAE,OAAA,CAAQ,CAAA;AAAA,EACpB,YAAA,EAAc,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA;AAAA,EAElC,MAAA,EAAQ,MAAA,CAAE,KAAA,CAAM,MAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,gCAAgC,CAAA;AAAA,EAChE,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AAClC,CAAC,CAAA,CACA,MAAA;AAAA,EACC,CAAC,IAAA,EAAA,GAAS;AAER,IAAA,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU;AACjB,MAAA,OAAO,IAAA,CAAK,aAAA,GAAgB,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,QAAQ,CAAA;AAAA,IACjE;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EACA,EAAE,OAAA,EAAS,6DAA6D;AAC1E,CAAA,CACC,MAAA;AAAA,EACC,CAAC,IAAA,EAAA,GAAS;AAER,IAAA,GAAA,CAAI,CAAC,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,YAAA,EAAc;AACvC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EACA,EAAE,OAAA,EAAS,0DAA0D;AACvE,CAAA;AAUF,IAAM,gBAAA,EAAkB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA;AAAA,EACjC,CAAC,IAAA,EAAA,GAAS;AAER,IAAA,GAAA,CAAK,mCAAA,CAAyC,QAAA,CAAS,IAAI,CAAA,EAAG;AAC5D,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,SAAS,EAAA,GAAK,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AACjD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA;AAAA,IACE,OAAA,EACE;AAAA,EACJ;AACF,CAAA;AAEO,IAAM,kBAAA,EAAoB,MAAA,CAAE,MAAA,CAAO;AAAA,EACxC,IAAA,EAAM,eAAA;AAAA,EACN,OAAA,EAAS,cAAA;AAAA,EACT,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AAClC,CAAC,CAAA;AAMM,IAAM,iBAAA,EAAmB,MAAA,CAAE,MAAA,CAAO;AAAA,EACvC,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,wBAAwB,CAAA;AAAA,EACtD,KAAA,EAAO,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,mBAAmB,CAAA;AAAA,EAC5C,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,KAAA,CAAM,KAAA,EAAO,wBAAwB,CAAA;AAAA,EACtD,OAAA,EAAS,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,EACrC,MAAA,EAAQ,MAAA,CAAE,KAAA,CAAM,iBAAiB,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC5C,MAAA,EAAQ,MAAA,CAAE,IAAA,CAAK,CAAC,OAAA,EAAS,WAAW,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAO,CAAA;AAAA,EACtD,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC/B,eAAA,EAAiB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AACvC,CAAC,CAAA;AAMM,IAAM,kBAAA,EAAoB,MAAA,CAAE,MAAA,CAAO;AAAA,EACxC,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,wBAAwB,CAAA;AAAA,EACtD,WAAA,EAAa,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,0BAA0B,CAAA;AAAA,EACzD,IAAA,EAAM,cAAA;AAAA,EACN,MAAA,EAAQ,MAAA,CAAE,IAAA,CAAK,CAAC,OAAA,EAAS,WAAW,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAO,CAAA;AAAA,EACtD,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC1B,KAAA,EAAO,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC3B,OAAA,EAAS,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC7B,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC/B,eAAA,EAAiB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AACvC,CAAC,CAAA;AAMD,IAAM,eAAA,EAAiB,MAAA,CAAE,MAAA,CAAO;AAAA,EAC9B,IAAA,EAAM,MAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,EACtB,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC;AAC9B,CAAC,CAAA;AAED,IAAM,gBAAA,EAAkB,MAAA,CAAE,MAAA,CAAO;AAAA,EAC/B,IAAA,EAAM,MAAA,CAAE,OAAA,CAAQ,OAAO,CAAA;AAAA,EACvB,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC;AAC9B,CAAC,CAAA;AAED,IAAM,mBAAA,EAAqB,MAAA,CAAE,MAAA,CAAO;AAAA,EAClC,IAAA,EAAM,MAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,EAC1B,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,aAAa;AACpC,CAAC,CAAA;AAED,IAAM,mBAAA,EAAqB,MAAA,CAAE,MAAA,CAAO;AAAA,EAClC,IAAA,EAAM,MAAA,CAAE,OAAA,CAAQ,UAAU;AAC5B,CAAC,CAAA;AAED,IAAM,qBAAA,EAAuB,MAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ;AAAA,EACxD,cAAA;AAAA,EACA,eAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGD,IAAM,yBAAA,EAA2B,MAAA,CAAE,MAAA,CAAO;AAAA,EACxC,KAAA,EAAO,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,mBAAmB,CAAA;AAAA,EAC5C,IAAA,EAAM,oBAAA;AAAA,EACN,KAAA,EAAO,MAAA,CAAE,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS;AAC9B,CAAC,CAAA;AAGM,IAAM,2BAAA,EAkBR,wBAAA,CAAyB,MAAA,CAAO;AAAA,EACnC,QAAA,EAAU,MAAA,CAAE,IAAA,CAAK,CAAA,EAAA,GAAM,MAAA,CAAE,KAAA,CAAM,0BAA0B,CAAC,CAAA,CAAE,QAAA,CAAS;AACvE,CAAC,CAAA;AAEM,IAAM,2BAAA,EAA6B,MAAA,CAAE,MAAA,CAAO;AAAA,EACjD,UAAA,EAAY,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,wBAAwB,CAAA;AAAA,EACtD,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,EAAG,kBAAkB,CAAA;AAAA,EAC1C,SAAA,EAAW,MAAA,CAAE,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAChC,KAAA,EAAO,MAAA,CAAE,KAAA,CAAM,0BAA0B;AAC3C,CAAC,CAAA;AAMM,IAAM,yBAAA,EAA2B,MAAA,CAAE,MAAA,CAAO;AAAA,EAC/C,YAAA,EAAc,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAClC,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC/B,eAAA,EAAiB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EACrC,gBAAA,EAAkB,MAAA,CAAE,MAAA,CAAO,MAAA,CAAE,MAAA,CAAO,CAAA,EAAG,MAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,QAAA,CAAS;AAC9D,CAAC,CAAA;AAMD,IAAM,wBAAA,EAA0B,MAAA,CAAE,MAAA,CAAO;AAAA,EACvC,YAAA,EAAc,MAAA,CAAE,KAAA,CAAM,uBAAuB,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EACxD,OAAA,EAAS,MAAA,CAAE,KAAA,CAAM,iBAAiB,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC7C,KAAA,EAAO,MAAA,CAAE,KAAA,CAAM,gBAAgB,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC1C,eAAA,EAAiB,MAAA,CAAE,KAAA,CAAM,0BAA0B,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC9D,QAAA,EAAU,wBAAA,CAAyB,QAAA,CAAS;AAC9C,CAAC,CAAA;AAEM,IAAM,oBAAA,EAAgD,uBAAA,CAC1D,WAAA,CAAY,CAAC,IAAA,EAAM,GAAA,EAAA,GAAQ;AAE1B,EAAA,GAAA,CAAI,IAAA,CAAK,aAAA,GAAgB,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG;AACrD,IAAA,MAAM,KAAA,EAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,CAAC,EAAA,EAAA,GAAO,EAAA,CAAG,GAAG,CAAA;AACjD,IAAA,MAAM,cAAA,EAAgB,IAAA,CAAK,MAAA,CAAO,CAAC,GAAA,EAAK,CAAA,EAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,EAAA,IAAM,CAAC,CAAA;AACrE,IAAA,GAAA,CAAI,aAAA,CAAc,OAAA,EAAS,CAAA,EAAG;AAC5B,MAAA,GAAA,CAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,MAAA,CAAE,YAAA,CAAa,MAAA;AAAA,QACrB,OAAA,EAAS,CAAA,8CAAA,EAAiD,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC7D,QAAA;AACtB,MAAA;AACH,IAAA;AACF,EAAA;AAGyC,EAAA;AACe,IAAA;AAC0B,IAAA;AACnD,IAAA;AACd,MAAA;AACU,QAAA;AAC2D,QAAA;AAClE,QAAA;AACf,MAAA;AACH,IAAA;AAG0C,IAAA;AACgC,IAAA;AAC3C,IAAA;AAChB,MAAA;AACU,QAAA;AACuD,QAAA;AAC9D,QAAA;AACf,MAAA;AACH,IAAA;AACF,EAAA;AAG6C,EAAA;AACa,IAAA;AACwB,IAAA;AACnD,IAAA;AACd,MAAA;AACU,QAAA;AAC4D,QAAA;AACjE,QAAA;AACjB,MAAA;AACH,IAAA;AACF,EAAA;AAG6D,EAAA;AACK,IAAA;AACgB,IAAA;AACnD,IAAA;AACd,MAAA;AACU,QAAA;AAC4D,QAAA;AACzD,QAAA;AACzB,MAAA;AACH,IAAA;AACF,EAAA;AACD;AF1FwF;AACA;AC5KvB;AAKvB;AAClC,EAAA;AACV;AAK+C;AACjC,EAAA;AACG,EAAA;AACA,EAAA;AAAA;AACjB;AAK4E;AAKM;AAKT;AAK7B;AACL,EAAA;AACA,EAAA;AACG,EAAA;AACxB,EAAA;AACa,IAAA;AAClB,IAAA;AACA,EAAA;AACoB,EAAA;AACtB;AAKmC;AAC3B,EAAA;AACe,IAAA;AACrB,IAAA;AACA,EAAA;AACO,EAAA;AACe,IAAA;AACtB,IAAA;AACA,EAAA;AACF;AAKkC;AACkB,EAAA;AAC9C,EAAA;AACE,EAAA;AACR;AAgB4D;AAYvB;AAC/B,EAAA;AACoC,IAAA;AACpB,IAAA;AAC/B,EAAA;AACF;AAK6C;AACnC,EAAA;AACA,EAAA;AACC,EAAA;AACV,EAAA;AACD;AAQ6C;AAClC,EAAA;AACyC,EAAA;AACA,EAAA;AACpD;AAOE;AAC6C,EAAA;AACE,EAAA;AAEtC;AASoC;AACK,EAAA;AACA,EAAA;AACpD;AAK8C;AACuC,EAAA;AACrF;AAQyE;AAChB,EAAA;AAC7C,IAAA;AACV,EAAA;AACC,EAAA;AACwC,IAAA;AACxC,IAAA;AACF,EAAA;AACS;AAcuE;AACb,EAAA;AAClE;AACS,EAAA;AAE6C,IAAA;AACvB,MAAA;AACE,MAAA;AAC/B,IAAA;AACH,EAAA;AACA,EAAA;AACW,IAAA;AACX,EAAA;AACF;AAQ4F;AAC3C,EAAA;AACpC,IAAA;AACV,EAAA;AACD,EAAA;AACS;AAkBgD;AACtB,EAAA;AAEyC,EAAA;AAEH,EAAA;AAC1B,IAAA;AAC5B,IAAA;AACA,MAAA;AACb,QAAA;AACS,QAAA;AAC8B,QAAA;AACxC,MAAA;AACD,MAAA;AACF,IAAA;AAGyC,IAAA;AAC0B,IAAA;AACpD,MAAA;AACe,MAAA;AACG,QAAA;AAEyB,QAAA;AAChB,UAAA;AACwB,QAAA;AACzB,UAAA;AACC,QAAA;AACA,UAAA;AACR,YAAA;AAC5B,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AAC0C,IAAA;AAGJ,IAAA;AACA,MAAA;AACnB,QAAA;AACb,UAAA;AACe,UAAA;AAC4D,UAAA;AAC5E,QAAA;AACH,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAUwE;AAAA;AAIhC,EAAA;AACzB,IAAA;AACV,EAAA;AACyC,EAAA;AACX,EAAA;AACA,EAAA;AACvB,EAAA;AACgB,EAAA;AACS,EAAA;AAAA;AAE4C,EAAA;AAAA;AAElE,EAAA;AACZ;AAAA;AAES,EAAA;AACsB,IAAA;AACwB,IAAA;AACxD,EAAA;AACA,EAAA;AACW,IAAA;AACW,IAAA;AACtB,EAAA;AACF;AAgBkF;AACxD,EAAA;AACa,EAAA;AAC7B,EAAA;AAEsC,EAAA;AAC3C;AAEa,IAAA;AACsB,MAAA;AACG,MAAA;AACrC,IAAA;AACsC,IAAA;AAE9B,EAAA;AACO,EAAA;AACG,EAAA;AACgB,EAAA;AAC9B;ADKiF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/chunk-ZIM53VP6.js","sourcesContent":[null,"/**\n * Zod validation schemas for SDK site configuration.\n *\n * These schemas are used to validate configuration fetched from\n * SDK sites before storing in the database.\n */\n\nimport { z } from 'zod';\nimport { blockCategoryEnum, fieldSchema, getBlockDefinition, type SdkCustomBlock, type FieldDefinition } from '@riverbankcms/blocks';\nimport type { RiverbankSiteConfig, BlockFieldOptionsMap, BlockFieldExtensionsMap, BlockFieldExtension } from './types';\nimport { contentConfigSchema } from './content-validation';\n\n// Re-export content schemas for convenience\nexport { contentConfigSchema } from './content-validation';\nexport type { ContentConfigInput, ContentConfigOutput } from './content-validation';\n\n/**\n * Schema for SDK theme palette.\n * Maps token names to CSS color values.\n */\nexport const sdkThemePaletteSchema = z.record(z.string(), z.string());\n\n/**\n * Schema for SDK theme configuration.\n */\nexport const sdkThemeConfigSchema = z.object({\n palette: sdkThemePaletteSchema,\n});\n\n/**\n * Schema for section background color options.\n */\nexport const sectionBackgroundSchema = z.object({\n id: z.string(),\n label: z.string(),\n token: z.string(), // Reference to theme palette token\n});\n\n/**\n * Schema for section spacing values.\n */\nexport const sectionSpacingSchema = z.enum(['compact', 'default', 'spacious']);\n\n/**\n * Schema for container max-width values.\n */\nexport const containerMaxWidthSchema = z.enum(['narrow', 'default', 'wide', 'full']);\n\n/**\n * Schema for container alignment values.\n */\nexport const containerAlignmentSchema = z.enum(['left', 'center', 'right']);\n\n/**\n * Schema for section options configuration.\n */\nexport const sectionOptionsSchema = z.object({\n backgroundColor: z.boolean().optional(),\n backgroundImage: z.boolean().optional(),\n backgroundGradient: z.boolean().optional(),\n spacing: z.union([\n z.array(sectionSpacingSchema),\n z.boolean(),\n ]).optional(),\n textColor: z.boolean().optional(),\n}).optional();\n\n/**\n * Schema for container options configuration.\n */\nexport const containerOptionsSchema = z.object({\n maxWidth: z.union([\n z.array(containerMaxWidthSchema),\n z.boolean(),\n ]).optional(),\n alignment: z.union([\n z.array(containerAlignmentSchema),\n z.boolean(),\n ]).optional(),\n}).optional();\n\n/**\n * Schema for site style configuration.\n */\nexport const siteStyleConfigSchema = z.object({\n sectionBackgrounds: z.array(sectionBackgroundSchema).optional(),\n sectionOptions: sectionOptionsSchema,\n containerOptions: containerOptionsSchema,\n}).optional();\n\n// ============================================================================\n// Data Loader Schemas\n// ============================================================================\n\nimport { SUPPORTED_LOADER_ENDPOINTS } from '../data/prefetchBlockData';\n\n/**\n * Whitelisted endpoints for SDK data loaders.\n *\n * These are the only CMS endpoints that can be called from config-based loaders.\n * This ensures SDK sites can only access safe, read-only public endpoints.\n *\n * Derived from SUPPORTED_LOADER_ENDPOINTS - the single source of truth.\n */\nexport const sdkLoaderEndpointSchema = z.enum(SUPPORTED_LOADER_ENDPOINTS);\n\n/**\n * A binding expression for dynamic loader params.\n *\n * @example\n * ```typescript\n * { $bind: { from: 'content.categoryId' } }\n * { $bind: { from: '$root.siteId' } }\n * { $bind: { from: 'content.limit', fallback: '10' } }\n * ```\n */\nexport const loaderParamBindingSchema = z.object({\n $bind: z.object({\n from: z.string().min(1, \"Binding path is required\"),\n fallback: z.string().optional(),\n }),\n});\n\n/**\n * A loader param value can be static or a binding expression.\n */\nexport const loaderParamValueSchema = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n loaderParamBindingSchema,\n]);\n\n/**\n * Schema for config-based data loader.\n *\n * Config loaders execute server-side during loadPage() and are\n * restricted to whitelisted CMS endpoints.\n */\nexport const sdkConfigLoaderSchema = z.object({\n endpoint: sdkLoaderEndpointSchema,\n params: z.record(z.string(), loaderParamValueSchema),\n mode: z.enum(['server', 'client']).default('server'),\n});\n\n/**\n * Schema for the dataLoaders field on custom blocks.\n * Validates the loader configuration and limits the number of loaders.\n */\nexport const sdkDataLoadersSchema = z.record(z.string(), sdkConfigLoaderSchema)\n .refine(\n (loaders) => Object.keys(loaders).length <= 5,\n { message: \"Maximum 5 data loaders per block\" }\n )\n .optional();\n\n// ============================================================================\n// Custom Block Schema\n// ============================================================================\n\n/**\n * Schema for field select option.\n */\nexport const fieldSelectOptionSchema = z.object({\n value: z.string().min(1, \"Option value is required\"),\n label: z.string().min(1, \"Option label is required\"),\n});\n\n/**\n * Schema for per-field configuration within a block.\n */\nexport const blockFieldConfigSchema = z.object({\n options: z.array(fieldSelectOptionSchema).min(1, \"At least one option is required\").optional(),\n});\n\n/**\n * Schema for per-block field options.\n *\n * Block IDs must be either 'block.*' (system blocks) or 'custom.*' (custom blocks).\n * Field IDs can be any valid identifier string.\n */\nexport const blockFieldOptionsSchema: z.ZodType<BlockFieldOptionsMap> = z.record(\n z.string().regex(/^(block\\.|custom\\.)[a-z][a-z0-9-]*$/, {\n message: \"Block ID must be 'block.*' or 'custom.*' format\",\n }),\n z.record(\n z.string().min(1, \"Field ID is required\"),\n blockFieldConfigSchema\n )\n).optional() as z.ZodType<BlockFieldOptionsMap>;\n\n// ============================================================================\n// Block Field Extensions Schema\n// ============================================================================\n\n/**\n * Schema for block field extension configuration.\n *\n * Validates additional fields to be appended to a built-in block.\n * Includes refinement to ensure required fields have defaultValue.\n *\n * Note: Explicit type annotation required due to recursive fieldSchema complexity.\n */\nexport const blockFieldExtensionSchema: z.ZodType<BlockFieldExtension> = z.object({\n fields: fieldSchema.array().min(1, \"At least one field is required\"),\n}).refine(\n (data) => {\n // All required fields must have a defaultValue\n return data.fields.every((field: FieldDefinition) => {\n if (!field.required) return true;\n return field.defaultValue !== undefined;\n });\n },\n {\n message: \"Required fields must have a defaultValue to support existing blocks\",\n }\n) as z.ZodType<BlockFieldExtension>;\n\n/**\n * Schema for block field extensions map.\n *\n * Block IDs must be system blocks (e.g., 'block.bodyText', 'block.hero').\n * Custom blocks ('custom.*') should define their fields directly, not via extensions.\n */\nexport const blockFieldExtensionsSchema: z.ZodType<BlockFieldExtensionsMap | undefined> = z.record(\n z.string().regex(/^block\\.[a-z][a-zA-Z0-9]*$/, {\n message: \"Block ID must be 'block.*' format (system blocks only)\",\n }),\n blockFieldExtensionSchema\n).optional() as z.ZodType<BlockFieldExtensionsMap | undefined>;\n\n/**\n * Validates that extended field IDs don't conflict with existing block fields.\n *\n * This validation should be called during config push to provide clear error messages.\n * Returns an array of conflict errors, or empty array if valid.\n *\n * @example\n * ```typescript\n * const conflicts = validateFieldIdConflicts(config.blockFieldExtensions);\n * if (conflicts.length > 0) {\n * throw new Error(conflicts.map(c => c.message).join('\\n'));\n * }\n * ```\n */\nexport function validateFieldIdConflicts(\n blockFieldExtensions?: BlockFieldExtensionsMap | null\n): { blockId: string; fieldId: string; message: string }[] {\n if (!blockFieldExtensions) return [];\n\n const conflicts: { blockId: string; fieldId: string; message: string }[] = [];\n\n for (const [blockId, extension] of Object.entries(blockFieldExtensions)) {\n const definition = getBlockDefinition(blockId);\n if (!definition) {\n conflicts.push({\n blockId,\n fieldId: '',\n message: `Unknown block type: ${blockId}`,\n });\n continue;\n }\n\n // Get all existing field IDs from the block manifest\n const existingFieldIds = new Set<string>();\n const collectFieldIds = (fields: FieldDefinition[] | undefined) => {\n if (!fields) return;\n for (const field of fields) {\n existingFieldIds.add(field.id);\n // Also collect nested field IDs from groups, modals, repeaters, tab groups\n if (field.type === 'group' || field.type === 'modal') {\n collectFieldIds(field.schema?.fields);\n } else if (field.type === 'repeater' && field.schema?.fields) {\n collectFieldIds(field.schema.fields);\n } else if (field.type === 'tabGroup') {\n for (const tab of field.tabs ?? []) {\n collectFieldIds(tab.fields);\n }\n }\n }\n };\n collectFieldIds(definition.manifest.fields);\n\n // Check for conflicts\n for (const field of extension.fields) {\n if (existingFieldIds.has(field.id)) {\n conflicts.push({\n blockId,\n fieldId: field.id,\n message: `Field ID \"${field.id}\" conflicts with existing field in ${blockId}`,\n });\n }\n }\n }\n\n return conflicts;\n}\n\n/**\n * Schema for SDK custom block definitions.\n *\n * Validates custom blocks defined in riverbank.config.ts.\n * Reuses fieldSchema from @riverbankcms/blocks for field validation.\n *\n * Note: Explicit type annotation required due to recursive fieldSchema complexity.\n */\nexport const sdkCustomBlockSchema: z.ZodType<SdkCustomBlock> = z.object({\n // Block ID must start with 'custom.'\n id: z.string()\n .min(8) // 'custom.' + at least 1 char\n .regex(/^custom\\.[a-z][a-z0-9-]*$/, {\n message: \"Block ID must start with 'custom.' followed by lowercase letters, numbers, or hyphens\",\n }),\n title: z.string().min(1, \"Title is required\"),\n titleSource: z.string().optional(),\n description: z.string().optional(),\n category: blockCategoryEnum,\n icon: z.string().optional(),\n tags: z.array(z.string()).optional(),\n // Reuse the exact field schema from @riverbankcms/blocks - all field types supported\n fields: fieldSchema.array().min(1, \"Custom blocks must have at least one field\"),\n // Data loaders for CMS endpoints\n dataLoaders: sdkDataLoadersSchema,\n}).refine(\n // Validate titleSource references a valid field if provided\n (data) => {\n if (!data.titleSource) return true;\n return data.fields.some(f => f.id === data.titleSource);\n },\n {\n message: \"titleSource must reference a valid field ID\",\n path: [\"titleSource\"],\n }\n) as z.ZodType<SdkCustomBlock>;\n\n/**\n * Schema for the complete SDK site configuration.\n *\n * Use this schema to validate configuration fetched from SDK sites\n * before storing in the database.\n *\n * @example\n * ```typescript\n * import { riverbankSiteConfigSchema } from '@riverbankcms/sdk/config/validation';\n *\n * const rawConfig = await response.json();\n * const config = riverbankSiteConfigSchema.parse(rawConfig);\n * ```\n */\nexport const riverbankSiteConfigSchema: z.ZodType<RiverbankSiteConfig> = z.object({\n siteId: z.string().uuid(),\n theme: sdkThemeConfigSchema.optional(),\n styles: siteStyleConfigSchema,\n customBlocks: z.array(sdkCustomBlockSchema)\n .max(20, \"Maximum 20 custom blocks per site\")\n .refine(\n // Ensure unique block IDs\n (blocks) => {\n const ids = blocks.map(b => b.id);\n return ids.length === new Set(ids).size;\n },\n { message: \"Block IDs must be unique\" }\n )\n .optional(),\n blockFieldOptions: blockFieldOptionsSchema,\n blockFieldExtensions: blockFieldExtensionsSchema,\n content: contentConfigSchema.optional(),\n}).strict() as z.ZodType<RiverbankSiteConfig>;\n\n/**\n * Type inferred from the validation schema.\n * This should match the RiverbankSiteConfig type from ./types.ts\n */\nexport type ValidatedRiverbankSiteConfig = z.infer<typeof riverbankSiteConfigSchema>;\n\n/**\n * Type for a validated SDK custom block.\n */\nexport type ValidatedSdkCustomBlock = z.infer<typeof sdkCustomBlockSchema>;\n\n// ============================================================================\n// Compile-time type assertions\n//\n// These assertions ensure the Zod schemas stay in sync with the TypeScript types.\n// If the schema output diverges from the expected type, TypeScript will error here.\n// ============================================================================\n\n/** Asserts sdkCustomBlockSchema output matches SdkCustomBlock */\ntype _AssertSdkCustomBlockSchema = z.infer<typeof sdkCustomBlockSchema> extends SdkCustomBlock\n ? SdkCustomBlock extends z.infer<typeof sdkCustomBlockSchema>\n ? true\n : never\n : never;\n\n/** Asserts riverbankSiteConfigSchema output matches RiverbankSiteConfig */\ntype _AssertRiverbankSiteConfigSchema = z.infer<typeof riverbankSiteConfigSchema> extends RiverbankSiteConfig\n ? RiverbankSiteConfig extends z.infer<typeof riverbankSiteConfigSchema>\n ? true\n : never\n : never;\n\n// These assignments will fail to compile if the types don't match\nconst _checkSdkCustomBlock: _AssertSdkCustomBlockSchema = true;\nconst _checkRiverbankSiteConfig: _AssertRiverbankSiteConfigSchema = true;\n\n// Prevent unused variable warnings\nvoid _checkSdkCustomBlock;\nvoid _checkRiverbankSiteConfig;\n","/**\n * SDK Content Config Validation\n *\n * Zod schemas for validating SDK content configuration.\n */\n\nimport { z } from 'zod';\nimport { SYSTEM_BLOCK_KINDS } from '../types';\nimport type { ContentConfig, ContentTypeConfig } from './content-types';\n\n// Use looseObject for data fields that can contain arbitrary values\nconst jsonDataSchema = z.record(z.string(), z.any());\n\n// ============================================================================\n// Content Type Schema\n// ============================================================================\n\n/**\n * Content type key validation.\n * Must be lowercase, start with a letter, and contain only letters, numbers, and hyphens.\n */\nconst contentTypeKeySchema = z\n .string()\n .min(1)\n .regex(\n /^[a-z][a-z0-9-]*$/,\n 'Key must be lowercase, start with a letter, and contain only letters, numbers, and hyphens'\n );\n\n/**\n * Content type config schema.\n */\nexport const contentTypeConfigSchema: z.ZodType<ContentTypeConfig> = z\n .object({\n key: contentTypeKeySchema,\n name: z.string().min(1),\n description: z.string().optional(),\n hasPages: z.boolean(),\n routePattern: z.string().optional(),\n // Fields are validated as any[] here - deep field validation happens in @riverbankcms/blocks\n fields: z.array(z.any()).min(1, 'At least one field is required'),\n titleField: z.string().optional(),\n })\n .refine(\n (data) => {\n // If hasPages is true, routePattern must be provided and contain {slug}\n if (data.hasPages) {\n return data.routePattern && data.routePattern.includes('{slug}');\n }\n return true;\n },\n { message: 'routePattern with {slug} is required when hasPages is true' }\n )\n .refine(\n (data) => {\n // If hasPages is false, routePattern must NOT be defined\n if (!data.hasPages && data.routePattern) {\n return false;\n }\n return true;\n },\n { message: 'routePattern must not be defined when hasPages is false' }\n ) as z.ZodType<ContentTypeConfig>;\n\n// ============================================================================\n// Block Config Schema\n// ============================================================================\n\n/**\n * Block kind validation.\n * Must be either a system block kind (e.g., 'block.hero') or a custom block kind (e.g., 'custom.myBlock').\n */\nconst blockKindSchema = z.string().refine(\n (kind) => {\n // Check if it's a system block kind\n if ((SYSTEM_BLOCK_KINDS as readonly string[]).includes(kind)) {\n return true;\n }\n // Check if it's a custom block kind (custom.${string})\n if (kind.startsWith('custom.') && kind.length > 7) {\n return true;\n }\n return false;\n },\n {\n message:\n 'Block kind must be a system block (e.g., \"block.hero\") or a custom block (e.g., \"custom.myBlock\")',\n }\n);\n\nexport const blockConfigSchema = z.object({\n kind: blockKindSchema,\n content: jsonDataSchema,\n orderIndex: z.number().optional(),\n});\n\n// ============================================================================\n// Page Config Schema\n// ============================================================================\n\nexport const pageConfigSchema = z.object({\n identifier: z.string().min(1, 'Identifier is required'),\n title: z.string().min(1, 'Title is required'),\n path: z.string().regex(/^\\//, 'Path must start with /'),\n purpose: z.string().default('content'),\n blocks: z.array(blockConfigSchema).optional(),\n status: z.enum(['draft', 'published']).default('draft'),\n metaTitle: z.string().optional(),\n metaDescription: z.string().optional(),\n});\n\n// ============================================================================\n// Entry Config Schema\n// ============================================================================\n\nexport const entryConfigSchema = z.object({\n identifier: z.string().min(1, 'Identifier is required'),\n contentType: z.string().min(1, 'Content type is required'),\n data: jsonDataSchema,\n status: z.enum(['draft', 'published']).default('draft'),\n slug: z.string().optional(),\n title: z.string().optional(),\n summary: z.string().optional(),\n metaTitle: z.string().optional(),\n metaDescription: z.string().optional(),\n});\n\n// ============================================================================\n// Navigation Config Schema\n// ============================================================================\n\nconst pageLinkSchema = z.object({\n kind: z.literal('page'),\n identifier: z.string().min(1),\n});\n\nconst entryLinkSchema = z.object({\n kind: z.literal('entry'),\n identifier: z.string().min(1),\n});\n\nconst externalLinkSchema = z.object({\n kind: z.literal('external'),\n href: z.string().url('Invalid URL'),\n});\n\nconst dropdownLinkSchema = z.object({\n kind: z.literal('dropdown'),\n});\n\nconst navigationLinkSchema = z.discriminatedUnion('kind', [\n pageLinkSchema,\n entryLinkSchema,\n externalLinkSchema,\n dropdownLinkSchema,\n]);\n\n// Navigation item with recursive children support\nconst baseNavigationItemSchema = z.object({\n label: z.string().min(1, 'Label is required'),\n link: navigationLinkSchema,\n isCta: z.boolean().optional(),\n});\n\n// Using z.lazy for recursive type\nexport const navigationItemConfigSchema: z.ZodType<{\n label: string;\n link:\n | { kind: 'page'; identifier: string }\n | { kind: 'entry'; identifier: string }\n | { kind: 'external'; href: string }\n | { kind: 'dropdown' };\n isCta?: boolean;\n children?: Array<{\n label: string;\n link:\n | { kind: 'page'; identifier: string }\n | { kind: 'entry'; identifier: string }\n | { kind: 'external'; href: string }\n | { kind: 'dropdown' };\n isCta?: boolean;\n children?: unknown[];\n }>;\n}> = baseNavigationItemSchema.extend({\n children: z.lazy(() => z.array(navigationItemConfigSchema)).optional(),\n});\n\nexport const navigationMenuConfigSchema = z.object({\n identifier: z.string().min(1, 'Identifier is required'),\n name: z.string().min(1, 'Name is required'),\n isPrimary: z.boolean().optional(),\n items: z.array(navigationItemConfigSchema),\n});\n\n// ============================================================================\n// Site Settings Schema\n// ============================================================================\n\nexport const siteSettingsConfigSchema = z.object({\n homepagePath: z.string().optional(),\n siteTitle: z.string().optional(),\n siteDescription: z.string().optional(),\n defaultTemplates: z.record(z.string(), z.string()).optional(),\n});\n\n// ============================================================================\n// Complete Content Config Schema\n// ============================================================================\n\nconst contentConfigBaseSchema = z.object({\n contentTypes: z.array(contentTypeConfigSchema).optional(),\n entries: z.array(entryConfigSchema).optional(),\n pages: z.array(pageConfigSchema).optional(),\n navigationMenus: z.array(navigationMenuConfigSchema).optional(),\n settings: siteSettingsConfigSchema.optional(),\n});\n\nexport const contentConfigSchema: z.ZodType<ContentConfig> = contentConfigBaseSchema\n .superRefine((data, ctx) => {\n // Validate unique content type keys\n if (data.contentTypes && data.contentTypes.length > 1) {\n const keys = data.contentTypes.map((ct) => ct.key);\n const duplicateKeys = keys.filter((key, i) => keys.indexOf(key) !== i);\n if (duplicateKeys.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Content type keys must be unique. Duplicates: ${duplicateKeys.join(', ')}`,\n path: ['contentTypes'],\n });\n }\n }\n\n // Validate unique page identifiers\n if (data.pages && data.pages.length > 1) {\n const identifiers = data.pages.map((p) => p.identifier);\n const duplicateIds = identifiers.filter((id, i) => identifiers.indexOf(id) !== i);\n if (duplicateIds.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Page identifiers must be unique. Duplicates: ${duplicateIds.join(', ')}`,\n path: ['pages'],\n });\n }\n\n // Validate unique page paths\n const paths = data.pages.map((p) => p.path);\n const duplicatePaths = paths.filter((path, i) => paths.indexOf(path) !== i);\n if (duplicatePaths.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Page paths must be unique. Duplicates: ${duplicatePaths.join(', ')}`,\n path: ['pages'],\n });\n }\n }\n\n // Validate unique entry identifiers\n if (data.entries && data.entries.length > 1) {\n const identifiers = data.entries.map((e) => e.identifier);\n const duplicateIds = identifiers.filter((id, i) => identifiers.indexOf(id) !== i);\n if (duplicateIds.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Entry identifiers must be unique. Duplicates: ${duplicateIds.join(', ')}`,\n path: ['entries'],\n });\n }\n }\n\n // Validate unique navigation menu identifiers\n if (data.navigationMenus && data.navigationMenus.length > 1) {\n const identifiers = data.navigationMenus.map((m) => m.identifier);\n const duplicateIds = identifiers.filter((id, i) => identifiers.indexOf(id) !== i);\n if (duplicateIds.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Navigation menu identifiers must be unique. Duplicates: ${duplicateIds.join(', ')}`,\n path: ['navigationMenus'],\n });\n }\n }\n }) as z.ZodType<ContentConfig>;\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type ContentTypeConfigInput = z.input<typeof contentTypeConfigSchema>;\nexport type ContentTypeConfigOutput = z.output<typeof contentTypeConfigSchema>;\n\nexport type PageConfigInput = z.input<typeof pageConfigSchema>;\nexport type PageConfigOutput = z.output<typeof pageConfigSchema>;\n\nexport type EntryConfigInput = z.input<typeof entryConfigSchema>;\nexport type EntryConfigOutput = z.output<typeof entryConfigSchema>;\n\nexport type NavigationMenuConfigInput = z.input<typeof navigationMenuConfigSchema>;\nexport type NavigationMenuConfigOutput = z.output<typeof navigationMenuConfigSchema>;\n\nexport type ContentConfigInput = z.input<typeof contentConfigSchema>;\nexport type ContentConfigOutput = z.output<typeof contentConfigSchema>;\n"]}