@sanity/validation 6.12.0-next.32 → 6.12.0-next.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,3 +10,20 @@ const markers = await validateDocument({document, schema, client})
10
10
 
11
11
  The package reports validation markers. It does not apply mutations or decide whether a document
12
12
  may be edited or published.
13
+
14
+ ## Migrating from `sanity`
15
+
16
+ Add `@sanity/validation` as a direct dependency. The workspace-based API is available as a
17
+ compatibility overload, so call sites that only import `validateDocument` can migrate by changing
18
+ the import:
19
+
20
+ ```ts
21
+ import {validateDocument} from '@sanity/validation'
22
+
23
+ const markers = await validateDocument({document, workspace})
24
+ ```
25
+
26
+ Call sites that also import `ValidateDocumentOptions` from `sanity` should use
27
+ `ValidateDocumentWorkspaceOptions` for the workspace-shaped options.
28
+
29
+ Prefer the `{document, schema, client}` API for new code.
@@ -1,4 +1,4 @@
1
- import { c as validateItem, i as resolveTypeForArrayItem, l as ValidationContext, n as ValidateDocumentObservableOptions, o as validateDocumentInternal, s as validateDocumentObservable, t as ValidateDocumentInternalOptions, u as LocaleSource } from "./validateDocument-C6wlQ7gA.js";
1
+ import { c as validateDocumentInternal, d as validateItem, f as ValidationContext, l as validateDocumentObservable, n as ValidateDocumentObservableOptions, o as resolveTypeForArrayItem, p as LocaleSource, t as ValidateDocumentInternalOptions } from "./validateDocument-CBOsd748.js";
2
2
  import { Path, Rule as Rule$1, RuleClass, Schema, SchemaType, SchemaValidationValue, ValidationContext as ValidationContext$1, ValidationError, ValidationMarker } from "@sanity/types";
3
3
  declare function getFallbackLocaleSource(): LocaleSource;
4
4
  declare const validationLocaleStrings: {
package/lib/_internal.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as validateItem, c as Rule, d as pathToString, f as getFallbackLocaleSource, i as validateDocumentObservable, l as typeString, o as getTypeChain, p as validationLocaleStrings, r as validateDocumentInternal, s as normalizeValidationRules, t as resolveTypeForArrayItem, u as convertToValidationMarker } from "./validateDocument-il4G-TLy.js";
1
+ import { c as normalizeValidationRules, d as convertToValidationMarker, f as pathToString, i as validateDocumentObservable, l as Rule, m as validationLocaleStrings, o as validateItem, p as getFallbackLocaleSource, r as validateDocumentInternal, s as getTypeChain, t as resolveTypeForArrayItem, u as typeString } from "./validateDocument-C77_Oewa.js";
2
2
  function inferFromSchemaType(typeDef) {
3
3
  return traverse(typeDef, /* @__PURE__ */ new Set()), typeDef;
4
4
  }
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as validateDocument, r as ValidateDocumentOptions } from "./validateDocument-C6wlQ7gA.js";
2
- export { type ValidateDocumentOptions, validateDocument };
1
+ import { a as ValidationSource, i as ValidateDocumentWorkspaceOptions, r as ValidateDocumentOptions, s as validateDocument, u as validateDocumentWithWorkspace } from "./validateDocument-CBOsd748.js";
2
+ export { type ValidateDocumentOptions, type ValidateDocumentWorkspaceOptions, type ValidationSource, validateDocument, validateDocumentWithWorkspace };
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as validateDocument } from "./validateDocument-il4G-TLy.js";
2
- export { validateDocument };
1
+ import { a as validateDocumentWithWorkspace, n as validateDocument } from "./validateDocument-C77_Oewa.js";
2
+ export { validateDocument, validateDocumentWithWorkspace };
@@ -674,14 +674,29 @@ function resolveTypeForArrayItem(item, candidates) {
674
674
  return primitive && primitive !== "object" ? candidates.find((candidate) => candidate.jsonType === primitive) : candidates.find((candidate) => candidate.type?.name === itemType) || candidates.find((candidate) => candidate.name === itemType) || candidates.find((candidate) => candidate.name === "object" && primitive === "object");
675
675
  }
676
676
  /**
677
- * Validates a document against a compiled schema. Returns validation markers
678
- * without deciding whether the document may be edited or published.
677
+ * Validates a document against the schema in a resolved Studio workspace or source.
679
678
  *
680
679
  * @beta
680
+ * @deprecated Prefer {@link validateDocument} with `{document, schema, client}` for new code.
681
681
  */
