cms-renderer 0.6.5 → 0.6.6
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.
- package/README.md +11 -11
- package/dist/lib/cms-api.d.ts +1 -0
- package/dist/lib/cms-api.js +11 -1
- package/dist/lib/cms-api.js.map +1 -1
- package/dist/lib/custom-schemas.js +17 -2
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/docs-markdown.d.ts +1 -0
- package/dist/lib/docs-markdown.js +97 -12
- package/dist/lib/docs-markdown.js.map +1 -1
- package/dist/lib/proxy.js +8 -20
- package/dist/lib/proxy.js.map +1 -1
- package/dist/lib/renderer.js +15 -10
- package/dist/lib/renderer.js.map +1 -1
- package/dist/lib/schema.d.ts +19 -7
- package/dist/lib/schema.js +41 -7
- package/dist/lib/schema.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/tokens.js","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/types/types.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/set-lookup.js","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/types/index.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/sets.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/util.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/tokenizer.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/sets-lookup.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/write-set-tokens.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/reconstruct.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/index.ts","../../../../node_modules/.bun/safe-regex2@5.0.0/node_modules/safe-regex2/index.js","../../lib/custom-schemas.ts","../../../../packages/cms-schema/src/documents/registry.ts","../../../../packages/cms-schema/src/documents/schemas/country.ts","../../../../packages/cms-schema/src/documents/schemas/language.ts","../../../../packages/cms-schema/src/documents/unified-registry.ts","../../../../packages/cms-schema/src/documents/rehydration.ts","../../../../packages/cms-schema/src/fields/complex/media.ts","../../../../packages/cms-schema/src/validation/image.ts","../../../../packages/cms-schema/src/fields/complex/richtext.ts","../../../../packages/cms-schema/src/utils/safe-regex.ts","../../../../packages/cms-schema/src/documents/schema-hash.ts","../../../../packages/cms-schema/src/documents/validations/country.ts","../../../../packages/cms-schema/src/documents/parse-field-definitions-json.ts","../../lib/cms-api.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=tokens.js.map",null,"\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=set-lookup.js.map",null,null,null,null,null,null,null,null,"'use strict'\n\nconst parse = require('ret')\nconst types = parse.types\n\nfunction safeRegex (re, opts) {\n if (!opts) opts = {}\n /* c8 ignore next */\n const replimit = opts.limit === undefined ? 25 : opts.limit\n\n /* c8 ignore next 2 */\n if (isRegExp(re)) re = re.source\n else if (typeof re !== 'string') re = String(re)\n\n try { re = parse(re) } catch { return false }\n\n let reps = 0\n return (function walk (node, starHeight) {\n let i\n let ok\n let len\n\n if (node.type === types.REPETITION) {\n starHeight++\n reps++\n if (starHeight > 1) return false\n if (reps > replimit) return false\n }\n\n if (node.options) {\n for (i = 0, len = node.options.length; i < len; i++) {\n ok = walk({ stack: node.options[i] }, starHeight)\n if (!ok) return false\n }\n }\n const stack = node.stack || node.value?.stack\n if (!stack) return true\n\n for (i = 0; i < stack.length; i++) {\n ok = walk(stack[i], starHeight)\n if (!ok) return false\n }\n\n return true\n })(re, 0)\n}\n\nfunction isRegExp (x) {\n return {}.toString.call(x) === '[object RegExp]'\n}\n\nmodule.exports = safeRegex\nmodule.exports.default = safeRegex\nmodule.exports.safeRegex = safeRegex\n","/**\n * Custom Schema Fetcher\n *\n * Fetches custom schema definitions (field metadata as JSON) from the CMS API\n * for a given website. Uses the tRPC client to call the customSchema router.\n */\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { FieldConstraints, FieldDefinition } from '@repo/cms-schema/documents';\nimport { rehydrateSchema } from '@repo/cms-schema/documents';\nimport escapeStringRegexp from 'escape-string-regexp';\nimport type { ZodObject, ZodRawShape } from 'zod';\nimport { type CmsConfig, getCmsClient } from './cms-api';\n\nexport interface CustomSchemaFields {\n name: string;\n displayName: string;\n description: string | null;\n fields: FieldDefinition[];\n routeSlugField: string | null;\n version: number;\n}\n\nexport type FetchCustomSchemasOptions = CmsConfig & { websiteId: string };\n\n/**\n * Fetches all custom schemas with their field definitions for a website.\n *\n * @example\n * ```ts\n * const schemas = await fetchAllCustomSchemaFields({\n * cmsUrl: 'http://localhost:3000',\n * apiKey: 'my-api-key',\n * websiteId: 'uuid-here',\n * });\n *\n * for (const schema of schemas) {\n * console.log(schema.name, schema.fields);\n * }\n * ```\n */\nexport async function fetchAllCustomSchemaFields(\n options: FetchCustomSchemasOptions\n): Promise<CustomSchemaFields[]> {\n const { websiteId } = options;\n\n const client = getCmsClient(options);\n\n // Get the list of all custom schemas (summaries only)\n const summaries = await client.customSchema.list.query({\n websiteId,\n includePresets: false,\n });\n\n // Fetch full field definitions for each schema in parallel\n const schemas = await Promise.all(\n summaries.map(async (summary) => {\n const detail = await client.customSchema.getByName.query({\n websiteId,\n name: summary.name,\n });\n\n return {\n name: detail.name,\n displayName: detail.displayName,\n description: detail.description ?? null,\n fields: detail.fields,\n routeSlugField: detail.routeSlugField ?? null,\n version: detail.version,\n } satisfies CustomSchemaFields;\n })\n );\n\n return schemas;\n}\n\n/**\n * Fetches a single custom schema's field definitions by name.\n *\n * @example\n * ```ts\n * const schema = await fetchCustomSchemaFields({\n * cmsUrl: 'http://localhost:3000',\n * apiKey: 'my-api-key',\n * websiteId: 'uuid-here',\n * }, 'blog_post');\n *\n * console.log(schema.fields);\n * ```\n */\nexport async function fetchCustomSchemaFields(\n options: FetchCustomSchemasOptions,\n schemaName: string\n): Promise<CustomSchemaFields> {\n const { websiteId } = options;\n const client = getCmsClient(options);\n\n const detail = await client.customSchema.getByName.query({\n websiteId,\n name: schemaName,\n });\n\n return {\n name: detail.name,\n displayName: detail.displayName,\n description: detail.description ?? null,\n fields: detail.fields,\n routeSlugField: detail.routeSlugField ?? null,\n version: detail.version,\n };\n}\n\n/**\n * Converts an array of custom schema definitions into a record of Zod schemas,\n * keyed by schema name.\n *\n * @example\n * ```ts\n * const schemas = await fetchAllCustomSchemaFields(options);\n * const zodSchemas = buildZodSchemas(schemas);\n *\n * // Validate a blog post document\n * const result = zodSchemas['blog_post'].safeParse(data);\n * ```\n */\nexport function buildZodSchemas(\n schemas: CustomSchemaFields[]\n): Record<string, ZodObject<ZodRawShape>> {\n // biome-ignore lint/suspicious/noExplicitAny: avoids excessively deep type instantiation from Zod generics\n const result: Record<string, any> = {};\n\n for (const schema of schemas) {\n result[schema.name] = rehydrateSchema(schema.fields);\n }\n\n return result;\n}\n\n/**\n * Generates combined Zod schema TypeScript source code and writes it to disk.\n *\n * @param schemas - Array of custom schema definitions\n * @param outputPath - File path to write the generated code to\n */\nexport async function saveZodSchemaCode(\n schemas: CustomSchemaFields[],\n outputPath: string\n): Promise<void> {\n const code = generateCombinedZodSchemaCode(\n schemas.map((s) => ({ name: s.name, fields: s.fields }))\n );\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, code, 'utf-8');\n}\n\nfunction generateCombinedZodSchemaCode(\n schemas: Array<{ name: string; fields: FieldDefinition[] }>\n): string {\n const lines: string[] = [];\n\n lines.push('/* eslint-disable */');\n lines.push('/* prettier-ignore */');\n lines.push('/* biome-ignore format: auto-generated */');\n lines.push('// This file is auto-generated by cms-renderer. Do not edit manually.');\n lines.push('');\n lines.push(`import { z } from 'zod';`);\n lines.push('');\n\n const hasImageField = schemas.some((s) => s.fields.some((f) => f.type === 'image'));\n if (hasImageField) {\n lines.push('const ImageReferenceSchema = z.object({');\n lines.push(\" alt: z.string().min(1, 'Alt text is required for accessibility'),\");\n lines.push(' caption: z.string().max(500).optional(),');\n lines.push(' attribution: z.string().max(255).optional(),');\n lines.push(' _asset: z.object({');\n lines.push(' id: z.string().uuid(),');\n lines.push(' }),');\n lines.push('});');\n lines.push('');\n }\n\n for (const [i, schema] of schemas.entries()) {\n if (i > 0) lines.push('');\n const varName = `${toCamelCase(schema.name)}Schema`;\n lines.push(`export const ${varName} = z.object({`);\n for (const field of schema.fields) {\n if (field.description) lines.push(` /** ${field.description} */`);\n lines.push(` ${field.name}: ${generateFieldCode(field)},`);\n }\n lines.push('});');\n lines.push('');\n lines.push(`export type ${toPascalCase(schema.name)} = z.infer<typeof ${varName}>;`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nfunction generateFieldCode(field: FieldDefinition): string {\n let code = generateBaseTypeCode(field.type, field.constraints);\n if (!field.required) code += '.optional()';\n return code;\n}\n\nfunction generateBaseTypeCode(\n type: FieldDefinition['type'],\n constraints?: FieldConstraints\n): string {\n switch (type) {\n case 'string':\n return applyStringConstraintCode('z.string()', constraints);\n case 'number':\n return applyNumberConstraintCode('z.number()', constraints);\n case 'boolean':\n return 'z.boolean()';\n case 'image':\n return 'ImageReferenceSchema';\n case 'date':\n return \"z.string().date('Invalid date format. Expected YYYY-MM-DD')\";\n case 'datetime':\n return \"z.string().datetime({ offset: true, message: 'Invalid datetime format. Expected ISO 8601' })\";\n case 'url':\n return applyStringConstraintCode(\"z.string().url('Invalid URL format')\", constraints);\n case 'email':\n return applyStringConstraintCode(\"z.string().email('Invalid email format')\", constraints);\n case 'enum': {\n const values = constraints?.enumValues;\n if (!values || values.length === 0) return \"z.enum([''])\";\n const formatted = values\n .map((v) => `'${v.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`)\n .join(', ');\n return `z.enum([${formatted}])`;\n }\n case 'reference':\n return 'z.record(z.string(), z.unknown())';\n case 'array': {\n const itemType = constraints?.arrayItemType ?? 'string';\n const itemCode =\n itemType === 'number'\n ? 'z.number()'\n : itemType === 'boolean'\n ? 'z.boolean()'\n : itemType === 'reference'\n ? 'z.record(z.string(), z.unknown())'\n : 'z.string()';\n return applyArrayConstraintCode(`z.array(${itemCode})`, constraints);\n }\n default:\n return 'z.unknown()';\n }\n}\n\nfunction applyStringConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.minLength !== undefined)\n code += `.min(${constraints.minLength}, 'Must be at least ${constraints.minLength} characters')`;\n if (constraints.maxLength !== undefined)\n code += `.max(${constraints.maxLength}, 'Must be at most ${constraints.maxLength} characters')`;\n if (constraints.pattern)\n code += `.regex(/${escapeStringRegexp(constraints.pattern)}/, 'Invalid format')`;\n return code;\n}\n\nfunction applyNumberConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.integer) code += `.int('Must be an integer')`;\n if (constraints.min !== undefined)\n code += `.min(${constraints.min}, 'Must be at least ${constraints.min}')`;\n if (constraints.max !== undefined)\n code += `.max(${constraints.max}, 'Must be at most ${constraints.max}')`;\n return code;\n}\n\nfunction applyArrayConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.minItems !== undefined)\n code += `.min(${constraints.minItems}, 'Must have at least ${constraints.minItems} items')`;\n if (constraints.maxItems !== undefined)\n code += `.max(${constraints.maxItems}, 'Must have at most ${constraints.maxItems} items')`;\n return code;\n}\n\nfunction toCamelCase(str: string): string {\n return str.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\nfunction toPascalCase(str: string): string {\n const camel = toCamelCase(str);\n return camel.charAt(0).toUpperCase() + camel.slice(1);\n}\n","/**\n * Document Schema Registry.\n *\n * Centralizes registration for all document schemas.\n * The CMS reads this registry to generate UI and validation.\n */\n\nimport { type ZodObject, type ZodRawShape, z } from 'zod';\nimport type { DocumentError } from '../db/document-types';\nimport { DocumentErrors } from '../db/document-types';\nimport type { TypedSupabaseClient } from '../db/types';\nimport type { Result } from '../types/errors';\nimport { err, ok } from '../types/errors';\n\n// =============================================================================\n// Validation Schemas\n// =============================================================================\n\n/**\n * Schema name validation - must be a non-empty string.\n */\nconst schemaNameValidator = z\n .string()\n .min(1, 'Schema name must be a non-empty string')\n .refine((name) => name.trim().length > 0, 'Schema name must not be only whitespace');\n\n/**\n * Runtime validator for document schema config.\n * Validates the config object structure at runtime.\n */\nconst documentSchemaConfigValidator = z.object({\n schema: z.custom<ZodObject<ZodRawShape>>(\n (val) => val !== null && typeof val === 'object' && '_def' in val,\n { message: 'schema must be a valid Zod schema' }\n ),\n titleField: z.string().optional(),\n displayName: z.string().optional(),\n description: z.string().optional(),\n validateContent: z.function().optional(),\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Configuration for a registered document schema.\n */\nexport interface DocumentSchemaConfig<T extends ZodRawShape = ZodRawShape> {\n /** Zod schema for content validation */\n schema: ZodObject<T>;\n /** Field to extract for title (default: tries 'name', 'title', 'code') */\n titleField?: string;\n /** Display name for the schema in the UI */\n displayName?: string;\n /** Description of the document type */\n description?: string;\n /** Optional custom validation function for schema-specific rules */\n validateContent?: (content: unknown, supabase: TypedSupabaseClient) => Promise<void>;\n}\n\n/**\n * Registered schema with computed metadata.\n */\nexport interface RegisteredSchema<T extends ZodRawShape = ZodRawShape>\n extends DocumentSchemaConfig<T> {\n /** Schema name (registry key) */\n name: string;\n}\n\n// =============================================================================\n// Registry\n// =============================================================================\n\nconst documentRegistry = new Map<string, DocumentSchemaConfig>();\n\n/**\n * Register a document schema.\n *\n * @example\n * registerDocumentSchema('country', {\n * schema: CountrySchema,\n * titleField: 'name',\n * displayName: 'Country',\n * });\n *\n * @throws {Error} If schema name is empty or already registered\n */\nexport function registerDocumentSchema<T extends ZodRawShape>(\n name: string,\n config: DocumentSchemaConfig<T>\n): void {\n // Validate schema name using Zod\n const nameResult = schemaNameValidator.safeParse(name);\n if (!nameResult.success) {\n throw new Error(nameResult.error.issues.at(0)?.message ?? 'Invalid schema name');\n }\n\n // Validate config structure using Zod\n const configResult = documentSchemaConfigValidator.safeParse(config);\n if (!configResult.success) {\n throw new Error(\n `Invalid schema config: ${configResult.error.issues.at(0)?.message ?? 'Unknown error'}`\n );\n }\n\n // Check for duplicate registration\n if (documentRegistry.has(name)) {\n throw new Error(`Document schema \"${name}\" is already registered`);\n }\n\n documentRegistry.set(name, config as DocumentSchemaConfig);\n}\n\n/**\n * Get a document schema configuration by name.\n */\nexport function getDocumentSchema(name: string): DocumentSchemaConfig | undefined {\n return documentRegistry.get(name);\n}\n\n/**\n * Get all registered schema names.\n */\nexport function getRegisteredDocumentSchemas(): string[] {\n return Array.from(documentRegistry.keys());\n}\n\n/**\n * Get all registered schemas with their configurations.\n */\nexport function getAllDocumentSchemas(): RegisteredSchema[] {\n return Array.from(documentRegistry.entries()).map(([name, config]) => ({\n name,\n ...config,\n }));\n}\n\n/**\n * Clear the document registry (for testing).\n */\nexport function clearDocumentRegistry(): void {\n documentRegistry.clear();\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\n/**\n * Validate document content against a registered schema.\n *\n * @returns Result with validated data or error\n */\nexport function validateDocumentContent<T>(\n schemaName: string,\n content: unknown\n): Result<T, DocumentError> {\n const config = documentRegistry.get(schemaName);\n\n if (!config) {\n return err(DocumentErrors.schemaNotFound(schemaName));\n }\n\n const result = config.schema.safeParse(content);\n\n if (!result.success) {\n const issues = result.error.issues.map((issue) => ({\n path: issue.path.filter((p): p is string | number => typeof p !== 'symbol'),\n message: issue.message,\n }));\n return err(DocumentErrors.validationError(issues));\n }\n\n return ok(result.data as T);\n}\n\n/**\n * Detailed validation result for UI display.\n */\nexport interface DocumentValidationResult<T> {\n valid: boolean;\n data?: T;\n issues?: Array<{ path: (string | number)[]; message: string }>;\n}\n\n/**\n * Validate document content with detailed error info for UI.\n */\nexport function validateDocumentContentDetailed<T>(\n schemaName: string,\n content: unknown\n): DocumentValidationResult<T> {\n const config = documentRegistry.get(schemaName);\n\n if (!config) {\n return {\n valid: false,\n issues: [{ path: [], message: `Document schema not found: ${schemaName}` }],\n };\n }\n\n const result = config.schema.safeParse(content);\n\n if (!result.success) {\n return {\n valid: false,\n issues: result.error.issues.map((issue) => ({\n path: issue.path.filter((p): p is string | number => typeof p !== 'symbol'),\n message: issue.message,\n })),\n };\n }\n\n return { valid: true, data: result.data as T };\n}\n\n// =============================================================================\n// Title Extraction\n// =============================================================================\n\n/**\n * Extract title from document content based on schema configuration.\n *\n * Tries in order:\n * 1. Schema's configured titleField\n * 2. 'title' field\n * 3. 'name' field\n * 4. 'code' field\n * 5. 'Untitled'\n */\nexport function extractDocumentTitle(schemaName: string, content: Record<string, unknown>): string {\n const config = documentRegistry.get(schemaName);\n\n // Try configured title field first\n if (config?.titleField && content[config.titleField] !== undefined) {\n return String(content[config.titleField]);\n }\n\n // Fall back to common title fields\n if (content.title !== undefined) return String(content.title);\n if (content.name !== undefined) return String(content.name);\n if (content.code !== undefined) return String(content.code);\n\n return 'Untitled';\n}\n\n// =============================================================================\n// Schema Introspection\n// =============================================================================\n\n/**\n * Get field information from a registered schema for dynamic form generation.\n */\nexport interface SchemaFieldInfo {\n name: string;\n type: string;\n isOptional: boolean;\n required: boolean;\n isArray: boolean;\n description?: string;\n /** For enum types, the available values */\n enumValues?: string[];\n /** For array types, the item type */\n itemType?: string;\n /** For reference types, the referenced schema */\n refSchema?: string;\n /** Default value if the field has one */\n defaultValue?: unknown;\n /** Whether this field has a default value */\n hasDefault?: boolean;\n}\n\n/**\n * Extract field info from a document schema for UI generation.\n */\nexport function getSchemaFields(schemaName: string): SchemaFieldInfo[] {\n const config = documentRegistry.get(schemaName);\n if (!config) return [];\n\n const shape = config.schema.shape;\n const fields: SchemaFieldInfo[] = [];\n\n for (const [name, zodType] of Object.entries(shape)) {\n const typeDef = zodType as z.ZodTypeAny;\n const isOptional = typeDef.isOptional();\n const fieldType = getFieldType(typeDef);\n const isArray = isArrayType(typeDef);\n const { value: defaultValue, hasDefault } = getDefaultValue(typeDef);\n\n const fieldInfo: SchemaFieldInfo = {\n name,\n type: fieldType,\n isOptional,\n required: !isOptional && !hasDefault, // Field is not required if it has a default\n isArray,\n description: typeDef.description,\n defaultValue,\n hasDefault,\n };\n\n // Extract enum values if this is an enum type\n // Also check if we can extract enum values even if type wasn't detected as enum\n const enumValues = getEnumValues(typeDef);\n if (enumValues.length > 0) {\n fieldInfo.enumValues = enumValues;\n // If we found enum values but type wasn't detected as enum, fix the type\n if (fieldType !== 'enum') {\n fieldInfo.type = 'enum';\n }\n }\n\n // Extract array item info\n if (isArray) {\n const arrayInfo = getArrayItemInfo(typeDef);\n fieldInfo.itemType = arrayInfo.itemType;\n fieldInfo.refSchema = arrayInfo.refSchema;\n }\n\n fields.push(fieldInfo);\n }\n\n return fields;\n}\n\nfunction getFieldType(zodType: z.ZodTypeAny): string {\n const unwrapped = unwrapType(zodType);\n // Zod v4 exposes runtime metadata via `def.type`/`def.checks` (legacy builds may still use `typeName`).\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n const kind = normalizeDefType(getDefType(def));\n if (!kind) return 'unknown';\n\n switch (kind) {\n case 'string': {\n const checks = (def?.checks as unknown[] | undefined) ?? [];\n for (const check of checks) {\n const checkDef =\n (check as { _def?: Record<string, unknown>; def?: Record<string, unknown> })._def ??\n (check as { _def?: Record<string, unknown>; def?: Record<string, unknown> }).def;\n const format = checkDef?.format;\n if (format === 'date') return 'date';\n if (format === 'datetime') return 'datetime';\n if (format === 'url') return 'url';\n if (format === 'email') return 'email';\n }\n return 'string';\n }\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'array':\n return 'array';\n case 'object':\n return 'object';\n case 'enum':\n return 'enum';\n default:\n return kind;\n }\n}\n\nfunction isArrayType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n const kind = normalizeDefType(getDefType(def));\n return kind === 'array';\n}\n\n/**\n * Extract default value from a Zod type.\n */\nfunction getDefaultValue(zodType: z.ZodTypeAny): { value?: unknown; hasDefault: boolean } {\n const def = zodType.def;\n if (!def) return { hasDefault: false };\n\n // Check for default value in ZodDefault\n const defType = getDefType(def);\n const isDefault = defType === 'ZodDefault' || defType === 'default';\n if (isDefault) {\n if ('defaultValue' in def) {\n const defaultValue = def.defaultValue;\n // Default value can be a function or a value\n if (typeof defaultValue === 'function') {\n try {\n return { value: defaultValue(), hasDefault: true };\n } catch {\n return { hasDefault: false };\n }\n }\n return { value: defaultValue, hasDefault: true };\n }\n }\n\n // Unwrap optional/nullable to check inner type\n if ('innerType' in def) {\n return getDefaultValue(def.innerType as z.ZodTypeAny);\n }\n\n return { hasDefault: false };\n}\n\n/**\n * Extract enum values from a Zod enum type.\n */\nfunction getEnumValues(zodType: z.ZodTypeAny): string[] {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return [];\n\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'enum') return [];\n\n const values = (def.values as unknown[] | undefined)?.filter(\n (value): value is string => typeof value === 'string'\n );\n if (values && values.length > 0) {\n return values;\n }\n\n const entries = def.entries as Record<string, unknown> | undefined;\n if (entries) {\n return Object.values(entries).filter((value): value is string => typeof value === 'string');\n }\n\n return [];\n}\n\n/**\n * Extract array item type information.\n */\nfunction getArrayItemInfo(zodType: z.ZodTypeAny): { itemType: string; refSchema?: string } {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return { itemType: 'unknown' };\n\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'array') return { itemType: 'unknown' };\n\n // Zod v4 stores array item schema in `element`; older versions may use `type`.\n const itemType = ((def.element ?? def.type) as z.ZodTypeAny | undefined) ?? null;\n if (!itemType) return { itemType: 'unknown' };\n const itemUnwrapped = unwrapType(itemType);\n const itemDef = itemUnwrapped.def as unknown as Record<string, unknown> | undefined;\n const itemKind = normalizeDefType(getDefType(itemDef));\n\n // Check if it's a reference object (has _type, _ref, _schema)\n if (itemKind === 'object') {\n const shape = getObjectShape(itemUnwrapped);\n if (shape && '_type' in shape && '_ref' in shape && '_schema' in shape) {\n const refSchema = getLiteralValue(shape._schema);\n if (refSchema) {\n return { itemType: 'reference', refSchema };\n }\n return { itemType: 'reference' };\n }\n }\n\n return { itemType: getFieldType(itemUnwrapped) };\n}\n\nfunction getDefType(def: unknown): string | undefined {\n if (!def || typeof def !== 'object') return undefined;\n // Keep compatibility with both v3-style `typeName` and v4-style `type`.\n const maybeDef = def as { typeName?: unknown; type?: unknown };\n if (typeof maybeDef.typeName === 'string') return maybeDef.typeName;\n if (typeof maybeDef.type === 'string') return maybeDef.type;\n return undefined;\n}\n\nfunction normalizeDefType(defType: string | undefined): string | undefined {\n if (!defType) return undefined;\n return defType.startsWith('Zod') ? defType.slice(3).toLowerCase() : defType.toLowerCase();\n}\n\nfunction unwrapType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let current: z.ZodTypeAny = zodType;\n\n while (true) {\n const def = current.def as unknown as Record<string, unknown> | undefined;\n if (!def) return current;\n const kind = normalizeDefType(getDefType(def));\n if (\n (kind === 'default' ||\n kind === 'optional' ||\n kind === 'nullable' ||\n kind === 'prefault' ||\n kind === 'catch' ||\n kind === 'readonly') &&\n def.innerType\n ) {\n current = def.innerType as z.ZodTypeAny;\n continue;\n }\n return current;\n }\n}\n\nfunction getObjectShape(schema: z.ZodTypeAny): Record<string, z.ZodTypeAny> | null {\n const schemaWithShape = schema as unknown as { shape?: unknown };\n if (schemaWithShape.shape && typeof schemaWithShape.shape === 'object') {\n return schemaWithShape.shape as Record<string, z.ZodTypeAny>;\n }\n\n const def = schema.def as unknown as Record<string, unknown> | undefined;\n const rawShape = def?.shape;\n if (typeof rawShape === 'function') {\n return rawShape() as Record<string, z.ZodTypeAny>;\n }\n if (rawShape && typeof rawShape === 'object') {\n return rawShape as Record<string, z.ZodTypeAny>;\n }\n return null;\n}\n\nfunction getLiteralValue(zodType: z.ZodTypeAny): string | undefined {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return undefined;\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'literal') return undefined;\n\n if (typeof def.value === 'string') {\n return def.value;\n }\n\n const values = def.values as unknown[] | undefined;\n if (values && typeof values[0] === 'string') {\n return values[0];\n }\n\n return undefined;\n}\n","/**\n * Country Document Schema.\n *\n * Defines the structure for country documents.\n * Countries store supported languages as ISO codes and may still contain\n * legacy references to language documents during migration.\n */\n\nimport { z } from 'zod';\n\n// Legacy language document reference kept for backwards compatibility.\nconst LanguageReferenceSchema = z.object({\n _type: z.literal('reference'),\n _ref: z.string().uuid('Language reference must be a valid UUID'),\n _schema: z.literal('language'),\n});\n\n/**\n * Country schema with validation rules.\n *\n * @example\n * {\n * code: 'us',\n * name: 'United States',\n * flag: '🇺🇸',\n * languages: ['en', 'es']\n * }\n *\n * @example\n * {\n * code: 'sa',\n * name: 'Saudi Arabia',\n * flag: '🇸🇦',\n * languages: ['ar', 'en']\n * }\n */\nexport const CountrySchema = z.object({\n /** 2-letter ISO 3166-1 alpha-2 country code */\n code: z.string().length(2, 'Country code must be 2 characters'),\n\n /** English name of the country */\n name: z.string().min(1, 'Country name required'),\n\n /** Flag emoji (optional but recommended) */\n flag: z.string().optional(),\n\n /**\n * List of supported languages (at least one required).\n * Supports either:\n * - Language codes (new format)\n * - Document references to languages (legacy format for backward compatibility)\n */\n languages: z\n .array(\n z.union([z.string().length(2, 'Language code must be 2 characters'), LanguageReferenceSchema])\n )\n .min(1, 'At least one language required'),\n});\n\nexport type Country = z.infer<typeof CountrySchema>;\n\nexport const COUNTRY_SCHEMA_NAME = 'country';\nexport const COUNTRY_DISPLAY_NAME = 'Country';\nexport const COUNTRY_TITLE_FIELD = 'name';\n\n/**\n * Create a default country object.\n */\nexport function createDefaultCountry(): Country {\n return {\n code: '',\n name: '',\n flag: '',\n languages: [],\n };\n}\n","/**\n * Language Document Schema.\n *\n * Defines the structure for language documents.\n */\n\nimport { z } from 'zod';\n\n/**\n * Language schema with validation rules.\n *\n * @example\n * {\n * code: 'en',\n * name: 'English',\n * nativeName: 'English'\n * }\n *\n * @example\n * {\n * code: 'ar',\n * name: 'Arabic',\n * nativeName: 'العربية'\n * }\n */\nexport const LanguageSchema = z.object({\n /** 2-letter ISO 639-1 language code */\n code: z.string().length(2, 'Language code must be 2 characters'),\n\n /** English name of the language */\n name: z.string().min(1, 'Language name required'),\n\n /** Name in the language itself (optional but recommended) */\n nativeName: z.string().optional(),\n});\n\n/** TypeScript type inferred from schema */\nexport type Language = z.infer<typeof LanguageSchema>;\n\n/** Schema name constant */\nexport const LANGUAGE_SCHEMA_NAME = 'language';\n\n/** Display name for UI */\nexport const LANGUAGE_DISPLAY_NAME = 'Language';\n\n/** Title field for list display */\nexport const LANGUAGE_TITLE_FIELD = 'name';\n\n/**\n * Create a default language object.\n */\nexport function createDefaultLanguage(): Language {\n return {\n code: '',\n name: '',\n nativeName: '',\n };\n}\n\n/**\n * Static list of all languages supported by the translation system.\n *\n * This is the authoritative source — both the language documents page and the\n * translation language picker render from this array. The Rust translation\n * service validates incoming language codes against the same set.\n */\nexport const SUPPORTED_LANGUAGES: Language[] = [\n { code: 'ar', name: 'Arabic', nativeName: 'العربية' },\n { code: 'zh', name: 'Chinese (Simplified)', nativeName: '中文(简体)' },\n { code: 'nl', name: 'Dutch', nativeName: 'Nederlands' },\n { code: 'en', name: 'English', nativeName: 'English' },\n { code: 'fr', name: 'French', nativeName: 'Français' },\n { code: 'de', name: 'German', nativeName: 'Deutsch' },\n { code: 'it', name: 'Italian', nativeName: 'Italiano' },\n { code: 'ja', name: 'Japanese', nativeName: '日本語' },\n { code: 'ko', name: 'Korean', nativeName: '한국어' },\n { code: 'pl', name: 'Polish', nativeName: 'Polski' },\n { code: 'pt', name: 'Portuguese', nativeName: 'Português' },\n { code: 'ru', name: 'Russian', nativeName: 'Русский' },\n { code: 'es', name: 'Spanish', nativeName: 'Español' },\n { code: 'tr', name: 'Turkish', nativeName: 'Türkçe' },\n];\n","/**\n * Unified Schema Registry\n *\n * Merges preset schemas (hardcoded in TypeScript) with custom schemas (stored as JSON in database).\n * Both types of schemas are served through the same API, making them indistinguishable to consumers.\n *\n * Custom schemas take precedence over presets with the same name.\n * Custom schemas are cached with a TTL and can be invalidated.\n */\n\nimport { type ZodObject, type ZodRawShape, z } from 'zod';\nimport type { TypedSupabaseClient } from '../db/types';\nimport { rehydrateSchema } from './rehydration';\nimport { createSchemaHash } from './schema-hash';\nimport type { CustomSchemaRow, FieldDefinition } from './schema-types';\n\n/** Source of a schema definition */\nexport type SchemaSource = 'preset' | 'custom';\n\ntype TitleCandidateFieldType = FieldDefinition['type'];\n\nconst titleCandidateFieldTypes = new Set<TitleCandidateFieldType>([\n 'string',\n 'enum',\n 'url',\n 'email',\n 'date',\n 'datetime',\n]);\n\nfunction inferTitleFieldFromZodSchema(schema: ZodObject<ZodRawShape>): string {\n const shape = schema.shape ?? {};\n const keys = Object.keys(shape);\n if (keys.includes('title')) return 'title';\n if (keys.includes('name')) return 'name';\n if (keys.includes('code')) return 'code';\n return keys[0] ?? 'title';\n}\n\nfunction resolveTitleFieldFromFields(options: {\n fields: FieldDefinition[];\n titleField?: string | null;\n routeSlugField?: string | null;\n}): string | undefined {\n const { fields, titleField, routeSlugField } = options;\n\n if (titleField) {\n return titleField;\n }\n\n const fieldMap = new Map(fields.map((f) => [f.name, f] as const));\n\n if (routeSlugField) {\n const slugField = fieldMap.get(routeSlugField);\n if (slugField && titleCandidateFieldTypes.has(slugField.type)) {\n return routeSlugField;\n }\n }\n\n for (const preferredName of ['title', 'name', 'code'] as const) {\n const preferred = fieldMap.get(preferredName);\n if (preferred && titleCandidateFieldTypes.has(preferred.type)) {\n return preferredName;\n }\n }\n\n const firstCandidate = fields.find((f) => titleCandidateFieldTypes.has(f.type));\n return firstCandidate?.name;\n}\n\n/** Unified schema configuration that works for both preset and custom schemas */\nexport interface UnifiedSchemaConfig {\n /** Database ID (only present for custom schemas) */\n id?: string;\n name: string;\n schema: ZodObject<ZodRawShape>;\n displayName: string;\n description?: string;\n titleField: string;\n /** Field name to use as URL routing slug. Value is auto-copied to content.code on document save. */\n routeSlugField?: string;\n icon?: string;\n source: SchemaSource;\n version?: number;\n /** ISO timestamp of last DB update (only present for custom schemas) */\n updatedAt?: string | null;\n /** Optional custom validation (typically for presets) */\n validateContent?: (content: unknown, supabase: TypedSupabaseClient) => Promise<void>;\n}\n\n/** Summary info for listing schemas (without full Zod schema) */\nexport interface SchemaSummary {\n /** Database ID (only present for custom schemas) */\n id?: string;\n name: string;\n displayName: string;\n description?: string;\n icon?: string;\n source: SchemaSource;\n version?: number;\n /** Field name used for URL routing - if not set, URL routing may not work */\n routeSlugField?: string;\n}\n\n// In-memory storage\nconst presetSchemas = new Map<string, UnifiedSchemaConfig>();\nconst customSchemaCacheByWebsite = new Map<string, Map<string, UnifiedSchemaConfig>>();\nconst customSchemasCacheTimeByWebsite = new Map<string, number>();\n\n/**\n * Optional hook called after the in-process cache is cleared.\n * Register this in deployment-aware entry points (e.g. Next.js server.ts)\n * to propagate invalidation across all instances via revalidateTag or similar.\n */\nlet onInvalidate: ((websiteId?: string) => void) | null = null;\n\n/**\n * Register a callback to be invoked whenever the schema cache is invalidated.\n * Intended for Next.js deployments: pass `revalidateTag` so invalidation\n * reaches all instances, not just the local process.\n *\n * @param fn - Receives the websiteId that was invalidated (undefined = all)\n */\nexport function setSchemaInvalidationHook(fn: (websiteId?: string) => void): void {\n onInvalidate = fn;\n}\n\nfunction cacheKeyForWebsite(websiteId?: string): string {\n return websiteId ?? '__all__';\n}\n\n/** Cache TTL in milliseconds (30 seconds) */\nconst CACHE_TTL_MS = 30_000;\n\n/**\n * Registers a preset schema. Called at application startup.\n *\n * @param name - Unique schema identifier (e.g., 'country', 'language')\n * @param config - Schema configuration without name and source\n * @throws If schema with name already registered\n */\nexport function registerPresetSchema(\n name: string,\n config: Omit<UnifiedSchemaConfig, 'name' | 'source' | 'titleField'> & { titleField?: string }\n): void {\n if (presetSchemas.has(name)) {\n throw new Error(`Preset schema \"${name}\" is already registered`);\n }\n\n presetSchemas.set(name, {\n ...config,\n name,\n titleField: config.titleField ?? inferTitleFieldFromZodSchema(config.schema),\n source: 'preset',\n });\n}\n\n/**\n * Gets a schema by name (preset or custom).\n * Cached custom schemas are checked first, then presets.\n * If cache is stale/missing, custom schemas are refreshed to preserve override behavior.\n *\n * @param name - Schema name to look up\n * @param supabase - Database client for loading custom schemas\n * @returns Schema configuration or null if not found\n */\nexport async function getSchema(\n name: string,\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<UnifiedSchemaConfig | null> {\n const key = cacheKeyForWebsite(websiteId);\n const presetSchema = presetSchemas.get(name) ?? null;\n\n // Fast path: use current cache first (custom overrides presets).\n const cachedCustomSchema = customSchemaCacheByWebsite.get(key)?.get(name);\n if (cachedCustomSchema) {\n return cachedCustomSchema;\n }\n\n // If preset exists and cache is fresh with no custom override, avoid DB roundtrip.\n const cacheTime = customSchemasCacheTimeByWebsite.get(key) ?? null;\n const cacheIsFresh = cacheTime !== null && Date.now() - cacheTime < CACHE_TTL_MS;\n if (presetSchema && cacheIsFresh) {\n return presetSchema;\n }\n\n // Load/refresh custom schemas if needed.\n await loadCustomSchemas(supabase, websiteId);\n const refreshedCustomSchema = customSchemaCacheByWebsite.get(key)?.get(name);\n if (refreshedCustomSchema) {\n return refreshedCustomSchema;\n }\n\n return presetSchema;\n}\n\n/**\n * Gets all registered schemas (presets + active custom).\n *\n * @param supabase - Database client for loading custom schemas\n * @returns Array of all available schema configurations\n */\nexport async function getAllSchemas(\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<UnifiedSchemaConfig[]> {\n await loadCustomSchemas(supabase, websiteId);\n\n const scopedCache = customSchemaCacheByWebsite.get(cacheKeyForWebsite(websiteId));\n const merged = new Map<string, UnifiedSchemaConfig>();\n\n for (const preset of presetSchemas.values()) {\n merged.set(preset.name, preset);\n }\n\n for (const custom of scopedCache?.values() ?? []) {\n merged.set(custom.name, custom);\n }\n\n return [...merged.values()];\n}\n\n/**\n * Gets summary info for all schemas (without full Zod schemas).\n * Useful for sidebar/listing where full validation isn't needed.\n */\nexport async function getAllSchemaSummaries(\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<SchemaSummary[]> {\n const schemas = await getAllSchemas(supabase, websiteId);\n\n return schemas.map((s) => ({\n id: s.id,\n name: s.name,\n displayName: s.displayName,\n description: s.description,\n icon: s.icon,\n source: s.source,\n version: s.version,\n routeSlugField: s.routeSlugField,\n }));\n}\n\n/**\n * Loads custom schemas from database into cache.\n * Uses TTL-based caching to avoid excessive database queries.\n *\n * @param supabase - Database client\n * @param force - If true, bypasses cache TTL\n */\nasync function loadCustomSchemas(\n supabase: TypedSupabaseClient,\n websiteId?: string,\n force = false\n): Promise<void> {\n const now = Date.now();\n const key = cacheKeyForWebsite(websiteId);\n const cacheTime = customSchemasCacheTimeByWebsite.get(key) ?? null;\n\n // Use cache if valid and not forced\n if (!force && cacheTime && now - cacheTime < CACHE_TTL_MS) {\n return;\n }\n\n let data: CustomSchemaRow[] | null = null;\n let error: unknown = null;\n\n try {\n let query = supabase\n .from('custom_schemas')\n .select(\n 'id, name, display_name, description, fields, title_field, route_slug_field, icon, version, state, updated_at'\n )\n .eq('state', 'active');\n if (websiteId) {\n query = query.eq('website_id', websiteId);\n }\n const result = (await query) as { data: CustomSchemaRow[] | null; error: unknown };\n data = result.data;\n error = result.error;\n } catch (err) {\n console.error('Failed to load custom schemas:', err);\n // Back off repeated attempts for this scope when loading fails.\n customSchemasCacheTimeByWebsite.set(key, now);\n // Keep stale cache on error rather than clearing\n return;\n }\n\n if (error) {\n console.error('Failed to load custom schemas:', error);\n // Back off repeated attempts for this scope when loading fails.\n customSchemasCacheTimeByWebsite.set(key, now);\n // Keep stale cache on error rather than clearing\n return;\n }\n\n // Rebuild cache\n const scopedCache = new Map<string, UnifiedSchemaConfig>();\n\n for (const row of data ?? []) {\n try {\n const fields = row.fields as FieldDefinition[];\n const zodSchema = rehydrateSchema(fields);\n const resolvedTitleField = resolveTitleFieldFromFields({\n fields,\n titleField: row.title_field ?? undefined,\n routeSlugField: row.route_slug_field ?? undefined,\n });\n\n const hasExistingTitleField = fields.some((f) => f.name === 'title');\n const schemaWithResolvedTitle =\n resolvedTitleField === undefined && !hasExistingTitleField\n ? zodSchema.extend({ title: z.string().optional() })\n : zodSchema;\n\n const finalTitleField =\n resolvedTitleField ?? (hasExistingTitleField ? 'title' : (fields[0]?.name ?? 'title'));\n\n scopedCache.set(row.name, {\n id: row.id,\n name: row.name,\n schema: schemaWithResolvedTitle,\n displayName: row.display_name,\n description: row.description ?? undefined,\n titleField: finalTitleField,\n routeSlugField: row.route_slug_field ?? undefined,\n icon: row.icon ?? undefined,\n source: 'custom',\n version: row.version,\n updatedAt: row.updated_at ?? null,\n });\n } catch (err) {\n // Log but don't fail - skip invalid schemas\n console.error(`Failed to rehydrate schema \"${row.name}\":`, err);\n }\n }\n\n customSchemaCacheByWebsite.set(key, scopedCache);\n customSchemasCacheTimeByWebsite.set(key, now);\n}\n\n/**\n * Invalidates the custom schema cache.\n * Call this after creating, updating, or deleting custom schemas.\n */\nexport function invalidateCustomSchemaCache(websiteId?: string): void {\n if (websiteId) {\n const key = cacheKeyForWebsite(websiteId);\n customSchemasCacheTimeByWebsite.delete(key);\n customSchemaCacheByWebsite.delete(key);\n } else {\n customSchemasCacheTimeByWebsite.clear();\n customSchemaCacheByWebsite.clear();\n }\n\n onInvalidate?.(websiteId);\n}\n\n/**\n * Forces a reload of custom schemas from database.\n */\nexport async function refreshCustomSchemas(supabase: TypedSupabaseClient): Promise<void> {\n await loadCustomSchemas(supabase, undefined, true);\n}\n\n/**\n * Checks if a schema name is a preset schema.\n */\nexport function isPresetSchema(name: string): boolean {\n return presetSchemas.has(name);\n}\n\n/**\n * Gets all preset schema names.\n */\nexport function getPresetSchemaNames(): string[] {\n return [...presetSchemas.keys()];\n}\n\n/**\n * Clears all registrations. FOR TESTING ONLY.\n */\nexport function clearUnifiedRegistry(): void {\n presetSchemas.clear();\n customSchemaCacheByWebsite.clear();\n customSchemasCacheTimeByWebsite.clear();\n}\n\n/**\n * Creates a hash for a custom schema from its fields.\n * Used for tracking schema versions in documents.\n */\nexport function createCustomSchemaHash(fields: FieldDefinition[]): string {\n const zodSchema = rehydrateSchema(fields);\n return createSchemaHash(zodSchema);\n}\n","/**\n * Zod Schema Rehydration\n *\n * Converts JSON field definitions (stored in database) into runtime Zod schemas.\n * This enables custom schemas to be validated identically to preset schemas.\n *\n * @example\n * ```typescript\n * const fields: FieldDefinition[] = [\n * { name: 'title', type: 'string', required: true, constraints: { minLength: 1 } },\n * { name: 'price', type: 'number', required: true, constraints: { min: 0 } },\n * ];\n * const schema = rehydrateSchema(fields);\n * // Equivalent to: z.object({ title: z.string().min(1), price: z.number().min(0) })\n * ```\n */\n\nimport { type ZodObject, type ZodRawShape, type ZodType, z } from 'zod';\nimport { ImageReferenceSchema } from '../fields/complex/media';\nimport { richtext as createRichtextField } from '../fields/complex/richtext';\nimport { validateSafeRegex } from '../utils/safe-regex';\nimport type { FieldConstraints, FieldDefinition, FieldType } from './schema-types';\n\n/** Error thrown when field definition cannot be rehydrated */\nexport class RehydrationError extends Error {\n constructor(\n message: string,\n public readonly fieldName?: string,\n public readonly fieldType?: FieldType\n ) {\n super(message);\n this.name = 'RehydrationError';\n }\n}\n\n/**\n * Rehydrates a single field definition into a Zod schema\n */\nexport function rehydrateField(field: FieldDefinition): ZodType {\n try {\n let schema = createBaseSchema(field.type, field.constraints);\n\n if (!field.required) {\n schema = schema.optional();\n }\n\n return schema;\n } catch (err) {\n throw new RehydrationError(\n `Failed to rehydrate field \"${field.name}\": ${err instanceof Error ? err.message : 'Unknown error'}`,\n field.name,\n field.type\n );\n }\n}\n\n/**\n * Creates the base Zod schema for a given field type\n */\nfunction createBaseSchema(type: FieldType, constraints?: FieldConstraints): ZodType {\n switch (type) {\n case 'string':\n return applyStringConstraints(z.string(), constraints);\n\n case 'richtext':\n return createRichtextField({ label: 'Rich Text', required: true });\n\n case 'number':\n return applyNumberConstraints(z.number(), constraints);\n\n case 'boolean':\n return z.boolean();\n\n case 'image':\n return ImageReferenceSchema;\n\n case 'date':\n return z.iso.date('Invalid date format. Expected YYYY-MM-DD');\n\n case 'datetime':\n return z.iso.datetime({\n offset: true,\n message: 'Invalid datetime format. Expected ISO 8601',\n });\n\n case 'url':\n return applyStringConstraints(z.string(), constraints).pipe(z.url('Invalid URL format'));\n\n case 'email':\n return applyStringConstraints(z.string(), constraints).pipe(z.email('Invalid email format'));\n\n case 'enum': {\n const values = constraints?.enumValues;\n if (!values || values.length === 0) {\n throw new Error('Enum field requires at least one enumValues in constraints');\n }\n return z.enum(values as [string, ...string[]]);\n }\n\n case 'reference':\n // Reference fields store inline objects (the referenced schema's field values)\n return z.record(z.string(), z.unknown());\n\n case 'array': {\n const itemType = constraints?.arrayItemType ?? 'string';\n const itemSchema =\n itemType === 'reference'\n ? z.record(z.string(), z.unknown())\n : createPrimitiveSchema(itemType);\n return applyArrayConstraints(z.array(itemSchema), constraints);\n }\n\n default:\n throw new Error(`Unknown field type: ${type}`);\n }\n}\n\n/**\n * Creates a Zod schema for primitive array item types\n */\nfunction createPrimitiveSchema(type: 'string' | 'number' | 'boolean'): ZodType {\n switch (type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'boolean':\n return z.boolean();\n default:\n throw new Error(`Unsupported array item type: ${type}`);\n }\n}\n\n/**\n * Applies string-specific constraints to a Zod string schema\n */\nfunction applyStringConstraints(schema: z.ZodString, constraints?: FieldConstraints): z.ZodString {\n if (!constraints) return schema;\n\n // Validate minLength <= maxLength when both are set\n if (\n constraints.minLength !== undefined &&\n constraints.maxLength !== undefined &&\n constraints.minLength > constraints.maxLength\n ) {\n throw new Error(\n `Invalid string constraints: minLength (${constraints.minLength}) cannot be greater than maxLength (${constraints.maxLength})`\n );\n }\n\n let result = schema;\n\n if (constraints.minLength !== undefined) {\n result = result.min(\n constraints.minLength,\n `Must be at least ${constraints.minLength} characters`\n );\n }\n if (constraints.maxLength !== undefined) {\n result = result.max(\n constraints.maxLength,\n `Must be at most ${constraints.maxLength} characters`\n );\n }\n if (constraints.pattern) {\n // Validate pattern is safe (prevents ReDoS attacks)\n const safetyError = validateSafeRegex(constraints.pattern);\n if (safetyError) {\n throw new Error(safetyError);\n }\n try {\n result = result.regex(new RegExp(constraints.pattern), 'Invalid format');\n } catch {\n throw new Error(`Invalid regex pattern: ${constraints.pattern}`);\n }\n }\n\n return result;\n}\n\n/**\n * Applies number-specific constraints to a Zod number schema\n */\nfunction applyNumberConstraints(schema: z.ZodNumber, constraints?: FieldConstraints): z.ZodNumber {\n if (!constraints) return schema;\n\n // Validate min <= max when both are set\n if (\n constraints.min !== undefined &&\n constraints.max !== undefined &&\n constraints.min > constraints.max\n ) {\n throw new Error(\n `Invalid number constraints: min (${constraints.min}) cannot be greater than max (${constraints.max})`\n );\n }\n\n let result = schema;\n\n if (constraints.min !== undefined) {\n result = result.min(constraints.min, `Must be at least ${constraints.min}`);\n }\n if (constraints.max !== undefined) {\n result = result.max(constraints.max, `Must be at most ${constraints.max}`);\n }\n if (constraints.integer) {\n result = result.int('Must be an integer');\n }\n\n return result;\n}\n\n/**\n * Applies array-specific constraints to a Zod array schema\n */\nfunction applyArrayConstraints(\n schema: z.ZodArray<ZodType>,\n constraints?: FieldConstraints\n): z.ZodArray<ZodType> {\n if (!constraints) return schema;\n\n // Validate minItems <= maxItems when both are set\n if (\n constraints.minItems !== undefined &&\n constraints.maxItems !== undefined &&\n constraints.minItems > constraints.maxItems\n ) {\n throw new Error(\n `Invalid array constraints: minItems (${constraints.minItems}) cannot be greater than maxItems (${constraints.maxItems})`\n );\n }\n\n let result = schema;\n\n if (constraints.minItems !== undefined) {\n result = result.min(constraints.minItems, `Must have at least ${constraints.minItems} items`);\n }\n if (constraints.maxItems !== undefined) {\n result = result.max(constraints.maxItems, `Must have at most ${constraints.maxItems} items`);\n }\n\n return result;\n}\n\n/**\n * Rehydrates a complete custom schema from field definitions into a Zod object schema\n *\n * @param fields - Array of field definitions from database\n * @returns Zod object schema that validates documents\n * @throws RehydrationError if any field cannot be rehydrated\n *\n * @example\n * ```typescript\n * const fields = [\n * { name: 'model', type: 'string', required: true },\n * { name: 'price', type: 'number', required: false },\n * ];\n * const schema = rehydrateSchema(fields);\n * schema.parse({ model: 'MacBook Pro' }); // Valid\n * schema.parse({ model: 'MacBook Pro', price: 1999 }); // Valid\n * schema.parse({ price: 1999 }); // Throws - model is required\n * ```\n */\nexport function rehydrateSchema(fields: FieldDefinition[]): ZodObject<ZodRawShape> {\n if (!Array.isArray(fields) || fields.length === 0) {\n throw new RehydrationError('Schema must have at least one field');\n }\n\n const shape: Record<string, ZodType> = {};\n const seenNames = new Set<string>();\n\n for (const field of fields) {\n // Validate field name uniqueness\n if (seenNames.has(field.name)) {\n throw new RehydrationError(`Duplicate field name: \"${field.name}\"`);\n }\n seenNames.add(field.name);\n\n // Validate field name format\n if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(field.name)) {\n throw new RehydrationError(\n `Invalid field name \"${field.name}\": must start with a letter and contain only alphanumeric characters and underscores`,\n field.name\n );\n }\n\n shape[field.name] = rehydrateField(field);\n }\n\n return z.object(shape);\n}\n\n/**\n * Validates that field definitions can be rehydrated without actually building the schema.\n * Useful for pre-validation before database insertion.\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateFieldDefinitions(fields: FieldDefinition[]): string | null {\n try {\n rehydrateSchema(fields);\n return null;\n } catch (err) {\n return err instanceof Error ? err.message : 'Unknown validation error';\n }\n}\n","/**\n * Image and file field factories.\n *\n * The image() factory creates an ImageReference schema that:\n * - References an ImageAsset by ID\n * - Stores context-specific alt text (required for accessibility)\n * - Supports optional hotspot (focal point) and crop settings\n */\n\nimport { z } from 'zod';\n\nimport type { FieldMeta } from '../../types';\nimport {\n DimensionSchema,\n FileSizeSchema,\n MAX_DIMENSION,\n MAX_FILE_SIZE,\n MIN_DIMENSION,\n MimeTypeSchema,\n} from '../../validation/image';\n\n// =============================================================================\n// ImageAsset Schema (Public API type)\n// =============================================================================\n\n/**\n * Public API schema for image assets.\n *\n * This is the camelCase API representation. The database uses snake_case\n * (ImageAssetRow in db/image-asset-types.ts). Conversion between formats\n * should happen at the API boundary.\n *\n * Reuses validation schemas from validation/image.ts to ensure consistency.\n */\nexport const ImageAssetSchema = z.object({\n /** UUID primary key */\n id: z.uuid(),\n /** R2/S3 storage URL for the original file */\n url: z.url(),\n /** Image width in pixels */\n width: DimensionSchema,\n /** Image height in pixels */\n height: DimensionSchema,\n /** Original filename from upload */\n originalFilename: z.string().min(1).max(255),\n /** MIME type (only web-safe formats allowed) */\n mimeType: MimeTypeSchema,\n /** File size in bytes */\n fileSize: FileSizeSchema,\n /** Base64-encoded tiny preview for blur-up loading */\n lqip: z.string().optional(),\n});\n\nexport type ImageAsset = z.infer<typeof ImageAssetSchema>;\n\n// =============================================================================\n// ImageReference Schema (Asset-reference model)\n// =============================================================================\n\n/**\n * Hotspot defines the focal point of an image.\n * Coordinates are fractions (0-1) from top-left.\n */\nexport const HotspotSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n});\n\nexport type Hotspot = z.infer<typeof HotspotSchema>;\n\n/**\n * Crop defines the region to extract from the image.\n * - x, y: Top-left coordinate of the crop region in pixels\n * - width, height: Size of the crop region in pixels\n * All values are positive integers representing pixel coordinates/dimensions.\n */\nexport const CropSchema = z.object({\n /** X coordinate of top-left corner in pixels */\n x: z.number().int().nonnegative(),\n /** Y coordinate of top-left corner in pixels */\n y: z.number().int().nonnegative(),\n /** Width of crop region in pixels (must be > 0) */\n width: z.number().int().positive(),\n /** Height of crop region in pixels (must be > 0) */\n height: z.number().int().positive(),\n});\n\nexport type Crop = z.infer<typeof CropSchema>;\n\n/**\n * ImageReference is what blocks store.\n * It points to an ImageAsset and adds context-specific metadata.\n */\nexport const ImageReferenceSchema = z.object({\n // Alt text is REQUIRED for accessibility\n alt: z.string().min(1, 'Alt text is required for accessibility'),\n\n // Optional metadata\n caption: z.string().max(500).optional(),\n attribution: z.string().max(255).optional(),\n\n // Reference to the ImageAsset with stored transformation\n _asset: z.object({\n id: z.uuid(),\n transformation: z.string().nullable().optional(),\n }),\n});\n\nexport type ImageReference = z.infer<typeof ImageReferenceSchema>;\n\n// =============================================================================\n// Image Field Factory\n// =============================================================================\n\nexport interface ImageFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n accept?: string;\n maxSize?: number;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n aspectRatio?: number;\n}\n\n/**\n * Create an image field with metadata.\n *\n * @example\n * const featuredImage = image({\n * label: 'Featured Image',\n * required: true,\n * accept: 'image/jpeg, image/png',\n * maxSize: 5 * 1024 * 1024,\n * });\n *\n * // Type of the value:\n * // {\n * // alt: string;\n * // caption?: string;\n * // attribution?: string;\n * // _asset: { id: string; transformation?: string | null };\n * // }\n */\nexport function image(options: ImageFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'image-uploader',\n required: options.required,\n description: options.description,\n options: {\n accept: options.accept ?? 'image/jpeg, image/png, image/webp',\n maxSize: options.maxSize ?? MAX_FILE_SIZE, // 10MB default\n minWidth: options.minWidth ?? MIN_DIMENSION,\n minHeight: options.minHeight ?? MIN_DIMENSION,\n maxWidth: options.maxWidth ?? MAX_DIMENSION,\n maxHeight: options.maxHeight ?? MAX_DIMENSION,\n aspectRatio: options.aspectRatio,\n },\n };\n\n // Use the new ImageReferenceSchema instead of URL-only\n const result = options.required ? ImageReferenceSchema : ImageReferenceSchema.nullish();\n\n return result.meta(meta);\n}\n\n// =============================================================================\n// File Field\n// =============================================================================\n\nexport interface FileFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n accept?: string;\n maxSize?: number;\n}\n\nconst fileSchema = z.object({\n url: z.url(),\n name: z.string(),\n size: z.number().int().positive(),\n type: z.string(),\n});\n\n/**\n * Create a file field with metadata.\n */\nexport function file(options: FileFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'file-uploader',\n required: options.required,\n description: options.description,\n options: {\n accept: options.accept ?? '*/*',\n maxSize: options.maxSize,\n },\n };\n\n const result = options.required ? fileSchema : fileSchema.nullish();\n return result.meta(meta);\n}\n","/**\n * Image Validation Utilities\n *\n * Provides validation for:\n * - File type (MIME type checking)\n * - File size (configurable limits)\n * - Image dimensions (width/height constraints)\n */\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp'] as const;\nexport type ImageMimeType = (typeof ALLOWED_MIME_TYPES)[number];\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\nexport const MIN_FILE_SIZE = 1024; // 1KB (avoid empty/corrupt files)\n\nexport const MAX_DIMENSION = 8192; // 8K resolution\nexport const MIN_DIMENSION = 10; // Minimum useful size\n\n// =============================================================================\n// Zod Schemas\n// =============================================================================\n\nexport const MimeTypeSchema = z.enum(ALLOWED_MIME_TYPES);\n\nexport const FileSizeSchema = z\n .number()\n .int()\n .min(MIN_FILE_SIZE, `File too small. Minimum: ${MIN_FILE_SIZE} bytes`)\n .max(MAX_FILE_SIZE, `File too large. Maximum: ${MAX_FILE_SIZE / 1024 / 1024}MB`);\n\nexport const DimensionSchema = z\n .number()\n .int()\n .min(MIN_DIMENSION, `Dimension too small. Minimum: ${MIN_DIMENSION}px`)\n .max(MAX_DIMENSION, `Dimension too large. Maximum: ${MAX_DIMENSION}px`);\n\n/**\n * Schema for upload request validation.\n */\nexport const UploadRequestSchema = z.object({\n filename: z\n .string()\n .min(1, 'Filename is required')\n .max(255, 'Filename too long')\n .regex(/^[^<>:\"/\\\\|?*]+$/, 'Filename contains invalid characters'),\n mimeType: MimeTypeSchema,\n fileSize: FileSizeSchema,\n});\n\nexport type UploadRequest = z.infer<typeof UploadRequestSchema>;\n\n/**\n * Schema for confirming upload with dimensions.\n * assetId is optional - if not provided, the server will generate a UUID.\n */\nexport const ConfirmUploadSchema = z.object({\n assetId: z.uuid().optional(),\n width: DimensionSchema,\n height: DimensionSchema,\n});\n\nexport type ConfirmUpload = z.infer<typeof ConfirmUploadSchema>;\n\n// =============================================================================\n// Validation Functions\n// =============================================================================\n\nexport interface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Validate file type by MIME type.\n */\nexport function validateMimeType(mimeType: string): ValidationResult {\n const result = MimeTypeSchema.safeParse(mimeType);\n if (result.success) {\n return { valid: true };\n }\n return {\n valid: false,\n error: `File type not supported. Use JPEG, PNG, or WebP.`,\n };\n}\n\n/**\n * Validate file size.\n */\nexport function validateFileSize(size: number): ValidationResult {\n if (size < MIN_FILE_SIZE) {\n return {\n valid: false,\n error: `File appears to be empty or corrupt.`,\n };\n }\n if (size > MAX_FILE_SIZE) {\n const sizeMB = (size / 1024 / 1024).toFixed(1);\n return {\n valid: false,\n error: `File too large (${sizeMB}MB). Maximum: 10 MB.`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Validate image dimensions.\n */\nexport function validateDimensions(width: number, height: number): ValidationResult {\n if (width < MIN_DIMENSION || height < MIN_DIMENSION) {\n return {\n valid: false,\n error: `Image too small. Minimum: ${MIN_DIMENSION}x${MIN_DIMENSION}px.`,\n };\n }\n if (width > MAX_DIMENSION || height > MAX_DIMENSION) {\n return {\n valid: false,\n error: `Image too large. Maximum: ${MAX_DIMENSION}x${MAX_DIMENSION}px.`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Validate complete upload request.\n */\nexport function validateUploadRequest(\n request: unknown\n): { valid: true; data: UploadRequest } | { valid: false; error: string } {\n const result = UploadRequestSchema.safeParse(request);\n if (result.success) {\n return { valid: true, data: result.data };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error: firstIssue?.message ?? 'Invalid upload request',\n };\n}\n\n// =============================================================================\n// File Extension Utilities\n// =============================================================================\n\nconst MIME_TO_EXT: Record<ImageMimeType, string> = {\n 'image/jpeg': 'jpg',\n 'image/png': 'png',\n 'image/webp': 'webp',\n};\n\nconst EXT_TO_MIME: Record<string, ImageMimeType> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n webp: 'image/webp',\n};\n\n/**\n * Get file extension from MIME type.\n */\nexport function getExtensionFromMime(mimeType: ImageMimeType | string): string {\n return MIME_TO_EXT[mimeType as ImageMimeType] ?? 'bin';\n}\n\n/**\n * Get MIME type from file extension.\n */\nexport function getMimeFromExtension(ext: string): ImageMimeType | undefined {\n return EXT_TO_MIME[ext.toLowerCase()];\n}\n\n/**\n * Extract extension from filename.\n */\nexport function getExtensionFromFilename(filename: string): string {\n const parts = filename.split('.');\n return parts.pop()?.toLowerCase?.() ?? '';\n}\n\n/**\n * Sanitize filename for storage.\n * Removes special characters, preserves extension.\n */\nexport function sanitizeFilename(filename: string): string {\n // Get extension\n const ext = getExtensionFromFilename(filename);\n\n // Get base name without extension\n const base = filename.slice(0, filename.length - ext.length - 1);\n\n // Sanitize: lowercase, replace spaces and special chars\n const sanitized = base\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 50); // Limit length\n\n return ext ? `${sanitized}.${ext}` : sanitized;\n}\n","/**\n * Rich text field factory.\n *\n * Accepts markdown strings for Lexical-based editors or Portable Text arrays.\n */\n\nimport { z } from 'zod';\nimport type { FieldMeta } from '../../types';\n\nexport type FormattingOption =\n | 'bold'\n | 'italic'\n | 'underline'\n | 'strikethrough'\n | 'link'\n | 'heading'\n | 'list'\n | 'blockquote'\n | 'code'\n | 'image';\n\nexport interface RichtextFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n formatting?: FormattingOption[];\n}\n\n// Portable Text node types\nconst textNodeSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n marks: z.array(z.string()).optional(),\n});\n\nconst blockSchema: z.ZodType<unknown> = z.lazy(() =>\n z.object({\n type: z.string(),\n children: z.array(z.union([textNodeSchema, blockSchema])).optional(),\n marks: z.array(z.string()).optional(),\n level: z.number().optional(),\n url: z.string().optional(),\n })\n);\n\nconst richtextSchema = z.union([z.array(blockSchema), z.string()]);\n\n/**\n * Create a rich text field with metadata.\n *\n * @example\n * const body = richtext({\n * label: 'Content',\n * required: true,\n * formatting: ['bold', 'italic', 'link', 'heading', 'list'],\n * });\n */\nexport function richtext(options: RichtextFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'richtext',\n required: options.required,\n description: options.description,\n options: {\n formatting: options.formatting ?? ['bold', 'italic', 'link', 'heading', 'list'],\n format: 'markdown',\n },\n };\n\n const result = options.required ? richtextSchema : richtextSchema.optional();\n return result.meta(meta);\n}\n","/**\n * Safe regex validation utilities.\n *\n * Prevents ReDoS (Regular Expression Denial of Service) attacks by\n * detecting potentially dangerous regex patterns.\n */\n\nimport safeRegex from 'safe-regex2';\n\n/**\n * Validates that a regex pattern is safe to use.\n * Uses safe-regex2 library to detect ReDoS vulnerabilities.\n *\n * @param pattern - The regex pattern to validate\n * @returns null if safe, error message if potentially dangerous\n */\nexport function validateSafeRegex(pattern: string): string | null {\n // Limit pattern length to prevent extremely long patterns\n if (pattern.length > 500) {\n return 'Regex pattern is too long (max 500 characters)';\n }\n\n // Use safe-regex2 to detect ReDoS vulnerabilities\n if (!safeRegex(pattern)) {\n return 'Regex pattern is potentially unsafe (ReDoS risk)';\n }\n\n // Try to compile the regex to ensure it's valid\n try {\n new RegExp(pattern);\n } catch (err) {\n return `Invalid regex: ${err instanceof Error ? err.message : 'Unknown'}`;\n }\n\n return null;\n}\n","/**\n * Schema hashing utility for document versioning.\n *\n * Creates a deterministic hash of a Zod schema's shape.\n * Used to detect when documents need migration after schema changes.\n */\n\nimport hash from 'object-hash';\nimport type { ZodObject, ZodRawShape, ZodTypeAny } from 'zod';\n\n/**\n * Unwraps optional, default, and nullable wrappers to get the inner type.\n */\nfunction unwrapZodType(zodType: ZodTypeAny): ZodTypeAny {\n const current = zodType;\n const def = current._def;\n\n // Unwrap optional/nullable/default wrappers\n if ('innerType' in def && def.innerType) {\n return unwrapZodType(def.innerType as ZodTypeAny);\n }\n\n return current;\n}\n\n/**\n * Gets the type name from a Zod type, unwrapping wrappers first.\n * In Zod v4, types are stored in _def.type (not typeName).\n */\nfunction getZodTypeName(zodType: ZodTypeAny): string {\n const unwrapped = unwrapZodType(zodType);\n const def = unwrapped._def;\n\n if (!def) return 'unknown';\n\n // Zod v4 uses _def.type for primitive types\n if ('type' in def && typeof def.type === 'string') {\n return def.type as string;\n }\n\n // Fallback: check for typeName (older Zod versions or complex types)\n if ('typeName' in def) {\n return def.typeName as string;\n }\n\n return 'unknown';\n}\n\n/**\n * Creates a deterministic hash of a Zod schema's shape.\n *\n * Uses object-hash library for canonical key ordering, ensuring\n * the same hash is produced regardless of property definition order.\n *\n * @param schema - A Zod object schema\n * @returns MD5 hash string of the schema shape\n */\nexport function createSchemaHash(schema: ZodObject<ZodRawShape>): string {\n const shape = schema.shape;\n\n // Create a serializable representation of the schema\n const schemaDefinition = Object.entries(shape).reduce(\n (acc, [key, zodType]) => {\n const typeName = getZodTypeName(zodType as ZodTypeAny);\n const unwrapped = unwrapZodType(zodType as ZodTypeAny);\n const unwrappedDef = unwrapped._def as unknown as Record<string, unknown>;\n\n // Check if optional (method exists on ZodTypeAny in Zod v4)\n const isOptional =\n 'isOptional' in zodType && typeof zodType.isOptional === 'function'\n ? zodType.isOptional()\n : false;\n\n acc[key] = {\n type: typeName,\n optional: isOptional,\n // Include nested shape for objects\n ...(typeName === 'object' &&\n 'shape' in unwrappedDef &&\n typeof unwrappedDef.shape === 'function' && {\n shape: Object.keys((unwrappedDef.shape as () => Record<string, unknown>)()),\n }),\n };\n return acc;\n },\n {} as Record<string, unknown>\n );\n\n return hash(schemaDefinition, {\n algorithm: 'md5',\n respectType: false,\n unorderedArrays: false,\n });\n}\n","/**\n * Country schema-specific validation.\n *\n * Validates that language codes exist in the database.\n */\n\nimport { TRPCError } from '@trpc/server';\nimport type { ReferenceValue } from '../../db/document-types';\nimport { isReference } from '../../db/document-types';\nimport type { TypedSupabaseClient } from '../../db/types';\n\n/**\n * Validate country content, specifically checking that language codes exist.\n *\n * @param content - Validated country content\n * @param supabase - Supabase client for database queries\n * @throws {TRPCError} If validation fails\n */\nexport async function validateCountryContent(\n content: unknown,\n supabase: TypedSupabaseClient\n): Promise<void> {\n const countryContent = content as {\n languages?: Array<string | ReferenceValue>;\n };\n const languages = Array.isArray(countryContent.languages) ? countryContent.languages : [];\n\n const languageCodes = languages.filter((lang): lang is string => typeof lang === 'string');\n const languageReferences = languages.filter(isReference);\n\n // Validate legacy reference format points to language schema\n const invalidReferences = languageReferences.filter((ref) => ref._schema !== 'language');\n if (invalidReferences.length > 0) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Language references must target the language schema',\n });\n }\n\n // Only perform database check when using code-based languages\n if (languageCodes.length > 0) {\n const { data: allLanguages, error: langError } = await supabase\n .from('documents')\n .select('content')\n .eq('schema_name', 'language');\n\n if (langError) {\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to validate language codes',\n cause: langError,\n });\n }\n\n const existingCodes = new Set(\n (allLanguages || [])\n .map((lang) => {\n const langContent = lang.content as { code?: string };\n return langContent?.code;\n })\n .filter((code): code is string => typeof code === 'string' && code.length > 0)\n );\n\n const missingCodes = languageCodes.filter((code) => !existingCodes.has(code));\n\n if (missingCodes.length > 0) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Language codes not found: ${missingCodes.join(', ')}. Please create language documents with these codes first.`,\n });\n }\n }\n}\n","/**\n * Field Definitions JSON Parser & Validator\n *\n * Accepts three JSON formats:\n *\n * 1. Sample data — { schemaName: { fieldName: exampleValue, ... }, ... }\n * Types are inferred from the example values. camelCase keys are\n * converted to snake_case. Arrays of objects create sub-schemas\n * automatically. Arrays of objects may nest up to MAX_SAMPLE_DEPTH levels deep.\n *\n * 2. FieldDefinition array — [ { name, type, required, ... }, ... ]\n * Single schema, exact FieldDefinition[] structure.\n *\n * 3. Multi-schema FieldDefinition — { schemaName: [ { name, type, required }, ... ], ... }\n * Multiple schemas in the explicit FieldDefinition[] format.\n *\n * Format is detected automatically from the structure.\n */\n\nimport { z } from 'zod';\nimport type { FieldDefinition } from './schema-types';\n\n// ---------------------------------------------------------------------------\n// FieldDefinition Zod schema (for formats 2 & 3)\n// ---------------------------------------------------------------------------\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/;\n\nconst fieldConstraintsSchema = z.object({\n minLength: z.number().int().min(0).optional(),\n maxLength: z.number().int().min(0).optional(),\n pattern: z.string().max(500).optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n integer: z.boolean().optional(),\n enumValues: z.array(z.string()).optional(),\n arrayItemType: z.enum(['string', 'number', 'boolean', 'reference']).optional(),\n minItems: z.number().int().min(0).optional(),\n maxItems: z.number().int().min(0).optional(),\n refSchema: z.string().regex(SNAKE_CASE, 'refSchema must be snake_case').optional(),\n});\n\nconst fieldDefinitionSchema = z.object({\n name: z\n .string()\n .regex(SNAKE_CASE, 'must be snake_case (lowercase letters, digits, underscores only)'),\n type: z.enum([\n 'string',\n 'richtext',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'url',\n 'email',\n 'enum',\n 'reference',\n 'array',\n 'image',\n ]),\n displayName: z.string().optional(),\n description: z.string().optional(),\n required: z.boolean(),\n constraints: fieldConstraintsSchema.optional(),\n});\n\nconst fieldArraySchema = z\n .array(fieldDefinitionSchema)\n .min(1, 'Schema must have at least one field');\n\nconst multiSchemaFieldDefSchema = z.record(\n z.string().regex(SNAKE_CASE, 'schema name must be snake_case'),\n fieldArraySchema\n);\n\n// ---------------------------------------------------------------------------\n// Result types\n// ---------------------------------------------------------------------------\nexport interface SingleSchemaResult {\n kind: 'single';\n fields: FieldDefinition[];\n}\n\nexport interface MultiSchemaResult {\n kind: 'multi';\n /** Ordered: sub-schemas appear before the parent schema that references them */\n schemas: Record<string, FieldDefinition[]>;\n}\n\nexport interface ParseFieldDefinitionsError {\n kind: 'error';\n message: string;\n}\n\nexport type ParseFieldDefinitionsResult =\n | SingleSchemaResult\n | MultiSchemaResult\n | ParseFieldDefinitionsError;\n\n// ---------------------------------------------------------------------------\n// Shared constraint / duplicate checks (formats 2 & 3)\n// ---------------------------------------------------------------------------\nfunction checkConstraints(fields: FieldDefinition[], prefix?: string): string | null {\n for (const f of fields) {\n const label = prefix ? `\"${prefix}.${f.name}\"` : `\"${f.name}\"`;\n const c = f.constraints;\n if (!c) {\n if (f.type === 'enum') return `${label}: enum type requires constraints.enumValues`;\n if (f.type === 'array') return `${label}: array type requires constraints.arrayItemType`;\n continue;\n }\n if (f.type === 'enum' && (!c.enumValues || c.enumValues.length === 0)) {\n return `${label}: enum type requires at least one value in constraints.enumValues`;\n }\n if (f.type === 'array' && !c.arrayItemType) {\n return `${label}: array type requires constraints.arrayItemType`;\n }\n if (c.min !== undefined && c.max !== undefined && c.min > c.max) {\n return `${label}: min must be ≤ max`;\n }\n if (c.minLength !== undefined && c.maxLength !== undefined && c.minLength > c.maxLength) {\n return `${label}: minLength must be ≤ maxLength`;\n }\n if (c.minItems !== undefined && c.maxItems !== undefined && c.minItems > c.maxItems) {\n return `${label}: minItems must be ≤ maxItems`;\n }\n }\n return null;\n}\n\nfunction checkDuplicates(fields: FieldDefinition[], prefix?: string): string | null {\n const seen = new Set<string>();\n for (const f of fields) {\n if (seen.has(f.name)) {\n return `Duplicate field name: \"${prefix ? `${prefix}.${f.name}` : f.name}\"`;\n }\n seen.add(f.name);\n }\n return null;\n}\n\nfunction formatZodError(err: z.ZodError): string {\n const issue = err.issues[0];\n if (!issue) return 'Validation error';\n const path = issue.path.length > 0 ? ` (at ${issue.path.join('.')})` : '';\n return `${issue.message}${path}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sample data format helpers (format 1)\n// ---------------------------------------------------------------------------\nfunction camelToSnake(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n}\n\nfunction singularize(word: string): string {\n if (word.endsWith('ies')) return `${word.slice(0, -3)}y`;\n if (word.endsWith('ses') || word.endsWith('xes') || word.endsWith('zes'))\n return word.slice(0, -2);\n if (word.endsWith('s') && word.length > 3) return word.slice(0, -1);\n return word;\n}\n\ntype InferResult = FieldDefinition | { error: string };\n\nconst MAX_SAMPLE_DEPTH = 3;\n\n/**\n * Infer a FieldDefinition from a sample value.\n *\n * @param depth - current nesting depth (0 = top-level schema fields).\n * Arrays of objects are allowed up to MAX_SAMPLE_DEPTH levels deep.\n */\nfunction inferFieldFromValue(\n rawFieldName: string,\n value: unknown,\n parentSchemaName: string,\n refSchemas: Map<string, FieldDefinition[]>,\n depth: number\n): InferResult {\n const name = camelToSnake(rawFieldName);\n\n if (typeof value === 'string') return { name, type: 'string', required: true };\n if (typeof value === 'number') return { name, type: 'number', required: true };\n if (typeof value === 'boolean') return { name, type: 'boolean', required: true };\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": direct nested objects are not allowed — represent nested data as an array of references`,\n };\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n // Default empty arrays to string items\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'string' } };\n }\n\n const first = value[0];\n\n if (typeof first === 'string')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'string' } };\n if (typeof first === 'number')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'number' } };\n if (typeof first === 'boolean')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'boolean' } };\n\n if (first !== null && typeof first === 'object' && !Array.isArray(first)) {\n if (depth >= MAX_SAMPLE_DEPTH) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": maximum nesting depth (${MAX_SAMPLE_DEPTH}) exceeded — arrays of objects cannot be nested this deep`,\n };\n }\n\n // Derive reference schema name: parent_singularField\n const snakeField = camelToSnake(rawFieldName);\n const refName = `${parentSchemaName}_${singularize(snakeField)}`;\n\n if (refSchemas.has(refName)) {\n return {\n error: `Naming conflict: two fields both resolve to sub-schema name \"${refName}\". Rename one of the fields.`,\n };\n }\n\n // Build sub-schema fields from the first array item\n const subFields: FieldDefinition[] = [];\n for (const [subKey, subVal] of Object.entries(first as Record<string, unknown>)) {\n const subField = inferFieldFromValue(subKey, subVal, refName, refSchemas, depth + 1);\n if ('error' in subField) return subField;\n subFields.push(subField);\n }\n\n refSchemas.set(refName, subFields);\n\n return {\n name,\n type: 'array',\n required: true,\n constraints: { arrayItemType: 'reference', refSchema: refName },\n };\n }\n\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": unsupported array item type (arrays must contain strings, numbers, booleans, or objects)`,\n };\n }\n\n if (value === null) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": null values are not supported — omit the field or use a real example value`,\n };\n }\n\n return { error: `\"${parentSchemaName}.${rawFieldName}\": unsupported value type` };\n}\n\nfunction parseSampleData(raw: Record<string, unknown>): ParseFieldDefinitionsResult {\n // ref sub-schemas collected while processing — must be created before their parents\n const refSchemas = new Map<string, FieldDefinition[]>();\n const topSchemas: Record<string, FieldDefinition[]> = {};\n\n for (const [rawSchemaName, schemaData] of Object.entries(raw)) {\n if (schemaData === null || typeof schemaData !== 'object' || Array.isArray(schemaData)) {\n return {\n kind: 'error',\n message: `\"${rawSchemaName}\": schema value must be an object of field examples`,\n };\n }\n\n const schemaName = camelToSnake(rawSchemaName);\n const fields: FieldDefinition[] = [];\n\n for (const [rawFieldName, value] of Object.entries(schemaData as Record<string, unknown>)) {\n const result = inferFieldFromValue(rawFieldName, value, schemaName, refSchemas, 0);\n if ('error' in result) return { kind: 'error', message: result.error };\n fields.push(result);\n }\n\n if (fields.length === 0) {\n return { kind: 'error', message: `\"${rawSchemaName}\": schema must have at least one field` };\n }\n\n topSchemas[schemaName] = fields;\n }\n\n if (Object.keys(topSchemas).length === 0) {\n return { kind: 'error', message: 'No schemas found in the JSON object' };\n }\n\n // sub-schemas first (creation order), then top-level schemas\n const ordered: Record<string, FieldDefinition[]> = {};\n for (const [name, fields] of refSchemas) {\n ordered[name] = fields;\n }\n for (const [name, fields] of Object.entries(topSchemas)) {\n ordered[name] = fields;\n }\n\n return { kind: 'multi', schemas: ordered };\n}\n\n/**\n * Returns true if the object looks like multi-schema FieldDefinition format,\n * i.e. values are arrays of objects with {name, type, required} keys.\n */\nfunction looksLikeFieldDefMultiSchema(obj: Record<string, unknown>): boolean {\n const firstValue = Object.values(obj)[0];\n if (!Array.isArray(firstValue) || firstValue.length === 0) return false;\n const item = firstValue[0];\n return (\n item !== null &&\n typeof item === 'object' &&\n !Array.isArray(item) &&\n 'name' in (item as object) &&\n 'type' in (item as object) &&\n 'required' in (item as object)\n );\n}\n\nexport function parseFieldDefinitionsJson(text: string): ParseFieldDefinitionsResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (e) {\n return { kind: 'error', message: `Invalid JSON: ${(e as Error).message}` };\n }\n\n // --- single schema FieldDefinition[] ---\n if (Array.isArray(parsed)) {\n const result = fieldArraySchema.safeParse(parsed);\n if (!result.success) return { kind: 'error', message: formatZodError(result.error) };\n\n const fields = result.data as FieldDefinition[];\n const dupErr = checkDuplicates(fields);\n if (dupErr) return { kind: 'error', message: dupErr };\n const constraintErr = checkConstraints(fields);\n if (constraintErr) return { kind: 'error', message: constraintErr };\n\n return { kind: 'single', fields };\n }\n\n if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {\n const obj = parsed as Record<string, unknown>;\n\n if (Object.keys(obj).length === 0) {\n return { kind: 'error', message: 'Object must not be empty' };\n }\n\n // --- multi-schema FieldDefinition ---\n if (looksLikeFieldDefMultiSchema(obj)) {\n const result = multiSchemaFieldDefSchema.safeParse(obj);\n if (!result.success) return { kind: 'error', message: formatZodError(result.error) };\n\n const schemas = result.data as Record<string, FieldDefinition[]>;\n for (const [name, fields] of Object.entries(schemas)) {\n const dupErr = checkDuplicates(fields, name);\n if (dupErr) return { kind: 'error', message: dupErr };\n const constraintErr = checkConstraints(fields, name);\n if (constraintErr) return { kind: 'error', message: constraintErr };\n }\n return { kind: 'multi', schemas };\n }\n\n // --- sample data ---\n return parseSampleData(obj);\n }\n\n return {\n kind: 'error',\n message:\n 'JSON must be a sample-data object, a FieldDefinition array, or a multi-schema FieldDefinition object',\n };\n}\n","/**\n * CMS API Client\n *\n * Creates an HTTP-based tRPC client for calling the CMS API.\n * Used in Server Components to fetch routes and blocks from the CMS.\n */\n\nimport type { AppRouter } from '@repo/cms-schema/trpc';\nimport { type CreateTRPCClient, createTRPCClient, httpBatchLink } from '@trpc/client';\nimport superjson from 'superjson';\n\n/** Type alias for the CMS API client */\ntype CmsClient = CreateTRPCClient<AppRouter>;\n\n/**\n * Get the CMS API URL from the provided base URL.\n */\nfunction getCmsApiUrl(cmsUrl: string): string {\n return new URL('/api/trpc', cmsUrl).toString();\n}\n\n/** Unified configuration for all CMS API access */\nexport interface CmsConfig {\n /** CMS API base URL (e.g., 'http://localhost:3000') */\n cmsUrl: string;\n /** API key for authentication */\n apiKey?: string;\n /** Website ID to scope API requests */\n websiteId?: string;\n}\n\n/**\n * Create a custom fetch function that appends API key as query parameter.\n */\nfunction createFetchWithApiKey(apiKey?: string, websiteId?: string) {\n return async (url: URL | RequestInfo, options?: RequestInit): Promise<Response> => {\n let finalUrl = url;\n\n const urlObj = new URL(url.toString());\n if (apiKey) {\n urlObj.searchParams.set('api_key', apiKey);\n }\n if (websiteId) {\n urlObj.searchParams.set('website_id', websiteId);\n }\n if (apiKey || websiteId) {\n finalUrl = urlObj.toString();\n }\n\n const response = await fetch(finalUrl, options);\n\n return response;\n };\n}\n\n/**\n * Create a tRPC client for the CMS API.\n */\nfunction createCmsClient(options: CmsConfig): CmsClient {\n const url = getCmsApiUrl(options.cmsUrl);\n\n return createTRPCClient<AppRouter>({\n links: [\n httpBatchLink({\n url,\n transformer: superjson,\n fetch: createFetchWithApiKey(options.apiKey, options.websiteId),\n }),\n ],\n });\n}\n\n/**\n * Get a CMS client for the specified CMS URL.\n */\nexport function getCmsClient(options: CmsConfig): CmsClient {\n return createCmsClient(options);\n}\n"],"mappings":"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","names":["types","safeRegex","ok","z","z","z","z","z","z","z","z","z","safeRegex","err","err","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/tokens.js","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/types/types.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/set-lookup.js","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/types/index.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/sets.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/util.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/tokenizer.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/sets-lookup.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/write-set-tokens.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/reconstruct.ts","../../../../node_modules/.bun/ret@0.5.0/node_modules/ret/lib/index.ts","../../../../node_modules/.bun/safe-regex2@5.0.0/node_modules/safe-regex2/index.js","../../lib/custom-schemas.ts","../../../../packages/cms-schema/src/documents/registry.ts","../../../../packages/cms-schema/src/documents/schemas/country.ts","../../../../packages/cms-schema/src/documents/schemas/language.ts","../../../../packages/cms-schema/src/documents/unified-registry.ts","../../../../packages/cms-schema/src/documents/rehydration.ts","../../../../packages/cms-schema/src/fields/complex/media.ts","../../../../packages/cms-schema/src/validation/image.ts","../../../../packages/cms-schema/src/fields/complex/richtext.ts","../../../../packages/cms-schema/src/utils/safe-regex.ts","../../../../packages/cms-schema/src/documents/schema-hash.ts","../../../../packages/cms-schema/src/documents/validations/country.ts","../../../../packages/cms-schema/src/documents/parse-field-definitions-json.ts","../../lib/cms-api.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=tokens.js.map",null,"\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=set-lookup.js.map",null,null,null,null,null,null,null,null,"'use strict'\n\nconst parse = require('ret')\nconst types = parse.types\n\nfunction safeRegex (re, opts) {\n if (!opts) opts = {}\n /* c8 ignore next */\n const replimit = opts.limit === undefined ? 25 : opts.limit\n\n /* c8 ignore next 2 */\n if (isRegExp(re)) re = re.source\n else if (typeof re !== 'string') re = String(re)\n\n try { re = parse(re) } catch { return false }\n\n let reps = 0\n return (function walk (node, starHeight) {\n let i\n let ok\n let len\n\n if (node.type === types.REPETITION) {\n starHeight++\n reps++\n if (starHeight > 1) return false\n if (reps > replimit) return false\n }\n\n if (node.options) {\n for (i = 0, len = node.options.length; i < len; i++) {\n ok = walk({ stack: node.options[i] }, starHeight)\n if (!ok) return false\n }\n }\n const stack = node.stack || node.value?.stack\n if (!stack) return true\n\n for (i = 0; i < stack.length; i++) {\n ok = walk(stack[i], starHeight)\n if (!ok) return false\n }\n\n return true\n })(re, 0)\n}\n\nfunction isRegExp (x) {\n return {}.toString.call(x) === '[object RegExp]'\n}\n\nmodule.exports = safeRegex\nmodule.exports.default = safeRegex\nmodule.exports.safeRegex = safeRegex\n","/**\n * Custom Schema Fetcher\n *\n * Fetches custom schema definitions (field metadata as JSON) from the CMS API\n * for a given website. Uses the tRPC client to call the customSchema router.\n */\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { FieldConstraints, FieldDefinition } from '@repo/cms-schema/documents';\nimport { rehydrateSchema } from '@repo/cms-schema/documents';\nimport escapeStringRegexp from 'escape-string-regexp';\nimport type { ZodObject, ZodRawShape } from 'zod';\nimport { type CmsConfig, getCmsClient } from './cms-api';\n\nexport interface CustomSchemaFields {\n name: string;\n displayName: string;\n description: string | null;\n fields: FieldDefinition[];\n routeSlugField: string | null;\n version: number;\n}\n\nexport type FetchCustomSchemasOptions = CmsConfig & { websiteId: string };\n\n/**\n * Fetches all custom schemas with their field definitions for a website.\n *\n * @example\n * ```ts\n * const schemas = await fetchAllCustomSchemaFields({\n * cmsUrl: 'http://localhost:3000',\n * apiKey: 'my-api-key',\n * websiteId: 'uuid-here',\n * });\n *\n * for (const schema of schemas) {\n * console.log(schema.name, schema.fields);\n * }\n * ```\n */\nexport async function fetchAllCustomSchemaFields(\n options: FetchCustomSchemasOptions\n): Promise<CustomSchemaFields[]> {\n const { websiteId } = options;\n\n const client = getCmsClient(options);\n\n // Get the list of all custom schemas (summaries only)\n const summaries = await client.customSchema.list.query({\n websiteId,\n includePresets: false,\n });\n\n // Fetch full field definitions for each schema in parallel\n const schemas = await Promise.all(\n summaries.map(async (summary) => {\n const detail = await client.customSchema.getByName.query({\n websiteId,\n name: summary.name,\n });\n\n return {\n name: detail.name,\n displayName: detail.displayName,\n description: detail.description ?? null,\n fields: detail.fields,\n routeSlugField: detail.routeSlugField ?? null,\n version: detail.version,\n } satisfies CustomSchemaFields;\n })\n );\n\n return schemas;\n}\n\n/**\n * Fetches a single custom schema's field definitions by name.\n *\n * @example\n * ```ts\n * const schema = await fetchCustomSchemaFields({\n * cmsUrl: 'http://localhost:3000',\n * apiKey: 'my-api-key',\n * websiteId: 'uuid-here',\n * }, 'blog_post');\n *\n * console.log(schema.fields);\n * ```\n */\nexport async function fetchCustomSchemaFields(\n options: FetchCustomSchemasOptions,\n schemaName: string\n): Promise<CustomSchemaFields> {\n const { websiteId } = options;\n const client = getCmsClient(options);\n\n const detail = await client.customSchema.getByName.query({\n websiteId,\n name: schemaName,\n });\n\n return {\n name: detail.name,\n displayName: detail.displayName,\n description: detail.description ?? null,\n fields: detail.fields,\n routeSlugField: detail.routeSlugField ?? null,\n version: detail.version,\n };\n}\n\n/**\n * Converts an array of custom schema definitions into a record of Zod schemas,\n * keyed by schema name.\n *\n * @example\n * ```ts\n * const schemas = await fetchAllCustomSchemaFields(options);\n * const zodSchemas = buildZodSchemas(schemas);\n *\n * // Validate a blog post document\n * const result = zodSchemas['blog_post'].safeParse(data);\n * ```\n */\nexport function buildZodSchemas(\n schemas: CustomSchemaFields[]\n): Record<string, ZodObject<ZodRawShape>> {\n // biome-ignore lint/suspicious/noExplicitAny: avoids excessively deep type instantiation from Zod generics\n const result: Record<string, any> = {};\n\n for (const schema of schemas) {\n result[schema.name] = rehydrateSchema(schema.fields);\n }\n\n return result;\n}\n\n/**\n * Generates combined Zod schema TypeScript source code and writes it to disk.\n *\n * @param schemas - Array of custom schema definitions\n * @param outputPath - File path to write the generated code to\n */\nexport async function saveZodSchemaCode(\n schemas: CustomSchemaFields[],\n outputPath: string\n): Promise<void> {\n const code = generateCombinedZodSchemaCode(\n schemas.map((s) => ({ name: s.name, fields: s.fields }))\n );\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, code, 'utf-8');\n}\n\nfunction generateCombinedZodSchemaCode(\n schemas: Array<{ name: string; fields: FieldDefinition[] }>\n): string {\n const lines: string[] = [];\n\n lines.push('/* eslint-disable */');\n lines.push('/* prettier-ignore */');\n lines.push('/* biome-ignore format: auto-generated */');\n lines.push('// This file is auto-generated by cms-renderer. Do not edit manually.');\n lines.push('');\n lines.push(`import { z } from 'zod';`);\n lines.push('');\n\n const hasImageField = schemas.some((s) => s.fields.some((f) => f.type === 'image'));\n if (hasImageField) {\n lines.push('const ImageReferenceSchema = z.object({');\n lines.push(\" alt: z.string().min(1, 'Alt text is required for accessibility'),\");\n lines.push(' caption: z.string().max(500).optional(),');\n lines.push(' attribution: z.string().max(255).optional(),');\n lines.push(' _asset: z.object({');\n lines.push(' id: z.string().uuid(),');\n lines.push(' }),');\n lines.push('});');\n lines.push('');\n }\n\n for (const [i, schema] of schemas.entries()) {\n if (i > 0) lines.push('');\n const varName = `${toCamelCase(schema.name)}Schema`;\n lines.push(`export const ${varName} = z.object({`);\n for (const field of schema.fields) {\n if (field.description) lines.push(` /** ${field.description} */`);\n lines.push(` ${field.name}: ${generateFieldCode(field)},`);\n }\n lines.push('});');\n lines.push('');\n lines.push(`export type ${toPascalCase(schema.name)} = z.infer<typeof ${varName}>;`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nfunction generateFieldCode(field: FieldDefinition): string {\n let code = generateBaseTypeCode(field.type, field.constraints);\n if (!field.required) code += '.optional()';\n return code;\n}\n\nfunction generateBaseTypeCode(\n type: FieldDefinition['type'],\n constraints?: FieldConstraints\n): string {\n switch (type) {\n case 'string':\n return applyStringConstraintCode('z.string()', constraints);\n case 'number':\n return applyNumberConstraintCode('z.number()', constraints);\n case 'boolean':\n return 'z.boolean()';\n case 'image':\n return 'ImageReferenceSchema';\n case 'date':\n return \"z.string().date('Invalid date format. Expected YYYY-MM-DD')\";\n case 'datetime':\n return \"z.string().datetime({ offset: true, message: 'Invalid datetime format. Expected ISO 8601' })\";\n case 'url':\n return applyStringConstraintCode(\"z.string().url('Invalid URL format')\", constraints);\n case 'email':\n return applyStringConstraintCode(\"z.string().email('Invalid email format')\", constraints);\n case 'enum': {\n const values = constraints?.enumValues;\n if (!values || values.length === 0) return \"z.enum([''])\";\n const formatted = values\n .map((v) => `'${v.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`)\n .join(', ');\n return `z.enum([${formatted}])`;\n }\n case 'reference':\n return 'z.record(z.string(), z.unknown())';\n case 'array': {\n const itemType = constraints?.arrayItemType ?? 'string';\n const itemCode =\n itemType === 'number'\n ? 'z.number()'\n : itemType === 'boolean'\n ? 'z.boolean()'\n : itemType === 'reference'\n ? 'z.record(z.string(), z.unknown())'\n : 'z.string()';\n return applyArrayConstraintCode(`z.array(${itemCode})`, constraints);\n }\n default:\n return 'z.unknown()';\n }\n}\n\nfunction applyStringConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.minLength !== undefined)\n code += `.min(${constraints.minLength}, 'Must be at least ${constraints.minLength} characters')`;\n if (constraints.maxLength !== undefined)\n code += `.max(${constraints.maxLength}, 'Must be at most ${constraints.maxLength} characters')`;\n if (constraints.pattern)\n code += `.regex(/${escapeStringRegexp(constraints.pattern)}/, 'Invalid format')`;\n return code;\n}\n\nfunction applyNumberConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.integer) code += `.int('Must be an integer')`;\n if (constraints.min !== undefined)\n code += `.min(${constraints.min}, 'Must be at least ${constraints.min}')`;\n if (constraints.max !== undefined)\n code += `.max(${constraints.max}, 'Must be at most ${constraints.max}')`;\n return code;\n}\n\nfunction applyArrayConstraintCode(base: string, constraints?: FieldConstraints): string {\n if (!constraints) return base;\n let code = base;\n if (constraints.minItems !== undefined)\n code += `.min(${constraints.minItems}, 'Must have at least ${constraints.minItems} items')`;\n if (constraints.maxItems !== undefined)\n code += `.max(${constraints.maxItems}, 'Must have at most ${constraints.maxItems} items')`;\n return code;\n}\n\nfunction toCamelCase(str: string): string {\n return str.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\nfunction toPascalCase(str: string): string {\n const camel = toCamelCase(str);\n return camel.charAt(0).toUpperCase() + camel.slice(1);\n}\n","/**\n * Document Schema Registry.\n *\n * Centralizes registration for all document schemas.\n * The CMS reads this registry to generate UI and validation.\n */\n\nimport { type ZodObject, type ZodRawShape, z } from 'zod';\nimport type { DocumentError } from '../db/document-types';\nimport { DocumentErrors } from '../db/document-types';\nimport type { TypedSupabaseClient } from '../db/types';\nimport type { Result } from '../types/errors';\nimport { err, ok } from '../types/errors';\n\n// =============================================================================\n// Validation Schemas\n// =============================================================================\n\n/**\n * Schema name validation - must be a non-empty string.\n */\nconst schemaNameValidator = z\n .string()\n .min(1, 'Schema name must be a non-empty string')\n .refine((name) => name.trim().length > 0, 'Schema name must not be only whitespace');\n\n/**\n * Runtime validator for document schema config.\n * Validates the config object structure at runtime.\n */\nconst documentSchemaConfigValidator = z.object({\n schema: z.custom<ZodObject<ZodRawShape>>(\n (val) => val !== null && typeof val === 'object' && '_def' in val,\n { message: 'schema must be a valid Zod schema' }\n ),\n titleField: z.string().optional(),\n displayName: z.string().optional(),\n description: z.string().optional(),\n validateContent: z.function().optional(),\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Configuration for a registered document schema.\n */\nexport interface DocumentSchemaConfig<T extends ZodRawShape = ZodRawShape> {\n /** Zod schema for content validation */\n schema: ZodObject<T>;\n /** Field to extract for title (default: tries 'name', 'title', 'code') */\n titleField?: string;\n /** Display name for the schema in the UI */\n displayName?: string;\n /** Description of the document type */\n description?: string;\n /** Optional custom validation function for schema-specific rules */\n validateContent?: (content: unknown, supabase: TypedSupabaseClient) => Promise<void>;\n}\n\n/**\n * Registered schema with computed metadata.\n */\nexport interface RegisteredSchema<T extends ZodRawShape = ZodRawShape>\n extends DocumentSchemaConfig<T> {\n /** Schema name (registry key) */\n name: string;\n}\n\n// =============================================================================\n// Registry\n// =============================================================================\n\nconst documentRegistry = new Map<string, DocumentSchemaConfig>();\n\n/**\n * Register a document schema.\n *\n * @example\n * registerDocumentSchema('country', {\n * schema: CountrySchema,\n * titleField: 'name',\n * displayName: 'Country',\n * });\n *\n * @throws {Error} If schema name is empty or already registered\n */\nexport function registerDocumentSchema<T extends ZodRawShape>(\n name: string,\n config: DocumentSchemaConfig<T>\n): void {\n // Validate schema name using Zod\n const nameResult = schemaNameValidator.safeParse(name);\n if (!nameResult.success) {\n throw new Error(nameResult.error.issues.at(0)?.message ?? 'Invalid schema name');\n }\n\n // Validate config structure using Zod\n const configResult = documentSchemaConfigValidator.safeParse(config);\n if (!configResult.success) {\n throw new Error(\n `Invalid schema config: ${configResult.error.issues.at(0)?.message ?? 'Unknown error'}`\n );\n }\n\n // Check for duplicate registration\n if (documentRegistry.has(name)) {\n throw new Error(`Document schema \"${name}\" is already registered`);\n }\n\n documentRegistry.set(name, config as DocumentSchemaConfig);\n}\n\n/**\n * Get a document schema configuration by name.\n */\nexport function getDocumentSchema(name: string): DocumentSchemaConfig | undefined {\n return documentRegistry.get(name);\n}\n\n/**\n * Get all registered schema names.\n */\nexport function getRegisteredDocumentSchemas(): string[] {\n return Array.from(documentRegistry.keys());\n}\n\n/**\n * Get all registered schemas with their configurations.\n */\nexport function getAllDocumentSchemas(): RegisteredSchema[] {\n return Array.from(documentRegistry.entries()).map(([name, config]) => ({\n name,\n ...config,\n }));\n}\n\n/**\n * Clear the document registry (for testing).\n */\nexport function clearDocumentRegistry(): void {\n documentRegistry.clear();\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\n/**\n * Validate document content against a registered schema.\n *\n * @returns Result with validated data or error\n */\nexport function validateDocumentContent<T>(\n schemaName: string,\n content: unknown\n): Result<T, DocumentError> {\n const config = documentRegistry.get(schemaName);\n\n if (!config) {\n return err(DocumentErrors.schemaNotFound(schemaName));\n }\n\n const result = config.schema.safeParse(content);\n\n if (!result.success) {\n const issues = result.error.issues.map((issue) => ({\n path: issue.path.filter((p): p is string | number => typeof p !== 'symbol'),\n message: issue.message,\n }));\n return err(DocumentErrors.validationError(issues));\n }\n\n return ok(result.data as T);\n}\n\n/**\n * Detailed validation result for UI display.\n */\nexport interface DocumentValidationResult<T> {\n valid: boolean;\n data?: T;\n issues?: Array<{ path: (string | number)[]; message: string }>;\n}\n\n/**\n * Validate document content with detailed error info for UI.\n */\nexport function validateDocumentContentDetailed<T>(\n schemaName: string,\n content: unknown\n): DocumentValidationResult<T> {\n const config = documentRegistry.get(schemaName);\n\n if (!config) {\n return {\n valid: false,\n issues: [{ path: [], message: `Document schema not found: ${schemaName}` }],\n };\n }\n\n const result = config.schema.safeParse(content);\n\n if (!result.success) {\n return {\n valid: false,\n issues: result.error.issues.map((issue) => ({\n path: issue.path.filter((p): p is string | number => typeof p !== 'symbol'),\n message: issue.message,\n })),\n };\n }\n\n return { valid: true, data: result.data as T };\n}\n\n// =============================================================================\n// Title Extraction\n// =============================================================================\n\n/**\n * Extract title from document content based on schema configuration.\n *\n * Tries in order:\n * 1. Schema's configured titleField\n * 2. 'title' field\n * 3. 'name' field\n * 4. 'code' field\n * 5. 'Untitled'\n */\nexport function extractDocumentTitle(schemaName: string, content: Record<string, unknown>): string {\n const config = documentRegistry.get(schemaName);\n\n // Try configured title field first\n if (config?.titleField && content[config.titleField] !== undefined) {\n return String(content[config.titleField]);\n }\n\n // Fall back to common title fields\n if (content.title !== undefined) return String(content.title);\n if (content.name !== undefined) return String(content.name);\n if (content.code !== undefined) return String(content.code);\n\n return 'Untitled';\n}\n\n// =============================================================================\n// Schema Introspection\n// =============================================================================\n\n/**\n * Get field information from a registered schema for dynamic form generation.\n */\nexport interface SchemaFieldInfo {\n name: string;\n type: string;\n isOptional: boolean;\n required: boolean;\n isArray: boolean;\n description?: string;\n /** For enum types, the available values */\n enumValues?: string[];\n /** For array types, the item type */\n itemType?: string;\n /** For reference types, the referenced schema */\n refSchema?: string;\n /** Default value if the field has one */\n defaultValue?: unknown;\n /** Whether this field has a default value */\n hasDefault?: boolean;\n}\n\n/**\n * Extract field info from a document schema for UI generation.\n */\nexport function getSchemaFields(schemaName: string): SchemaFieldInfo[] {\n const config = documentRegistry.get(schemaName);\n if (!config) return [];\n\n const shape = config.schema.shape;\n const fields: SchemaFieldInfo[] = [];\n\n for (const [name, zodType] of Object.entries(shape)) {\n const typeDef = zodType as z.ZodTypeAny;\n const isOptional = typeDef.isOptional();\n const fieldType = getFieldType(typeDef);\n const isArray = isArrayType(typeDef);\n const { value: defaultValue, hasDefault } = getDefaultValue(typeDef);\n\n const fieldInfo: SchemaFieldInfo = {\n name,\n type: fieldType,\n isOptional,\n required: !isOptional && !hasDefault, // Field is not required if it has a default\n isArray,\n description: typeDef.description,\n defaultValue,\n hasDefault,\n };\n\n // Extract enum values if this is an enum type\n // Also check if we can extract enum values even if type wasn't detected as enum\n const enumValues = getEnumValues(typeDef);\n if (enumValues.length > 0) {\n fieldInfo.enumValues = enumValues;\n // If we found enum values but type wasn't detected as enum, fix the type\n if (fieldType !== 'enum') {\n fieldInfo.type = 'enum';\n }\n }\n\n // Extract array item info\n if (isArray) {\n const arrayInfo = getArrayItemInfo(typeDef);\n fieldInfo.itemType = arrayInfo.itemType;\n fieldInfo.refSchema = arrayInfo.refSchema;\n }\n\n fields.push(fieldInfo);\n }\n\n return fields;\n}\n\nfunction getFieldType(zodType: z.ZodTypeAny): string {\n const unwrapped = unwrapType(zodType);\n // Zod v4 exposes runtime metadata via `def.type`/`def.checks` (legacy builds may still use `typeName`).\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n const kind = normalizeDefType(getDefType(def));\n if (!kind) return 'unknown';\n\n switch (kind) {\n case 'string': {\n const checks = (def?.checks as unknown[] | undefined) ?? [];\n for (const check of checks) {\n const checkDef =\n (check as { _def?: Record<string, unknown>; def?: Record<string, unknown> })._def ??\n (check as { _def?: Record<string, unknown>; def?: Record<string, unknown> }).def;\n const format = checkDef?.format;\n if (format === 'date') return 'date';\n if (format === 'datetime') return 'datetime';\n if (format === 'url') return 'url';\n if (format === 'email') return 'email';\n }\n return 'string';\n }\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'array':\n return 'array';\n case 'object':\n return 'object';\n case 'enum':\n return 'enum';\n default:\n return kind;\n }\n}\n\nfunction isArrayType(zodType: z.ZodTypeAny): boolean {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n const kind = normalizeDefType(getDefType(def));\n return kind === 'array';\n}\n\n/**\n * Extract default value from a Zod type.\n */\nfunction getDefaultValue(zodType: z.ZodTypeAny): { value?: unknown; hasDefault: boolean } {\n const def = zodType.def;\n if (!def) return { hasDefault: false };\n\n // Check for default value in ZodDefault\n const defType = getDefType(def);\n const isDefault = defType === 'ZodDefault' || defType === 'default';\n if (isDefault) {\n if ('defaultValue' in def) {\n const defaultValue = def.defaultValue;\n // Default value can be a function or a value\n if (typeof defaultValue === 'function') {\n try {\n return { value: defaultValue(), hasDefault: true };\n } catch {\n return { hasDefault: false };\n }\n }\n return { value: defaultValue, hasDefault: true };\n }\n }\n\n // Unwrap optional/nullable to check inner type\n if ('innerType' in def) {\n return getDefaultValue(def.innerType as z.ZodTypeAny);\n }\n\n return { hasDefault: false };\n}\n\n/**\n * Extract enum values from a Zod enum type.\n */\nfunction getEnumValues(zodType: z.ZodTypeAny): string[] {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return [];\n\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'enum') return [];\n\n const values = (def.values as unknown[] | undefined)?.filter(\n (value): value is string => typeof value === 'string'\n );\n if (values && values.length > 0) {\n return values;\n }\n\n const entries = def.entries as Record<string, unknown> | undefined;\n if (entries) {\n return Object.values(entries).filter((value): value is string => typeof value === 'string');\n }\n\n return [];\n}\n\n/**\n * Extract array item type information.\n */\nfunction getArrayItemInfo(zodType: z.ZodTypeAny): { itemType: string; refSchema?: string } {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return { itemType: 'unknown' };\n\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'array') return { itemType: 'unknown' };\n\n // Zod v4 stores array item schema in `element`; older versions may use `type`.\n const itemType = ((def.element ?? def.type) as z.ZodTypeAny | undefined) ?? null;\n if (!itemType) return { itemType: 'unknown' };\n const itemUnwrapped = unwrapType(itemType);\n const itemDef = itemUnwrapped.def as unknown as Record<string, unknown> | undefined;\n const itemKind = normalizeDefType(getDefType(itemDef));\n\n // Check if it's a reference object (has _type, _ref, _schema)\n if (itemKind === 'object') {\n const shape = getObjectShape(itemUnwrapped);\n if (shape && '_type' in shape && '_ref' in shape && '_schema' in shape) {\n const refSchema = getLiteralValue(shape._schema);\n if (refSchema) {\n return { itemType: 'reference', refSchema };\n }\n return { itemType: 'reference' };\n }\n }\n\n return { itemType: getFieldType(itemUnwrapped) };\n}\n\nfunction getDefType(def: unknown): string | undefined {\n if (!def || typeof def !== 'object') return undefined;\n // Keep compatibility with both v3-style `typeName` and v4-style `type`.\n const maybeDef = def as { typeName?: unknown; type?: unknown };\n if (typeof maybeDef.typeName === 'string') return maybeDef.typeName;\n if (typeof maybeDef.type === 'string') return maybeDef.type;\n return undefined;\n}\n\nfunction normalizeDefType(defType: string | undefined): string | undefined {\n if (!defType) return undefined;\n return defType.startsWith('Zod') ? defType.slice(3).toLowerCase() : defType.toLowerCase();\n}\n\nfunction unwrapType(zodType: z.ZodTypeAny): z.ZodTypeAny {\n let current: z.ZodTypeAny = zodType;\n\n while (true) {\n const def = current.def as unknown as Record<string, unknown> | undefined;\n if (!def) return current;\n const kind = normalizeDefType(getDefType(def));\n if (\n (kind === 'default' ||\n kind === 'optional' ||\n kind === 'nullable' ||\n kind === 'prefault' ||\n kind === 'catch' ||\n kind === 'readonly') &&\n def.innerType\n ) {\n current = def.innerType as z.ZodTypeAny;\n continue;\n }\n return current;\n }\n}\n\nfunction getObjectShape(schema: z.ZodTypeAny): Record<string, z.ZodTypeAny> | null {\n const schemaWithShape = schema as unknown as { shape?: unknown };\n if (schemaWithShape.shape && typeof schemaWithShape.shape === 'object') {\n return schemaWithShape.shape as Record<string, z.ZodTypeAny>;\n }\n\n const def = schema.def as unknown as Record<string, unknown> | undefined;\n const rawShape = def?.shape;\n if (typeof rawShape === 'function') {\n return rawShape() as Record<string, z.ZodTypeAny>;\n }\n if (rawShape && typeof rawShape === 'object') {\n return rawShape as Record<string, z.ZodTypeAny>;\n }\n return null;\n}\n\nfunction getLiteralValue(zodType: z.ZodTypeAny): string | undefined {\n const unwrapped = unwrapType(zodType);\n const def = unwrapped.def as unknown as Record<string, unknown> | undefined;\n if (!def) return undefined;\n const kind = normalizeDefType(getDefType(def));\n if (kind !== 'literal') return undefined;\n\n if (typeof def.value === 'string') {\n return def.value;\n }\n\n const values = def.values as unknown[] | undefined;\n if (values && typeof values[0] === 'string') {\n return values[0];\n }\n\n return undefined;\n}\n","/**\n * Country Document Schema.\n *\n * Defines the structure for country documents.\n * Countries store supported languages as ISO codes and may still contain\n * legacy references to language documents during migration.\n */\n\nimport { z } from 'zod';\n\n// Legacy language document reference kept for backwards compatibility.\nconst LanguageReferenceSchema = z.object({\n _type: z.literal('reference'),\n _ref: z.string().uuid('Language reference must be a valid UUID'),\n _schema: z.literal('language'),\n});\n\n/**\n * Country schema with validation rules.\n *\n * @example\n * {\n * code: 'us',\n * name: 'United States',\n * flag: '🇺🇸',\n * languages: ['en', 'es']\n * }\n *\n * @example\n * {\n * code: 'sa',\n * name: 'Saudi Arabia',\n * flag: '🇸🇦',\n * languages: ['ar', 'en']\n * }\n */\nexport const CountrySchema = z.object({\n /** 2-letter ISO 3166-1 alpha-2 country code */\n code: z.string().length(2, 'Country code must be 2 characters'),\n\n /** English name of the country */\n name: z.string().min(1, 'Country name required'),\n\n /** Flag emoji (optional but recommended) */\n flag: z.string().optional(),\n\n /**\n * List of supported languages (at least one required).\n * Supports either:\n * - Language codes (new format)\n * - Document references to languages (legacy format for backward compatibility)\n */\n languages: z\n .array(\n z.union([z.string().length(2, 'Language code must be 2 characters'), LanguageReferenceSchema])\n )\n .min(1, 'At least one language required'),\n});\n\nexport type Country = z.infer<typeof CountrySchema>;\n\nexport const COUNTRY_SCHEMA_NAME = 'country';\nexport const COUNTRY_DISPLAY_NAME = 'Country';\nexport const COUNTRY_TITLE_FIELD = 'name';\n\n/**\n * Create a default country object.\n */\nexport function createDefaultCountry(): Country {\n return {\n code: '',\n name: '',\n flag: '',\n languages: [],\n };\n}\n","/**\n * Language Document Schema.\n *\n * Defines the structure for language documents.\n */\n\nimport { z } from 'zod';\n\n/**\n * Language schema with validation rules.\n *\n * @example\n * {\n * code: 'en',\n * name: 'English',\n * nativeName: 'English'\n * }\n *\n * @example\n * {\n * code: 'ar',\n * name: 'Arabic',\n * nativeName: 'العربية'\n * }\n */\nexport const LanguageSchema = z.object({\n /** 2-letter ISO 639-1 language code */\n code: z.string().length(2, 'Language code must be 2 characters'),\n\n /** English name of the language */\n name: z.string().min(1, 'Language name required'),\n\n /** Name in the language itself (optional but recommended) */\n nativeName: z.string().optional(),\n});\n\n/** TypeScript type inferred from schema */\nexport type Language = z.infer<typeof LanguageSchema>;\n\n/** Schema name constant */\nexport const LANGUAGE_SCHEMA_NAME = 'language';\n\n/** Display name for UI */\nexport const LANGUAGE_DISPLAY_NAME = 'Language';\n\n/** Title field for list display */\nexport const LANGUAGE_TITLE_FIELD = 'name';\n\n/**\n * Create a default language object.\n */\nexport function createDefaultLanguage(): Language {\n return {\n code: '',\n name: '',\n nativeName: '',\n };\n}\n\n/**\n * Static list of all languages supported by the translation system.\n *\n * This is the authoritative source — both the language documents page and the\n * translation language picker render from this array. The Rust translation\n * service validates incoming language codes against the same set.\n */\nexport const SUPPORTED_LANGUAGES: Language[] = [\n { code: 'ar', name: 'Arabic', nativeName: 'العربية' },\n { code: 'zh', name: 'Chinese (Simplified)', nativeName: '中文(简体)' },\n { code: 'nl', name: 'Dutch', nativeName: 'Nederlands' },\n { code: 'en', name: 'English', nativeName: 'English' },\n { code: 'fr', name: 'French', nativeName: 'Français' },\n { code: 'de', name: 'German', nativeName: 'Deutsch' },\n { code: 'it', name: 'Italian', nativeName: 'Italiano' },\n { code: 'ja', name: 'Japanese', nativeName: '日本語' },\n { code: 'ko', name: 'Korean', nativeName: '한국어' },\n { code: 'pl', name: 'Polish', nativeName: 'Polski' },\n { code: 'pt', name: 'Portuguese', nativeName: 'Português' },\n { code: 'ru', name: 'Russian', nativeName: 'Русский' },\n { code: 'es', name: 'Spanish', nativeName: 'Español' },\n { code: 'tr', name: 'Turkish', nativeName: 'Türkçe' },\n];\n","/**\n * Unified Schema Registry\n *\n * Merges preset schemas (hardcoded in TypeScript) with custom schemas (stored as JSON in database).\n * Both types of schemas are served through the same API, making them indistinguishable to consumers.\n *\n * Custom schemas take precedence over presets with the same name.\n * Custom schemas are cached with a TTL and can be invalidated.\n */\n\nimport { type ZodObject, type ZodRawShape, z } from 'zod';\nimport type { TypedSupabaseClient } from '../db/types';\nimport { rehydrateSchema } from './rehydration';\nimport { createSchemaHash } from './schema-hash';\nimport type { CustomSchemaRow, FieldDefinition } from './schema-types';\n\n/** Source of a schema definition */\nexport type SchemaSource = 'preset' | 'custom';\n\ntype TitleCandidateFieldType = FieldDefinition['type'];\n\nconst titleCandidateFieldTypes = new Set<TitleCandidateFieldType>([\n 'string',\n 'enum',\n 'url',\n 'email',\n 'date',\n 'datetime',\n]);\n\nfunction inferTitleFieldFromZodSchema(schema: ZodObject<ZodRawShape>): string {\n const shape = schema.shape ?? {};\n const keys = Object.keys(shape);\n if (keys.includes('title')) return 'title';\n if (keys.includes('name')) return 'name';\n if (keys.includes('code')) return 'code';\n return keys[0] ?? 'title';\n}\n\nfunction resolveTitleFieldFromFields(options: {\n fields: FieldDefinition[];\n titleField?: string | null;\n routeSlugField?: string | null;\n}): string | undefined {\n const { fields, titleField, routeSlugField } = options;\n\n if (titleField) {\n return titleField;\n }\n\n const fieldMap = new Map(fields.map((f) => [f.name, f] as const));\n\n if (routeSlugField) {\n const slugField = fieldMap.get(routeSlugField);\n if (slugField && titleCandidateFieldTypes.has(slugField.type)) {\n return routeSlugField;\n }\n }\n\n for (const preferredName of ['title', 'name', 'code'] as const) {\n const preferred = fieldMap.get(preferredName);\n if (preferred && titleCandidateFieldTypes.has(preferred.type)) {\n return preferredName;\n }\n }\n\n const firstCandidate = fields.find((f) => titleCandidateFieldTypes.has(f.type));\n return firstCandidate?.name;\n}\n\n/** Unified schema configuration that works for both preset and custom schemas */\nexport interface UnifiedSchemaConfig {\n /** Database ID (only present for custom schemas) */\n id?: string;\n name: string;\n schema: ZodObject<ZodRawShape>;\n displayName: string;\n description?: string;\n titleField: string;\n /** Field name to use as URL routing slug. Value is auto-copied to content.code on document save. */\n routeSlugField?: string;\n icon?: string;\n source: SchemaSource;\n version?: number;\n /** ISO timestamp of last DB update (only present for custom schemas) */\n updatedAt?: string | null;\n /** Optional custom validation (typically for presets) */\n validateContent?: (content: unknown, supabase: TypedSupabaseClient) => Promise<void>;\n}\n\n/** Summary info for listing schemas (without full Zod schema) */\nexport interface SchemaSummary {\n /** Database ID (only present for custom schemas) */\n id?: string;\n name: string;\n displayName: string;\n description?: string;\n icon?: string;\n source: SchemaSource;\n version?: number;\n /** Field name used for URL routing - if not set, URL routing may not work */\n routeSlugField?: string;\n}\n\n// In-memory storage\nconst presetSchemas = new Map<string, UnifiedSchemaConfig>();\nconst customSchemaCacheByWebsite = new Map<string, Map<string, UnifiedSchemaConfig>>();\nconst customSchemasCacheTimeByWebsite = new Map<string, number>();\n\n/**\n * Optional hook called after the in-process cache is cleared.\n * Register this in deployment-aware entry points (e.g. Next.js server.ts)\n * to propagate invalidation across all instances via revalidateTag or similar.\n */\nlet onInvalidate: ((websiteId?: string) => void) | null = null;\n\n/**\n * Register a callback to be invoked whenever the schema cache is invalidated.\n * Intended for Next.js deployments: pass `revalidateTag` so invalidation\n * reaches all instances, not just the local process.\n *\n * @param fn - Receives the websiteId that was invalidated (undefined = all)\n */\nexport function setSchemaInvalidationHook(fn: (websiteId?: string) => void): void {\n onInvalidate = fn;\n}\n\nfunction cacheKeyForWebsite(websiteId?: string): string {\n return websiteId ?? '__all__';\n}\n\n/** Cache TTL in milliseconds (30 seconds) */\nconst CACHE_TTL_MS = 30_000;\n\n/**\n * Registers a preset schema. Called at application startup.\n *\n * @param name - Unique schema identifier (e.g., 'country', 'language')\n * @param config - Schema configuration without name and source\n * @throws If schema with name already registered\n */\nexport function registerPresetSchema(\n name: string,\n config: Omit<UnifiedSchemaConfig, 'name' | 'source' | 'titleField'> & { titleField?: string }\n): void {\n if (presetSchemas.has(name)) {\n throw new Error(`Preset schema \"${name}\" is already registered`);\n }\n\n presetSchemas.set(name, {\n ...config,\n name,\n titleField: config.titleField ?? inferTitleFieldFromZodSchema(config.schema),\n source: 'preset',\n });\n}\n\n/**\n * Gets a schema by name (preset or custom).\n * Cached custom schemas are checked first, then presets.\n * If cache is stale/missing, custom schemas are refreshed to preserve override behavior.\n *\n * @param name - Schema name to look up\n * @param supabase - Database client for loading custom schemas\n * @returns Schema configuration or null if not found\n */\nexport async function getSchema(\n name: string,\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<UnifiedSchemaConfig | null> {\n const key = cacheKeyForWebsite(websiteId);\n const presetSchema = presetSchemas.get(name) ?? null;\n\n // Fast path: use current cache first (custom overrides presets).\n const cachedCustomSchema = customSchemaCacheByWebsite.get(key)?.get(name);\n if (cachedCustomSchema) {\n return cachedCustomSchema;\n }\n\n // If preset exists and cache is fresh with no custom override, avoid DB roundtrip.\n const cacheTime = customSchemasCacheTimeByWebsite.get(key) ?? null;\n const cacheIsFresh = cacheTime !== null && Date.now() - cacheTime < CACHE_TTL_MS;\n if (presetSchema && cacheIsFresh) {\n return presetSchema;\n }\n\n // Load/refresh custom schemas if needed.\n await loadCustomSchemas(supabase, websiteId);\n const refreshedCustomSchema = customSchemaCacheByWebsite.get(key)?.get(name);\n if (refreshedCustomSchema) {\n return refreshedCustomSchema;\n }\n\n return presetSchema;\n}\n\n/**\n * Gets all registered schemas (presets + active custom).\n *\n * @param supabase - Database client for loading custom schemas\n * @returns Array of all available schema configurations\n */\nexport async function getAllSchemas(\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<UnifiedSchemaConfig[]> {\n await loadCustomSchemas(supabase, websiteId);\n\n const scopedCache = customSchemaCacheByWebsite.get(cacheKeyForWebsite(websiteId));\n const merged = new Map<string, UnifiedSchemaConfig>();\n\n for (const preset of presetSchemas.values()) {\n merged.set(preset.name, preset);\n }\n\n for (const custom of scopedCache?.values() ?? []) {\n merged.set(custom.name, custom);\n }\n\n return [...merged.values()];\n}\n\n/**\n * Gets summary info for all schemas (without full Zod schemas).\n * Useful for sidebar/listing where full validation isn't needed.\n */\nexport async function getAllSchemaSummaries(\n supabase: TypedSupabaseClient,\n websiteId?: string\n): Promise<SchemaSummary[]> {\n const schemas = await getAllSchemas(supabase, websiteId);\n\n return schemas.map((s) => ({\n id: s.id,\n name: s.name,\n displayName: s.displayName,\n description: s.description,\n icon: s.icon,\n source: s.source,\n version: s.version,\n routeSlugField: s.routeSlugField,\n }));\n}\n\n/**\n * Loads custom schemas from database into cache.\n * Uses TTL-based caching to avoid excessive database queries.\n *\n * @param supabase - Database client\n * @param force - If true, bypasses cache TTL\n */\nasync function loadCustomSchemas(\n supabase: TypedSupabaseClient,\n websiteId?: string,\n force = false\n): Promise<void> {\n const now = Date.now();\n const key = cacheKeyForWebsite(websiteId);\n const cacheTime = customSchemasCacheTimeByWebsite.get(key) ?? null;\n\n // Use cache if valid and not forced\n if (!force && cacheTime && now - cacheTime < CACHE_TTL_MS) {\n return;\n }\n\n let data: CustomSchemaRow[] | null = null;\n let error: unknown = null;\n\n try {\n let query = supabase\n .from('custom_schemas')\n .select(\n 'id, name, display_name, description, fields, title_field, route_slug_field, icon, version, state, updated_at'\n )\n .eq('state', 'active');\n if (websiteId) {\n query = query.eq('website_id', websiteId);\n }\n const result = (await query) as { data: CustomSchemaRow[] | null; error: unknown };\n data = result.data;\n error = result.error;\n } catch (err) {\n console.error('Failed to load custom schemas:', err);\n // Back off repeated attempts for this scope when loading fails.\n customSchemasCacheTimeByWebsite.set(key, now);\n // Keep stale cache on error rather than clearing\n return;\n }\n\n if (error) {\n console.error('Failed to load custom schemas:', error);\n // Back off repeated attempts for this scope when loading fails.\n customSchemasCacheTimeByWebsite.set(key, now);\n // Keep stale cache on error rather than clearing\n return;\n }\n\n // Rebuild cache\n const scopedCache = new Map<string, UnifiedSchemaConfig>();\n\n for (const row of data ?? []) {\n try {\n const fields = row.fields as FieldDefinition[];\n const zodSchema = rehydrateSchema(fields);\n const resolvedTitleField = resolveTitleFieldFromFields({\n fields,\n titleField: row.title_field ?? undefined,\n routeSlugField: row.route_slug_field ?? undefined,\n });\n\n const hasExistingTitleField = fields.some((f) => f.name === 'title');\n const schemaWithResolvedTitle =\n resolvedTitleField === undefined && !hasExistingTitleField\n ? zodSchema.extend({ title: z.string().optional() })\n : zodSchema;\n\n const finalTitleField =\n resolvedTitleField ?? (hasExistingTitleField ? 'title' : (fields[0]?.name ?? 'title'));\n\n scopedCache.set(row.name, {\n id: row.id,\n name: row.name,\n schema: schemaWithResolvedTitle,\n displayName: row.display_name,\n description: row.description ?? undefined,\n titleField: finalTitleField,\n routeSlugField: row.route_slug_field ?? undefined,\n icon: row.icon ?? undefined,\n source: 'custom',\n version: row.version,\n updatedAt: row.updated_at ?? null,\n });\n } catch (err) {\n // Log but don't fail - skip invalid schemas\n console.error(`Failed to rehydrate schema \"${row.name}\":`, err);\n }\n }\n\n customSchemaCacheByWebsite.set(key, scopedCache);\n customSchemasCacheTimeByWebsite.set(key, now);\n}\n\n/**\n * Invalidates the custom schema cache.\n * Call this after creating, updating, or deleting custom schemas.\n */\nexport function invalidateCustomSchemaCache(websiteId?: string): void {\n if (websiteId) {\n const key = cacheKeyForWebsite(websiteId);\n customSchemasCacheTimeByWebsite.delete(key);\n customSchemaCacheByWebsite.delete(key);\n } else {\n customSchemasCacheTimeByWebsite.clear();\n customSchemaCacheByWebsite.clear();\n }\n\n onInvalidate?.(websiteId);\n}\n\n/**\n * Forces a reload of custom schemas from database.\n */\nexport async function refreshCustomSchemas(supabase: TypedSupabaseClient): Promise<void> {\n await loadCustomSchemas(supabase, undefined, true);\n}\n\n/**\n * Checks if a schema name is a preset schema.\n */\nexport function isPresetSchema(name: string): boolean {\n return presetSchemas.has(name);\n}\n\n/**\n * Gets all preset schema names.\n */\nexport function getPresetSchemaNames(): string[] {\n return [...presetSchemas.keys()];\n}\n\n/**\n * Clears all registrations. FOR TESTING ONLY.\n */\nexport function clearUnifiedRegistry(): void {\n presetSchemas.clear();\n customSchemaCacheByWebsite.clear();\n customSchemasCacheTimeByWebsite.clear();\n}\n\n/**\n * Creates a hash for a custom schema from its fields.\n * Used for tracking schema versions in documents.\n */\nexport function createCustomSchemaHash(fields: FieldDefinition[]): string {\n const zodSchema = rehydrateSchema(fields);\n return createSchemaHash(zodSchema);\n}\n","/**\n * Zod Schema Rehydration\n *\n * Converts JSON field definitions (stored in database) into runtime Zod schemas.\n * This enables custom schemas to be validated identically to preset schemas.\n *\n * @example\n * ```typescript\n * const fields: FieldDefinition[] = [\n * { name: 'title', type: 'string', required: true, constraints: { minLength: 1 } },\n * { name: 'price', type: 'number', required: true, constraints: { min: 0 } },\n * ];\n * const schema = rehydrateSchema(fields);\n * // Equivalent to: z.object({ title: z.string().min(1), price: z.number().min(0) })\n * ```\n */\n\nimport { type ZodObject, type ZodRawShape, type ZodType, z } from 'zod';\nimport { ImageReferenceSchema } from '../fields/complex/media';\nimport { richtext as createRichtextField } from '../fields/complex/richtext';\nimport { validateSafeRegex } from '../utils/safe-regex';\nimport type { FieldConstraints, FieldDefinition, FieldType } from './schema-types';\n\n/** Error thrown when field definition cannot be rehydrated */\nexport class RehydrationError extends Error {\n constructor(\n message: string,\n public readonly fieldName?: string,\n public readonly fieldType?: FieldType\n ) {\n super(message);\n this.name = 'RehydrationError';\n }\n}\n\n/**\n * Rehydrates a single field definition into a Zod schema\n */\nexport function rehydrateField(field: FieldDefinition): ZodType {\n try {\n let schema = createBaseSchema(field.type, field.constraints);\n\n if (!field.required) {\n schema = schema.optional();\n }\n\n return schema;\n } catch (err) {\n throw new RehydrationError(\n `Failed to rehydrate field \"${field.name}\": ${err instanceof Error ? err.message : 'Unknown error'}`,\n field.name,\n field.type\n );\n }\n}\n\n/**\n * Creates the base Zod schema for a given field type\n */\nfunction createBaseSchema(type: FieldType, constraints?: FieldConstraints): ZodType {\n switch (type) {\n case 'string':\n return applyStringConstraints(z.string(), constraints);\n\n case 'richtext':\n return createRichtextField({ label: 'Rich Text', required: true });\n\n case 'number':\n return applyNumberConstraints(z.number(), constraints);\n\n case 'boolean':\n return z.boolean();\n\n case 'image':\n return ImageReferenceSchema;\n\n case 'icon':\n // Icon name stored as \"variant:Name\" (e.g. \"outline:StarIcon\")\n return z.string().max(50);\n\n case 'date':\n return z.iso.date('Invalid date format. Expected YYYY-MM-DD');\n\n case 'datetime':\n return z.iso.datetime({\n offset: true,\n message: 'Invalid datetime format. Expected ISO 8601',\n });\n\n case 'url':\n return applyStringConstraints(z.string(), constraints).pipe(z.url('Invalid URL format'));\n\n case 'email':\n return applyStringConstraints(z.string(), constraints).pipe(z.email('Invalid email format'));\n\n case 'enum': {\n const values = constraints?.enumValues;\n if (!values || values.length === 0) {\n throw new Error('Enum field requires at least one enumValues in constraints');\n }\n return z.enum(values as [string, ...string[]]);\n }\n\n case 'reference':\n // Reference fields store inline objects (the referenced schema's field values)\n return z.record(z.string(), z.unknown());\n\n case 'array': {\n const itemType = constraints?.arrayItemType ?? 'string';\n const itemSchema =\n itemType === 'reference'\n ? z.record(z.string(), z.unknown())\n : createPrimitiveSchema(itemType);\n return applyArrayConstraints(z.array(itemSchema), constraints);\n }\n\n default:\n throw new Error(`Unknown field type: ${type}`);\n }\n}\n\n/**\n * Creates a Zod schema for primitive array item types\n */\nfunction createPrimitiveSchema(type: 'string' | 'number' | 'boolean'): ZodType {\n switch (type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'boolean':\n return z.boolean();\n default:\n throw new Error(`Unsupported array item type: ${type}`);\n }\n}\n\n/**\n * Applies string-specific constraints to a Zod string schema\n */\nfunction applyStringConstraints(schema: z.ZodString, constraints?: FieldConstraints): z.ZodString {\n if (!constraints) return schema;\n\n // Validate minLength <= maxLength when both are set\n if (\n constraints.minLength !== undefined &&\n constraints.maxLength !== undefined &&\n constraints.minLength > constraints.maxLength\n ) {\n throw new Error(\n `Invalid string constraints: minLength (${constraints.minLength}) cannot be greater than maxLength (${constraints.maxLength})`\n );\n }\n\n let result = schema;\n\n if (constraints.minLength !== undefined) {\n result = result.min(\n constraints.minLength,\n `Must be at least ${constraints.minLength} characters`\n );\n }\n if (constraints.maxLength !== undefined) {\n result = result.max(\n constraints.maxLength,\n `Must be at most ${constraints.maxLength} characters`\n );\n }\n if (constraints.pattern) {\n // Validate pattern is safe (prevents ReDoS attacks)\n const safetyError = validateSafeRegex(constraints.pattern);\n if (safetyError) {\n throw new Error(safetyError);\n }\n try {\n result = result.regex(new RegExp(constraints.pattern), 'Invalid format');\n } catch {\n throw new Error(`Invalid regex pattern: ${constraints.pattern}`);\n }\n }\n\n return result;\n}\n\n/**\n * Applies number-specific constraints to a Zod number schema\n */\nfunction applyNumberConstraints(schema: z.ZodNumber, constraints?: FieldConstraints): z.ZodNumber {\n if (!constraints) return schema;\n\n // Validate min <= max when both are set\n if (\n constraints.min !== undefined &&\n constraints.max !== undefined &&\n constraints.min > constraints.max\n ) {\n throw new Error(\n `Invalid number constraints: min (${constraints.min}) cannot be greater than max (${constraints.max})`\n );\n }\n\n let result = schema;\n\n if (constraints.min !== undefined) {\n result = result.min(constraints.min, `Must be at least ${constraints.min}`);\n }\n if (constraints.max !== undefined) {\n result = result.max(constraints.max, `Must be at most ${constraints.max}`);\n }\n if (constraints.integer) {\n result = result.int('Must be an integer');\n }\n\n return result;\n}\n\n/**\n * Applies array-specific constraints to a Zod array schema\n */\nfunction applyArrayConstraints(\n schema: z.ZodArray<ZodType>,\n constraints?: FieldConstraints\n): z.ZodArray<ZodType> {\n if (!constraints) return schema;\n\n // Validate minItems <= maxItems when both are set\n if (\n constraints.minItems !== undefined &&\n constraints.maxItems !== undefined &&\n constraints.minItems > constraints.maxItems\n ) {\n throw new Error(\n `Invalid array constraints: minItems (${constraints.minItems}) cannot be greater than maxItems (${constraints.maxItems})`\n );\n }\n\n let result = schema;\n\n if (constraints.minItems !== undefined) {\n result = result.min(constraints.minItems, `Must have at least ${constraints.minItems} items`);\n }\n if (constraints.maxItems !== undefined) {\n result = result.max(constraints.maxItems, `Must have at most ${constraints.maxItems} items`);\n }\n\n return result;\n}\n\n/**\n * Rehydrates a complete custom schema from field definitions into a Zod object schema\n *\n * @param fields - Array of field definitions from database\n * @returns Zod object schema that validates documents\n * @throws RehydrationError if any field cannot be rehydrated\n *\n * @example\n * ```typescript\n * const fields = [\n * { name: 'model', type: 'string', required: true },\n * { name: 'price', type: 'number', required: false },\n * ];\n * const schema = rehydrateSchema(fields);\n * schema.parse({ model: 'MacBook Pro' }); // Valid\n * schema.parse({ model: 'MacBook Pro', price: 1999 }); // Valid\n * schema.parse({ price: 1999 }); // Throws - model is required\n * ```\n */\nexport function rehydrateSchema(fields: FieldDefinition[]): ZodObject<ZodRawShape> {\n if (!Array.isArray(fields) || fields.length === 0) {\n throw new RehydrationError('Schema must have at least one field');\n }\n\n const shape: Record<string, ZodType> = {};\n const seenNames = new Set<string>();\n\n for (const field of fields) {\n // Validate field name uniqueness\n if (seenNames.has(field.name)) {\n throw new RehydrationError(`Duplicate field name: \"${field.name}\"`);\n }\n seenNames.add(field.name);\n\n // Validate field name format\n if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(field.name)) {\n throw new RehydrationError(\n `Invalid field name \"${field.name}\": must start with a letter and contain only alphanumeric characters and underscores`,\n field.name\n );\n }\n\n shape[field.name] = rehydrateField(field);\n }\n\n return z.object(shape);\n}\n\n/**\n * Validates that field definitions can be rehydrated without actually building the schema.\n * Useful for pre-validation before database insertion.\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateFieldDefinitions(fields: FieldDefinition[]): string | null {\n try {\n rehydrateSchema(fields);\n return null;\n } catch (err) {\n return err instanceof Error ? err.message : 'Unknown validation error';\n }\n}\n","/**\n * Image and file field factories.\n *\n * The image() factory creates an ImageReference schema that:\n * - References an ImageAsset by ID\n * - Stores context-specific alt text (required for accessibility)\n * - Supports optional hotspot (focal point) and crop settings\n */\n\nimport { z } from 'zod';\n\nimport type { FieldMeta } from '../../types';\nimport {\n DimensionSchema,\n FileSizeSchema,\n MAX_DIMENSION,\n MAX_FILE_SIZE,\n MIN_DIMENSION,\n MimeTypeSchema,\n} from '../../validation/image';\n\n// =============================================================================\n// ImageAsset Schema (Public API type)\n// =============================================================================\n\n/**\n * Public API schema for image assets.\n *\n * This is the camelCase API representation. The database uses snake_case\n * (ImageAssetRow in db/image-asset-types.ts). Conversion between formats\n * should happen at the API boundary.\n *\n * Reuses validation schemas from validation/image.ts to ensure consistency.\n */\nexport const ImageAssetSchema = z.object({\n /** UUID primary key */\n id: z.uuid(),\n /** R2/S3 storage URL for the original file */\n url: z.url(),\n /** Image width in pixels */\n width: DimensionSchema,\n /** Image height in pixels */\n height: DimensionSchema,\n /** Original filename from upload */\n originalFilename: z.string().min(1).max(255),\n /** MIME type (only web-safe formats allowed) */\n mimeType: MimeTypeSchema,\n /** File size in bytes */\n fileSize: FileSizeSchema,\n /** Base64-encoded tiny preview for blur-up loading */\n lqip: z.string().optional(),\n});\n\nexport type ImageAsset = z.infer<typeof ImageAssetSchema>;\n\n// =============================================================================\n// ImageReference Schema (Asset-reference model)\n// =============================================================================\n\n/**\n * Hotspot defines the focal point of an image.\n * Coordinates are fractions (0-1) from top-left.\n */\nexport const HotspotSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n});\n\nexport type Hotspot = z.infer<typeof HotspotSchema>;\n\n/**\n * Crop defines the region to extract from the image.\n * - x, y: Top-left coordinate of the crop region in pixels\n * - width, height: Size of the crop region in pixels\n * All values are positive integers representing pixel coordinates/dimensions.\n */\nexport const CropSchema = z.object({\n /** X coordinate of top-left corner in pixels */\n x: z.number().int().nonnegative(),\n /** Y coordinate of top-left corner in pixels */\n y: z.number().int().nonnegative(),\n /** Width of crop region in pixels (must be > 0) */\n width: z.number().int().positive(),\n /** Height of crop region in pixels (must be > 0) */\n height: z.number().int().positive(),\n});\n\nexport type Crop = z.infer<typeof CropSchema>;\n\n/**\n * ImageReference is what blocks store.\n * It points to an ImageAsset and adds context-specific metadata.\n */\nexport const ImageReferenceSchema = z.object({\n // Alt text is REQUIRED for accessibility\n alt: z.string().min(1, 'Alt text is required for accessibility'),\n\n // Optional metadata\n caption: z.string().max(500).optional(),\n attribution: z.string().max(255).optional(),\n\n // Reference to the ImageAsset with stored transformation\n _asset: z.object({\n id: z.uuid(),\n transformation: z.string().nullable().optional(),\n }),\n});\n\nexport type ImageReference = z.infer<typeof ImageReferenceSchema>;\n\n// =============================================================================\n// Image Field Factory\n// =============================================================================\n\nexport interface ImageFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n accept?: string;\n maxSize?: number;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n aspectRatio?: number;\n}\n\n/**\n * Create an image field with metadata.\n *\n * @example\n * const featuredImage = image({\n * label: 'Featured Image',\n * required: true,\n * accept: 'image/jpeg, image/png',\n * maxSize: 5 * 1024 * 1024,\n * });\n *\n * // Type of the value:\n * // {\n * // alt: string;\n * // caption?: string;\n * // attribution?: string;\n * // _asset: { id: string; transformation?: string | null };\n * // }\n */\nexport function image(options: ImageFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'image-uploader',\n required: options.required,\n description: options.description,\n options: {\n accept: options.accept ?? 'image/jpeg, image/png, image/webp',\n maxSize: options.maxSize ?? MAX_FILE_SIZE, // 10MB default\n minWidth: options.minWidth ?? MIN_DIMENSION,\n minHeight: options.minHeight ?? MIN_DIMENSION,\n maxWidth: options.maxWidth ?? MAX_DIMENSION,\n maxHeight: options.maxHeight ?? MAX_DIMENSION,\n aspectRatio: options.aspectRatio,\n },\n };\n\n // Use the new ImageReferenceSchema instead of URL-only\n const result = options.required ? ImageReferenceSchema : ImageReferenceSchema.nullish();\n\n return result.meta(meta);\n}\n\n// =============================================================================\n// File Field\n// =============================================================================\n\nexport interface FileFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n accept?: string;\n maxSize?: number;\n}\n\nconst fileSchema = z.object({\n url: z.url(),\n name: z.string(),\n size: z.number().int().positive(),\n type: z.string(),\n});\n\n/**\n * Create a file field with metadata.\n */\nexport function file(options: FileFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'file-uploader',\n required: options.required,\n description: options.description,\n options: {\n accept: options.accept ?? '*/*',\n maxSize: options.maxSize,\n },\n };\n\n const result = options.required ? fileSchema : fileSchema.nullish();\n return result.meta(meta);\n}\n","/**\n * Image Validation Utilities\n *\n * Provides validation for:\n * - File type (MIME type checking)\n * - File size (configurable limits)\n * - Image dimensions (width/height constraints)\n */\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp'] as const;\nexport type ImageMimeType = (typeof ALLOWED_MIME_TYPES)[number];\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\nexport const MIN_FILE_SIZE = 1024; // 1KB (avoid empty/corrupt files)\n\nexport const MAX_DIMENSION = 8192; // 8K resolution\nexport const MIN_DIMENSION = 10; // Minimum useful size\n\n// =============================================================================\n// Zod Schemas\n// =============================================================================\n\nexport const MimeTypeSchema = z.enum(ALLOWED_MIME_TYPES);\n\nexport const FileSizeSchema = z\n .number()\n .int()\n .min(MIN_FILE_SIZE, `File too small. Minimum: ${MIN_FILE_SIZE} bytes`)\n .max(MAX_FILE_SIZE, `File too large. Maximum: ${MAX_FILE_SIZE / 1024 / 1024}MB`);\n\nexport const DimensionSchema = z\n .number()\n .int()\n .min(MIN_DIMENSION, `Dimension too small. Minimum: ${MIN_DIMENSION}px`)\n .max(MAX_DIMENSION, `Dimension too large. Maximum: ${MAX_DIMENSION}px`);\n\n/**\n * Schema for upload request validation.\n */\nexport const UploadRequestSchema = z.object({\n filename: z\n .string()\n .min(1, 'Filename is required')\n .max(255, 'Filename too long')\n .regex(/^[^<>:\"/\\\\|?*]+$/, 'Filename contains invalid characters'),\n mimeType: MimeTypeSchema,\n fileSize: FileSizeSchema,\n});\n\nexport type UploadRequest = z.infer<typeof UploadRequestSchema>;\n\n/**\n * Schema for confirming upload with dimensions.\n * assetId is optional - if not provided, the server will generate a UUID.\n */\nexport const ConfirmUploadSchema = z.object({\n assetId: z.uuid().optional(),\n width: DimensionSchema,\n height: DimensionSchema,\n});\n\nexport type ConfirmUpload = z.infer<typeof ConfirmUploadSchema>;\n\n// =============================================================================\n// Validation Functions\n// =============================================================================\n\nexport interface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Validate file type by MIME type.\n */\nexport function validateMimeType(mimeType: string): ValidationResult {\n const result = MimeTypeSchema.safeParse(mimeType);\n if (result.success) {\n return { valid: true };\n }\n return {\n valid: false,\n error: `File type not supported. Use JPEG, PNG, or WebP.`,\n };\n}\n\n/**\n * Validate file size.\n */\nexport function validateFileSize(size: number): ValidationResult {\n if (size < MIN_FILE_SIZE) {\n return {\n valid: false,\n error: `File appears to be empty or corrupt.`,\n };\n }\n if (size > MAX_FILE_SIZE) {\n const sizeMB = (size / 1024 / 1024).toFixed(1);\n return {\n valid: false,\n error: `File too large (${sizeMB}MB). Maximum: 10 MB.`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Validate image dimensions.\n */\nexport function validateDimensions(width: number, height: number): ValidationResult {\n if (width < MIN_DIMENSION || height < MIN_DIMENSION) {\n return {\n valid: false,\n error: `Image too small. Minimum: ${MIN_DIMENSION}x${MIN_DIMENSION}px.`,\n };\n }\n if (width > MAX_DIMENSION || height > MAX_DIMENSION) {\n return {\n valid: false,\n error: `Image too large. Maximum: ${MAX_DIMENSION}x${MAX_DIMENSION}px.`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Validate complete upload request.\n */\nexport function validateUploadRequest(\n request: unknown\n): { valid: true; data: UploadRequest } | { valid: false; error: string } {\n const result = UploadRequestSchema.safeParse(request);\n if (result.success) {\n return { valid: true, data: result.data };\n }\n const firstIssue = result.error.issues[0];\n return {\n valid: false,\n error: firstIssue?.message ?? 'Invalid upload request',\n };\n}\n\n// =============================================================================\n// File Extension Utilities\n// =============================================================================\n\nconst MIME_TO_EXT: Record<ImageMimeType, string> = {\n 'image/jpeg': 'jpg',\n 'image/png': 'png',\n 'image/webp': 'webp',\n};\n\nconst EXT_TO_MIME: Record<string, ImageMimeType> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n webp: 'image/webp',\n};\n\n/**\n * Get file extension from MIME type.\n */\nexport function getExtensionFromMime(mimeType: ImageMimeType | string): string {\n return MIME_TO_EXT[mimeType as ImageMimeType] ?? 'bin';\n}\n\n/**\n * Get MIME type from file extension.\n */\nexport function getMimeFromExtension(ext: string): ImageMimeType | undefined {\n return EXT_TO_MIME[ext.toLowerCase()];\n}\n\n/**\n * Extract extension from filename.\n */\nexport function getExtensionFromFilename(filename: string): string {\n const parts = filename.split('.');\n return parts.pop()?.toLowerCase?.() ?? '';\n}\n\n/**\n * Sanitize filename for storage.\n * Removes special characters, preserves extension.\n */\nexport function sanitizeFilename(filename: string): string {\n // Get extension\n const ext = getExtensionFromFilename(filename);\n\n // Get base name without extension\n const base = filename.slice(0, filename.length - ext.length - 1);\n\n // Sanitize: lowercase, replace spaces and special chars\n const sanitized = base\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 50); // Limit length\n\n return ext ? `${sanitized}.${ext}` : sanitized;\n}\n","/**\n * Rich text field factory.\n *\n * Accepts markdown strings for Lexical-based editors or Portable Text arrays.\n */\n\nimport { z } from 'zod';\nimport type { FieldMeta } from '../../types';\n\nexport type FormattingOption =\n | 'bold'\n | 'italic'\n | 'underline'\n | 'strikethrough'\n | 'link'\n | 'heading'\n | 'list'\n | 'blockquote'\n | 'code'\n | 'image';\n\nexport interface RichtextFieldOptions {\n label: string;\n description?: string;\n required?: boolean;\n formatting?: FormattingOption[];\n}\n\n// Portable Text node types\nconst textNodeSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n marks: z.array(z.string()).optional(),\n});\n\nconst blockSchema: z.ZodType<unknown> = z.lazy(() =>\n z.object({\n type: z.string(),\n children: z.array(z.union([textNodeSchema, blockSchema])).optional(),\n marks: z.array(z.string()).optional(),\n level: z.number().optional(),\n url: z.string().optional(),\n })\n);\n\nconst richtextSchema = z.union([z.array(blockSchema), z.string()]);\n\n/**\n * Create a rich text field with metadata.\n *\n * @example\n * const body = richtext({\n * label: 'Content',\n * required: true,\n * formatting: ['bold', 'italic', 'link', 'heading', 'list'],\n * });\n */\nexport function richtext(options: RichtextFieldOptions) {\n const meta: FieldMeta = {\n label: options.label,\n component: 'richtext',\n required: options.required,\n description: options.description,\n options: {\n formatting: options.formatting ?? ['bold', 'italic', 'link', 'heading', 'list'],\n format: 'markdown',\n },\n };\n\n const result = options.required ? richtextSchema : richtextSchema.optional();\n return result.meta(meta);\n}\n","/**\n * Safe regex validation utilities.\n *\n * Prevents ReDoS (Regular Expression Denial of Service) attacks by\n * detecting potentially dangerous regex patterns.\n */\n\nimport safeRegex from 'safe-regex2';\n\n/**\n * Validates that a regex pattern is safe to use.\n * Uses safe-regex2 library to detect ReDoS vulnerabilities.\n *\n * @param pattern - The regex pattern to validate\n * @returns null if safe, error message if potentially dangerous\n */\nexport function validateSafeRegex(pattern: string): string | null {\n // Limit pattern length to prevent extremely long patterns\n if (pattern.length > 500) {\n return 'Regex pattern is too long (max 500 characters)';\n }\n\n // Use safe-regex2 to detect ReDoS vulnerabilities\n if (!safeRegex(pattern)) {\n return 'Regex pattern is potentially unsafe (ReDoS risk)';\n }\n\n // Try to compile the regex to ensure it's valid\n try {\n new RegExp(pattern);\n } catch (err) {\n return `Invalid regex: ${err instanceof Error ? err.message : 'Unknown'}`;\n }\n\n return null;\n}\n","/**\n * Schema hashing utility for document versioning.\n *\n * Creates a deterministic hash of a Zod schema's shape.\n * Used to detect when documents need migration after schema changes.\n */\n\nimport hash from 'object-hash';\nimport type { ZodObject, ZodRawShape, ZodTypeAny } from 'zod';\n\n/**\n * Unwraps optional, default, and nullable wrappers to get the inner type.\n */\nfunction unwrapZodType(zodType: ZodTypeAny): ZodTypeAny {\n const current = zodType;\n const def = current._def;\n\n // Unwrap optional/nullable/default wrappers\n if ('innerType' in def && def.innerType) {\n return unwrapZodType(def.innerType as ZodTypeAny);\n }\n\n return current;\n}\n\n/**\n * Gets the type name from a Zod type, unwrapping wrappers first.\n * In Zod v4, types are stored in _def.type (not typeName).\n */\nfunction getZodTypeName(zodType: ZodTypeAny): string {\n const unwrapped = unwrapZodType(zodType);\n const def = unwrapped._def;\n\n if (!def) return 'unknown';\n\n // Zod v4 uses _def.type for primitive types\n if ('type' in def && typeof def.type === 'string') {\n return def.type as string;\n }\n\n // Fallback: check for typeName (older Zod versions or complex types)\n if ('typeName' in def) {\n return def.typeName as string;\n }\n\n return 'unknown';\n}\n\n/**\n * Creates a deterministic hash of a Zod schema's shape.\n *\n * Uses object-hash library for canonical key ordering, ensuring\n * the same hash is produced regardless of property definition order.\n *\n * @param schema - A Zod object schema\n * @returns MD5 hash string of the schema shape\n */\nexport function createSchemaHash(schema: ZodObject<ZodRawShape>): string {\n const shape = schema.shape;\n\n // Create a serializable representation of the schema\n const schemaDefinition = Object.entries(shape).reduce(\n (acc, [key, zodType]) => {\n const typeName = getZodTypeName(zodType as ZodTypeAny);\n const unwrapped = unwrapZodType(zodType as ZodTypeAny);\n const unwrappedDef = unwrapped._def as unknown as Record<string, unknown>;\n\n // Check if optional (method exists on ZodTypeAny in Zod v4)\n const isOptional =\n 'isOptional' in zodType && typeof zodType.isOptional === 'function'\n ? zodType.isOptional()\n : false;\n\n acc[key] = {\n type: typeName,\n optional: isOptional,\n // Include nested shape for objects\n ...(typeName === 'object' &&\n 'shape' in unwrappedDef &&\n typeof unwrappedDef.shape === 'function' && {\n shape: Object.keys((unwrappedDef.shape as () => Record<string, unknown>)()),\n }),\n };\n return acc;\n },\n {} as Record<string, unknown>\n );\n\n return hash(schemaDefinition, {\n algorithm: 'md5',\n respectType: false,\n unorderedArrays: false,\n });\n}\n","/**\n * Country schema-specific validation.\n *\n * Validates that language codes exist in the database.\n */\n\nimport { TRPCError } from '@trpc/server';\nimport type { ReferenceValue } from '../../db/document-types';\nimport { isReference } from '../../db/document-types';\nimport type { TypedSupabaseClient } from '../../db/types';\n\n/**\n * Validate country content, specifically checking that language codes exist.\n *\n * @param content - Validated country content\n * @param supabase - Supabase client for database queries\n * @throws {TRPCError} If validation fails\n */\nexport async function validateCountryContent(\n content: unknown,\n supabase: TypedSupabaseClient\n): Promise<void> {\n const countryContent = content as {\n languages?: Array<string | ReferenceValue>;\n };\n const languages = Array.isArray(countryContent.languages) ? countryContent.languages : [];\n\n const languageCodes = languages.filter((lang): lang is string => typeof lang === 'string');\n const languageReferences = languages.filter(isReference);\n\n // Validate legacy reference format points to language schema\n const invalidReferences = languageReferences.filter((ref) => ref._schema !== 'language');\n if (invalidReferences.length > 0) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Language references must target the language schema',\n });\n }\n\n // Only perform database check when using code-based languages\n if (languageCodes.length > 0) {\n const { data: allLanguages, error: langError } = await supabase\n .from('documents')\n .select('content')\n .eq('schema_name', 'language');\n\n if (langError) {\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to validate language codes',\n cause: langError,\n });\n }\n\n const existingCodes = new Set(\n (allLanguages || [])\n .map((lang) => {\n const langContent = lang.content as { code?: string };\n return langContent?.code;\n })\n .filter((code): code is string => typeof code === 'string' && code.length > 0)\n );\n\n const missingCodes = languageCodes.filter((code) => !existingCodes.has(code));\n\n if (missingCodes.length > 0) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Language codes not found: ${missingCodes.join(', ')}. Please create language documents with these codes first.`,\n });\n }\n }\n}\n","/**\n * Field Definitions JSON Parser & Validator\n *\n * Accepts three JSON formats:\n *\n * 1. Sample data — { schemaName: { fieldName: exampleValue, ... }, ... }\n * Types are inferred from the example values. camelCase keys are\n * converted to snake_case. Arrays of objects create sub-schemas\n * automatically. Arrays of objects may nest up to MAX_SAMPLE_DEPTH levels deep.\n *\n * 2. FieldDefinition array — [ { name, type, required, ... }, ... ]\n * Single schema, exact FieldDefinition[] structure.\n *\n * 3. Multi-schema FieldDefinition — { schemaName: [ { name, type, required }, ... ], ... }\n * Multiple schemas in the explicit FieldDefinition[] format.\n *\n * Format is detected automatically from the structure.\n */\n\nimport { z } from 'zod';\nimport type { FieldDefinition } from './schema-types';\n\n// ---------------------------------------------------------------------------\n// FieldDefinition Zod schema (for formats 2 & 3)\n// ---------------------------------------------------------------------------\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/;\n\nconst fieldConstraintsSchema = z.object({\n minLength: z.number().int().min(0).optional(),\n maxLength: z.number().int().min(0).optional(),\n pattern: z.string().max(500).optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n integer: z.boolean().optional(),\n enumValues: z.array(z.string()).optional(),\n arrayItemType: z.enum(['string', 'number', 'boolean', 'reference']).optional(),\n minItems: z.number().int().min(0).optional(),\n maxItems: z.number().int().min(0).optional(),\n refSchema: z.string().regex(SNAKE_CASE, 'refSchema must be snake_case').optional(),\n});\n\nconst fieldDefinitionSchema = z.object({\n name: z\n .string()\n .regex(SNAKE_CASE, 'must be snake_case (lowercase letters, digits, underscores only)'),\n type: z.enum([\n 'string',\n 'richtext',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'url',\n 'email',\n 'enum',\n 'reference',\n 'array',\n 'image',\n 'icon',\n ]),\n displayName: z.string().optional(),\n description: z.string().optional(),\n required: z.boolean(),\n constraints: fieldConstraintsSchema.optional(),\n});\n\nconst fieldArraySchema = z\n .array(fieldDefinitionSchema)\n .min(1, 'Schema must have at least one field');\n\nconst multiSchemaFieldDefSchema = z.record(\n z.string().regex(SNAKE_CASE, 'schema name must be snake_case'),\n fieldArraySchema\n);\n\n// ---------------------------------------------------------------------------\n// Result types\n// ---------------------------------------------------------------------------\nexport interface SingleSchemaResult {\n kind: 'single';\n fields: FieldDefinition[];\n}\n\nexport interface MultiSchemaResult {\n kind: 'multi';\n /** Ordered: sub-schemas appear before the parent schema that references them */\n schemas: Record<string, FieldDefinition[]>;\n}\n\nexport interface ParseFieldDefinitionsError {\n kind: 'error';\n message: string;\n}\n\nexport type ParseFieldDefinitionsResult =\n | SingleSchemaResult\n | MultiSchemaResult\n | ParseFieldDefinitionsError;\n\n// ---------------------------------------------------------------------------\n// Shared constraint / duplicate checks (formats 2 & 3)\n// ---------------------------------------------------------------------------\nfunction checkConstraints(fields: FieldDefinition[], prefix?: string): string | null {\n for (const f of fields) {\n const label = prefix ? `\"${prefix}.${f.name}\"` : `\"${f.name}\"`;\n const c = f.constraints;\n if (!c) {\n if (f.type === 'enum') return `${label}: enum type requires constraints.enumValues`;\n if (f.type === 'array') return `${label}: array type requires constraints.arrayItemType`;\n continue;\n }\n if (f.type === 'enum' && (!c.enumValues || c.enumValues.length === 0)) {\n return `${label}: enum type requires at least one value in constraints.enumValues`;\n }\n if (f.type === 'array' && !c.arrayItemType) {\n return `${label}: array type requires constraints.arrayItemType`;\n }\n if (c.min !== undefined && c.max !== undefined && c.min > c.max) {\n return `${label}: min must be ≤ max`;\n }\n if (c.minLength !== undefined && c.maxLength !== undefined && c.minLength > c.maxLength) {\n return `${label}: minLength must be ≤ maxLength`;\n }\n if (c.minItems !== undefined && c.maxItems !== undefined && c.minItems > c.maxItems) {\n return `${label}: minItems must be ≤ maxItems`;\n }\n }\n return null;\n}\n\nfunction checkDuplicates(fields: FieldDefinition[], prefix?: string): string | null {\n const seen = new Set<string>();\n for (const f of fields) {\n if (seen.has(f.name)) {\n return `Duplicate field name: \"${prefix ? `${prefix}.${f.name}` : f.name}\"`;\n }\n seen.add(f.name);\n }\n return null;\n}\n\nfunction formatZodError(err: z.ZodError): string {\n const issue = err.issues[0];\n if (!issue) return 'Validation error';\n const path = issue.path.length > 0 ? ` (at ${issue.path.join('.')})` : '';\n return `${issue.message}${path}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sample data format helpers (format 1)\n// ---------------------------------------------------------------------------\nfunction camelToSnake(str: string): string {\n return str\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n}\n\nfunction singularize(word: string): string {\n if (word.endsWith('ies')) return `${word.slice(0, -3)}y`;\n if (word.endsWith('ses') || word.endsWith('xes') || word.endsWith('zes'))\n return word.slice(0, -2);\n if (word.endsWith('s') && word.length > 3) return word.slice(0, -1);\n return word;\n}\n\ntype InferResult = FieldDefinition | { error: string };\n\nconst MAX_SAMPLE_DEPTH = 3;\n\n/**\n * Infer a FieldDefinition from a sample value.\n *\n * @param depth - current nesting depth (0 = top-level schema fields).\n * Arrays of objects are allowed up to MAX_SAMPLE_DEPTH levels deep.\n */\nfunction inferFieldFromValue(\n rawFieldName: string,\n value: unknown,\n parentSchemaName: string,\n refSchemas: Map<string, FieldDefinition[]>,\n depth: number\n): InferResult {\n const name = camelToSnake(rawFieldName);\n\n if (typeof value === 'string') return { name, type: 'string', required: true };\n if (typeof value === 'number') return { name, type: 'number', required: true };\n if (typeof value === 'boolean') return { name, type: 'boolean', required: true };\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": direct nested objects are not allowed — represent nested data as an array of references`,\n };\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n // Default empty arrays to string items\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'string' } };\n }\n\n const first = value[0];\n\n if (typeof first === 'string')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'string' } };\n if (typeof first === 'number')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'number' } };\n if (typeof first === 'boolean')\n return { name, type: 'array', required: true, constraints: { arrayItemType: 'boolean' } };\n\n if (first !== null && typeof first === 'object' && !Array.isArray(first)) {\n if (depth >= MAX_SAMPLE_DEPTH) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": maximum nesting depth (${MAX_SAMPLE_DEPTH}) exceeded — arrays of objects cannot be nested this deep`,\n };\n }\n\n // Derive reference schema name: parent_singularField\n const snakeField = camelToSnake(rawFieldName);\n const refName = `${parentSchemaName}_${singularize(snakeField)}`;\n\n if (refSchemas.has(refName)) {\n return {\n error: `Naming conflict: two fields both resolve to sub-schema name \"${refName}\". Rename one of the fields.`,\n };\n }\n\n // Build sub-schema fields from the first array item\n const subFields: FieldDefinition[] = [];\n for (const [subKey, subVal] of Object.entries(first as Record<string, unknown>)) {\n const subField = inferFieldFromValue(subKey, subVal, refName, refSchemas, depth + 1);\n if ('error' in subField) return subField;\n subFields.push(subField);\n }\n\n refSchemas.set(refName, subFields);\n\n return {\n name,\n type: 'array',\n required: true,\n constraints: { arrayItemType: 'reference', refSchema: refName },\n };\n }\n\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": unsupported array item type (arrays must contain strings, numbers, booleans, or objects)`,\n };\n }\n\n if (value === null) {\n return {\n error: `\"${parentSchemaName}.${rawFieldName}\": null values are not supported — omit the field or use a real example value`,\n };\n }\n\n return { error: `\"${parentSchemaName}.${rawFieldName}\": unsupported value type` };\n}\n\nfunction parseSampleData(raw: Record<string, unknown>): ParseFieldDefinitionsResult {\n // ref sub-schemas collected while processing — must be created before their parents\n const refSchemas = new Map<string, FieldDefinition[]>();\n const topSchemas: Record<string, FieldDefinition[]> = {};\n\n for (const [rawSchemaName, schemaData] of Object.entries(raw)) {\n if (schemaData === null || typeof schemaData !== 'object' || Array.isArray(schemaData)) {\n return {\n kind: 'error',\n message: `\"${rawSchemaName}\": schema value must be an object of field examples`,\n };\n }\n\n const schemaName = camelToSnake(rawSchemaName);\n const fields: FieldDefinition[] = [];\n\n for (const [rawFieldName, value] of Object.entries(schemaData as Record<string, unknown>)) {\n const result = inferFieldFromValue(rawFieldName, value, schemaName, refSchemas, 0);\n if ('error' in result) return { kind: 'error', message: result.error };\n fields.push(result);\n }\n\n if (fields.length === 0) {\n return { kind: 'error', message: `\"${rawSchemaName}\": schema must have at least one field` };\n }\n\n topSchemas[schemaName] = fields;\n }\n\n if (Object.keys(topSchemas).length === 0) {\n return { kind: 'error', message: 'No schemas found in the JSON object' };\n }\n\n // sub-schemas first (creation order), then top-level schemas\n const ordered: Record<string, FieldDefinition[]> = {};\n for (const [name, fields] of refSchemas) {\n ordered[name] = fields;\n }\n for (const [name, fields] of Object.entries(topSchemas)) {\n ordered[name] = fields;\n }\n\n return { kind: 'multi', schemas: ordered };\n}\n\n/**\n * Returns true if the object looks like multi-schema FieldDefinition format,\n * i.e. values are arrays of objects with {name, type, required} keys.\n */\nfunction looksLikeFieldDefMultiSchema(obj: Record<string, unknown>): boolean {\n const firstValue = Object.values(obj)[0];\n if (!Array.isArray(firstValue) || firstValue.length === 0) return false;\n const item = firstValue[0];\n return (\n item !== null &&\n typeof item === 'object' &&\n !Array.isArray(item) &&\n 'name' in (item as object) &&\n 'type' in (item as object) &&\n 'required' in (item as object)\n );\n}\n\nexport function parseFieldDefinitionsJson(text: string): ParseFieldDefinitionsResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (e) {\n return { kind: 'error', message: `Invalid JSON: ${(e as Error).message}` };\n }\n\n // --- single schema FieldDefinition[] ---\n if (Array.isArray(parsed)) {\n const result = fieldArraySchema.safeParse(parsed);\n if (!result.success) return { kind: 'error', message: formatZodError(result.error) };\n\n const fields = result.data as FieldDefinition[];\n const dupErr = checkDuplicates(fields);\n if (dupErr) return { kind: 'error', message: dupErr };\n const constraintErr = checkConstraints(fields);\n if (constraintErr) return { kind: 'error', message: constraintErr };\n\n return { kind: 'single', fields };\n }\n\n if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {\n const obj = parsed as Record<string, unknown>;\n\n if (Object.keys(obj).length === 0) {\n return { kind: 'error', message: 'Object must not be empty' };\n }\n\n // --- multi-schema FieldDefinition ---\n if (looksLikeFieldDefMultiSchema(obj)) {\n const result = multiSchemaFieldDefSchema.safeParse(obj);\n if (!result.success) return { kind: 'error', message: formatZodError(result.error) };\n\n const schemas = result.data as Record<string, FieldDefinition[]>;\n for (const [name, fields] of Object.entries(schemas)) {\n const dupErr = checkDuplicates(fields, name);\n if (dupErr) return { kind: 'error', message: dupErr };\n const constraintErr = checkConstraints(fields, name);\n if (constraintErr) return { kind: 'error', message: constraintErr };\n }\n return { kind: 'multi', schemas };\n }\n\n // --- sample data ---\n return parseSampleData(obj);\n }\n\n return {\n kind: 'error',\n message:\n 'JSON must be a sample-data object, a FieldDefinition array, or a multi-schema FieldDefinition object',\n };\n}\n","/**\n * CMS API Client\n *\n * Creates an HTTP-based tRPC client for calling the CMS API.\n * Used in Server Components to fetch routes and blocks from the CMS.\n */\n\nimport type { AppRouter } from '@repo/cms-schema/trpc';\nimport { type CreateTRPCClient, createTRPCClient, httpBatchLink } from '@trpc/client';\nimport superjson from 'superjson';\n\n/** Type alias for the CMS API client */\ntype CmsClient = CreateTRPCClient<AppRouter>;\n\n/**\n * Get the CMS API URL from the provided base URL.\n */\nfunction getCmsApiUrl(cmsUrl: string): string {\n return new URL('/api/trpc', cmsUrl).toString();\n}\n\n/** Unified configuration for all CMS API access */\nexport interface CmsConfig {\n /** CMS API base URL (e.g., 'http://localhost:3000') */\n cmsUrl: string;\n /** API key for authentication */\n apiKey?: string;\n /** Website ID to scope API requests */\n websiteId?: string;\n}\n\n/**\n * Create a custom fetch function that appends API key as query parameter.\n */\nfunction createFetchWithApiKey(apiKey?: string, websiteId?: string) {\n return async (url: URL | RequestInfo, options?: RequestInit): Promise<Response> => {\n let finalUrl = url;\n\n const urlObj = new URL(url.toString());\n if (apiKey) {\n urlObj.searchParams.set('api_key', apiKey);\n }\n if (websiteId) {\n urlObj.searchParams.set('website_id', websiteId);\n }\n if (apiKey || websiteId) {\n finalUrl = urlObj.toString();\n }\n\n const response = await fetch(finalUrl, options);\n\n return response;\n };\n}\n\n/**\n * Create a tRPC client for the CMS API.\n */\nfunction createCmsClient(options: CmsConfig): CmsClient {\n const url = getCmsApiUrl(options.cmsUrl);\n\n return createTRPCClient<AppRouter>({\n links: [\n httpBatchLink({\n url,\n transformer: superjson,\n fetch: createFetchWithApiKey(options.apiKey, options.websiteId),\n }),\n ],\n });\n}\n\nconst clientCache = new Map<string, CmsClient>();\n\nfunction getClientCacheKey(options: CmsConfig): string {\n return `${options.cmsUrl}|${options.apiKey ?? ''}|${options.websiteId ?? ''}`;\n}\n\n/**\n * Get a CMS client for the specified CMS URL.\n * Uses a singleton cache to avoid recreating clients with identical configuration.\n */\nexport function getCmsClient(options: CmsConfig): CmsClient {\n const cacheKey = getClientCacheKey(options);\n\n let client = clientCache.get(cacheKey);\n if (!client) {\n client = createCmsClient(options);\n clientCache.set(cacheKey, client);\n }\n\n return client;\n}\n"],"mappings":"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","names":["types","safeRegex","ok","z","z","z","z","z","z","z","z","z","safeRegex","err","err","z","z"]}
|