{"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<TAttribute> = Schema.Attribute.Value<TAttribute>,\n> {\n  attr: TAttribute;\n  model: Struct.Schema;\n  updatedAttribute: {\n    name: string;\n    value: TValue;\n  };\n  data: Record<string, unknown>;\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\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 = <T extends yup.AnySchema>(\n  validator: T,\n  {\n    attr,\n    model,\n    updatedAttribute,\n    entity,\n    componentContext,\n  }: ValidatorMetas<Schema.Attribute.AnyAttribute & Schema.Attribute.UniqueOption>,\n  options: ValidatorOptions\n): T => {\n  if (attr.type !== 'uid' && !attr.unique) {\n    return validator;\n  }\n\n  const validateUniqueFieldWithinComponent = async (value: any): Promise<boolean> => {\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<string, any> = {};\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<boolean> => {\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    /**\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<string, any> = {\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<Schema.Attribute.Email>,\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<Schema.Attribute.UID>,\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<Schema.Attribute.Integer | Schema.Attribute.BigInteger>,\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<Schema.Attribute.Decimal | Schema.Attribute.Float>,\n  options: ValidatorOptions\n) => {\n  let schema = yup.number();\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<Schema.Attribute.BigInteger>,\n  options: ValidatorOptions\n) => {\n  const schema = yup.mixed();\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","addMinLengthValidator","validator","attr","isDraft","minLength","_","isInteger","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","test","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","datesValidator","Validators","text","richtext","password","enumeration","boolean","nullable","json","biginteger","float","decimal","date","time","datetime","timestamp","blocks","blocksValidator"],"mappings":"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"}