682
- function validateDocument({ client, document, schema, ...options }) {
682
+ function validateDocumentWithWorkspace({ document, workspace, getClient = workspace.getClient, getDocumentExists, environment = "studio", maxCustomValidationConcurrency, maxFetchConcurrency, currentUser }) {
683
683
  return validateDocumentInternal({
684
- ...options,
684
+ currentUser,
685
+ document,
686
+ environment,
687
+ getClient,
688
+ getDocumentExists,
689
+ i18n: workspace.i18n,
690
+ maxCustomValidationConcurrency,
691
+ maxFetchConcurrency,
692
+ schema: workspace.schema
693
+ });
694
+ }
695
+ function validateDocument(options) {
696
+ if ("workspace" in options) return validateDocumentWithWorkspace(options);
697
+ let { client, document, schema, ...internalOptions } = options;
698
+ return validateDocumentInternal({
699
+ ...internalOptions,
685
700
  document,
686
701
  environment: "cli",
687
702
  getClient: ({ apiVersion }) => client.withConfig({ apiVersion }),
@@ -823,6 +838,6 @@ function idle(timeout) {
823
838
  return () => cancelIdleCallback(handle);
824
839
  });
825
840
  }
826
- export { validateItem as a, Rule$2 as c, pathToString as d, getFallbackLocaleSource as f, validateDocumentObservable as i, typeString as l, validateDocument as n, getTypeChain as o, validationLocaleStrings as p, validateDocumentInternal as r, normalizeValidationRules as s, resolveTypeForArrayItem as t, convertToValidationMarker as u };
841
+ export { validateDocumentWithWorkspace as a, normalizeValidationRules as c, convertToValidationMarker as d, pathToString as f, validateDocumentObservable as i, Rule$2 as l, validationLocaleStrings as m, validateDocument as n, validateItem as o, getFallbackLocaleSource as p, validateDocumentInternal as r, getTypeChain as s, resolveTypeForArrayItem as t, typeString as u };
827
842
 
828
- //# sourceMappingURL=validateDocument-il4G-TLy.js.map
843
+ //# sourceMappingURL=validateDocument-C77_Oewa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validateDocument-il4G-TLy.js","names":["isRecord","Rule","BaseRule","RuleClass","switchMap","mergeMap","map"],"sources":["../src/i18n/resources.ts","../src/i18n/fallback.ts","../src/resolveConditionalProperty.ts","../src/util/createBatchedGetDocumentExists.ts","../src/util/pathToString.ts","../src/util/convertToValidationMarker.ts","../src/util/localizeMessage.ts","../src/util/deepEqualsIgnoreKey.ts","../src/util/typeString.ts","../src/validators/genericValidator.ts","../src/validators/arrayValidator.ts","../src/validators/booleanValidator.ts","../src/validators/dateValidator.ts","../src/validators/numberValidator.ts","../src/validators/objectValidator.ts","../src/validators/stringValidator.ts","../src/Rule.ts","../src/validators/slugValidator.ts","../src/util/normalizeValidationRules.ts","../src/util/requestIdleCallback.ts","../src/validators/unknownFieldsValidator.ts","../src/validateDocument.ts"],"sourcesContent":["export const validationLocaleStrings = {\n 'array.exact-length': 'Must have exactly {{wantedLength}} items',\n 'array.exact-length_blocks': 'Must have exactly {{wantedLength}} blocks',\n 'array.item-duplicate': \"Can't be a duplicate\",\n 'array.maximum-length': 'Must have at most {{maxLength}} items',\n 'array.maximum-length_blocks': 'Must have at most {{maxLength}} blocks',\n 'array.minimum-length': 'Must have at least {{minLength}} items',\n 'array.minimum-length_blocks': 'Must have at least {{minLength}} blocks',\n 'date.invalid-format': 'Must be a valid ISO-8601 formatted date string',\n 'date.maximum': 'Must be at or before {{maxDate}}',\n 'date.minimum': 'Must be at or after {{minDate}}',\n 'generic.incorrect-type': 'Expected type \"{{expectedType}}\", got \"{{actualType}}\"',\n 'generic.not-allowed': 'Value did not match any allowed values',\n 'generic.not-allowed_hint': 'Value \"{{hint}}\" did not match any allowed values',\n 'generic.required': 'Required',\n 'number.greater-than': 'Must be greater than {{threshold}}',\n 'number.less-than': 'Must be less than {{threshold}}',\n 'number.maximum': 'Must be lower than or equal to {{maxNumber}}',\n 'number.maximum-precision': 'Max precision is {{limit}}',\n 'number.minimum': 'Must be greater than or equal to {{minNumber}}',\n 'number.non-integer': 'Must be an integer',\n 'object.asset-required': 'Asset is required',\n 'object.asset-required_file': 'File is required',\n 'object.asset-required_image': 'Image is required',\n 'object.media-not-found': 'The asset could not be found in the Media Library',\n 'object.not-media-library-asset': 'Must be a reference to a Media Library asset',\n 'object.not-reference': 'Must be a reference to a document',\n 'object.reference-not-published': 'Referenced document must be published',\n 'slug.missing-current': 'Slug must have a value',\n 'slug.not-object': 'Slug must be an object',\n 'slug.not-unique': 'Slug is already in use',\n 'string.email': 'Must be a valid email address',\n 'string.exact-length': 'Must be exactly {{wantedLength}} characters long',\n 'string.lowercase': 'Must be all lowercase characters',\n 'string.maximum-length': 'Must be at most {{maxLength}} characters long',\n 'string.minimum-length': 'Must be at least {{minLength}} characters long',\n 'string.regex-does-not-match': 'Does not match \"{{name}}\"-pattern',\n 'string.regex-match': 'Should not match \"{{name}}\"-pattern',\n 'string.uppercase': 'Must be all uppercase characters',\n 'string.url.disallowed-scheme': 'Does not match allowed protocols/schemes',\n 'string.url.includes-credentials': 'Username/password not allowed',\n 'string.url.invalid': 'Not a valid URL',\n 'string.url.not-absolute': 'Relative URLs are not allowed',\n 'string.url.not-relative': 'Only relative URLs are allowed',\n} as const\n","import {createInstance} from 'i18next'\n\nimport {validationLocaleStrings} from './resources'\nimport {type LocaleSource} from './types'\n\nlet fallbackLocaleSource: LocaleSource | undefined\n\nexport function getFallbackLocaleSource(): LocaleSource {\n if (fallbackLocaleSource) return fallbackLocaleSource\n\n const i18n = createInstance({\n defaultNS: 'validation',\n fallbackLng: 'en-US',\n initAsync: false,\n interpolation: {escapeValue: false},\n lng: 'en-US',\n ns: ['validation'],\n resources: {'en-US': {validation: validationLocaleStrings}},\n supportedLngs: ['en-US'],\n })\n void i18n.init()\n\n fallbackLocaleSource = {\n currentLocale: {id: 'en-US'},\n loadNamespaces: (namespaces) => i18n.loadNamespaces(namespaces),\n t: i18n.t,\n }\n return fallbackLocaleSource\n}\n","import {type ConditionalProperty, type CurrentUser, type Path} from '@sanity/types'\n\ninterface ConditionalPropertyCallbackContext {\n parent?: unknown\n document?: Record<string, unknown>\n currentUser: Omit<CurrentUser, 'role'> | null\n value: unknown\n path: Path\n}\n\nexport function resolveConditionalProperty(\n property: ConditionalProperty,\n context: ConditionalPropertyCallbackContext,\n) {\n const {currentUser, document, parent, value, path} = context\n\n if (typeof property === 'boolean' || property === undefined) return Boolean(property)\n\n // oxlint-disable-next-line no-unnecessary-boolean-literal-compare -- runtime callbacks may return non-booleans\n return property({document: document as never, parent, value, currentUser, path}) === true\n}\n","import {type SanityClient} from '@sanity/client'\nimport {ConcurrencyLimiter} from '@sanity/util/concurrency-limiter'\nimport {\n bufferTime,\n filter,\n finalize,\n firstValueFrom,\n from,\n map,\n mergeMap,\n share,\n Subject,\n switchMap,\n} from 'rxjs'\n\ninterface AvailabilityResponse {\n omitted: {id: string; reason: 'existence' | 'permission'}[]\n}\n\n/**\n * The amount of time reserved for waiting for new IDs.\n */\nconst BUFFER_TIME = 250\n/**\n * The upper limit for IDs sent to the `doc` endpoint at once. From some manual\n * testing, 100 seems to be a safe amount.\n */\nexport const MAX_BUFFER_SIZE = 100\n/**\n * The max amount of inflight requests to the `doc` endpoint to check for\n * availability. Currently set to 1 because the endpoint is expensive\n *\n * From: https://www.sanity.io/docs/http-doc\n *\n * \"it is less scalable/performant than the other query-mechanisms, so should\n * be used sparingly*\n */\nexport const MAX_REQUEST_CONCURRENCY = 1\n\nexport function createBatchedGetDocumentExists(\n client: SanityClient,\n): (options: {id: string}) => Promise<boolean> {\n const id$ = new Subject<string>()\n const limiter = new ConcurrencyLimiter(MAX_REQUEST_CONCURRENCY)\n\n const existence$ = id$.pipe(\n bufferTime(BUFFER_TIME, null, MAX_BUFFER_SIZE),\n map((ids) => Array.from(new Set(ids))),\n mergeMap((ids) =>\n from(limiter.ready()).pipe(\n switchMap(() =>\n client.observable\n .request<AvailabilityResponse>({\n url: client.getDataUrl('doc', ids.join(',')),\n query: {excludeContent: 'true'},\n tag: 'documents-availability',\n })\n .pipe(map((availability) => ({availability, ids}))),\n ),\n finalize(limiter.release),\n ),\n ),\n mergeMap(({availability, ids}) =>\n ids.map((id) => {\n const omittedIds = availability.omitted.reduce<Record<string, 'existence' | 'permission'>>(\n (acc, next) => {\n acc[next.id] = next.reason\n return acc\n },\n {},\n )\n\n // if not in the `omitted`, then it exists\n if (!omittedIds[id]) return {id, exists: true}\n // if in the `omitted` due to existence, then it does not exist\n if (omittedIds[id] === 'existence') return {id, exists: false}\n // otherwise, it must exist\n return {id, exists: true}\n }),\n ),\n share(),\n )\n\n return async function getDocumentExists(options) {\n // set up a promise/listener that waits for the result\n const result = firstValueFrom(existence$.pipe(filter(({id}) => id === options.id)))\n // send off the request to the stream for batching\n id$.next(options.id)\n\n const {exists} = await result\n return exists\n }\n}\n","import {isKeyedObject, type Path} from '@sanity/types'\n\nexport function pathToString(path: Path | undefined = []): string {\n return path.reduce<string>((target, segment, i) => {\n const segmentType = typeof segment\n if (segmentType === 'number') {\n return `${target}[${segment}]`\n }\n\n if (segmentType === 'string') {\n const separator = i === 0 ? '' : '.'\n return `${target}${separator}${segment}`\n }\n\n if (isKeyedObject(segment)) {\n return `${target}[_key==\"${segment._key}\"]`\n }\n\n throw new Error(`Unsupported path segment \"${segment}\"`)\n }, '')\n}\n","/* oxlint-disable typescript/no-deprecated -- marker compatibility requires legacy fields */\nimport {type Path, type ValidationError, type ValidationMarker} from '@sanity/types'\n\nimport {type ValidationContext} from '../types'\nimport {pathToString} from '../util/pathToString'\n\nfunction isNonNullable<T>(t: T): t is NonNullable<T> {\n return t !== null || t !== undefined\n}\n\nexport function convertToValidationMarker(\n validatorResult: true | true[] | string | string[] | ValidationError | ValidationError[],\n level: 'error' | 'warning' | 'info' | undefined,\n context: ValidationContext,\n): ValidationMarker[] {\n if (!context) {\n throw new Error('missing context')\n }\n\n if (validatorResult === true) return []\n\n if (Array.isArray(validatorResult)) {\n return validatorResult\n .flatMap((child) => convertToValidationMarker(child, level, context))\n .filter(isNonNullable)\n }\n\n if (typeof validatorResult === 'string') {\n return convertToValidationMarker({message: validatorResult}, level, context)\n }\n\n if (typeof validatorResult.message !== 'string') {\n // in order to accept the `ValidationError`, it at least needs to have a\n // `message` in the object\n throw new Error(\n `${pathToString(\n context.path,\n )}: Validator must return 'true' if valid or an error message as a string on errors`,\n )\n }\n\n const {message, __internal_metadata} = validatorResult\n\n const normalizedPaths: Path[] = []\n if (validatorResult.path) {\n normalizedPaths.push(validatorResult.path)\n }\n\n // legacy support for `paths`\n for (const path of validatorResult.paths || []) {\n normalizedPaths.push(path)\n }\n\n // the validator result does not include any item-level relative paths,\n // then just return the top-level path with the validation result\n if (!normalizedPaths.length) {\n return [\n {\n level: level || 'error',\n item: {message},\n message,\n path: context.path || [],\n __internal_metadata,\n },\n ]\n }\n\n // if the validator result did include item-level relative paths, then for\n // each item-level relative path, create a validation marker that concatenates\n // the relative path with the path from the validation context\n return normalizedPaths.map((path) => ({\n path: (context.path || []).concat(path),\n level: level || 'error',\n item: {message},\n message,\n __internal_metadata,\n }))\n}\n","import {type CustomValidatorResult, type LocalizedValidationMessages} from '@sanity/types'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\n\nimport {type LocaleSource} from '../i18n/types'\n\n/**\n * Extracts the correct localized validation message based on given locale source\n *\n * @param message - Localized messages to extract string from\n * @param i18n - Locale source, holding the current locale\n * @returns The localized string, or a fallback \"Unknown error\" if not found\n * @internal\n */\nexport function localizeMessage(message: LocalizedValidationMessages, i18n: LocaleSource): string {\n const {currentLocale} = i18n\n const locale = currentLocale.id\n\n // Obviously, try direct match first (`no-NB`)\n if (message[locale]) {\n return message[locale]\n }\n\n // In the case of composed languages (`en-US`, `no-NB` etc), fall back to base language (`en`)\n if (locale.includes('-')) {\n const language = locale.split('-', 1)[0]\n if (message[language]) {\n return message[language]\n }\n }\n\n // Try english as last resort\n return (\n message['en-US'] || message['en-GB'] || message.en || 'Unknown validation error (not localized)'\n )\n}\n\n/**\n * Check if passed message/result is a localized message object\n *\n * @param message - Message to check\n * @returns True if message is a localized message object, false otherwise\n * @internal\n */\nexport function isLocalizedMessages(\n message: CustomValidatorResult | undefined,\n): message is LocalizedValidationMessages {\n return (\n message !== true &&\n typeof message !== 'undefined' &&\n typeof message !== 'string' &&\n isPlainObject(message) &&\n !('message' in message)\n )\n}\n","/**\n * Modified version of fast-deep-equal (https://github.com/epoberezkin/fast-deep-equal)\n * MIT-licensed, copyright (c) 2017 Evgeny Poberezkin\n **/\n\n// NOTE: when converting to typescript, some of the checks were inlined (vs\n// having them in a variable) because the type predicate type narrowing only\n// works when type predicate is called inline in the condition that starts the\n// control flow branch.\n// see here: https://www.typescriptlang.org/docs/handbook/2/narrowing.html\nexport function deepEqualsIgnoreKey(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!deepEqualsIgnoreKey(a[i], b[i])) {\n return false\n }\n }\n return true\n }\n\n if (Array.isArray(a) != Array.isArray(b)) {\n return false\n }\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n const keys = Object.keys(a)\n if (keys.length !== Object.keys(b).length) {\n return false\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n if (a instanceof Date != b instanceof Date) {\n return false\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() == b.toString()\n }\n\n if (a instanceof RegExp != b instanceof RegExp) {\n return false\n }\n\n for (let i = 0; i < keys.length; i++) {\n if (keys[i] === '_key') {\n continue\n }\n\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {\n return false\n }\n }\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i] as keyof typeof a\n if (key === '_key') {\n continue\n }\n\n if (!deepEqualsIgnoreKey(a[key], b[key])) {\n return false\n }\n }\n\n return true\n }\n\n return false\n}\n","// this file was adapted from a previous dependency `type-of-is`\n// https://github.com/stephenhandley/type-of-is/blob/7138a7e79f5af7c286bf8123f60843a91aaebf38/index.js\nconst _toString = {}.toString\n\nconst builtIns = [Object, Function, Array, String, Boolean, Number, Date, RegExp, Error]\n\nfunction isBuiltIn(_constructor: unknown) {\n for (let i = 0; i < builtIns.length; i++) {\n if (builtIns[i] === _constructor) return true\n }\n return false\n}\n\nexport function typeString(obj: unknown): string {\n // [object Blah] -> Blah\n const stringType = _toString.call(obj).slice(8, -1)\n if (obj === null || obj === undefined) return stringType.toLowerCase()\n\n const constructorType = (obj as object).constructor\n if (constructorType && !isBuiltIn(constructorType)) return constructorType.name\n return stringType\n}\n","/* oxlint-disable typescript/no-deprecated -- marker compatibility requires the legacy item field */\nimport {type ValidationMarker, type Validators} from '@sanity/types'\n\nimport {type LocaleSource} from '../i18n/types'\nimport {deepEqualsIgnoreKey} from '../util/deepEqualsIgnoreKey'\nimport {isLocalizedMessages, localizeMessage} from '../util/localizeMessage'\nimport {pathToString} from '../util/pathToString'\nimport {typeString} from '../util/typeString'\n\nexport const SLOW_VALIDATOR_TIMEOUT = 5000\n\nconst formatValidationErrors = (options: {\n message: string | undefined\n results: ValidationMarker[]\n operation: 'conjunction' | 'disjunction'\n i18n: LocaleSource\n}) => {\n if (options.message) return options.message\n if (options.results.length === 1) return options.results[0]?.message\n\n // Intentionally hard-coded to use locale conjunction/disjunctions\n return options.i18n.t('{{messages, list}}', {\n messages: options.results.map((err) => err.message || err.item?.message),\n formatParams: {messages: {style: 'long', type: options.operation}},\n })\n}\n\nexport const genericValidators: Validators = {\n type: (expectedType, value, message, {i18n}) => {\n const actualType = typeString(value)\n if (actualType !== expectedType && actualType !== 'undefined') {\n return message || i18n.t('validation:generic.incorrect-type', {actualType, expectedType})\n }\n\n return true\n },\n\n presence: (expected, value, message, {i18n}) => {\n if (value === undefined && expected === 'required') {\n return message || i18n.t('validation:generic.required')\n }\n\n return true\n },\n\n all: async (children, value, message, context) => {\n const resolved = await Promise.all(children.map((child) => child.validate(value, context)))\n const results = resolved.flat()\n\n if (results.length === 0) {\n return true\n }\n\n return formatValidationErrors({\n message,\n results,\n operation: 'conjunction',\n i18n: context.i18n,\n })\n },\n\n either: async (children, value, message, context) => {\n const resolved = await Promise.all(children.map((child) => child.validate(value, context)))\n const results = resolved.flat()\n\n // if one of the results is an empty array then at least one rule match\n if (resolved.find((result) => !result.length)) {\n return true\n }\n\n return formatValidationErrors({\n message,\n results,\n operation: 'disjunction',\n i18n: context.i18n,\n })\n },\n\n valid: (allowedValues, actual, message, {i18n}) => {\n const valueType = typeof actual\n if (valueType === 'undefined') {\n return true\n }\n\n const value = (valueType === 'number' || valueType === 'string') && `${actual}`\n const strValue = value && value.length > 30 ? `${value.slice(0, 30)}…` : value\n\n return allowedValues.some((expected) => deepEqualsIgnoreKey(expected, actual))\n ? true\n : message ||\n i18n.t(\n 'validation:generic.not-allowed',\n value ? {context: 'hint', replace: {hint: strValue}} : {},\n )\n },\n\n custom: async (fn, value, message, context) => {\n const slowTimer = setTimeout(() => {\n // only show this warning in the studio\n if (context.environment !== 'studio') return\n\n console.warn(\n `Custom validator at ${pathToString(\n context.path,\n )} has taken more than ${SLOW_VALIDATOR_TIMEOUT}ms to respond`,\n )\n }, SLOW_VALIDATOR_TIMEOUT)\n\n let result\n try {\n result = await fn(value, context)\n } finally {\n clearTimeout(slowTimer)\n }\n\n if (isLocalizedMessages(result)) {\n return localizeMessage(result, context.i18n)\n }\n\n if (typeof result === 'string') {\n return message || result\n }\n\n return result\n },\n}\n","import {\n isArrayOfBlocksSchemaType,\n type Path,\n type PathSegment,\n type Validators,\n} from '@sanity/types'\n\nimport {deepEqualsIgnoreKey} from '../util/deepEqualsIgnoreKey'\nimport {genericValidators} from './genericValidator'\n\nexport const arrayValidators: Validators = {\n ...genericValidators,\n\n min: (minLength, value, message, {i18n, type}) => {\n if (!value || value.length >= minLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.minimum-length', {minLength, context})\n },\n\n max: (maxLength, value, message, {i18n, type}) => {\n if (!value || value.length <= maxLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.maximum-length', {maxLength, context})\n },\n\n length: (wantedLength, value, message, {i18n, type}) => {\n if (!value || value.length === wantedLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.exact-length', {wantedLength, context})\n },\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && !value) {\n return message || i18n.t('validation:generic.required', {context: 'array'})\n }\n\n return true\n },\n\n valid: (allowedValues, values, message, {i18n}) => {\n const valueType = typeof values\n if (valueType === 'undefined') {\n return true\n }\n\n const paths: Path[] = []\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (allowedValues.some((expected) => deepEqualsIgnoreKey(expected, value))) {\n continue\n }\n\n const pathSegment: PathSegment = value && value._key ? {_key: value._key} : i\n paths.push([pathSegment])\n }\n\n // we emit the same message for each path we find in this array\n const sharedMessage = message || i18n.t('validation:generic.not-allowed')\n\n return paths.map((path) => ({message: sharedMessage, path}))\n },\n\n unique: (_unused, value, message, {i18n}) => {\n const dupeIndices = []\n if (!value) {\n return true\n }\n\n for (let x = 0; x < value.length; x++) {\n for (let y = x + 1; y < value.length; y++) {\n const itemA = value[x]\n const itemB = value[y]\n\n if (!deepEqualsIgnoreKey(itemA, itemB)) {\n continue\n }\n\n if (dupeIndices.indexOf(x) === -1) {\n dupeIndices.push(x)\n }\n\n if (dupeIndices.indexOf(y) === -1) {\n dupeIndices.push(y)\n }\n }\n }\n\n const paths = dupeIndices.map((idx) => {\n const item = value[idx]\n const pathSegment = item && item._key ? {_key: item._key} : idx\n return [pathSegment]\n })\n\n // we emit the same message for each path we find in this array\n const sharedMessage = message || i18n.t('validation:array.item-duplicate')\n\n return paths.map((path) => ({message: sharedMessage, path}))\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nexport const booleanValidators: Validators = {\n ...genericValidators,\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && typeof value !== 'boolean') {\n return message || i18n.t('validation:generic.required', {context: 'boolean'})\n }\n\n return true\n },\n}\n","import {type Validators} from '@sanity/types'\nimport * as legacyDateFormat from '@sanity/util/legacyDateFormat'\n\nimport {genericValidators} from './genericValidator'\n\nfunction isRecord(obj: unknown): obj is Record<string, unknown> {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj)\n}\n\nconst isoDate =\n /^(?:[-+]\\d{2})?(?:\\d{4}(?!\\d{2}\\b))(?:(-?)(?:(?:0[1-9]|1[0-2])(?:\\1(?:[12]\\d|0[1-9]|3[01]))?|W(?:[0-4]\\d|5[0-2])(?:-?[1-7])?|(?:00[1-9]|0[1-9]\\d|[12]\\d{2}|3(?:[0-5]\\d|6[1-6])))(?![T]$|[T][\\d]+Z$)(?:[T\\s](?:(?:(?:[01]\\d|2[0-3])(?:(:?)[0-5]\\d)?|24:?00)(?:[.,]\\d+(?!:))?)(?:\\2[0-5]\\d(?:[.,]\\d+)?)?(?:[Z]|(?:[+-])(?:[01]\\d|2[0-3])(?::?[0-5]\\d)?)?)?)?$/\n\n// TODO (eventually): move these to schema type package\ninterface DateTimeOptions {\n // @todo accept object representing `Intl.DateTimeFormatOptions`? how do we localize?\n dateFormat?: string\n timeFormat?: string\n}\n\nconst getFormattedDate = (type = '', value: Date, options?: DateTimeOptions) => {\n const dateFormat = options?.dateFormat || legacyDateFormat.DEFAULT_DATE_FORMAT\n const timeFormat = options?.timeFormat || legacyDateFormat.DEFAULT_TIME_FORMAT\n\n // adding the time information in the date only case causes timezone information to be kept\n // instead of it being assumed to be UTC. This was a problem because midnight UTC is the previous\n // day in many other timezones resulting in the date displayed to be the previous day.\n return legacyDateFormat.format(\n value,\n type === 'date' ? dateFormat : `${dateFormat} ${timeFormat}`,\n {useUTC: type === 'date'},\n )\n}\n\nfunction parseDate(date: unknown): Date | null\nfunction parseDate(date: unknown, throwOnError: true): Date\nfunction parseDate(date: unknown, throwOnError = false): Date | null {\n if (!date) return null\n if (date === 'now') return new Date()\n\n // oxlint-disable-next-line no-explicit-any\n const parsed = new Date(date as any)\n const isInvalid = isNaN(parsed.getTime())\n if (isInvalid && throwOnError) {\n throw new Error(`Unable to parse \"${date}\" to a date`)\n }\n\n return isInvalid ? null : parsed\n}\n\nexport const dateValidators: Validators = {\n ...genericValidators,\n\n type: (_unused, value, message, {i18n}) => {\n if (typeof value === 'undefined' || isoDate.test(`${value}`)) {\n return true\n }\n\n return message || i18n.t('validation:date.invalid-format')\n },\n\n min: (minDate, value, message, {type, i18n}) => {\n const dateVal = parseDate(value)\n const minDateVal = parseDate(minDate, true)\n\n if (!dateVal) {\n return true // `type()` should catch parse errors\n }\n\n if (!value || dateVal >= minDateVal) {\n return true\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context.`)\n }\n\n const dateTimeOptions: DateTimeOptions = isRecord(type.options)\n ? (type.options as DateTimeOptions)\n : {}\n\n return (\n message ||\n // Note that the `minDate` passed here is _formatted_, while the raw value provided to the\n // validator is available as `providedMinDate`. This because the formatted date is likely\n // what the developer wants to present to the user\n i18n.t('validation:date.minimum', {\n minDate: getFormattedDate(type.name, minDateVal, dateTimeOptions),\n providedMinDate: minDate,\n })\n )\n },\n\n max: (maxDate, value, message, {type, i18n}) => {\n const dateVal = parseDate(value)\n const maxDateVal = parseDate(maxDate, true)\n\n if (!dateVal) {\n return true // `type()` should catch parse errors\n }\n\n if (!value || dateVal <= maxDateVal) {\n return true\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context.`)\n }\n\n const dateTimeOptions: DateTimeOptions = isRecord(type.options)\n ? (type.options as DateTimeOptions)\n : {}\n\n return (\n message ||\n // Note that the `maxDate` passed here is _formatted_, while the raw value provided to the\n // validator is available as `providedMaxDate`. This because the formatted date is likely\n // what the developer wants to present to the user\n i18n.t('validation:date.maximum', {\n maxDate: getFormattedDate(type.name, maxDateVal, dateTimeOptions),\n providedMaxDate: maxDate,\n })\n )\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nconst precisionRx = /(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/\n\nexport const numberValidators: Validators = {\n ...genericValidators,\n\n integer: (_unused, value, message, {i18n}) => {\n if (!Number.isInteger(value)) {\n return message || i18n.t('validation:number.non-integer')\n }\n\n return true\n },\n\n precision: (limit, value, message, {i18n}) => {\n if (value === undefined) return true\n\n const places = value.toString().match(precisionRx)\n const decimals = Math.max(\n (places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0),\n 0,\n )\n\n if (decimals > limit) {\n return message || i18n.t('validation:number.maximum-precision', {limit})\n }\n\n return true\n },\n\n min: (minNumber, value, message, {i18n}) => {\n if (value >= minNumber) {\n return true\n }\n\n return message || i18n.t('validation:number.minimum', {minNumber})\n },\n\n max: (maxNumber, value, message, {i18n}) => {\n if (value <= maxNumber) {\n return true\n }\n\n return message || i18n.t('validation:number.maximum', {maxNumber})\n },\n\n greaterThan: (threshold, value, message, {i18n}) => {\n if (value > threshold) {\n return true\n }\n\n return message || i18n.t('validation:number.greater-than', {threshold})\n },\n\n lessThan: (threshold, value, message, {i18n}) => {\n if (value < threshold) {\n return true\n }\n\n return message || i18n.t('validation:number.less-than', {threshold})\n },\n}\n","import {type DocumentId, getPublishedId} from '@sanity/id-utils'\nimport {type CustomValidatorResult, isReference, type Validators} from '@sanity/types'\n\nimport {isLocalizedMessages, localizeMessage} from '../util/localizeMessage'\nimport {pathToString} from '../util/pathToString'\nimport {genericValidators, SLOW_VALIDATOR_TIMEOUT} from './genericValidator'\n\nconst metaKeys = ['_key', '_type', '_weak']\n\ninterface MediaLibraryAsset {\n currentVersion: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport const objectValidators: Validators = {\n ...genericValidators,\n\n presence: (expected, value, message, {i18n}) => {\n if (expected !== 'required') {\n return true\n }\n\n const keys = value && Object.keys(value).filter((key) => !metaKeys.includes(key))\n\n if (value === undefined || (keys && keys.length === 0)) {\n return message || i18n.t('validation:generic.required', {context: 'object'})\n }\n\n return true\n },\n\n reference: async (_unused, value: unknown, message, context) => {\n if (!value) {\n return true\n }\n\n const {type, document, getDocumentExists, i18n} = context\n\n if (!isReference(value)) {\n return message || i18n.t('validation:object.not-reference')\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context`)\n }\n\n if ('weak' in type && type.weak) {\n return true\n }\n\n if (!getDocumentExists) {\n throw new Error(`\\`getDocumentExists\\` was not provided in validation context`)\n }\n\n const documentId = document?._id\n if (documentId && value._ref == getPublishedId(documentId as DocumentId)) {\n // a document should be able to reference itself without first being published\n return true\n }\n const exists = await getDocumentExists({id: value._ref})\n if (!exists) {\n return i18n.t('validation:object.reference-not-published', {documentId: value._ref})\n }\n\n return true\n },\n\n assetRequired: (flag, value, message, {i18n}) => {\n if (!value || !value.asset || !value.asset._ref) {\n return {\n __internal_metadata: {\n name: 'assetRequired',\n },\n message:\n message || i18n.t('validation:object.asset-required', {context: flag.assetType || ''}),\n }\n }\n\n return true\n },\n\n media: async (fn, value, message, context) => {\n const slowTimer = setTimeout(() => {\n // only show this warning in the studio\n if (context.environment !== 'studio') return\n\n console.warn(\n `Media validator at ${pathToString(\n context.path,\n )} has taken more than ${SLOW_VALIDATOR_TIMEOUT}ms to respond`,\n )\n }, SLOW_VALIDATOR_TIMEOUT)\n\n // If no value is provided, we assume the validation passes. This should be handled by the 'isRequired' validator.\n if (!value) {\n return true\n }\n\n // If the value is not an object or does not have a media reference, we return an error message.\n // It should not be allowed to use regular dataset assets with this validator.\n if (!value || !value.media || !value.media._ref) {\n return context.i18n.t('validation:object.not-media-library-asset')\n }\n\n let result: CustomValidatorResult = true\n\n try {\n const [type, libraryId, documentId] = value.media._ref.split(':', 3)\n // TODO: replace this with stable resource config when available\n const resourceConfig = {resource: {type, id: libraryId}}\n const asset = await context\n .getClient({apiVersion: '2025-02-19'})\n .withConfig(resourceConfig)\n .fetch<MediaLibraryAsset | null>(\n `*[_id == $id] { ..., 'currentVersion': @.currentVersion-> { ... } }[0]`,\n {\n id: documentId,\n },\n )\n if (!asset) {\n console.warn(\n `${context.i18n.t('validation:object.media-not-found')}\\nAsset ID: ${value.media._ref}`,\n )\n return context.i18n.t('validation:object.media-not-found')\n }\n\n result = await fn(\n {\n media: {\n asset: asset as unknown as Parameters<typeof fn>[0]['media']['asset'],\n },\n value,\n },\n context,\n )\n } catch (err) {\n const error = new Error(\n `Media validator at ${pathToString(\n context.path,\n )} failed with an error: ${err instanceof Error ? err.message : String(err)}`,\n {cause: err},\n )\n throw error\n } finally {\n clearTimeout(slowTimer)\n }\n\n const validationErrorMetadata = {\n __internal_metadata: {\n name: 'media',\n },\n }\n\n // Valid, no errors\n if (result === true) {\n return result\n }\n\n // Ensure we always return ValidationMarker with metadata\n return Array.isArray(result)\n ? result\n : [result].map((res) => {\n if (typeof res === 'string') {\n return {...validationErrorMetadata, message: message || res}\n }\n if (isLocalizedMessages(res)) {\n return {\n ...validationErrorMetadata,\n message: message || localizeMessage(res, context.i18n),\n }\n }\n return {...validationErrorMetadata, ...res, message: message || res.message}\n })\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nconst DUMMY_ORIGIN = 'http://sanity'\nconst isRelativeUrl = (url: string) => /^\\.*\\//.test(url)\nconst emailRegex =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n\nexport const stringValidators: Validators = {\n ...genericValidators,\n\n min: (minLength, value, message, {i18n}) => {\n if (!value || value.length >= minLength) {\n return true\n }\n\n return message || i18n.t('validation:string.minimum-length', {minLength})\n },\n\n max: (maxLength, value, message, {i18n}) => {\n if (!value || value.length <= maxLength) {\n return true\n }\n\n return message || i18n.t('validation:string.maximum-length', {maxLength})\n },\n\n length: (wantedLength, value, message, {i18n}) => {\n const strValue = value || ''\n if (strValue.length === wantedLength) {\n return true\n }\n\n return message || i18n.t('validation:string.exact-length', {wantedLength})\n },\n\n uri: (constraints, value, message, {i18n}) => {\n const strValue = value || ''\n if (!strValue) {\n return true // `presence()` should catch empty values\n }\n\n const {options} = constraints\n const {allowCredentials, relativeOnly} = options\n const allowRelative = options.allowRelative || relativeOnly\n\n let url\n try {\n // WARNING: Safari checks for a given `base` param by looking at the length of arguments passed\n // to new URL(str, base), and will fail if invoked with new URL(strValue, undefined)\n url = allowRelative ? new URL(strValue, DUMMY_ORIGIN) : new URL(strValue)\n } catch {\n return message || i18n.t('validation:string.url.invalid')\n }\n\n if (relativeOnly && url.origin !== DUMMY_ORIGIN) {\n return message || i18n.t('validation:string.url.not-relative')\n }\n\n if (!allowRelative && url.origin === DUMMY_ORIGIN && isRelativeUrl(strValue)) {\n return message || i18n.t('validation:string.url.not-absolute')\n }\n\n if (!allowCredentials && (url.username || url.password)) {\n return message || i18n.t('validation:string.url.includes-credentials')\n }\n\n const urlScheme = url.protocol.replace(/:$/, '')\n const isRelative = isRelativeUrl(strValue)\n const matchesAllowedScheme =\n isRelative || options.scheme.some((scheme) => scheme.test(urlScheme))\n if (!matchesAllowedScheme) {\n return message || i18n.t('validation:string.url.disallowed-scheme', {scheme: urlScheme})\n }\n\n return true\n },\n\n stringCasing: (casing, value, message, {i18n}) => {\n const strValue = value || ''\n if (casing === 'uppercase' && strValue !== strValue.toLocaleUpperCase()) {\n return message || i18n.t('validation:string.uppercase')\n }\n\n if (casing === 'lowercase' && strValue !== strValue.toLocaleLowerCase()) {\n return message || i18n.t('validation:string.lowercase')\n }\n\n return true\n },\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && !value) {\n return message || i18n.t('validation:generic.required', {context: 'string'})\n }\n\n return true\n },\n\n regex: (options, value, message, {i18n}) => {\n const {pattern, name, invert} = options\n const regName = name || `${pattern.toString()}`\n const strValue = value || ''\n // Regexes with global or sticky flags are stateful (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex).\n // This resets the state stored from the previous check\n pattern.lastIndex = 0\n const matches = pattern.test(strValue)\n if ((!invert && !matches) || (invert && matches)) {\n if (message) {\n return message\n }\n\n return invert\n ? i18n.t('validation:string.regex-match', {name: regName})\n : i18n.t('validation:string.regex-does-not-match', {name: regName})\n }\n\n return true\n },\n\n email: (_unused, value, message, {i18n}) => {\n const strValue = `${value || ''}`.trim()\n if (!strValue || emailRegex.test(strValue)) {\n return true\n }\n\n return message || i18n.t('validation:string.email')\n },\n}\n","/* oxlint-disable typescript/no-deprecated -- this is the concrete implementation of the legacy Rule internals */\nimport {Rule as BaseRule} from '@sanity/schema'\nimport {\n type CustomValidator,\n type Rule as IRule,\n type RuleClass,\n type SchemaType,\n type ValidationMarker,\n type Validator,\n} from '@sanity/types'\nimport get from 'lodash-es/get.js'\n\nimport {convertToValidationMarker} from './util/convertToValidationMarker'\nimport {isLocalizedMessages, localizeMessage} from './util/localizeMessage'\nimport {pathToString} from './util/pathToString'\nimport {arrayValidators} from './validators/arrayValidator'\nimport {booleanValidators} from './validators/booleanValidator'\nimport {dateValidators} from './validators/dateValidator'\nimport {genericValidators} from './validators/genericValidator'\nimport {numberValidators} from './validators/numberValidator'\nimport {objectValidators} from './validators/objectValidator'\nimport {stringValidators} from './validators/stringValidator'\n\nconst typeValidators = {\n Boolean: booleanValidators,\n Number: numberValidators,\n String: stringValidators,\n Array: arrayValidators,\n Object: objectValidators,\n Date: dateValidators,\n}\n\nconst isFieldRef = (constraint: unknown): constraint is {type: symbol; path: string | string[]} => {\n if (typeof constraint !== 'object' || !constraint) return false\n return (constraint as Record<string, unknown>).type === Rule.FIELD_REF\n}\n\nconst EMPTY_ARRAY: unknown[] = []\n\n/**\n * Concrete Rule implementation with validation logic.\n * This extends the base Rule class from `@sanity/schema` and adds the validate method.\n *\n * Note: `RuleClass` and `Rule` are split to fit the current `@sanity/types`\n * setup. Classes are a bit weird in the `@sanity/types` package because classes\n * create an actual javascript class while simultaneously creating a type\n * definition.\n *\n * This implicitly creates two types:\n * 1. the instance type — `Rule` and\n * 2. the static/class type - `RuleClass`\n *\n * The `RuleClass` type contains the static methods and the `Rule` instance\n * contains the instance methods.\n *\n * This package exports the RuleClass as a value without implicitly exporting\n * an instance definition. This should help reminder downstream users to import\n * from the `@sanity/types` package.\n *\n * @internal\n */\n// export class Rule extends BaseRule implements IRule {\nexport const Rule: RuleClass = class Rule extends BaseRule implements IRule {\n static array = (def?: SchemaType): Rule => new Rule(def).type('Array')\n static object = (def?: SchemaType): Rule => new Rule(def).type('Object')\n static string = (def?: SchemaType): Rule => new Rule(def).type('String')\n static number = (def?: SchemaType): Rule => new Rule(def).type('Number')\n static boolean = (def?: SchemaType): Rule => new Rule(def).type('Boolean')\n static dateTime = (def?: SchemaType): Rule => new Rule(def).type('Date')\n\n clone(): Rule {\n const rule = new Rule()\n rule._type = this._type\n rule._message = this._message\n rule._required = this._required\n rule._rules = [...this._rules]\n rule._level = this._level\n rule._fieldRules = this._fieldRules\n rule._typeDef = this._typeDef\n return rule\n }\n\n async validate(\n value: unknown,\n {__internal = {}, ...context}: Parameters<IRule['validate']>[1],\n ): Promise<ValidationMarker[]> {\n const {customValidationConcurrencyLimiter} = __internal\n\n const valueIsEmpty = value === null || value === undefined\n\n // Short-circuit on optional, empty fields\n if (valueIsEmpty && this._required === 'optional') {\n return EMPTY_ARRAY as ValidationMarker[]\n }\n\n const rules =\n // Run only the _custom_ functions if the rule is not set to required or optional\n this._required === undefined && valueIsEmpty\n ? this._rules.filter((curr) => curr.flag === 'custom')\n : this._rules\n\n const validators = (this._type && typeValidators[this._type]) || genericValidators\n\n const results = await Promise.all(\n rules.map(async (curr) => {\n if (curr.flag === undefined) {\n throw new Error('Invalid rule, did not contain \"flag\"-property')\n }\n\n const validator: Validator | undefined = validators[curr.flag]\n if (!validator) {\n const forType = this._type ? `type \"${this._type}\"` : 'rule without declared type'\n throw new Error(`Validator for flag \"${curr.flag}\" not found for ${forType}`)\n }\n\n let specConstraint = 'constraint' in curr ? curr.constraint : null\n if (isFieldRef(specConstraint)) {\n specConstraint = get(context.parent, specConstraint.path)\n }\n\n if (\n curr.flag === 'custom' &&\n customValidationConcurrencyLimiter &&\n !(specConstraint as CustomValidator)?.bypassConcurrencyLimit\n ) {\n const customValidator = specConstraint as CustomValidator\n specConstraint = async (...args: Parameters<CustomValidator>) => {\n await customValidationConcurrencyLimiter.ready()\n try {\n return await customValidator(...args)\n } finally {\n customValidationConcurrencyLimiter.release()\n }\n }\n }\n\n const message = isLocalizedMessages(this._message)\n ? localizeMessage(this._message, context.i18n)\n : this._message\n\n try {\n const result = await validator(specConstraint, value, message, context)\n return convertToValidationMarker(result, this._level, context)\n } catch (err) {\n const errorMessage = `${pathToString(\n context.path,\n )}: Exception occurred while validating value: ${err.message}`\n\n return convertToValidationMarker({message: errorMessage}, 'error', context)\n }\n }),\n )\n\n return results.flat()\n }\n}\n","import {type DocumentId, getPublishedId} from '@sanity/id-utils'\nimport {\n type CustomValidator,\n isKeyedObject,\n isSlug,\n type Path,\n type SlugIsUniqueValidator,\n type SlugParent,\n type SlugSchemaType,\n type SlugValidationContext,\n} from '@sanity/types'\nimport memoize from 'lodash-es/memoize.js'\n\nconst DEFAULT_API_VERSION = '2025-02-19'\n\nconst memoizedWarnOnArraySlug = memoize(warnOnArraySlug)\n\nfunction serializePath(path: Path): string {\n return path.reduce<string>((target, part, i) => {\n const isIndex = typeof part === 'number'\n const isKey = isKeyedObject(part)\n const separator = i === 0 ? '' : '.'\n const add = isIndex || isKey ? '[]' : `${separator}${part}`\n return `${target}${add}`\n }, '')\n}\n\nconst defaultIsUnique: SlugIsUniqueValidator = (slug, context) => {\n const {getClient, document, path, type} = context\n const schemaOptions = type?.options\n\n if (!document) {\n throw new Error(`\\`document\\` was not provided in validation context.`)\n }\n if (!path) {\n throw new Error(`\\`path\\` was not provided in validation context.`)\n }\n\n const disableArrayWarning = schemaOptions?.disableArrayWarning || false\n const docType = document._type\n const atPath = serializePath(path.concat('current'))\n\n if (!disableArrayWarning && atPath.includes('[]') && context.environment === 'studio') {\n memoizedWarnOnArraySlug(serializePath(path))\n }\n\n const constraints = [\n '_type == $docType',\n `!sanity::versionOf($published)`,\n `${atPath} == $slug`,\n ].join(' && ')\n\n return getClient({apiVersion: DEFAULT_API_VERSION})\n .withConfig({perspective: 'raw'})\n .fetch<boolean>(\n `!defined(*[${constraints}][0]._id)`,\n {\n docType,\n published: getPublishedId(document._id as DocumentId),\n slug,\n },\n {tag: 'validation.slug-is-unique'},\n )\n}\n\nfunction warnOnArraySlug(serializedPath: string) {\n console.warn(\n [\n `Slug field at path ${serializedPath} is within an array and cannot be automatically checked for uniqueness`,\n `If you need to check for uniqueness, provide your own \"isUnique\" method`,\n `To disable this message, set \\`disableArrayWarning: true\\` on the slug \\`options\\` field`,\n ].join('\\n'),\n )\n}\n\n/**\n * Validates slugs values by querying for uniqueness from the client.\n *\n * This is a custom rule implementation (e.g. `Rule.custom(slugValidator)`)\n * that's populated in `inferFromSchemaType` when the type name is `slug`\n */\nexport const slugValidator: CustomValidator = async (value, context) => {\n if (!value) {\n return true\n }\n\n const {i18n} = context\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n return i18n.t('validation:slug.not-object')\n }\n\n if (!isSlug(value) || value.current.trim().length === 0) {\n return i18n.t('validation:slug.missing-current')\n }\n\n const options = context?.type?.options as {isUnique?: SlugIsUniqueValidator} | undefined\n const isUnique = options?.isUnique || defaultIsUnique\n\n const slugContext: SlugValidationContext = {\n ...context,\n parent: context.parent as SlugParent,\n type: context.type as SlugSchemaType,\n defaultIsUnique,\n }\n\n const wasUnique = await isUnique(value.current, slugContext)\n if (wasUnique) {\n return true\n }\n\n return i18n.t('validation:slug.not-unique', {slug: value.current})\n}\n","import {\n type Rule,\n type RuleSpec,\n type RuleTypeConstraint,\n type SchemaType,\n type ValidationContext,\n} from '@sanity/types'\nimport isEqual from 'lodash-es/isEqual.js'\n\nimport {Rule as RuleClass} from '../Rule'\nimport {slugValidator} from '../validators/slugValidator'\n\nconst ruleConstraintTypes: {[P in Lowercase<RuleTypeConstraint>]: true} = {\n array: true,\n boolean: true,\n date: true,\n number: true,\n object: true,\n string: true,\n}\n\nconst isRuleConstraint = (typeString: string): typeString is Lowercase<RuleTypeConstraint> =>\n typeString in ruleConstraintTypes\n\nexport function getTypeChain(\n type: SchemaType | undefined,\n visited: Set<SchemaType> = new Set(),\n): SchemaType[] {\n if (!type) return []\n if (visited.has(type)) return []\n\n visited.add(type)\n\n const next = type.type ? getTypeChain(type.type, visited) : []\n return [...next, type]\n}\n\nfunction baseRuleReducer(inputRule: Rule, type: SchemaType) {\n let baseRule = inputRule\n\n if (isRuleConstraint(type.jsonType)) {\n baseRule = baseRule.type(type.jsonType)\n }\n\n const typeOptionsList =\n // if type.options is truthy\n type?.options &&\n // and type.options is an object (non-null from the previous)\n typeof type.options === 'object' &&\n // and if `list` is in options\n 'list' in type.options &&\n // then finally access the list\n type.options.list\n\n if (Array.isArray(typeOptionsList)) {\n baseRule = baseRule.valid(\n typeOptionsList.map((option) => extractValueFromListOption(option, type)),\n )\n }\n\n if (type.name === 'datetime') return baseRule.type('Date')\n if (type.name === 'date') return baseRule.type('Date')\n if (type.name === 'url') return baseRule.uri()\n if (type.name === 'slug') return baseRule.custom(slugValidator, {bypassConcurrencyLimit: true})\n if (type.name === 'reference') return baseRule.reference()\n if (type.name === 'email') return baseRule.email()\n return baseRule\n}\n\nfunction hasValueField(typeDef: SchemaType | undefined): boolean {\n if (!typeDef) return false\n if (!('fields' in typeDef) && typeDef.type) return hasValueField(typeDef.type)\n if (!('fields' in typeDef)) return false\n if (!Array.isArray(typeDef.fields)) return false\n return typeDef.fields.some((field) => field.name === 'value')\n}\n\nfunction extractValueFromListOption(option: unknown, typeDef: SchemaType): unknown {\n // If you define a `list` option with object items, where the item has a `value` field,\n // we don't want to treat that as the value but rather the surrounding object\n // This differs from the case where you have a title/value pair setup for a string/number, for instance\n if (typeDef.jsonType === 'object' && hasValueField(typeDef)) return option\n\n return (option as Record<string, unknown>).value === undefined\n ? option\n : (option as Record<string, unknown>).value\n}\n\nconst isUriSpec = (spec: RuleSpec): spec is Extract<RuleSpec, {flag: 'uri'}> => spec.flag === 'uri'\n\n// A `url` type auto-injects the default `.uri()` onto every array element, so a\n// custom scheme on one element cannot override the default on its siblings (GH #3298).\nfunction omitLeakedDefaultUri(rules: Rule[], typeDef: SchemaType): Rule[] {\n const isUrlType = getTypeChain(typeDef).some((type) => type.name === 'url')\n if (!isUrlType) return rules\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const defaultUri = new RuleClass(typeDef).uri()._rules.find(isUriSpec)?.constraint\n const isDefaultUri = (spec: RuleSpec) => isUriSpec(spec) && isEqual(spec.constraint, defaultUri)\n const isCustomUri = (spec: RuleSpec) => isUriSpec(spec) && !isEqual(spec.constraint, defaultUri)\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const someElementSetsScheme = rules.some((rule) => rule._rules.some(isCustomUri))\n if (!someElementSetsScheme) return rules\n\n return rules.map((rule) => {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n if (!rule._rules.some(isDefaultUri)) return rule\n const cleaned = rule.clone()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n cleaned._rules = rule._rules.filter((spec) => !isDefaultUri(spec))\n return cleaned\n })\n}\n\nexport function normalizeValidationRules(\n typeDef: SchemaType | undefined,\n context?: ValidationContext,\n): Rule[] {\n if (!typeDef) {\n return []\n }\n\n const validation = typeDef.validation\n\n if (Array.isArray(validation)) {\n const rules = validation.flatMap((i) =>\n normalizeValidationRules(\n {\n ...typeDef,\n validation: i,\n },\n context,\n ),\n )\n return omitLeakedDefaultUri(rules, typeDef)\n }\n\n const baseRule =\n // using an object + Object.values to de-dupe the type chain by type name\n Object.values(\n getTypeChain(typeDef).reduce<Record<string, SchemaType>>((acc, type) => {\n acc[type.name] = type\n return acc\n }, {}),\n ).reduce(baseRuleReducer, new RuleClass(typeDef))\n\n if (validation && typeof validation === 'object') {\n return [validation]\n }\n\n if (!validation) {\n return [baseRule]\n }\n\n if (typeof validation === 'function') {\n return normalizeValidationRules(\n {\n ...typeDef,\n validation: validation(baseRule, context),\n },\n context,\n )\n }\n\n return [baseRule]\n}\n","/**\n * Simple requestIdleCallback polyfill\n * Can be removed when all browsers support requestIdleCallback: https://caniuse.com/requestidlecallback\n * @param callback -\n * @param options -\n */\nconst requestIdleCallbackShim: typeof window.requestIdleCallback = function requestIdleCallbackShim(\n callback,\n _options?,\n): number {\n const start = Date.now()\n return globalThis.setTimeout(() => {\n callback({\n didTimeout: false,\n timeRemaining() {\n return Math.max(0, Date.now() - start)\n },\n })\n }, 0) as unknown as number\n}\n\nconst cancelIdleCallbackShim: typeof window.cancelIdleCallback = function cancelIdleCallbackShim(\n handle: number,\n): void {\n return globalThis.clearTimeout(handle)\n}\n\nconst win = typeof window === 'undefined' ? undefined : window\n\nexport const requestIdleCallback = win?.requestIdleCallback || requestIdleCallbackShim\nexport const cancelIdleCallback = win?.cancelIdleCallback || cancelIdleCallbackShim\n","import {type CustomValidator, type ObjectSchemaType} from '@sanity/types'\n\n/**\n * Given a schema type, returns a custom validator used to warn users of unknown\n * fields found in an object.\n */\nexport const unknownFieldsValidator =\n (type: ObjectSchemaType): CustomValidator =>\n (value) => {\n if (typeof value !== 'object') return true\n if (!value) return true\n\n const fieldNames = new Set(type.fields?.map((field) => field.name))\n\n const unknownFields = Object.keys(value)\n .filter((key) => !key.startsWith('_'))\n .filter((key) => !fieldNames.has(key))\n\n return unknownFields.map((unknownField) => ({\n message: `Field '${unknownField}' does not exist on type '${type.name}'`,\n path: [unknownField],\n }))\n }\n","/* oxlint-disable typescript/no-deprecated -- marker and Rule compatibility require legacy internals */\nimport {type SanityClient} from '@sanity/client'\nimport {\n isKeyedObject,\n isTypedObject,\n type CurrentUser,\n type Rule,\n type SanityDocument,\n type Schema,\n type SchemaType,\n type ValidationMarker,\n} from '@sanity/types'\nimport {createClientConcurrencyLimiter} from '@sanity/util/client'\nimport {ConcurrencyLimiter} from '@sanity/util/concurrency-limiter'\nimport flatten from 'lodash-es/flatten.js'\nimport uniqBy from 'lodash-es/uniqBy.js'\nimport {concat, defer, from, lastValueFrom, merge, Observable, of} from 'rxjs'\nimport {catchError, map, mergeAll, mergeMap, switchMap, toArray} from 'rxjs/operators'\n\nimport {getFallbackLocaleSource} from './i18n/fallback'\nimport {type LocaleSource} from './i18n/types'\nimport {resolveConditionalProperty} from './resolveConditionalProperty'\nimport {type ValidationContext} from './types'\nimport {createBatchedGetDocumentExists} from './util/createBatchedGetDocumentExists'\nimport {getTypeChain, normalizeValidationRules} from './util/normalizeValidationRules'\nimport {cancelIdleCallback, requestIdleCallback} from './util/requestIdleCallback'\nimport {typeString} from './util/typeString'\nimport {unknownFieldsValidator} from './validators/unknownFieldsValidator'\n\n// this is the number of requests allowed inflight at once. this is done to prevent\n// the validation library from overwhelming our backend.\n// NOTE: this was upped from 10 to prevent issues where many concurrency\n// `client.fetch` requests would \"clog\" custom validators from finishing due to\n// not enough concurrent requests being fulfilled\n//\n// NOTE: ensure to update the TSDoc and CLI help test if this is changed\nconst DEFAULT_MAX_FETCH_CONCURRENCY = 25\n\n// NOTE: ensure to update the TSDoc and CLI help test if this is changed\nconst DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY = 5\n\nconst DEFAULT_VALIDATION_CLIENT_OPTIONS = {apiVersion: '2025-02-19'} as const\n\nconst isRecord = (maybeRecord: unknown): maybeRecord is Record<string, unknown> =>\n typeof maybeRecord === 'object' && maybeRecord !== null && !Array.isArray(maybeRecord)\n\n/**\n * Recursively extracts all `_fieldRules` from a rule and its nested constraints.\n * This handles cases where `Rule.fields()` is used inside `Rule.all()` or `Rule.either()`.\n */\nfunction extractFieldRulesFromRule(rule: Rule): NonNullable<Rule['_fieldRules']>[] {\n const results: NonNullable<Rule['_fieldRules']>[] = []\n\n // Add direct _fieldRules if present\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n if (rule._fieldRules) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n results.push(rule._fieldRules)\n }\n\n // Check for nested rules in 'all' or 'either' constraints\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n for (const ruleSpec of rule._rules) {\n if (ruleSpec.flag === 'all' || ruleSpec.flag === 'either') {\n const childRules = ruleSpec.constraint\n if (Array.isArray(childRules)) {\n for (const childRule of childRules) {\n results.push(...extractFieldRulesFromRule(childRule))\n }\n }\n }\n }\n\n return results\n}\n\n/**\n * @internal\n */\nexport function resolveTypeForArrayItem(\n item: unknown,\n candidates: SchemaType[],\n): SchemaType | undefined {\n // if there is only one type available, assume that it's the correct one\n if (candidates.length === 1) return candidates[0]\n\n const itemType = isTypedObject(item) && item._type\n const primitive =\n item === undefined || item === null || (!itemType && typeString(item).toLowerCase())\n\n if (primitive && primitive !== 'object') {\n return candidates.find((candidate) => candidate.jsonType === primitive)\n }\n\n return (\n candidates.find((candidate) => candidate.type?.name === itemType) ||\n candidates.find((candidate) => candidate.name === itemType) ||\n candidates.find((candidate) => candidate.name === 'object' && primitive === 'object')\n )\n}\n\n/**\n * @beta\n */\nexport interface ValidateDocumentOptions {\n /**\n * The document to be validated\n */\n document: SanityDocument\n /** The compiled schema to validate against. */\n schema: Schema\n\n /** A configured client used for reference checks and custom validators. */\n client: SanityClient\n\n /**\n * Function used to check if referenced documents exists (and is published).\n *\n * If you're validating many documents in bulk, you may want to query for all\n * document IDs first and provide your own implementation using those.\n *\n * If no function is provided a default one will be provided that will batch\n * call the `doc` endpoint to check for document existence.\n */\n getDocumentExists?: (options: {id: string}) => Promise<boolean>\n\n /**\n * The maximum amount of custom validation functions to be running\n * concurrently at once. This helps prevent custom validators from\n * overwhelming backend services (e.g. called via fetch) used in async,\n * user-defined validation functions. (i.e. `rule.custom(async() => {})`)\n *\n * Note that lowering this number may also help in cases where a custom\n * validator could potentially exhaust the fetch concurrency. This is 5 by\n * default.\n */\n maxCustomValidationConcurrency?: number\n\n /**\n * The amount of allowed inflight fetch requests at once for this validation.\n * You may need to up this value if you have complex custom validations that\n * require many `client.fetch` requests at once. It's possible for a custom\n * validator to stall if there are not enough concurrent fetch requests\n * available to fulfill the custom validation. Must be a positive integer.\n * This is 25 by default.\n */\n maxFetchConcurrency?: number\n\n /**\n * The current user, when available. Used when resolving schema `hidden`\n * conditionals so validation matches what the form shows. If omitted, hidden\n * is resolved with no user (e.g. CLI or headless validation).\n */\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/**\n * Validates a document against a compiled schema. Returns validation markers\n * without deciding whether the document may be edited or published.\n *\n * @beta\n */\nexport function validateDocument({\n client,\n document,\n schema,\n ...options\n}: ValidateDocumentOptions): Promise<ValidationMarker[]> {\n return validateDocumentInternal({\n ...options,\n document,\n environment: 'cli',\n getClient: ({apiVersion}) => client.withConfig({apiVersion}),\n i18n: getFallbackLocaleSource(),\n schema,\n })\n}\n\n/** @internal */\nexport interface ValidateDocumentInternalOptions {\n document: SanityDocument\n schema: Schema\n getClient: (clientOptions: {apiVersion: string}) => SanityClient\n getDocumentExists?: (options: {id: string}) => Promise<boolean>\n i18n?: LocaleSource\n environment: 'cli' | 'studio'\n maxCustomValidationConcurrency?: number\n maxFetchConcurrency?: number\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/** @internal */\nexport function validateDocumentInternal({\n document,\n schema,\n getClient,\n getDocumentExists,\n i18n = getFallbackLocaleSource(),\n environment,\n maxCustomValidationConcurrency,\n maxFetchConcurrency,\n currentUser,\n}: ValidateDocumentInternalOptions): Promise<ValidationMarker[]> {\n const limitConcurrency = createClientConcurrencyLimiter(\n maxFetchConcurrency ?? DEFAULT_MAX_FETCH_CONCURRENCY,\n )\n const getConcurrencyLimitedClient = (clientOptions: {apiVersion: string}) =>\n limitConcurrency(getClient(clientOptions))\n\n return lastValueFrom(\n validateDocumentObservable({\n document,\n getClient: getConcurrencyLimitedClient,\n i18n,\n schema,\n getDocumentExists:\n getDocumentExists ||\n createBatchedGetDocumentExists(getClient(DEFAULT_VALIDATION_CLIENT_OPTIONS)),\n environment,\n maxCustomValidationConcurrency,\n currentUser,\n }),\n )\n}\n\n/**\n * @internal\n */\nexport interface ValidateDocumentObservableOptions extends Pick<\n ValidationContext,\n 'getDocumentExists' | 'i18n'\n> {\n getClient: (options: {apiVersion: string}) => SanityClient\n document: SanityDocument\n schema: Schema\n environment: 'cli' | 'studio'\n maxCustomValidationConcurrency?: number\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\nconst customValidationConcurrencyLimiters = new WeakMap<Schema, ConcurrencyLimiter>()\n\n/**\n * Validates a document against the given schema, returning an Observable\n * @internal\n */\nexport function validateDocumentObservable({\n document,\n getClient,\n i18n = getFallbackLocaleSource(),\n schema,\n getDocumentExists,\n environment,\n maxCustomValidationConcurrency,\n currentUser,\n}: ValidateDocumentObservableOptions): Observable<ValidationMarker[]> {\n if (typeof document?._type !== 'string') {\n throw new Error(`Tried to validate a value without a '_type'`)\n }\n\n const documentType = schema.get(document._type)\n\n if (!documentType) {\n if (environment === 'studio') {\n console.warn(\n 'Schema type for object type \"%s\" not found, skipping validation',\n document._type,\n )\n return of([])\n }\n\n return of([\n {\n level: 'warning',\n message: `Could not find schema type for type '${document._type}', skipping validation`,\n path: [],\n },\n ])\n }\n\n let customValidationConcurrencyLimiter = customValidationConcurrencyLimiters.get(schema)\n if (!customValidationConcurrencyLimiter) {\n customValidationConcurrencyLimiter = new ConcurrencyLimiter(\n maxCustomValidationConcurrency ?? DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY,\n )\n customValidationConcurrencyLimiters.set(schema, customValidationConcurrencyLimiter)\n }\n\n const validationOptions: ValidateItemOptions = {\n getClient,\n schema,\n parent: undefined,\n value: document,\n path: [],\n document: document,\n type: documentType,\n i18n,\n getDocumentExists,\n environment,\n customValidationConcurrencyLimiter,\n currentUser,\n }\n\n return from(i18n.loadNamespaces(['validation'])).pipe(\n switchMap(() => validateItemObservable(validationOptions)),\n catchError((err) => {\n console.error(err)\n\n const message = err?.message || 'Unknown error'\n const errorMarker: ValidationMarker = {\n level: 'error',\n message,\n item: {message},\n path: [],\n }\n\n return of([errorMarker])\n }),\n )\n}\n\n/**\n * this is used make optional properties required by replacing optionals with\n * `T[P] | undefined`. this is used to prevent errors in `validateItem` where\n * an option from a previous invocation would be incorrectly passed down.\n *\n * https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585\n */\ntype ExplicitUndefined<T> = {\n [P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : T[P] | undefined\n}\n\ntype ValidateItemOptions = {\n value: unknown\n customValidationConcurrencyLimiter?: ConcurrencyLimiter\n hidden?: boolean\n currentUser?: Omit<CurrentUser, 'role'> | null\n} & ExplicitUndefined<Omit<ValidationContext, 'hidden'>>\n\nexport function validateItem(opts: ValidateItemOptions): Promise<ValidationMarker[]> {\n return lastValueFrom(validateItemObservable(opts))\n}\n\nfunction validateItemObservable({\n value,\n type,\n path = [],\n parent,\n customValidationConcurrencyLimiter,\n environment,\n ...restOfContext\n}: ValidateItemOptions): Observable<ValidationMarker[]> {\n // Track whether any ancestor in the tree is hidden.\n // It will be true if this field OR any ancestor is hidden.\n // This allows validation rules to check `context.hidden` to skip validation for hidden fields,\n // without needing to know whether the field itself or an ancestor caused it to be hidden.\n const ancestorHidden = restOfContext.hidden === true\n const resolveHiddenForType = (\n schemaType: SchemaType | undefined,\n schemaValue: unknown,\n schemaParent: unknown,\n schemaPath: ValidationContext['path'],\n ancestorHiddenValue: boolean,\n ) => {\n // If there is no schema type, fall back to the ancestor's hidden state.\n if (!schemaType) {\n return ancestorHiddenValue\n }\n return (\n ancestorHiddenValue ||\n resolveConditionalProperty(schemaType.hidden, {\n ...restOfContext,\n parent: schemaParent,\n value: schemaValue,\n path: schemaPath || [],\n currentUser: restOfContext.currentUser ?? null,\n })\n )\n }\n const hidden = resolveHiddenForType(type, value, parent, path, ancestorHidden)\n\n // Note: this validator is added here because it's conditional based on the\n // environment.\n const addUnknownFieldsValidator = (rule: Rule) => {\n if (\n // if the schema type is an object type\n type?.jsonType === 'object' &&\n // and if somewhere in it's type chain, it inherits from object or document\n getTypeChain(type).find((t) => ['object', 'document', 'file', 'image'].includes(t.name)) &&\n // and the environment is not the studio\n environment !== 'studio'\n ) {\n // then add the validator for unknown fields\n return rule.custom(unknownFieldsValidator(type), {bypassConcurrencyLimit: true}).warning()\n }\n\n // otherwise, leave it unchanged\n return rule\n }\n\n const rules = normalizeValidationRules(type, {\n ...restOfContext,\n hidden,\n environment,\n parent,\n path,\n type,\n })\n // run validation for the current value\n const selfChecks = rules.map(addUnknownFieldsValidator).map((rule) =>\n defer(() =>\n rule.validate(value, {\n ...restOfContext,\n environment,\n hidden,\n parent,\n path,\n type,\n __internal: {customValidationConcurrencyLimiter},\n }),\n ),\n )\n\n // run validation for nested values (conditionally)\n let nestedChecks: Array<Observable<ValidationMarker[]>> = []\n\n const selfIsRequired = rules.some((rule) => rule.isRequired())\n const shouldRunNestedObjectValidation =\n // run nested validation for objects\n type?.jsonType === 'object' &&\n // if the value is truthy\n (!!value || // or\n // (the value is null or undefined) and the top-level value is required\n ((value === null || value === undefined) && selfIsRequired))\n\n if (shouldRunNestedObjectValidation) {\n const fieldTypes = type.fields.reduce<Record<string, SchemaType>>((acc, field) => {\n acc[field.name] = field.type\n return acc\n }, {})\n\n // Validation for rules set at the object level with `Rule.fields({/* ... */})`\n // Use extractFieldRulesFromRule to handle Rule.fields() inside Rule.all() or Rule.either()\n nestedChecks = nestedChecks.concat(\n rules\n .flatMap((rule) => extractFieldRulesFromRule(rule))\n .flatMap((fieldResults) => Object.entries(fieldResults))\n .flatMap(([name, validation]) => {\n const fieldType = fieldTypes[name]\n return normalizeValidationRules({...fieldType, validation})\n .map(addUnknownFieldsValidator)\n .map((subRule) => {\n const nestedValue = isRecord(value) ? value[name] : undefined\n const nestedHidden = resolveHiddenForType(\n fieldType,\n nestedValue,\n value,\n path.concat(name),\n hidden,\n )\n return defer(() =>\n subRule.validate(nestedValue, {\n ...restOfContext,\n parent: value,\n path: path.concat(name),\n type: fieldType,\n environment,\n hidden: nestedHidden,\n __internal: {customValidationConcurrencyLimiter},\n }),\n )\n })\n }),\n )\n\n // Validation from each field's schema `validation: Rule => {/* ... */}` function\n nestedChecks = nestedChecks.concat(\n type.fields.map((field) =>\n validateItemObservable({\n ...restOfContext,\n hidden,\n parent: value,\n value: isRecord(value) ? value[field.name] : undefined,\n path: path.concat(field.name),\n type: field.type,\n environment,\n customValidationConcurrencyLimiter,\n }),\n ),\n )\n }\n\n // note: unlike objects, arrays should not run nested validation for undefined\n // values because we won't have a valid path to put a marker (i.e. missing the\n // key or index in the path) and the downstream form builder won't have a\n // valid target component\n const shouldRunNestedValidationForArrays = type?.jsonType === 'array' && Array.isArray(value)\n\n if (shouldRunNestedValidationForArrays) {\n nestedChecks = nestedChecks.concat(\n value.map((item, index) =>\n validateItemObservable({\n ...restOfContext,\n hidden,\n parent: value,\n value: item,\n path: path.concat(isKeyedObject(item) ? {_key: item._key} : index),\n type: resolveTypeForArrayItem(item, type.of),\n environment,\n customValidationConcurrencyLimiter,\n }),\n ),\n )\n }\n\n return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(\n mergeMap((validateNode) => concat(idle(), validateNode), 40),\n mergeAll(),\n toArray(),\n map(flatten),\n map((results) => {\n // run `uniqBy` if `_fieldRules` are present because they can\n // cause repeat markers (check recursively for nested rules)\n if (rules.some((rule) => extractFieldRulesFromRule(rule).length > 0)) {\n return uniqBy(results, (rule) => JSON.stringify(rule))\n }\n return results\n }),\n )\n}\n\nfunction idle(timeout?: number): Observable<never> {\n return new Observable<never>((observer) => {\n const handle = requestIdleCallback(\n () => {\n observer.complete()\n },\n timeout ? {timeout} : undefined,\n )\n\n return () => cancelIdleCallback(handle)\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validateDocument-C77_Oewa.js","names":["isRecord","Rule","BaseRule","RuleClass","switchMap","mergeMap","map"],"sources":["../src/i18n/resources.ts","../src/i18n/fallback.ts","../src/resolveConditionalProperty.ts","../src/util/createBatchedGetDocumentExists.ts","../src/util/pathToString.ts","../src/util/convertToValidationMarker.ts","../src/util/localizeMessage.ts","../src/util/deepEqualsIgnoreKey.ts","../src/util/typeString.ts","../src/validators/genericValidator.ts","../src/validators/arrayValidator.ts","../src/validators/booleanValidator.ts","../src/validators/dateValidator.ts","../src/validators/numberValidator.ts","../src/validators/objectValidator.ts","../src/validators/stringValidator.ts","../src/Rule.ts","../src/validators/slugValidator.ts","../src/util/normalizeValidationRules.ts","../src/util/requestIdleCallback.ts","../src/validators/unknownFieldsValidator.ts","../src/validateDocument.ts"],"sourcesContent":["export const validationLocaleStrings = {\n 'array.exact-length': 'Must have exactly {{wantedLength}} items',\n 'array.exact-length_blocks': 'Must have exactly {{wantedLength}} blocks',\n 'array.item-duplicate': \"Can't be a duplicate\",\n 'array.maximum-length': 'Must have at most {{maxLength}} items',\n 'array.maximum-length_blocks': 'Must have at most {{maxLength}} blocks',\n 'array.minimum-length': 'Must have at least {{minLength}} items',\n 'array.minimum-length_blocks': 'Must have at least {{minLength}} blocks',\n 'date.invalid-format': 'Must be a valid ISO-8601 formatted date string',\n 'date.maximum': 'Must be at or before {{maxDate}}',\n 'date.minimum': 'Must be at or after {{minDate}}',\n 'generic.incorrect-type': 'Expected type \"{{expectedType}}\", got \"{{actualType}}\"',\n 'generic.not-allowed': 'Value did not match any allowed values',\n 'generic.not-allowed_hint': 'Value \"{{hint}}\" did not match any allowed values',\n 'generic.required': 'Required',\n 'number.greater-than': 'Must be greater than {{threshold}}',\n 'number.less-than': 'Must be less than {{threshold}}',\n 'number.maximum': 'Must be lower than or equal to {{maxNumber}}',\n 'number.maximum-precision': 'Max precision is {{limit}}',\n 'number.minimum': 'Must be greater than or equal to {{minNumber}}',\n 'number.non-integer': 'Must be an integer',\n 'object.asset-required': 'Asset is required',\n 'object.asset-required_file': 'File is required',\n 'object.asset-required_image': 'Image is required',\n 'object.media-not-found': 'The asset could not be found in the Media Library',\n 'object.not-media-library-asset': 'Must be a reference to a Media Library asset',\n 'object.not-reference': 'Must be a reference to a document',\n 'object.reference-not-published': 'Referenced document must be published',\n 'slug.missing-current': 'Slug must have a value',\n 'slug.not-object': 'Slug must be an object',\n 'slug.not-unique': 'Slug is already in use',\n 'string.email': 'Must be a valid email address',\n 'string.exact-length': 'Must be exactly {{wantedLength}} characters long',\n 'string.lowercase': 'Must be all lowercase characters',\n 'string.maximum-length': 'Must be at most {{maxLength}} characters long',\n 'string.minimum-length': 'Must be at least {{minLength}} characters long',\n 'string.regex-does-not-match': 'Does not match \"{{name}}\"-pattern',\n 'string.regex-match': 'Should not match \"{{name}}\"-pattern',\n 'string.uppercase': 'Must be all uppercase characters',\n 'string.url.disallowed-scheme': 'Does not match allowed protocols/schemes',\n 'string.url.includes-credentials': 'Username/password not allowed',\n 'string.url.invalid': 'Not a valid URL',\n 'string.url.not-absolute': 'Relative URLs are not allowed',\n 'string.url.not-relative': 'Only relative URLs are allowed',\n} as const\n","import {createInstance} from 'i18next'\n\nimport {validationLocaleStrings} from './resources'\nimport {type LocaleSource} from './types'\n\nlet fallbackLocaleSource: LocaleSource | undefined\n\nexport function getFallbackLocaleSource(): LocaleSource {\n if (fallbackLocaleSource) return fallbackLocaleSource\n\n const i18n = createInstance({\n defaultNS: 'validation',\n fallbackLng: 'en-US',\n initAsync: false,\n interpolation: {escapeValue: false},\n lng: 'en-US',\n ns: ['validation'],\n resources: {'en-US': {validation: validationLocaleStrings}},\n supportedLngs: ['en-US'],\n })\n void i18n.init()\n\n fallbackLocaleSource = {\n currentLocale: {id: 'en-US'},\n loadNamespaces: (namespaces) => i18n.loadNamespaces(namespaces),\n t: i18n.t,\n }\n return fallbackLocaleSource\n}\n","import {type ConditionalProperty, type CurrentUser, type Path} from '@sanity/types'\n\ninterface ConditionalPropertyCallbackContext {\n parent?: unknown\n document?: Record<string, unknown>\n currentUser: Omit<CurrentUser, 'role'> | null\n value: unknown\n path: Path\n}\n\nexport function resolveConditionalProperty(\n property: ConditionalProperty,\n context: ConditionalPropertyCallbackContext,\n) {\n const {currentUser, document, parent, value, path} = context\n\n if (typeof property === 'boolean' || property === undefined) return Boolean(property)\n\n // oxlint-disable-next-line no-unnecessary-boolean-literal-compare -- runtime callbacks may return non-booleans\n return property({document: document as never, parent, value, currentUser, path}) === true\n}\n","import {type SanityClient} from '@sanity/client'\nimport {ConcurrencyLimiter} from '@sanity/util/concurrency-limiter'\nimport {\n bufferTime,\n filter,\n finalize,\n firstValueFrom,\n from,\n map,\n mergeMap,\n share,\n Subject,\n switchMap,\n} from 'rxjs'\n\ninterface AvailabilityResponse {\n omitted: {id: string; reason: 'existence' | 'permission'}[]\n}\n\n/**\n * The amount of time reserved for waiting for new IDs.\n */\nconst BUFFER_TIME = 250\n/**\n * The upper limit for IDs sent to the `doc` endpoint at once. From some manual\n * testing, 100 seems to be a safe amount.\n */\nexport const MAX_BUFFER_SIZE = 100\n/**\n * The max amount of inflight requests to the `doc` endpoint to check for\n * availability. Currently set to 1 because the endpoint is expensive\n *\n * From: https://www.sanity.io/docs/http-doc\n *\n * \"it is less scalable/performant than the other query-mechanisms, so should\n * be used sparingly*\n */\nexport const MAX_REQUEST_CONCURRENCY = 1\n\nexport function createBatchedGetDocumentExists(\n client: SanityClient,\n): (options: {id: string}) => Promise<boolean> {\n const id$ = new Subject<string>()\n const limiter = new ConcurrencyLimiter(MAX_REQUEST_CONCURRENCY)\n\n const existence$ = id$.pipe(\n bufferTime(BUFFER_TIME, null, MAX_BUFFER_SIZE),\n map((ids) => Array.from(new Set(ids))),\n mergeMap((ids) =>\n from(limiter.ready()).pipe(\n switchMap(() =>\n client.observable\n .request<AvailabilityResponse>({\n url: client.getDataUrl('doc', ids.join(',')),\n query: {excludeContent: 'true'},\n tag: 'documents-availability',\n })\n .pipe(map((availability) => ({availability, ids}))),\n ),\n finalize(limiter.release),\n ),\n ),\n mergeMap(({availability, ids}) =>\n ids.map((id) => {\n const omittedIds = availability.omitted.reduce<Record<string, 'existence' | 'permission'>>(\n (acc, next) => {\n acc[next.id] = next.reason\n return acc\n },\n {},\n )\n\n // if not in the `omitted`, then it exists\n if (!omittedIds[id]) return {id, exists: true}\n // if in the `omitted` due to existence, then it does not exist\n if (omittedIds[id] === 'existence') return {id, exists: false}\n // otherwise, it must exist\n return {id, exists: true}\n }),\n ),\n share(),\n )\n\n return async function getDocumentExists(options) {\n // set up a promise/listener that waits for the result\n const result = firstValueFrom(existence$.pipe(filter(({id}) => id === options.id)))\n // send off the request to the stream for batching\n id$.next(options.id)\n\n const {exists} = await result\n return exists\n }\n}\n","import {isKeyedObject, type Path} from '@sanity/types'\n\nexport function pathToString(path: Path | undefined = []): string {\n return path.reduce<string>((target, segment, i) => {\n const segmentType = typeof segment\n if (segmentType === 'number') {\n return `${target}[${segment}]`\n }\n\n if (segmentType === 'string') {\n const separator = i === 0 ? '' : '.'\n return `${target}${separator}${segment}`\n }\n\n if (isKeyedObject(segment)) {\n return `${target}[_key==\"${segment._key}\"]`\n }\n\n throw new Error(`Unsupported path segment \"${segment}\"`)\n }, '')\n}\n","/* oxlint-disable typescript/no-deprecated -- marker compatibility requires legacy fields */\nimport {type Path, type ValidationError, type ValidationMarker} from '@sanity/types'\n\nimport {type ValidationContext} from '../types'\nimport {pathToString} from '../util/pathToString'\n\nfunction isNonNullable<T>(t: T): t is NonNullable<T> {\n return t !== null || t !== undefined\n}\n\nexport function convertToValidationMarker(\n validatorResult: true | true[] | string | string[] | ValidationError | ValidationError[],\n level: 'error' | 'warning' | 'info' | undefined,\n context: ValidationContext,\n): ValidationMarker[] {\n if (!context) {\n throw new Error('missing context')\n }\n\n if (validatorResult === true) return []\n\n if (Array.isArray(validatorResult)) {\n return validatorResult\n .flatMap((child) => convertToValidationMarker(child, level, context))\n .filter(isNonNullable)\n }\n\n if (typeof validatorResult === 'string') {\n return convertToValidationMarker({message: validatorResult}, level, context)\n }\n\n if (typeof validatorResult.message !== 'string') {\n // in order to accept the `ValidationError`, it at least needs to have a\n // `message` in the object\n throw new Error(\n `${pathToString(\n context.path,\n )}: Validator must return 'true' if valid or an error message as a string on errors`,\n )\n }\n\n const {message, __internal_metadata} = validatorResult\n\n const normalizedPaths: Path[] = []\n if (validatorResult.path) {\n normalizedPaths.push(validatorResult.path)\n }\n\n // legacy support for `paths`\n for (const path of validatorResult.paths || []) {\n normalizedPaths.push(path)\n }\n\n // the validator result does not include any item-level relative paths,\n // then just return the top-level path with the validation result\n if (!normalizedPaths.length) {\n return [\n {\n level: level || 'error',\n item: {message},\n message,\n path: context.path || [],\n __internal_metadata,\n },\n ]\n }\n\n // if the validator result did include item-level relative paths, then for\n // each item-level relative path, create a validation marker that concatenates\n // the relative path with the path from the validation context\n return normalizedPaths.map((path) => ({\n path: (context.path || []).concat(path),\n level: level || 'error',\n item: {message},\n message,\n __internal_metadata,\n }))\n}\n","import {type CustomValidatorResult, type LocalizedValidationMessages} from '@sanity/types'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\n\nimport {type LocaleSource} from '../i18n/types'\n\n/**\n * Extracts the correct localized validation message based on given locale source\n *\n * @param message - Localized messages to extract string from\n * @param i18n - Locale source, holding the current locale\n * @returns The localized string, or a fallback \"Unknown error\" if not found\n * @internal\n */\nexport function localizeMessage(message: LocalizedValidationMessages, i18n: LocaleSource): string {\n const {currentLocale} = i18n\n const locale = currentLocale.id\n\n // Obviously, try direct match first (`no-NB`)\n if (message[locale]) {\n return message[locale]\n }\n\n // In the case of composed languages (`en-US`, `no-NB` etc), fall back to base language (`en`)\n if (locale.includes('-')) {\n const language = locale.split('-', 1)[0]\n if (message[language]) {\n return message[language]\n }\n }\n\n // Try english as last resort\n return (\n message['en-US'] || message['en-GB'] || message.en || 'Unknown validation error (not localized)'\n )\n}\n\n/**\n * Check if passed message/result is a localized message object\n *\n * @param message - Message to check\n * @returns True if message is a localized message object, false otherwise\n * @internal\n */\nexport function isLocalizedMessages(\n message: CustomValidatorResult | undefined,\n): message is LocalizedValidationMessages {\n return (\n message !== true &&\n typeof message !== 'undefined' &&\n typeof message !== 'string' &&\n isPlainObject(message) &&\n !('message' in message)\n )\n}\n","/**\n * Modified version of fast-deep-equal (https://github.com/epoberezkin/fast-deep-equal)\n * MIT-licensed, copyright (c) 2017 Evgeny Poberezkin\n **/\n\n// NOTE: when converting to typescript, some of the checks were inlined (vs\n// having them in a variable) because the type predicate type narrowing only\n// works when type predicate is called inline in the condition that starts the\n// control flow branch.\n// see here: https://www.typescriptlang.org/docs/handbook/2/narrowing.html\nexport function deepEqualsIgnoreKey(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!deepEqualsIgnoreKey(a[i], b[i])) {\n return false\n }\n }\n return true\n }\n\n if (Array.isArray(a) != Array.isArray(b)) {\n return false\n }\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n const keys = Object.keys(a)\n if (keys.length !== Object.keys(b).length) {\n return false\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n if (a instanceof Date != b instanceof Date) {\n return false\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() == b.toString()\n }\n\n if (a instanceof RegExp != b instanceof RegExp) {\n return false\n }\n\n for (let i = 0; i < keys.length; i++) {\n if (keys[i] === '_key') {\n continue\n }\n\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {\n return false\n }\n }\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i] as keyof typeof a\n if (key === '_key') {\n continue\n }\n\n if (!deepEqualsIgnoreKey(a[key], b[key])) {\n return false\n }\n }\n\n return true\n }\n\n return false\n}\n","// this file was adapted from a previous dependency `type-of-is`\n// https://github.com/stephenhandley/type-of-is/blob/7138a7e79f5af7c286bf8123f60843a91aaebf38/index.js\nconst _toString = {}.toString\n\nconst builtIns = [Object, Function, Array, String, Boolean, Number, Date, RegExp, Error]\n\nfunction isBuiltIn(_constructor: unknown) {\n for (let i = 0; i < builtIns.length; i++) {\n if (builtIns[i] === _constructor) return true\n }\n return false\n}\n\nexport function typeString(obj: unknown): string {\n // [object Blah] -> Blah\n const stringType = _toString.call(obj).slice(8, -1)\n if (obj === null || obj === undefined) return stringType.toLowerCase()\n\n const constructorType = (obj as object).constructor\n if (constructorType && !isBuiltIn(constructorType)) return constructorType.name\n return stringType\n}\n","/* oxlint-disable typescript/no-deprecated -- marker compatibility requires the legacy item field */\nimport {type ValidationMarker, type Validators} from '@sanity/types'\n\nimport {type LocaleSource} from '../i18n/types'\nimport {deepEqualsIgnoreKey} from '../util/deepEqualsIgnoreKey'\nimport {isLocalizedMessages, localizeMessage} from '../util/localizeMessage'\nimport {pathToString} from '../util/pathToString'\nimport {typeString} from '../util/typeString'\n\nexport const SLOW_VALIDATOR_TIMEOUT = 5000\n\nconst formatValidationErrors = (options: {\n message: string | undefined\n results: ValidationMarker[]\n operation: 'conjunction' | 'disjunction'\n i18n: LocaleSource\n}) => {\n if (options.message) return options.message\n if (options.results.length === 1) return options.results[0]?.message\n\n // Intentionally hard-coded to use locale conjunction/disjunctions\n return options.i18n.t('{{messages, list}}', {\n messages: options.results.map((err) => err.message || err.item?.message),\n formatParams: {messages: {style: 'long', type: options.operation}},\n })\n}\n\nexport const genericValidators: Validators = {\n type: (expectedType, value, message, {i18n}) => {\n const actualType = typeString(value)\n if (actualType !== expectedType && actualType !== 'undefined') {\n return message || i18n.t('validation:generic.incorrect-type', {actualType, expectedType})\n }\n\n return true\n },\n\n presence: (expected, value, message, {i18n}) => {\n if (value === undefined && expected === 'required') {\n return message || i18n.t('validation:generic.required')\n }\n\n return true\n },\n\n all: async (children, value, message, context) => {\n const resolved = await Promise.all(children.map((child) => child.validate(value, context)))\n const results = resolved.flat()\n\n if (results.length === 0) {\n return true\n }\n\n return formatValidationErrors({\n message,\n results,\n operation: 'conjunction',\n i18n: context.i18n,\n })\n },\n\n either: async (children, value, message, context) => {\n const resolved = await Promise.all(children.map((child) => child.validate(value, context)))\n const results = resolved.flat()\n\n // if one of the results is an empty array then at least one rule match\n if (resolved.find((result) => !result.length)) {\n return true\n }\n\n return formatValidationErrors({\n message,\n results,\n operation: 'disjunction',\n i18n: context.i18n,\n })\n },\n\n valid: (allowedValues, actual, message, {i18n}) => {\n const valueType = typeof actual\n if (valueType === 'undefined') {\n return true\n }\n\n const value = (valueType === 'number' || valueType === 'string') && `${actual}`\n const strValue = value && value.length > 30 ? `${value.slice(0, 30)}…` : value\n\n return allowedValues.some((expected) => deepEqualsIgnoreKey(expected, actual))\n ? true\n : message ||\n i18n.t(\n 'validation:generic.not-allowed',\n value ? {context: 'hint', replace: {hint: strValue}} : {},\n )\n },\n\n custom: async (fn, value, message, context) => {\n const slowTimer = setTimeout(() => {\n // only show this warning in the studio\n if (context.environment !== 'studio') return\n\n console.warn(\n `Custom validator at ${pathToString(\n context.path,\n )} has taken more than ${SLOW_VALIDATOR_TIMEOUT}ms to respond`,\n )\n }, SLOW_VALIDATOR_TIMEOUT)\n\n let result\n try {\n result = await fn(value, context)\n } finally {\n clearTimeout(slowTimer)\n }\n\n if (isLocalizedMessages(result)) {\n return localizeMessage(result, context.i18n)\n }\n\n if (typeof result === 'string') {\n return message || result\n }\n\n return result\n },\n}\n","import {\n isArrayOfBlocksSchemaType,\n type Path,\n type PathSegment,\n type Validators,\n} from '@sanity/types'\n\nimport {deepEqualsIgnoreKey} from '../util/deepEqualsIgnoreKey'\nimport {genericValidators} from './genericValidator'\n\nexport const arrayValidators: Validators = {\n ...genericValidators,\n\n min: (minLength, value, message, {i18n, type}) => {\n if (!value || value.length >= minLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.minimum-length', {minLength, context})\n },\n\n max: (maxLength, value, message, {i18n, type}) => {\n if (!value || value.length <= maxLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.maximum-length', {maxLength, context})\n },\n\n length: (wantedLength, value, message, {i18n, type}) => {\n if (!value || value.length === wantedLength) {\n return true\n }\n\n const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined\n return message || i18n.t('validation:array.exact-length', {wantedLength, context})\n },\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && !value) {\n return message || i18n.t('validation:generic.required', {context: 'array'})\n }\n\n return true\n },\n\n valid: (allowedValues, values, message, {i18n}) => {\n const valueType = typeof values\n if (valueType === 'undefined') {\n return true\n }\n\n const paths: Path[] = []\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (allowedValues.some((expected) => deepEqualsIgnoreKey(expected, value))) {\n continue\n }\n\n const pathSegment: PathSegment = value && value._key ? {_key: value._key} : i\n paths.push([pathSegment])\n }\n\n // we emit the same message for each path we find in this array\n const sharedMessage = message || i18n.t('validation:generic.not-allowed')\n\n return paths.map((path) => ({message: sharedMessage, path}))\n },\n\n unique: (_unused, value, message, {i18n}) => {\n const dupeIndices = []\n if (!value) {\n return true\n }\n\n for (let x = 0; x < value.length; x++) {\n for (let y = x + 1; y < value.length; y++) {\n const itemA = value[x]\n const itemB = value[y]\n\n if (!deepEqualsIgnoreKey(itemA, itemB)) {\n continue\n }\n\n if (dupeIndices.indexOf(x) === -1) {\n dupeIndices.push(x)\n }\n\n if (dupeIndices.indexOf(y) === -1) {\n dupeIndices.push(y)\n }\n }\n }\n\n const paths = dupeIndices.map((idx) => {\n const item = value[idx]\n const pathSegment = item && item._key ? {_key: item._key} : idx\n return [pathSegment]\n })\n\n // we emit the same message for each path we find in this array\n const sharedMessage = message || i18n.t('validation:array.item-duplicate')\n\n return paths.map((path) => ({message: sharedMessage, path}))\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nexport const booleanValidators: Validators = {\n ...genericValidators,\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && typeof value !== 'boolean') {\n return message || i18n.t('validation:generic.required', {context: 'boolean'})\n }\n\n return true\n },\n}\n","import {type Validators} from '@sanity/types'\nimport * as legacyDateFormat from '@sanity/util/legacyDateFormat'\n\nimport {genericValidators} from './genericValidator'\n\nfunction isRecord(obj: unknown): obj is Record<string, unknown> {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj)\n}\n\nconst isoDate =\n /^(?:[-+]\\d{2})?(?:\\d{4}(?!\\d{2}\\b))(?:(-?)(?:(?:0[1-9]|1[0-2])(?:\\1(?:[12]\\d|0[1-9]|3[01]))?|W(?:[0-4]\\d|5[0-2])(?:-?[1-7])?|(?:00[1-9]|0[1-9]\\d|[12]\\d{2}|3(?:[0-5]\\d|6[1-6])))(?![T]$|[T][\\d]+Z$)(?:[T\\s](?:(?:(?:[01]\\d|2[0-3])(?:(:?)[0-5]\\d)?|24:?00)(?:[.,]\\d+(?!:))?)(?:\\2[0-5]\\d(?:[.,]\\d+)?)?(?:[Z]|(?:[+-])(?:[01]\\d|2[0-3])(?::?[0-5]\\d)?)?)?)?$/\n\n// TODO (eventually): move these to schema type package\ninterface DateTimeOptions {\n // @todo accept object representing `Intl.DateTimeFormatOptions`? how do we localize?\n dateFormat?: string\n timeFormat?: string\n}\n\nconst getFormattedDate = (type = '', value: Date, options?: DateTimeOptions) => {\n const dateFormat = options?.dateFormat || legacyDateFormat.DEFAULT_DATE_FORMAT\n const timeFormat = options?.timeFormat || legacyDateFormat.DEFAULT_TIME_FORMAT\n\n // adding the time information in the date only case causes timezone information to be kept\n // instead of it being assumed to be UTC. This was a problem because midnight UTC is the previous\n // day in many other timezones resulting in the date displayed to be the previous day.\n return legacyDateFormat.format(\n value,\n type === 'date' ? dateFormat : `${dateFormat} ${timeFormat}`,\n {useUTC: type === 'date'},\n )\n}\n\nfunction parseDate(date: unknown): Date | null\nfunction parseDate(date: unknown, throwOnError: true): Date\nfunction parseDate(date: unknown, throwOnError = false): Date | null {\n if (!date) return null\n if (date === 'now') return new Date()\n\n // oxlint-disable-next-line no-explicit-any\n const parsed = new Date(date as any)\n const isInvalid = isNaN(parsed.getTime())\n if (isInvalid && throwOnError) {\n throw new Error(`Unable to parse \"${date}\" to a date`)\n }\n\n return isInvalid ? null : parsed\n}\n\nexport const dateValidators: Validators = {\n ...genericValidators,\n\n type: (_unused, value, message, {i18n}) => {\n if (typeof value === 'undefined' || isoDate.test(`${value}`)) {\n return true\n }\n\n return message || i18n.t('validation:date.invalid-format')\n },\n\n min: (minDate, value, message, {type, i18n}) => {\n const dateVal = parseDate(value)\n const minDateVal = parseDate(minDate, true)\n\n if (!dateVal) {\n return true // `type()` should catch parse errors\n }\n\n if (!value || dateVal >= minDateVal) {\n return true\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context.`)\n }\n\n const dateTimeOptions: DateTimeOptions = isRecord(type.options)\n ? (type.options as DateTimeOptions)\n : {}\n\n return (\n message ||\n // Note that the `minDate` passed here is _formatted_, while the raw value provided to the\n // validator is available as `providedMinDate`. This because the formatted date is likely\n // what the developer wants to present to the user\n i18n.t('validation:date.minimum', {\n minDate: getFormattedDate(type.name, minDateVal, dateTimeOptions),\n providedMinDate: minDate,\n })\n )\n },\n\n max: (maxDate, value, message, {type, i18n}) => {\n const dateVal = parseDate(value)\n const maxDateVal = parseDate(maxDate, true)\n\n if (!dateVal) {\n return true // `type()` should catch parse errors\n }\n\n if (!value || dateVal <= maxDateVal) {\n return true\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context.`)\n }\n\n const dateTimeOptions: DateTimeOptions = isRecord(type.options)\n ? (type.options as DateTimeOptions)\n : {}\n\n return (\n message ||\n // Note that the `maxDate` passed here is _formatted_, while the raw value provided to the\n // validator is available as `providedMaxDate`. This because the formatted date is likely\n // what the developer wants to present to the user\n i18n.t('validation:date.maximum', {\n maxDate: getFormattedDate(type.name, maxDateVal, dateTimeOptions),\n providedMaxDate: maxDate,\n })\n )\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nconst precisionRx = /(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/\n\nexport const numberValidators: Validators = {\n ...genericValidators,\n\n integer: (_unused, value, message, {i18n}) => {\n if (!Number.isInteger(value)) {\n return message || i18n.t('validation:number.non-integer')\n }\n\n return true\n },\n\n precision: (limit, value, message, {i18n}) => {\n if (value === undefined) return true\n\n const places = value.toString().match(precisionRx)\n const decimals = Math.max(\n (places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0),\n 0,\n )\n\n if (decimals > limit) {\n return message || i18n.t('validation:number.maximum-precision', {limit})\n }\n\n return true\n },\n\n min: (minNumber, value, message, {i18n}) => {\n if (value >= minNumber) {\n return true\n }\n\n return message || i18n.t('validation:number.minimum', {minNumber})\n },\n\n max: (maxNumber, value, message, {i18n}) => {\n if (value <= maxNumber) {\n return true\n }\n\n return message || i18n.t('validation:number.maximum', {maxNumber})\n },\n\n greaterThan: (threshold, value, message, {i18n}) => {\n if (value > threshold) {\n return true\n }\n\n return message || i18n.t('validation:number.greater-than', {threshold})\n },\n\n lessThan: (threshold, value, message, {i18n}) => {\n if (value < threshold) {\n return true\n }\n\n return message || i18n.t('validation:number.less-than', {threshold})\n },\n}\n","import {type DocumentId, getPublishedId} from '@sanity/id-utils'\nimport {type CustomValidatorResult, isReference, type Validators} from '@sanity/types'\n\nimport {isLocalizedMessages, localizeMessage} from '../util/localizeMessage'\nimport {pathToString} from '../util/pathToString'\nimport {genericValidators, SLOW_VALIDATOR_TIMEOUT} from './genericValidator'\n\nconst metaKeys = ['_key', '_type', '_weak']\n\ninterface MediaLibraryAsset {\n currentVersion: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport const objectValidators: Validators = {\n ...genericValidators,\n\n presence: (expected, value, message, {i18n}) => {\n if (expected !== 'required') {\n return true\n }\n\n const keys = value && Object.keys(value).filter((key) => !metaKeys.includes(key))\n\n if (value === undefined || (keys && keys.length === 0)) {\n return message || i18n.t('validation:generic.required', {context: 'object'})\n }\n\n return true\n },\n\n reference: async (_unused, value: unknown, message, context) => {\n if (!value) {\n return true\n }\n\n const {type, document, getDocumentExists, i18n} = context\n\n if (!isReference(value)) {\n return message || i18n.t('validation:object.not-reference')\n }\n\n if (!type) {\n throw new Error(`\\`type\\` was not provided in validation context`)\n }\n\n if ('weak' in type && type.weak) {\n return true\n }\n\n if (!getDocumentExists) {\n throw new Error(`\\`getDocumentExists\\` was not provided in validation context`)\n }\n\n const documentId = document?._id\n if (documentId && value._ref == getPublishedId(documentId as DocumentId)) {\n // a document should be able to reference itself without first being published\n return true\n }\n const exists = await getDocumentExists({id: value._ref})\n if (!exists) {\n return i18n.t('validation:object.reference-not-published', {documentId: value._ref})\n }\n\n return true\n },\n\n assetRequired: (flag, value, message, {i18n}) => {\n if (!value || !value.asset || !value.asset._ref) {\n return {\n __internal_metadata: {\n name: 'assetRequired',\n },\n message:\n message || i18n.t('validation:object.asset-required', {context: flag.assetType || ''}),\n }\n }\n\n return true\n },\n\n media: async (fn, value, message, context) => {\n const slowTimer = setTimeout(() => {\n // only show this warning in the studio\n if (context.environment !== 'studio') return\n\n console.warn(\n `Media validator at ${pathToString(\n context.path,\n )} has taken more than ${SLOW_VALIDATOR_TIMEOUT}ms to respond`,\n )\n }, SLOW_VALIDATOR_TIMEOUT)\n\n // If no value is provided, we assume the validation passes. This should be handled by the 'isRequired' validator.\n if (!value) {\n return true\n }\n\n // If the value is not an object or does not have a media reference, we return an error message.\n // It should not be allowed to use regular dataset assets with this validator.\n if (!value || !value.media || !value.media._ref) {\n return context.i18n.t('validation:object.not-media-library-asset')\n }\n\n let result: CustomValidatorResult = true\n\n try {\n const [type, libraryId, documentId] = value.media._ref.split(':', 3)\n // TODO: replace this with stable resource config when available\n const resourceConfig = {resource: {type, id: libraryId}}\n const asset = await context\n .getClient({apiVersion: '2025-02-19'})\n .withConfig(resourceConfig)\n .fetch<MediaLibraryAsset | null>(\n `*[_id == $id] { ..., 'currentVersion': @.currentVersion-> { ... } }[0]`,\n {\n id: documentId,\n },\n )\n if (!asset) {\n console.warn(\n `${context.i18n.t('validation:object.media-not-found')}\\nAsset ID: ${value.media._ref}`,\n )\n return context.i18n.t('validation:object.media-not-found')\n }\n\n result = await fn(\n {\n media: {\n asset: asset as unknown as Parameters<typeof fn>[0]['media']['asset'],\n },\n value,\n },\n context,\n )\n } catch (err) {\n const error = new Error(\n `Media validator at ${pathToString(\n context.path,\n )} failed with an error: ${err instanceof Error ? err.message : String(err)}`,\n {cause: err},\n )\n throw error\n } finally {\n clearTimeout(slowTimer)\n }\n\n const validationErrorMetadata = {\n __internal_metadata: {\n name: 'media',\n },\n }\n\n // Valid, no errors\n if (result === true) {\n return result\n }\n\n // Ensure we always return ValidationMarker with metadata\n return Array.isArray(result)\n ? result\n : [result].map((res) => {\n if (typeof res === 'string') {\n return {...validationErrorMetadata, message: message || res}\n }\n if (isLocalizedMessages(res)) {\n return {\n ...validationErrorMetadata,\n message: message || localizeMessage(res, context.i18n),\n }\n }\n return {...validationErrorMetadata, ...res, message: message || res.message}\n })\n },\n}\n","import {type Validators} from '@sanity/types'\n\nimport {genericValidators} from './genericValidator'\n\nconst DUMMY_ORIGIN = 'http://sanity'\nconst isRelativeUrl = (url: string) => /^\\.*\\//.test(url)\nconst emailRegex =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n\nexport const stringValidators: Validators = {\n ...genericValidators,\n\n min: (minLength, value, message, {i18n}) => {\n if (!value || value.length >= minLength) {\n return true\n }\n\n return message || i18n.t('validation:string.minimum-length', {minLength})\n },\n\n max: (maxLength, value, message, {i18n}) => {\n if (!value || value.length <= maxLength) {\n return true\n }\n\n return message || i18n.t('validation:string.maximum-length', {maxLength})\n },\n\n length: (wantedLength, value, message, {i18n}) => {\n const strValue = value || ''\n if (strValue.length === wantedLength) {\n return true\n }\n\n return message || i18n.t('validation:string.exact-length', {wantedLength})\n },\n\n uri: (constraints, value, message, {i18n}) => {\n const strValue = value || ''\n if (!strValue) {\n return true // `presence()` should catch empty values\n }\n\n const {options} = constraints\n const {allowCredentials, relativeOnly} = options\n const allowRelative = options.allowRelative || relativeOnly\n\n let url\n try {\n // WARNING: Safari checks for a given `base` param by looking at the length of arguments passed\n // to new URL(str, base), and will fail if invoked with new URL(strValue, undefined)\n url = allowRelative ? new URL(strValue, DUMMY_ORIGIN) : new URL(strValue)\n } catch {\n return message || i18n.t('validation:string.url.invalid')\n }\n\n if (relativeOnly && url.origin !== DUMMY_ORIGIN) {\n return message || i18n.t('validation:string.url.not-relative')\n }\n\n if (!allowRelative && url.origin === DUMMY_ORIGIN && isRelativeUrl(strValue)) {\n return message || i18n.t('validation:string.url.not-absolute')\n }\n\n if (!allowCredentials && (url.username || url.password)) {\n return message || i18n.t('validation:string.url.includes-credentials')\n }\n\n const urlScheme = url.protocol.replace(/:$/, '')\n const isRelative = isRelativeUrl(strValue)\n const matchesAllowedScheme =\n isRelative || options.scheme.some((scheme) => scheme.test(urlScheme))\n if (!matchesAllowedScheme) {\n return message || i18n.t('validation:string.url.disallowed-scheme', {scheme: urlScheme})\n }\n\n return true\n },\n\n stringCasing: (casing, value, message, {i18n}) => {\n const strValue = value || ''\n if (casing === 'uppercase' && strValue !== strValue.toLocaleUpperCase()) {\n return message || i18n.t('validation:string.uppercase')\n }\n\n if (casing === 'lowercase' && strValue !== strValue.toLocaleLowerCase()) {\n return message || i18n.t('validation:string.lowercase')\n }\n\n return true\n },\n\n presence: (flag, value, message, {i18n}) => {\n if (flag === 'required' && !value) {\n return message || i18n.t('validation:generic.required', {context: 'string'})\n }\n\n return true\n },\n\n regex: (options, value, message, {i18n}) => {\n const {pattern, name, invert} = options\n const regName = name || `${pattern.toString()}`\n const strValue = value || ''\n // Regexes with global or sticky flags are stateful (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex).\n // This resets the state stored from the previous check\n pattern.lastIndex = 0\n const matches = pattern.test(strValue)\n if ((!invert && !matches) || (invert && matches)) {\n if (message) {\n return message\n }\n\n return invert\n ? i18n.t('validation:string.regex-match', {name: regName})\n : i18n.t('validation:string.regex-does-not-match', {name: regName})\n }\n\n return true\n },\n\n email: (_unused, value, message, {i18n}) => {\n const strValue = `${value || ''}`.trim()\n if (!strValue || emailRegex.test(strValue)) {\n return true\n }\n\n return message || i18n.t('validation:string.email')\n },\n}\n","/* oxlint-disable typescript/no-deprecated -- this is the concrete implementation of the legacy Rule internals */\nimport {Rule as BaseRule} from '@sanity/schema'\nimport {\n type CustomValidator,\n type Rule as IRule,\n type RuleClass,\n type SchemaType,\n type ValidationMarker,\n type Validator,\n} from '@sanity/types'\nimport get from 'lodash-es/get.js'\n\nimport {convertToValidationMarker} from './util/convertToValidationMarker'\nimport {isLocalizedMessages, localizeMessage} from './util/localizeMessage'\nimport {pathToString} from './util/pathToString'\nimport {arrayValidators} from './validators/arrayValidator'\nimport {booleanValidators} from './validators/booleanValidator'\nimport {dateValidators} from './validators/dateValidator'\nimport {genericValidators} from './validators/genericValidator'\nimport {numberValidators} from './validators/numberValidator'\nimport {objectValidators} from './validators/objectValidator'\nimport {stringValidators} from './validators/stringValidator'\n\nconst typeValidators = {\n Boolean: booleanValidators,\n Number: numberValidators,\n String: stringValidators,\n Array: arrayValidators,\n Object: objectValidators,\n Date: dateValidators,\n}\n\nconst isFieldRef = (constraint: unknown): constraint is {type: symbol; path: string | string[]} => {\n if (typeof constraint !== 'object' || !constraint) return false\n return (constraint as Record<string, unknown>).type === Rule.FIELD_REF\n}\n\nconst EMPTY_ARRAY: unknown[] = []\n\n/**\n * Concrete Rule implementation with validation logic.\n * This extends the base Rule class from `@sanity/schema` and adds the validate method.\n *\n * Note: `RuleClass` and `Rule` are split to fit the current `@sanity/types`\n * setup. Classes are a bit weird in the `@sanity/types` package because classes\n * create an actual javascript class while simultaneously creating a type\n * definition.\n *\n * This implicitly creates two types:\n * 1. the instance type — `Rule` and\n * 2. the static/class type - `RuleClass`\n *\n * The `RuleClass` type contains the static methods and the `Rule` instance\n * contains the instance methods.\n *\n * This package exports the RuleClass as a value without implicitly exporting\n * an instance definition. This should help reminder downstream users to import\n * from the `@sanity/types` package.\n *\n * @internal\n */\n// export class Rule extends BaseRule implements IRule {\nexport const Rule: RuleClass = class Rule extends BaseRule implements IRule {\n static array = (def?: SchemaType): Rule => new Rule(def).type('Array')\n static object = (def?: SchemaType): Rule => new Rule(def).type('Object')\n static string = (def?: SchemaType): Rule => new Rule(def).type('String')\n static number = (def?: SchemaType): Rule => new Rule(def).type('Number')\n static boolean = (def?: SchemaType): Rule => new Rule(def).type('Boolean')\n static dateTime = (def?: SchemaType): Rule => new Rule(def).type('Date')\n\n clone(): Rule {\n const rule = new Rule()\n rule._type = this._type\n rule._message = this._message\n rule._required = this._required\n rule._rules = [...this._rules]\n rule._level = this._level\n rule._fieldRules = this._fieldRules\n rule._typeDef = this._typeDef\n return rule\n }\n\n async validate(\n value: unknown,\n {__internal = {}, ...context}: Parameters<IRule['validate']>[1],\n ): Promise<ValidationMarker[]> {\n const {customValidationConcurrencyLimiter} = __internal\n\n const valueIsEmpty = value === null || value === undefined\n\n // Short-circuit on optional, empty fields\n if (valueIsEmpty && this._required === 'optional') {\n return EMPTY_ARRAY as ValidationMarker[]\n }\n\n const rules =\n // Run only the _custom_ functions if the rule is not set to required or optional\n this._required === undefined && valueIsEmpty\n ? this._rules.filter((curr) => curr.flag === 'custom')\n : this._rules\n\n const validators = (this._type && typeValidators[this._type]) || genericValidators\n\n const results = await Promise.all(\n rules.map(async (curr) => {\n if (curr.flag === undefined) {\n throw new Error('Invalid rule, did not contain \"flag\"-property')\n }\n\n const validator: Validator | undefined = validators[curr.flag]\n if (!validator) {\n const forType = this._type ? `type \"${this._type}\"` : 'rule without declared type'\n throw new Error(`Validator for flag \"${curr.flag}\" not found for ${forType}`)\n }\n\n let specConstraint = 'constraint' in curr ? curr.constraint : null\n if (isFieldRef(specConstraint)) {\n specConstraint = get(context.parent, specConstraint.path)\n }\n\n if (\n curr.flag === 'custom' &&\n customValidationConcurrencyLimiter &&\n !(specConstraint as CustomValidator)?.bypassConcurrencyLimit\n ) {\n const customValidator = specConstraint as CustomValidator\n specConstraint = async (...args: Parameters<CustomValidator>) => {\n await customValidationConcurrencyLimiter.ready()\n try {\n return await customValidator(...args)\n } finally {\n customValidationConcurrencyLimiter.release()\n }\n }\n }\n\n const message = isLocalizedMessages(this._message)\n ? localizeMessage(this._message, context.i18n)\n : this._message\n\n try {\n const result = await validator(specConstraint, value, message, context)\n return convertToValidationMarker(result, this._level, context)\n } catch (err) {\n const errorMessage = `${pathToString(\n context.path,\n )}: Exception occurred while validating value: ${err.message}`\n\n return convertToValidationMarker({message: errorMessage}, 'error', context)\n }\n }),\n )\n\n return results.flat()\n }\n}\n","import {type DocumentId, getPublishedId} from '@sanity/id-utils'\nimport {\n type CustomValidator,\n isKeyedObject,\n isSlug,\n type Path,\n type SlugIsUniqueValidator,\n type SlugParent,\n type SlugSchemaType,\n type SlugValidationContext,\n} from '@sanity/types'\nimport memoize from 'lodash-es/memoize.js'\n\nconst DEFAULT_API_VERSION = '2025-02-19'\n\nconst memoizedWarnOnArraySlug = memoize(warnOnArraySlug)\n\nfunction serializePath(path: Path): string {\n return path.reduce<string>((target, part, i) => {\n const isIndex = typeof part === 'number'\n const isKey = isKeyedObject(part)\n const separator = i === 0 ? '' : '.'\n const add = isIndex || isKey ? '[]' : `${separator}${part}`\n return `${target}${add}`\n }, '')\n}\n\nconst defaultIsUnique: SlugIsUniqueValidator = (slug, context) => {\n const {getClient, document, path, type} = context\n const schemaOptions = type?.options\n\n if (!document) {\n throw new Error(`\\`document\\` was not provided in validation context.`)\n }\n if (!path) {\n throw new Error(`\\`path\\` was not provided in validation context.`)\n }\n\n const disableArrayWarning = schemaOptions?.disableArrayWarning || false\n const docType = document._type\n const atPath = serializePath(path.concat('current'))\n\n if (!disableArrayWarning && atPath.includes('[]') && context.environment === 'studio') {\n memoizedWarnOnArraySlug(serializePath(path))\n }\n\n const constraints = [\n '_type == $docType',\n `!sanity::versionOf($published)`,\n `${atPath} == $slug`,\n ].join(' && ')\n\n return getClient({apiVersion: DEFAULT_API_VERSION})\n .withConfig({perspective: 'raw'})\n .fetch<boolean>(\n `!defined(*[${constraints}][0]._id)`,\n {\n docType,\n published: getPublishedId(document._id as DocumentId),\n slug,\n },\n {tag: 'validation.slug-is-unique'},\n )\n}\n\nfunction warnOnArraySlug(serializedPath: string) {\n console.warn(\n [\n `Slug field at path ${serializedPath} is within an array and cannot be automatically checked for uniqueness`,\n `If you need to check for uniqueness, provide your own \"isUnique\" method`,\n `To disable this message, set \\`disableArrayWarning: true\\` on the slug \\`options\\` field`,\n ].join('\\n'),\n )\n}\n\n/**\n * Validates slugs values by querying for uniqueness from the client.\n *\n * This is a custom rule implementation (e.g. `Rule.custom(slugValidator)`)\n * that's populated in `inferFromSchemaType` when the type name is `slug`\n */\nexport const slugValidator: CustomValidator = async (value, context) => {\n if (!value) {\n return true\n }\n\n const {i18n} = context\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n return i18n.t('validation:slug.not-object')\n }\n\n if (!isSlug(value) || value.current.trim().length === 0) {\n return i18n.t('validation:slug.missing-current')\n }\n\n const options = context?.type?.options as {isUnique?: SlugIsUniqueValidator} | undefined\n const isUnique = options?.isUnique || defaultIsUnique\n\n const slugContext: SlugValidationContext = {\n ...context,\n parent: context.parent as SlugParent,\n type: context.type as SlugSchemaType,\n defaultIsUnique,\n }\n\n const wasUnique = await isUnique(value.current, slugContext)\n if (wasUnique) {\n return true\n }\n\n return i18n.t('validation:slug.not-unique', {slug: value.current})\n}\n","import {\n type Rule,\n type RuleSpec,\n type RuleTypeConstraint,\n type SchemaType,\n type ValidationContext,\n} from '@sanity/types'\nimport isEqual from 'lodash-es/isEqual.js'\n\nimport {Rule as RuleClass} from '../Rule'\nimport {slugValidator} from '../validators/slugValidator'\n\nconst ruleConstraintTypes: {[P in Lowercase<RuleTypeConstraint>]: true} = {\n array: true,\n boolean: true,\n date: true,\n number: true,\n object: true,\n string: true,\n}\n\nconst isRuleConstraint = (typeString: string): typeString is Lowercase<RuleTypeConstraint> =>\n typeString in ruleConstraintTypes\n\nexport function getTypeChain(\n type: SchemaType | undefined,\n visited: Set<SchemaType> = new Set(),\n): SchemaType[] {\n if (!type) return []\n if (visited.has(type)) return []\n\n visited.add(type)\n\n const next = type.type ? getTypeChain(type.type, visited) : []\n return [...next, type]\n}\n\nfunction baseRuleReducer(inputRule: Rule, type: SchemaType) {\n let baseRule = inputRule\n\n if (isRuleConstraint(type.jsonType)) {\n baseRule = baseRule.type(type.jsonType)\n }\n\n const typeOptionsList =\n // if type.options is truthy\n type?.options &&\n // and type.options is an object (non-null from the previous)\n typeof type.options === 'object' &&\n // and if `list` is in options\n 'list' in type.options &&\n // then finally access the list\n type.options.list\n\n if (Array.isArray(typeOptionsList)) {\n baseRule = baseRule.valid(\n typeOptionsList.map((option) => extractValueFromListOption(option, type)),\n )\n }\n\n if (type.name === 'datetime') return baseRule.type('Date')\n if (type.name === 'date') return baseRule.type('Date')\n if (type.name === 'url') return baseRule.uri()\n if (type.name === 'slug') return baseRule.custom(slugValidator, {bypassConcurrencyLimit: true})\n if (type.name === 'reference') return baseRule.reference()\n if (type.name === 'email') return baseRule.email()\n return baseRule\n}\n\nfunction hasValueField(typeDef: SchemaType | undefined): boolean {\n if (!typeDef) return false\n if (!('fields' in typeDef) && typeDef.type) return hasValueField(typeDef.type)\n if (!('fields' in typeDef)) return false\n if (!Array.isArray(typeDef.fields)) return false\n return typeDef.fields.some((field) => field.name === 'value')\n}\n\nfunction extractValueFromListOption(option: unknown, typeDef: SchemaType): unknown {\n // If you define a `list` option with object items, where the item has a `value` field,\n // we don't want to treat that as the value but rather the surrounding object\n // This differs from the case where you have a title/value pair setup for a string/number, for instance\n if (typeDef.jsonType === 'object' && hasValueField(typeDef)) return option\n\n return (option as Record<string, unknown>).value === undefined\n ? option\n : (option as Record<string, unknown>).value\n}\n\nconst isUriSpec = (spec: RuleSpec): spec is Extract<RuleSpec, {flag: 'uri'}> => spec.flag === 'uri'\n\n// A `url` type auto-injects the default `.uri()` onto every array element, so a\n// custom scheme on one element cannot override the default on its siblings (GH #3298).\nfunction omitLeakedDefaultUri(rules: Rule[], typeDef: SchemaType): Rule[] {\n const isUrlType = getTypeChain(typeDef).some((type) => type.name === 'url')\n if (!isUrlType) return rules\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const defaultUri = new RuleClass(typeDef).uri()._rules.find(isUriSpec)?.constraint\n const isDefaultUri = (spec: RuleSpec) => isUriSpec(spec) && isEqual(spec.constraint, defaultUri)\n const isCustomUri = (spec: RuleSpec) => isUriSpec(spec) && !isEqual(spec.constraint, defaultUri)\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const someElementSetsScheme = rules.some((rule) => rule._rules.some(isCustomUri))\n if (!someElementSetsScheme) return rules\n\n return rules.map((rule) => {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n if (!rule._rules.some(isDefaultUri)) return rule\n const cleaned = rule.clone()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n cleaned._rules = rule._rules.filter((spec) => !isDefaultUri(spec))\n return cleaned\n })\n}\n\nexport function normalizeValidationRules(\n typeDef: SchemaType | undefined,\n context?: ValidationContext,\n): Rule[] {\n if (!typeDef) {\n return []\n }\n\n const validation = typeDef.validation\n\n if (Array.isArray(validation)) {\n const rules = validation.flatMap((i) =>\n normalizeValidationRules(\n {\n ...typeDef,\n validation: i,\n },\n context,\n ),\n )\n return omitLeakedDefaultUri(rules, typeDef)\n }\n\n const baseRule =\n // using an object + Object.values to de-dupe the type chain by type name\n Object.values(\n getTypeChain(typeDef).reduce<Record<string, SchemaType>>((acc, type) => {\n acc[type.name] = type\n return acc\n }, {}),\n ).reduce(baseRuleReducer, new RuleClass(typeDef))\n\n if (validation && typeof validation === 'object') {\n return [validation]\n }\n\n if (!validation) {\n return [baseRule]\n }\n\n if (typeof validation === 'function') {\n return normalizeValidationRules(\n {\n ...typeDef,\n validation: validation(baseRule, context),\n },\n context,\n )\n }\n\n return [baseRule]\n}\n","/**\n * Simple requestIdleCallback polyfill\n * Can be removed when all browsers support requestIdleCallback: https://caniuse.com/requestidlecallback\n * @param callback -\n * @param options -\n */\nconst requestIdleCallbackShim: typeof window.requestIdleCallback = function requestIdleCallbackShim(\n callback,\n _options?,\n): number {\n const start = Date.now()\n return globalThis.setTimeout(() => {\n callback({\n didTimeout: false,\n timeRemaining() {\n return Math.max(0, Date.now() - start)\n },\n })\n }, 0) as unknown as number\n}\n\nconst cancelIdleCallbackShim: typeof window.cancelIdleCallback = function cancelIdleCallbackShim(\n handle: number,\n): void {\n return globalThis.clearTimeout(handle)\n}\n\nconst win = typeof window === 'undefined' ? undefined : window\n\nexport const requestIdleCallback = win?.requestIdleCallback || requestIdleCallbackShim\nexport const cancelIdleCallback = win?.cancelIdleCallback || cancelIdleCallbackShim\n","import {type CustomValidator, type ObjectSchemaType} from '@sanity/types'\n\n/**\n * Given a schema type, returns a custom validator used to warn users of unknown\n * fields found in an object.\n */\nexport const unknownFieldsValidator =\n (type: ObjectSchemaType): CustomValidator =>\n (value) => {\n if (typeof value !== 'object') return true\n if (!value) return true\n\n const fieldNames = new Set(type.fields?.map((field) => field.name))\n\n const unknownFields = Object.keys(value)\n .filter((key) => !key.startsWith('_'))\n .filter((key) => !fieldNames.has(key))\n\n return unknownFields.map((unknownField) => ({\n message: `Field '${unknownField}' does not exist on type '${type.name}'`,\n path: [unknownField],\n }))\n }\n","/* oxlint-disable typescript/no-deprecated -- marker and Rule compatibility require legacy internals */\nimport {type SanityClient} from '@sanity/client'\nimport {\n isKeyedObject,\n isTypedObject,\n type CurrentUser,\n type Rule,\n type SanityDocument,\n type Schema,\n type SchemaType,\n type ValidationMarker,\n} from '@sanity/types'\nimport {createClientConcurrencyLimiter} from '@sanity/util/client'\nimport {ConcurrencyLimiter} from '@sanity/util/concurrency-limiter'\nimport flatten from 'lodash-es/flatten.js'\nimport uniqBy from 'lodash-es/uniqBy.js'\nimport {concat, defer, from, lastValueFrom, merge, Observable, of} from 'rxjs'\nimport {catchError, map, mergeAll, mergeMap, switchMap, toArray} from 'rxjs/operators'\n\nimport {getFallbackLocaleSource} from './i18n/fallback'\nimport {type LocaleSource} from './i18n/types'\nimport {resolveConditionalProperty} from './resolveConditionalProperty'\nimport {type ValidationContext} from './types'\nimport {createBatchedGetDocumentExists} from './util/createBatchedGetDocumentExists'\nimport {getTypeChain, normalizeValidationRules} from './util/normalizeValidationRules'\nimport {cancelIdleCallback, requestIdleCallback} from './util/requestIdleCallback'\nimport {typeString} from './util/typeString'\nimport {unknownFieldsValidator} from './validators/unknownFieldsValidator'\n\n// this is the number of requests allowed inflight at once. this is done to prevent\n// the validation library from overwhelming our backend.\n// NOTE: this was upped from 10 to prevent issues where many concurrency\n// `client.fetch` requests would \"clog\" custom validators from finishing due to\n// not enough concurrent requests being fulfilled\n//\n// NOTE: ensure to update the TSDoc and CLI help test if this is changed\nconst DEFAULT_MAX_FETCH_CONCURRENCY = 25\n\n// NOTE: ensure to update the TSDoc and CLI help test if this is changed\nconst DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY = 5\n\nconst DEFAULT_VALIDATION_CLIENT_OPTIONS = {apiVersion: '2025-02-19'} as const\n\nconst isRecord = (maybeRecord: unknown): maybeRecord is Record<string, unknown> =>\n typeof maybeRecord === 'object' && maybeRecord !== null && !Array.isArray(maybeRecord)\n\n/**\n * Recursively extracts all `_fieldRules` from a rule and its nested constraints.\n * This handles cases where `Rule.fields()` is used inside `Rule.all()` or `Rule.either()`.\n */\nfunction extractFieldRulesFromRule(rule: Rule): NonNullable<Rule['_fieldRules']>[] {\n const results: NonNullable<Rule['_fieldRules']>[] = []\n\n // Add direct _fieldRules if present\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n if (rule._fieldRules) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n results.push(rule._fieldRules)\n }\n\n // Check for nested rules in 'all' or 'either' constraints\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n for (const ruleSpec of rule._rules) {\n if (ruleSpec.flag === 'all' || ruleSpec.flag === 'either') {\n const childRules = ruleSpec.constraint\n if (Array.isArray(childRules)) {\n for (const childRule of childRules) {\n results.push(...extractFieldRulesFromRule(childRule))\n }\n }\n }\n }\n\n return results\n}\n\n/**\n * @internal\n */\nexport function resolveTypeForArrayItem(\n item: unknown,\n candidates: SchemaType[],\n): SchemaType | undefined {\n // if there is only one type available, assume that it's the correct one\n if (candidates.length === 1) return candidates[0]\n\n const itemType = isTypedObject(item) && item._type\n const primitive =\n item === undefined || item === null || (!itemType && typeString(item).toLowerCase())\n\n if (primitive && primitive !== 'object') {\n return candidates.find((candidate) => candidate.jsonType === primitive)\n }\n\n return (\n candidates.find((candidate) => candidate.type?.name === itemType) ||\n candidates.find((candidate) => candidate.name === itemType) ||\n candidates.find((candidate) => candidate.name === 'object' && primitive === 'object')\n )\n}\n\n/**\n * @beta\n */\nexport interface ValidateDocumentOptions {\n /**\n * The document to be validated\n */\n document: SanityDocument\n /** The compiled schema to validate against. */\n schema: Schema\n\n /** A configured client used for reference checks and custom validators. */\n client: SanityClient\n\n /**\n * Function used to check if referenced documents exists (and is published).\n *\n * If you're validating many documents in bulk, you may want to query for all\n * document IDs first and provide your own implementation using those.\n *\n * If no function is provided a default one will be provided that will batch\n * call the `doc` endpoint to check for document existence.\n */\n getDocumentExists?: (options: {id: string}) => Promise<boolean>\n\n /**\n * The maximum amount of custom validation functions to be running\n * concurrently at once. This helps prevent custom validators from\n * overwhelming backend services (e.g. called via fetch) used in async,\n * user-defined validation functions. (i.e. `rule.custom(async() => {})`)\n *\n * Note that lowering this number may also help in cases where a custom\n * validator could potentially exhaust the fetch concurrency. This is 5 by\n * default.\n */\n maxCustomValidationConcurrency?: number\n\n /**\n * The amount of allowed inflight fetch requests at once for this validation.\n * You may need to up this value if you have complex custom validations that\n * require many `client.fetch` requests at once. It's possible for a custom\n * validator to stall if there are not enough concurrent fetch requests\n * available to fulfill the custom validation. Must be a positive integer.\n * This is 25 by default.\n */\n maxFetchConcurrency?: number\n\n /**\n * The current user, when available. Used when resolving schema `hidden`\n * conditionals so validation matches what the form shows. If omitted, hidden\n * is resolved with no user (e.g. CLI or headless validation).\n */\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/**\n * The validation capabilities required from a resolved Studio source or workspace.\n *\n * @beta\n */\nexport interface ValidationSource {\n /** The compiled schema to validate against. */\n schema: Schema\n\n /** Factory used to get the client passed to custom validators. */\n getClient: (clientOptions: {apiVersion: string}) => SanityClient\n\n /** Internationalization utilities used for validation messages. */\n i18n: LocaleSource\n}\n\n/**\n * Options accepted by the compatibility overload for Studio workspace validation.\n *\n * @beta\n */\nexport interface ValidateDocumentWorkspaceOptions extends Omit<\n ValidateDocumentOptions,\n 'client' | 'schema'\n> {\n /** The resolved Studio workspace or source used for validation. */\n workspace: ValidationSource\n\n /**\n * Factory used to get the client passed to custom validators.\n *\n * @deprecated For internal use only\n */\n getClient?: ValidationSource['getClient']\n\n /** Validation environment exposed to custom validators. */\n environment?: 'cli' | 'studio'\n}\n\n/**\n * Validates a document against the schema in a resolved Studio workspace or source.\n *\n * @beta\n * @deprecated Prefer {@link validateDocument} with `{document, schema, client}` for new code.\n */\nexport function validateDocumentWithWorkspace({\n document,\n workspace,\n getClient = workspace.getClient,\n getDocumentExists,\n environment = 'studio',\n maxCustomValidationConcurrency,\n maxFetchConcurrency,\n currentUser,\n}: ValidateDocumentWorkspaceOptions): Promise<ValidationMarker[]> {\n return validateDocumentInternal({\n currentUser,\n document,\n environment,\n getClient,\n getDocumentExists,\n i18n: workspace.i18n,\n maxCustomValidationConcurrency,\n maxFetchConcurrency,\n schema: workspace.schema,\n })\n}\n\n/**\n * Validates a document against the schema in a resolved Studio workspace or source.\n *\n * This compatibility overload preserves the existing `sanity` API. Prefer the\n * `{document, schema, client}` overload for new code.\n *\n * @beta\n */\nexport function validateDocument(\n options: ValidateDocumentWorkspaceOptions,\n): Promise<ValidationMarker[]>\n/**\n * Validates a document against a compiled schema. Returns validation markers\n * without deciding whether the document may be edited or published.\n *\n * @beta\n */\nexport function validateDocument(options: ValidateDocumentOptions): Promise<ValidationMarker[]>\nexport function validateDocument(\n options: ValidateDocumentOptions | ValidateDocumentWorkspaceOptions,\n): Promise<ValidationMarker[]> {\n if ('workspace' in options) {\n return validateDocumentWithWorkspace(options)\n }\n\n const {client, document, schema, ...internalOptions} = options\n return validateDocumentInternal({\n ...internalOptions,\n document,\n environment: 'cli',\n getClient: ({apiVersion}) => client.withConfig({apiVersion}),\n i18n: getFallbackLocaleSource(),\n schema,\n })\n}\n\n/** @internal */\nexport interface ValidateDocumentInternalOptions {\n document: SanityDocument\n schema: Schema\n getClient: (clientOptions: {apiVersion: string}) => SanityClient\n getDocumentExists?: (options: {id: string}) => Promise<boolean>\n i18n?: LocaleSource\n environment: 'cli' | 'studio'\n maxCustomValidationConcurrency?: number\n maxFetchConcurrency?: number\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/** @internal */\nexport function validateDocumentInternal({\n document,\n schema,\n getClient,\n getDocumentExists,\n i18n = getFallbackLocaleSource(),\n environment,\n maxCustomValidationConcurrency,\n maxFetchConcurrency,\n currentUser,\n}: ValidateDocumentInternalOptions): Promise<ValidationMarker[]> {\n const limitConcurrency = createClientConcurrencyLimiter(\n maxFetchConcurrency ?? DEFAULT_MAX_FETCH_CONCURRENCY,\n )\n const getConcurrencyLimitedClient = (clientOptions: {apiVersion: string}) =>\n limitConcurrency(getClient(clientOptions))\n\n return lastValueFrom(\n validateDocumentObservable({\n document,\n getClient: getConcurrencyLimitedClient,\n i18n,\n schema,\n getDocumentExists:\n getDocumentExists ||\n createBatchedGetDocumentExists(getClient(DEFAULT_VALIDATION_CLIENT_OPTIONS)),\n environment,\n maxCustomValidationConcurrency,\n currentUser,\n }),\n )\n}\n\n/**\n * @internal\n */\nexport interface ValidateDocumentObservableOptions extends Pick<\n ValidationContext,\n 'getDocumentExists' | 'i18n'\n> {\n getClient: (options: {apiVersion: string}) => SanityClient\n document: SanityDocument\n schema: Schema\n environment: 'cli' | 'studio'\n maxCustomValidationConcurrency?: number\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\nconst customValidationConcurrencyLimiters = new WeakMap<Schema, ConcurrencyLimiter>()\n\n/**\n * Validates a document against the given schema, returning an Observable\n * @internal\n */\nexport function validateDocumentObservable({\n document,\n getClient,\n i18n = getFallbackLocaleSource(),\n schema,\n getDocumentExists,\n environment,\n maxCustomValidationConcurrency,\n currentUser,\n}: ValidateDocumentObservableOptions): Observable<ValidationMarker[]> {\n if (typeof document?._type !== 'string') {\n throw new Error(`Tried to validate a value without a '_type'`)\n }\n\n const documentType = schema.get(document._type)\n\n if (!documentType) {\n if (environment === 'studio') {\n console.warn(\n 'Schema type for object type \"%s\" not found, skipping validation',\n document._type,\n )\n return of([])\n }\n\n return of([\n {\n level: 'warning',\n message: `Could not find schema type for type '${document._type}', skipping validation`,\n path: [],\n },\n ])\n }\n\n let customValidationConcurrencyLimiter = customValidationConcurrencyLimiters.get(schema)\n if (!customValidationConcurrencyLimiter) {\n customValidationConcurrencyLimiter = new ConcurrencyLimiter(\n maxCustomValidationConcurrency ?? DEFAULT_MAX_CUSTOM_VALIDATION_CONCURRENCY,\n )\n customValidationConcurrencyLimiters.set(schema, customValidationConcurrencyLimiter)\n }\n\n const validationOptions: ValidateItemOptions = {\n getClient,\n schema,\n parent: undefined,\n value: document,\n path: [],\n document: document,\n type: documentType,\n i18n,\n getDocumentExists,\n environment,\n customValidationConcurrencyLimiter,\n currentUser,\n }\n\n return from(i18n.loadNamespaces(['validation'])).pipe(\n switchMap(() => validateItemObservable(validationOptions)),\n catchError((err) => {\n console.error(err)\n\n const message = err?.message || 'Unknown error'\n const errorMarker: ValidationMarker = {\n level: 'error',\n message,\n item: {message},\n path: [],\n }\n\n return of([errorMarker])\n }),\n )\n}\n\n/**\n * this is used make optional properties required by replacing optionals with\n * `T[P] | undefined`. this is used to prevent errors in `validateItem` where\n * an option from a previous invocation would be incorrectly passed down.\n *\n * https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585\n */\ntype ExplicitUndefined<T> = {\n [P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : T[P] | undefined\n}\n\ntype ValidateItemOptions = {\n value: unknown\n customValidationConcurrencyLimiter?: ConcurrencyLimiter\n hidden?: boolean\n currentUser?: Omit<CurrentUser, 'role'> | null\n} & ExplicitUndefined<Omit<ValidationContext, 'hidden'>>\n\nexport function validateItem(opts: ValidateItemOptions): Promise<ValidationMarker[]> {\n return lastValueFrom(validateItemObservable(opts))\n}\n\nfunction validateItemObservable({\n value,\n type,\n path = [],\n parent,\n customValidationConcurrencyLimiter,\n environment,\n ...restOfContext\n}: ValidateItemOptions): Observable<ValidationMarker[]> {\n // Track whether any ancestor in the tree is hidden.\n // It will be true if this field OR any ancestor is hidden.\n // This allows validation rules to check `context.hidden` to skip validation for hidden fields,\n // without needing to know whether the field itself or an ancestor caused it to be hidden.\n const ancestorHidden = restOfContext.hidden === true\n const resolveHiddenForType = (\n schemaType: SchemaType | undefined,\n schemaValue: unknown,\n schemaParent: unknown,\n schemaPath: ValidationContext['path'],\n ancestorHiddenValue: boolean,\n ) => {\n // If there is no schema type, fall back to the ancestor's hidden state.\n if (!schemaType) {\n return ancestorHiddenValue\n }\n return (\n ancestorHiddenValue ||\n resolveConditionalProperty(schemaType.hidden, {\n ...restOfContext,\n parent: schemaParent,\n value: schemaValue,\n path: schemaPath || [],\n currentUser: restOfContext.currentUser ?? null,\n })\n )\n }\n const hidden = resolveHiddenForType(type, value, parent, path, ancestorHidden)\n\n // Note: this validator is added here because it's conditional based on the\n // environment.\n const addUnknownFieldsValidator = (rule: Rule) => {\n if (\n // if the schema type is an object type\n type?.jsonType === 'object' &&\n // and if somewhere in it's type chain, it inherits from object or document\n getTypeChain(type).find((t) => ['object', 'document', 'file', 'image'].includes(t.name)) &&\n // and the environment is not the studio\n environment !== 'studio'\n ) {\n // then add the validator for unknown fields\n return rule.custom(unknownFieldsValidator(type), {bypassConcurrencyLimit: true}).warning()\n }\n\n // otherwise, leave it unchanged\n return rule\n }\n\n const rules = normalizeValidationRules(type, {\n ...restOfContext,\n hidden,\n environment,\n parent,\n path,\n type,\n })\n // run validation for the current value\n const selfChecks = rules.map(addUnknownFieldsValidator).map((rule) =>\n defer(() =>\n rule.validate(value, {\n ...restOfContext,\n environment,\n hidden,\n parent,\n path,\n type,\n __internal: {customValidationConcurrencyLimiter},\n }),\n ),\n )\n\n // run validation for nested values (conditionally)\n let nestedChecks: Array<Observable<ValidationMarker[]>> = []\n\n const selfIsRequired = rules.some((rule) => rule.isRequired())\n const shouldRunNestedObjectValidation =\n // run nested validation for objects\n type?.jsonType === 'object' &&\n // if the value is truthy\n (!!value || // or\n // (the value is null or undefined) and the top-level value is required\n ((value === null || value === undefined) && selfIsRequired))\n\n if (shouldRunNestedObjectValidation) {\n const fieldTypes = type.fields.reduce<Record<string, SchemaType>>((acc, field) => {\n acc[field.name] = field.type\n return acc\n }, {})\n\n // Validation for rules set at the object level with `Rule.fields({/* ... */})`\n // Use extractFieldRulesFromRule to handle Rule.fields() inside Rule.all() or Rule.either()\n nestedChecks = nestedChecks.concat(\n rules\n .flatMap((rule) => extractFieldRulesFromRule(rule))\n .flatMap((fieldResults) => Object.entries(fieldResults))\n .flatMap(([name, validation]) => {\n const fieldType = fieldTypes[name]\n return normalizeValidationRules({...fieldType, validation})\n .map(addUnknownFieldsValidator)\n .map((subRule) => {\n const nestedValue = isRecord(value) ? value[name] : undefined\n const nestedHidden = resolveHiddenForType(\n fieldType,\n nestedValue,\n value,\n path.concat(name),\n hidden,\n )\n return defer(() =>\n subRule.validate(nestedValue, {\n ...restOfContext,\n parent: value,\n path: path.concat(name),\n type: fieldType,\n environment,\n hidden: nestedHidden,\n __internal: {customValidationConcurrencyLimiter},\n }),\n )\n })\n }),\n )\n\n // Validation from each field's schema `validation: Rule => {/* ... */}` function\n nestedChecks = nestedChecks.concat(\n type.fields.map((field) =>\n validateItemObservable({\n ...restOfContext,\n hidden,\n parent: value,\n value: isRecord(value) ? value[field.name] : undefined,\n path: path.concat(field.name),\n type: field.type,\n environment,\n customValidationConcurrencyLimiter,\n }),\n ),\n )\n }\n\n // note: unlike objects, arrays should not run nested validation for undefined\n // values because we won't have a valid path to put a marker (i.e. missing the\n // key or index in the path) and the downstream form builder won't have a\n // valid target component\n const shouldRunNestedValidationForArrays = type?.jsonType === 'array' && Array.isArray(value)\n\n if (shouldRunNestedValidationForArrays) {\n nestedChecks = nestedChecks.concat(\n value.map((item, index) =>\n validateItemObservable({\n ...restOfContext,\n hidden,\n parent: value,\n value: item,\n path: path.concat(isKeyedObject(item) ? {_key: item._key} : index),\n type: resolveTypeForArrayItem(item, type.of),\n environment,\n customValidationConcurrencyLimiter,\n }),\n ),\n )\n }\n\n return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(\n mergeMap((validateNode) => concat(idle(), validateNode), 40),\n mergeAll(),\n toArray(),\n map(flatten),\n map((results) => {\n // run `uniqBy` if `_fieldRules` are present because they can\n // cause repeat markers (check recursively for nested rules)\n if (rules.some((rule) => extractFieldRulesFromRule(rule).length > 0)) {\n return uniqBy(results, (rule) => JSON.stringify(rule))\n }\n return results\n }),\n )\n}\n\nfunction idle(timeout?: number): Observable<never> {\n return new Observable<never>((observer) => {\n const handle = requestIdleCallback(\n () => {\n observer.complete()\n },\n timeout ? {timeout} : undefined,\n )\n\n return () => cancelIdleCallback(handle)\n })\n}\n"],"mappings":"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"}
@@ -89,13 +89,61 @@ interface ValidateDocumentOptions {
89
89
  */
90
90
  currentUser?: Omit<CurrentUser, 'role'> | null;
91
91
  }
92
+ /**
93
+ * The validation capabilities required from a resolved Studio source or workspace.
94
+ *
95
+ * @beta
96
+ */
97
+ interface ValidationSource {
98
+ /** The compiled schema to validate against. */
99
+ schema: Schema;
100
+ /** Factory used to get the client passed to custom validators. */
101
+ getClient: (clientOptions: {
102
+ apiVersion: string;
103
+ }) => SanityClient;
104
+ /** Internationalization utilities used for validation messages. */
105
+ i18n: LocaleSource;
106
+ }
107
+ /**
108
+ * Options accepted by the compatibility overload for Studio workspace validation.
109
+ *
110
+ * @beta
111
+ */
112
+ interface ValidateDocumentWorkspaceOptions extends Omit<ValidateDocumentOptions, 'client' | 'schema'> {
113
+ /** The resolved Studio workspace or source used for validation. */
114
+ workspace: ValidationSource;
115
+ /**
116
+ * Factory used to get the client passed to custom validators.
117
+ *
118
+ * @deprecated For internal use only
119
+ */
120
+ getClient?: ValidationSource['getClient'];
121
+ /** Validation environment exposed to custom validators. */
122
+ environment?: 'cli' | 'studio';
123
+ }
124
+ /**
125
+ * Validates a document against the schema in a resolved Studio workspace or source.
126
+ *
127
+ * @beta
128
+ * @deprecated Prefer {@link validateDocument} with `{document, schema, client}` for new code.
129
+ */
130
+ declare function validateDocumentWithWorkspace({ document, workspace, getClient, getDocumentExists, environment, maxCustomValidationConcurrency, maxFetchConcurrency, currentUser }: ValidateDocumentWorkspaceOptions): Promise<ValidationMarker[]>;
131
+ /**
132
+ * Validates a document against the schema in a resolved Studio workspace or source.
133
+ *
134
+ * This compatibility overload preserves the existing `sanity` API. Prefer the
135
+ * `{document, schema, client}` overload for new code.
136
+ *
137
+ * @beta
138
+ */
139
+ declare function validateDocument(options: ValidateDocumentWorkspaceOptions): Promise<ValidationMarker[]>;
92
140
  /**
93
141
  * Validates a document against a compiled schema. Returns validation markers
94
142
  * without deciding whether the document may be edited or published.
95
143
  *
96
144
  * @beta
97
145
  */
98
- declare function validateDocument({ client, document, schema, ...options }: ValidateDocumentOptions): Promise<ValidationMarker[]>;
146
+ declare function validateDocument(options: ValidateDocumentOptions): Promise<ValidationMarker[]>;
99
147
  /** @internal */
100
148
  interface ValidateDocumentInternalOptions {
101
149
  document: SanityDocument;
@@ -147,5 +195,5 @@ type ValidateItemOptions = {
147
195
  currentUser?: Omit<CurrentUser, 'role'> | null;
148
196
  } & ExplicitUndefined<Omit<ValidationContext$1, 'hidden'>>;
149
197
  declare function validateItem(opts: ValidateItemOptions): Promise<ValidationMarker[]>;
150
- export { validateDocument as a, validateItem as c, resolveTypeForArrayItem as i, ValidationContext$1 as l, ValidateDocumentObservableOptions as n, validateDocumentInternal as o, ValidateDocumentOptions as r, validateDocumentObservable as s, ValidateDocumentInternalOptions as t, LocaleSource as u };
151
- //# sourceMappingURL=validateDocument-C6wlQ7gA.d.ts.map
198
+ export { ValidationSource as a, validateDocumentInternal as c, validateItem as d, ValidationContext$1 as f, ValidateDocumentWorkspaceOptions as i, validateDocumentObservable as l, ValidateDocumentObservableOptions as n, resolveTypeForArrayItem as o, LocaleSource as p, ValidateDocumentOptions as r, validateDocument as s, ValidateDocumentInternalOptions as t, validateDocumentWithWorkspace as u };
199
+ //# sourceMappingURL=validateDocument-CBOsd748.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/validation",
3
- "version": "6.12.0-next.32",
3
+ "version": "6.12.0-next.46",
4
4
  "description": "Document validation for Sanity schemas",
5
5
  "keywords": [
6
6
  "cms",
@@ -44,23 +44,23 @@
44
44
  "dependencies": {
45
45
  "@sanity/client": "^8.3.0",
46
46
  "@sanity/id-utils": "^1.0.0",
47
- "i18next": "^26.2.0",
47
+ "@sanity/schema": "6.12.0-next.46+a0ad3951be",
48
+ "@sanity/types": "6.12.0-next.46+a0ad3951be",
49
+ "@sanity/util": "6.12.0-next.46+a0ad3951be",
50
+ "i18next": "^26.4.0",
48
51
  "lodash-es": "^4.18.1",
49
- "rxjs": "^7.8.2",
50
- "@sanity/types": "6.12.0-next.32+51f4486582",
51
- "@sanity/util": "6.12.0-next.32+51f4486582",
52
- "@sanity/schema": "6.12.0-next.32+51f4486582"
52
+ "rxjs": "^7.8.2"
53
53
  },
54
54
  "devDependencies": {
55
+ "@repo/test-config": "6.9.2",
56
+ "@repo/tsconfig": "6.9.2",
57
+ "@repo/tsdown.config": "6.9.2",
55
58
  "@types/lodash-es": "^4.17.12",
56
59
  "@types/react": "^19.2.18",
57
60
  "tsdown": "^0.22.14",
58
61
  "typescript": "^7.0.2",
59
62
  "vite": "^8.2.2",
60
- "vitest": "^4.1.11",
61
- "@repo/test-config": "6.9.2",
62
- "@repo/tsconfig": "6.9.2",
63
- "@repo/tsdown.config": "6.9.2"
63
+ "vitest": "^4.1.11"
64
64
  },
65
65
  "browserslist": [
66
66
  "node >=22.12",