@sanity/agent-schema 0.3.0 → 0.4.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/validation/utils.ts","../../src/validation/array.validator.ts","../../src/validation/rules.ts","../../src/validation/customValidators.ts","../../src/validation/document-path-resolver.ts","../../src/validation/language.validator.ts","../../src/validation/object.validator.ts","../../src/validation/path-validation.ts","../../src/validation/portable-text.validator.ts","../../src/validation/primitive.validator.ts","../../src/validation/reference.validator.ts","../../src/validation/requiredFields.ts","../../src/validation/slugCollisions.ts","../../src/validation/special-types.validator.ts","../../src/validation/validate-value.ts","../../src/validation/validateForPublish.ts"],"sourcesContent":["/**\n * Shared utility functions for the validation system.\n */\n\nimport type { ValidationError, ValidationErrorCode } from './types.js'\n\n/**\n * Create a validation error with consistent formatting.\n */\nexport function createError(\n path: string,\n code: ValidationErrorCode,\n message: string,\n received: string,\n expected: string,\n fix: string,\n): ValidationError {\n return { path, code, message, received, expected, fix }\n}\n\n/**\n * Format a value for display in error messages.\n * Handles truncation for long values.\n */\nexport function formatValue(value: unknown): string {\n if (value === undefined) return '(not provided)'\n if (value === null) return 'null'\n\n const type = typeof value\n if (type === 'string') {\n const str = value as string\n if (str.length > 50) {\n return `\"${str.slice(0, 47)}...\" (string)`\n }\n return `\"${str}\" (string)`\n }\n if (type === 'number') return `${value} (number)`\n if (type === 'boolean') return `${value} (boolean)`\n if (Array.isArray(value)) {\n return `[...] (array with ${value.length} items)`\n }\n if (type === 'object') {\n const obj = value as Record<string, unknown>\n if (obj._type) {\n return `{_type: \"${obj._type}\", ...} (object)`\n }\n return `{...} (object)`\n }\n return String(value)\n}\n\n/**\n * Map Sanity schema type to expected JavaScript type.\n * See SANITY_SCHEMA_STRUCTURE.md for full reference.\n */\nexport function getExpectedJsType(\n schemaType: string,\n): 'string' | 'number' | 'boolean' | 'array' | 'object' {\n switch (schemaType) {\n // String types\n case 'string':\n case 'text':\n case 'url':\n case 'email':\n case 'date':\n case 'datetime':\n return 'string'\n\n // Number\n case 'number':\n return 'number'\n\n // Boolean\n case 'boolean':\n return 'boolean'\n\n // Array\n case 'array':\n return 'array'\n\n // Everything else is an object (document, object, reference, image, file, slug, geopoint, block, custom types)\n default:\n return 'object'\n }\n}\n\n/**\n * Get the actual JavaScript type of a value.\n */\nexport function getActualJsType(\n value: unknown,\n): 'string' | 'number' | 'boolean' | 'array' | 'object' | 'null' | 'undefined' {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (Array.isArray(value)) return 'array'\n return typeof value as 'string' | 'number' | 'boolean' | 'object'\n}\n\n/**\n * Get the uniqueness key for an array item based on its type.\n * - References: unique by _ref\n * - Primitives: unique by value\n * - Objects: strip _key and compare rest\n */\nexport function getUniquenessKey(item: unknown): string {\n if (typeof item !== 'object' || item === null) {\n return JSON.stringify(item)\n }\n const itemObj = item as Record<string, unknown>\n if (itemObj._type === 'reference' && typeof itemObj._ref === 'string') {\n return itemObj._ref\n }\n const itemForComparison = Object.fromEntries(\n Object.entries(itemObj).filter(([k]) => k !== '_key'),\n )\n return JSON.stringify(itemForComparison)\n}\n\ntype PathSegment =\n | { type: 'property'; value: string }\n | { type: 'index'; value: number }\n | { type: 'key'; value: string }\n\n/**\n * Get a value from an object using a path string.\n * Supports dot notation, array index notation [0], and _key selectors [_key==\"value\"].\n */\nexport function getValueAtPath(obj: unknown, path: string): unknown {\n const segments = parsePath(path)\n let current: unknown = obj\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined\n }\n\n if (segment.type === 'property') {\n if (typeof current !== 'object' || Array.isArray(current)) {\n return undefined\n }\n current = (current as Record<string, unknown>)[segment.value]\n } else if (segment.type === 'index') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment.value]\n } else if (segment.type === 'key') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current.find(\n (item): item is Record<string, unknown> =>\n typeof item === 'object' &&\n item !== null &&\n (item as Record<string, unknown>)._key === segment.value,\n )\n }\n }\n\n return current\n}\n\n/**\n * Parse a path string into segments.\n * Handles property access, array indices, and _key selectors.\n */\nfunction parsePath(path: string): PathSegment[] {\n const segments: PathSegment[] = []\n const parts = path.split(/\\.(?![^[]*\\])/)\n\n for (const part of parts) {\n const match = part.match(/^([^[]*)(?:\\[(.+)\\])?$/)\n if (!match) continue\n\n const [, prop, selector] = match\n\n if (prop) {\n segments.push({ type: 'property', value: prop })\n }\n\n if (selector) {\n const keyMatch = selector.match(/^_key\\s*==\\s*\"([^\"]+)\"$/)\n if (keyMatch) {\n segments.push({ type: 'key', value: keyMatch[1] })\n } else {\n const index = parseInt(selector, 10)\n if (!Number.isNaN(index)) {\n segments.push({ type: 'index', value: index })\n }\n }\n }\n }\n\n return segments\n}\n\n/**\n * Validate that an object only contains allowed properties.\n * Reports errors for any unknown properties found.\n *\n * @param obj - The object to validate\n * @param allowedProperties - Set of property names that are allowed\n * @param path - The path to the object for error reporting\n * @param typeName - Human-readable type name for error messages (e.g., \"reference\", \"slug\")\n * @param errors - Array to collect validation errors\n */\nexport function validateNoExtraProperties(\n obj: Record<string, unknown>,\n allowedProperties: Set<string>,\n path: string,\n typeName: string,\n errors: ValidationError[],\n): void {\n for (const key of Object.keys(obj)) {\n if (!allowedProperties.has(key)) {\n errors.push(\n createError(\n `${path}.${key}`,\n 'FIELD_NOT_IN_SCHEMA',\n `Unknown property \"${key}\" on ${typeName} object`,\n formatValue(obj[key]),\n `Only allowed properties: ${[...allowedProperties].join(', ')}`,\n `Remove the \"${key}\" property from the ${typeName} object`,\n ),\n )\n }\n }\n}\n\n/**\n * Format validation errors for display to the LLM.\n *\n * @param errors - List of validation errors\n * @returns Formatted error message\n */\nexport function formatValidationErrors(errors: ValidationError[]): string {\n if (errors.length === 0) {\n return ''\n }\n\n const header = `Validation failed with ${errors.length} error(s):\\n\\n`\n\n const errorList = errors\n .map((err, i) => {\n return [\n `${i + 1}. At path \"${err.path}\": ${err.message}`,\n ` Received: ${err.received}`,\n ` Expected: ${err.expected}`,\n ` Fix: ${err.fix}`,\n ].join('\\n')\n })\n .join('\\n\\n')\n\n return `${header + errorList}\\n\\nPlease correct all errors and try again.`\n}\n","/**\n * Array validator - validates arrays and their items.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue, getUniquenessKey } from './utils.js'\n\n/**\n * Validate an array value and its items.\n */\nexport async function validateArray(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (!Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Expected array',\n formatValue(value),\n 'array',\n 'Provide an array value',\n ),\n )\n return\n }\n\n // Get allowed item types from schema\n const itemTypes = fieldSchema.of || []\n if (itemTypes.length === 0) {\n // No item type constraints - can't validate items\n return\n }\n\n // Check if this is a primitive array (no named types, only primitive types)\n const isPrimitiveArray = itemTypes.every(\n (t) => !t.name && isPrimitiveType(t.type as string | undefined),\n )\n\n // Track _key values for duplicate detection (only for object arrays)\n const seenKeys = new Set<string>()\n\n // Validate each item\n for (let i = 0; i < value.length; i++) {\n const item = value[i]\n const itemPath = `${path}[${i}]`\n\n // Track error count before this item so we can tag any new errors with itemIndex\n const errorCountBefore = errors.length\n\n // Determine item type\n const itemObj = item as Record<string, unknown>\n const itemType = itemObj?._type as string | undefined\n const itemKey = itemObj?._key as string | undefined\n\n // For non-primitive arrays, validate _key\n if (!isPrimitiveArray && typeof item === 'object' && item !== null) {\n // Check for missing _key\n if (itemKey === undefined) {\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n 'Object array item missing \"_key\" property',\n formatValue(item),\n 'Object with _key property',\n 'Add a unique _key property to the array item',\n ),\n )\n } else if (typeof itemKey === 'string' && itemKey !== '') {\n // Check for duplicate _key\n if (seenKeys.has(itemKey)) {\n errors.push(\n createError(\n `${itemPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${itemKey}\" in array`,\n itemKey,\n 'Unique _key value',\n 'Ensure all array items have unique _key values',\n ),\n )\n } else {\n seenKeys.add(itemKey)\n }\n }\n }\n\n // Find matching schema for this item\n let matchingSchema: ManifestSchemaType | undefined\n\n for (const typeSchema of itemTypes) {\n // Match by name (for named types like blocks or named wrappers)\n // When a schema has a `name`, items MUST use that name as _type\n if (typeSchema.name && typeSchema.name === itemType) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // Match by type (for anonymous types only - no name in schema)\n // If schema has a name, we don't fall back to type matching\n if (!typeSchema.name && typeSchema.type === itemType) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // Handle single-type arrays where _type might be omitted.\n // Match the item to the sole schema so its fields are still deeply validated.\n // Covers named schemas like { name: \"object\", type: \"object\" } where\n // the skeleton builder omits _type on inline objects.\n if (\n typeSchema.type &&\n !itemType &&\n itemTypes.length === 1 &&\n typeof item === 'object' &&\n item !== null\n ) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // For primitive arrays (string[], number[])\n if (\n !itemType &&\n typeSchema.type &&\n typeof typeSchema.type === 'string' &&\n isPrimitiveType(typeSchema.type)\n ) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n }\n\n // If no match found, try looking up the item's _type in the global schema\n // This handles cases like markDefs where the allowed types might be defined globally\n if (!matchingSchema && itemType) {\n const globalTypeSchema = schema.find((s) => s.name === itemType)\n if (globalTypeSchema) {\n matchingSchema = globalTypeSchema\n }\n }\n\n if (!matchingSchema) {\n // Couldn't find matching schema for item\n const allowedTypeNames = itemTypes\n .map((t) => t.name || t.type)\n .filter(Boolean)\n .join(', ')\n\n // Check if a primitive is in an object array (type mismatch)\n const isObjectArray = !isPrimitiveArray\n const itemIsPrimitive =\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n item === null\n\n if (isObjectArray && itemIsPrimitive) {\n // Primitive in object array - this is a type mismatch\n errors.push(\n createError(\n itemPath,\n 'TYPE_MISMATCH',\n 'Expected object but found primitive in array',\n formatValue(item),\n `object of type: ${allowedTypeNames}`,\n `Provide an object with _type set to one of: ${allowedTypeNames}`,\n ),\n )\n // Tag errors from this item\n tagItemErrors(errors, errorCountBefore, i, path)\n continue\n }\n\n // Check if there's a named type that should be used\n const namedTypes = itemTypes.filter((t) => t.name)\n if (namedTypes.length > 0 && itemType) {\n // The item has a _type but it doesn't match any named schema\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n `Wrong _type \"${itemType}\" for array item`,\n formatValue(item),\n `_type must be one of: ${namedTypes.map((t) => t.name).join(', ')}`,\n `Use one of the allowed types: ${namedTypes.map((t) => t.name).join(', ')}`,\n ),\n )\n } else {\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n itemType ? `Unknown array item type: ${itemType}` : 'Invalid array item',\n formatValue(item),\n `One of: ${allowedTypeNames}`,\n itemType\n ? `Use one of the allowed types: ${allowedTypeNames}`\n : `Provide a valid array item of type: ${allowedTypeNames}`,\n ),\n )\n }\n // Tag errors from this item\n tagItemErrors(errors, errorCountBefore, i, path)\n continue\n }\n\n // Recursively validate the item\n await validateValue(item, matchingSchema, itemPath, errors, context, schema)\n\n // Tag any errors produced by recursive validation of this item\n tagItemErrors(errors, errorCountBefore, i, path)\n }\n}\n\n/**\n * Tag all errors added since `startIndex` with itemIndex and arrayPath.\n * This allows the patch tool to identify per-item errors and filter invalid items\n * while writing valid ones.\n */\nfunction tagItemErrors(\n errors: ValidationError[],\n startIndex: number,\n itemIndex: number,\n arrayPath: string,\n): void {\n for (let e = startIndex; e < errors.length; e++) {\n errors[e].itemIndex = itemIndex\n errors[e].arrayPath = arrayPath\n }\n}\n\n/**\n * Validate that new items don't duplicate existing array items or each other.\n * Used by patch operations (APPEND, INSERT) to check uniqueItems constraints\n * against the existing document state.\n */\nexport function validateUniqueItems(\n newItems: unknown[],\n existingArray: unknown[],\n pathPrefix: string,\n errors: ValidationError[],\n): void {\n const existingKeys = new Set<string>()\n for (const item of existingArray) {\n existingKeys.add(getUniquenessKey(item))\n }\n\n const newKeys = new Set<string>()\n for (let i = 0; i < newItems.length; i++) {\n const item = newItems[i]\n const uniquenessKey = getUniquenessKey(item)\n\n if (existingKeys.has(uniquenessKey)) {\n errors.push(\n createError(\n `${pathPrefix}${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Item would duplicate an existing array item',\n formatValue(item),\n 'Unique array items',\n 'Remove the duplicate item or modify it to be unique',\n ),\n )\n } else if (newKeys.has(uniquenessKey)) {\n errors.push(\n createError(\n `${pathPrefix}${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Items contain duplicates',\n formatValue(item),\n 'Unique array items',\n 'Remove duplicate items from the operation',\n ),\n )\n }\n newKeys.add(uniquenessKey)\n }\n}\n","/**\n * Predicates for validation rules on a `ManifestField` or `ManifestSchemaType`.\n *\n * Two rule shapes appear in practice:\n * - manifest format: `{ flag: 'presence', constraint: 'required' }`\n * - encoded lexicon format: `{ type: 'required' }` / `{ type: 'custom' }`\n *\n * Both are normalized here so callers don't need to know about the wire format.\n */\n\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\n\nconst isRequiredRule = (rule: Record<string, unknown>): boolean =>\n rule.type === 'required' || (rule.flag === 'presence' && rule.constraint === 'required')\n\nconst isCustomRule = (rule: Record<string, unknown>): boolean =>\n rule.type === 'custom' || rule.flag === 'custom'\n\nconst matchesAnyRule = (\n field: ManifestField | ManifestSchemaType,\n predicate: (rule: Record<string, unknown>) => boolean,\n errorLevelOnly: boolean,\n): boolean =>\n (field.validation ?? []).some(\n (group) =>\n (!errorLevelOnly || (group.level ?? 'error') === 'error') &&\n (group.rules ?? []).some((rule) => predicate(rule as Record<string, unknown>)),\n )\n\n/** True when the field has an error-level required validator. */\nexport const hasRequiredValidator = (field: ManifestField | ManifestSchemaType): boolean =>\n matchesAnyRule(field, isRequiredRule, true)\n\n/** True when the field has a `Rule.custom(...)` validator at any level. */\nexport const hasCustomValidator = (field: ManifestField | ManifestSchemaType): boolean =>\n matchesAnyRule(field, isCustomRule, false)\n","/**\n * Finds schema paths that have a `Rule.custom(...)` validator.\n *\n * Custom validators serialize with the function body stripped, so we cannot\n * run them ourselves. We surface the paths so a caller can ask the user to\n * confirm before publishing.\n *\n * Walks every reachable field, including those nested inside arrays of\n * objects.\n */\n\nimport { walkSchemaTree } from '../navigate/walkTree.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { hasCustomValidator } from './rules'\n\n/**\n * Return paths of fields with custom validators on the document type.\n * Document-level custom validators are reported at `(document)`.\n */\nexport function detectCustomValidators(\n documentType: string,\n schema: ManifestSchemaType[],\n): string[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) return []\n\n const paths: string[] = []\n if (hasCustomValidator(typeSchema)) paths.push('(document)')\n\n walkSchemaTree(documentType, schema, (field, path) => {\n if (hasCustomValidator(field)) paths.push(path)\n })\n return paths\n}\n","/**\n * Document-aware path resolution for dynamic array structures.\n *\n * When schema-only navigation fails (e.g., for PTE markDefs, inline objects),\n * this utility uses the actual document to resolve the correct schema for validation.\n *\n * This handles cases where the item's type is stored in the document (_type field)\n * rather than being statically derivable from the schema structure alone.\n */\n\nimport { BUILT_IN_TYPE_FIELDS } from '../navigate/constants.js'\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { getValueAtPath } from './utils.js'\n\ninterface PathResolutionResult {\n /** The resolved field schema, or null if not found */\n schema: ManifestSchemaType | null\n /** How the schema was resolved: 'schema' (static), 'document' (dynamic), or null (failed) */\n resolvedVia: 'schema' | 'document' | null\n}\n\n/**\n * Check if a path contains array selectors that could benefit from document resolution.\n */\nfunction pathHasArraySelectors(path: string): boolean {\n return /\\[(_key==|[0-9])/.test(path)\n}\n\n/**\n * Resolve field schema at path, using document for accurate type resolution.\n *\n * When a document is provided and the path contains array selectors, we use\n * document-based resolution to determine the correct type at each array access.\n * This is essential for union arrays where multiple types have the same field name.\n *\n * @param path - Dot-notation path, may include array selectors like [_key==\"abc\"]\n * @param typeSchema - The document type schema to start navigation from\n * @param allSchemas - All available schemas for type resolution\n * @param document - Optional existing document for dynamic resolution\n * @returns Resolution result with schema and resolution method\n */\nexport function resolveFieldSchemaAtPath(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document?: Record<string, unknown>,\n): PathResolutionResult {\n // When document is provided and path has array selectors, prefer document-based resolution\n // This ensures we resolve the correct type in union arrays\n if (document && pathHasArraySelectors(path)) {\n const documentResult = resolveFieldSchemaWithDocument(path, typeSchema, allSchemas, document)\n if (documentResult) {\n return { schema: documentResult, resolvedVia: 'document' }\n }\n }\n\n // Try schema-only navigation\n const schemaResult = resolveFieldSchema(path, typeSchema, allSchemas)\n if (schemaResult) {\n return { schema: schemaResult, resolvedVia: 'schema' }\n }\n\n // Fall back to document-based resolution for last-field lookup\n if (document) {\n const documentResult = resolveFieldSchemaFromDocument(path, document, allSchemas)\n if (documentResult) {\n return { schema: documentResult, resolvedVia: 'document' }\n }\n }\n\n return { schema: null, resolvedVia: null }\n}\n\n/**\n * Resolve item _type from a document to a schema.\n *\n * In Sanity, array union items can have a `name` that differs from their `type`.\n * For example: `{ name: \"card\", type: \"linkCard\" }` in the `of` array means documents\n * store `_type: \"card\"`, but the actual schema with fields is named `\"linkCard\"`.\n *\n * This function first tries a direct lookup in allSchemas, then falls back to\n * checking the parent array's `of` items to resolve aliased names.\n */\nfunction resolveItemSchema(\n itemType: string,\n allSchemas: ManifestSchemaType[],\n parentArraySchema?: ManifestSchemaType,\n): ManifestSchemaType | null {\n // Direct lookup — works when _type matches a top-level schema name\n const directMatch = allSchemas.find((s) => s.name === itemType)\n if (directMatch) {\n return directMatch\n }\n\n // Aliased name lookup — check the parent array's `of` items\n // e.g., of: [{ name: \"card\", type: \"linkCard\" }] → _type \"card\" resolves to \"linkCard\"\n if (parentArraySchema?.of) {\n for (const ofItem of parentArraySchema.of as ManifestSchemaType[]) {\n if (ofItem.name === itemType && ofItem.type) {\n const resolvedSchema = allSchemas.find((s) => s.name === ofItem.type)\n if (resolvedSchema) {\n return resolvedSchema\n }\n }\n }\n }\n\n return null\n}\n\ninterface PathFieldSegment {\n field: string\n selector: string | null\n}\n\n/**\n * Parse a path into field segments with their selectors.\n * \"content[_key==\"abc\"].title\" -> [{field: \"content\", selector: \"[_key==\"abc\"]\"}, {field: \"title\", selector: null}]\n *\n * Note: This is different from parsePathSegments in schemaTraversal.ts which tracks isArray/arrayIndex,\n * and different from @sanity/types PathSegment which is a union type for path operations.\n */\nfunction parsePathIntoFieldSegments(path: string): PathFieldSegment[] {\n const segments: PathFieldSegment[] = []\n\n // Split by dots but keep selectors attached\n const parts = path.split(/\\.(?![^[]*\\])/)\n\n for (const part of parts) {\n const match = part.match(/^([^[]+)(\\[.+\\])?$/)\n if (match) {\n segments.push({\n field: match[1],\n selector: match[2] || null,\n })\n }\n }\n\n return segments\n}\n\n/**\n * Walk the path segment by segment, using document to resolve array item types.\n *\n * For path \"content[_key==\"text1\"].title\":\n * 1. Start with document type schema\n * 2. Find \"content\" field -> array type\n * 3. Get item at [_key==\"text1\"] from document -> _type is \"textBlock\"\n * 4. Look up \"textBlock\" schema, find \"title\" field -> string\n *\n * This handles union arrays correctly by using the actual _type from the document.\n */\nfunction resolveFieldSchemaWithDocument(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document: Record<string, unknown>,\n): ManifestSchemaType | null {\n // Parse path into field segments with their selectors\n const segments = parsePathIntoFieldSegments(path)\n\n let currentSchema: ManifestSchemaType = typeSchema\n let currentPath = ''\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n const isLastSegment = i === segments.length - 1\n\n // Build the path up to this point (including selector if present)\n if (currentPath) {\n currentPath += `.${segment.field}`\n } else {\n currentPath = segment.field\n }\n if (segment.selector) {\n currentPath += segment.selector\n }\n\n // Check for built-in type fields first (e.g., span.text, block.style)\n if (BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment.field]) {\n const builtInField = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment.field]\n if (isLastSegment) {\n return builtInField\n }\n\n // If built-in field is an array (like block.children) and has a selector,\n // we need to resolve the item type for the next segment\n if (builtInField.type === 'array' && segment.selector && builtInField.of) {\n // Get the item value from document to determine its _type\n const itemValue = getValueAtPath(document, currentPath)\n\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n // First check if it's a built-in type (like span)\n if (BUILT_IN_TYPE_FIELDS[itemType]) {\n // Create a synthetic schema for the built-in type\n currentSchema = { name: itemType, type: itemType } as ManifestSchemaType\n continue\n }\n // Otherwise look it up in allSchemas (handles aliased names)\n const itemSchema = resolveItemSchema(itemType, allSchemas, builtInField)\n if (itemSchema) {\n currentSchema = itemSchema\n continue\n }\n }\n }\n // Fall back to first item type in schema\n if (builtInField.of.length > 0) {\n const firstItemType = (builtInField.of[0] as ManifestSchemaType).type\n if (BUILT_IN_TYPE_FIELDS[firstItemType]) {\n currentSchema = { name: firstItemType, type: firstItemType } as ManifestSchemaType\n continue\n }\n const itemSchema = allSchemas.find((s) => s.name === firstItemType)\n currentSchema = itemSchema || (builtInField.of[0] as ManifestSchemaType)\n continue\n }\n }\n\n currentSchema = builtInField\n continue\n }\n\n // Find the field in current schema\n let field: ManifestSchemaType | undefined\n\n if (currentSchema.fields) {\n field = currentSchema.fields.find((f) => f.name === segment.field) as\n | ManifestSchemaType\n | undefined\n }\n\n // If not found in fields, check if current schema is an array\n if (!field && currentSchema.type === 'array' && currentSchema.of) {\n // Need to determine the item type from the document\n const parentPath = segments\n .slice(0, i)\n .map((s: PathFieldSegment) => s.field + (s.selector || ''))\n .join('.')\n const parentValue = parentPath ? getValueAtPath(document, parentPath) : document\n\n if (parentValue && typeof parentValue === 'object' && !Array.isArray(parentValue)) {\n const itemType = (parentValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas, currentSchema)\n if (itemSchema?.fields) {\n field = itemSchema.fields.find((f) => f.name === segment.field) as\n | ManifestSchemaType\n | undefined\n }\n }\n }\n }\n\n // If still not found, the document type schema may have empty fields (e.g., manifest\n // doesn't surface fields in groups). Use the document value at currentPath to resolve\n // the item's _type directly and skip ahead.\n if (!field) {\n const itemValue = getValueAtPath(document, currentPath)\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas)\n if (itemSchema) {\n if (isLastSegment) {\n return itemSchema\n }\n currentSchema = itemSchema\n continue\n }\n }\n }\n return null\n }\n\n if (isLastSegment) {\n return field\n }\n\n // Navigate into the field for next iteration\n // If field is an array and has a selector, we need to resolve the item type from document\n // Resolve named type references first (e.g., field type \"link\" -> array schema \"link\")\n let resolvedFieldForNav: ManifestSchemaType = field\n if (field.type !== 'array' && field.type) {\n const referencedArray = allSchemas.find((s) => s.name === field.type && s.type === 'array')\n if (referencedArray) {\n resolvedFieldForNav = referencedArray\n }\n }\n\n if (resolvedFieldForNav.type === 'array' && segment.selector) {\n const itemValue = getValueAtPath(document, currentPath)\n\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas, resolvedFieldForNav)\n if (itemSchema) {\n currentSchema = itemSchema\n continue\n }\n }\n }\n // Fall back to first item type in schema\n if (resolvedFieldForNav.of && resolvedFieldForNav.of.length > 0) {\n const firstItemType = (resolvedFieldForNav.of[0] as ManifestSchemaType).type\n const itemSchema = allSchemas.find((s) => s.name === firstItemType)\n currentSchema = itemSchema || (resolvedFieldForNav.of[0] as ManifestSchemaType)\n continue\n }\n }\n\n // Resolve type reference if needed\n if (field.type && field.type !== 'array') {\n const referencedSchema = allSchemas.find((s) => s.name === field.type)\n if (referencedSchema) {\n currentSchema = referencedSchema\n continue\n }\n }\n\n currentSchema = field\n }\n\n return currentSchema\n}\n\n/**\n * Resolve field schema by looking up the parent object's _type in the document.\n *\n * For path \"content[_key==\"x\"].markDefs[_key==\"y\"].href\":\n * 1. Parent path = \"content[_key==\"x\"].markDefs[_key==\"y\"]\"\n * 2. Get parent from document, find its _type (e.g., \"link\")\n * 3. Look up \"link\" type in schema\n * 4. Find \"href\" field in that type\n *\n * This handles:\n * - PTE markDefs with annotation types (link, internalLink, etc.)\n * - PTE children with inline object types\n * - Custom blocks in PTE arrays (callout, image, code, etc.)\n * - Nested PTE fields (e.g., callout.content[].markDefs[].href)\n *\n * @param path - Full path to the field\n * @param document - The document to look up values from\n * @param allSchemas - All available schemas for type resolution\n * @returns The field schema if found, null otherwise\n */\nexport function resolveFieldSchemaFromDocument(\n path: string,\n document: Record<string, unknown>,\n allSchemas: ManifestSchemaType[],\n): ManifestSchemaType | null {\n // Need a parent path to look up the object's _type\n const lastDotIndex = path.lastIndexOf('.')\n if (lastDotIndex === -1) {\n return null\n }\n\n const parentPath = path.substring(0, lastDotIndex)\n const fieldName = path.substring(lastDotIndex + 1)\n\n // Get parent object from document\n const parentValue = getValueAtPath(document, parentPath)\n\n if (parentValue === null || parentValue === undefined) {\n return null\n }\n\n if (typeof parentValue !== 'object' || Array.isArray(parentValue)) {\n return null\n }\n\n // Get the _type of the parent object\n const parentType = (parentValue as Record<string, unknown>)._type as string | undefined\n\n if (!parentType) {\n return null\n }\n\n // Look up the type in schema (handles aliased names via resolveItemSchema)\n const typeSchema = resolveItemSchema(parentType, allSchemas)\n\n if (!typeSchema) {\n return null\n }\n\n // Find the field in that type's fields\n if (typeSchema.fields) {\n const field = typeSchema.fields.find((f) => f.name === fieldName)\n if (field) {\n return field\n }\n }\n\n return null\n}\n\n/**\n * Validate that a path can be resolved to a schema.\n *\n * Returns true if:\n * - Path can be resolved via schema (static), OR\n * - Path can be resolved via document (parent exists with valid _type and field)\n *\n * @param path - Dot-notation path to validate\n * @param typeSchema - The document type schema\n * @param allSchemas - All available schemas\n * @param document - Optional document for dynamic resolution\n * @returns true if path can be resolved to a schema\n */\nexport function validatePathExists(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document?: Record<string, unknown>,\n): boolean {\n const result = resolveFieldSchemaAtPath(path, typeSchema, allSchemas, document)\n return result.schema !== null\n}\n","/**\n * Language field validators for document-level and field-level translations.\n */\n\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate a document-level language field value against available languages.\n *\n * This validator is called when:\n * 1. The document uses document-level translation\n * 2. The field being validated is the language field (e.g., \"language\", \"locale\")\n * 3. There are known available languages to validate against\n *\n * @param value - The language value to validate\n * @param languageFieldName - Name of the language field (e.g., \"language\", \"locale\")\n * @param availableLanguages - List of valid language codes from existing documents\n * @param path - The field path for error reporting\n * @param errors - Array to collect validation errors\n */\nexport function validateDocumentLanguageField(\n value: unknown,\n languageFieldName: string,\n availableLanguages: string[],\n path: string,\n errors: ValidationError[],\n): void {\n // Skip validation if no available languages to compare against\n if (!availableLanguages || availableLanguages.length === 0) {\n return\n }\n\n // Skip null/undefined - those are handled elsewhere\n if (value === null || value === undefined) {\n return\n }\n\n // Language must be a string\n if (typeof value !== 'string') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n `Language field \"${languageFieldName}\" must be a string`,\n formatValue(value),\n 'string (language code)',\n `Provide a language code like \"${availableLanguages[0]}\"`,\n ),\n )\n return\n }\n\n // Check if value is one of the available languages\n if (!availableLanguages.includes(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language code for \"${languageFieldName}\"`,\n formatValue(value),\n `One of: ${availableLanguages.map((l) => `\"${l}\"`).join(', ')}`,\n `Use a valid language code: ${availableLanguages.join(', ')}`,\n ),\n )\n }\n}\n\n/**\n * Validate a field-level language key (the _key in internationalizedArray items).\n *\n * This validator is called when processing arrays with options.languages,\n * to ensure that array item _key values match configured language IDs.\n *\n * @param key - The _key value from an array item\n * @param allowedLanguages - List of allowed languages with id and title\n * @param path - The field path for error reporting\n * @param errors - Array to collect validation errors\n */\nexport function validateFieldLevelLanguageKey(\n key: string,\n allowedLanguages: Array<{ id: string; title: string | null }>,\n path: string,\n errors: ValidationError[],\n): void {\n // Skip validation if no allowed languages configured\n if (!allowedLanguages || allowedLanguages.length === 0) {\n return\n }\n\n const languageIds = allowedLanguages.map((lang) => lang.id)\n\n // Check if key is one of the allowed language IDs\n if (!languageIds.includes(key)) {\n const languageList = allowedLanguages\n .map((lang) => `\"${lang.id}\"${lang.title ? ` (${lang.title})` : ''}`)\n .join(', ')\n\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language key \"${key}\" in internationalized array`,\n `\"${key}\"`,\n `One of: ${languageList}`,\n `Use a valid language key: ${languageIds.join(', ')}`,\n ),\n )\n }\n}\n\n/**\n * Validate a field-level language field value (v5 format where language is a dedicated field).\n *\n * In v5 of the internationalized-array plugin, the language code is stored in a\n * dedicated `language` field instead of `_key`.\n */\nexport function validateFieldLevelLanguageField(\n languageValue: unknown,\n allowedLanguages: Array<{ id: string; title: string | null }>,\n path: string,\n errors: ValidationError[],\n): void {\n if (!allowedLanguages || allowedLanguages.length === 0) {\n return\n }\n\n if (typeof languageValue !== 'string' || languageValue === '') {\n const languageIds = allowedLanguages.map((lang) => lang.id)\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n 'Missing or invalid \"language\" field in internationalized array item',\n formatValue(languageValue),\n `One of: ${allowedLanguages.map((l) => `\"${l.id}\"${l.title ? ` (${l.title})` : ''}`).join(', ')}`,\n `Set the \"language\" field to a valid language code: ${languageIds.join(', ')}`,\n ),\n )\n return\n }\n\n const languageIds = allowedLanguages.map((lang) => lang.id)\n if (!languageIds.includes(languageValue)) {\n const languageList = allowedLanguages\n .map((lang) => `\"${lang.id}\"${lang.title ? ` (${lang.title})` : ''}`)\n .join(', ')\n\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language \"${languageValue}\" in internationalized array item`,\n `\"${languageValue}\"`,\n `One of: ${languageList}`,\n `Use a valid language: ${languageIds.join(', ')}`,\n ),\n )\n }\n}\n\ntype LanguageOption = { id: string; title: string | null }\n\ninterface SchemaWithOptions {\n name?: string\n type?: string\n fields?: Array<{ name: string; type: string }>\n of?: Array<{ name?: string; type?: string; fields?: Array<{ name: string; type: string }> }>\n options?: { languages?: LanguageOption[] }\n}\n\n/**\n * Detect whether an internationalized array uses v5 format (dedicated `language` field)\n * by checking if the array's value type has a `language` field in its schema.\n */\nexport function isV5InternationalizedArray(\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n): boolean {\n // Resolve the array type definition\n const resolvedSchema =\n allSchemas.find((s) => s.name === fieldSchema.name || s.name === fieldSchema.type) ??\n fieldSchema\n const itemType = resolvedSchema.of?.[0]\n if (!itemType) return false\n\n // Resolve the value type name\n const valueTypeName = itemType.name || itemType.type\n if (!valueTypeName) return false\n\n // Look up the value type in the full schema\n const valueType = allSchemas.find((s) => s.name === valueTypeName)\n const fieldsToCheck = valueType?.fields || itemType.fields\n\n return !!fieldsToCheck?.some((f) => f.name === 'language')\n}\n\n/**\n * Check if a field schema represents an internationalized array type.\n *\n * @param fieldSchema - The field schema to check\n * @returns true if the field is an internationalized array\n */\nexport function isInternationalizedArrayField(fieldSchema: SchemaWithOptions): boolean {\n return (\n !!fieldSchema.type?.startsWith('internationalizedArray') ||\n !!fieldSchema.name?.startsWith('internationalizedArray')\n )\n}\n\n/**\n * Resolve configured languages from a field schema, falling back to global schemas.\n */\nfunction resolveLanguages(\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n): LanguageOption[] | undefined {\n let languages = fieldSchema.options?.languages\n if (!languages?.length) {\n const resolvedSchema = allSchemas.find((s) => s.name === fieldSchema.type)\n languages = resolvedSchema?.options?.languages\n }\n return languages?.length ? languages : undefined\n}\n\n/**\n * Validate a SET operation against internationalized array language constraints.\n *\n * Handles two cases:\n * 1. Setting the whole array (value is an array) — validates each item's _key\n * 2. Setting a _key directly (path ends with `._key`) — validates the new key value\n *\n * Resolves the field schema from the path. No-ops if the field isn't an internationalized array.\n *\n * @param path - The SET operation path\n * @param value - The new value being set\n * @param fieldSchema - The resolved field schema for the path\n * @param typeSchema - The document type schema (for resolving parent paths)\n * @param allSchemas - All schemas for resolving named types\n * @param errors - Array to collect validation errors\n */\nexport function validateInternationalizedArraySet(\n path: string,\n value: unknown,\n fieldSchema: ManifestSchemaType,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n // Case 1: setting the whole array\n if (isInternationalizedArrayField(fieldSchema) && Array.isArray(value)) {\n validateInternationalizedArrayItems(value, fieldSchema, allSchemas, path, errors)\n return\n }\n\n // Case 2: setting a _key on an item (v4 only — in v5, _key is random)\n if (path.endsWith('._key') && typeof value === 'string') {\n const arrayPath = path.replace(/\\[[^\\]]+\\]\\._key$/, '')\n const arrayFieldSchema = resolveFieldSchema(arrayPath, typeSchema, allSchemas)\n if (!arrayFieldSchema || !isInternationalizedArrayField(arrayFieldSchema)) {\n return\n }\n\n // In v5, _key is a random ID — skip language validation\n if (isV5InternationalizedArray(arrayFieldSchema, allSchemas)) {\n return\n }\n\n const languages = resolveLanguages(arrayFieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n validateFieldLevelLanguageKey(value, languages, path, errors)\n return\n }\n\n // Case 3: setting the .language field on an item (v5 only)\n if (path.endsWith('.language') && typeof value === 'string') {\n const arrayPath = path.replace(/\\[[^\\]]+\\]\\.language$/, '')\n const arrayFieldSchema = resolveFieldSchema(arrayPath, typeSchema, allSchemas)\n if (!arrayFieldSchema || !isInternationalizedArrayField(arrayFieldSchema)) {\n return\n }\n\n if (!isV5InternationalizedArray(arrayFieldSchema, allSchemas)) {\n return\n }\n\n const languages = resolveLanguages(arrayFieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n validateFieldLevelLanguageField(value, languages, path, errors)\n }\n}\n\n/**\n * Validate language keys for items being added to an internationalized array.\n *\n * Callers should check `isInternationalizedArrayField()` before calling this.\n *\n * @param items - Array items to validate\n * @param fieldSchema - The field schema (may be a named type reference)\n * @param allSchemas - All schemas for resolving named types\n * @param path - The array field path (e.g., 'description')\n * @param errors - Array to collect validation errors\n */\nexport function validateInternationalizedArrayItems(\n items: unknown[],\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n path: string,\n errors: ValidationError[],\n): void {\n const languages = resolveLanguages(fieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n const v5 = isV5InternationalizedArray(fieldSchema, allSchemas)\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (typeof item === 'object' && item !== null) {\n const itemObj = item as Record<string, unknown>\n if (v5) {\n // v5: validate the dedicated \"language\" field, not \"_key\"\n validateFieldLevelLanguageField(\n itemObj.language,\n languages,\n `${path}[${i}].language`,\n errors,\n )\n } else {\n // v4: validate \"_key\" as the language identifier\n if (itemObj._key && typeof itemObj._key === 'string') {\n validateFieldLevelLanguageKey(itemObj._key, languages, `${path}[${i}]._key`, errors)\n }\n }\n }\n }\n}\n","/**\n * Object validator - validates objects and their fields.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate an object value and its fields.\n */\nexport async function validateObject(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Expected object',\n formatValue(value),\n 'object',\n 'Provide an object value',\n ),\n )\n return\n }\n\n const objValue = value as Record<string, unknown>\n\n // Get fields from schema (could be inline or from referenced type)\n let fields = fieldSchema.fields || []\n\n // If no inline fields, look up the type in schema\n if (fields.length === 0 && fieldSchema.type) {\n const referencedType = schema.find((s) => s.name === fieldSchema.type)\n if (referencedType?.fields) {\n fields = referencedType.fields\n }\n }\n\n if (fields.length === 0) {\n // No field constraints - can't validate fields\n return\n }\n\n // Build set of valid field names\n const validFieldNames = new Set(fields.map((f) => f.name))\n\n // For block type (Portable Text), always allow standard Portable Text fields\n // These are built-in fields that may not be explicitly listed in schema\n const isBlockType = fieldSchema.type === 'block' || fieldSchema.name === 'block'\n if (isBlockType) {\n validFieldNames.add('children')\n validFieldNames.add('markDefs')\n validFieldNames.add('style')\n validFieldNames.add('listItem')\n validFieldNames.add('level')\n }\n\n // Check for fields not in schema\n for (const key of Object.keys(objValue)) {\n // Skip system fields\n if (key.startsWith('_')) continue\n\n if (!validFieldNames.has(key)) {\n const validFieldsList = fields.map((f) => f.name).join(', ')\n errors.push(\n createError(\n path ? `${path}.${key}` : key,\n 'FIELD_NOT_IN_SCHEMA',\n 'Field does not exist in schema',\n formatValue(objValue[key]),\n `Field must be one of: ${validFieldsList}`,\n 'Remove this field or check the schema for valid field names',\n ),\n )\n }\n }\n\n // Validate each field\n for (const field of fields) {\n const fieldValue = objValue[field.name]\n const fieldPath = path ? `${path}.${field.name}` : field.name\n\n // Skip undefined fields - we don't enforce required fields\n if (fieldValue === undefined) {\n continue\n }\n\n // Recursively validate the field value\n await validateValue(fieldValue, field, fieldPath, errors, context, schema)\n }\n}\n","/**\n * Path validation utilities.\n * Functions for validating paths against schemas with error generation.\n */\n\nimport { resolveFieldSchemaAllUnions } from '../navigate/navigateAllUnions.js'\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { resolveFieldSchemaFromDocument } from './document-path-resolver.js'\nimport type { FieldSchemaLookupResult, ValidationError, ValidationResult } from './types.js'\nimport { createError, getValueAtPath as getValueAtPathWithKeys } from './utils.js'\n\n/**\n * Get valid image metadata field names for a given image path.\n *\n * This uses the navigation logic to find the image field schema\n * and extract valid metadata field names. Used for silent filtering of metadata.\n *\n * @param imagePath - The path to the image field\n * @param typeSchema - The document type schema\n * @param schema - All available schemas\n * @returns Set of valid metadata field names, or null if path is invalid\n */\nexport function getValidImageMetadataFields(\n imagePath: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): Set<string> | null {\n // Navigate to the image field in the schema\n const imageFieldSchema = resolveFieldSchema(imagePath, typeSchema, schema)\n\n if (!imageFieldSchema) {\n return null\n }\n\n // Get valid metadata field names from the image field schema\n const validFieldNames = new Set<string>()\n\n // Standard image fields that are always valid\n validFieldNames.add('hotspot')\n validFieldNames.add('crop')\n\n // Add custom metadata fields from the image schema\n if (imageFieldSchema.fields) {\n for (const field of imageFieldSchema.fields) {\n validFieldNames.add(field.name)\n }\n }\n\n return validFieldNames\n}\n\n/**\n * Get the field schema(s) at a given path in the document type.\n *\n * For union types (arrays with multiple `of` types), returns ALL possible schemas.\n * This is important for validating fields that might exist in some but not all union types.\n *\n * @param path - Dot-notation path, may include array selectors like [_key==\"abc\"]\n * @param documentType - The document type name\n * @param schema - Full schema array\n * @param existingDocument - Optional document to validate path existence against\n * @returns Object with schemas array and any validation errors\n */\nexport function getFieldSchemaAtPath(\n path: string,\n documentType: string,\n schema: ManifestSchemaType[],\n existingDocument?: Record<string, unknown>,\n): FieldSchemaLookupResult {\n const errors: ValidationError[] = []\n\n if (!path) {\n errors.push(\n createError(\n '',\n 'INVALID_PATH',\n 'Empty path provided',\n '(empty)',\n 'Non-empty path string',\n 'Provide a valid path to a field',\n ),\n )\n return { schemas: null, errors }\n }\n\n // Find the document type schema\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) {\n errors.push(\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Document type \"${documentType}\" not found in schema`,\n documentType,\n 'Valid document type',\n 'Check the document type name',\n ),\n )\n return { schemas: null, errors }\n }\n\n // Navigate to field schema(s) using schema navigation module\n let fieldSchemas = resolveFieldSchemaAllUnions(path, typeSchema, schema)\n\n // If schema navigation fails and we have a document, try document-based resolution\n // This handles dynamic array structures like PTE markDefs where the item's _type\n // is stored in the document, not derivable from schema structure alone\n if ((!fieldSchemas || fieldSchemas.length === 0) && existingDocument) {\n const documentResolvedSchema = resolveFieldSchemaFromDocument(path, existingDocument, schema)\n if (documentResolvedSchema) {\n fieldSchemas = [documentResolvedSchema]\n }\n }\n\n if (!fieldSchemas || fieldSchemas.length === 0) {\n errors.push(\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Field at path \"${path}\" does not exist in schema`,\n path,\n 'Valid field path',\n 'Check the path matches a field in the schema',\n ),\n )\n return { schemas: null, errors }\n }\n\n // If document provided, validate the path exists (for array items with _key selectors)\n // and that parent objects exist for nested paths\n if (existingDocument) {\n const hasNestedPath = path.includes('.') || path.includes('[')\n\n if (hasNestedPath) {\n const value = getValueAtPathWithKeys(existingDocument, path)\n\n if (value === undefined) {\n // Check if it's creating a new field on an existing parent\n const lastDotIndex = path.lastIndexOf('.')\n if (lastDotIndex > 0) {\n const parentPath = path.substring(0, lastDotIndex)\n const parentValue = getValueAtPathWithKeys(existingDocument, parentPath)\n\n if (parentValue === undefined) {\n // Parent doesn't exist - error for both array selectors and nested objects\n if (path.includes('[')) {\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Array item does not exist in document`,\n path,\n 'Existing array item',\n 'Ensure the array item exists before setting fields on it',\n ),\n )\n } else {\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Parent object at \"${parentPath}\" does not exist in document`,\n path,\n 'Existing parent object',\n 'Ensure the parent object exists before setting nested fields',\n ),\n )\n }\n return { schemas: fieldSchemas, errors }\n }\n } else if (path.includes('[')) {\n // Path like \"gallery[_key=='x']\" with no dots\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Array item does not exist in document`,\n path,\n 'Existing array item',\n 'Ensure the array item exists before accessing it',\n ),\n )\n return { schemas: fieldSchemas, errors }\n }\n }\n }\n }\n\n return { schemas: fieldSchemas, errors: [] }\n}\n\n/**\n * Validate that a path points to an image field.\n *\n * This is a convenience wrapper around getFieldSchemaAtPath that checks\n * whether the field at the path is an image type.\n *\n * @param path - Dot-notation path to the field\n * @param documentType - The document type name\n * @param schema - Full schema array\n * @param existingDocument - Optional document to validate path existence against\n * @returns Validation result with errors if path is invalid or not an image field\n */\nexport function validateImagePath(\n path: string,\n documentType: string,\n schema: ManifestSchemaType[],\n existingDocument?: Record<string, unknown>,\n): ValidationResult {\n const { schemas, errors } = getFieldSchemaAtPath(path, documentType, schema, existingDocument)\n\n if (errors.length > 0) {\n return { valid: false, errors, warnings: [] }\n }\n\n if (!schemas || schemas.length === 0) {\n return {\n valid: false,\n warnings: [],\n errors: [\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Field at path \"${path}\" does not exist in schema`,\n path,\n 'Valid image field path',\n 'Check the path matches an image field in the schema',\n ),\n ],\n }\n }\n\n // Check if any of the schemas represent an image type\n const hasImageType = schemas.some((s) => s.type === 'image')\n\n if (!hasImageType) {\n const types = schemas.map((s) => s.type || 'unknown').join(', ')\n return {\n valid: false,\n warnings: [],\n errors: [\n createError(\n path,\n 'TYPE_MISMATCH',\n `Field at path \"${path}\" is not an image field`,\n `type: ${types}`,\n 'type: image',\n 'Provide a path to an image field in the schema',\n ),\n ],\n }\n }\n\n return { valid: true, errors: [], warnings: [] }\n}\n\n/**\n * Validates metadata fields for an image against the schema\n * Removes fields that don't exist in the image field's schema definition\n *\n * @param metadata - The metadata object to validate (e.g., {alt: \"...\", caption: \"...\"})\n * @param imagePath - The path to the image field (e.g., \"heroImage\" or \"content[_key==\"abc\"].image\")\n * @param typeSchema - The document type schema\n * @param schema - All available schemas\n * @returns Cleaned metadata object with only valid fields, or undefined if no valid fields\n */\nexport function validateImageMetadata(\n metadata: Record<string, string>,\n imagePath: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): Record<string, string> | undefined {\n if (!metadata || typeof metadata !== 'object' || Object.keys(metadata).length === 0) {\n return undefined\n }\n\n // Try using the navigation helper first (handles simple paths)\n const simpleValidFields = getValidImageMetadataFields(imagePath, typeSchema, schema)\n\n // If navigation found valid fields, use them\n // Otherwise, fall back to union-aware navigation for complex array paths\n let validFieldNames: Set<string>\n\n if (simpleValidFields && simpleValidFields.size > 0) {\n validFieldNames = simpleValidFields\n } else {\n // Fall back to union-aware navigation for complex array paths\n const imageFieldSchemas = resolveFieldSchemaAllUnions(imagePath, typeSchema, schema)\n\n if (!imageFieldSchemas || imageFieldSchemas.length === 0) {\n // Can't validate without schema, return empty to prevent hallucinated fields\n return undefined\n }\n\n // Collect valid metadata field names from ALL possible union type schemas\n // This handles cases like content[_key==\"x\"].image where different blocks may have different metadata\n validFieldNames = new Set<string>()\n for (const fieldSchema of imageFieldSchemas) {\n if (fieldSchema?.fields && Array.isArray(fieldSchema.fields)) {\n for (const field of fieldSchema.fields) {\n validFieldNames.add(field.name)\n }\n }\n }\n }\n\n if (validFieldNames.size === 0) {\n // No metadata fields available in any union type\n return undefined\n }\n\n // Filter metadata to only include valid fields\n const cleanedMetadata: Record<string, string> = {}\n for (const [key, value] of Object.entries(metadata)) {\n if (validFieldNames.has(key) && typeof value === 'string') {\n cleanedMetadata[key] = value\n }\n }\n\n return Object.keys(cleanedMetadata).length > 0 ? cleanedMetadata : undefined\n}\n","/**\n * Portable Text (Block) validator - validates PT blocks, spans, and markDefs.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate a Portable Text block value.\n *\n * Blocks have special validation requirements:\n * - children must be an array containing spans and inline objects (from block.of)\n * - markDefs must be an array containing annotations (from block.marks.annotations)\n * - style, listItem, level are optional fields\n */\nexport async function validateBlock(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid block value',\n formatValue(value),\n 'Object with { _type: \"block\", children: [...], markDefs?: [...] }',\n 'Provide a valid Portable Text block object',\n ),\n )\n return\n }\n\n const blockObj = value as Record<string, unknown>\n\n // Validate children field - REQUIRED for blocks with _type: 'block'\n if (blockObj.children === undefined) {\n // children is required for Portable Text blocks\n errors.push(\n createError(\n `${path}.children`,\n 'REQUIRED_FIELD_MISSING',\n 'Block is missing required \"children\" field',\n 'undefined',\n 'Array of spans and inline objects',\n 'Provide a children array, e.g., children: [{ _type: \"span\", text: \"Hello\", _key: \"s1\", marks: [] }]',\n ),\n )\n } else if (!Array.isArray(blockObj.children)) {\n errors.push(\n createError(\n `${path}.children`,\n 'TYPE_MISMATCH',\n 'Block children must be an array',\n formatValue(blockObj.children),\n 'Array of spans and inline objects',\n 'Provide an array of children, e.g., [{ _type: \"span\", text: \"Hello\", _key: \"s1\" }]',\n ),\n )\n } else {\n // Extract markDef keys for mark reference validation\n const markDefKeys = new Set<string>()\n if (Array.isArray(blockObj.markDefs)) {\n for (const markDef of blockObj.markDefs) {\n if (typeof markDef === 'object' && markDef !== null) {\n const key = (markDef as Record<string, unknown>)._key\n if (typeof key === 'string') {\n markDefKeys.add(key)\n }\n }\n }\n }\n\n // Get allowed decorators from schema (default: strong, em, code, underline, strike-through)\n const marks = fieldSchema.marks as { decorators?: Array<{ value: string }> } | undefined\n const schemaDecorators = marks?.decorators?.map((d) => d.value) || []\n // Default decorators if not specified in schema\n const defaultDecorators = ['strong', 'em', 'code', 'underline', 'strike-through']\n const allowedDecorators = new Set(\n schemaDecorators.length > 0 ? schemaDecorators : defaultDecorators,\n )\n\n // Validate children array items\n await validateBlockChildren(\n blockObj.children,\n fieldSchema,\n `${path}.children`,\n schema,\n errors,\n context,\n markDefKeys,\n allowedDecorators,\n validateValue,\n )\n }\n\n // Validate markDefs field - MUST be an array if present\n if (blockObj.markDefs !== undefined) {\n if (!Array.isArray(blockObj.markDefs)) {\n errors.push(\n createError(\n `${path}.markDefs`,\n 'TYPE_MISMATCH',\n 'Block markDefs must be an array',\n formatValue(blockObj.markDefs),\n 'Array of annotation objects',\n 'Provide an array of markDefs, e.g., [{ _type: \"link\", _key: \"l1\", href: \"...\" }]',\n ),\n )\n } else {\n // Validate markDefs array items\n await validateBlockMarkDefs(\n blockObj.markDefs,\n fieldSchema,\n `${path}.markDefs`,\n schema,\n errors,\n context,\n validateValue,\n )\n }\n }\n\n // Validate optional scalar fields (style, listItem, level)\n // Get allowed styles from schema (default: normal, h1-h6, blockquote)\n const stylesConfig = fieldSchema.styles as Array<{ value: string }> | undefined\n const schemaStyles = stylesConfig?.map((s) => s.value) || []\n const defaultStyles = ['normal', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote']\n const allowedStyles = new Set(schemaStyles.length > 0 ? schemaStyles : defaultStyles)\n\n if (blockObj.style !== undefined) {\n if (typeof blockObj.style !== 'string') {\n errors.push(\n createError(\n `${path}.style`,\n 'TYPE_MISMATCH',\n 'Block style must be a string',\n formatValue(blockObj.style),\n 'string (e.g., \"normal\", \"h1\", \"blockquote\")',\n 'Provide a valid style string',\n ),\n )\n } else if (!allowedStyles.has(blockObj.style)) {\n const styleList = [...allowedStyles].join(', ')\n errors.push(\n createError(\n `${path}.style`,\n 'INVALID_ENUM_VALUE',\n `Block style \"${blockObj.style}\" is not allowed`,\n blockObj.style,\n `One of: ${styleList}`,\n `Use one of the allowed styles: ${styleList}`,\n ),\n )\n }\n }\n\n // Get allowed list items from schema (default: bullet, number)\n const listsConfig = fieldSchema.lists as Array<{ value: string }> | undefined\n const schemaLists = listsConfig?.map((l) => l.value) || []\n const defaultLists = ['bullet', 'number']\n const allowedLists = new Set(schemaLists.length > 0 ? schemaLists : defaultLists)\n\n if (blockObj.listItem !== undefined) {\n if (typeof blockObj.listItem !== 'string') {\n errors.push(\n createError(\n `${path}.listItem`,\n 'TYPE_MISMATCH',\n 'Block listItem must be a string',\n formatValue(blockObj.listItem),\n 'string (e.g., \"bullet\", \"number\")',\n 'Provide a valid listItem string',\n ),\n )\n } else if (!allowedLists.has(blockObj.listItem)) {\n const listItemList = [...allowedLists].join(', ')\n errors.push(\n createError(\n `${path}.listItem`,\n 'INVALID_ENUM_VALUE',\n `Block listItem \"${blockObj.listItem}\" is not allowed`,\n blockObj.listItem,\n `One of: ${listItemList}`,\n `Use one of the allowed list types: ${listItemList}`,\n ),\n )\n }\n }\n\n if (blockObj.level !== undefined && typeof blockObj.level !== 'number') {\n errors.push(\n createError(\n `${path}.level`,\n 'TYPE_MISMATCH',\n 'Block level must be a number',\n formatValue(blockObj.level),\n 'number (list nesting level, 1-based)',\n 'Provide a valid level number',\n ),\n )\n }\n\n // listItem and level are an atomic pair - if listItem exists, level is required\n if (blockObj.listItem !== undefined && blockObj.level === undefined) {\n errors.push(\n createError(\n `${path}.level`,\n 'REQUIRED_FIELD_MISSING',\n 'Block with listItem must have a level',\n 'undefined',\n 'number (list nesting level, 1-based)',\n 'Add a level property (e.g., level: 1) when using listItem',\n ),\n )\n }\n\n // Inverse: if level exists, listItem is required (atomic pair)\n if (blockObj.level !== undefined && blockObj.listItem === undefined) {\n errors.push(\n createError(\n `${path}.listItem`,\n 'REQUIRED_FIELD_MISSING',\n 'Block with level must have a listItem',\n 'undefined',\n 'string (e.g., \"bullet\", \"number\")',\n 'Add a listItem property (e.g., listItem: \"bullet\") when using level',\n ),\n )\n }\n\n // Validate custom fields defined in block schema, and check for unknown fields\n const blockFields = fieldSchema.fields || []\n if (blockFields.length > 0) {\n // Build set of valid field names (schema-defined + built-in PT fields)\n const validFieldNames = new Set(blockFields.map((f) => f.name))\n // Add built-in Portable Text fields\n validFieldNames.add('children')\n validFieldNames.add('markDefs')\n validFieldNames.add('style')\n validFieldNames.add('listItem')\n validFieldNames.add('level')\n\n // Check for unknown fields\n for (const key of Object.keys(blockObj)) {\n // Skip system fields\n if (key.startsWith('_')) continue\n\n if (!validFieldNames.has(key)) {\n const validFieldsList = [...validFieldNames].join(', ')\n errors.push(\n createError(\n `${path}.${key}`,\n 'FIELD_NOT_IN_SCHEMA',\n 'Field does not exist in block schema',\n formatValue(blockObj[key]),\n `Field must be one of: ${validFieldsList}`,\n 'Remove this field or check the schema for valid field names',\n ),\n )\n }\n }\n\n // Validate schema-defined custom fields\n for (const field of blockFields) {\n // Skip built-in PT fields (already validated above)\n if (['style', 'listItem', 'level', 'children', 'markDefs'].includes(field.name)) {\n continue\n }\n\n const fieldValue = blockObj[field.name]\n if (fieldValue !== undefined) {\n const fieldPath = `${path}.${field.name}`\n await validateValue(fieldValue, field, fieldPath, errors, context, schema)\n }\n }\n }\n}\n\n/**\n * Validate block children array.\n *\n * Children can contain:\n * - spans (_type: \"span\")\n * - inline objects (from block.of schema)\n */\nasync function validateBlockChildren(\n children: unknown[],\n blockSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n markDefKeys: Set<string>,\n allowedDecorators: Set<string>,\n validateValue: ValidateValueFn,\n): Promise<void> {\n // Get inline object types from block.of\n const inlineTypes = (blockSchema.of || []) as ManifestSchemaType[]\n\n // Track _key values for duplicate detection\n const seenKeys = new Set<string>()\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n const childPath = `${path}[${i}]`\n\n if (typeof child !== 'object' || child === null) {\n errors.push(\n createError(\n childPath,\n 'TYPE_MISMATCH',\n 'Block child must be an object',\n formatValue(child),\n 'Object (span or inline object)',\n 'Provide a span or inline object',\n ),\n )\n continue\n }\n\n const childObj = child as Record<string, unknown>\n const childType = childObj._type as string | undefined\n const childKey = childObj._key as string | undefined\n\n // Validate _key\n if (childKey === undefined) {\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n 'Block child missing \"_key\" property',\n formatValue(child),\n 'Object with _key property',\n 'Add a unique _key property to the child',\n ),\n )\n } else if (typeof childKey === 'string' && childKey !== '') {\n if (seenKeys.has(childKey)) {\n errors.push(\n createError(\n `${childPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${childKey}\" in children array`,\n childKey,\n 'Unique _key value',\n 'Ensure all children have unique _key values',\n ),\n )\n } else {\n seenKeys.add(childKey)\n }\n }\n\n // Check if this is a span\n if (childType === 'span') {\n validateSpan(childObj, childPath, errors, markDefKeys, allowedDecorators)\n continue\n }\n\n // Check if this matches an inline type from block.of\n let matchingSchema: ManifestSchemaType | undefined\n for (const inlineSchema of inlineTypes) {\n if (inlineSchema.name === childType) {\n matchingSchema = inlineSchema\n break\n }\n }\n\n if (matchingSchema) {\n // Recursively validate the inline object\n await validateValue(child, matchingSchema, childPath, errors, context, schema)\n } else if (childType) {\n // Unknown type in children\n const allowedTypes = ['span', ...inlineTypes.map((t) => t.name).filter(Boolean)]\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n `Unknown type \"${childType}\" in block children`,\n formatValue(child),\n `One of: ${allowedTypes.join(', ')}`,\n `Use one of the allowed types: ${allowedTypes.join(', ')}`,\n ),\n )\n } else {\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n 'Block child missing _type property',\n formatValue(child),\n 'Object with _type property (\"span\" or inline object type)',\n 'Add a _type property to identify the child type',\n ),\n )\n }\n }\n}\n\n/**\n * Validate a span object.\n *\n * Marks must either be:\n * 1. A decorator (strong, em, code, underline, strike-through, or custom from schema)\n * 2. A _key reference to an object in markDefs\n */\nfunction validateSpan(\n spanObj: Record<string, unknown>,\n path: string,\n errors: ValidationError[],\n markDefKeys: Set<string>,\n allowedDecorators: Set<string>,\n): void {\n // Validate text field\n if (spanObj.text === undefined) {\n errors.push(\n createError(\n `${path}.text`,\n 'REQUIRED_FIELD_MISSING',\n 'Span missing \"text\" property',\n '(not provided)',\n 'string',\n 'Add a text property to the span',\n ),\n )\n } else if (typeof spanObj.text !== 'string') {\n errors.push(\n createError(\n `${path}.text`,\n 'TYPE_MISMATCH',\n 'Span text must be a string',\n formatValue(spanObj.text),\n 'string',\n 'Provide a string value for text',\n ),\n )\n }\n\n // Validate marks field (optional, but must be array of strings if present)\n if (spanObj.marks !== undefined) {\n if (!Array.isArray(spanObj.marks)) {\n errors.push(\n createError(\n `${path}.marks`,\n 'TYPE_MISMATCH',\n 'Span marks must be an array',\n formatValue(spanObj.marks),\n 'Array of strings (decorator names or annotation _keys)',\n 'Provide an array of mark strings',\n ),\n )\n } else {\n for (let i = 0; i < spanObj.marks.length; i++) {\n const mark = spanObj.marks[i]\n if (typeof mark !== 'string') {\n errors.push(\n createError(\n `${path}.marks[${i}]`,\n 'TYPE_MISMATCH',\n 'Span mark must be a string',\n formatValue(mark),\n 'string (decorator name or annotation _key)',\n 'Provide a string mark value',\n ),\n )\n } else {\n // Mark is a string - validate it's either a decorator or a markDef key\n const isDecorator = allowedDecorators.has(mark)\n const isMarkDefRef = markDefKeys.has(mark)\n\n if (!isDecorator && !isMarkDefRef) {\n const decoratorList = [...allowedDecorators].join(', ')\n errors.push(\n createError(\n `${path}.marks[${i}]`,\n 'INVALID_MARK_REFERENCE',\n `Mark \"${mark}\" is not a valid decorator and does not reference a markDef`,\n mark,\n `Decorator (${decoratorList}) or _key from markDefs`,\n markDefKeys.size > 0\n ? `Use a decorator (${decoratorList}) or one of the markDef keys: ${[...markDefKeys].join(', ')}`\n : `Use a decorator (${decoratorList}) or add a markDef with _key \"${mark}\"`,\n ),\n )\n }\n }\n }\n }\n }\n}\n\n/**\n * Validate block markDefs array.\n *\n * markDefs contain annotations defined in block.marks.annotations.\n */\nasync function validateBlockMarkDefs(\n markDefs: unknown[],\n blockSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n // Get annotation types from block.marks.annotations\n // Default annotation type is \"link\" if none specified in schema\n const marks = blockSchema.marks as { annotations?: ManifestSchemaType[] } | undefined\n const schemaAnnotations = marks?.annotations || []\n const defaultAnnotationTypes = ['link']\n const annotationTypes = schemaAnnotations.length > 0 ? schemaAnnotations : []\n const allowedAnnotationNames =\n schemaAnnotations.length > 0\n ? schemaAnnotations.map((t) => t.name).filter(Boolean)\n : defaultAnnotationTypes\n\n // Track _key values for duplicate detection\n const seenKeys = new Set<string>()\n\n for (let i = 0; i < markDefs.length; i++) {\n const markDef = markDefs[i]\n const markPath = `${path}[${i}]`\n\n if (typeof markDef !== 'object' || markDef === null) {\n errors.push(\n createError(\n markPath,\n 'TYPE_MISMATCH',\n 'markDef must be an object',\n formatValue(markDef),\n 'Annotation object with _type and _key',\n 'Provide an annotation object',\n ),\n )\n continue\n }\n\n const markObj = markDef as Record<string, unknown>\n const markType = markObj._type as string | undefined\n const markKey = markObj._key as string | undefined\n\n // Validate _key\n if (markKey === undefined) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n 'markDef missing \"_key\" property',\n formatValue(markDef),\n 'Object with _key property',\n 'Add a unique _key property to the markDef',\n ),\n )\n } else if (typeof markKey === 'string' && markKey !== '') {\n if (seenKeys.has(markKey)) {\n errors.push(\n createError(\n `${markPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${markKey}\" in markDefs array`,\n markKey,\n 'Unique _key value',\n 'Ensure all markDefs have unique _key values',\n ),\n )\n } else {\n seenKeys.add(markKey)\n }\n }\n\n // Validate _type is present\n if (markType === undefined) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n 'markDef missing \"_type\" property',\n formatValue(markDef),\n 'Object with _type property (annotation type)',\n 'Add a _type property to identify the annotation type, e.g., { _type: \"link\", _key: \"l1\", href: \"...\" }',\n ),\n )\n continue\n }\n\n // Find matching annotation schema\n let matchingSchema: ManifestSchemaType | undefined\n for (const annSchema of annotationTypes) {\n if (annSchema.name === markType) {\n matchingSchema = annSchema\n break\n }\n }\n\n if (matchingSchema) {\n // Validate annotation fields using validateValue which will route to validateObject\n await validateValue(markDef, matchingSchema, markPath, errors, context, schema)\n } else {\n // Check if the annotation type is allowed (either from schema or default)\n if (!allowedAnnotationNames.includes(markType)) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n `Unknown annotation type \"${markType}\" in markDefs`,\n formatValue(markDef),\n `One of: ${allowedAnnotationNames.join(', ')}`,\n `Use one of the allowed annotation types: ${allowedAnnotationNames.join(', ')}`,\n ),\n )\n }\n }\n }\n}\n","/**\n * Primitive type validators (string, number, boolean, date, etc.)\n * and schema constraint validation (min, max, enum, unique).\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport {\n createError,\n formatValue,\n getActualJsType,\n getExpectedJsType,\n getUniquenessKey,\n} from './utils.js'\n\n/**\n * Resolve encoded marker values from @sanity/descriptors.\n * The descriptor encoding system uses marker objects for values that can't be\n * directly represented in EncodableValue:\n * - NumberMarker: {__type: \"number\", value: \"3\"} -> 3\n * - ObjectMarker: {__type: \"object\", value: {...}} -> the inner object\n * - UndefinedMarker: {__type: \"undefined\"} -> undefined\n */\nfunction resolveEncodedValue(v: unknown): unknown {\n if (typeof v === 'object' && v !== null && '__type' in v) {\n const marker = v as Record<string, unknown>\n if (marker.__type === 'number' && typeof marker.value === 'string') {\n return parseFloat(marker.value)\n }\n if (marker.__type === 'object' && typeof marker.value === 'object' && marker.value !== null) {\n return marker.value\n }\n if (marker.__type === 'undefined') {\n return undefined\n }\n }\n return v\n}\n\n/**\n * Validate a primitive value against its schema type.\n */\nexport function validatePrimitive(\n value: unknown,\n schemaType: string,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n): void {\n const expectedType = getExpectedJsType(schemaType)\n const actualType = getActualJsType(value)\n\n // Skip null/undefined - those are handled elsewhere (required field validation)\n if (actualType === 'null' || actualType === 'undefined') {\n return\n }\n\n // Type mismatch\n if (actualType !== expectedType) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Type mismatch',\n formatValue(value),\n expectedType,\n `Provide a ${expectedType} value`,\n ),\n )\n return\n }\n\n // Format validation for specific string types\n if (actualType === 'string') {\n const strValue = value as string\n if (schemaType === 'date') validateDate(strValue, path, errors)\n else if (schemaType === 'datetime') validateDatetime(strValue, path, errors)\n else if (schemaType === 'email') validateEmail(strValue, path, errors)\n else if (schemaType === 'url') validateUrl(strValue, path, errors, fieldSchema)\n }\n\n // Number validation\n if (actualType === 'number') {\n const numValue = value as number\n if (Number.isNaN(numValue)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid number (NaN)',\n 'NaN',\n 'A valid number',\n 'Provide a valid numeric value',\n ),\n )\n } else if (!Number.isFinite(numValue)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid number (Infinity)',\n numValue > 0 ? 'Infinity' : '-Infinity',\n 'A finite number',\n 'Provide a valid finite numeric value',\n ),\n )\n }\n }\n}\n\n/** Validate ISO date format (YYYY-MM-DD) and value correctness. */\nfunction validateDate(value: string, path: string, errors: ValidationError[]): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date format',\n formatValue(value),\n 'ISO date format (YYYY-MM-DD)',\n 'Provide a date like \"2024-01-15\"',\n ),\n )\n return\n }\n\n const parsed = new Date(`${value}T00:00:00Z`)\n if (Number.isNaN(parsed.getTime())) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date value',\n formatValue(value),\n 'A valid date (e.g., month 01-12, valid day for month)',\n 'Provide a valid date like \"2024-01-15\"',\n ),\n )\n return\n }\n\n // Check that the date components match (to catch invalid dates like 2024-02-30)\n const [year, month, day] = value.split('-').map(Number)\n if (\n parsed.getUTCFullYear() !== year ||\n parsed.getUTCMonth() + 1 !== month ||\n parsed.getUTCDate() !== day\n ) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date value',\n formatValue(value),\n 'A valid date (e.g., valid day for the given month)',\n 'Provide a valid date like \"2024-01-15\"',\n ),\n )\n }\n}\n\n/** Validate ISO datetime format and value correctness. */\nfunction validateDatetime(value: string, path: string, errors: ValidationError[]): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime format',\n formatValue(value),\n 'ISO datetime format (YYYY-MM-DDTHH:mm:ss)',\n 'Provide a datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n return\n }\n\n const parsed = new Date(value)\n if (Number.isNaN(parsed.getTime())) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid datetime (valid date and time components)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n return\n }\n\n // Validate date components (to catch invalid dates like 2024-02-30)\n const datePart = value.slice(0, 10)\n const [year, month, day] = datePart.split('-').map(Number)\n if (\n parsed.getUTCFullYear() !== year ||\n parsed.getUTCMonth() + 1 !== month ||\n parsed.getUTCDate() !== day\n ) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid datetime (valid day for the given month)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n }\n\n // Validate time components (hour 0-23, minute 0-59)\n const timeMatch = value.match(/T(\\d{2}):(\\d{2}):(\\d{2})/)\n if (timeMatch) {\n const [, hour, minute] = timeMatch.map(Number)\n if (hour > 23 || minute > 59) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid time (hour 00-23, minute 00-59)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n }\n }\n}\n\n/** Validate email format. */\nfunction validateEmail(value: string, path: string, errors: ValidationError[]): void {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid email format',\n formatValue(value),\n 'Valid email address (e.g., \"user@example.com\")',\n 'Provide a valid email address',\n ),\n )\n }\n}\n\n/** Validate URL format, with optional allowRelative support from schema. */\nfunction validateUrl(\n value: string,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n): void {\n const allowRelative = fieldSchema?.validation?.some((group) =>\n group.rules.some(\n (rule) =>\n ((rule as Record<string, unknown>).type === 'uri' || rule.flag === 'uri') &&\n (rule as Record<string, unknown>).allowRelative === true,\n ),\n )\n\n // Relative URLs are valid when the schema explicitly allows them\n if (allowRelative && value.startsWith('/')) {\n return\n }\n\n try {\n new URL(value)\n } catch {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid URL format',\n formatValue(value),\n allowRelative\n ? 'Valid URL (e.g., \"https://example.com\" or \"/path\")'\n : 'Valid URL (e.g., \"https://example.com\")',\n allowRelative\n ? 'Provide a valid URL starting with http://, https://, or /'\n : 'Provide a valid URL starting with http:// or https://',\n ),\n )\n }\n}\n\n/**\n * Validate a value against schema validation rules (min, max, enum, uniqueItems).\n *\n * Supports two schema formats:\n * - Manifest format: { flag: 'min', constraint: 5 }\n * - Encoded format (from @sanity/descriptors): { type: 'minimum', value: '5' }\n */\nexport function validateSchemaRules(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n warnings?: ValidationError[],\n): void {\n if (!fieldSchema.validation) return\n\n for (const group of fieldSchema.validation) {\n // Warning-level violations are non-blocking — they go to warnings (if provided) instead of errors.\n const isWarning = group.level === 'warning' || group.level === 'info'\n const target = isWarning ? (warnings ?? null) : errors\n if (target === null) continue\n\n for (const rule of group.rules) {\n const r = rule as Record<string, unknown>\n const ruleType = (r.type as string) || r.flag\n\n if (ruleType === 'min' || ruleType === 'minimum') {\n validateBound(value, 'min', getConstraint(r), path, target)\n } else if (ruleType === 'max' || ruleType === 'maximum') {\n validateBound(value, 'max', getConstraint(r), path, target)\n } else if (ruleType === 'enum') {\n validateEnum(value, r, path, target)\n } else if (ruleType === 'regex') {\n validateRegex(value, r, path, target)\n } else if (ruleType === 'unique' || ruleType === 'uniqueItems') {\n validateUniqueRule(value, path, target)\n }\n }\n }\n}\n\n/** Get numeric constraint from either manifest format (constraint) or encoded format (value). */\nfunction getConstraint(r: Record<string, unknown>): number | undefined {\n if (r.value !== undefined) return parseFloat(r.value as string)\n if (r.constraint !== undefined) return r.constraint as number\n return undefined\n}\n\n/** Validate min or max bound for strings (length), numbers (value), and arrays (length). */\nfunction validateBound(\n value: unknown,\n direction: 'min' | 'max',\n bound: number | undefined,\n path: string,\n target: ValidationError[],\n): void {\n if (bound === undefined) return\n\n const isMin = direction === 'min'\n const fails = isMin ? (actual: number) => actual < bound : (actual: number) => actual > bound\n\n if (typeof value === 'string' && fails(value.length)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin\n ? `Value is below minimum length of ${bound}`\n : `Value exceeds maximum length of ${bound}`,\n `${value.length} characters`,\n `${isMin ? 'At least' : 'At most'} ${bound} characters`,\n `Provide a value with ${isMin ? 'at least' : 'at most'} ${bound} characters`,\n ),\n )\n } else if (typeof value === 'number' && fails(value)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin ? `Value is below minimum of ${bound}` : `Value exceeds maximum of ${bound}`,\n String(value),\n `${isMin ? 'At least' : 'At most'} ${bound}`,\n `Provide a value of ${isMin ? 'at least' : 'at most'} ${bound}`,\n ),\n )\n } else if (Array.isArray(value) && fails(value.length)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin ? `Array has fewer than ${bound} items` : `Array has more than ${bound} items`,\n `${value.length} items`,\n `${isMin ? 'At least' : 'At most'} ${bound} items`,\n `Provide ${isMin ? 'at least' : 'at most'} ${bound} items`,\n ),\n )\n }\n}\n\n/** Validate value against an enum constraint. For arrays, checks each item. */\nfunction validateEnum(\n value: unknown,\n r: Record<string, unknown>,\n path: string,\n target: ValidationError[],\n): void {\n const allowedValues = (r.values as unknown[]) || (r.constraint as unknown[])\n if (!allowedValues) return\n\n const resolvedValues = allowedValues.map(resolveEncodedValue)\n const formatAllowed = () => resolvedValues.map((v) => JSON.stringify(v)).join(', ')\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n if (!resolvedValues.includes(value[i])) {\n target.push(\n createError(\n `${path}[${i}]`,\n 'INVALID_ENUM_VALUE',\n 'Array item is not one of the allowed options',\n formatValue(value[i]),\n `One of: ${formatAllowed()}`,\n `Use one of the allowed values: ${formatAllowed()}`,\n ),\n )\n }\n }\n } else if (!resolvedValues.includes(value)) {\n target.push(\n createError(\n path,\n 'INVALID_ENUM_VALUE',\n 'Value is not one of the allowed options',\n formatValue(value),\n `One of: ${formatAllowed()}`,\n `Use one of the allowed values: ${formatAllowed()}`,\n ),\n )\n }\n}\n\n/** Validate a string value against a regex pattern. */\nfunction validateRegex(\n value: unknown,\n r: Record<string, unknown>,\n path: string,\n target: ValidationError[],\n): void {\n if (!r.pattern || typeof value !== 'string') return\n\n const pattern = r.pattern as string\n const flags = (r.flags as string) || ''\n\n try {\n const regex = new RegExp(pattern, flags)\n if (!regex.test(value)) {\n target.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Value does not match required regex pattern',\n formatValue(value),\n `String matching pattern: ${pattern}`,\n 'Provide a value that matches the required format',\n ),\n )\n }\n } catch {\n // Invalid regex pattern — skip rather than error\n }\n}\n\n/** Validate that an array contains no duplicate items. */\nfunction validateUniqueRule(value: unknown, path: string, target: ValidationError[]): void {\n if (!Array.isArray(value)) return\n\n const seen = new Set<string>()\n for (let i = 0; i < value.length; i++) {\n const key = getUniquenessKey(value[i])\n if (seen.has(key)) {\n target.push(\n createError(\n `${path}[${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Duplicate item in array with unique constraint',\n formatValue(value[i]),\n 'Unique array items',\n 'Remove or modify duplicate items in the array',\n ),\n )\n break // Only report first duplicate\n }\n seen.add(key)\n }\n}\n","/**\n * Reference validator - validates document references.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue, validateNoExtraProperties } from './utils.js'\n\n/**\n * Validate a reference value.\n * Checks structure and optionally validates existence via client.\n */\nexport async function validateReference(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n context: ValidationContext,\n): Promise<void> {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid reference value',\n formatValue(value),\n 'Object with { _type: \"reference\", _ref: \"document-id\" }',\n 'Provide a reference object like { _type: \"reference\", _ref: \"person-123\" }',\n ),\n )\n return\n }\n\n const refObj = value as Record<string, unknown>\n\n // Global document references (e.g. media library links) are cross-system —\n // skip validation, just ensure _weak is set.\n if (refObj._type === 'globalDocumentReference') {\n return\n }\n\n // Check _ref exists and is not empty\n if (typeof refObj._ref !== 'string') {\n errors.push(\n createError(\n `${path}._ref`,\n 'INVALID_REFERENCE',\n 'Reference missing \"_ref\" property',\n formatValue(refObj._ref),\n 'string (document ID)',\n 'Provide a valid document ID in the _ref property',\n ),\n )\n return\n }\n\n // Check _ref is not empty\n if (refObj._ref === '') {\n errors.push(\n createError(\n `${path}._ref`,\n 'INVALID_REFERENCE',\n 'Reference \"_ref\" cannot be empty',\n '\"\"',\n 'Non-empty string (document ID)',\n 'Provide a valid document ID in the _ref property',\n ),\n )\n return\n }\n\n // Check for extra properties not allowed on references\n const allowedReferenceProperties = new Set([\n '_ref',\n '_type',\n '_weak',\n '_key',\n '_strengthenOnPublish',\n ])\n validateNoExtraProperties(refObj, allowedReferenceProperties, path, 'reference', errors)\n\n // Get allowed target types from schema\n const allowedTypes: string[] = []\n if (fieldSchema.to && Array.isArray(fieldSchema.to)) {\n for (const target of fieldSchema.to) {\n const targetType = (target as { type?: string }).type\n if (targetType) {\n allowedTypes.push(targetType)\n }\n }\n }\n\n // Weak references are allowed to dangle — skip existence check.\n // Structure validation (above) still applies.\n if (refObj._weak) {\n return\n }\n\n // Validate reference exists via client (if available)\n if (context.client) {\n try {\n const doc = await context.client.getDocument(refObj._ref as string)\n\n if (!doc) {\n errors.push(\n createError(\n `${path}._ref`,\n 'REFERENCE_NOT_FOUND',\n 'Referenced document does not exist',\n formatValue(refObj._ref),\n allowedTypes.length > 0\n ? `Valid document ID of type \"${allowedTypes.join('\" or \"')}\"`\n : 'Valid document ID',\n 'Use an existing document ID, or create the document first',\n ),\n )\n return\n }\n\n // Check document type matches allowed types\n if (allowedTypes.length > 0 && !allowedTypes.includes(doc._type)) {\n errors.push(\n createError(\n `${path}._ref`,\n 'REFERENCE_WRONG_TYPE',\n 'Reference points to wrong document type',\n `Document \"${refObj._ref}\" (type: ${doc._type})`,\n `Reference to document of type \"${allowedTypes.join('\" or \"')}\"`,\n `Use a document ID that references a \"${allowedTypes[0]}\" document`,\n ),\n )\n }\n } catch {\n // Network error or other issue - skip existence validation\n // The error will be caught at commit time\n }\n }\n}\n","/**\n * Walks a document and reports paths where a schema-required field is missing.\n *\n * Recurses into nested objects and array items so required fields anywhere\n * in the tree are caught. When a parent is missing, the report stops at the\n * parent rather than enumerating every required descendant.\n *\n * No cycle guard is needed: recursion is bounded by document data, not by the\n * schema graph. Self-referencing object types only recurse as deep as the data\n * actually nests.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport { joinSchemaPath } from '../navigate/walkTree.js'\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\nimport { hasRequiredValidator } from './rules'\nimport type { ValidationError } from './types'\nimport { createError, formatValue } from './utils'\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isMissing = (value: unknown): boolean => {\n if (value === undefined || value === null) return true\n if (typeof value === 'string') return value.length === 0\n if (Array.isArray(value)) return value.length === 0\n return false\n}\n\nconst missingRequiredError = (path: string, field: ManifestField): ValidationError =>\n createError(\n path,\n 'REQUIRED_FIELD_MISSING',\n `Required field \"${field.name}\" is missing`,\n formatValue(undefined),\n `${field.title ?? field.name} (${field.type})`,\n `Set a value for \"${field.name}\" before publishing`,\n )\n\nconst itemPath = (parent: string, item: Record<string, unknown>, index: number): string => {\n const key = item._key\n return typeof key === 'string' ? `${parent}[_key==\"${key}\"]` : `${parent}[${index}]`\n}\n\nconst resolveItemFields = (\n itemSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): ManifestField[] | undefined => {\n // Inline object items in `of` declare their own fields.\n if (itemSchema.fields?.length) return itemSchema.fields\n if (!itemSchema.type || isPrimitiveType(itemSchema.type)) return undefined\n const referenced = schema.find((s) => s.name === itemSchema.type)\n return referenced?.fields\n}\n\nfunction walkArray(\n field: ManifestField,\n value: unknown[],\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n if (!field.of?.length) return\n\n for (let index = 0; index < value.length; index++) {\n const item = value[index]\n if (!isPlainObject(item)) continue\n\n const matched = field.of.find((member) => member.type === item._type) ?? field.of[0]\n const itemFields = resolveItemFields(matched as ManifestSchemaType, schema)\n if (!itemFields?.length) continue\n\n walkFields(itemFields, item, itemPath(path, item, index), schema, errors)\n }\n}\n\nfunction walkFields(\n fields: ManifestField[],\n value: unknown,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n const obj = isPlainObject(value) ? value : {}\n\n for (const field of fields) {\n const fieldValue = obj[field.name]\n const fieldPath = joinSchemaPath(path, field.name)\n\n if (hasRequiredValidator(field) && isMissing(fieldValue)) {\n errors.push(missingRequiredError(fieldPath, field))\n continue\n }\n\n if (isMissing(fieldValue)) continue\n\n if (Array.isArray(fieldValue)) {\n walkArray(field, fieldValue, fieldPath, schema, errors)\n continue\n }\n\n if (field.fields?.length) {\n walkFields(field.fields, fieldValue, fieldPath, schema, errors)\n continue\n }\n\n if (!field.type || isPrimitiveType(field.type)) continue\n const referenced = schema.find((s) => s.name === field.type)\n if (referenced?.fields?.length) {\n walkFields(referenced.fields, fieldValue, fieldPath, schema, errors)\n }\n }\n}\n\nexport function validateRequiredFields(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n): ValidationError[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema?.fields?.length) return []\n\n const errors: ValidationError[] = []\n walkFields(typeSchema.fields, document, '', schema, errors)\n return errors\n}\n","/**\n * Detects slug collisions before publishing.\n *\n * Mirrors Studio's default `isUnique` behavior (cross-document-type uniqueness).\n * If a schema customizes `options.isUnique`, we cannot replicate the function:\n * the manifest serializes it as `{ __type: 'function' }`. We skip the check\n * for that field and let the server/Studio surface the real error after publish.\n *\n * Only top-level slug fields are checked. Nested slugs in arrays/objects are\n * uncommon and require path semantics we don't have here yet.\n */\n\nimport type { SanityClient } from '@sanity/client'\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types'\nimport { createError, formatValue } from './utils'\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\ntype SlugField = {\n path: string\n field: ManifestField\n current: string\n}\n\n/** True when the field is a slug, including aliased custom types that extend slug. */\nconst isSlugType = (field: ManifestField, schema: ManifestSchemaType[]): boolean => {\n if (field.type === 'slug') return true\n const referenced = schema.find((s) => s.name === field.type)\n return referenced?.type === 'slug'\n}\n\nconst hasCustomIsUnique = (field: ManifestField): boolean => {\n const isUnique = field.options?.isUnique\n return isPlainObject(isUnique) && isUnique.__type === 'function'\n}\n\nconst readSlugCurrent = (value: unknown): string | undefined => {\n if (!isPlainObject(value)) return undefined\n const current = value.current\n return typeof current === 'string' && current.length > 0 ? current : undefined\n}\n\nfunction collectSlugFields(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n): SlugField[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema?.fields?.length) return []\n\n const out: SlugField[] = []\n for (const field of typeSchema.fields) {\n if (!isSlugType(field, schema)) continue\n const current = readSlugCurrent(document[field.name])\n if (current === undefined) continue\n out.push({ path: field.name, field, current })\n }\n return out\n}\n\nconst collisionError = (path: string, current: string, conflictingId: string): ValidationError =>\n createError(\n `${path}.current`,\n 'INVALID_FORMAT',\n `Slug \"${current}\" is already in use by another document`,\n formatValue(current),\n 'A slug not used by any other document',\n `Choose a different slug for \"${path}\". The conflicting document is \"${conflictingId}\".`,\n )\n\n/**\n * Check whether the slug values on a draft collide with any other document in\n * the dataset (excluding the draft and its published twin).\n */\nexport async function validateSlugCollisions(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n client: SanityClient,\n ids: { publishedId: string; draftId: string },\n): Promise<ValidationError[]> {\n const slugs = collectSlugFields(document, documentType, schema)\n if (slugs.length === 0) return []\n\n const checks = await Promise.all(\n slugs.map(async ({ path, field, current }) => {\n if (hasCustomIsUnique(field)) return undefined\n\n // Mirrors Studio's default `defaultIsUnique`: cross-document-type, excluding\n // both ID variants of the document being published.\n //\n // `path` is interpolated rather than parameterized because GROQ does not\n // support parameterizing field paths. The value comes from a schema field\n // name, which the manifest constrains to safe identifiers.\n const query = `*[!(_id in [$publishedId, $draftId]) && ${path}.current == $slug][0]._id`\n const conflictingId = await client.fetch<string | null>(query, {\n publishedId: ids.publishedId,\n draftId: ids.draftId,\n slug: current,\n })\n\n return conflictingId ? collisionError(path, current, conflictingId) : undefined\n }),\n )\n\n return checks.filter((e): e is ValidationError => e !== undefined)\n}\n","/**\n * Validators for special Sanity types: slug, geopoint, image, file.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport {\n createError,\n formatValue,\n getActualJsType,\n getExpectedJsType,\n validateNoExtraProperties,\n} from './utils.js'\n\n/**\n * Validate a slug value.\n */\nexport function validateSlug(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid slug value',\n formatValue(value),\n 'Object with { _type: \"slug\", current: \"slug-value\" }',\n 'Provide a slug object like { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n return\n }\n\n const slugObj = value as Record<string, unknown>\n\n // Validate _type is \"slug\" if present\n if (slugObj._type !== undefined && slugObj._type !== 'slug') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Slug has wrong _type value',\n formatValue(slugObj._type),\n '_type: \"slug\"',\n 'Set _type to \"slug\", e.g., { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n }\n\n if (typeof slugObj.current !== 'string') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Slug missing \"current\" property',\n formatValue(value),\n 'Object with \"current\" string property',\n 'Add a \"current\" property with the slug string, e.g., { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n }\n\n // Check for extra properties\n const allowedSlugProperties = new Set(['_type', 'current'])\n validateNoExtraProperties(slugObj, allowedSlugProperties, path, 'slug', errors)\n}\n\n/**\n * Validate a geopoint value.\n */\nexport function validateGeopoint(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid geopoint value',\n formatValue(value),\n 'Object with { _type: \"geopoint\", lat: number, lng: number }',\n 'Provide a geopoint object like { _type: \"geopoint\", lat: 37.7749, lng: -122.4194 }',\n ),\n )\n return\n }\n\n const geoObj = value as Record<string, unknown>\n\n // Validate latitude\n if (typeof geoObj.lat !== 'number') {\n errors.push(\n createError(\n `${path}.lat`,\n 'TYPE_MISMATCH',\n 'Geopoint missing valid \"lat\" property',\n formatValue(geoObj.lat),\n 'number (latitude in degrees)',\n 'Provide a numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (Number.isNaN(geoObj.lat)) {\n errors.push(\n createError(\n `${path}.lat`,\n 'TYPE_MISMATCH',\n 'Geopoint latitude is NaN',\n 'NaN',\n 'A valid numeric latitude (-90 to 90)',\n 'Provide a valid numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (!Number.isFinite(geoObj.lat)) {\n errors.push(\n createError(\n `${path}.lat`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint latitude is infinite',\n geoObj.lat > 0 ? 'Infinity' : '-Infinity',\n 'A finite numeric latitude (-90 to 90)',\n 'Provide a valid numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (geoObj.lat < -90 || geoObj.lat > 90) {\n errors.push(\n createError(\n `${path}.lat`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint latitude out of range',\n String(geoObj.lat),\n 'Latitude between -90 and 90 degrees',\n 'Provide a latitude between -90 and 90, e.g., 37.7749',\n ),\n )\n }\n\n // Validate longitude\n if (typeof geoObj.lng !== 'number') {\n errors.push(\n createError(\n `${path}.lng`,\n 'TYPE_MISMATCH',\n 'Geopoint missing valid \"lng\" property',\n formatValue(geoObj.lng),\n 'number (longitude in degrees)',\n 'Provide a numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (Number.isNaN(geoObj.lng)) {\n errors.push(\n createError(\n `${path}.lng`,\n 'TYPE_MISMATCH',\n 'Geopoint longitude is NaN',\n 'NaN',\n 'A valid numeric longitude (-180 to 180)',\n 'Provide a valid numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (!Number.isFinite(geoObj.lng)) {\n errors.push(\n createError(\n `${path}.lng`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint longitude is infinite',\n geoObj.lng > 0 ? 'Infinity' : '-Infinity',\n 'A finite numeric longitude (-180 to 180)',\n 'Provide a valid numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (geoObj.lng < -180 || geoObj.lng > 180) {\n errors.push(\n createError(\n `${path}.lng`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint longitude out of range',\n String(geoObj.lng),\n 'Longitude between -180 and 180 degrees',\n 'Provide a longitude between -180 and 180, e.g., -122.4194',\n ),\n )\n }\n\n // Check for extra properties\n const allowedGeopointProperties = new Set(['_type', 'lat', 'lng', 'alt'])\n validateNoExtraProperties(geoObj, allowedGeopointProperties, path, 'geopoint', errors)\n}\n\n/**\n * Validate an image value structure.\n * Note: Asset existence is validated separately in reference validation.\n */\nexport function validateImage(\n value: unknown,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n schema?: ManifestSchemaType[],\n): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid image value',\n formatValue(value),\n 'Object with { _type: \"image\", asset: { _type: \"reference\", _ref: \"...\" } }',\n 'Provide an image object or use the create-image tool',\n ),\n )\n return\n }\n\n // Image can be empty (no asset yet) or have an asset reference\n const imgObj = value as Record<string, unknown>\n\n // Validate _type is \"image\" or matches the custom type name (e.g. \"ImageDefault\")\n if (\n imgObj._type !== undefined &&\n imgObj._type !== 'image' &&\n imgObj._type !== fieldSchema?.name\n ) {\n errors.push(\n createError(\n `${path}._type`,\n 'TYPE_MISMATCH',\n 'Image must have _type: \"image\"',\n formatValue(imgObj._type),\n '_type: \"image\"',\n 'Set _type to \"image\"',\n ),\n )\n }\n\n // If there's an asset, validate its structure\n if (imgObj.asset !== undefined && imgObj.asset !== null) {\n const asset = imgObj.asset as Record<string, unknown>\n\n // Validate asset._ref first (most common error)\n if (typeof asset._ref !== 'string') {\n errors.push(\n createError(\n `${path}.asset._ref`,\n 'TYPE_MISMATCH',\n 'Image asset missing \"_ref\" property',\n formatValue(asset._ref),\n 'string (asset document ID)',\n 'Provide a valid asset reference like { _type: \"reference\", _ref: \"image-abc123-...\" }',\n ),\n )\n }\n\n // Validate asset._type is \"reference\"\n if (asset._type !== 'reference') {\n errors.push(\n createError(\n `${path}.asset._type`,\n 'TYPE_MISMATCH',\n 'Image asset must have _type: \"reference\"',\n formatValue(asset._type),\n '_type: \"reference\"',\n 'Set asset._type to \"reference\", e.g., { _type: \"reference\", _ref: \"image-abc123-...\" }',\n ),\n )\n }\n }\n\n // Validate hotspot if present\n if (imgObj.hotspot !== undefined && imgObj.hotspot !== null) {\n const hotspot = imgObj.hotspot as Record<string, unknown>\n\n // Validate hotspot properties are numbers in range 0-1\n const hotspotProps = ['x', 'y', 'height', 'width'] as const\n for (const prop of hotspotProps) {\n if (hotspot[prop] !== undefined) {\n if (typeof hotspot[prop] !== 'number') {\n errors.push(\n createError(\n `${path}.hotspot.${prop}`,\n 'TYPE_MISMATCH',\n `Hotspot ${prop} must be a number`,\n formatValue(hotspot[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for hotspot.${prop}`,\n ),\n )\n } else if ((hotspot[prop] as number) < 0 || (hotspot[prop] as number) > 1) {\n errors.push(\n createError(\n `${path}.hotspot.${prop}`,\n 'VALUE_OUT_OF_RANGE',\n `Hotspot ${prop} out of range`,\n String(hotspot[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for hotspot.${prop}`,\n ),\n )\n }\n }\n }\n }\n\n // Validate crop if present\n if (imgObj.crop !== undefined && imgObj.crop !== null) {\n const crop = imgObj.crop as Record<string, unknown>\n\n // Validate crop properties are numbers in range 0-1\n const cropProps = ['top', 'bottom', 'left', 'right'] as const\n for (const prop of cropProps) {\n if (crop[prop] !== undefined) {\n if (typeof crop[prop] !== 'number') {\n errors.push(\n createError(\n `${path}.crop.${prop}`,\n 'TYPE_MISMATCH',\n `Crop ${prop} must be a number`,\n formatValue(crop[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for crop.${prop}`,\n ),\n )\n } else if ((crop[prop] as number) < 0 || (crop[prop] as number) > 1) {\n errors.push(\n createError(\n `${path}.crop.${prop}`,\n 'VALUE_OUT_OF_RANGE',\n `Crop ${prop} out of range`,\n String(crop[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for crop.${prop}`,\n ),\n )\n }\n }\n }\n }\n\n // Validate custom metadata fields if schema is provided\n if (fieldSchema?.fields && schema) {\n for (const field of fieldSchema.fields) {\n const fieldValue = imgObj[field.name]\n if (fieldValue !== undefined && fieldValue !== null) {\n // Basic type validation for custom metadata fields\n const expectedType = getExpectedJsType(field.type)\n const actualType = getActualJsType(fieldValue)\n if (actualType !== expectedType) {\n errors.push(\n createError(\n `${path}.${field.name}`,\n 'TYPE_MISMATCH',\n `Image metadata field \"${field.name}\" has wrong type`,\n formatValue(fieldValue),\n expectedType,\n `Provide a ${expectedType} value for ${field.name}`,\n ),\n )\n }\n }\n }\n }\n\n // Check for extra properties - include built-in image properties + any schema-defined fields\n // _key is allowed because images can be array items\n const allowedImageProperties = new Set(['_type', '_key', 'asset', 'hotspot', 'crop'])\n\n // Add fields defined in schema.fields\n if (fieldSchema?.fields) {\n for (const field of fieldSchema.fields) {\n allowedImageProperties.add(field.name)\n }\n }\n\n // Add fields from options (captionField, aiAssist.imageDescriptionField)\n if (fieldSchema?.options) {\n const options = fieldSchema.options as Record<string, unknown>\n\n // Handle options.captionField\n if (typeof options.captionField === 'string') {\n allowedImageProperties.add(options.captionField)\n }\n\n // Handle options.aiAssist.imageDescriptionField\n if (options.aiAssist && typeof options.aiAssist === 'object') {\n const aiAssist = options.aiAssist as Record<string, unknown>\n if (typeof aiAssist.imageDescriptionField === 'string') {\n allowedImageProperties.add(aiAssist.imageDescriptionField)\n }\n }\n }\n\n validateNoExtraProperties(imgObj, allowedImageProperties, path, 'image', errors)\n}\n\n/**\n * Validate a file value structure.\n */\nexport function validateFile(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid file value',\n formatValue(value),\n 'Object with { _type: \"file\", asset: { _type: \"reference\", _ref: \"...\" } }',\n 'Provide a file object with an asset reference',\n ),\n )\n return\n }\n\n const fileObj = value as Record<string, unknown>\n\n // Validate _type is \"file\"\n if (fileObj._type !== undefined && fileObj._type !== 'file') {\n errors.push(\n createError(\n `${path}._type`,\n 'TYPE_MISMATCH',\n 'File must have _type: \"file\"',\n formatValue(fileObj._type),\n '_type: \"file\"',\n 'Set _type to \"file\"',\n ),\n )\n }\n\n // If there's an asset, validate its structure\n if (fileObj.asset !== undefined && fileObj.asset !== null) {\n const asset = fileObj.asset as Record<string, unknown>\n\n // Validate asset._type is \"reference\"\n if (asset._type !== 'reference') {\n errors.push(\n createError(\n `${path}.asset._type`,\n 'TYPE_MISMATCH',\n 'File asset must have _type: \"reference\"',\n formatValue(asset._type),\n '_type: \"reference\"',\n 'Set asset._type to \"reference\", e.g., { _type: \"reference\", _ref: \"file-abc123-...\" }',\n ),\n )\n }\n\n if (typeof asset._ref !== 'string') {\n errors.push(\n createError(\n `${path}.asset._ref`,\n 'TYPE_MISMATCH',\n 'File asset missing \"_ref\" property',\n formatValue(asset._ref),\n 'string (asset document ID)',\n 'Provide a valid asset reference like { _type: \"reference\", _ref: \"file-abc123-...\" }',\n ),\n )\n }\n }\n\n // Check for extra properties\n // _key is allowed because files can be array items\n const allowedFileProperties = new Set(['_type', '_key', 'asset'])\n validateNoExtraProperties(fileObj, allowedFileProperties, path, 'file', errors)\n}\n","/**\n * Core recursive validator that dispatches to type-specific validators.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { validateArray } from './array.validator.js'\nimport { validateObject } from './object.validator.js'\nimport { validateBlock } from './portable-text.validator.js'\nimport { validatePrimitive, validateSchemaRules } from './primitive.validator.js'\nimport { validateReference } from './reference.validator.js'\nimport {\n validateFile,\n validateGeopoint,\n validateImage,\n validateSlug,\n} from './special-types.validator.js'\nimport type { ValidationContext, ValidationError } from './types.js'\n\n/**\n * Validate a single value against its schema.\n * This is the core recursive validator that dispatches to type-specific validators.\n */\nexport async function validateValue(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n context: ValidationContext,\n schema: ManifestSchemaType[],\n warnings?: ValidationError[],\n): Promise<void> {\n const schemaType = fieldSchema.type\n\n // Handle null/undefined - we don't enforce required fields\n if (value === null || value === undefined) {\n return\n }\n\n // Validate against schema validation rules (min, max, enum, uniqueItems)\n validateSchemaRules(value, fieldSchema, path, errors, warnings)\n\n // Route to appropriate validator based on type\n switch (schemaType) {\n // Primitive types\n case 'string':\n case 'text':\n case 'number':\n case 'boolean':\n case 'date':\n case 'datetime':\n case 'url':\n case 'email':\n validatePrimitive(value, schemaType, path, errors, fieldSchema)\n break\n\n // Special types\n case 'slug':\n validateSlug(value, path, errors)\n break\n\n case 'geopoint':\n validateGeopoint(value, path, errors)\n break\n\n case 'image':\n validateImage(value, path, errors, fieldSchema, schema)\n break\n\n case 'file':\n validateFile(value, path, errors)\n break\n\n case 'reference':\n await validateReference(value, fieldSchema, path, errors, context)\n break\n\n // Array type\n case 'array':\n await validateArray(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Block type (Portable Text) - special validation\n case 'block':\n await validateBlock(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Object/document types\n case 'object':\n case 'document':\n await validateObject(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Custom types - look up in schema\n default: {\n const customSchema = schema.find((s) => s.name === schemaType)\n if (customSchema) {\n // Determine actual type from custom schema\n const actualType = customSchema.type\n if (actualType === 'array') {\n await validateArray(value, customSchema, path, schema, errors, context, validateValue)\n } else if (actualType === 'object' || actualType === 'document') {\n await validateObject(value, customSchema, path, schema, errors, context, validateValue)\n } else if (actualType === 'reference') {\n await validateReference(value, customSchema, path, errors, context)\n } else if (isPrimitiveType(actualType)) {\n validatePrimitive(value, actualType, path, errors)\n } else {\n // Nested custom type - recurse\n await validateValue(value, customSchema, path, errors, context, schema)\n }\n }\n // Unknown type - skip validation\n break\n }\n }\n}\n","/**\n * Pre-publish validation pipeline.\n *\n * Reuses the structural validator (`validateValue` via `validateObject`) for\n * type and value checks, then layers on:\n * - required-field presence (the structural validator skips this for unset fields)\n * - slug uniqueness across the dataset\n *\n * Custom validators (`Rule.custom(...)`) cannot be replicated because function\n * bodies aren't serialized into the manifest. Use `detectCustomValidators` to\n * identify affected paths and surface them to the user before publishing.\n */\n\nimport type { SanityClient } from '@sanity/client'\nimport type { ManifestSchemaType } from '../types.js'\nimport { validateObject } from './object.validator'\nimport { validateRequiredFields } from './requiredFields'\nimport { validateSlugCollisions } from './slugCollisions'\nimport type { ValidationError, ValidationResult } from './types'\nimport { createError } from './utils'\nimport { validateValue } from './validate-value'\n\ntype ValidateForPublishInput = {\n document: Record<string, unknown>\n documentType: string\n schema: ManifestSchemaType[]\n client: SanityClient\n publishedId: string\n draftId: string\n}\n\nexport async function validateForPublish({\n document,\n documentType,\n schema,\n client,\n publishedId,\n draftId,\n}: ValidateForPublishInput): Promise<ValidationResult> {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) {\n return {\n valid: false,\n errors: [\n createError(\n '_type',\n 'FIELD_NOT_IN_SCHEMA',\n `Document type \"${documentType}\" not found in schema`,\n documentType,\n 'Valid document type',\n 'Check the schema for valid document type names',\n ),\n ],\n warnings: [],\n }\n }\n\n const structuralErrors: ValidationError[] = []\n\n const [, slugs] = await Promise.all([\n validateObject(\n document,\n typeSchema,\n '',\n schema,\n structuralErrors,\n { documentType, client },\n validateValue,\n ),\n validateSlugCollisions(document, documentType, schema, client, { publishedId, draftId }),\n ])\n const required = validateRequiredFields(document, documentType, schema)\n\n const errors = [...structuralErrors, ...required, ...slugs]\n return { valid: errors.length === 0, errors, warnings: [] }\n}\n"],"names":["validateValue","itemPath","languageIds","getValueAtPathWithKeys","isPlainObject"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/validation/utils.ts","../../src/validation/array.validator.ts","../../src/validation/rules.ts","../../src/validation/customValidators.ts","../../src/validation/document-path-resolver.ts","../../src/validation/language.validator.ts","../../src/validation/object.validator.ts","../../src/validation/path-validation.ts","../../src/validation/portable-text.validator.ts","../../src/validation/primitive.validator.ts","../../src/validation/reference.validator.ts","../../src/validation/requiredFields.ts","../../src/validation/slugCollisions.ts","../../src/validation/special-types.validator.ts","../../src/validation/validate-value.ts","../../src/validation/validateForPublish.ts"],"sourcesContent":["/**\n * Shared utility functions for the validation system.\n */\n\nimport type { ValidationError, ValidationErrorCode } from './types.js'\n\n/**\n * Create a validation error with consistent formatting.\n */\nexport function createError(\n path: string,\n code: ValidationErrorCode,\n message: string,\n received: string,\n expected: string,\n fix: string,\n): ValidationError {\n return { path, code, message, received, expected, fix }\n}\n\n/**\n * Format a value for display in error messages.\n * Handles truncation for long values.\n */\nexport function formatValue(value: unknown): string {\n if (value === undefined) return '(not provided)'\n if (value === null) return 'null'\n\n const type = typeof value\n if (type === 'string') {\n const str = value as string\n if (str.length > 50) {\n return `\"${str.slice(0, 47)}...\" (string)`\n }\n return `\"${str}\" (string)`\n }\n if (type === 'number') return `${value} (number)`\n if (type === 'boolean') return `${value} (boolean)`\n if (Array.isArray(value)) {\n return `[...] (array with ${value.length} items)`\n }\n if (type === 'object') {\n const obj = value as Record<string, unknown>\n if (obj._type) {\n return `{_type: \"${obj._type}\", ...} (object)`\n }\n return `{...} (object)`\n }\n return String(value)\n}\n\n/**\n * Map Sanity schema type to expected JavaScript type.\n * See SANITY_SCHEMA_STRUCTURE.md for full reference.\n */\nexport function getExpectedJsType(\n schemaType: string,\n): 'string' | 'number' | 'boolean' | 'array' | 'object' {\n switch (schemaType) {\n // String types\n case 'string':\n case 'text':\n case 'url':\n case 'email':\n case 'date':\n case 'datetime':\n return 'string'\n\n // Number\n case 'number':\n return 'number'\n\n // Boolean\n case 'boolean':\n return 'boolean'\n\n // Array\n case 'array':\n return 'array'\n\n // Everything else is an object (document, object, reference, image, file, slug, geopoint, block, custom types)\n default:\n return 'object'\n }\n}\n\n/**\n * Get the actual JavaScript type of a value.\n */\nexport function getActualJsType(\n value: unknown,\n): 'string' | 'number' | 'boolean' | 'array' | 'object' | 'null' | 'undefined' {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (Array.isArray(value)) return 'array'\n return typeof value as 'string' | 'number' | 'boolean' | 'object'\n}\n\n/**\n * Get the uniqueness key for an array item based on its type.\n * - References: unique by _ref\n * - Primitives: unique by value\n * - Objects: strip _key and compare rest\n */\nexport function getUniquenessKey(item: unknown): string {\n if (typeof item !== 'object' || item === null) {\n return JSON.stringify(item)\n }\n const itemObj = item as Record<string, unknown>\n if (itemObj._type === 'reference' && typeof itemObj._ref === 'string') {\n return itemObj._ref\n }\n const itemForComparison = Object.fromEntries(\n Object.entries(itemObj).filter(([k]) => k !== '_key'),\n )\n return JSON.stringify(itemForComparison)\n}\n\ntype PathSegment =\n | { type: 'property'; value: string }\n | { type: 'index'; value: number }\n | { type: 'key'; value: string }\n\n/**\n * Get a value from an object using a path string.\n * Supports dot notation, array index notation [0], and _key selectors [_key==\"value\"].\n */\nexport function getValueAtPath(obj: unknown, path: string): unknown {\n const segments = parsePath(path)\n let current: unknown = obj\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined\n }\n\n if (segment.type === 'property') {\n if (typeof current !== 'object' || Array.isArray(current)) {\n return undefined\n }\n current = (current as Record<string, unknown>)[segment.value]\n } else if (segment.type === 'index') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment.value]\n } else if (segment.type === 'key') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current.find(\n (item): item is Record<string, unknown> =>\n typeof item === 'object' &&\n item !== null &&\n (item as Record<string, unknown>)._key === segment.value,\n )\n }\n }\n\n return current\n}\n\n/**\n * Parse a path string into segments.\n * Handles property access, array indices, and _key selectors.\n */\nfunction parsePath(path: string): PathSegment[] {\n const segments: PathSegment[] = []\n const parts = path.split(/\\.(?![^[]*\\])/)\n\n for (const part of parts) {\n const match = part.match(/^([^[]*)(?:\\[(.+)\\])?$/)\n if (!match) continue\n\n const [, prop, selector] = match\n\n if (prop) {\n segments.push({ type: 'property', value: prop })\n }\n\n if (selector) {\n const keyMatch = selector.match(/^_key\\s*==\\s*\"([^\"]+)\"$/)\n if (keyMatch) {\n segments.push({ type: 'key', value: keyMatch[1] })\n } else {\n const index = parseInt(selector, 10)\n if (!Number.isNaN(index)) {\n segments.push({ type: 'index', value: index })\n }\n }\n }\n }\n\n return segments\n}\n\n/**\n * Validate that an object only contains allowed properties.\n * Reports errors for any unknown properties found.\n *\n * @param obj - The object to validate\n * @param allowedProperties - Set of property names that are allowed\n * @param path - The path to the object for error reporting\n * @param typeName - Human-readable type name for error messages (e.g., \"reference\", \"slug\")\n * @param errors - Array to collect validation errors\n */\nexport function validateNoExtraProperties(\n obj: Record<string, unknown>,\n allowedProperties: Set<string>,\n path: string,\n typeName: string,\n errors: ValidationError[],\n): void {\n for (const key of Object.keys(obj)) {\n if (!allowedProperties.has(key)) {\n errors.push(\n createError(\n `${path}.${key}`,\n 'FIELD_NOT_IN_SCHEMA',\n `Unknown property \"${key}\" on ${typeName} object`,\n formatValue(obj[key]),\n `Only allowed properties: ${[...allowedProperties].join(', ')}`,\n `Remove the \"${key}\" property from the ${typeName} object`,\n ),\n )\n }\n }\n}\n\n/**\n * Format validation errors for display to the LLM.\n *\n * @param errors - List of validation errors\n * @returns Formatted error message\n */\nexport function formatValidationErrors(errors: ValidationError[]): string {\n if (errors.length === 0) {\n return ''\n }\n\n const header = `Validation failed with ${errors.length} error(s):\\n\\n`\n\n const errorList = errors\n .map((err, i) => {\n return [\n `${i + 1}. At path \"${err.path}\": ${err.message}`,\n ` Received: ${err.received}`,\n ` Expected: ${err.expected}`,\n ` Fix: ${err.fix}`,\n ].join('\\n')\n })\n .join('\\n\\n')\n\n return `${header + errorList}\\n\\nPlease correct all errors and try again.`\n}\n","/**\n * Array validator - validates arrays and their items.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue, getUniquenessKey } from './utils.js'\n\n/**\n * Validate an array value and its items.\n */\nexport async function validateArray(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (!Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Expected array',\n formatValue(value),\n 'array',\n 'Provide an array value',\n ),\n )\n return\n }\n\n // Get allowed item types from schema\n const itemTypes = fieldSchema.of || []\n if (itemTypes.length === 0) {\n // No item type constraints - can't validate items\n return\n }\n\n // Check if this is a primitive array (no named types, only primitive types)\n const isPrimitiveArray = itemTypes.every(\n (t) => !t.name && isPrimitiveType(t.type as string | undefined),\n )\n\n // Track _key values for duplicate detection (only for object arrays)\n const seenKeys = new Set<string>()\n\n // Validate each item\n for (let i = 0; i < value.length; i++) {\n const item = value[i]\n const itemPath = `${path}[${i}]`\n\n // Track error count before this item so we can tag any new errors with itemIndex\n const errorCountBefore = errors.length\n\n // Determine item type\n const itemObj = item as Record<string, unknown>\n const itemType = itemObj?._type as string | undefined\n const itemKey = itemObj?._key as string | undefined\n\n // For non-primitive arrays, validate _key\n if (!isPrimitiveArray && typeof item === 'object' && item !== null) {\n // Check for missing _key\n if (itemKey === undefined) {\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n 'Object array item missing \"_key\" property',\n formatValue(item),\n 'Object with _key property',\n 'Add a unique _key property to the array item',\n ),\n )\n } else if (typeof itemKey === 'string' && itemKey !== '') {\n // Check for duplicate _key\n if (seenKeys.has(itemKey)) {\n errors.push(\n createError(\n `${itemPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${itemKey}\" in array`,\n itemKey,\n 'Unique _key value',\n 'Ensure all array items have unique _key values',\n ),\n )\n } else {\n seenKeys.add(itemKey)\n }\n }\n }\n\n // Find matching schema for this item\n let matchingSchema: ManifestSchemaType | undefined\n\n for (const typeSchema of itemTypes) {\n // Match by name (for named types like blocks or named wrappers)\n // When a schema has a `name`, items MUST use that name as _type\n if (typeSchema.name && typeSchema.name === itemType) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // Match by type (for anonymous types only - no name in schema)\n // If schema has a name, we don't fall back to type matching\n if (!typeSchema.name && typeSchema.type === itemType) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // Handle single-type arrays where _type might be omitted.\n // Match the item to the sole schema so its fields are still deeply validated.\n // Covers named schemas like { name: \"object\", type: \"object\" } where\n // the skeleton builder omits _type on inline objects.\n if (\n typeSchema.type &&\n !itemType &&\n itemTypes.length === 1 &&\n typeof item === 'object' &&\n item !== null\n ) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n // For primitive arrays (string[], number[])\n if (\n !itemType &&\n typeSchema.type &&\n typeof typeSchema.type === 'string' &&\n isPrimitiveType(typeSchema.type)\n ) {\n matchingSchema = typeSchema as ManifestSchemaType\n break\n }\n }\n\n // If no match found, try looking up the item's _type in the global schema\n // This handles cases like markDefs where the allowed types might be defined globally\n if (!matchingSchema && itemType) {\n const globalTypeSchema = schema.find((s) => s.name === itemType)\n if (globalTypeSchema) {\n matchingSchema = globalTypeSchema\n }\n }\n\n if (!matchingSchema) {\n // Couldn't find matching schema for item\n const allowedTypeNames = itemTypes\n .map((t) => t.name || t.type)\n .filter(Boolean)\n .join(', ')\n\n // Check if a primitive is in an object array (type mismatch)\n const isObjectArray = !isPrimitiveArray\n const itemIsPrimitive =\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean' ||\n item === null\n\n if (isObjectArray && itemIsPrimitive) {\n // Primitive in object array - this is a type mismatch\n errors.push(\n createError(\n itemPath,\n 'TYPE_MISMATCH',\n 'Expected object but found primitive in array',\n formatValue(item),\n `object of type: ${allowedTypeNames}`,\n `Provide an object with _type set to one of: ${allowedTypeNames}`,\n ),\n )\n // Tag errors from this item\n tagItemErrors(errors, errorCountBefore, i, path)\n continue\n }\n\n // Check if there's a named type that should be used\n const namedTypes = itemTypes.filter((t) => t.name)\n if (namedTypes.length > 0 && itemType) {\n // The item has a _type but it doesn't match any named schema\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n `Wrong _type \"${itemType}\" for array item`,\n formatValue(item),\n `_type must be one of: ${namedTypes.map((t) => t.name).join(', ')}`,\n `Use one of the allowed types: ${namedTypes.map((t) => t.name).join(', ')}`,\n ),\n )\n } else {\n errors.push(\n createError(\n itemPath,\n 'ARRAY_ITEM_INVALID',\n itemType ? `Unknown array item type: ${itemType}` : 'Invalid array item',\n formatValue(item),\n `One of: ${allowedTypeNames}`,\n itemType\n ? `Use one of the allowed types: ${allowedTypeNames}`\n : `Provide a valid array item of type: ${allowedTypeNames}`,\n ),\n )\n }\n // Tag errors from this item\n tagItemErrors(errors, errorCountBefore, i, path)\n continue\n }\n\n // Recursively validate the item\n await validateValue(item, matchingSchema, itemPath, errors, context, schema)\n\n // Tag any errors produced by recursive validation of this item\n tagItemErrors(errors, errorCountBefore, i, path)\n }\n}\n\n/**\n * Tag all errors added since `startIndex` with itemIndex and arrayPath.\n * This allows the patch tool to identify per-item errors and filter invalid items\n * while writing valid ones.\n */\nfunction tagItemErrors(\n errors: ValidationError[],\n startIndex: number,\n itemIndex: number,\n arrayPath: string,\n): void {\n for (let e = startIndex; e < errors.length; e++) {\n errors[e].itemIndex = itemIndex\n errors[e].arrayPath = arrayPath\n }\n}\n\n/**\n * Validate that new items don't duplicate existing array items or each other.\n * Used by patch operations (APPEND, INSERT) to check uniqueItems constraints\n * against the existing document state.\n */\nexport function validateUniqueItems(\n newItems: unknown[],\n existingArray: unknown[],\n pathPrefix: string,\n errors: ValidationError[],\n): void {\n const existingKeys = new Set<string>()\n for (const item of existingArray) {\n existingKeys.add(getUniquenessKey(item))\n }\n\n const newKeys = new Set<string>()\n for (let i = 0; i < newItems.length; i++) {\n const item = newItems[i]\n const uniquenessKey = getUniquenessKey(item)\n\n if (existingKeys.has(uniquenessKey)) {\n errors.push(\n createError(\n `${pathPrefix}${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Item would duplicate an existing array item',\n formatValue(item),\n 'Unique array items',\n 'Remove the duplicate item or modify it to be unique',\n ),\n )\n } else if (newKeys.has(uniquenessKey)) {\n errors.push(\n createError(\n `${pathPrefix}${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Items contain duplicates',\n formatValue(item),\n 'Unique array items',\n 'Remove duplicate items from the operation',\n ),\n )\n }\n newKeys.add(uniquenessKey)\n }\n}\n","/**\n * Predicates for validation rules on a `ManifestField` or `ManifestSchemaType`.\n *\n * Two rule shapes appear in practice:\n * - manifest format: `{ flag: 'presence', constraint: 'required' }`\n * - encoded lexicon format: `{ type: 'required' }` / `{ type: 'custom' }`\n *\n * Both are normalized here so callers don't need to know about the wire format.\n */\n\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\n\nconst isRequiredRule = (rule: Record<string, unknown>): boolean =>\n rule.type === 'required' || (rule.flag === 'presence' && rule.constraint === 'required')\n\nconst isCustomRule = (rule: Record<string, unknown>): boolean =>\n rule.type === 'custom' || rule.flag === 'custom'\n\nconst matchesAnyRule = (\n field: ManifestField | ManifestSchemaType,\n predicate: (rule: Record<string, unknown>) => boolean,\n errorLevelOnly: boolean,\n): boolean =>\n (field.validation ?? []).some(\n (group) =>\n (!errorLevelOnly || (group.level ?? 'error') === 'error') &&\n (group.rules ?? []).some((rule) => predicate(rule as Record<string, unknown>)),\n )\n\n/** True when the field has an error-level required validator. */\nexport const hasRequiredValidator = (field: ManifestField | ManifestSchemaType): boolean =>\n matchesAnyRule(field, isRequiredRule, true)\n\n/** True when the field has a `Rule.custom(...)` validator at any level. */\nexport const hasCustomValidator = (field: ManifestField | ManifestSchemaType): boolean =>\n matchesAnyRule(field, isCustomRule, false)\n","/**\n * Finds schema paths that have a `Rule.custom(...)` validator.\n *\n * Custom validators serialize with the function body stripped, so we cannot\n * run them ourselves. We surface the paths so a caller can ask the user to\n * confirm before publishing.\n *\n * Walks every reachable field, including those nested inside arrays of\n * objects.\n */\n\nimport { walkSchemaTree } from '../navigate/walkTree.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { hasCustomValidator } from './rules'\n\n/**\n * Return paths of fields with custom validators on the document type.\n * Document-level custom validators are reported at `(document)`.\n */\nexport function detectCustomValidators(\n documentType: string,\n schema: ManifestSchemaType[],\n): string[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) return []\n\n const paths: string[] = []\n if (hasCustomValidator(typeSchema)) paths.push('(document)')\n\n walkSchemaTree(documentType, schema, (field, path) => {\n if (hasCustomValidator(field)) paths.push(path)\n })\n return paths\n}\n","/**\n * Document-aware path resolution for dynamic array structures.\n *\n * When schema-only navigation fails (e.g., for PTE markDefs, inline objects),\n * this utility uses the actual document to resolve the correct schema for validation.\n *\n * This handles cases where the item's type is stored in the document (_type field)\n * rather than being statically derivable from the schema structure alone.\n */\n\nimport { BUILT_IN_TYPE_FIELDS } from '../navigate/constants.js'\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { getValueAtPath } from './utils.js'\n\ninterface PathResolutionResult {\n /** The resolved field schema, or null if not found */\n schema: ManifestSchemaType | null\n /** How the schema was resolved: 'schema' (static), 'document' (dynamic), or null (failed) */\n resolvedVia: 'schema' | 'document' | null\n}\n\n/**\n * Check if a path contains array selectors that could benefit from document resolution.\n */\nfunction pathHasArraySelectors(path: string): boolean {\n return /\\[(_key==|[0-9])/.test(path)\n}\n\n/**\n * Resolve field schema at path, using document for accurate type resolution.\n *\n * When a document is provided and the path contains array selectors, we use\n * document-based resolution to determine the correct type at each array access.\n * This is essential for union arrays where multiple types have the same field name.\n *\n * @param path - Dot-notation path, may include array selectors like [_key==\"abc\"]\n * @param typeSchema - The document type schema to start navigation from\n * @param allSchemas - All available schemas for type resolution\n * @param document - Optional existing document for dynamic resolution\n * @returns Resolution result with schema and resolution method\n */\nexport function resolveFieldSchemaAtPath(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document?: Record<string, unknown>,\n): PathResolutionResult {\n // When document is provided and path has array selectors, prefer document-based resolution\n // This ensures we resolve the correct type in union arrays\n if (document && pathHasArraySelectors(path)) {\n const documentResult = resolveFieldSchemaWithDocument(path, typeSchema, allSchemas, document)\n if (documentResult) {\n return { schema: documentResult, resolvedVia: 'document' }\n }\n }\n\n // Try schema-only navigation\n const schemaResult = resolveFieldSchema(path, typeSchema, allSchemas)\n if (schemaResult) {\n return { schema: schemaResult, resolvedVia: 'schema' }\n }\n\n // Fall back to document-based resolution for last-field lookup\n if (document) {\n const documentResult = resolveFieldSchemaFromDocument(path, document, allSchemas)\n if (documentResult) {\n return { schema: documentResult, resolvedVia: 'document' }\n }\n }\n\n return { schema: null, resolvedVia: null }\n}\n\n/**\n * Resolve item _type from a document to a schema.\n *\n * In Sanity, array union items can have a `name` that differs from their `type`.\n * For example: `{ name: \"card\", type: \"linkCard\" }` in the `of` array means documents\n * store `_type: \"card\"`, but the actual schema with fields is named `\"linkCard\"`.\n *\n * This function first tries a direct lookup in allSchemas, then falls back to\n * checking the parent array's `of` items to resolve aliased names.\n */\nfunction resolveItemSchema(\n itemType: string,\n allSchemas: ManifestSchemaType[],\n parentArraySchema?: ManifestSchemaType,\n): ManifestSchemaType | null {\n // Direct lookup — works when _type matches a top-level schema name\n const directMatch = allSchemas.find((s) => s.name === itemType)\n if (directMatch) {\n return directMatch\n }\n\n // Aliased name lookup — check the parent array's `of` items\n // e.g., of: [{ name: \"card\", type: \"linkCard\" }] → _type \"card\" resolves to \"linkCard\"\n if (parentArraySchema?.of) {\n for (const ofItem of parentArraySchema.of as ManifestSchemaType[]) {\n if (ofItem.name === itemType && ofItem.type) {\n const resolvedSchema = allSchemas.find((s) => s.name === ofItem.type)\n if (resolvedSchema) {\n return resolvedSchema\n }\n }\n }\n }\n\n return null\n}\n\ninterface PathFieldSegment {\n field: string\n selector: string | null\n}\n\n/**\n * Parse a path into field segments with their selectors.\n * \"content[_key==\"abc\"].title\" -> [{field: \"content\", selector: \"[_key==\"abc\"]\"}, {field: \"title\", selector: null}]\n *\n * Note: This is different from parsePathSegments in schemaTraversal.ts which tracks isArray/arrayIndex,\n * and different from @sanity/types PathSegment which is a union type for path operations.\n */\nfunction parsePathIntoFieldSegments(path: string): PathFieldSegment[] {\n const segments: PathFieldSegment[] = []\n\n // Split by dots but keep selectors attached\n const parts = path.split(/\\.(?![^[]*\\])/)\n\n for (const part of parts) {\n const match = part.match(/^([^[]+)(\\[.+\\])?$/)\n if (match) {\n segments.push({\n field: match[1],\n selector: match[2] || null,\n })\n }\n }\n\n return segments\n}\n\n/**\n * Walk the path segment by segment, using document to resolve array item types.\n *\n * For path \"content[_key==\"text1\"].title\":\n * 1. Start with document type schema\n * 2. Find \"content\" field -> array type\n * 3. Get item at [_key==\"text1\"] from document -> _type is \"textBlock\"\n * 4. Look up \"textBlock\" schema, find \"title\" field -> string\n *\n * This handles union arrays correctly by using the actual _type from the document.\n */\nfunction resolveFieldSchemaWithDocument(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document: Record<string, unknown>,\n): ManifestSchemaType | null {\n // Parse path into field segments with their selectors\n const segments = parsePathIntoFieldSegments(path)\n\n let currentSchema: ManifestSchemaType = typeSchema\n let currentPath = ''\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n const isLastSegment = i === segments.length - 1\n\n // Build the path up to this point (including selector if present)\n if (currentPath) {\n currentPath += `.${segment.field}`\n } else {\n currentPath = segment.field\n }\n if (segment.selector) {\n currentPath += segment.selector\n }\n\n // Check for built-in type fields first (e.g., span.text, block.style)\n if (BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment.field]) {\n const builtInField = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment.field]\n if (isLastSegment) {\n return builtInField\n }\n\n // If built-in field is an array (like block.children) and has a selector,\n // we need to resolve the item type for the next segment\n if (builtInField.type === 'array' && segment.selector && builtInField.of) {\n // Get the item value from document to determine its _type\n const itemValue = getValueAtPath(document, currentPath)\n\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n // First check if it's a built-in type (like span)\n if (BUILT_IN_TYPE_FIELDS[itemType]) {\n // Create a synthetic schema for the built-in type\n currentSchema = { name: itemType, type: itemType } as ManifestSchemaType\n continue\n }\n // Otherwise look it up in allSchemas (handles aliased names)\n const itemSchema = resolveItemSchema(itemType, allSchemas, builtInField)\n if (itemSchema) {\n currentSchema = itemSchema\n continue\n }\n }\n }\n // Fall back to first item type in schema\n if (builtInField.of.length > 0) {\n const firstItemType = (builtInField.of[0] as ManifestSchemaType).type\n if (BUILT_IN_TYPE_FIELDS[firstItemType]) {\n currentSchema = { name: firstItemType, type: firstItemType } as ManifestSchemaType\n continue\n }\n const itemSchema = allSchemas.find((s) => s.name === firstItemType)\n currentSchema = itemSchema || (builtInField.of[0] as ManifestSchemaType)\n continue\n }\n }\n\n currentSchema = builtInField\n continue\n }\n\n // Find the field in current schema\n let field: ManifestSchemaType | undefined\n\n if (currentSchema.fields) {\n field = currentSchema.fields.find((f) => f.name === segment.field) as\n | ManifestSchemaType\n | undefined\n }\n\n // If not found in fields, check if current schema is an array\n if (!field && currentSchema.type === 'array' && currentSchema.of) {\n // Need to determine the item type from the document\n const parentPath = segments\n .slice(0, i)\n .map((s: PathFieldSegment) => s.field + (s.selector || ''))\n .join('.')\n const parentValue = parentPath ? getValueAtPath(document, parentPath) : document\n\n if (parentValue && typeof parentValue === 'object' && !Array.isArray(parentValue)) {\n const itemType = (parentValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas, currentSchema)\n if (itemSchema?.fields) {\n field = itemSchema.fields.find((f) => f.name === segment.field) as\n | ManifestSchemaType\n | undefined\n }\n }\n }\n }\n\n // If still not found, the document type schema may have empty fields (e.g., manifest\n // doesn't surface fields in groups). Use the document value at currentPath to resolve\n // the item's _type directly and skip ahead.\n if (!field) {\n const itemValue = getValueAtPath(document, currentPath)\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas)\n if (itemSchema) {\n if (isLastSegment) {\n return itemSchema\n }\n currentSchema = itemSchema\n continue\n }\n }\n }\n return null\n }\n\n if (isLastSegment) {\n return field\n }\n\n // Navigate into the field for next iteration\n // If field is an array and has a selector, we need to resolve the item type from document\n // Resolve named type references first (e.g., field type \"link\" -> array schema \"link\")\n let resolvedFieldForNav: ManifestSchemaType = field\n if (field.type !== 'array' && field.type) {\n const referencedArray = allSchemas.find((s) => s.name === field.type && s.type === 'array')\n if (referencedArray) {\n resolvedFieldForNav = referencedArray\n }\n }\n\n if (resolvedFieldForNav.type === 'array' && segment.selector) {\n const itemValue = getValueAtPath(document, currentPath)\n\n if (itemValue && typeof itemValue === 'object' && !Array.isArray(itemValue)) {\n const itemType = (itemValue as Record<string, unknown>)._type as string | undefined\n if (itemType) {\n const itemSchema = resolveItemSchema(itemType, allSchemas, resolvedFieldForNav)\n if (itemSchema) {\n currentSchema = itemSchema\n continue\n }\n }\n }\n // Fall back to first item type in schema\n if (resolvedFieldForNav.of && resolvedFieldForNav.of.length > 0) {\n const firstItemType = (resolvedFieldForNav.of[0] as ManifestSchemaType).type\n const itemSchema = allSchemas.find((s) => s.name === firstItemType)\n currentSchema = itemSchema || (resolvedFieldForNav.of[0] as ManifestSchemaType)\n continue\n }\n }\n\n // Resolve type reference if needed\n if (field.type && field.type !== 'array') {\n const referencedSchema = allSchemas.find((s) => s.name === field.type)\n if (referencedSchema) {\n currentSchema = referencedSchema\n continue\n }\n }\n\n currentSchema = field\n }\n\n return currentSchema\n}\n\n/**\n * Resolve field schema by looking up the parent object's _type in the document.\n *\n * For path \"content[_key==\"x\"].markDefs[_key==\"y\"].href\":\n * 1. Parent path = \"content[_key==\"x\"].markDefs[_key==\"y\"]\"\n * 2. Get parent from document, find its _type (e.g., \"link\")\n * 3. Look up \"link\" type in schema\n * 4. Find \"href\" field in that type\n *\n * This handles:\n * - PTE markDefs with annotation types (link, internalLink, etc.)\n * - PTE children with inline object types\n * - Custom blocks in PTE arrays (callout, image, code, etc.)\n * - Nested PTE fields (e.g., callout.content[].markDefs[].href)\n *\n * @param path - Full path to the field\n * @param document - The document to look up values from\n * @param allSchemas - All available schemas for type resolution\n * @returns The field schema if found, null otherwise\n */\nexport function resolveFieldSchemaFromDocument(\n path: string,\n document: Record<string, unknown>,\n allSchemas: ManifestSchemaType[],\n): ManifestSchemaType | null {\n // Need a parent path to look up the object's _type\n const lastDotIndex = path.lastIndexOf('.')\n if (lastDotIndex === -1) {\n return null\n }\n\n const parentPath = path.substring(0, lastDotIndex)\n const fieldName = path.substring(lastDotIndex + 1)\n\n // Get parent object from document\n const parentValue = getValueAtPath(document, parentPath)\n\n if (parentValue === null || parentValue === undefined) {\n return null\n }\n\n if (typeof parentValue !== 'object' || Array.isArray(parentValue)) {\n return null\n }\n\n // Get the _type of the parent object\n const parentType = (parentValue as Record<string, unknown>)._type as string | undefined\n\n if (!parentType) {\n return null\n }\n\n // Look up the type in schema (handles aliased names via resolveItemSchema)\n const typeSchema = resolveItemSchema(parentType, allSchemas)\n\n if (!typeSchema) {\n return null\n }\n\n // Find the field in that type's fields\n if (typeSchema.fields) {\n const field = typeSchema.fields.find((f) => f.name === fieldName)\n if (field) {\n return field\n }\n }\n\n return null\n}\n\n/**\n * Validate that a path can be resolved to a schema.\n *\n * Returns true if:\n * - Path can be resolved via schema (static), OR\n * - Path can be resolved via document (parent exists with valid _type and field)\n *\n * @param path - Dot-notation path to validate\n * @param typeSchema - The document type schema\n * @param allSchemas - All available schemas\n * @param document - Optional document for dynamic resolution\n * @returns true if path can be resolved to a schema\n */\nexport function validatePathExists(\n path: string,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n document?: Record<string, unknown>,\n): boolean {\n const result = resolveFieldSchemaAtPath(path, typeSchema, allSchemas, document)\n return result.schema !== null\n}\n","/**\n * Language field validators for document-level and field-level translations.\n */\n\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate a document-level language field value against available languages.\n *\n * This validator is called when:\n * 1. The document uses document-level translation\n * 2. The field being validated is the language field (e.g., \"language\", \"locale\")\n * 3. There are known available languages to validate against\n *\n * @param value - The language value to validate\n * @param languageFieldName - Name of the language field (e.g., \"language\", \"locale\")\n * @param availableLanguages - List of valid language codes from existing documents\n * @param path - The field path for error reporting\n * @param errors - Array to collect validation errors\n */\nexport function validateDocumentLanguageField(\n value: unknown,\n languageFieldName: string,\n availableLanguages: string[],\n path: string,\n errors: ValidationError[],\n): void {\n // Skip validation if no available languages to compare against\n if (!availableLanguages || availableLanguages.length === 0) {\n return\n }\n\n // Skip null/undefined - those are handled elsewhere\n if (value === null || value === undefined) {\n return\n }\n\n // Language must be a string\n if (typeof value !== 'string') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n `Language field \"${languageFieldName}\" must be a string`,\n formatValue(value),\n 'string (language code)',\n `Provide a language code like \"${availableLanguages[0]}\"`,\n ),\n )\n return\n }\n\n // Check if value is one of the available languages\n if (!availableLanguages.includes(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language code for \"${languageFieldName}\"`,\n formatValue(value),\n `One of: ${availableLanguages.map((l) => `\"${l}\"`).join(', ')}`,\n `Use a valid language code: ${availableLanguages.join(', ')}`,\n ),\n )\n }\n}\n\n/**\n * Validate a field-level language key (the _key in internationalizedArray items).\n *\n * This validator is called when processing arrays with options.languages,\n * to ensure that array item _key values match configured language IDs.\n *\n * @param key - The _key value from an array item\n * @param allowedLanguages - List of allowed languages with id and title\n * @param path - The field path for error reporting\n * @param errors - Array to collect validation errors\n */\nexport function validateFieldLevelLanguageKey(\n key: string,\n allowedLanguages: Array<{ id: string; title: string | null }>,\n path: string,\n errors: ValidationError[],\n): void {\n // Skip validation if no allowed languages configured\n if (!allowedLanguages || allowedLanguages.length === 0) {\n return\n }\n\n const languageIds = allowedLanguages.map((lang) => lang.id)\n\n // Check if key is one of the allowed language IDs\n if (!languageIds.includes(key)) {\n const languageList = allowedLanguages\n .map((lang) => `\"${lang.id}\"${lang.title ? ` (${lang.title})` : ''}`)\n .join(', ')\n\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language key \"${key}\" in internationalized array`,\n `\"${key}\"`,\n `One of: ${languageList}`,\n `Use a valid language key: ${languageIds.join(', ')}`,\n ),\n )\n }\n}\n\n/**\n * Validate a field-level language field value (v5 format where language is a dedicated field).\n *\n * In v5 of the internationalized-array plugin, the language code is stored in a\n * dedicated `language` field instead of `_key`.\n */\nexport function validateFieldLevelLanguageField(\n languageValue: unknown,\n allowedLanguages: Array<{ id: string; title: string | null }>,\n path: string,\n errors: ValidationError[],\n): void {\n if (!allowedLanguages || allowedLanguages.length === 0) {\n return\n }\n\n if (typeof languageValue !== 'string' || languageValue === '') {\n const languageIds = allowedLanguages.map((lang) => lang.id)\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n 'Missing or invalid \"language\" field in internationalized array item',\n formatValue(languageValue),\n `One of: ${allowedLanguages.map((l) => `\"${l.id}\"${l.title ? ` (${l.title})` : ''}`).join(', ')}`,\n `Set the \"language\" field to a valid language code: ${languageIds.join(', ')}`,\n ),\n )\n return\n }\n\n const languageIds = allowedLanguages.map((lang) => lang.id)\n if (!languageIds.includes(languageValue)) {\n const languageList = allowedLanguages\n .map((lang) => `\"${lang.id}\"${lang.title ? ` (${lang.title})` : ''}`)\n .join(', ')\n\n errors.push(\n createError(\n path,\n 'INVALID_LANGUAGE',\n `Invalid language \"${languageValue}\" in internationalized array item`,\n `\"${languageValue}\"`,\n `One of: ${languageList}`,\n `Use a valid language: ${languageIds.join(', ')}`,\n ),\n )\n }\n}\n\ntype LanguageOption = { id: string; title: string | null }\n\ninterface SchemaWithOptions {\n name?: string\n type?: string\n fields?: Array<{ name: string; type: string }>\n of?: Array<{ name?: string; type?: string; fields?: Array<{ name: string; type: string }> }>\n options?: { languages?: LanguageOption[] }\n}\n\n/**\n * Detect whether an internationalized array uses v5 format (dedicated `language` field)\n * by checking if the array's value type has a `language` field in its schema.\n */\nexport function isV5InternationalizedArray(\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n): boolean {\n // Resolve the array type definition\n const resolvedSchema =\n allSchemas.find((s) => s.name === fieldSchema.name || s.name === fieldSchema.type) ??\n fieldSchema\n const itemType = resolvedSchema.of?.[0]\n if (!itemType) return false\n\n // Resolve the value type name\n const valueTypeName = itemType.name || itemType.type\n if (!valueTypeName) return false\n\n // Look up the value type in the full schema\n const valueType = allSchemas.find((s) => s.name === valueTypeName)\n const fieldsToCheck = valueType?.fields || itemType.fields\n\n return !!fieldsToCheck?.some((f) => f.name === 'language')\n}\n\n/**\n * Check if a field schema represents an internationalized array type.\n *\n * @param fieldSchema - The field schema to check\n * @returns true if the field is an internationalized array\n */\nexport function isInternationalizedArrayField(fieldSchema: SchemaWithOptions): boolean {\n return (\n !!fieldSchema.type?.startsWith('internationalizedArray') ||\n !!fieldSchema.name?.startsWith('internationalizedArray')\n )\n}\n\n/**\n * Resolve configured languages from a field schema, falling back to global schemas.\n */\nfunction resolveLanguages(\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n): LanguageOption[] | undefined {\n let languages = fieldSchema.options?.languages\n if (!languages?.length) {\n const resolvedSchema = allSchemas.find((s) => s.name === fieldSchema.type)\n languages = resolvedSchema?.options?.languages\n }\n return languages?.length ? languages : undefined\n}\n\n/**\n * Validate a SET operation against internationalized array language constraints.\n *\n * Handles two cases:\n * 1. Setting the whole array (value is an array) — validates each item's _key\n * 2. Setting a _key directly (path ends with `._key`) — validates the new key value\n *\n * Resolves the field schema from the path. No-ops if the field isn't an internationalized array.\n *\n * @param path - The SET operation path\n * @param value - The new value being set\n * @param fieldSchema - The resolved field schema for the path\n * @param typeSchema - The document type schema (for resolving parent paths)\n * @param allSchemas - All schemas for resolving named types\n * @param errors - Array to collect validation errors\n */\nexport function validateInternationalizedArraySet(\n path: string,\n value: unknown,\n fieldSchema: ManifestSchemaType,\n typeSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n // Case 1: setting the whole array\n if (isInternationalizedArrayField(fieldSchema) && Array.isArray(value)) {\n validateInternationalizedArrayItems(value, fieldSchema, allSchemas, path, errors)\n return\n }\n\n // Case 2: setting a _key on an item (v4 only — in v5, _key is random)\n if (path.endsWith('._key') && typeof value === 'string') {\n const arrayPath = path.replace(/\\[[^\\]]+\\]\\._key$/, '')\n const arrayFieldSchema = resolveFieldSchema(arrayPath, typeSchema, allSchemas)\n if (!arrayFieldSchema || !isInternationalizedArrayField(arrayFieldSchema)) {\n return\n }\n\n // In v5, _key is a random ID — skip language validation\n if (isV5InternationalizedArray(arrayFieldSchema, allSchemas)) {\n return\n }\n\n const languages = resolveLanguages(arrayFieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n validateFieldLevelLanguageKey(value, languages, path, errors)\n return\n }\n\n // Case 3: setting the .language field on an item (v5 only)\n if (path.endsWith('.language') && typeof value === 'string') {\n const arrayPath = path.replace(/\\[[^\\]]+\\]\\.language$/, '')\n const arrayFieldSchema = resolveFieldSchema(arrayPath, typeSchema, allSchemas)\n if (!arrayFieldSchema || !isInternationalizedArrayField(arrayFieldSchema)) {\n return\n }\n\n if (!isV5InternationalizedArray(arrayFieldSchema, allSchemas)) {\n return\n }\n\n const languages = resolveLanguages(arrayFieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n validateFieldLevelLanguageField(value, languages, path, errors)\n }\n}\n\n/**\n * Validate language keys for items being added to an internationalized array.\n *\n * Callers should check `isInternationalizedArrayField()` before calling this.\n *\n * @param items - Array items to validate\n * @param fieldSchema - The field schema (may be a named type reference)\n * @param allSchemas - All schemas for resolving named types\n * @param path - The array field path (e.g., 'description')\n * @param errors - Array to collect validation errors\n */\nexport function validateInternationalizedArrayItems(\n items: unknown[],\n fieldSchema: SchemaWithOptions,\n allSchemas: SchemaWithOptions[],\n path: string,\n errors: ValidationError[],\n): void {\n const languages = resolveLanguages(fieldSchema, allSchemas)\n if (!languages) {\n return\n }\n\n const v5 = isV5InternationalizedArray(fieldSchema, allSchemas)\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (typeof item === 'object' && item !== null) {\n const itemObj = item as Record<string, unknown>\n if (v5) {\n // v5: validate the dedicated \"language\" field, not \"_key\"\n validateFieldLevelLanguageField(\n itemObj.language,\n languages,\n `${path}[${i}].language`,\n errors,\n )\n } else {\n // v4: validate \"_key\" as the language identifier\n if (itemObj._key && typeof itemObj._key === 'string') {\n validateFieldLevelLanguageKey(itemObj._key, languages, `${path}[${i}]._key`, errors)\n }\n }\n }\n }\n}\n","/**\n * Object validator - validates objects and their fields.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate an object value and its fields.\n */\nexport async function validateObject(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Expected object',\n formatValue(value),\n 'object',\n 'Provide an object value',\n ),\n )\n return\n }\n\n const objValue = value as Record<string, unknown>\n\n // Get fields from schema (could be inline or from referenced type)\n let fields = fieldSchema.fields || []\n\n // If no inline fields, look up the type in schema\n if (fields.length === 0 && fieldSchema.type) {\n const referencedType = schema.find((s) => s.name === fieldSchema.type)\n if (referencedType?.fields) {\n fields = referencedType.fields\n }\n }\n\n if (fields.length === 0) {\n // No field constraints - can't validate fields\n return\n }\n\n // Build set of valid field names\n const validFieldNames = new Set(fields.map((f) => f.name))\n\n // For block type (Portable Text), always allow standard Portable Text fields\n // These are built-in fields that may not be explicitly listed in schema\n const isBlockType = fieldSchema.type === 'block' || fieldSchema.name === 'block'\n if (isBlockType) {\n validFieldNames.add('children')\n validFieldNames.add('markDefs')\n validFieldNames.add('style')\n validFieldNames.add('listItem')\n validFieldNames.add('level')\n }\n\n // Check for fields not in schema\n for (const key of Object.keys(objValue)) {\n // Skip system fields\n if (key.startsWith('_')) continue\n\n if (!validFieldNames.has(key)) {\n const validFieldsList = fields.map((f) => f.name).join(', ')\n errors.push(\n createError(\n path ? `${path}.${key}` : key,\n 'FIELD_NOT_IN_SCHEMA',\n 'Field does not exist in schema',\n formatValue(objValue[key]),\n `Field must be one of: ${validFieldsList}`,\n 'Remove this field or check the schema for valid field names',\n ),\n )\n }\n }\n\n // Validate each field\n for (const field of fields) {\n const fieldValue = objValue[field.name]\n const fieldPath = path ? `${path}.${field.name}` : field.name\n\n // Skip undefined fields - we don't enforce required fields\n if (fieldValue === undefined) {\n continue\n }\n\n // Recursively validate the field value\n await validateValue(fieldValue, field, fieldPath, errors, context, schema)\n }\n}\n","/**\n * Path validation utilities.\n * Functions for validating paths against schemas with error generation.\n */\n\nimport { resolveFieldSchemaAllUnions } from '../navigate/navigateAllUnions.js'\nimport { resolveFieldSchema } from '../navigate/navigateToField.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { resolveFieldSchemaFromDocument } from './document-path-resolver.js'\nimport type { FieldSchemaLookupResult, ValidationError, ValidationResult } from './types.js'\nimport { createError, getValueAtPath as getValueAtPathWithKeys } from './utils.js'\n\n/**\n * Get valid image metadata field names for a given image path.\n *\n * This uses the navigation logic to find the image field schema\n * and extract valid metadata field names. Used for silent filtering of metadata.\n *\n * @param imagePath - The path to the image field\n * @param typeSchema - The document type schema\n * @param schema - All available schemas\n * @returns Set of valid metadata field names, or null if path is invalid\n */\nexport function getValidImageMetadataFields(\n imagePath: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): Set<string> | null {\n // Navigate to the image field in the schema\n const imageFieldSchema = resolveFieldSchema(imagePath, typeSchema, schema)\n\n if (!imageFieldSchema) {\n return null\n }\n\n // Get valid metadata field names from the image field schema\n const validFieldNames = new Set<string>()\n\n // Standard image fields that are always valid\n validFieldNames.add('hotspot')\n validFieldNames.add('crop')\n\n // Add custom metadata fields from the image schema\n if (imageFieldSchema.fields) {\n for (const field of imageFieldSchema.fields) {\n validFieldNames.add(field.name)\n }\n }\n\n return validFieldNames\n}\n\n/**\n * Get the field schema(s) at a given path in the document type.\n *\n * For union types (arrays with multiple `of` types), returns ALL possible schemas.\n * This is important for validating fields that might exist in some but not all union types.\n *\n * @param path - Dot-notation path, may include array selectors like [_key==\"abc\"]\n * @param documentType - The document type name\n * @param schema - Full schema array\n * @param existingDocument - Optional document to validate path existence against\n * @returns Object with schemas array and any validation errors\n */\nexport function getFieldSchemaAtPath(\n path: string,\n documentType: string,\n schema: ManifestSchemaType[],\n existingDocument?: Record<string, unknown>,\n): FieldSchemaLookupResult {\n const errors: ValidationError[] = []\n\n if (!path) {\n errors.push(\n createError(\n '',\n 'INVALID_PATH',\n 'Empty path provided',\n '(empty)',\n 'Non-empty path string',\n 'Provide a valid path to a field',\n ),\n )\n return { schemas: null, errors }\n }\n\n // Find the document type schema\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) {\n errors.push(\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Document type \"${documentType}\" not found in schema`,\n documentType,\n 'Valid document type',\n 'Check the document type name',\n ),\n )\n return { schemas: null, errors }\n }\n\n // Navigate to field schema(s) using schema navigation module\n let fieldSchemas = resolveFieldSchemaAllUnions(path, typeSchema, schema)\n\n // If schema navigation fails and we have a document, try document-based resolution\n // This handles dynamic array structures like PTE markDefs where the item's _type\n // is stored in the document, not derivable from schema structure alone\n if ((!fieldSchemas || fieldSchemas.length === 0) && existingDocument) {\n const documentResolvedSchema = resolveFieldSchemaFromDocument(path, existingDocument, schema)\n if (documentResolvedSchema) {\n fieldSchemas = [documentResolvedSchema]\n }\n }\n\n if (!fieldSchemas || fieldSchemas.length === 0) {\n errors.push(\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Field at path \"${path}\" does not exist in schema`,\n path,\n 'Valid field path',\n 'Check the path matches a field in the schema',\n ),\n )\n return { schemas: null, errors }\n }\n\n // If document provided, validate the path exists (for array items with _key selectors)\n // and that parent objects exist for nested paths\n if (existingDocument) {\n const hasNestedPath = path.includes('.') || path.includes('[')\n\n if (hasNestedPath) {\n const value = getValueAtPathWithKeys(existingDocument, path)\n\n if (value === undefined) {\n // Check if it's creating a new field on an existing parent\n const lastDotIndex = path.lastIndexOf('.')\n if (lastDotIndex > 0) {\n const parentPath = path.substring(0, lastDotIndex)\n const parentValue = getValueAtPathWithKeys(existingDocument, parentPath)\n\n if (parentValue === undefined) {\n // Parent doesn't exist - error for both array selectors and nested objects\n if (path.includes('[')) {\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Array item does not exist in document`,\n path,\n 'Existing array item',\n 'Ensure the array item exists before setting fields on it',\n ),\n )\n } else {\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Parent object at \"${parentPath}\" does not exist in document`,\n path,\n 'Existing parent object',\n 'Ensure the parent object exists before setting nested fields',\n ),\n )\n }\n return { schemas: fieldSchemas, errors }\n }\n } else if (path.includes('[')) {\n // Path like \"gallery[_key=='x']\" with no dots\n errors.push(\n createError(\n path,\n 'INVALID_PATH',\n `Array item does not exist in document`,\n path,\n 'Existing array item',\n 'Ensure the array item exists before accessing it',\n ),\n )\n return { schemas: fieldSchemas, errors }\n }\n }\n }\n }\n\n return { schemas: fieldSchemas, errors: [] }\n}\n\n/**\n * Whether the field at `path` is an image field.\n *\n * Resolves the path via getFieldSchemaAtPath — handling array items, union\n * arrays, named-type indirection, and document-based resolution — and returns\n * true when any resolved schema is an `image` type. Boolean counterpart to\n * validateImagePath, for callers that just need a yes/no answer.\n *\n * @param path - Dot-notation path to the field\n * @param documentType - The document type name\n * @param schema - Full schema array\n * @param existingDocument - Optional document for dynamic path resolution\n */\nexport function isImageFieldAtPath(\n path: string,\n documentType: string,\n schema: ManifestSchemaType[],\n existingDocument?: Record<string, unknown>,\n): boolean {\n const { schemas, errors } = getFieldSchemaAtPath(path, documentType, schema, existingDocument)\n if (errors.length > 0 || !schemas?.length) return false\n return schemas.some((s) => s.type === 'image')\n}\n\n/**\n * Validate that a path points to an image field.\n *\n * This is a convenience wrapper around getFieldSchemaAtPath that checks\n * whether the field at the path is an image type.\n *\n * @param path - Dot-notation path to the field\n * @param documentType - The document type name\n * @param schema - Full schema array\n * @param existingDocument - Optional document to validate path existence against\n * @returns Validation result with errors if path is invalid or not an image field\n */\nexport function validateImagePath(\n path: string,\n documentType: string,\n schema: ManifestSchemaType[],\n existingDocument?: Record<string, unknown>,\n): ValidationResult {\n const { schemas, errors } = getFieldSchemaAtPath(path, documentType, schema, existingDocument)\n\n if (errors.length > 0) {\n return { valid: false, errors, warnings: [] }\n }\n\n if (!schemas || schemas.length === 0) {\n return {\n valid: false,\n warnings: [],\n errors: [\n createError(\n path,\n 'FIELD_NOT_IN_SCHEMA',\n `Field at path \"${path}\" does not exist in schema`,\n path,\n 'Valid image field path',\n 'Check the path matches an image field in the schema',\n ),\n ],\n }\n }\n\n // Check if any of the schemas represent an image type\n if (!isImageFieldAtPath(path, documentType, schema, existingDocument)) {\n const types = schemas.map((s) => s.type || 'unknown').join(', ')\n return {\n valid: false,\n warnings: [],\n errors: [\n createError(\n path,\n 'TYPE_MISMATCH',\n `Field at path \"${path}\" is not an image field`,\n `type: ${types}`,\n 'type: image',\n 'Provide a path to an image field in the schema',\n ),\n ],\n }\n }\n\n return { valid: true, errors: [], warnings: [] }\n}\n\n/**\n * Validates metadata fields for an image against the schema\n * Removes fields that don't exist in the image field's schema definition\n *\n * @param metadata - The metadata object to validate (e.g., {alt: \"...\", caption: \"...\"})\n * @param imagePath - The path to the image field (e.g., \"heroImage\" or \"content[_key==\"abc\"].image\")\n * @param typeSchema - The document type schema\n * @param schema - All available schemas\n * @returns Cleaned metadata object with only valid fields, or undefined if no valid fields\n */\nexport function validateImageMetadata(\n metadata: Record<string, string>,\n imagePath: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): Record<string, string> | undefined {\n if (!metadata || typeof metadata !== 'object' || Object.keys(metadata).length === 0) {\n return undefined\n }\n\n // Try using the navigation helper first (handles simple paths)\n const simpleValidFields = getValidImageMetadataFields(imagePath, typeSchema, schema)\n\n // If navigation found valid fields, use them\n // Otherwise, fall back to union-aware navigation for complex array paths\n let validFieldNames: Set<string>\n\n if (simpleValidFields && simpleValidFields.size > 0) {\n validFieldNames = simpleValidFields\n } else {\n // Fall back to union-aware navigation for complex array paths\n const imageFieldSchemas = resolveFieldSchemaAllUnions(imagePath, typeSchema, schema)\n\n if (!imageFieldSchemas || imageFieldSchemas.length === 0) {\n // Can't validate without schema, return empty to prevent hallucinated fields\n return undefined\n }\n\n // Collect valid metadata field names from ALL possible union type schemas\n // This handles cases like content[_key==\"x\"].image where different blocks may have different metadata\n validFieldNames = new Set<string>()\n for (const fieldSchema of imageFieldSchemas) {\n if (fieldSchema?.fields && Array.isArray(fieldSchema.fields)) {\n for (const field of fieldSchema.fields) {\n validFieldNames.add(field.name)\n }\n }\n }\n }\n\n if (validFieldNames.size === 0) {\n // No metadata fields available in any union type\n return undefined\n }\n\n // Filter metadata to only include valid fields\n const cleanedMetadata: Record<string, string> = {}\n for (const [key, value] of Object.entries(metadata)) {\n if (validFieldNames.has(key) && typeof value === 'string') {\n cleanedMetadata[key] = value\n }\n }\n\n return Object.keys(cleanedMetadata).length > 0 ? cleanedMetadata : undefined\n}\n","/**\n * Portable Text (Block) validator - validates PT blocks, spans, and markDefs.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidateValueFn, ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue } from './utils.js'\n\n/**\n * Validate a Portable Text block value.\n *\n * Blocks have special validation requirements:\n * - children must be an array containing spans and inline objects (from block.of)\n * - markDefs must be an array containing annotations (from block.marks.annotations)\n * - style, listItem, level are optional fields\n */\nexport async function validateBlock(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid block value',\n formatValue(value),\n 'Object with { _type: \"block\", children: [...], markDefs?: [...] }',\n 'Provide a valid Portable Text block object',\n ),\n )\n return\n }\n\n const blockObj = value as Record<string, unknown>\n\n // Validate children field - REQUIRED for blocks with _type: 'block'\n if (blockObj.children === undefined) {\n // children is required for Portable Text blocks\n errors.push(\n createError(\n `${path}.children`,\n 'REQUIRED_FIELD_MISSING',\n 'Block is missing required \"children\" field',\n 'undefined',\n 'Array of spans and inline objects',\n 'Provide a children array, e.g., children: [{ _type: \"span\", text: \"Hello\", _key: \"s1\", marks: [] }]',\n ),\n )\n } else if (!Array.isArray(blockObj.children)) {\n errors.push(\n createError(\n `${path}.children`,\n 'TYPE_MISMATCH',\n 'Block children must be an array',\n formatValue(blockObj.children),\n 'Array of spans and inline objects',\n 'Provide an array of children, e.g., [{ _type: \"span\", text: \"Hello\", _key: \"s1\" }]',\n ),\n )\n } else {\n // Extract markDef keys for mark reference validation\n const markDefKeys = new Set<string>()\n if (Array.isArray(blockObj.markDefs)) {\n for (const markDef of blockObj.markDefs) {\n if (typeof markDef === 'object' && markDef !== null) {\n const key = (markDef as Record<string, unknown>)._key\n if (typeof key === 'string') {\n markDefKeys.add(key)\n }\n }\n }\n }\n\n // Get allowed decorators from schema (default: strong, em, code, underline, strike-through)\n const marks = fieldSchema.marks as { decorators?: Array<{ value: string }> } | undefined\n const schemaDecorators = marks?.decorators?.map((d) => d.value) || []\n // Default decorators if not specified in schema\n const defaultDecorators = ['strong', 'em', 'code', 'underline', 'strike-through']\n const allowedDecorators = new Set(\n schemaDecorators.length > 0 ? schemaDecorators : defaultDecorators,\n )\n\n // Validate children array items\n await validateBlockChildren(\n blockObj.children,\n fieldSchema,\n `${path}.children`,\n schema,\n errors,\n context,\n markDefKeys,\n allowedDecorators,\n validateValue,\n )\n }\n\n // Validate markDefs field - MUST be an array if present\n if (blockObj.markDefs !== undefined) {\n if (!Array.isArray(blockObj.markDefs)) {\n errors.push(\n createError(\n `${path}.markDefs`,\n 'TYPE_MISMATCH',\n 'Block markDefs must be an array',\n formatValue(blockObj.markDefs),\n 'Array of annotation objects',\n 'Provide an array of markDefs, e.g., [{ _type: \"link\", _key: \"l1\", href: \"...\" }]',\n ),\n )\n } else {\n // Validate markDefs array items\n await validateBlockMarkDefs(\n blockObj.markDefs,\n fieldSchema,\n `${path}.markDefs`,\n schema,\n errors,\n context,\n validateValue,\n )\n }\n }\n\n // Validate optional scalar fields (style, listItem, level)\n // Get allowed styles from schema (default: normal, h1-h6, blockquote)\n const stylesConfig = fieldSchema.styles as Array<{ value: string }> | undefined\n const schemaStyles = stylesConfig?.map((s) => s.value) || []\n const defaultStyles = ['normal', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote']\n const allowedStyles = new Set(schemaStyles.length > 0 ? schemaStyles : defaultStyles)\n\n if (blockObj.style !== undefined) {\n if (typeof blockObj.style !== 'string') {\n errors.push(\n createError(\n `${path}.style`,\n 'TYPE_MISMATCH',\n 'Block style must be a string',\n formatValue(blockObj.style),\n 'string (e.g., \"normal\", \"h1\", \"blockquote\")',\n 'Provide a valid style string',\n ),\n )\n } else if (!allowedStyles.has(blockObj.style)) {\n const styleList = [...allowedStyles].join(', ')\n errors.push(\n createError(\n `${path}.style`,\n 'INVALID_ENUM_VALUE',\n `Block style \"${blockObj.style}\" is not allowed`,\n blockObj.style,\n `One of: ${styleList}`,\n `Use one of the allowed styles: ${styleList}`,\n ),\n )\n }\n }\n\n // Get allowed list items from schema (default: bullet, number)\n const listsConfig = fieldSchema.lists as Array<{ value: string }> | undefined\n const schemaLists = listsConfig?.map((l) => l.value) || []\n const defaultLists = ['bullet', 'number']\n const allowedLists = new Set(schemaLists.length > 0 ? schemaLists : defaultLists)\n\n if (blockObj.listItem !== undefined) {\n if (typeof blockObj.listItem !== 'string') {\n errors.push(\n createError(\n `${path}.listItem`,\n 'TYPE_MISMATCH',\n 'Block listItem must be a string',\n formatValue(blockObj.listItem),\n 'string (e.g., \"bullet\", \"number\")',\n 'Provide a valid listItem string',\n ),\n )\n } else if (!allowedLists.has(blockObj.listItem)) {\n const listItemList = [...allowedLists].join(', ')\n errors.push(\n createError(\n `${path}.listItem`,\n 'INVALID_ENUM_VALUE',\n `Block listItem \"${blockObj.listItem}\" is not allowed`,\n blockObj.listItem,\n `One of: ${listItemList}`,\n `Use one of the allowed list types: ${listItemList}`,\n ),\n )\n }\n }\n\n if (blockObj.level !== undefined && typeof blockObj.level !== 'number') {\n errors.push(\n createError(\n `${path}.level`,\n 'TYPE_MISMATCH',\n 'Block level must be a number',\n formatValue(blockObj.level),\n 'number (list nesting level, 1-based)',\n 'Provide a valid level number',\n ),\n )\n }\n\n // listItem and level are an atomic pair - if listItem exists, level is required\n if (blockObj.listItem !== undefined && blockObj.level === undefined) {\n errors.push(\n createError(\n `${path}.level`,\n 'REQUIRED_FIELD_MISSING',\n 'Block with listItem must have a level',\n 'undefined',\n 'number (list nesting level, 1-based)',\n 'Add a level property (e.g., level: 1) when using listItem',\n ),\n )\n }\n\n // Inverse: if level exists, listItem is required (atomic pair)\n if (blockObj.level !== undefined && blockObj.listItem === undefined) {\n errors.push(\n createError(\n `${path}.listItem`,\n 'REQUIRED_FIELD_MISSING',\n 'Block with level must have a listItem',\n 'undefined',\n 'string (e.g., \"bullet\", \"number\")',\n 'Add a listItem property (e.g., listItem: \"bullet\") when using level',\n ),\n )\n }\n\n // Validate custom fields defined in block schema, and check for unknown fields\n const blockFields = fieldSchema.fields || []\n if (blockFields.length > 0) {\n // Build set of valid field names (schema-defined + built-in PT fields)\n const validFieldNames = new Set(blockFields.map((f) => f.name))\n // Add built-in Portable Text fields\n validFieldNames.add('children')\n validFieldNames.add('markDefs')\n validFieldNames.add('style')\n validFieldNames.add('listItem')\n validFieldNames.add('level')\n\n // Check for unknown fields\n for (const key of Object.keys(blockObj)) {\n // Skip system fields\n if (key.startsWith('_')) continue\n\n if (!validFieldNames.has(key)) {\n const validFieldsList = [...validFieldNames].join(', ')\n errors.push(\n createError(\n `${path}.${key}`,\n 'FIELD_NOT_IN_SCHEMA',\n 'Field does not exist in block schema',\n formatValue(blockObj[key]),\n `Field must be one of: ${validFieldsList}`,\n 'Remove this field or check the schema for valid field names',\n ),\n )\n }\n }\n\n // Validate schema-defined custom fields\n for (const field of blockFields) {\n // Skip built-in PT fields (already validated above)\n if (['style', 'listItem', 'level', 'children', 'markDefs'].includes(field.name)) {\n continue\n }\n\n const fieldValue = blockObj[field.name]\n if (fieldValue !== undefined) {\n const fieldPath = `${path}.${field.name}`\n await validateValue(fieldValue, field, fieldPath, errors, context, schema)\n }\n }\n }\n}\n\n/**\n * Validate block children array.\n *\n * Children can contain:\n * - spans (_type: \"span\")\n * - inline objects (from block.of schema)\n */\nasync function validateBlockChildren(\n children: unknown[],\n blockSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n markDefKeys: Set<string>,\n allowedDecorators: Set<string>,\n validateValue: ValidateValueFn,\n): Promise<void> {\n // Get inline object types from block.of\n const inlineTypes = (blockSchema.of || []) as ManifestSchemaType[]\n\n // Track _key values for duplicate detection\n const seenKeys = new Set<string>()\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n const childPath = `${path}[${i}]`\n\n if (typeof child !== 'object' || child === null) {\n errors.push(\n createError(\n childPath,\n 'TYPE_MISMATCH',\n 'Block child must be an object',\n formatValue(child),\n 'Object (span or inline object)',\n 'Provide a span or inline object',\n ),\n )\n continue\n }\n\n const childObj = child as Record<string, unknown>\n const childType = childObj._type as string | undefined\n const childKey = childObj._key as string | undefined\n\n // Validate _key\n if (childKey === undefined) {\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n 'Block child missing \"_key\" property',\n formatValue(child),\n 'Object with _key property',\n 'Add a unique _key property to the child',\n ),\n )\n } else if (typeof childKey === 'string' && childKey !== '') {\n if (seenKeys.has(childKey)) {\n errors.push(\n createError(\n `${childPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${childKey}\" in children array`,\n childKey,\n 'Unique _key value',\n 'Ensure all children have unique _key values',\n ),\n )\n } else {\n seenKeys.add(childKey)\n }\n }\n\n // Check if this is a span\n if (childType === 'span') {\n validateSpan(childObj, childPath, errors, markDefKeys, allowedDecorators)\n continue\n }\n\n // Check if this matches an inline type from block.of\n let matchingSchema: ManifestSchemaType | undefined\n for (const inlineSchema of inlineTypes) {\n if (inlineSchema.name === childType) {\n matchingSchema = inlineSchema\n break\n }\n }\n\n if (matchingSchema) {\n // Recursively validate the inline object\n await validateValue(child, matchingSchema, childPath, errors, context, schema)\n } else if (childType) {\n // Unknown type in children\n const allowedTypes = ['span', ...inlineTypes.map((t) => t.name).filter(Boolean)]\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n `Unknown type \"${childType}\" in block children`,\n formatValue(child),\n `One of: ${allowedTypes.join(', ')}`,\n `Use one of the allowed types: ${allowedTypes.join(', ')}`,\n ),\n )\n } else {\n errors.push(\n createError(\n childPath,\n 'ARRAY_ITEM_INVALID',\n 'Block child missing _type property',\n formatValue(child),\n 'Object with _type property (\"span\" or inline object type)',\n 'Add a _type property to identify the child type',\n ),\n )\n }\n }\n}\n\n/**\n * Validate a span object.\n *\n * Marks must either be:\n * 1. A decorator (strong, em, code, underline, strike-through, or custom from schema)\n * 2. A _key reference to an object in markDefs\n */\nfunction validateSpan(\n spanObj: Record<string, unknown>,\n path: string,\n errors: ValidationError[],\n markDefKeys: Set<string>,\n allowedDecorators: Set<string>,\n): void {\n // Validate text field\n if (spanObj.text === undefined) {\n errors.push(\n createError(\n `${path}.text`,\n 'REQUIRED_FIELD_MISSING',\n 'Span missing \"text\" property',\n '(not provided)',\n 'string',\n 'Add a text property to the span',\n ),\n )\n } else if (typeof spanObj.text !== 'string') {\n errors.push(\n createError(\n `${path}.text`,\n 'TYPE_MISMATCH',\n 'Span text must be a string',\n formatValue(spanObj.text),\n 'string',\n 'Provide a string value for text',\n ),\n )\n }\n\n // Validate marks field (optional, but must be array of strings if present)\n if (spanObj.marks !== undefined) {\n if (!Array.isArray(spanObj.marks)) {\n errors.push(\n createError(\n `${path}.marks`,\n 'TYPE_MISMATCH',\n 'Span marks must be an array',\n formatValue(spanObj.marks),\n 'Array of strings (decorator names or annotation _keys)',\n 'Provide an array of mark strings',\n ),\n )\n } else {\n for (let i = 0; i < spanObj.marks.length; i++) {\n const mark = spanObj.marks[i]\n if (typeof mark !== 'string') {\n errors.push(\n createError(\n `${path}.marks[${i}]`,\n 'TYPE_MISMATCH',\n 'Span mark must be a string',\n formatValue(mark),\n 'string (decorator name or annotation _key)',\n 'Provide a string mark value',\n ),\n )\n } else {\n // Mark is a string - validate it's either a decorator or a markDef key\n const isDecorator = allowedDecorators.has(mark)\n const isMarkDefRef = markDefKeys.has(mark)\n\n if (!isDecorator && !isMarkDefRef) {\n const decoratorList = [...allowedDecorators].join(', ')\n errors.push(\n createError(\n `${path}.marks[${i}]`,\n 'INVALID_MARK_REFERENCE',\n `Mark \"${mark}\" is not a valid decorator and does not reference a markDef`,\n mark,\n `Decorator (${decoratorList}) or _key from markDefs`,\n markDefKeys.size > 0\n ? `Use a decorator (${decoratorList}) or one of the markDef keys: ${[...markDefKeys].join(', ')}`\n : `Use a decorator (${decoratorList}) or add a markDef with _key \"${mark}\"`,\n ),\n )\n }\n }\n }\n }\n }\n}\n\n/**\n * Validate block markDefs array.\n *\n * markDefs contain annotations defined in block.marks.annotations.\n */\nasync function validateBlockMarkDefs(\n markDefs: unknown[],\n blockSchema: ManifestSchemaType,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n context: ValidationContext,\n validateValue: ValidateValueFn,\n): Promise<void> {\n // Get annotation types from block.marks.annotations\n // Default annotation type is \"link\" if none specified in schema\n const marks = blockSchema.marks as { annotations?: ManifestSchemaType[] } | undefined\n const schemaAnnotations = marks?.annotations || []\n const defaultAnnotationTypes = ['link']\n const annotationTypes = schemaAnnotations.length > 0 ? schemaAnnotations : []\n const allowedAnnotationNames =\n schemaAnnotations.length > 0\n ? schemaAnnotations.map((t) => t.name).filter(Boolean)\n : defaultAnnotationTypes\n\n // Track _key values for duplicate detection\n const seenKeys = new Set<string>()\n\n for (let i = 0; i < markDefs.length; i++) {\n const markDef = markDefs[i]\n const markPath = `${path}[${i}]`\n\n if (typeof markDef !== 'object' || markDef === null) {\n errors.push(\n createError(\n markPath,\n 'TYPE_MISMATCH',\n 'markDef must be an object',\n formatValue(markDef),\n 'Annotation object with _type and _key',\n 'Provide an annotation object',\n ),\n )\n continue\n }\n\n const markObj = markDef as Record<string, unknown>\n const markType = markObj._type as string | undefined\n const markKey = markObj._key as string | undefined\n\n // Validate _key\n if (markKey === undefined) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n 'markDef missing \"_key\" property',\n formatValue(markDef),\n 'Object with _key property',\n 'Add a unique _key property to the markDef',\n ),\n )\n } else if (typeof markKey === 'string' && markKey !== '') {\n if (seenKeys.has(markKey)) {\n errors.push(\n createError(\n `${markPath}._key`,\n 'ARRAY_ITEM_INVALID',\n `duplicate _key \"${markKey}\" in markDefs array`,\n markKey,\n 'Unique _key value',\n 'Ensure all markDefs have unique _key values',\n ),\n )\n } else {\n seenKeys.add(markKey)\n }\n }\n\n // Validate _type is present\n if (markType === undefined) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n 'markDef missing \"_type\" property',\n formatValue(markDef),\n 'Object with _type property (annotation type)',\n 'Add a _type property to identify the annotation type, e.g., { _type: \"link\", _key: \"l1\", href: \"...\" }',\n ),\n )\n continue\n }\n\n // Find matching annotation schema\n let matchingSchema: ManifestSchemaType | undefined\n for (const annSchema of annotationTypes) {\n if (annSchema.name === markType) {\n matchingSchema = annSchema\n break\n }\n }\n\n if (matchingSchema) {\n // Validate annotation fields using validateValue which will route to validateObject\n await validateValue(markDef, matchingSchema, markPath, errors, context, schema)\n } else {\n // Check if the annotation type is allowed (either from schema or default)\n if (!allowedAnnotationNames.includes(markType)) {\n errors.push(\n createError(\n markPath,\n 'ARRAY_ITEM_INVALID',\n `Unknown annotation type \"${markType}\" in markDefs`,\n formatValue(markDef),\n `One of: ${allowedAnnotationNames.join(', ')}`,\n `Use one of the allowed annotation types: ${allowedAnnotationNames.join(', ')}`,\n ),\n )\n }\n }\n }\n}\n","/**\n * Primitive type validators (string, number, boolean, date, etc.)\n * and schema constraint validation (min, max, enum, unique).\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport {\n createError,\n formatValue,\n getActualJsType,\n getExpectedJsType,\n getUniquenessKey,\n} from './utils.js'\n\n/**\n * Resolve encoded marker values from @sanity/descriptors.\n * The descriptor encoding system uses marker objects for values that can't be\n * directly represented in EncodableValue:\n * - NumberMarker: {__type: \"number\", value: \"3\"} -> 3\n * - ObjectMarker: {__type: \"object\", value: {...}} -> the inner object\n * - UndefinedMarker: {__type: \"undefined\"} -> undefined\n */\nfunction resolveEncodedValue(v: unknown): unknown {\n if (typeof v === 'object' && v !== null && '__type' in v) {\n const marker = v as Record<string, unknown>\n if (marker.__type === 'number' && typeof marker.value === 'string') {\n return parseFloat(marker.value)\n }\n if (marker.__type === 'object' && typeof marker.value === 'object' && marker.value !== null) {\n return marker.value\n }\n if (marker.__type === 'undefined') {\n return undefined\n }\n }\n return v\n}\n\n/**\n * Validate a primitive value against its schema type.\n */\nexport function validatePrimitive(\n value: unknown,\n schemaType: string,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n): void {\n const expectedType = getExpectedJsType(schemaType)\n const actualType = getActualJsType(value)\n\n // Skip null/undefined - those are handled elsewhere (required field validation)\n if (actualType === 'null' || actualType === 'undefined') {\n return\n }\n\n // Type mismatch\n if (actualType !== expectedType) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Type mismatch',\n formatValue(value),\n expectedType,\n `Provide a ${expectedType} value`,\n ),\n )\n return\n }\n\n // Format validation for specific string types\n if (actualType === 'string') {\n const strValue = value as string\n if (schemaType === 'date') validateDate(strValue, path, errors)\n else if (schemaType === 'datetime') validateDatetime(strValue, path, errors)\n else if (schemaType === 'email') validateEmail(strValue, path, errors)\n else if (schemaType === 'url') validateUrl(strValue, path, errors, fieldSchema)\n }\n\n // Number validation\n if (actualType === 'number') {\n const numValue = value as number\n if (Number.isNaN(numValue)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid number (NaN)',\n 'NaN',\n 'A valid number',\n 'Provide a valid numeric value',\n ),\n )\n } else if (!Number.isFinite(numValue)) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid number (Infinity)',\n numValue > 0 ? 'Infinity' : '-Infinity',\n 'A finite number',\n 'Provide a valid finite numeric value',\n ),\n )\n }\n }\n}\n\n/** Validate ISO date format (YYYY-MM-DD) and value correctness. */\nfunction validateDate(value: string, path: string, errors: ValidationError[]): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date format',\n formatValue(value),\n 'ISO date format (YYYY-MM-DD)',\n 'Provide a date like \"2024-01-15\"',\n ),\n )\n return\n }\n\n const parsed = new Date(`${value}T00:00:00Z`)\n if (Number.isNaN(parsed.getTime())) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date value',\n formatValue(value),\n 'A valid date (e.g., month 01-12, valid day for month)',\n 'Provide a valid date like \"2024-01-15\"',\n ),\n )\n return\n }\n\n // Check that the date components match (to catch invalid dates like 2024-02-30)\n const [year, month, day] = value.split('-').map(Number)\n if (\n parsed.getUTCFullYear() !== year ||\n parsed.getUTCMonth() + 1 !== month ||\n parsed.getUTCDate() !== day\n ) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid date value',\n formatValue(value),\n 'A valid date (e.g., valid day for the given month)',\n 'Provide a valid date like \"2024-01-15\"',\n ),\n )\n }\n}\n\n/** Validate ISO datetime format and value correctness. */\nfunction validateDatetime(value: string, path: string, errors: ValidationError[]): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime format',\n formatValue(value),\n 'ISO datetime format (YYYY-MM-DDTHH:mm:ss)',\n 'Provide a datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n return\n }\n\n const parsed = new Date(value)\n if (Number.isNaN(parsed.getTime())) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid datetime (valid date and time components)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n return\n }\n\n // Validate date components (to catch invalid dates like 2024-02-30)\n const datePart = value.slice(0, 10)\n const [year, month, day] = datePart.split('-').map(Number)\n if (\n parsed.getUTCFullYear() !== year ||\n parsed.getUTCMonth() + 1 !== month ||\n parsed.getUTCDate() !== day\n ) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid datetime (valid day for the given month)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n }\n\n // Validate time components (hour 0-23, minute 0-59)\n const timeMatch = value.match(/T(\\d{2}):(\\d{2}):(\\d{2})/)\n if (timeMatch) {\n const [, hour, minute] = timeMatch.map(Number)\n if (hour > 23 || minute > 59) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid datetime value',\n formatValue(value),\n 'A valid time (hour 00-23, minute 00-59)',\n 'Provide a valid datetime like \"2024-01-15T10:30:00Z\"',\n ),\n )\n }\n }\n}\n\n/** Validate email format. */\nfunction validateEmail(value: string, path: string, errors: ValidationError[]): void {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid email format',\n formatValue(value),\n 'Valid email address (e.g., \"user@example.com\")',\n 'Provide a valid email address',\n ),\n )\n }\n}\n\n/** Validate URL format, with optional allowRelative support from schema. */\nfunction validateUrl(\n value: string,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n): void {\n const allowRelative = fieldSchema?.validation?.some((group) =>\n group.rules.some(\n (rule) =>\n ((rule as Record<string, unknown>).type === 'uri' || rule.flag === 'uri') &&\n (rule as Record<string, unknown>).allowRelative === true,\n ),\n )\n\n // Relative URLs are valid when the schema explicitly allows them\n if (allowRelative && value.startsWith('/')) {\n return\n }\n\n try {\n new URL(value)\n } catch {\n errors.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Invalid URL format',\n formatValue(value),\n allowRelative\n ? 'Valid URL (e.g., \"https://example.com\" or \"/path\")'\n : 'Valid URL (e.g., \"https://example.com\")',\n allowRelative\n ? 'Provide a valid URL starting with http://, https://, or /'\n : 'Provide a valid URL starting with http:// or https://',\n ),\n )\n }\n}\n\n/**\n * Validate a value against schema validation rules (min, max, enum, uniqueItems).\n *\n * Supports two schema formats:\n * - Manifest format: { flag: 'min', constraint: 5 }\n * - Encoded format (from @sanity/descriptors): { type: 'minimum', value: '5' }\n */\nexport function validateSchemaRules(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n warnings?: ValidationError[],\n): void {\n if (!fieldSchema.validation) return\n\n for (const group of fieldSchema.validation) {\n // Warning-level violations are non-blocking — they go to warnings (if provided) instead of errors.\n const isWarning = group.level === 'warning' || group.level === 'info'\n const target = isWarning ? (warnings ?? null) : errors\n if (target === null) continue\n\n for (const rule of group.rules) {\n const r = rule as Record<string, unknown>\n const ruleType = (r.type as string) || r.flag\n\n if (ruleType === 'min' || ruleType === 'minimum') {\n validateBound(value, 'min', getConstraint(r), path, target)\n } else if (ruleType === 'max' || ruleType === 'maximum') {\n validateBound(value, 'max', getConstraint(r), path, target)\n } else if (ruleType === 'enum') {\n validateEnum(value, r, path, target)\n } else if (ruleType === 'regex') {\n validateRegex(value, r, path, target)\n } else if (ruleType === 'unique' || ruleType === 'uniqueItems') {\n validateUniqueRule(value, path, target)\n }\n }\n }\n}\n\n/** Get numeric constraint from either manifest format (constraint) or encoded format (value). */\nfunction getConstraint(r: Record<string, unknown>): number | undefined {\n if (r.value !== undefined) return parseFloat(r.value as string)\n if (r.constraint !== undefined) return r.constraint as number\n return undefined\n}\n\n/** Validate min or max bound for strings (length), numbers (value), and arrays (length). */\nfunction validateBound(\n value: unknown,\n direction: 'min' | 'max',\n bound: number | undefined,\n path: string,\n target: ValidationError[],\n): void {\n if (bound === undefined) return\n\n const isMin = direction === 'min'\n const fails = isMin ? (actual: number) => actual < bound : (actual: number) => actual > bound\n\n if (typeof value === 'string' && fails(value.length)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin\n ? `Value is below minimum length of ${bound}`\n : `Value exceeds maximum length of ${bound}`,\n `${value.length} characters`,\n `${isMin ? 'At least' : 'At most'} ${bound} characters`,\n `Provide a value with ${isMin ? 'at least' : 'at most'} ${bound} characters`,\n ),\n )\n } else if (typeof value === 'number' && fails(value)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin ? `Value is below minimum of ${bound}` : `Value exceeds maximum of ${bound}`,\n String(value),\n `${isMin ? 'At least' : 'At most'} ${bound}`,\n `Provide a value of ${isMin ? 'at least' : 'at most'} ${bound}`,\n ),\n )\n } else if (Array.isArray(value) && fails(value.length)) {\n target.push(\n createError(\n path,\n 'VALUE_OUT_OF_RANGE',\n isMin ? `Array has fewer than ${bound} items` : `Array has more than ${bound} items`,\n `${value.length} items`,\n `${isMin ? 'At least' : 'At most'} ${bound} items`,\n `Provide ${isMin ? 'at least' : 'at most'} ${bound} items`,\n ),\n )\n }\n}\n\n/** Validate value against an enum constraint. For arrays, checks each item. */\nfunction validateEnum(\n value: unknown,\n r: Record<string, unknown>,\n path: string,\n target: ValidationError[],\n): void {\n const allowedValues = (r.values as unknown[]) || (r.constraint as unknown[])\n if (!allowedValues) return\n\n const resolvedValues = allowedValues.map(resolveEncodedValue)\n const formatAllowed = () => resolvedValues.map((v) => JSON.stringify(v)).join(', ')\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n if (!resolvedValues.includes(value[i])) {\n target.push(\n createError(\n `${path}[${i}]`,\n 'INVALID_ENUM_VALUE',\n 'Array item is not one of the allowed options',\n formatValue(value[i]),\n `One of: ${formatAllowed()}`,\n `Use one of the allowed values: ${formatAllowed()}`,\n ),\n )\n }\n }\n } else if (!resolvedValues.includes(value)) {\n target.push(\n createError(\n path,\n 'INVALID_ENUM_VALUE',\n 'Value is not one of the allowed options',\n formatValue(value),\n `One of: ${formatAllowed()}`,\n `Use one of the allowed values: ${formatAllowed()}`,\n ),\n )\n }\n}\n\n/** Validate a string value against a regex pattern. */\nfunction validateRegex(\n value: unknown,\n r: Record<string, unknown>,\n path: string,\n target: ValidationError[],\n): void {\n if (!r.pattern || typeof value !== 'string') return\n\n const pattern = r.pattern as string\n const flags = (r.flags as string) || ''\n\n try {\n const regex = new RegExp(pattern, flags)\n if (!regex.test(value)) {\n target.push(\n createError(\n path,\n 'INVALID_FORMAT',\n 'Value does not match required regex pattern',\n formatValue(value),\n `String matching pattern: ${pattern}`,\n 'Provide a value that matches the required format',\n ),\n )\n }\n } catch {\n // Invalid regex pattern — skip rather than error\n }\n}\n\n/** Validate that an array contains no duplicate items. */\nfunction validateUniqueRule(value: unknown, path: string, target: ValidationError[]): void {\n if (!Array.isArray(value)) return\n\n const seen = new Set<string>()\n for (let i = 0; i < value.length; i++) {\n const key = getUniquenessKey(value[i])\n if (seen.has(key)) {\n target.push(\n createError(\n `${path}[${i}]`,\n 'DUPLICATE_ARRAY_ITEM',\n 'Duplicate item in array with unique constraint',\n formatValue(value[i]),\n 'Unique array items',\n 'Remove or modify duplicate items in the array',\n ),\n )\n break // Only report first duplicate\n }\n seen.add(key)\n }\n}\n","/**\n * Reference validator - validates document references.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationContext, ValidationError } from './types.js'\nimport { createError, formatValue, validateNoExtraProperties } from './utils.js'\n\n/**\n * Validate a reference value.\n * Checks structure and optionally validates existence via client.\n */\nexport async function validateReference(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n context: ValidationContext,\n): Promise<void> {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid reference value',\n formatValue(value),\n 'Object with { _type: \"reference\", _ref: \"document-id\" }',\n 'Provide a reference object like { _type: \"reference\", _ref: \"person-123\" }',\n ),\n )\n return\n }\n\n const refObj = value as Record<string, unknown>\n\n // Global document references (e.g. media library links) are cross-system —\n // skip validation, just ensure _weak is set.\n if (refObj._type === 'globalDocumentReference') {\n return\n }\n\n // Check _ref exists and is not empty\n if (typeof refObj._ref !== 'string') {\n errors.push(\n createError(\n `${path}._ref`,\n 'INVALID_REFERENCE',\n 'Reference missing \"_ref\" property',\n formatValue(refObj._ref),\n 'string (document ID)',\n 'Provide a valid document ID in the _ref property',\n ),\n )\n return\n }\n\n // Check _ref is not empty\n if (refObj._ref === '') {\n errors.push(\n createError(\n `${path}._ref`,\n 'INVALID_REFERENCE',\n 'Reference \"_ref\" cannot be empty',\n '\"\"',\n 'Non-empty string (document ID)',\n 'Provide a valid document ID in the _ref property',\n ),\n )\n return\n }\n\n // Check for extra properties not allowed on references\n const allowedReferenceProperties = new Set([\n '_ref',\n '_type',\n '_weak',\n '_key',\n '_strengthenOnPublish',\n ])\n validateNoExtraProperties(refObj, allowedReferenceProperties, path, 'reference', errors)\n\n // Get allowed target types from schema\n const allowedTypes: string[] = []\n if (fieldSchema.to && Array.isArray(fieldSchema.to)) {\n for (const target of fieldSchema.to) {\n const targetType = (target as { type?: string }).type\n if (targetType) {\n allowedTypes.push(targetType)\n }\n }\n }\n\n // Weak references are allowed to dangle — skip existence check.\n // Structure validation (above) still applies.\n if (refObj._weak) {\n return\n }\n\n // Validate reference exists via client (if available)\n if (context.client) {\n try {\n const doc = await context.client.getDocument(refObj._ref as string)\n\n if (!doc) {\n errors.push(\n createError(\n `${path}._ref`,\n 'REFERENCE_NOT_FOUND',\n 'Referenced document does not exist',\n formatValue(refObj._ref),\n allowedTypes.length > 0\n ? `Valid document ID of type \"${allowedTypes.join('\" or \"')}\"`\n : 'Valid document ID',\n 'Use an existing document ID, or create the document first',\n ),\n )\n return\n }\n\n // Check document type matches allowed types\n if (allowedTypes.length > 0 && !allowedTypes.includes(doc._type)) {\n errors.push(\n createError(\n `${path}._ref`,\n 'REFERENCE_WRONG_TYPE',\n 'Reference points to wrong document type',\n `Document \"${refObj._ref}\" (type: ${doc._type})`,\n `Reference to document of type \"${allowedTypes.join('\" or \"')}\"`,\n `Use a document ID that references a \"${allowedTypes[0]}\" document`,\n ),\n )\n }\n } catch {\n // Network error or other issue - skip existence validation\n // The error will be caught at commit time\n }\n }\n}\n","/**\n * Walks a document and reports paths where a schema-required field is missing.\n *\n * Recurses into nested objects and array items so required fields anywhere\n * in the tree are caught. When a parent is missing, the report stops at the\n * parent rather than enumerating every required descendant.\n *\n * No cycle guard is needed: recursion is bounded by document data, not by the\n * schema graph. Self-referencing object types only recurse as deep as the data\n * actually nests.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport { joinSchemaPath } from '../navigate/walkTree.js'\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\nimport { hasRequiredValidator } from './rules'\nimport type { ValidationError } from './types'\nimport { createError, formatValue } from './utils'\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isMissing = (value: unknown): boolean => {\n if (value === undefined || value === null) return true\n if (typeof value === 'string') return value.length === 0\n if (Array.isArray(value)) return value.length === 0\n return false\n}\n\nconst missingRequiredError = (path: string, field: ManifestField): ValidationError =>\n createError(\n path,\n 'REQUIRED_FIELD_MISSING',\n `Required field \"${field.name}\" is missing`,\n formatValue(undefined),\n `${field.title ?? field.name} (${field.type})`,\n `Set a value for \"${field.name}\" before publishing`,\n )\n\nconst itemPath = (parent: string, item: Record<string, unknown>, index: number): string => {\n const key = item._key\n return typeof key === 'string' ? `${parent}[_key==\"${key}\"]` : `${parent}[${index}]`\n}\n\nconst resolveItemFields = (\n itemSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): ManifestField[] | undefined => {\n // Inline object items in `of` declare their own fields.\n if (itemSchema.fields?.length) return itemSchema.fields\n if (!itemSchema.type || isPrimitiveType(itemSchema.type)) return undefined\n const referenced = schema.find((s) => s.name === itemSchema.type)\n return referenced?.fields\n}\n\nfunction walkArray(\n field: ManifestField,\n value: unknown[],\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n if (!field.of?.length) return\n\n for (let index = 0; index < value.length; index++) {\n const item = value[index]\n if (!isPlainObject(item)) continue\n\n const matched = field.of.find((member) => member.type === item._type) ?? field.of[0]\n const itemFields = resolveItemFields(matched as ManifestSchemaType, schema)\n if (!itemFields?.length) continue\n\n walkFields(itemFields, item, itemPath(path, item, index), schema, errors)\n }\n}\n\nfunction walkFields(\n fields: ManifestField[],\n value: unknown,\n path: string,\n schema: ManifestSchemaType[],\n errors: ValidationError[],\n): void {\n const obj = isPlainObject(value) ? value : {}\n\n for (const field of fields) {\n const fieldValue = obj[field.name]\n const fieldPath = joinSchemaPath(path, field.name)\n\n if (hasRequiredValidator(field) && isMissing(fieldValue)) {\n errors.push(missingRequiredError(fieldPath, field))\n continue\n }\n\n if (isMissing(fieldValue)) continue\n\n if (Array.isArray(fieldValue)) {\n walkArray(field, fieldValue, fieldPath, schema, errors)\n continue\n }\n\n if (field.fields?.length) {\n walkFields(field.fields, fieldValue, fieldPath, schema, errors)\n continue\n }\n\n if (!field.type || isPrimitiveType(field.type)) continue\n const referenced = schema.find((s) => s.name === field.type)\n if (referenced?.fields?.length) {\n walkFields(referenced.fields, fieldValue, fieldPath, schema, errors)\n }\n }\n}\n\nexport function validateRequiredFields(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n): ValidationError[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema?.fields?.length) return []\n\n const errors: ValidationError[] = []\n walkFields(typeSchema.fields, document, '', schema, errors)\n return errors\n}\n","/**\n * Detects slug collisions before publishing.\n *\n * Mirrors Studio's default `isUnique` behavior (cross-document-type uniqueness).\n * If a schema customizes `options.isUnique`, we cannot replicate the function:\n * the manifest serializes it as `{ __type: 'function' }`. We skip the check\n * for that field and let the server/Studio surface the real error after publish.\n *\n * Only top-level slug fields are checked. Nested slugs in arrays/objects are\n * uncommon and require path semantics we don't have here yet.\n */\n\nimport type { SanityClient } from '@sanity/client'\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types'\nimport { createError, formatValue } from './utils'\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\ntype SlugField = {\n path: string\n field: ManifestField\n current: string\n}\n\n/** True when the field is a slug, including aliased custom types that extend slug. */\nconst isSlugType = (field: ManifestField, schema: ManifestSchemaType[]): boolean => {\n if (field.type === 'slug') return true\n const referenced = schema.find((s) => s.name === field.type)\n return referenced?.type === 'slug'\n}\n\nconst hasCustomIsUnique = (field: ManifestField): boolean => {\n const isUnique = field.options?.isUnique\n return isPlainObject(isUnique) && isUnique.__type === 'function'\n}\n\nconst readSlugCurrent = (value: unknown): string | undefined => {\n if (!isPlainObject(value)) return undefined\n const current = value.current\n return typeof current === 'string' && current.length > 0 ? current : undefined\n}\n\nfunction collectSlugFields(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n): SlugField[] {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema?.fields?.length) return []\n\n const out: SlugField[] = []\n for (const field of typeSchema.fields) {\n if (!isSlugType(field, schema)) continue\n const current = readSlugCurrent(document[field.name])\n if (current === undefined) continue\n out.push({ path: field.name, field, current })\n }\n return out\n}\n\nconst collisionError = (path: string, current: string, conflictingId: string): ValidationError =>\n createError(\n `${path}.current`,\n 'INVALID_FORMAT',\n `Slug \"${current}\" is already in use by another document`,\n formatValue(current),\n 'A slug not used by any other document',\n `Choose a different slug for \"${path}\". The conflicting document is \"${conflictingId}\".`,\n )\n\n/**\n * Check whether the slug values on a draft collide with any other document in\n * the dataset (excluding the draft and its published twin).\n */\nexport async function validateSlugCollisions(\n document: Record<string, unknown>,\n documentType: string,\n schema: ManifestSchemaType[],\n client: SanityClient,\n ids: { publishedId: string; draftId: string },\n): Promise<ValidationError[]> {\n const slugs = collectSlugFields(document, documentType, schema)\n if (slugs.length === 0) return []\n\n const checks = await Promise.all(\n slugs.map(async ({ path, field, current }) => {\n if (hasCustomIsUnique(field)) return undefined\n\n // Mirrors Studio's default `defaultIsUnique`: cross-document-type, excluding\n // both ID variants of the document being published.\n //\n // `path` is interpolated rather than parameterized because GROQ does not\n // support parameterizing field paths. The value comes from a schema field\n // name, which the manifest constrains to safe identifiers.\n const query = `*[!(_id in [$publishedId, $draftId]) && ${path}.current == $slug][0]._id`\n const conflictingId = await client.fetch<string | null>(query, {\n publishedId: ids.publishedId,\n draftId: ids.draftId,\n slug: current,\n })\n\n return conflictingId ? collisionError(path, current, conflictingId) : undefined\n }),\n )\n\n return checks.filter((e): e is ValidationError => e !== undefined)\n}\n","/**\n * Validators for special Sanity types: slug, geopoint, image, file.\n */\n\nimport type { ManifestSchemaType } from '../types.js'\nimport type { ValidationError } from './types.js'\nimport {\n createError,\n formatValue,\n getActualJsType,\n getExpectedJsType,\n validateNoExtraProperties,\n} from './utils.js'\n\n/**\n * Validate a slug value.\n */\nexport function validateSlug(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid slug value',\n formatValue(value),\n 'Object with { _type: \"slug\", current: \"slug-value\" }',\n 'Provide a slug object like { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n return\n }\n\n const slugObj = value as Record<string, unknown>\n\n // Validate _type is \"slug\" if present\n if (slugObj._type !== undefined && slugObj._type !== 'slug') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Slug has wrong _type value',\n formatValue(slugObj._type),\n '_type: \"slug\"',\n 'Set _type to \"slug\", e.g., { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n }\n\n if (typeof slugObj.current !== 'string') {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Slug missing \"current\" property',\n formatValue(value),\n 'Object with \"current\" string property',\n 'Add a \"current\" property with the slug string, e.g., { _type: \"slug\", current: \"my-page\" }',\n ),\n )\n }\n\n // Check for extra properties\n const allowedSlugProperties = new Set(['_type', 'current'])\n validateNoExtraProperties(slugObj, allowedSlugProperties, path, 'slug', errors)\n}\n\n/**\n * Validate a geopoint value.\n */\nexport function validateGeopoint(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid geopoint value',\n formatValue(value),\n 'Object with { _type: \"geopoint\", lat: number, lng: number }',\n 'Provide a geopoint object like { _type: \"geopoint\", lat: 37.7749, lng: -122.4194 }',\n ),\n )\n return\n }\n\n const geoObj = value as Record<string, unknown>\n\n // Validate latitude\n if (typeof geoObj.lat !== 'number') {\n errors.push(\n createError(\n `${path}.lat`,\n 'TYPE_MISMATCH',\n 'Geopoint missing valid \"lat\" property',\n formatValue(geoObj.lat),\n 'number (latitude in degrees)',\n 'Provide a numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (Number.isNaN(geoObj.lat)) {\n errors.push(\n createError(\n `${path}.lat`,\n 'TYPE_MISMATCH',\n 'Geopoint latitude is NaN',\n 'NaN',\n 'A valid numeric latitude (-90 to 90)',\n 'Provide a valid numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (!Number.isFinite(geoObj.lat)) {\n errors.push(\n createError(\n `${path}.lat`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint latitude is infinite',\n geoObj.lat > 0 ? 'Infinity' : '-Infinity',\n 'A finite numeric latitude (-90 to 90)',\n 'Provide a valid numeric latitude value, e.g., 37.7749',\n ),\n )\n } else if (geoObj.lat < -90 || geoObj.lat > 90) {\n errors.push(\n createError(\n `${path}.lat`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint latitude out of range',\n String(geoObj.lat),\n 'Latitude between -90 and 90 degrees',\n 'Provide a latitude between -90 and 90, e.g., 37.7749',\n ),\n )\n }\n\n // Validate longitude\n if (typeof geoObj.lng !== 'number') {\n errors.push(\n createError(\n `${path}.lng`,\n 'TYPE_MISMATCH',\n 'Geopoint missing valid \"lng\" property',\n formatValue(geoObj.lng),\n 'number (longitude in degrees)',\n 'Provide a numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (Number.isNaN(geoObj.lng)) {\n errors.push(\n createError(\n `${path}.lng`,\n 'TYPE_MISMATCH',\n 'Geopoint longitude is NaN',\n 'NaN',\n 'A valid numeric longitude (-180 to 180)',\n 'Provide a valid numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (!Number.isFinite(geoObj.lng)) {\n errors.push(\n createError(\n `${path}.lng`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint longitude is infinite',\n geoObj.lng > 0 ? 'Infinity' : '-Infinity',\n 'A finite numeric longitude (-180 to 180)',\n 'Provide a valid numeric longitude value, e.g., -122.4194',\n ),\n )\n } else if (geoObj.lng < -180 || geoObj.lng > 180) {\n errors.push(\n createError(\n `${path}.lng`,\n 'VALUE_OUT_OF_RANGE',\n 'Geopoint longitude out of range',\n String(geoObj.lng),\n 'Longitude between -180 and 180 degrees',\n 'Provide a longitude between -180 and 180, e.g., -122.4194',\n ),\n )\n }\n\n // Check for extra properties\n const allowedGeopointProperties = new Set(['_type', 'lat', 'lng', 'alt'])\n validateNoExtraProperties(geoObj, allowedGeopointProperties, path, 'geopoint', errors)\n}\n\n/**\n * Validate an image value structure.\n * Note: Asset existence is validated separately in reference validation.\n */\nexport function validateImage(\n value: unknown,\n path: string,\n errors: ValidationError[],\n fieldSchema?: ManifestSchemaType,\n schema?: ManifestSchemaType[],\n): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid image value',\n formatValue(value),\n 'Object with { _type: \"image\", asset: { _type: \"reference\", _ref: \"...\" } }',\n 'Provide an image object or use the create-image tool',\n ),\n )\n return\n }\n\n // Image can be empty (no asset yet) or have an asset reference\n const imgObj = value as Record<string, unknown>\n\n // Validate _type is \"image\" or matches the custom type name (e.g. \"ImageDefault\")\n if (\n imgObj._type !== undefined &&\n imgObj._type !== 'image' &&\n imgObj._type !== fieldSchema?.name\n ) {\n errors.push(\n createError(\n `${path}._type`,\n 'TYPE_MISMATCH',\n 'Image must have _type: \"image\"',\n formatValue(imgObj._type),\n '_type: \"image\"',\n 'Set _type to \"image\"',\n ),\n )\n }\n\n // If there's an asset, validate its structure\n if (imgObj.asset !== undefined && imgObj.asset !== null) {\n const asset = imgObj.asset as Record<string, unknown>\n\n // Validate asset._ref first (most common error)\n if (typeof asset._ref !== 'string') {\n errors.push(\n createError(\n `${path}.asset._ref`,\n 'TYPE_MISMATCH',\n 'Image asset missing \"_ref\" property',\n formatValue(asset._ref),\n 'string (asset document ID)',\n 'Provide a valid asset reference like { _type: \"reference\", _ref: \"image-abc123-...\" }',\n ),\n )\n }\n\n // Validate asset._type is \"reference\"\n if (asset._type !== 'reference') {\n errors.push(\n createError(\n `${path}.asset._type`,\n 'TYPE_MISMATCH',\n 'Image asset must have _type: \"reference\"',\n formatValue(asset._type),\n '_type: \"reference\"',\n 'Set asset._type to \"reference\", e.g., { _type: \"reference\", _ref: \"image-abc123-...\" }',\n ),\n )\n }\n }\n\n // Validate hotspot if present\n if (imgObj.hotspot !== undefined && imgObj.hotspot !== null) {\n const hotspot = imgObj.hotspot as Record<string, unknown>\n\n // Validate hotspot properties are numbers in range 0-1\n const hotspotProps = ['x', 'y', 'height', 'width'] as const\n for (const prop of hotspotProps) {\n if (hotspot[prop] !== undefined) {\n if (typeof hotspot[prop] !== 'number') {\n errors.push(\n createError(\n `${path}.hotspot.${prop}`,\n 'TYPE_MISMATCH',\n `Hotspot ${prop} must be a number`,\n formatValue(hotspot[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for hotspot.${prop}`,\n ),\n )\n } else if ((hotspot[prop] as number) < 0 || (hotspot[prop] as number) > 1) {\n errors.push(\n createError(\n `${path}.hotspot.${prop}`,\n 'VALUE_OUT_OF_RANGE',\n `Hotspot ${prop} out of range`,\n String(hotspot[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for hotspot.${prop}`,\n ),\n )\n }\n }\n }\n }\n\n // Validate crop if present\n if (imgObj.crop !== undefined && imgObj.crop !== null) {\n const crop = imgObj.crop as Record<string, unknown>\n\n // Validate crop properties are numbers in range 0-1\n const cropProps = ['top', 'bottom', 'left', 'right'] as const\n for (const prop of cropProps) {\n if (crop[prop] !== undefined) {\n if (typeof crop[prop] !== 'number') {\n errors.push(\n createError(\n `${path}.crop.${prop}`,\n 'TYPE_MISMATCH',\n `Crop ${prop} must be a number`,\n formatValue(crop[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for crop.${prop}`,\n ),\n )\n } else if ((crop[prop] as number) < 0 || (crop[prop] as number) > 1) {\n errors.push(\n createError(\n `${path}.crop.${prop}`,\n 'VALUE_OUT_OF_RANGE',\n `Crop ${prop} out of range`,\n String(crop[prop]),\n 'number between 0 and 1',\n `Provide a number between 0 and 1 for crop.${prop}`,\n ),\n )\n }\n }\n }\n }\n\n // Validate custom metadata fields if schema is provided\n if (fieldSchema?.fields && schema) {\n for (const field of fieldSchema.fields) {\n const fieldValue = imgObj[field.name]\n if (fieldValue !== undefined && fieldValue !== null) {\n // Basic type validation for custom metadata fields\n const expectedType = getExpectedJsType(field.type)\n const actualType = getActualJsType(fieldValue)\n if (actualType !== expectedType) {\n errors.push(\n createError(\n `${path}.${field.name}`,\n 'TYPE_MISMATCH',\n `Image metadata field \"${field.name}\" has wrong type`,\n formatValue(fieldValue),\n expectedType,\n `Provide a ${expectedType} value for ${field.name}`,\n ),\n )\n }\n }\n }\n }\n\n // Check for extra properties - include built-in image properties + any schema-defined fields\n // _key is allowed because images can be array items\n const allowedImageProperties = new Set(['_type', '_key', 'asset', 'hotspot', 'crop'])\n\n // Add fields defined in schema.fields\n if (fieldSchema?.fields) {\n for (const field of fieldSchema.fields) {\n allowedImageProperties.add(field.name)\n }\n }\n\n // Add fields from options (captionField, aiAssist.imageDescriptionField)\n if (fieldSchema?.options) {\n const options = fieldSchema.options as Record<string, unknown>\n\n // Handle options.captionField\n if (typeof options.captionField === 'string') {\n allowedImageProperties.add(options.captionField)\n }\n\n // Handle options.aiAssist.imageDescriptionField\n if (options.aiAssist && typeof options.aiAssist === 'object') {\n const aiAssist = options.aiAssist as Record<string, unknown>\n if (typeof aiAssist.imageDescriptionField === 'string') {\n allowedImageProperties.add(aiAssist.imageDescriptionField)\n }\n }\n }\n\n validateNoExtraProperties(imgObj, allowedImageProperties, path, 'image', errors)\n}\n\n/**\n * Validate a file value structure.\n */\nexport function validateFile(value: unknown, path: string, errors: ValidationError[]): void {\n if (typeof value !== 'object' || value === null) {\n errors.push(\n createError(\n path,\n 'TYPE_MISMATCH',\n 'Invalid file value',\n formatValue(value),\n 'Object with { _type: \"file\", asset: { _type: \"reference\", _ref: \"...\" } }',\n 'Provide a file object with an asset reference',\n ),\n )\n return\n }\n\n const fileObj = value as Record<string, unknown>\n\n // Validate _type is \"file\"\n if (fileObj._type !== undefined && fileObj._type !== 'file') {\n errors.push(\n createError(\n `${path}._type`,\n 'TYPE_MISMATCH',\n 'File must have _type: \"file\"',\n formatValue(fileObj._type),\n '_type: \"file\"',\n 'Set _type to \"file\"',\n ),\n )\n }\n\n // If there's an asset, validate its structure\n if (fileObj.asset !== undefined && fileObj.asset !== null) {\n const asset = fileObj.asset as Record<string, unknown>\n\n // Validate asset._type is \"reference\"\n if (asset._type !== 'reference') {\n errors.push(\n createError(\n `${path}.asset._type`,\n 'TYPE_MISMATCH',\n 'File asset must have _type: \"reference\"',\n formatValue(asset._type),\n '_type: \"reference\"',\n 'Set asset._type to \"reference\", e.g., { _type: \"reference\", _ref: \"file-abc123-...\" }',\n ),\n )\n }\n\n if (typeof asset._ref !== 'string') {\n errors.push(\n createError(\n `${path}.asset._ref`,\n 'TYPE_MISMATCH',\n 'File asset missing \"_ref\" property',\n formatValue(asset._ref),\n 'string (asset document ID)',\n 'Provide a valid asset reference like { _type: \"reference\", _ref: \"file-abc123-...\" }',\n ),\n )\n }\n }\n\n // Check for extra properties\n // _key is allowed because files can be array items\n const allowedFileProperties = new Set(['_type', '_key', 'asset'])\n validateNoExtraProperties(fileObj, allowedFileProperties, path, 'file', errors)\n}\n","/**\n * Core recursive validator that dispatches to type-specific validators.\n */\n\nimport { isPrimitiveType } from '../navigate/types.js'\nimport type { ManifestSchemaType } from '../types.js'\nimport { validateArray } from './array.validator.js'\nimport { validateObject } from './object.validator.js'\nimport { validateBlock } from './portable-text.validator.js'\nimport { validatePrimitive, validateSchemaRules } from './primitive.validator.js'\nimport { validateReference } from './reference.validator.js'\nimport {\n validateFile,\n validateGeopoint,\n validateImage,\n validateSlug,\n} from './special-types.validator.js'\nimport type { ValidationContext, ValidationError } from './types.js'\n\n/**\n * Validate a single value against its schema.\n * This is the core recursive validator that dispatches to type-specific validators.\n */\nexport async function validateValue(\n value: unknown,\n fieldSchema: ManifestSchemaType,\n path: string,\n errors: ValidationError[],\n context: ValidationContext,\n schema: ManifestSchemaType[],\n warnings?: ValidationError[],\n): Promise<void> {\n const schemaType = fieldSchema.type\n\n // Handle null/undefined - we don't enforce required fields\n if (value === null || value === undefined) {\n return\n }\n\n // Validate against schema validation rules (min, max, enum, uniqueItems)\n validateSchemaRules(value, fieldSchema, path, errors, warnings)\n\n // Route to appropriate validator based on type\n switch (schemaType) {\n // Primitive types\n case 'string':\n case 'text':\n case 'number':\n case 'boolean':\n case 'date':\n case 'datetime':\n case 'url':\n case 'email':\n validatePrimitive(value, schemaType, path, errors, fieldSchema)\n break\n\n // Special types\n case 'slug':\n validateSlug(value, path, errors)\n break\n\n case 'geopoint':\n validateGeopoint(value, path, errors)\n break\n\n case 'image':\n validateImage(value, path, errors, fieldSchema, schema)\n break\n\n case 'file':\n validateFile(value, path, errors)\n break\n\n case 'reference':\n await validateReference(value, fieldSchema, path, errors, context)\n break\n\n // Array type\n case 'array':\n await validateArray(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Block type (Portable Text) - special validation\n case 'block':\n await validateBlock(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Object/document types\n case 'object':\n case 'document':\n await validateObject(value, fieldSchema, path, schema, errors, context, validateValue)\n break\n\n // Custom types - look up in schema\n default: {\n const customSchema = schema.find((s) => s.name === schemaType)\n if (customSchema) {\n // Determine actual type from custom schema\n const actualType = customSchema.type\n if (actualType === 'array') {\n await validateArray(value, customSchema, path, schema, errors, context, validateValue)\n } else if (actualType === 'object' || actualType === 'document') {\n await validateObject(value, customSchema, path, schema, errors, context, validateValue)\n } else if (actualType === 'reference') {\n await validateReference(value, customSchema, path, errors, context)\n } else if (isPrimitiveType(actualType)) {\n validatePrimitive(value, actualType, path, errors)\n } else {\n // Nested custom type - recurse\n await validateValue(value, customSchema, path, errors, context, schema)\n }\n }\n // Unknown type - skip validation\n break\n }\n }\n}\n","/**\n * Pre-publish validation pipeline.\n *\n * Reuses the structural validator (`validateValue` via `validateObject`) for\n * type and value checks, then layers on:\n * - required-field presence (the structural validator skips this for unset fields)\n * - slug uniqueness across the dataset\n *\n * Custom validators (`Rule.custom(...)`) cannot be replicated because function\n * bodies aren't serialized into the manifest. Use `detectCustomValidators` to\n * identify affected paths and surface them to the user before publishing.\n */\n\nimport type { SanityClient } from '@sanity/client'\nimport type { ManifestSchemaType } from '../types.js'\nimport { validateObject } from './object.validator'\nimport { validateRequiredFields } from './requiredFields'\nimport { validateSlugCollisions } from './slugCollisions'\nimport type { ValidationError, ValidationResult } from './types'\nimport { createError } from './utils'\nimport { validateValue } from './validate-value'\n\ntype ValidateForPublishInput = {\n document: Record<string, unknown>\n documentType: string\n schema: ManifestSchemaType[]\n client: SanityClient\n publishedId: string\n draftId: string\n}\n\nexport async function validateForPublish({\n document,\n documentType,\n schema,\n client,\n publishedId,\n draftId,\n}: ValidateForPublishInput): Promise<ValidationResult> {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema) {\n return {\n valid: false,\n errors: [\n createError(\n '_type',\n 'FIELD_NOT_IN_SCHEMA',\n `Document type \"${documentType}\" not found in schema`,\n documentType,\n 'Valid document type',\n 'Check the schema for valid document type names',\n ),\n ],\n warnings: [],\n }\n }\n\n const structuralErrors: ValidationError[] = []\n\n const [, slugs] = await Promise.all([\n validateObject(\n document,\n typeSchema,\n '',\n schema,\n structuralErrors,\n { documentType, client },\n validateValue,\n ),\n validateSlugCollisions(document, documentType, schema, client, { publishedId, draftId }),\n ])\n const required = validateRequiredFields(document, documentType, schema)\n\n const errors = [...structuralErrors, ...required, ...slugs]\n return { valid: errors.length === 0, errors, warnings: [] }\n}\n"],"names":["validateValue","itemPath","languageIds","getValueAtPathWithKeys","isPlainObject"],"mappings":"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"}