{"version":3,"file":"validators.mjs","sources":["../../../src/services/entity-validator/validators.ts"],"sourcesContent":["/**\n * Validators check if the entry data meets specific criteria before saving or publishing.\n * (e.g., length, range, format).\n *\n * Drafts have limited validations (mainly max constraints),\n * while published content undergoes full validation.\n *\n * The system also takes locales into account when validating data.\n * E.g, unique fields must be unique within the same locale.\n */\nimport _ from 'lodash';\nimport { yup } from '@strapi/utils';\nimport type { Schema, Struct, Modules } from '@strapi/types';\nimport { blocksValidator } from './blocks-validator';\n\nimport type { ComponentContext } from '.';\n\nexport interface ValidatorMetas<\n TAttribute extends Schema.Attribute.AnyAttribute = Schema.Attribute.AnyAttribute,\n TValue extends Schema.Attribute.Value = Schema.Attribute.Value,\n> {\n attr: TAttribute;\n model: Struct.Schema;\n updatedAttribute: {\n name: string;\n value: TValue;\n };\n data: Record;\n componentContext?: ComponentContext;\n entity?: Modules.EntityValidator.Entity;\n}\n\ninterface ValidatorOptions {\n isDraft: boolean;\n locale?: string;\n}\n\n/* Validator utils */\n\nconst toNumberSafe = (value: unknown): number | undefined => {\n if (value === undefined || value === null) return undefined;\n const num = Number(value);\n return Number.isFinite(num) ? num : undefined;\n};\n\nconst BIG_INTEGER_REGEX = /^[+-]?\\d+$/;\n\nconst toBigIntegerString = (value: unknown): string | undefined => {\n if (value == null) {\n return undefined;\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || !Number.isInteger(value)) {\n return undefined;\n }\n\n return value.toString();\n }\n\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n\n if (!BIG_INTEGER_REGEX.test(trimmedValue)) {\n return undefined;\n }\n\n return BigInt(trimmedValue).toString();\n }\n\n return undefined;\n};\n\nconst isValidBigInteger = (value: unknown): boolean => toBigIntegerString(value) != null;\n\nconst isValidFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nconst isValidInteger = (value: unknown): value is number =>\n isValidFiniteNumber(value) && Number.isInteger(value);\n\nconst shouldSkipUniqueValidation = (\n attrType: Schema.Attribute.AnyAttribute['type'],\n value: unknown\n): boolean => {\n switch (attrType) {\n case 'integer':\n return !isValidInteger(value);\n case 'float':\n case 'decimal':\n return !isValidFiniteNumber(value);\n case 'biginteger':\n return !isValidBigInteger(value);\n default:\n return false;\n }\n};\n\n/**\n * Adds minLength validator\n */\nconst addMinLengthValidator = (\n validator: yup.StringSchema,\n {\n attr,\n }: {\n attr:\n | Schema.Attribute.String\n | Schema.Attribute.Text\n | Schema.Attribute.RichText\n | Schema.Attribute.Password\n | Schema.Attribute.Email\n | Schema.Attribute.UID;\n },\n { isDraft }: ValidatorOptions\n) => {\n return attr.minLength && _.isInteger(attr.minLength) && !isDraft\n ? validator.min(attr.minLength)\n : validator;\n};\n\n/**\n * Adds maxLength validator\n * @returns {StringSchema}\n */\nconst addMaxLengthValidator = (\n validator: yup.StringSchema,\n {\n attr,\n }: {\n attr:\n | Schema.Attribute.String\n | Schema.Attribute.Text\n | Schema.Attribute.RichText\n | Schema.Attribute.Password\n | Schema.Attribute.Email\n | Schema.Attribute.UID;\n }\n) => {\n return attr.maxLength && _.isInteger(attr.maxLength) ? validator.max(attr.maxLength) : validator;\n};\n\n/**\n * Adds min integer validator\n * @returns {NumberSchema}\n */\nconst addMinIntegerValidator = (\n validator: yup.NumberSchema,\n {\n attr,\n }: {\n attr: Schema.Attribute.Integer | Schema.Attribute.BigInteger;\n },\n { isDraft }: ValidatorOptions\n) => {\n const min = toNumberSafe(attr.min);\n return min !== undefined && !isDraft ? validator.min(_.toInteger(min)) : validator;\n};\n\n/**\n * Adds max integer validator\n */\nconst addMaxIntegerValidator = (\n validator: yup.NumberSchema,\n {\n attr,\n }: {\n attr: Schema.Attribute.Integer | Schema.Attribute.BigInteger;\n }\n) => {\n const max = toNumberSafe(attr.max);\n return max !== undefined ? validator.max(_.toInteger(max)) : validator;\n};\n\n/**\n * Adds min float/decimal validator\n */\nconst addMinFloatValidator = (\n validator: yup.NumberSchema,\n {\n attr,\n }: {\n attr: Schema.Attribute.Decimal | Schema.Attribute.Float;\n },\n { isDraft }: ValidatorOptions\n) => {\n const min = toNumberSafe(attr.min);\n return min !== undefined && !isDraft ? validator.min(min) : validator;\n};\n\n/**\n * Adds max float/decimal validator\n */\nconst addMaxFloatValidator = (\n validator: yup.NumberSchema,\n {\n attr,\n }: {\n attr: Schema.Attribute.Decimal | Schema.Attribute.Float;\n }\n) => {\n const max = toNumberSafe(attr.max);\n return max !== undefined ? validator.max(max) : validator;\n};\n\n/**\n * Adds regex validator\n */\nconst addStringRegexValidator = (\n validator: yup.StringSchema,\n {\n attr,\n }: {\n attr:\n | Schema.Attribute.String\n | Schema.Attribute.Text\n | Schema.Attribute.RichText\n | Schema.Attribute.Password\n | Schema.Attribute.Email\n | Schema.Attribute.UID;\n },\n { isDraft }: ValidatorOptions\n) => {\n return 'regex' in attr && !_.isUndefined(attr.regex) && !isDraft\n ? validator.matches(new RegExp(attr.regex), { excludeEmptyString: !attr.required })\n : validator;\n};\n\nconst addUniqueValidator = (\n validator: T,\n {\n attr,\n model,\n updatedAttribute,\n entity,\n componentContext,\n }: ValidatorMetas,\n options: ValidatorOptions\n): T => {\n if (attr.type !== 'uid' && !attr.unique) {\n return validator;\n }\n\n const validateUniqueFieldWithinComponent = async (value: any): Promise => {\n if (!componentContext) {\n return false;\n }\n\n // If we are validating a unique field within a repeatable component,\n // we first need to ensure that the repeatable in the current entity is\n // valid against itself.\n const hasRepeatableData = componentContext.repeatableData.length > 0;\n if (hasRepeatableData) {\n const { name: updatedName, value: updatedValue } = updatedAttribute;\n // Construct the full path to the unique field within the component.\n const pathToCheck = [...componentContext.pathToComponent.slice(1), updatedName].join('.');\n\n // Extract the values from the repeatable data using the constructed path\n const values = componentContext.repeatableData.map((item) => {\n return pathToCheck.split('.').reduce((acc, key) => acc[key], item as any);\n });\n\n // Check if the value is repeated in the current entity\n const isUpdatedAttributeRepeatedInThisEntity =\n values.filter((value) => value === updatedValue).length > 1;\n\n if (isUpdatedAttributeRepeatedInThisEntity) {\n return false;\n }\n }\n\n /**\n * When `componentContext` is present it means we are dealing with a unique\n * field within a component.\n *\n * The unique validation must consider the specific context of the\n * component, which will always be contained within a parent content type\n * and may also be nested within another component.\n *\n * We construct a query that takes into account the parent's model UID,\n * dimensions (such as draft and publish state/locale) and excludes the current\n * content type entity by its ID if provided.\n */\n const {\n model: parentModel,\n options: parentOptions,\n id: excludeId,\n } = componentContext.parentContent;\n\n const whereConditions: Record = {};\n const isParentDraft = parentOptions && parentOptions.isDraft;\n\n whereConditions.publishedAt = isParentDraft ? null : { $notNull: true };\n\n if (parentOptions?.locale) {\n whereConditions.locale = parentOptions.locale;\n }\n\n if (excludeId && !Number.isNaN(excludeId)) {\n whereConditions.id = { $ne: excludeId };\n }\n\n const queryUid = parentModel.uid;\n const queryWhere = {\n ...componentContext.pathToComponent.reduceRight((acc, key) => ({ [key]: acc }), {\n [updatedAttribute.name]: value,\n }),\n\n ...whereConditions,\n };\n\n // The validation should pass if there is no other record found from the query\n return !(await strapi.db.query(queryUid).findOne({ where: queryWhere }));\n };\n\n const validateUniqueFieldWithinDynamicZoneComponent = async (\n startOfPath: string\n ): Promise => {\n if (!componentContext) {\n return false;\n }\n\n const targetComponentUID = model.uid;\n // Ensure that the value is unique within the dynamic zone in this entity.\n const countOfValueInThisEntity = (componentContext?.fullDynamicZoneContent ?? []).reduce(\n (acc, component) => {\n if (component.__component !== targetComponentUID) {\n return acc;\n }\n\n const updatedValue = component[updatedAttribute.name];\n return updatedValue === updatedAttribute.value ? acc + 1 : acc;\n },\n 0\n );\n\n if (countOfValueInThisEntity > 1) {\n // If the value is repeated in the current entity, the validation fails.\n return false;\n }\n\n // Build a query for the parent content type to find all entities in the\n // same locale and publication state\n type QueryType = {\n select: string[];\n where: {\n published_at?: { $eq: null } | { $ne: null };\n id?: { $ne: number };\n locale?: string;\n };\n populate: {\n [key: string]: {\n on: {\n [key: string]: {\n select: string[];\n where: { [key: string]: string | number | boolean };\n };\n };\n };\n };\n };\n\n // Populate the dynamic zone for any components that share the same value\n // as the updated attribute.\n const query: QueryType = {\n select: ['id'],\n where: {},\n populate: {\n [startOfPath]: {\n on: {\n [targetComponentUID]: {\n select: ['id'],\n where: { [updatedAttribute.name]: updatedAttribute.value },\n },\n },\n },\n },\n };\n\n const { options, id } = componentContext.parentContent;\n\n if (options?.isDraft !== undefined) {\n query.where.published_at = options.isDraft ? { $eq: null } : { $ne: null };\n }\n\n if (id) {\n query.where.id = { $ne: id };\n }\n\n if (options?.locale) {\n query.where.locale = options.locale;\n }\n\n const parentModelQueryResult = await strapi.db\n .query(componentContext.parentContent.model.uid)\n .findMany(query);\n\n // Filter the results to only include results that have components in the\n // dynamic zone that match the target component type.\n const filteredResults = parentModelQueryResult\n .filter((result) => Array.isArray(result[startOfPath]) && result[startOfPath].length)\n .flatMap((result) => result[startOfPath])\n .filter((dynamicZoneComponent) => dynamicZoneComponent.__component === targetComponentUID);\n\n if (filteredResults.length >= 1) {\n return false;\n }\n\n return true;\n };\n\n return validator.test('unique', 'This attribute must be unique', async (value) => {\n /**\n * If the attribute value is `null` or an empty string we want to skip the unique validation.\n * Otherwise it'll only accept a single entry with that value in the database.\n */\n if (_.isNil(value) || value === '') {\n return true;\n }\n\n // Skip unique checks for invalid scalar numeric values and let the type validator fail.\n // This prevents malformed values from reaching the DB query layer when abortEarly=false.\n if (shouldSkipUniqueValidation(attr.type, value)) {\n return true;\n }\n\n /**\n * We don't validate any unique constraint for draft entries.\n */\n if (options.isDraft) {\n return true;\n }\n\n const hasPathToComponent = componentContext && componentContext.pathToComponent.length > 0;\n if (hasPathToComponent) {\n // Detect if we are validating within a dynamiczone by checking if the first\n // path is a dynamiczone attribute in the parent content type.\n const startOfPath = componentContext.pathToComponent[0];\n const testingDZ =\n componentContext.parentContent.model.attributes[startOfPath].type === 'dynamiczone';\n\n if (testingDZ) {\n return validateUniqueFieldWithinDynamicZoneComponent(startOfPath);\n }\n\n return validateUniqueFieldWithinComponent(value);\n }\n\n /**\n * Here we are validating a scalar unique field from the content type's schema.\n * We construct a query to check if the value is unique\n * considering dimensions (e.g. locale, publication state) and excluding the current entity by its ID if available.\n */\n const scalarAttributeWhere: Record = {\n [updatedAttribute.name]: value,\n publishedAt: { $notNull: true },\n };\n\n if (options?.locale) {\n scalarAttributeWhere.locale = options.locale;\n }\n\n if (entity?.id) {\n scalarAttributeWhere.id = { $ne: entity.id };\n }\n\n // The validation should pass if there is no other record found from the query\n return !(await strapi.db\n .query(model.uid)\n .findOne({ where: scalarAttributeWhere, select: ['id'] }));\n });\n};\n\n/* Type validators */\n\nconst stringValidator = (\n metas: ValidatorMetas<\n | Schema.Attribute.String\n | Schema.Attribute.Text\n | Schema.Attribute.RichText\n | Schema.Attribute.Password\n | Schema.Attribute.Email\n | Schema.Attribute.UID\n >,\n options: ValidatorOptions\n) => {\n let schema = yup.string().transform((val, originalVal) => originalVal);\n\n schema = addMinLengthValidator(schema, metas, options);\n schema = addMaxLengthValidator(schema, metas);\n schema = addStringRegexValidator(schema, metas, options);\n schema = addUniqueValidator(schema, metas, options);\n\n return schema;\n};\n\nexport const emailValidator = (\n metas: ValidatorMetas,\n options: ValidatorOptions\n) => {\n const schema = stringValidator(metas, options);\n\n if (options.isDraft) {\n return schema;\n }\n\n return schema.email().min(\n 1,\n // eslint-disable-next-line no-template-curly-in-string\n '${path} cannot be empty'\n );\n};\n\nexport const uidValidator = (\n metas: ValidatorMetas,\n options: ValidatorOptions\n) => {\n const schema = stringValidator(metas, options);\n\n if (options.isDraft) {\n return schema;\n }\n\n if (metas.attr.regex) {\n return schema.matches(new RegExp(metas.attr.regex));\n }\n\n return schema.matches(/^[A-Za-z0-9-_.~]*$/);\n};\n\nexport const enumerationValidator = ({ attr }: { attr: Schema.Attribute.Enumeration }) => {\n return yup\n .string()\n .oneOf((Array.isArray(attr.enum) ? attr.enum : [attr.enum]).concat(null as any));\n};\n\nexport const integerValidator = (\n metas: ValidatorMetas,\n options: ValidatorOptions\n) => {\n let schema = yup.number().integer();\n\n schema = addMinIntegerValidator(schema, metas, options);\n schema = addMaxIntegerValidator(schema, metas);\n schema = addUniqueValidator(schema, metas, options);\n\n return schema;\n};\n\nexport const floatValidator = (\n metas: ValidatorMetas,\n options: ValidatorOptions\n) => {\n let schema = yup.number().test(\n 'is-finite-number',\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolates validation path placeholders.\n '${path} must be a finite number',\n (value) => value == null || isValidFiniteNumber(value)\n );\n\n schema = addMinFloatValidator(schema, metas, options);\n schema = addMaxFloatValidator(schema, metas);\n schema = addUniqueValidator(schema, metas, options);\n\n return schema;\n};\n\nexport const bigintegerValidator = (\n metas: ValidatorMetas,\n options: ValidatorOptions\n) => {\n const schema = yup\n .mixed()\n .transform((value, originalValue) => toBigIntegerString(originalValue) ?? value)\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolates validation path placeholders.\n .test('is-biginteger', '${path} must be a valid integer', (value) => {\n if (value == null) {\n return true;\n }\n\n return isValidBigInteger(value);\n });\n\n return addUniqueValidator(schema, metas, options);\n};\n\nexport const datesValidator = (\n metas: ValidatorMetas<\n | Schema.Attribute.Date\n | Schema.Attribute.DateTime\n | Schema.Attribute.Time\n | Schema.Attribute.Timestamp\n >,\n options: ValidatorOptions\n) => {\n const schema = yup.mixed();\n return addUniqueValidator(schema, metas, options);\n};\n\nexport const Validators = {\n string: stringValidator,\n text: stringValidator,\n richtext: stringValidator,\n password: stringValidator,\n email: emailValidator,\n enumeration: enumerationValidator,\n boolean: () => yup.boolean().nullable(),\n uid: uidValidator,\n json: () => yup.mixed(),\n integer: integerValidator,\n biginteger: bigintegerValidator,\n float: floatValidator,\n decimal: floatValidator,\n date: datesValidator,\n time: datesValidator,\n datetime: datesValidator,\n timestamp: datesValidator,\n blocks: blocksValidator,\n};\n"],"names":["toNumberSafe","value","undefined","num","Number","isFinite","BIG_INTEGER_REGEX","toBigIntegerString","toString","isInteger","trimmedValue","trim","test","BigInt","isValidBigInteger","isValidFiniteNumber","isValidInteger","shouldSkipUniqueValidation","attrType","addMinLengthValidator","validator","attr","isDraft","minLength","_","min","addMaxLengthValidator","maxLength","max","addMinIntegerValidator","toInteger","addMaxIntegerValidator","addMinFloatValidator","addMaxFloatValidator","addStringRegexValidator","isUndefined","regex","matches","RegExp","excludeEmptyString","required","addUniqueValidator","model","updatedAttribute","entity","componentContext","options","type","unique","validateUniqueFieldWithinComponent","hasRepeatableData","repeatableData","length","name","updatedName","updatedValue","pathToCheck","pathToComponent","slice","join","values","map","item","split","reduce","acc","key","isUpdatedAttributeRepeatedInThisEntity","filter","parentModel","parentOptions","id","excludeId","parentContent","whereConditions","isParentDraft","publishedAt","$notNull","locale","isNaN","$ne","queryUid","uid","queryWhere","reduceRight","strapi","db","query","findOne","where","validateUniqueFieldWithinDynamicZoneComponent","startOfPath","targetComponentUID","countOfValueInThisEntity","fullDynamicZoneContent","component","__component","select","populate","on","published_at","$eq","parentModelQueryResult","findMany","filteredResults","result","Array","isArray","flatMap","dynamicZoneComponent","isNil","hasPathToComponent","testingDZ","attributes","scalarAttributeWhere","stringValidator","metas","schema","yup","string","transform","val","originalVal","emailValidator","email","uidValidator","enumerationValidator","oneOf","enum","concat","integerValidator","number","integer","floatValidator","bigintegerValidator","mixed","originalValue","datesValidator","Validators","text","richtext","password","enumeration","boolean","nullable","json","biginteger","float","decimal","date","time","datetime","timestamp","blocks","blocksValidator"],"mappings":"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"}