@strapi/content-manager 0.0.0-next.e3eb76a86aff89979cc9098aec129d2ffa600c56 → 0.0.0-next.e5d4b412da0d932b61b2fa5012d16513fda6de04
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/Widgets.js +267 -9
- package/dist/admin/components/Widgets.js.map +1 -1
- package/dist/admin/components/Widgets.mjs +250 -12
- package/dist/admin/components/Widgets.mjs.map +1 -1
- package/dist/admin/history/components/VersionContent.js +24 -3
- package/dist/admin/history/components/VersionContent.js.map +1 -1
- package/dist/admin/history/components/VersionContent.mjs +25 -4
- package/dist/admin/history/components/VersionContent.mjs.map +1 -1
- package/dist/admin/hooks/useDocumentActions.js +0 -3
- package/dist/admin/hooks/useDocumentActions.js.map +1 -1
- package/dist/admin/hooks/useDocumentActions.mjs +1 -4
- package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
- package/dist/admin/index.js +47 -8
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +47 -9
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/layout.js +1 -27
- package/dist/admin/layout.js.map +1 -1
- package/dist/admin/layout.mjs +2 -9
- package/dist/admin/layout.mjs.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.js +24 -6
- package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.mjs +26 -8
- package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +69 -20
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +70 -21
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +12 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +13 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +13 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +14 -3
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +16 -3
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +17 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +4 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +4 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.js +27 -3
- package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.mjs +27 -3
- package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/utils/data.js +109 -0
- package/dist/admin/pages/EditView/utils/data.js.map +1 -1
- package/dist/admin/pages/EditView/utils/data.mjs +109 -1
- package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +221 -203
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +222 -204
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js +12 -2
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs +12 -2
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.js +3 -1
- package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.mjs +3 -1
- package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
- package/dist/admin/preview/components/PreviewSidePanel.js +31 -4
- package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
- package/dist/admin/preview/components/PreviewSidePanel.mjs +32 -5
- package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
- package/dist/admin/preview/pages/Preview.js +136 -35
- package/dist/admin/preview/pages/Preview.js.map +1 -1
- package/dist/admin/preview/pages/Preview.mjs +137 -36
- package/dist/admin/preview/pages/Preview.mjs.map +1 -1
- package/dist/admin/preview/utils/constants.js +21 -0
- package/dist/admin/preview/utils/constants.js.map +1 -0
- package/dist/admin/preview/utils/constants.mjs +19 -0
- package/dist/admin/preview/utils/constants.mjs.map +1 -0
- package/dist/admin/preview/utils/previewScript.js +203 -0
- package/dist/admin/preview/utils/previewScript.js.map +1 -0
- package/dist/admin/preview/utils/previewScript.mjs +201 -0
- package/dist/admin/preview/utils/previewScript.mjs.map +1 -0
- package/dist/admin/services/api.js +4 -1
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs +4 -1
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/services/documents.js +40 -14
- package/dist/admin/services/documents.js.map +1 -1
- package/dist/admin/services/documents.mjs +40 -14
- package/dist/admin/services/documents.mjs.map +1 -1
- package/dist/admin/src/components/Widgets.d.ts +2 -1
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/pages/EditView/utils/data.d.ts +19 -1
- package/dist/admin/src/preview/services/preview.d.ts +1 -1
- package/dist/admin/src/preview/utils/constants.d.ts +17 -0
- package/dist/admin/src/preview/utils/previewScript.d.ts +18 -0
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +16 -16
- package/dist/admin/src/services/homepage.d.ts +1 -1
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +1 -1
- package/dist/admin/src/utils/validation.d.ts +1 -0
- package/dist/admin/translations/en.json.js +6 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +6 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/es.json.js +5 -2
- package/dist/admin/translations/es.json.js.map +1 -1
- package/dist/admin/translations/es.json.mjs +5 -2
- package/dist/admin/translations/es.json.mjs.map +1 -1
- package/dist/admin/translations/fr.json.js +10 -2
- package/dist/admin/translations/fr.json.js.map +1 -1
- package/dist/admin/translations/fr.json.mjs +10 -2
- package/dist/admin/translations/fr.json.mjs.map +1 -1
- package/dist/admin/utils/api.js +1 -1
- package/dist/admin/utils/api.js.map +1 -1
- package/dist/admin/utils/api.mjs +1 -1
- package/dist/admin/utils/api.mjs.map +1 -1
- package/dist/admin/utils/validation.js +18 -6
- package/dist/admin/utils/validation.js.map +1 -1
- package/dist/admin/utils/validation.mjs +18 -6
- package/dist/admin/utils/validation.mjs.map +1 -1
- package/dist/server/controllers/relations.js +2 -2
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +2 -2
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/history/services/lifecycles.js +20 -19
- package/dist/server/history/services/lifecycles.js.map +1 -1
- package/dist/server/history/services/lifecycles.mjs +20 -19
- package/dist/server/history/services/lifecycles.mjs.map +1 -1
- package/dist/server/homepage/controllers/homepage.js +5 -0
- package/dist/server/homepage/controllers/homepage.js.map +1 -1
- package/dist/server/homepage/controllers/homepage.mjs +5 -0
- package/dist/server/homepage/controllers/homepage.mjs.map +1 -1
- package/dist/server/homepage/routes/homepage.js +11 -0
- package/dist/server/homepage/routes/homepage.js.map +1 -1
- package/dist/server/homepage/routes/homepage.mjs +11 -0
- package/dist/server/homepage/routes/homepage.mjs.map +1 -1
- package/dist/server/homepage/services/homepage.js +86 -46
- package/dist/server/homepage/services/homepage.js.map +1 -1
- package/dist/server/homepage/services/homepage.mjs +86 -46
- package/dist/server/homepage/services/homepage.mjs.map +1 -1
- package/dist/server/preview/services/preview-config.js +5 -1
- package/dist/server/preview/services/preview-config.js.map +1 -1
- package/dist/server/preview/services/preview-config.mjs +5 -1
- package/dist/server/preview/services/preview-config.mjs.map +1 -1
- package/dist/server/preview/services/preview.js +4 -0
- package/dist/server/preview/services/preview.js.map +1 -1
- package/dist/server/preview/services/preview.mjs +4 -0
- package/dist/server/preview/services/preview.mjs.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/homepage/controllers/homepage.d.ts +2 -1
- package/dist/server/src/homepage/controllers/homepage.d.ts.map +1 -1
- package/dist/server/src/homepage/index.d.ts +7 -0
- package/dist/server/src/homepage/index.d.ts.map +1 -1
- package/dist/server/src/homepage/routes/homepage.d.ts.map +1 -1
- package/dist/server/src/homepage/services/homepage.d.ts +4 -1
- package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
- package/dist/server/src/homepage/services/index.d.ts +7 -0
- package/dist/server/src/homepage/services/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/preview/services/index.d.ts +1 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -1
- package/dist/server/src/preview/services/preview-config.d.ts +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
- package/dist/server/src/preview/services/preview.d.ts.map +1 -1
- package/dist/server/src/preview/utils.d.ts +1 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +7 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/shared/contracts/homepage.d.ts +13 -0
- package/dist/shared/contracts/homepage.d.ts.map +1 -1
- package/package.json +7 -8
|
@@ -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}\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});\n\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 = (attributes: Schema['attributes']): yup.ObjectSchema<any> =>\n yup\n .object()\n .shape(\n Object.entries(attributes).reduce<ObjectShape>((acc, [name, attribute]) => {\n if (DOCUMENT_META_FIELDS.includes(name)) {\n return acc;\n }\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).nullable(false))\n ).test(arrayValidator(attribute, options)),\n };\n } else {\n return {\n ...acc,\n [name]: transformSchema(createModelSchema(attributes).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));\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);\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 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) {\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","createYupSchema","attributes","components","createModelSchema","yup","object","shape","Object","entries","reduce","acc","name","DOCUMENT_META_FIELDS","includes","validations","addNullableValidation","addRequiredValidation","addMinLengthValidation","addMaxLengthValidation","addMinValidation","addMaxValidation","addRegexValidation","map","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","RegExp","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();\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,iBAAiBC,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,UAAmC,GAAA,EAAE,EACrCC,UAAmC,GAAA,EAAE,EACrCf,OAA6B,GAAA;IAAEM,MAAQ,EAAA;AAAK,CAAC,GAAA;IAE7C,MAAMU,iBAAAA,GAAoB,CACxBF,UACAG,EAAAA,iBAAAA,GAA8B,EAAE,GAEhCC,GAAAA,CACGC,MAAM,EACNC,CAAAA,KAAK,CACJC,MAAOC,CAAAA,OAAO,CAACR,UAAYS,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,CAAC,EAAED,QAAAA,CAAS,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,oBAAAA,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,GAAIoC,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,GAAIoC,CAAAA,KAAK,EAAGC,CAAAA,EAAE,CACZrC,GAAAA,CAAIuC,IAAI,CACN,CACEC,IAAAA,GAAAA;AAEA,4BAAA,MAAM5C,UAAaC,GAAAA,UAAAA,GAAa2C,IAAAA,EAAMC,YAAY,EAAE7C,UAAAA;AAEpD,4BAAA,MAAM8C,UAAa1C,GAAAA,GAAAA,CAChBC,MAAM,EAAA,CACNC,KAAK,CAAC;gCACLuC,WAAazC,EAAAA,GAAAA,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,GAAIuC,CAAAA,IAAI,CAAC,CAACpD,KAAAA,GAAAA;AACR,4BAAA,IAAI,CAACA,KAAO,EAAA;AACV,gCAAA,OAAOa,GAAI+C,CAAAA,KAAK,EAAGT,CAAAA,QAAQ,CAAC,IAAA,CAAA;AAC9B,6BAAA,MAAO,IAAIjD,KAAAA,CAAMC,OAAO,CAACH,KAAQ,CAAA,EAAA;;;gCAG/B,OAAOa,GAAAA,CAAIoC,KAAK,EAAGC,CAAAA,EAAE,CACnBrC,GAAIC,CAAAA,MAAM,EAAGC,CAAAA,KAAK,CAAC;oCACjB8C,EAAIhD,EAAAA,GAAAA,CAAIiD,MAAM,EAAA,CAAGhE,QAAQ;AAC3B,iCAAA,CAAA,CAAA;6BAEG,MAAA,IAAI,OAAOE,KAAAA,KAAU,QAAU,EAAA;;;;AAIpC,gCAAA,OAAOa,IAAIC,MAAM,EAAA;6BACZ,MAAA;AACL,gCAAA,OAAOD,IACJ+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,UAAYd,EAAAA,OAAAA,CAAQiB,iBAAiB,CAAA;AAChE;AAEA,MAAMmD,wBAAwB,CAC5BrE,SAAAA,GAAAA;AAKA,IAAA,OAAQA,UAAUoD,IAAI;QACpB,KAAK,YAAA;AACH,YAAA,OAAOjC,GAAI2C,CAAAA,MAAM,EAAGS,CAAAA,OAAO,CAAC,SAAA,CAAA;QAC9B,KAAK,SAAA;AACH,YAAA,OAAOpD,IAAIqD,OAAO,EAAA;QACpB,KAAK,QAAA;YACH,OAAOrD,GAAAA,CAAI+C,KAAK,EAAG7D,CAAAA,IAAI,CAAC,UAAYF,EAAAA,gBAAAA,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,IAAIiD,MAAM,EAAA;QACnB,KAAK,OAAA;AACH,YAAA,OAAOjD,IAAI2C,MAAM,EAAA,CAAGY,KAAK,CAACvE,iBAAiBuE,KAAK,CAAA;QAClD,KAAK,aAAA;AACH,YAAA,OAAOvD,GAAI2C,CAAAA,MAAM,EAAGC,CAAAA,KAAK,CAAC;AAAI/D,gBAAAA,GAAAA,SAAAA,CAAU2E,IAAI;AAAE,gBAAA;AAAK,aAAA,CAAA;QACrD,KAAK,MAAA;YACH,OAAOxD,GAAAA,CAAI+C,KAAK,EAAG7D,CAAAA,IAAI,CAAC,QAAUF,EAAAA,gBAAAA,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,GAAAA,CAAI2C,MAAM,EAAA,CAAGL,QAAQ,EAAA;QAC9B,KAAK,UAAA;QACL,KAAK,QAAA;QACL,KAAK,MAAA;AACH,YAAA,OAAOtC,IAAI2C,MAAM,EAAA;QACnB,KAAK,KAAA;AACH,YAAA,OAAO3C,GACJ2C,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,IAAI+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,gBAAAA,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,iBAAiBgF,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,iBAAiBqF,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,iBAAiBmF,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,iBAAiBsF,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,gBAAAA,CAAiB6E,KAAK,CAACb,EAAE;oBAC7B4B,cAAgB,EAAA;AAClB,iBAAA;gBAEAC,kBAAoB,EAAA,CAAChG,UAAUI;AACjC,aAAA,CAAA;AACF;QAEA,OAAO8E,MAAAA;AACT,KAAA;;;;"}
|
|
@@ -22,8 +22,8 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
|
|
|
22
22
|
// Whether the user has the permission to access the model's main field (using RBAC abilities)
|
|
23
23
|
const canReadMainField = permissionChecker.can.read(null, mainField);
|
|
24
24
|
if (!isMainFieldListable || !canReadMainField) {
|
|
25
|
-
// Default to '
|
|
26
|
-
return '
|
|
25
|
+
// Default to 'documentId' if the actual main field shouldn't be displayed
|
|
26
|
+
return 'documentId';
|
|
27
27
|
}
|
|
28
28
|
// Edge cases
|
|
29
29
|
// 1. Enforce 'name' as the main field for users and permissions' roles
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'id' if the actual main field shouldn't be displayed\n return 'id';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP) return { status: undefined };\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n 'documentId',\n ]);\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: uniq(idsToOmit) },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish) {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP) return { status: undefined };\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n 'documentId',\n ]);\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: uniq(idsToOmit) },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish) {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
|
|
@@ -20,8 +20,8 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
|
|
|
20
20
|
// Whether the user has the permission to access the model's main field (using RBAC abilities)
|
|
21
21
|
const canReadMainField = permissionChecker.can.read(null, mainField);
|
|
22
22
|
if (!isMainFieldListable || !canReadMainField) {
|
|
23
|
-
// Default to '
|
|
24
|
-
return '
|
|
23
|
+
// Default to 'documentId' if the actual main field shouldn't be displayed
|
|
24
|
+
return 'documentId';
|
|
25
25
|
}
|
|
26
26
|
// Edge cases
|
|
27
27
|
// 1. Enforce 'name' as the main field for users and permissions' roles
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'id' if the actual main field shouldn't be displayed\n return 'id';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP) return { status: undefined };\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n 'documentId',\n ]);\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: uniq(idsToOmit) },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish) {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP) return { status: undefined };\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n 'documentId',\n ]);\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: uniq(idsToOmit) },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish) {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var strapiUtils = require('@strapi/utils');
|
|
4
4
|
var fp = require('lodash/fp');
|
|
5
|
-
var nodeSchedule = require('node-schedule');
|
|
6
5
|
var utils$1 = require('../utils.js');
|
|
7
6
|
var constants = require('../constants.js');
|
|
8
7
|
var utils = require('./utils.js');
|
|
@@ -58,7 +57,6 @@ var utils = require('./utils.js');
|
|
|
58
57
|
};
|
|
59
58
|
const createLifecyclesService = ({ strapi: strapi1 })=>{
|
|
60
59
|
const state = {
|
|
61
|
-
deleteExpiredJob: null,
|
|
62
60
|
isInitialized: false
|
|
63
61
|
};
|
|
64
62
|
const serviceUtils = utils.createServiceUtils({
|
|
@@ -127,27 +125,30 @@ const createLifecyclesService = ({ strapi: strapi1 })=>{
|
|
|
127
125
|
return result;
|
|
128
126
|
});
|
|
129
127
|
// Schedule a job to delete expired history versions every day at midnight
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
strapi1.cron.add({
|
|
129
|
+
deleteHistoryDaily: {
|
|
130
|
+
async task () {
|
|
131
|
+
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;
|
|
132
|
+
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
|
133
|
+
strapi1.db.query(constants.HISTORY_VERSION_UID).deleteMany({
|
|
134
|
+
where: {
|
|
135
|
+
created_at: {
|
|
136
|
+
$lt: expirationDate
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}).catch((error)=>{
|
|
140
|
+
if (error instanceof Error) {
|
|
141
|
+
strapi1.log.error('Error deleting expired history versions', error.message);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
options: '0 0 * * *'
|
|
146
|
+
}
|
|
144
147
|
});
|
|
145
148
|
state.isInitialized = true;
|
|
146
149
|
},
|
|
147
150
|
async destroy () {
|
|
148
|
-
|
|
149
|
-
state.deleteExpiredJob.cancel();
|
|
150
|
-
}
|
|
151
|
+
strapi1.cron.remove('deleteHistoryDaily');
|
|
151
152
|
}
|
|
152
153
|
};
|
|
153
154
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycles.js","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { scheduleJob } from 'node-schedule';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n deleteExpiredJob: ReturnType<typeof scheduleJob> | null;\n isInitialized: boolean;\n } = {\n deleteExpiredJob: null,\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n const { persistTablesWithPrefix } = strapi.service('admin::persist-tables');\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n // Avoid data loss in case users temporarily don't have a license\n await persistTablesWithPrefix('strapi_history_versions');\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n state.deleteExpiredJob = scheduleJob('historyDaily', '0 0 * * *', () => {\n const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n if (state.deleteExpiredJob) {\n state.deleteExpiredJob.cancel();\n }\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","deleteExpiredJob","isInitialized","serviceUtils","createServiceUtils","persistTablesWithPrefix","service","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","scheduleJob","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","destroy","cancel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lifecycles.js","sources":["../../../../server/src/history/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules, UID } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport { omit, castArray } from 'lodash/fp';\n\nimport { getService } from '../utils';\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\n\nimport type { CreateHistoryVersion } from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\n\n/**\n * Filters out actions that should not create a history version.\n */\nconst shouldCreateHistoryVersion = (\n context: Modules.Documents.Middleware.Context\n): context is Modules.Documents.Middleware.Context & {\n action: 'create' | 'update' | 'clone' | 'publish' | 'unpublish' | 'discardDraft';\n contentType: UID.CollectionType;\n} => {\n // Ignore requests that are not related to the content manager\n if (!strapi.requestContext.get()?.request.url.startsWith('/content-manager')) {\n return false;\n }\n\n // NOTE: cannot do type narrowing with array includes\n if (\n context.action !== 'create' &&\n context.action !== 'update' &&\n context.action !== 'clone' &&\n context.action !== 'publish' &&\n context.action !== 'unpublish' &&\n context.action !== 'discardDraft'\n ) {\n return false;\n }\n\n /**\n * When a document is published, the draft version of the document is also updated.\n * It creates confusion for users because they see two history versions each publish action.\n * To avoid this, we silence the update action during a publish request,\n * so that they only see the published version of the document in the history.\n */\n if (\n context.action === 'update' &&\n strapi.requestContext.get()?.request.url.endsWith('/actions/publish')\n ) {\n return false;\n }\n\n // Ignore content types not created by the user\n if (!context.contentType.uid.startsWith('api::')) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Returns the content type schema (and its components schemas).\n * Used to determine if changes were made in the content type builder since a history version was created.\n * And therefore which fields can be restored and which cannot.\n */\nconst getSchemas = (uid: UID.CollectionType) => {\n const attributesSchema = strapi.getModel(uid).attributes;\n\n // TODO: Handle nested components\n const componentsSchemas = Object.keys(attributesSchema).reduce(\n (currentComponentSchemas, key) => {\n const fieldSchema = attributesSchema[key];\n\n if (fieldSchema.type === 'component') {\n const componentSchema = strapi.getModel(fieldSchema.component).attributes;\n return {\n ...currentComponentSchemas,\n [fieldSchema.component]: componentSchema,\n };\n }\n\n // Ignore anything that's not a component\n return currentComponentSchemas;\n },\n {} as CreateHistoryVersion['componentsSchemas']\n );\n\n return {\n schema: omit(FIELDS_TO_IGNORE, attributesSchema) as CreateHistoryVersion['schema'],\n componentsSchemas,\n };\n};\n\nconst createLifecyclesService = ({ strapi }: { strapi: Core.Strapi }) => {\n const state: {\n isInitialized: boolean;\n } = {\n isInitialized: false,\n };\n\n const serviceUtils = createServiceUtils({ strapi });\n const { persistTablesWithPrefix } = strapi.service('admin::persist-tables');\n\n return {\n async bootstrap() {\n // Prevent initializing the service twice\n if (state.isInitialized) {\n return;\n }\n\n // Avoid data loss in case users temporarily don't have a license\n await persistTablesWithPrefix('strapi_history_versions');\n\n strapi.documents.use(async (context, next) => {\n const result = (await next()) as any;\n\n if (!shouldCreateHistoryVersion(context)) {\n return result;\n }\n\n // On create/clone actions, the documentId is not available before creating the action is executed\n const documentId =\n context.action === 'create' || context.action === 'clone'\n ? result.documentId\n : context.params.documentId;\n\n // Apply default locale if not available in the request\n const defaultLocale = await serviceUtils.getDefaultLocale();\n const locales = castArray(context.params?.locale || defaultLocale);\n if (!locales.length) {\n return result;\n }\n\n // All schemas related to the content type\n const uid = context.contentType.uid;\n const schemas = getSchemas(uid);\n const model = strapi.getModel(uid);\n\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);\n\n // Find all affected entries\n const localeEntries = await strapi.db.query(uid).findMany({\n where: {\n documentId,\n ...(isLocalizedContentType ? { locale: { $in: locales } } : {}),\n ...(contentTypes.hasDraftAndPublish(strapi.contentTypes[uid])\n ? { publishedAt: null }\n : {}),\n },\n populate: serviceUtils.getDeepPopulate(uid, true /* use database syntax */),\n });\n\n await strapi.db.transaction(async ({ onCommit }) => {\n // .createVersion() is executed asynchronously,\n // onCommit prevents creating a history version\n // when the transaction has already been committed\n onCommit(async () => {\n for (const entry of localeEntries) {\n const status = await serviceUtils.getVersionStatus(uid, entry);\n\n await getService(strapi, 'history').createVersion({\n contentType: uid,\n data: omit(FIELDS_TO_IGNORE, entry) as Modules.Documents.AnyDocument,\n relatedDocumentId: documentId,\n locale: entry.locale,\n status,\n ...schemas,\n });\n }\n });\n });\n\n return result;\n });\n\n // Schedule a job to delete expired history versions every day at midnight\n strapi.cron.add({\n deleteHistoryDaily: {\n async task() {\n const retentionDaysInMilliseconds =\n serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;\n const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);\n\n strapi.db\n .query(HISTORY_VERSION_UID)\n .deleteMany({\n where: {\n created_at: {\n $lt: expirationDate,\n },\n },\n })\n .catch((error) => {\n if (error instanceof Error) {\n strapi.log.error('Error deleting expired history versions', error.message);\n }\n });\n },\n options: '0 0 * * *',\n },\n });\n\n state.isInitialized = true;\n },\n\n async destroy() {\n strapi.cron.remove('deleteHistoryDaily');\n },\n };\n};\n\nexport { createLifecyclesService };\n"],"names":["shouldCreateHistoryVersion","context","strapi","requestContext","get","request","url","startsWith","action","endsWith","contentType","uid","getSchemas","attributesSchema","getModel","attributes","componentsSchemas","Object","keys","reduce","currentComponentSchemas","key","fieldSchema","type","componentSchema","component","schema","omit","FIELDS_TO_IGNORE","createLifecyclesService","state","isInitialized","serviceUtils","createServiceUtils","persistTablesWithPrefix","service","bootstrap","documents","use","next","result","documentId","params","defaultLocale","getDefaultLocale","locales","castArray","locale","length","schemas","model","isLocalizedContentType","localeEntries","db","query","findMany","where","$in","contentTypes","hasDraftAndPublish","publishedAt","populate","getDeepPopulate","transaction","onCommit","entry","status","getVersionStatus","getService","createVersion","data","relatedDocumentId","cron","add","deleteHistoryDaily","task","retentionDaysInMilliseconds","getRetentionDays","expirationDate","Date","now","HISTORY_VERSION_UID","deleteMany","created_at","$lt","catch","error","Error","log","message","options","destroy","remove"],"mappings":"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"}
|