@strapi/content-manager 5.31.3 → 5.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/ConfigurationForm/Fields.js +74 -14
- package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.mjs +75 -15
- package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
- package/dist/admin/hooks/useDocument.js +0 -1
- package/dist/admin/hooks/useDocument.js.map +1 -1
- package/dist/admin/hooks/useDocument.mjs +0 -1
- package/dist/admin/hooks/useDocument.mjs.map +1 -1
- package/dist/admin/hooks/useDocumentActions.js +0 -1
- package/dist/admin/hooks/useDocumentActions.js.map +1 -1
- package/dist/admin/hooks/useDocumentActions.mjs +0 -1
- package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +16 -4
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs +17 -6
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs.map +1 -1
- package/dist/admin/pages/EditView/utils/data.js +3 -11
- package/dist/admin/pages/EditView/utils/data.js.map +1 -1
- package/dist/admin/pages/EditView/utils/data.mjs +3 -11
- package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +0 -1
- package/dist/admin/src/hooks/useDocumentActions.d.ts +0 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.d.ts +7 -2
- package/dist/admin/utils/validation.js +1 -1
- package/dist/admin/utils/validation.js.map +1 -1
- package/dist/admin/utils/validation.mjs +1 -1
- package/dist/admin/utils/validation.mjs.map +1 -1
- package/dist/server/services/document-metadata.js +17 -4
- package/dist/server/services/document-metadata.js.map +1 -1
- package/dist/server/services/document-metadata.mjs +17 -4
- package/dist/server/services/document-metadata.mjs.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sources":["../../../admin/src/utils/validation.ts"],"sourcesContent":["import { translatedErrors } from '@strapi/admin/strapi-admin';\nimport pipe from 'lodash/fp/pipe';\nimport * as yup from 'yup';\n\nimport { DOCUMENT_META_FIELDS } from '../constants/attributes';\n\nimport type { ComponentsDictionary, Schema } from '../hooks/useDocument';\nimport type { Schema as SchemaUtils } from '@strapi/types';\nimport type { ObjectShape } from 'yup/lib/object';\n\ntype AnySchema =\n | yup.StringSchema\n | yup.NumberSchema\n | yup.BooleanSchema\n | yup.DateSchema\n | yup.ArraySchema<any>\n | yup.ObjectSchema<any>;\n\n/* -------------------------------------------------------------------------------------------------\n * createYupSchema\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ValidationOptions {\n status: 'draft' | 'published' | null;\n removedAttributes?: string[];\n}\n\nconst arrayValidator = (attribute: Schema['attributes'][string], options: ValidationOptions) => ({\n message: translatedErrors.required,\n test(value: unknown) {\n if (options.status === 'draft') {\n return true;\n }\n\n if (!attribute.required) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n\n return true;\n },\n});\nconst escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n/**\n * TODO: should we create a Map to store these based on the hash of the schema?\n */\nconst createYupSchema = (\n attributes: Schema['attributes'] = {},\n components: ComponentsDictionary = {},\n options: ValidationOptions = { status: null }\n): yup.ObjectSchema<any> => {\n const createModelSchema = (\n attributes: Schema['attributes'],\n removedAttributes: string[] = []\n ): yup.ObjectSchema<any> =>\n yup\n .object()\n .shape(\n Object.entries(attributes).reduce<ObjectShape>((acc, [name, attribute]) => {\n const getNestedPathsForAttribute = (removed: string[], attrName: string): string[] => {\n const prefix = `${attrName}.`;\n const bracketRegex = new RegExp(`^${escapeRegex(attrName)}\\\\[\\\\d+\\\\]\\\\.`);\n\n return removed\n .filter((p) => p.startsWith(prefix) || bracketRegex.test(p))\n .map((p) =>\n p.startsWith(prefix) ? p.slice(prefix.length) : p.replace(bracketRegex, '')\n );\n };\n\n if (DOCUMENT_META_FIELDS.includes(name)) {\n return acc;\n }\n\n if (removedAttributes?.includes(name)) {\n // If the attribute is not visible, we don't want to validate it\n return acc;\n }\n\n const nestedRemoved = getNestedPathsForAttribute(removedAttributes, name);\n\n /**\n * These validations won't apply to every attribute\n * and that's okay, in that case we just return the\n * schema as it was passed.\n */\n const validations = [\n addNullableValidation,\n addRequiredValidation,\n addMinLengthValidation,\n addMaxLengthValidation,\n addMinValidation,\n addMaxValidation,\n addRegexValidation,\n ].map((fn) => fn(attribute, options));\n\n const transformSchema = pipe(...validations);\n\n switch (attribute.type) {\n case 'component': {\n const { attributes } = components[attribute.component];\n\n if (attribute.repeatable) {\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(createModelSchema(attributes, nestedRemoved).nullable(false))\n ).test(arrayValidator(attribute, options)),\n };\n } else {\n return {\n ...acc,\n [name]: transformSchema(createModelSchema(attributes, nestedRemoved).nullable()),\n };\n }\n }\n case 'dynamiczone':\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(\n yup.lazy(\n (\n data: SchemaUtils.Attribute.Value<SchemaUtils.Attribute.DynamicZone>[number]\n ) => {\n const attributes = components?.[data?.__component]?.attributes;\n\n const validation = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(components)),\n })\n .nullable(false);\n if (!attributes) {\n return validation;\n }\n\n return validation.concat(createModelSchema(attributes, nestedRemoved));\n }\n ) as unknown as yup.ObjectSchema<any>\n )\n ).test(arrayValidator(attribute, options)),\n };\n case 'relation':\n return {\n ...acc,\n [name]: transformSchema(\n yup.lazy((value) => {\n if (!value) {\n return yup.mixed().nullable(true);\n } else if (Array.isArray(value)) {\n // If a relation value is an array, we expect\n // an array of objects with {id} properties, representing the related entities.\n return yup.array().of(\n yup.object().shape({\n id: yup.number().required(),\n })\n );\n } else if (typeof value === 'object') {\n // A realtion value can also be an object. Some API\n // repsonses return the number of entities in the relation\n // as { count: x }\n return yup.object();\n } else {\n return yup\n .mixed()\n .test(\n 'type-error',\n 'Relation values must be either null, an array of objects with {id} or an object.',\n () => false\n );\n }\n })\n ),\n };\n default:\n return {\n ...acc,\n [name]: transformSchema(createAttributeSchema(attribute)),\n };\n }\n }, {})\n )\n /**\n * TODO: investigate why an undefined object fails a check of `nullable`.\n */\n .default(null);\n\n return createModelSchema(attributes, options.removedAttributes);\n};\n\nconst createAttributeSchema = (\n attribute: Exclude<\n SchemaUtils.Attribute.AnyAttribute,\n { type: 'dynamiczone' } | { type: 'component' } | { type: 'relation' }\n >\n) => {\n switch (attribute.type) {\n case 'biginteger':\n return yup.string().matches(/^-?\\d*$/);\n case 'boolean':\n return yup.boolean();\n case 'blocks':\n return yup.mixed().test('isBlocks', translatedErrors.json, (value) => {\n if (!value || Array.isArray(value)) {\n return true;\n } else {\n return false;\n }\n });\n case 'decimal':\n case 'float':\n case 'integer':\n return yup.number();\n case 'email':\n return yup.string().email(translatedErrors.email);\n case 'enumeration':\n return yup.string().oneOf([...attribute.enum, null]);\n case 'json':\n return yup.mixed().test('isJSON', translatedErrors.json, (value) => {\n /**\n * We don't want to validate the JSON field if it's empty.\n */\n if (!value || (typeof value === 'string' && value.length === 0)) {\n return true;\n }\n\n // If the value was created via content API and wasn't changed, then it's still an object\n if (typeof value === 'object') {\n try {\n JSON.stringify(value);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n try {\n JSON.parse(value);\n\n return true;\n } catch (err) {\n return false;\n }\n });\n case 'password':\n return yup.string().nullable();\n case 'richtext':\n case 'string':\n case 'text':\n return yup.string();\n case 'uid':\n return yup\n .string()\n .matches(attribute.regex ? new RegExp(attribute.regex) : /^[A-Za-z0-9-_.~]*$/);\n default:\n /**\n * This allows any value.\n */\n return yup.mixed();\n }\n};\n\n// Helper function to return schema.nullable() if it exists, otherwise return schema\nconst nullableSchema = <TSchema extends AnySchema>(schema: TSchema) => {\n return schema?.nullable\n ? schema.nullable()\n : // In some cases '.nullable' will not be available on the schema.\n // e.g. when the schema has been built using yup.lazy (e.g. for relations).\n // In these cases we should just return the schema as it is.\n schema;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validators\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Our validator functions can be preped with the\n * attribute and then have the schema piped through them.\n */\ntype ValidationFn = (\n attribute: Schema['attributes'][string],\n options: ValidationOptions\n) => <TSchema extends AnySchema>(schema: TSchema) => TSchema;\n\nconst addNullableValidation: ValidationFn = () => (schema) => {\n return nullableSchema(schema);\n};\n\nconst addRequiredValidation: ValidationFn = (attribute, options) => (schema) => {\n if (options.status === 'draft' || !attribute.required || attribute.type === 'password') {\n return schema;\n }\n\n if (attribute.required && 'required' in schema) {\n return schema.required(translatedErrors.required);\n }\n\n return schema;\n};\n\nconst addMinLengthValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // Skip minLength validation for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if (\n 'minLength' in attribute &&\n attribute.minLength &&\n Number.isInteger(attribute.minLength) &&\n 'min' in schema\n ) {\n return schema.min(attribute.minLength, {\n ...translatedErrors.minLength,\n values: {\n min: attribute.minLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMaxLengthValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if (\n 'maxLength' in attribute &&\n attribute.maxLength &&\n Number.isInteger(attribute.maxLength) &&\n 'max' in schema\n ) {\n return schema.max(attribute.maxLength, {\n ...translatedErrors.maxLength,\n values: {\n max: attribute.maxLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMinValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // do not validate min for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if ('min' in attribute && 'min' in schema) {\n const min = toInteger(attribute.min);\n\n if (min) {\n return schema.min(min, {\n ...translatedErrors.min,\n values: {\n min,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst addMaxValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('max' in attribute) {\n const max = toInteger(attribute.max);\n\n if ('max' in schema && max) {\n return schema.max(max, {\n ...translatedErrors.max,\n values: {\n max,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst toInteger = (val?: string | number): number | undefined => {\n if (typeof val === 'number' || val === undefined) {\n return val;\n } else {\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n }\n};\n\nconst addRegexValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('regex' in attribute && attribute.regex && 'matches' in schema) {\n return schema.matches(new RegExp(attribute.regex), {\n message: {\n id: translatedErrors.regex.id,\n defaultMessage: 'The value does not match the defined pattern.',\n },\n\n excludeEmptyString: !attribute.required,\n }) as TSchema;\n }\n\n return schema;\n };\n\nexport { createYupSchema };\n"],"names":["arrayValidator","attribute","options","message","translatedErrors","required","test","value","status","Array","isArray","length","escapeRegex","str","replace","createYupSchema","attributes","components","createModelSchema","removedAttributes","yup","object","shape","Object","entries","reduce","acc","name","getNestedPathsForAttribute","removed","attrName","prefix","bracketRegex","RegExp","filter","p","startsWith","map","slice","DOCUMENT_META_FIELDS","includes","nestedRemoved","validations","addNullableValidation","addRequiredValidation","addMinLengthValidation","addMaxLengthValidation","addMinValidation","addMaxValidation","addRegexValidation","fn","transformSchema","pipe","type","component","repeatable","array","of","nullable","lazy","data","__component","validation","string","oneOf","keys","concat","mixed","id","number","createAttributeSchema","default","matches","boolean","json","email","enum","JSON","stringify","err","parse","regex","nullableSchema","schema","minLength","Number","isInteger","min","values","maxLength","max","toInteger","val","undefined","num","isNaN","defaultMessage","excludeEmptyString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.js","sources":["../../../admin/src/utils/validation.ts"],"sourcesContent":["import { translatedErrors } from '@strapi/admin/strapi-admin';\nimport pipe from 'lodash/fp/pipe';\nimport * as yup from 'yup';\n\nimport { DOCUMENT_META_FIELDS } from '../constants/attributes';\n\nimport type { ComponentsDictionary, Schema } from '../hooks/useDocument';\nimport type { Schema as SchemaUtils } from '@strapi/types';\nimport type { ObjectShape } from 'yup/lib/object';\n\ntype AnySchema =\n | yup.StringSchema\n | yup.NumberSchema\n | yup.BooleanSchema\n | yup.DateSchema\n | yup.ArraySchema<any>\n | yup.ObjectSchema<any>;\n\n/* -------------------------------------------------------------------------------------------------\n * createYupSchema\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ValidationOptions {\n status: 'draft' | 'published' | null;\n removedAttributes?: string[];\n}\n\nconst arrayValidator = (attribute: Schema['attributes'][string], options: ValidationOptions) => ({\n message: translatedErrors.required,\n test(value: unknown) {\n if (options.status === 'draft') {\n return true;\n }\n\n if (!attribute.required) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n\n return true;\n },\n});\nconst escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n/**\n * TODO: should we create a Map to store these based on the hash of the schema?\n */\nconst createYupSchema = (\n attributes: Schema['attributes'] = {},\n components: ComponentsDictionary = {},\n options: ValidationOptions = { status: null }\n): yup.ObjectSchema<any> => {\n const createModelSchema = (\n attributes: Schema['attributes'],\n removedAttributes: string[] = []\n ): yup.ObjectSchema<any> =>\n yup\n .object()\n .shape(\n Object.entries(attributes).reduce<ObjectShape>((acc, [name, attribute]) => {\n const getNestedPathsForAttribute = (removed: string[], attrName: string): string[] => {\n const prefix = `${attrName}.`;\n const bracketRegex = new RegExp(`^${escapeRegex(attrName)}\\\\[\\\\d+\\\\]\\\\.`);\n\n return removed\n .filter((p) => p.startsWith(prefix) || bracketRegex.test(p))\n .map((p) =>\n p.startsWith(prefix) ? p.slice(prefix.length) : p.replace(bracketRegex, '')\n );\n };\n\n if (DOCUMENT_META_FIELDS.includes(name)) {\n return acc;\n }\n\n if (removedAttributes?.includes(name)) {\n // If the attribute is not visible, we don't want to validate it\n return acc;\n }\n\n const nestedRemoved = getNestedPathsForAttribute(removedAttributes, name);\n\n /**\n * These validations won't apply to every attribute\n * and that's okay, in that case we just return the\n * schema as it was passed.\n */\n const validations = [\n addNullableValidation,\n addRequiredValidation,\n addMinLengthValidation,\n addMaxLengthValidation,\n addMinValidation,\n addMaxValidation,\n addRegexValidation,\n ].map((fn) => fn(attribute, options));\n\n const transformSchema = pipe(...validations);\n\n switch (attribute.type) {\n case 'component': {\n const { attributes } = components[attribute.component];\n\n if (attribute.repeatable) {\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(createModelSchema(attributes, nestedRemoved).nullable(false))\n ).test(arrayValidator(attribute, options)),\n };\n } else {\n return {\n ...acc,\n [name]: transformSchema(createModelSchema(attributes, nestedRemoved).nullable()),\n };\n }\n }\n case 'dynamiczone':\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(\n yup.lazy(\n (\n data: SchemaUtils.Attribute.Value<SchemaUtils.Attribute.DynamicZone>[number]\n ) => {\n const attributes = components?.[data?.__component]?.attributes;\n\n const validation = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(components)),\n })\n .nullable(false);\n if (!attributes) {\n return validation;\n }\n\n return validation.concat(createModelSchema(attributes, nestedRemoved));\n }\n ) as unknown as yup.ObjectSchema<any>\n )\n ).test(arrayValidator(attribute, options)),\n };\n case 'relation':\n return {\n ...acc,\n [name]: transformSchema(\n yup.lazy((value) => {\n if (!value) {\n return yup.mixed().nullable(true);\n } else if (Array.isArray(value)) {\n // If a relation value is an array, we expect\n // an array of objects with {id} properties, representing the related entities.\n return yup.array().of(\n yup.object().shape({\n id: yup.number().required(),\n })\n );\n } else if (typeof value === 'object') {\n // A realtion value can also be an object. Some API\n // repsonses return the number of entities in the relation\n // as { count: x }\n return yup.object();\n } else {\n return yup\n .mixed()\n .test(\n 'type-error',\n 'Relation values must be either null, an array of objects with {id} or an object.',\n () => false\n );\n }\n })\n ),\n };\n default:\n return {\n ...acc,\n [name]: transformSchema(createAttributeSchema(attribute)),\n };\n }\n }, {})\n )\n /**\n * TODO: investigate why an undefined object fails a check of `nullable`.\n */\n .default(null);\n\n return createModelSchema(attributes, options.removedAttributes);\n};\n\nconst createAttributeSchema = (\n attribute: Exclude<\n SchemaUtils.Attribute.AnyAttribute,\n { type: 'dynamiczone' } | { type: 'component' } | { type: 'relation' }\n >\n) => {\n switch (attribute.type) {\n case 'biginteger':\n return yup.string().matches(/^-?\\d*$/);\n case 'boolean':\n return yup.boolean().nullable();\n case 'blocks':\n return yup.mixed().test('isBlocks', translatedErrors.json, (value) => {\n if (!value || Array.isArray(value)) {\n return true;\n } else {\n return false;\n }\n });\n case 'decimal':\n case 'float':\n case 'integer':\n return yup.number();\n case 'email':\n return yup.string().email(translatedErrors.email);\n case 'enumeration':\n return yup.string().oneOf([...attribute.enum, null]);\n case 'json':\n return yup.mixed().test('isJSON', translatedErrors.json, (value) => {\n /**\n * We don't want to validate the JSON field if it's empty.\n */\n if (!value || (typeof value === 'string' && value.length === 0)) {\n return true;\n }\n\n // If the value was created via content API and wasn't changed, then it's still an object\n if (typeof value === 'object') {\n try {\n JSON.stringify(value);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n try {\n JSON.parse(value);\n\n return true;\n } catch (err) {\n return false;\n }\n });\n case 'password':\n return yup.string().nullable();\n case 'richtext':\n case 'string':\n case 'text':\n return yup.string();\n case 'uid':\n return yup\n .string()\n .matches(attribute.regex ? new RegExp(attribute.regex) : /^[A-Za-z0-9-_.~]*$/);\n default:\n /**\n * This allows any value.\n */\n return yup.mixed();\n }\n};\n\n// Helper function to return schema.nullable() if it exists, otherwise return schema\nconst nullableSchema = <TSchema extends AnySchema>(schema: TSchema) => {\n return schema?.nullable\n ? schema.nullable()\n : // In some cases '.nullable' will not be available on the schema.\n // e.g. when the schema has been built using yup.lazy (e.g. for relations).\n // In these cases we should just return the schema as it is.\n schema;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validators\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Our validator functions can be preped with the\n * attribute and then have the schema piped through them.\n */\ntype ValidationFn = (\n attribute: Schema['attributes'][string],\n options: ValidationOptions\n) => <TSchema extends AnySchema>(schema: TSchema) => TSchema;\n\nconst addNullableValidation: ValidationFn = () => (schema) => {\n return nullableSchema(schema);\n};\n\nconst addRequiredValidation: ValidationFn = (attribute, options) => (schema) => {\n if (options.status === 'draft' || !attribute.required || attribute.type === 'password') {\n return schema;\n }\n\n if (attribute.required && 'required' in schema) {\n return schema.required(translatedErrors.required);\n }\n\n return schema;\n};\n\nconst addMinLengthValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // Skip minLength validation for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if (\n 'minLength' in attribute &&\n attribute.minLength &&\n Number.isInteger(attribute.minLength) &&\n 'min' in schema\n ) {\n return schema.min(attribute.minLength, {\n ...translatedErrors.minLength,\n values: {\n min: attribute.minLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMaxLengthValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if (\n 'maxLength' in attribute &&\n attribute.maxLength &&\n Number.isInteger(attribute.maxLength) &&\n 'max' in schema\n ) {\n return schema.max(attribute.maxLength, {\n ...translatedErrors.maxLength,\n values: {\n max: attribute.maxLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMinValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // do not validate min for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if ('min' in attribute && 'min' in schema) {\n const min = toInteger(attribute.min);\n\n if (min) {\n return schema.min(min, {\n ...translatedErrors.min,\n values: {\n min,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst addMaxValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('max' in attribute) {\n const max = toInteger(attribute.max);\n\n if ('max' in schema && max) {\n return schema.max(max, {\n ...translatedErrors.max,\n values: {\n max,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst toInteger = (val?: string | number): number | undefined => {\n if (typeof val === 'number' || val === undefined) {\n return val;\n } else {\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n }\n};\n\nconst addRegexValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('regex' in attribute && attribute.regex && 'matches' in schema) {\n return schema.matches(new RegExp(attribute.regex), {\n message: {\n id: translatedErrors.regex.id,\n defaultMessage: 'The value does not match the defined pattern.',\n },\n\n excludeEmptyString: !attribute.required,\n }) as TSchema;\n }\n\n return schema;\n };\n\nexport { createYupSchema };\n"],"names":["arrayValidator","attribute","options","message","translatedErrors","required","test","value","status","Array","isArray","length","escapeRegex","str","replace","createYupSchema","attributes","components","createModelSchema","removedAttributes","yup","object","shape","Object","entries","reduce","acc","name","getNestedPathsForAttribute","removed","attrName","prefix","bracketRegex","RegExp","filter","p","startsWith","map","slice","DOCUMENT_META_FIELDS","includes","nestedRemoved","validations","addNullableValidation","addRequiredValidation","addMinLengthValidation","addMaxLengthValidation","addMinValidation","addMaxValidation","addRegexValidation","fn","transformSchema","pipe","type","component","repeatable","array","of","nullable","lazy","data","__component","validation","string","oneOf","keys","concat","mixed","id","number","createAttributeSchema","default","matches","boolean","json","email","enum","JSON","stringify","err","parse","regex","nullableSchema","schema","minLength","Number","isInteger","min","values","maxLength","max","toInteger","val","undefined","num","isNaN","defaultMessage","excludeEmptyString"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAMA,cAAiB,GAAA,CAACC,SAAyCC,EAAAA,OAAAA,IAAgC;AAC/FC,QAAAA,OAAAA,EAASC,6BAAiBC,QAAQ;AAClCC,QAAAA,IAAAA,CAAAA,CAAKC,KAAc,EAAA;YACjB,IAAIL,OAAAA,CAAQM,MAAM,KAAK,OAAS,EAAA;gBAC9B,OAAO,IAAA;AACT;YAEA,IAAI,CAACP,SAAUI,CAAAA,QAAQ,EAAE;gBACvB,OAAO,IAAA;AACT;AAEA,YAAA,IAAI,CAACE,KAAO,EAAA;gBACV,OAAO,KAAA;AACT;AAEA,YAAA,IAAIE,MAAMC,OAAO,CAACH,UAAUA,KAAMI,CAAAA,MAAM,KAAK,CAAG,EAAA;gBAC9C,OAAO,KAAA;AACT;YAEA,OAAO,IAAA;AACT;KACF,CAAA;AACA,MAAMC,cAAc,CAACC,GAAAA,GAAgBA,GAAIC,CAAAA,OAAO,CAAC,qBAAuB,EAAA,MAAA,CAAA;AACxE;;IAGA,MAAMC,eAAkB,GAAA,CACtBC,YAAmC,GAAA,EAAE,EACrCC,UAAmC,GAAA,EAAE,EACrCf,OAA6B,GAAA;IAAEM,MAAQ,EAAA;AAAK,CAAC,GAAA;IAE7C,MAAMU,iBAAAA,GAAoB,CACxBF,YACAG,EAAAA,iBAAAA,GAA8B,EAAE,GAEhCC,cAAAA,CACGC,MAAM,EACNC,CAAAA,KAAK,CACJC,MAAOC,CAAAA,OAAO,CAACR,YAAYS,CAAAA,CAAAA,MAAM,CAAc,CAACC,GAAAA,EAAK,CAACC,IAAAA,EAAM1B,SAAU,CAAA,GAAA;YACpE,MAAM2B,0BAAAA,GAA6B,CAACC,OAAmBC,EAAAA,QAAAA,GAAAA;AACrD,gBAAA,MAAMC,MAAS,GAAA,CAAA,EAAGD,QAAS,CAAA,CAAC,CAAC;gBAC7B,MAAME,YAAAA,GAAe,IAAIC,MAAO,CAAA,CAAC,CAAC,EAAErB,WAAAA,CAAYkB,QAAU,CAAA,CAAA,aAAa,CAAC,CAAA;AAExE,gBAAA,OAAOD,OACJK,CAAAA,MAAM,CAAC,CAACC,CAAMA,GAAAA,CAAAA,CAAEC,UAAU,CAACL,MAAWC,CAAAA,IAAAA,YAAAA,CAAa1B,IAAI,CAAC6B,IACxDE,GAAG,CAAC,CAACF,CAAAA,GACJA,CAAEC,CAAAA,UAAU,CAACL,MAAAA,CAAAA,GAAUI,CAAEG,CAAAA,KAAK,CAACP,MAAAA,CAAOpB,MAAM,CAAA,GAAIwB,CAAErB,CAAAA,OAAO,CAACkB,YAAc,EAAA,EAAA,CAAA,CAAA;AAE9E,aAAA;YAEA,IAAIO,+BAAAA,CAAqBC,QAAQ,CAACb,IAAO,CAAA,EAAA;gBACvC,OAAOD,GAAAA;AACT;YAEA,IAAIP,iBAAAA,EAAmBqB,SAASb,IAAO,CAAA,EAAA;;gBAErC,OAAOD,GAAAA;AACT;YAEA,MAAMe,aAAAA,GAAgBb,2BAA2BT,iBAAmBQ,EAAAA,IAAAA,CAAAA;AAEpE;;;;AAIC,cACD,MAAMe,WAAc,GAAA;AAClBC,gBAAAA,qBAAAA;AACAC,gBAAAA,qBAAAA;AACAC,gBAAAA,sBAAAA;AACAC,gBAAAA,sBAAAA;AACAC,gBAAAA,gBAAAA;AACAC,gBAAAA,gBAAAA;AACAC,gBAAAA;AACD,aAAA,CAACZ,GAAG,CAAC,CAACa,EAAAA,GAAOA,GAAGjD,SAAWC,EAAAA,OAAAA,CAAAA,CAAAA;AAE5B,YAAA,MAAMiD,kBAAkBC,IAAQV,CAAAA,GAAAA,WAAAA,CAAAA;AAEhC,YAAA,OAAQzC,UAAUoD,IAAI;gBACpB,KAAK,WAAA;AAAa,oBAAA;wBAChB,MAAM,EAAErC,UAAU,EAAE,GAAGC,UAAU,CAAChB,SAAAA,CAAUqD,SAAS,CAAC;wBAEtD,IAAIrD,SAAAA,CAAUsD,UAAU,EAAE;4BACxB,OAAO;AACL,gCAAA,GAAG7B,GAAG;AACN,gCAAA,CAACC,OAAOwB,eAAAA,CACN/B,cAAIoC,CAAAA,KAAK,GAAGC,EAAE,CAACvC,iBAAkBF,CAAAA,UAAAA,EAAYyB,eAAeiB,QAAQ,CAAC,SACrEpD,IAAI,CAACN,eAAeC,SAAWC,EAAAA,OAAAA,CAAAA;AACnC,6BAAA;yBACK,MAAA;4BACL,OAAO;AACL,gCAAA,GAAGwB,GAAG;AACN,gCAAA,CAACC,OAAOwB,eAAAA,CAAgBjC,iBAAkBF,CAAAA,UAAAA,EAAYyB,eAAeiB,QAAQ,EAAA;AAC/E,6BAAA;AACF;AACF;gBACA,KAAK,aAAA;oBACH,OAAO;AACL,wBAAA,GAAGhC,GAAG;wBACN,CAACC,IAAAA,GAAOwB,eAAAA,CACN/B,cAAIoC,CAAAA,KAAK,EAAGC,CAAAA,EAAE,CACZrC,cAAAA,CAAIuC,IAAI,CACN,CACEC,IAAAA,GAAAA;AAEA,4BAAA,MAAM5C,UAAaC,GAAAA,UAAAA,GAAa2C,IAAAA,EAAMC,YAAY,EAAE7C,UAAAA;AAEpD,4BAAA,MAAM8C,UAAa1C,GAAAA,cAAAA,CAChBC,MAAM,EAAA,CACNC,KAAK,CAAC;gCACLuC,WAAazC,EAAAA,cAAAA,CAAI2C,MAAM,EAAG1D,CAAAA,QAAQ,GAAG2D,KAAK,CAACzC,MAAO0C,CAAAA,IAAI,CAAChD,UAAAA,CAAAA;AACzD,6BAAA,CAAA,CACCyC,QAAQ,CAAC,KAAA,CAAA;AACZ,4BAAA,IAAI,CAAC1C,UAAY,EAAA;gCACf,OAAO8C,UAAAA;AACT;AAEA,4BAAA,OAAOA,UAAWI,CAAAA,MAAM,CAAChD,iBAAAA,CAAkBF,UAAYyB,EAAAA,aAAAA,CAAAA,CAAAA;yBAI7DnC,CAAAA,CAAAA,CAAAA,CAAAA,IAAI,CAACN,cAAAA,CAAeC,SAAWC,EAAAA,OAAAA,CAAAA;AACnC,qBAAA;gBACF,KAAK,UAAA;oBACH,OAAO;AACL,wBAAA,GAAGwB,GAAG;AACN,wBAAA,CAACC,OAAOwB,eAAAA,CACN/B,cAAIuC,CAAAA,IAAI,CAAC,CAACpD,KAAAA,GAAAA;AACR,4BAAA,IAAI,CAACA,KAAO,EAAA;AACV,gCAAA,OAAOa,cAAI+C,CAAAA,KAAK,EAAGT,CAAAA,QAAQ,CAAC,IAAA,CAAA;AAC9B,6BAAA,MAAO,IAAIjD,KAAAA,CAAMC,OAAO,CAACH,KAAQ,CAAA,EAAA;;;gCAG/B,OAAOa,cAAAA,CAAIoC,KAAK,EAAGC,CAAAA,EAAE,CACnBrC,cAAIC,CAAAA,MAAM,EAAGC,CAAAA,KAAK,CAAC;oCACjB8C,EAAIhD,EAAAA,cAAAA,CAAIiD,MAAM,EAAA,CAAGhE,QAAQ;AAC3B,iCAAA,CAAA,CAAA;6BAEG,MAAA,IAAI,OAAOE,KAAAA,KAAU,QAAU,EAAA;;;;AAIpC,gCAAA,OAAOa,eAAIC,MAAM,EAAA;6BACZ,MAAA;AACL,gCAAA,OAAOD,eACJ+C,KAAK,EAAA,CACL7D,IAAI,CACH,YAAA,EACA,oFACA,IAAM,KAAA,CAAA;AAEZ;AACF,yBAAA,CAAA;AAEJ,qBAAA;AACF,gBAAA;oBACE,OAAO;AACL,wBAAA,GAAGoB,GAAG;wBACN,CAACC,IAAAA,GAAOwB,eAAAA,CAAgBmB,qBAAsBrE,CAAAA,SAAAA,CAAAA;AAChD,qBAAA;AACJ;AACF,SAAA,EAAG,EAEL,CAAA,CAAA;;AAEC,WACAsE,OAAO,CAAC,IAAA,CAAA;IAEb,OAAOrD,iBAAAA,CAAkBF,YAAYd,EAAAA,OAAAA,CAAQiB,iBAAiB,CAAA;AAChE;AAEA,MAAMmD,wBAAwB,CAC5BrE,SAAAA,GAAAA;AAKA,IAAA,OAAQA,UAAUoD,IAAI;QACpB,KAAK,YAAA;AACH,YAAA,OAAOjC,cAAI2C,CAAAA,MAAM,EAAGS,CAAAA,OAAO,CAAC,SAAA,CAAA;QAC9B,KAAK,SAAA;YACH,OAAOpD,cAAAA,CAAIqD,OAAO,EAAA,CAAGf,QAAQ,EAAA;QAC/B,KAAK,QAAA;YACH,OAAOtC,cAAAA,CAAI+C,KAAK,EAAG7D,CAAAA,IAAI,CAAC,UAAYF,EAAAA,4BAAAA,CAAiBsE,IAAI,EAAE,CAACnE,KAAAA,GAAAA;AAC1D,gBAAA,IAAI,CAACA,KAAAA,IAASE,KAAMC,CAAAA,OAAO,CAACH,KAAQ,CAAA,EAAA;oBAClC,OAAO,IAAA;iBACF,MAAA;oBACL,OAAO,KAAA;AACT;AACF,aAAA,CAAA;QACF,KAAK,SAAA;QACL,KAAK,OAAA;QACL,KAAK,SAAA;AACH,YAAA,OAAOa,eAAIiD,MAAM,EAAA;QACnB,KAAK,OAAA;AACH,YAAA,OAAOjD,eAAI2C,MAAM,EAAA,CAAGY,KAAK,CAACvE,6BAAiBuE,KAAK,CAAA;QAClD,KAAK,aAAA;AACH,YAAA,OAAOvD,cAAI2C,CAAAA,MAAM,EAAGC,CAAAA,KAAK,CAAC;AAAI/D,gBAAAA,GAAAA,SAAAA,CAAU2E,IAAI;AAAE,gBAAA;AAAK,aAAA,CAAA;QACrD,KAAK,MAAA;YACH,OAAOxD,cAAAA,CAAI+C,KAAK,EAAG7D,CAAAA,IAAI,CAAC,QAAUF,EAAAA,4BAAAA,CAAiBsE,IAAI,EAAE,CAACnE,KAAAA,GAAAA;AACxD;;YAGA,IAAI,CAACA,KAAU,IAAA,OAAOA,UAAU,QAAYA,IAAAA,KAAAA,CAAMI,MAAM,KAAK,CAAI,EAAA;oBAC/D,OAAO,IAAA;AACT;;gBAGA,IAAI,OAAOJ,UAAU,QAAU,EAAA;oBAC7B,IAAI;AACFsE,wBAAAA,IAAAA,CAAKC,SAAS,CAACvE,KAAAA,CAAAA;wBACf,OAAO,IAAA;AACT,qBAAA,CAAE,OAAOwE,GAAK,EAAA;wBACZ,OAAO,KAAA;AACT;AACF;gBAEA,IAAI;AACFF,oBAAAA,IAAAA,CAAKG,KAAK,CAACzE,KAAAA,CAAAA;oBAEX,OAAO,IAAA;AACT,iBAAA,CAAE,OAAOwE,GAAK,EAAA;oBACZ,OAAO,KAAA;AACT;AACF,aAAA,CAAA;QACF,KAAK,UAAA;YACH,OAAO3D,cAAAA,CAAI2C,MAAM,EAAA,CAAGL,QAAQ,EAAA;QAC9B,KAAK,UAAA;QACL,KAAK,QAAA;QACL,KAAK,MAAA;AACH,YAAA,OAAOtC,eAAI2C,MAAM,EAAA;QACnB,KAAK,KAAA;AACH,YAAA,OAAO3C,cACJ2C,CAAAA,MAAM,EACNS,CAAAA,OAAO,CAACvE,SAAAA,CAAUgF,KAAK,GAAG,IAAIhD,MAAAA,CAAOhC,SAAUgF,CAAAA,KAAK,CAAI,GAAA,oBAAA,CAAA;AAC7D,QAAA;AACE;;UAGA,OAAO7D,eAAI+C,KAAK,EAAA;AACpB;AACF,CAAA;AAEA;AACA,MAAMe,iBAAiB,CAA4BC,MAAAA,GAAAA;AACjD,IAAA,OAAOA,MAAQzB,EAAAA,QAAAA,GACXyB,MAAOzB,CAAAA,QAAQ;;AAIfyB,IAAAA,MAAAA;AACN,CAAA;AAcA,MAAMxC,qBAAAA,GAAsC,IAAM,CAACwC,MAAAA,GAAAA;AACjD,QAAA,OAAOD,cAAeC,CAAAA,MAAAA,CAAAA;AACxB,KAAA;AAEA,MAAMvC,qBAAsC,GAAA,CAAC3C,SAAWC,EAAAA,OAAAA,GAAY,CAACiF,MAAAA,GAAAA;QACnE,IAAIjF,OAAAA,CAAQM,MAAM,KAAK,OAAW,IAAA,CAACP,SAAUI,CAAAA,QAAQ,IAAIJ,SAAAA,CAAUoD,IAAI,KAAK,UAAY,EAAA;YACtF,OAAO8B,MAAAA;AACT;AAEA,QAAA,IAAIlF,SAAUI,CAAAA,QAAQ,IAAI,UAAA,IAAc8E,MAAQ,EAAA;AAC9C,YAAA,OAAOA,MAAO9E,CAAAA,QAAQ,CAACD,4BAAAA,CAAiBC,QAAQ,CAAA;AAClD;QAEA,OAAO8E,MAAAA;AACT,KAAA;AAEA,MAAMtC,sBACJ,GAAA,CAAC5C,SAAWC,EAAAA,OAAAA,GACZ,CAA4BiF,MAAAA,GAAAA;;QAE1B,IAAIjF,OAAAA,CAAQM,MAAM,KAAK,OAAS,EAAA;YAC9B,OAAO2E,MAAAA;AACT;AAEA,QAAA,IACE,WAAelF,IAAAA,SAAAA,IACfA,SAAUmF,CAAAA,SAAS,IACnBC,MAAAA,CAAOC,SAAS,CAACrF,SAAUmF,CAAAA,SAAS,CACpC,IAAA,KAAA,IAASD,MACT,EAAA;AACA,YAAA,OAAOA,MAAOI,CAAAA,GAAG,CAACtF,SAAAA,CAAUmF,SAAS,EAAE;AACrC,gBAAA,GAAGhF,6BAAiBgF,SAAS;gBAC7BI,MAAQ,EAAA;AACND,oBAAAA,GAAAA,EAAKtF,UAAUmF;AACjB;AACF,aAAA,CAAA;AACF;QAEA,OAAOD,MAAAA;AACT,KAAA;AAEF,MAAMrC,sBAAAA,GACJ,CAAC7C,SAAAA,GACD,CAA4BkF,MAAAA,GAAAA;AAC1B,QAAA,IACE,WAAelF,IAAAA,SAAAA,IACfA,SAAUwF,CAAAA,SAAS,IACnBJ,MAAAA,CAAOC,SAAS,CAACrF,SAAUwF,CAAAA,SAAS,CACpC,IAAA,KAAA,IAASN,MACT,EAAA;AACA,YAAA,OAAOA,MAAOO,CAAAA,GAAG,CAACzF,SAAAA,CAAUwF,SAAS,EAAE;AACrC,gBAAA,GAAGrF,6BAAiBqF,SAAS;gBAC7BD,MAAQ,EAAA;AACNE,oBAAAA,GAAAA,EAAKzF,UAAUwF;AACjB;AACF,aAAA,CAAA;AACF;QAEA,OAAON,MAAAA;AACT,KAAA;AAEF,MAAMpC,gBACJ,GAAA,CAAC9C,SAAWC,EAAAA,OAAAA,GACZ,CAA4BiF,MAAAA,GAAAA;;QAE1B,IAAIjF,OAAAA,CAAQM,MAAM,KAAK,OAAS,EAAA;YAC9B,OAAO2E,MAAAA;AACT;QAEA,IAAI,KAAA,IAASlF,SAAa,IAAA,KAAA,IAASkF,MAAQ,EAAA;YACzC,MAAMI,GAAAA,GAAMI,SAAU1F,CAAAA,SAAAA,CAAUsF,GAAG,CAAA;AAEnC,YAAA,IAAIA,GAAK,EAAA;gBACP,OAAOJ,MAAAA,CAAOI,GAAG,CAACA,GAAK,EAAA;AACrB,oBAAA,GAAGnF,6BAAiBmF,GAAG;oBACvBC,MAAQ,EAAA;AACND,wBAAAA;AACF;AACF,iBAAA,CAAA;AACF;AACF;QAEA,OAAOJ,MAAAA;AACT,KAAA;AAEF,MAAMnC,gBAAAA,GACJ,CAAC/C,SAAAA,GACD,CAA4BkF,MAAAA,GAAAA;AAC1B,QAAA,IAAI,SAASlF,SAAW,EAAA;YACtB,MAAMyF,GAAAA,GAAMC,SAAU1F,CAAAA,SAAAA,CAAUyF,GAAG,CAAA;YAEnC,IAAI,KAAA,IAASP,UAAUO,GAAK,EAAA;gBAC1B,OAAOP,MAAAA,CAAOO,GAAG,CAACA,GAAK,EAAA;AACrB,oBAAA,GAAGtF,6BAAiBsF,GAAG;oBACvBF,MAAQ,EAAA;AACNE,wBAAAA;AACF;AACF,iBAAA,CAAA;AACF;AACF;QAEA,OAAOP,MAAAA;AACT,KAAA;AAEF,MAAMQ,YAAY,CAACC,GAAAA,GAAAA;AACjB,IAAA,IAAI,OAAOA,GAAAA,KAAQ,QAAYA,IAAAA,GAAAA,KAAQC,SAAW,EAAA;QAChD,OAAOD,GAAAA;KACF,MAAA;AACL,QAAA,MAAME,MAAMT,MAAOO,CAAAA,GAAAA,CAAAA;QACnB,OAAOG,KAAAA,CAAMD,OAAOD,SAAYC,GAAAA,GAAAA;AAClC;AACF,CAAA;AAEA,MAAM7C,kBAAAA,GACJ,CAAChD,SAAAA,GACD,CAA4BkF,MAAAA,GAAAA;AAC1B,QAAA,IAAI,WAAWlF,SAAaA,IAAAA,SAAAA,CAAUgF,KAAK,IAAI,aAAaE,MAAQ,EAAA;AAClE,YAAA,OAAOA,OAAOX,OAAO,CAAC,IAAIvC,MAAOhC,CAAAA,SAAAA,CAAUgF,KAAK,CAAG,EAAA;gBACjD9E,OAAS,EAAA;oBACPiE,EAAIhE,EAAAA,4BAAAA,CAAiB6E,KAAK,CAACb,EAAE;oBAC7B4B,cAAgB,EAAA;AAClB,iBAAA;gBAEAC,kBAAoB,EAAA,CAAChG,UAAUI;AACjC,aAAA,CAAA;AACF;QAEA,OAAO8E,MAAAA;AACT,KAAA;;;;"}
|
|
@@ -123,7 +123,7 @@ const createAttributeSchema = (attribute)=>{
|
|
|
123
123
|
case 'biginteger':
|
|
124
124
|
return yup.string().matches(/^-?\d*$/);
|
|
125
125
|
case 'boolean':
|
|
126
|
-
return yup.boolean();
|
|
126
|
+
return yup.boolean().nullable();
|
|
127
127
|
case 'blocks':
|
|
128
128
|
return yup.mixed().test('isBlocks', translatedErrors.json, (value)=>{
|
|
129
129
|
if (!value || Array.isArray(value)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.mjs","sources":["../../../admin/src/utils/validation.ts"],"sourcesContent":["import { translatedErrors } from '@strapi/admin/strapi-admin';\nimport pipe from 'lodash/fp/pipe';\nimport * as yup from 'yup';\n\nimport { DOCUMENT_META_FIELDS } from '../constants/attributes';\n\nimport type { ComponentsDictionary, Schema } from '../hooks/useDocument';\nimport type { Schema as SchemaUtils } from '@strapi/types';\nimport type { ObjectShape } from 'yup/lib/object';\n\ntype AnySchema =\n | yup.StringSchema\n | yup.NumberSchema\n | yup.BooleanSchema\n | yup.DateSchema\n | yup.ArraySchema<any>\n | yup.ObjectSchema<any>;\n\n/* -------------------------------------------------------------------------------------------------\n * createYupSchema\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ValidationOptions {\n status: 'draft' | 'published' | null;\n removedAttributes?: string[];\n}\n\nconst arrayValidator = (attribute: Schema['attributes'][string], options: ValidationOptions) => ({\n message: translatedErrors.required,\n test(value: unknown) {\n if (options.status === 'draft') {\n return true;\n }\n\n if (!attribute.required) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n\n return true;\n },\n});\nconst escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n/**\n * TODO: should we create a Map to store these based on the hash of the schema?\n */\nconst createYupSchema = (\n attributes: Schema['attributes'] = {},\n components: ComponentsDictionary = {},\n options: ValidationOptions = { status: null }\n): yup.ObjectSchema<any> => {\n const createModelSchema = (\n attributes: Schema['attributes'],\n removedAttributes: string[] = []\n ): yup.ObjectSchema<any> =>\n yup\n .object()\n .shape(\n Object.entries(attributes).reduce<ObjectShape>((acc, [name, attribute]) => {\n const getNestedPathsForAttribute = (removed: string[], attrName: string): string[] => {\n const prefix = `${attrName}.`;\n const bracketRegex = new RegExp(`^${escapeRegex(attrName)}\\\\[\\\\d+\\\\]\\\\.`);\n\n return removed\n .filter((p) => p.startsWith(prefix) || bracketRegex.test(p))\n .map((p) =>\n p.startsWith(prefix) ? p.slice(prefix.length) : p.replace(bracketRegex, '')\n );\n };\n\n if (DOCUMENT_META_FIELDS.includes(name)) {\n return acc;\n }\n\n if (removedAttributes?.includes(name)) {\n // If the attribute is not visible, we don't want to validate it\n return acc;\n }\n\n const nestedRemoved = getNestedPathsForAttribute(removedAttributes, name);\n\n /**\n * These validations won't apply to every attribute\n * and that's okay, in that case we just return the\n * schema as it was passed.\n */\n const validations = [\n addNullableValidation,\n addRequiredValidation,\n addMinLengthValidation,\n addMaxLengthValidation,\n addMinValidation,\n addMaxValidation,\n addRegexValidation,\n ].map((fn) => fn(attribute, options));\n\n const transformSchema = pipe(...validations);\n\n switch (attribute.type) {\n case 'component': {\n const { attributes } = components[attribute.component];\n\n if (attribute.repeatable) {\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(createModelSchema(attributes, nestedRemoved).nullable(false))\n ).test(arrayValidator(attribute, options)),\n };\n } else {\n return {\n ...acc,\n [name]: transformSchema(createModelSchema(attributes, nestedRemoved).nullable()),\n };\n }\n }\n case 'dynamiczone':\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(\n yup.lazy(\n (\n data: SchemaUtils.Attribute.Value<SchemaUtils.Attribute.DynamicZone>[number]\n ) => {\n const attributes = components?.[data?.__component]?.attributes;\n\n const validation = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(components)),\n })\n .nullable(false);\n if (!attributes) {\n return validation;\n }\n\n return validation.concat(createModelSchema(attributes, nestedRemoved));\n }\n ) as unknown as yup.ObjectSchema<any>\n )\n ).test(arrayValidator(attribute, options)),\n };\n case 'relation':\n return {\n ...acc,\n [name]: transformSchema(\n yup.lazy((value) => {\n if (!value) {\n return yup.mixed().nullable(true);\n } else if (Array.isArray(value)) {\n // If a relation value is an array, we expect\n // an array of objects with {id} properties, representing the related entities.\n return yup.array().of(\n yup.object().shape({\n id: yup.number().required(),\n })\n );\n } else if (typeof value === 'object') {\n // A realtion value can also be an object. Some API\n // repsonses return the number of entities in the relation\n // as { count: x }\n return yup.object();\n } else {\n return yup\n .mixed()\n .test(\n 'type-error',\n 'Relation values must be either null, an array of objects with {id} or an object.',\n () => false\n );\n }\n })\n ),\n };\n default:\n return {\n ...acc,\n [name]: transformSchema(createAttributeSchema(attribute)),\n };\n }\n }, {})\n )\n /**\n * TODO: investigate why an undefined object fails a check of `nullable`.\n */\n .default(null);\n\n return createModelSchema(attributes, options.removedAttributes);\n};\n\nconst createAttributeSchema = (\n attribute: Exclude<\n SchemaUtils.Attribute.AnyAttribute,\n { type: 'dynamiczone' } | { type: 'component' } | { type: 'relation' }\n >\n) => {\n switch (attribute.type) {\n case 'biginteger':\n return yup.string().matches(/^-?\\d*$/);\n case 'boolean':\n return yup.boolean();\n case 'blocks':\n return yup.mixed().test('isBlocks', translatedErrors.json, (value) => {\n if (!value || Array.isArray(value)) {\n return true;\n } else {\n return false;\n }\n });\n case 'decimal':\n case 'float':\n case 'integer':\n return yup.number();\n case 'email':\n return yup.string().email(translatedErrors.email);\n case 'enumeration':\n return yup.string().oneOf([...attribute.enum, null]);\n case 'json':\n return yup.mixed().test('isJSON', translatedErrors.json, (value) => {\n /**\n * We don't want to validate the JSON field if it's empty.\n */\n if (!value || (typeof value === 'string' && value.length === 0)) {\n return true;\n }\n\n // If the value was created via content API and wasn't changed, then it's still an object\n if (typeof value === 'object') {\n try {\n JSON.stringify(value);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n try {\n JSON.parse(value);\n\n return true;\n } catch (err) {\n return false;\n }\n });\n case 'password':\n return yup.string().nullable();\n case 'richtext':\n case 'string':\n case 'text':\n return yup.string();\n case 'uid':\n return yup\n .string()\n .matches(attribute.regex ? new RegExp(attribute.regex) : /^[A-Za-z0-9-_.~]*$/);\n default:\n /**\n * This allows any value.\n */\n return yup.mixed();\n }\n};\n\n// Helper function to return schema.nullable() if it exists, otherwise return schema\nconst nullableSchema = <TSchema extends AnySchema>(schema: TSchema) => {\n return schema?.nullable\n ? schema.nullable()\n : // In some cases '.nullable' will not be available on the schema.\n // e.g. when the schema has been built using yup.lazy (e.g. for relations).\n // In these cases we should just return the schema as it is.\n schema;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validators\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Our validator functions can be preped with the\n * attribute and then have the schema piped through them.\n */\ntype ValidationFn = (\n attribute: Schema['attributes'][string],\n options: ValidationOptions\n) => <TSchema extends AnySchema>(schema: TSchema) => TSchema;\n\nconst addNullableValidation: ValidationFn = () => (schema) => {\n return nullableSchema(schema);\n};\n\nconst addRequiredValidation: ValidationFn = (attribute, options) => (schema) => {\n if (options.status === 'draft' || !attribute.required || attribute.type === 'password') {\n return schema;\n }\n\n if (attribute.required && 'required' in schema) {\n return schema.required(translatedErrors.required);\n }\n\n return schema;\n};\n\nconst addMinLengthValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // Skip minLength validation for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if (\n 'minLength' in attribute &&\n attribute.minLength &&\n Number.isInteger(attribute.minLength) &&\n 'min' in schema\n ) {\n return schema.min(attribute.minLength, {\n ...translatedErrors.minLength,\n values: {\n min: attribute.minLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMaxLengthValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if (\n 'maxLength' in attribute &&\n attribute.maxLength &&\n Number.isInteger(attribute.maxLength) &&\n 'max' in schema\n ) {\n return schema.max(attribute.maxLength, {\n ...translatedErrors.maxLength,\n values: {\n max: attribute.maxLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMinValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // do not validate min for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if ('min' in attribute && 'min' in schema) {\n const min = toInteger(attribute.min);\n\n if (min) {\n return schema.min(min, {\n ...translatedErrors.min,\n values: {\n min,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst addMaxValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('max' in attribute) {\n const max = toInteger(attribute.max);\n\n if ('max' in schema && max) {\n return schema.max(max, {\n ...translatedErrors.max,\n values: {\n max,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst toInteger = (val?: string | number): number | undefined => {\n if (typeof val === 'number' || val === undefined) {\n return val;\n } else {\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n }\n};\n\nconst addRegexValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('regex' in attribute && attribute.regex && 'matches' in schema) {\n return schema.matches(new RegExp(attribute.regex), {\n message: {\n id: translatedErrors.regex.id,\n defaultMessage: 'The value does not match the defined pattern.',\n },\n\n excludeEmptyString: !attribute.required,\n }) as TSchema;\n }\n\n return schema;\n };\n\nexport { createYupSchema };\n"],"names":["arrayValidator","attribute","options","message","translatedErrors","required","test","value","status","Array","isArray","length","escapeRegex","str","replace","createYupSchema","attributes","components","createModelSchema","removedAttributes","yup","object","shape","Object","entries","reduce","acc","name","getNestedPathsForAttribute","removed","attrName","prefix","bracketRegex","RegExp","filter","p","startsWith","map","slice","DOCUMENT_META_FIELDS","includes","nestedRemoved","validations","addNullableValidation","addRequiredValidation","addMinLengthValidation","addMaxLengthValidation","addMinValidation","addMaxValidation","addRegexValidation","fn","transformSchema","pipe","type","component","repeatable","array","of","nullable","lazy","data","__component","validation","string","oneOf","keys","concat","mixed","id","number","createAttributeSchema","default","matches","boolean","json","email","enum","JSON","stringify","err","parse","regex","nullableSchema","schema","minLength","Number","isInteger","min","values","maxLength","max","toInteger","val","undefined","num","isNaN","defaultMessage","excludeEmptyString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.mjs","sources":["../../../admin/src/utils/validation.ts"],"sourcesContent":["import { translatedErrors } from '@strapi/admin/strapi-admin';\nimport pipe from 'lodash/fp/pipe';\nimport * as yup from 'yup';\n\nimport { DOCUMENT_META_FIELDS } from '../constants/attributes';\n\nimport type { ComponentsDictionary, Schema } from '../hooks/useDocument';\nimport type { Schema as SchemaUtils } from '@strapi/types';\nimport type { ObjectShape } from 'yup/lib/object';\n\ntype AnySchema =\n | yup.StringSchema\n | yup.NumberSchema\n | yup.BooleanSchema\n | yup.DateSchema\n | yup.ArraySchema<any>\n | yup.ObjectSchema<any>;\n\n/* -------------------------------------------------------------------------------------------------\n * createYupSchema\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ValidationOptions {\n status: 'draft' | 'published' | null;\n removedAttributes?: string[];\n}\n\nconst arrayValidator = (attribute: Schema['attributes'][string], options: ValidationOptions) => ({\n message: translatedErrors.required,\n test(value: unknown) {\n if (options.status === 'draft') {\n return true;\n }\n\n if (!attribute.required) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n\n return true;\n },\n});\nconst escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n/**\n * TODO: should we create a Map to store these based on the hash of the schema?\n */\nconst createYupSchema = (\n attributes: Schema['attributes'] = {},\n components: ComponentsDictionary = {},\n options: ValidationOptions = { status: null }\n): yup.ObjectSchema<any> => {\n const createModelSchema = (\n attributes: Schema['attributes'],\n removedAttributes: string[] = []\n ): yup.ObjectSchema<any> =>\n yup\n .object()\n .shape(\n Object.entries(attributes).reduce<ObjectShape>((acc, [name, attribute]) => {\n const getNestedPathsForAttribute = (removed: string[], attrName: string): string[] => {\n const prefix = `${attrName}.`;\n const bracketRegex = new RegExp(`^${escapeRegex(attrName)}\\\\[\\\\d+\\\\]\\\\.`);\n\n return removed\n .filter((p) => p.startsWith(prefix) || bracketRegex.test(p))\n .map((p) =>\n p.startsWith(prefix) ? p.slice(prefix.length) : p.replace(bracketRegex, '')\n );\n };\n\n if (DOCUMENT_META_FIELDS.includes(name)) {\n return acc;\n }\n\n if (removedAttributes?.includes(name)) {\n // If the attribute is not visible, we don't want to validate it\n return acc;\n }\n\n const nestedRemoved = getNestedPathsForAttribute(removedAttributes, name);\n\n /**\n * These validations won't apply to every attribute\n * and that's okay, in that case we just return the\n * schema as it was passed.\n */\n const validations = [\n addNullableValidation,\n addRequiredValidation,\n addMinLengthValidation,\n addMaxLengthValidation,\n addMinValidation,\n addMaxValidation,\n addRegexValidation,\n ].map((fn) => fn(attribute, options));\n\n const transformSchema = pipe(...validations);\n\n switch (attribute.type) {\n case 'component': {\n const { attributes } = components[attribute.component];\n\n if (attribute.repeatable) {\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(createModelSchema(attributes, nestedRemoved).nullable(false))\n ).test(arrayValidator(attribute, options)),\n };\n } else {\n return {\n ...acc,\n [name]: transformSchema(createModelSchema(attributes, nestedRemoved).nullable()),\n };\n }\n }\n case 'dynamiczone':\n return {\n ...acc,\n [name]: transformSchema(\n yup.array().of(\n yup.lazy(\n (\n data: SchemaUtils.Attribute.Value<SchemaUtils.Attribute.DynamicZone>[number]\n ) => {\n const attributes = components?.[data?.__component]?.attributes;\n\n const validation = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(components)),\n })\n .nullable(false);\n if (!attributes) {\n return validation;\n }\n\n return validation.concat(createModelSchema(attributes, nestedRemoved));\n }\n ) as unknown as yup.ObjectSchema<any>\n )\n ).test(arrayValidator(attribute, options)),\n };\n case 'relation':\n return {\n ...acc,\n [name]: transformSchema(\n yup.lazy((value) => {\n if (!value) {\n return yup.mixed().nullable(true);\n } else if (Array.isArray(value)) {\n // If a relation value is an array, we expect\n // an array of objects with {id} properties, representing the related entities.\n return yup.array().of(\n yup.object().shape({\n id: yup.number().required(),\n })\n );\n } else if (typeof value === 'object') {\n // A realtion value can also be an object. Some API\n // repsonses return the number of entities in the relation\n // as { count: x }\n return yup.object();\n } else {\n return yup\n .mixed()\n .test(\n 'type-error',\n 'Relation values must be either null, an array of objects with {id} or an object.',\n () => false\n );\n }\n })\n ),\n };\n default:\n return {\n ...acc,\n [name]: transformSchema(createAttributeSchema(attribute)),\n };\n }\n }, {})\n )\n /**\n * TODO: investigate why an undefined object fails a check of `nullable`.\n */\n .default(null);\n\n return createModelSchema(attributes, options.removedAttributes);\n};\n\nconst createAttributeSchema = (\n attribute: Exclude<\n SchemaUtils.Attribute.AnyAttribute,\n { type: 'dynamiczone' } | { type: 'component' } | { type: 'relation' }\n >\n) => {\n switch (attribute.type) {\n case 'biginteger':\n return yup.string().matches(/^-?\\d*$/);\n case 'boolean':\n return yup.boolean().nullable();\n case 'blocks':\n return yup.mixed().test('isBlocks', translatedErrors.json, (value) => {\n if (!value || Array.isArray(value)) {\n return true;\n } else {\n return false;\n }\n });\n case 'decimal':\n case 'float':\n case 'integer':\n return yup.number();\n case 'email':\n return yup.string().email(translatedErrors.email);\n case 'enumeration':\n return yup.string().oneOf([...attribute.enum, null]);\n case 'json':\n return yup.mixed().test('isJSON', translatedErrors.json, (value) => {\n /**\n * We don't want to validate the JSON field if it's empty.\n */\n if (!value || (typeof value === 'string' && value.length === 0)) {\n return true;\n }\n\n // If the value was created via content API and wasn't changed, then it's still an object\n if (typeof value === 'object') {\n try {\n JSON.stringify(value);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n try {\n JSON.parse(value);\n\n return true;\n } catch (err) {\n return false;\n }\n });\n case 'password':\n return yup.string().nullable();\n case 'richtext':\n case 'string':\n case 'text':\n return yup.string();\n case 'uid':\n return yup\n .string()\n .matches(attribute.regex ? new RegExp(attribute.regex) : /^[A-Za-z0-9-_.~]*$/);\n default:\n /**\n * This allows any value.\n */\n return yup.mixed();\n }\n};\n\n// Helper function to return schema.nullable() if it exists, otherwise return schema\nconst nullableSchema = <TSchema extends AnySchema>(schema: TSchema) => {\n return schema?.nullable\n ? schema.nullable()\n : // In some cases '.nullable' will not be available on the schema.\n // e.g. when the schema has been built using yup.lazy (e.g. for relations).\n // In these cases we should just return the schema as it is.\n schema;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validators\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Our validator functions can be preped with the\n * attribute and then have the schema piped through them.\n */\ntype ValidationFn = (\n attribute: Schema['attributes'][string],\n options: ValidationOptions\n) => <TSchema extends AnySchema>(schema: TSchema) => TSchema;\n\nconst addNullableValidation: ValidationFn = () => (schema) => {\n return nullableSchema(schema);\n};\n\nconst addRequiredValidation: ValidationFn = (attribute, options) => (schema) => {\n if (options.status === 'draft' || !attribute.required || attribute.type === 'password') {\n return schema;\n }\n\n if (attribute.required && 'required' in schema) {\n return schema.required(translatedErrors.required);\n }\n\n return schema;\n};\n\nconst addMinLengthValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // Skip minLength validation for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if (\n 'minLength' in attribute &&\n attribute.minLength &&\n Number.isInteger(attribute.minLength) &&\n 'min' in schema\n ) {\n return schema.min(attribute.minLength, {\n ...translatedErrors.minLength,\n values: {\n min: attribute.minLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMaxLengthValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if (\n 'maxLength' in attribute &&\n attribute.maxLength &&\n Number.isInteger(attribute.maxLength) &&\n 'max' in schema\n ) {\n return schema.max(attribute.maxLength, {\n ...translatedErrors.maxLength,\n values: {\n max: attribute.maxLength,\n },\n }) as TSchema;\n }\n\n return schema;\n };\n\nconst addMinValidation: ValidationFn =\n (attribute, options) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n // do not validate min for draft\n if (options.status === 'draft') {\n return schema;\n }\n\n if ('min' in attribute && 'min' in schema) {\n const min = toInteger(attribute.min);\n\n if (min) {\n return schema.min(min, {\n ...translatedErrors.min,\n values: {\n min,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst addMaxValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('max' in attribute) {\n const max = toInteger(attribute.max);\n\n if ('max' in schema && max) {\n return schema.max(max, {\n ...translatedErrors.max,\n values: {\n max,\n },\n }) as TSchema;\n }\n }\n\n return schema;\n };\n\nconst toInteger = (val?: string | number): number | undefined => {\n if (typeof val === 'number' || val === undefined) {\n return val;\n } else {\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n }\n};\n\nconst addRegexValidation: ValidationFn =\n (attribute) =>\n <TSchema extends AnySchema>(schema: TSchema): TSchema => {\n if ('regex' in attribute && attribute.regex && 'matches' in schema) {\n return schema.matches(new RegExp(attribute.regex), {\n message: {\n id: translatedErrors.regex.id,\n defaultMessage: 'The value does not match the defined pattern.',\n },\n\n excludeEmptyString: !attribute.required,\n }) as TSchema;\n }\n\n return schema;\n };\n\nexport { createYupSchema };\n"],"names":["arrayValidator","attribute","options","message","translatedErrors","required","test","value","status","Array","isArray","length","escapeRegex","str","replace","createYupSchema","attributes","components","createModelSchema","removedAttributes","yup","object","shape","Object","entries","reduce","acc","name","getNestedPathsForAttribute","removed","attrName","prefix","bracketRegex","RegExp","filter","p","startsWith","map","slice","DOCUMENT_META_FIELDS","includes","nestedRemoved","validations","addNullableValidation","addRequiredValidation","addMinLengthValidation","addMaxLengthValidation","addMinValidation","addMaxValidation","addRegexValidation","fn","transformSchema","pipe","type","component","repeatable","array","of","nullable","lazy","data","__component","validation","string","oneOf","keys","concat","mixed","id","number","createAttributeSchema","default","matches","boolean","json","email","enum","JSON","stringify","err","parse","regex","nullableSchema","schema","minLength","Number","isInteger","min","values","maxLength","max","toInteger","val","undefined","num","isNaN","defaultMessage","excludeEmptyString"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ var fp = require('lodash/fp');
|
|
|
4
4
|
var strapiUtils = require('@strapi/utils');
|
|
5
5
|
var populate = require('./utils/populate.js');
|
|
6
6
|
|
|
7
|
-
const { getScalarAttributes } = strapiUtils.contentTypes;
|
|
7
|
+
const { getScalarAttributes, getMediaAttributes } = strapiUtils.contentTypes;
|
|
8
8
|
const AVAILABLE_STATUS_FIELDS = [
|
|
9
9
|
'id',
|
|
10
10
|
'documentId',
|
|
@@ -151,8 +151,9 @@ var documentMetadata = (({ strapi })=>({
|
|
|
151
151
|
// TODO: Ignore publishedAt if availableStatus=false, and ignore locale if
|
|
152
152
|
// i18n is disabled
|
|
153
153
|
const { populate: populate$1 = {}, fields = [] } = populate.getPopulateForValidation(uid);
|
|
154
|
-
// Include non-translatable scalar fields in availableLocales for i18n prefilling
|
|
154
|
+
// Include non-translatable scalar and media fields in availableLocales for i18n prefilling
|
|
155
155
|
let nonLocalizedFields = [];
|
|
156
|
+
let nonLocalizedMediaFields = [];
|
|
156
157
|
try {
|
|
157
158
|
const i18nPlugin = strapi.plugin('i18n');
|
|
158
159
|
if (i18nPlugin) {
|
|
@@ -161,19 +162,31 @@ var documentMetadata = (({ strapi })=>({
|
|
|
161
162
|
const model = strapi.getModel(uid);
|
|
162
163
|
if (model?.attributes) {
|
|
163
164
|
const allNonLocalized = i18nService.getNonLocalizedAttributes(model);
|
|
164
|
-
// Get
|
|
165
|
+
// Get scalar and media attributes separately
|
|
165
166
|
const scalarAttrs = getScalarAttributes(model);
|
|
166
|
-
|
|
167
|
+
const mediaAttrs = getMediaAttributes(model);
|
|
168
|
+
// Separate scalar fields (can be in fields array) from media fields (need to be populated)
|
|
167
169
|
nonLocalizedFields = allNonLocalized.filter((field)=>field in model.attributes && scalarAttrs.includes(field));
|
|
170
|
+
nonLocalizedMediaFields = allNonLocalized.filter((field)=>field in model.attributes && mediaAttrs.includes(field));
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
}
|
|
171
174
|
} catch (error) {
|
|
172
175
|
// i18n plugin might not be enabled or might error, ignore silently
|
|
173
176
|
}
|
|
177
|
+
// Build populate object for non-localized media fields
|
|
178
|
+
const mediaPopulate = nonLocalizedMediaFields.reduce((acc, field)=>{
|
|
179
|
+
acc[field] = {
|
|
180
|
+
populate: {
|
|
181
|
+
folder: true
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return acc;
|
|
185
|
+
}, {});
|
|
174
186
|
const params = {
|
|
175
187
|
populate: {
|
|
176
188
|
...populate$1,
|
|
189
|
+
...mediaPopulate,
|
|
177
190
|
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
|
178
191
|
createdBy: {
|
|
179
192
|
select: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-metadata.js","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get only scalar attributes (components, relations, etc. can't be in fields array)\n const scalarAttrs = getScalarAttributes(model);\n // Only include scalar, non-localized fields that actually exist in the model\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n const params = {\n populate: {\n ...populate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","field","includes","error","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-metadata.js","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...populate,\n ...mediaPopulate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { groupBy, pick, uniq } from 'lodash/fp';
|
|
|
2
2
|
import { async, contentTypes } from '@strapi/utils';
|
|
3
3
|
import { getPopulateForValidation } from './utils/populate.mjs';
|
|
4
4
|
|
|
5
|
-
const { getScalarAttributes } = contentTypes;
|
|
5
|
+
const { getScalarAttributes, getMediaAttributes } = contentTypes;
|
|
6
6
|
const AVAILABLE_STATUS_FIELDS = [
|
|
7
7
|
'id',
|
|
8
8
|
'documentId',
|
|
@@ -149,8 +149,9 @@ var documentMetadata = (({ strapi })=>({
|
|
|
149
149
|
// TODO: Ignore publishedAt if availableStatus=false, and ignore locale if
|
|
150
150
|
// i18n is disabled
|
|
151
151
|
const { populate = {}, fields = [] } = getPopulateForValidation(uid);
|
|
152
|
-
// Include non-translatable scalar fields in availableLocales for i18n prefilling
|
|
152
|
+
// Include non-translatable scalar and media fields in availableLocales for i18n prefilling
|
|
153
153
|
let nonLocalizedFields = [];
|
|
154
|
+
let nonLocalizedMediaFields = [];
|
|
154
155
|
try {
|
|
155
156
|
const i18nPlugin = strapi.plugin('i18n');
|
|
156
157
|
if (i18nPlugin) {
|
|
@@ -159,19 +160,31 @@ var documentMetadata = (({ strapi })=>({
|
|
|
159
160
|
const model = strapi.getModel(uid);
|
|
160
161
|
if (model?.attributes) {
|
|
161
162
|
const allNonLocalized = i18nService.getNonLocalizedAttributes(model);
|
|
162
|
-
// Get
|
|
163
|
+
// Get scalar and media attributes separately
|
|
163
164
|
const scalarAttrs = getScalarAttributes(model);
|
|
164
|
-
|
|
165
|
+
const mediaAttrs = getMediaAttributes(model);
|
|
166
|
+
// Separate scalar fields (can be in fields array) from media fields (need to be populated)
|
|
165
167
|
nonLocalizedFields = allNonLocalized.filter((field)=>field in model.attributes && scalarAttrs.includes(field));
|
|
168
|
+
nonLocalizedMediaFields = allNonLocalized.filter((field)=>field in model.attributes && mediaAttrs.includes(field));
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
} catch (error) {
|
|
170
173
|
// i18n plugin might not be enabled or might error, ignore silently
|
|
171
174
|
}
|
|
175
|
+
// Build populate object for non-localized media fields
|
|
176
|
+
const mediaPopulate = nonLocalizedMediaFields.reduce((acc, field)=>{
|
|
177
|
+
acc[field] = {
|
|
178
|
+
populate: {
|
|
179
|
+
folder: true
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
return acc;
|
|
183
|
+
}, {});
|
|
172
184
|
const params = {
|
|
173
185
|
populate: {
|
|
174
186
|
...populate,
|
|
187
|
+
...mediaPopulate,
|
|
175
188
|
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
|
176
189
|
createdBy: {
|
|
177
190
|
select: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-metadata.mjs","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get only scalar attributes (components, relations, etc. can't be in fields array)\n const scalarAttrs = getScalarAttributes(model);\n // Only include scalar, non-localized fields that actually exist in the model\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n const params = {\n populate: {\n ...populate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","field","includes","error","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-metadata.mjs","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...populate,\n ...mediaPopulate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-metadata.d.ts","sourceRoot":"","sources":["../../../../server/src/services/document-metadata.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAKnF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CACpC;AA6BD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;qCAoB2B;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;IACjD;;OAEG;6BAEI,IAAI,WAAW,WACX,eAAe,eACX,eAAe,EAAE;IA2ChC;;OAEG;gCACyB,eAAe,eAAe,eAAe,EAAE;IAoB3E;;;;;OAKG;gCAC+B,IAAI,WAAW,aAAa,eAAe,EAAE;uBAuB5D,eAAe,0BAA0B,gBAAgB,CAAC,iBAAiB,CAAC;qBAgCxF,IAAI,WAAW,WACX,eAAe,0CAC6B,kBAAkB;;;;
|
|
1
|
+
{"version":3,"file":"document-metadata.d.ts","sourceRoot":"","sources":["../../../../server/src/services/document-metadata.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAKnF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CACpC;AA6BD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;qCAoB2B;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;IACjD;;OAEG;6BAEI,IAAI,WAAW,WACX,eAAe,eACX,eAAe,EAAE;IA2ChC;;OAEG;gCACyB,eAAe,eAAe,eAAe,EAAE;IAoB3E;;;;;OAKG;gCAC+B,IAAI,WAAW,aAAa,eAAe,EAAE;uBAuB5D,eAAe,0BAA0B,gBAAgB,CAAC,iBAAiB,CAAC;qBAgCxF,IAAI,WAAW,WACX,eAAe,0CAC6B,kBAAkB;;;;IAoFzE;;;;OAIG;oCAEI,IAAI,WAAW,YACV,eAAe,SACnB,kBAAkB;;;;;;;;;;;;;;;;AApO5B,wBAmRG"}
|