UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

109 lines (85 loc) 3.01 kB
import { isArrayOfBlocksSchemaType, type Path, type PathSegment, type Validators, } from '@sanity/types' import {deepEquals} from '../util/deepEquals' import {genericValidators} from './genericValidator' export const arrayValidators: Validators = { ...genericValidators, min: (minLength, value, message, {i18n, type}) => { if (!value || value.length >= minLength) { return true } const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined return message || i18n.t('validation:array.minimum-length', {minLength, context}) }, max: (maxLength, value, message, {i18n, type}) => { if (!value || value.length <= maxLength) { return true } const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined return message || i18n.t('validation:array.maximum-length', {maxLength, context}) }, length: (wantedLength, value, message, {i18n, type}) => { if (!value || value.length === wantedLength) { return true } const context = isArrayOfBlocksSchemaType(type) ? 'blocks' : undefined return message || i18n.t('validation:array.exact-length', {wantedLength, context}) }, presence: (flag, value, message, {i18n}) => { if (flag === 'required' && !value) { return message || i18n.t('validation:generic.required', {context: 'array'}) } return true }, valid: (allowedValues, values, message, {i18n}) => { const valueType = typeof values if (valueType === 'undefined') { return true } const paths: Path[] = [] for (let i = 0; i < values.length; i++) { const value = values[i] if (allowedValues.some((expected) => deepEquals(expected, value))) { continue } const pathSegment: PathSegment = value && value._key ? {_key: value._key} : i paths.push([pathSegment]) } // we emit the same message for each path we find in this array const sharedMessage = message || i18n.t('validation:generic.not-allowed') return paths.map((path) => ({message: sharedMessage, path})) }, unique: (_unused, value, message, {i18n}) => { const dupeIndices = [] if (!value) { return true } for (let x = 0; x < value.length; x++) { for (let y = x + 1; y < value.length; y++) { const itemA = value[x] const itemB = value[y] if (!deepEquals(itemA, itemB)) { continue } if (dupeIndices.indexOf(x) === -1) { dupeIndices.push(x) } if (dupeIndices.indexOf(y) === -1) { dupeIndices.push(y) } } } const paths = dupeIndices.map((idx) => { const item = value[idx] const pathSegment = item && item._key ? {_key: item._key} : idx return [pathSegment] }) // we emit the same message for each path we find in this array const sharedMessage = message || i18n.t('validation:array.item-duplicate') return paths.map((path) => ({message: sharedMessage, path})) }, }