@strapi/content-manager 5.50.0 → 5.50.1
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/ComponentIcon.js.map +1 -1
- package/dist/admin/components/ComponentIcon.mjs.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
- package/dist/admin/components/DragLayer.js.map +1 -1
- package/dist/admin/components/DragLayer.mjs.map +1 -1
- package/dist/admin/components/LeftMenu.js +66 -67
- package/dist/admin/components/LeftMenu.js.map +1 -1
- package/dist/admin/components/LeftMenu.mjs +68 -69
- package/dist/admin/components/LeftMenu.mjs.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.js +3 -3
- package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs +3 -3
- package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
- package/dist/admin/history/routes.js.map +1 -1
- package/dist/admin/history/routes.mjs.map +1 -1
- package/dist/admin/hooks/useDocumentActions.js +15 -8
- package/dist/admin/hooks/useDocumentActions.js.map +1 -1
- package/dist/admin/hooks/useDocumentActions.mjs +15 -8
- package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
- package/dist/admin/hooks/useDocumentContext.js.map +1 -1
- package/dist/admin/hooks/useDocumentContext.mjs.map +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/layout.js +18 -6
- package/dist/admin/layout.js.map +1 -1
- package/dist/admin/layout.mjs +18 -6
- package/dist/admin/layout.mjs.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +7 -6
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +7 -6
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js +6 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs +6 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +8 -5
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +8 -5
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.js +5 -4
- package/dist/admin/pages/EditView/components/FormInputs/UID.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.mjs +5 -4
- package/dist/admin/pages/EditView/components/FormInputs/UID.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.js +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.mjs +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/utils.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/utils.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/Panels.js.map +1 -1
- package/dist/admin/pages/EditView/components/Panels.mjs.map +1 -1
- package/dist/admin/pages/EditView/utils/data.js.map +1 -1
- package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/Settings.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/Settings.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +71 -11
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +73 -13
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/Actions.js +2 -1
- package/dist/admin/pages/ListView/components/BulkActions/Actions.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/Actions.mjs +2 -1
- package/dist/admin/pages/ListView/components/BulkActions/Actions.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.js +5 -3
- package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.mjs +5 -3
- package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableActions.js +37 -0
- package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableActions.mjs +39 -2
- package/dist/admin/pages/ListView/components/TableActions.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellContent.js +26 -1
- package/dist/admin/pages/ListView/components/TableCells/CellContent.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellContent.mjs +26 -2
- package/dist/admin/pages/ListView/components/TableCells/CellContent.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellValue.js +8 -7
- package/dist/admin/pages/ListView/components/TableCells/CellValue.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellValue.mjs +8 -7
- package/dist/admin/pages/ListView/components/TableCells/CellValue.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Components.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Components.mjs.map +1 -1
- package/dist/admin/preview/pages/Preview.js +2 -0
- package/dist/admin/preview/pages/Preview.js.map +1 -1
- package/dist/admin/preview/pages/Preview.mjs +2 -0
- package/dist/admin/preview/pages/Preview.mjs.map +1 -1
- package/dist/admin/preview/routes.js.map +1 -1
- package/dist/admin/preview/routes.mjs.map +1 -1
- package/dist/admin/preview/utils/fieldUtils.js.map +1 -1
- package/dist/admin/preview/utils/fieldUtils.mjs.map +1 -1
- package/dist/admin/router.js.map +1 -1
- package/dist/admin/router.mjs.map +1 -1
- package/dist/admin/services/documents.js.map +1 -1
- package/dist/admin/services/documents.mjs.map +1 -1
- package/dist/admin/src/components/ComponentIcon.d.ts +4 -3
- package/dist/admin/src/components/DragLayer.d.ts +1 -1
- package/dist/admin/src/history/routes.d.ts +2 -2
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocumentActions.d.ts +17 -16
- package/dist/admin/src/hooks/useDocumentContext.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Editor.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/utils/utils.d.ts +7 -1
- package/dist/admin/src/pages/ListView/components/TableCells/CellContent.d.ts +11 -2
- package/dist/admin/src/pages/ListView/components/TableCells/CellValue.d.ts +1 -1
- package/dist/admin/src/preview/routes.d.ts +2 -2
- package/dist/admin/src/preview/services/preview.d.ts +1 -1
- package/dist/admin/src/router.d.ts +2 -2
- 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 +19 -19
- 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 +2 -2
- package/dist/admin/src/utils/conditionalFields.d.ts +1 -0
- package/dist/admin/src/utils/objects.d.ts +7 -4
- package/dist/admin/src/utils/validation.d.ts +2 -1
- package/dist/admin/translations/en.json.js +1 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +1 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/api.js +6 -1
- package/dist/admin/utils/api.js.map +1 -1
- package/dist/admin/utils/api.mjs +6 -1
- package/dist/admin/utils/api.mjs.map +1 -1
- package/dist/admin/utils/conditionalFields.js.map +1 -1
- package/dist/admin/utils/conditionalFields.mjs.map +1 -1
- package/dist/admin/utils/objects.js +43 -13
- package/dist/admin/utils/objects.js.map +1 -1
- package/dist/admin/utils/objects.mjs +43 -13
- package/dist/admin/utils/objects.mjs.map +1 -1
- package/dist/admin/utils/validation.js.map +1 -1
- package/dist/admin/utils/validation.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +4 -1
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +4 -1
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/relations.js +5 -4
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +5 -4
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/controllers/validation/model-configuration.js +3 -1
- package/dist/server/controllers/validation/model-configuration.js.map +1 -1
- package/dist/server/controllers/validation/model-configuration.mjs +3 -1
- package/dist/server/controllers/validation/model-configuration.mjs.map +1 -1
- package/dist/server/homepage/services/homepage.js +27 -7
- package/dist/server/homepage/services/homepage.js.map +1 -1
- package/dist/server/homepage/services/homepage.mjs +27 -7
- package/dist/server/homepage/services/homepage.mjs.map +1 -1
- package/dist/server/services/permission.js +4 -3
- package/dist/server/services/permission.js.map +1 -1
- package/dist/server/services/permission.mjs +4 -3
- package/dist/server/services/permission.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
- package/dist/server/src/services/permission.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -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';\nimport { indexByDocumentId } from './utils/document-status';\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 const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\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 && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\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 || sourceSchema?.modelType === 'component') {\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 important 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","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","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","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';\nimport { indexByDocumentId } from './utils/document-status';\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 const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\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 && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\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 {\n idsToOmit,\n idsToInclude,\n // `_q` is the public query parameter name; keep the alias grep-able.\n _q: search,\n ...query\n } = 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 (search) {\n const filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [filter]: search } });\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 || sourceSchema?.modelType === 'component') {\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 important 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","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","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","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","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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"}
|
|
@@ -23,7 +23,8 @@ const createSettingsSchema = (schema)=>{
|
|
|
23
23
|
// should be reset when the type changes
|
|
24
24
|
mainField: strapiUtils.yup.string().oneOf(validAttributes.concat('id')).default('id'),
|
|
25
25
|
// should be reset when the type changes
|
|
26
|
-
defaultSortBy: strapiUtils.yup.string()
|
|
26
|
+
defaultSortBy: strapiUtils.yup.string()// eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder
|
|
27
|
+
.test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value)=>settings.isValidDefaultSort(schema, value)).default('id'),
|
|
27
28
|
defaultSortOrder: strapiUtils.yup.string().oneOf([
|
|
28
29
|
'ASC',
|
|
29
30
|
'DESC'
|
|
@@ -67,6 +68,7 @@ const createMetadasSchema = (schema)=>{
|
|
|
67
68
|
};
|
|
68
69
|
const createArrayTest = ({ allowUndefined = false } = {})=>({
|
|
69
70
|
name: 'isArray',
|
|
71
|
+
// eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder
|
|
70
72
|
message: '${path} is required and must be an array',
|
|
71
73
|
test: (val)=>allowUndefined === true && val === undefined ? true : Array.isArray(val)
|
|
72
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-configuration.js","sources":["../../../../server/src/controllers/validation/model-configuration.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\nimport { getService } from '../../utils';\nimport { isListable, hasEditableAttribute } from '../../services/utils/configuration/attributes';\nimport { isValidDefaultSort } from '../../services/utils/configuration/settings';\n\n/**\n * Creates the validation schema for content-type configurations\n */\nexport default (schema: any, opts = {}) =>\n yup\n .object()\n .shape({\n settings: createSettingsSchema(schema).default(null).nullable(),\n metadatas: createMetadasSchema(schema).default(null).nullable(),\n layouts: createLayoutsSchema(schema, opts).default(null).nullable(),\n options: yup.object().optional(),\n })\n .noUnknown();\n\nconst createSettingsSchema = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n return yup\n .object()\n .shape({\n bulkable: yup.boolean().required(),\n filterable: yup.boolean().required(),\n pageSize: yup.number().integer().min(10).max(100).required(),\n searchable: yup.boolean().required(),\n // should be reset when the type changes\n mainField: yup.string().oneOf(validAttributes.concat('id')).default('id'),\n // should be reset when the type changes\n defaultSortBy: yup\n .string()\n .test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value) =>\n isValidDefaultSort(schema, value)\n )\n .default('id'),\n defaultSortOrder: yup.string().oneOf(['ASC', 'DESC']).default('ASC'),\n relationOpenMode: yup.string().oneOf(['modal', 'page', 'newTab']).default('modal'),\n })\n .noUnknown();\n};\n\nconst createMetadasSchema = (schema: any) => {\n return yup.object().shape(\n Object.keys(schema.attributes).reduce((acc: any, key) => {\n acc[key] = yup\n .object()\n .shape({\n edit: yup\n .object()\n .shape({\n label: yup.string(),\n description: yup.string().nullable(),\n placeholder: yup.string().nullable(),\n editable: yup.boolean(),\n visible: yup.boolean(),\n mainField: yup.lazy((value) => {\n if (!value) {\n return yup.string();\n }\n\n const targetSchema = getService('content-types').findContentType(\n schema.attributes[key].targetModel\n );\n\n if (!targetSchema) {\n return yup.string();\n }\n\n const validAttributes = Object.keys(targetSchema.attributes).filter((key) =>\n isListable(targetSchema, key)\n );\n\n return yup.string().oneOf(validAttributes.concat('id')).default('id');\n }),\n })\n .noUnknown()\n .required(),\n list: yup\n .object()\n .shape({\n label: yup.string(),\n searchable: yup.boolean(),\n sortable: yup.boolean(),\n })\n .noUnknown()\n .required(),\n })\n .noUnknown();\n\n return acc;\n }, {})\n );\n};\n\nconst createArrayTest = ({ allowUndefined = false } = {}) => ({\n name: 'isArray',\n message: '${path} is required and must be an array',\n test: (val: any) => (allowUndefined === true && val === undefined ? true : Array.isArray(val)),\n});\n\nconst createLayoutsSchema = (schema: any, opts = {}) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const editAttributes = Object.keys(schema.attributes).filter((key) =>\n hasEditableAttribute(schema, key)\n );\n\n return yup.object().shape({\n edit: yup\n .array()\n .of(\n yup.array().of(\n yup\n .object()\n .shape({\n name: yup.string().oneOf(editAttributes).required(),\n size: yup.number().integer().positive().required(),\n })\n .noUnknown()\n )\n )\n .test(createArrayTest(opts)),\n list: yup.array().of(yup.string().oneOf(validAttributes)).test(createArrayTest(opts)),\n });\n};\n"],"names":["schema","opts","yup","object","shape","settings","createSettingsSchema","default","nullable","metadatas","createMetadasSchema","layouts","createLayoutsSchema","options","optional","noUnknown","validAttributes","Object","keys","attributes","filter","key","isListable","bulkable","boolean","required","filterable","pageSize","number","integer","min","max","searchable","mainField","string","oneOf","concat","defaultSortBy","test","value","isValidDefaultSort","defaultSortOrder","relationOpenMode","reduce","acc","edit","label","description","placeholder","editable","visible","lazy","targetSchema","getService","findContentType","targetModel","list","sortable","createArrayTest","allowUndefined","name","message","val","undefined","Array","isArray","editAttributes","hasEditableAttribute","array","of","size","positive"],"mappings":";;;;;;;AAKA;;AAEC,IACD,qCAAe,CAAA,CAACA,MAAAA,EAAaC,IAAAA,GAAO,EAAE,GACpCC,eAAAA,CACGC,MAAM,EAAA,CACNC,KAAK,CAAC;AACLC,QAAAA,QAAAA,EAAUC,oBAAAA,CAAqBN,MAAAA,CAAAA,CAAQO,OAAO,CAAC,MAAMC,QAAQ,EAAA;AAC7DC,QAAAA,SAAAA,EAAWC,mBAAAA,CAAoBV,MAAAA,CAAAA,CAAQO,OAAO,CAAC,MAAMC,QAAQ,EAAA;AAC7DG,QAAAA,OAAAA,EAASC,oBAAoBZ,MAAAA,EAAQC,IAAAA,CAAAA,CAAMM,OAAO,CAAC,MAAMC,QAAQ,EAAA;QACjEK,OAAAA,EAASX,eAAAA,CAAIC,MAAM,EAAA,CAAGW,QAAQ;KAChC,CAAA,CACCC,SAAS,EAAC;AAEf,MAAMT,uBAAuB,CAACN,MAAAA,GAAAA;AAC5B,IAAA,MAAMgB,eAAAA,GAAkBC,MAAAA,CAAOC,IAAI,CAAClB,MAAAA,CAAOmB,UAAU,CAAA,CAAEC,MAAM,CAAC,CAACC,GAAAA,GAAQC,qBAAAA,CAAWtB,MAAAA,EAAQqB,GAAAA,CAAAA,CAAAA;AAE1F,IAAA,OAAOnB,eAAAA,CACJC,MAAM,EAAA,CACNC,KAAK,CAAC;QACLmB,QAAAA,EAAUrB,eAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;QAChCC,UAAAA,EAAYxB,eAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;QAClCE,QAAAA,EAAUzB,eAAAA,CAAI0B,MAAM,EAAA,CAAGC,OAAO,EAAA,CAAGC,GAAG,CAAC,EAAA,CAAA,CAAIC,GAAG,CAAC,GAAA,CAAA,CAAKN,QAAQ,EAAA;QAC1DO,UAAAA,EAAY9B,eAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;;QAElCQ,SAAAA,EAAW/B,eAAAA,CAAIgC,MAAM,EAAA,CAAGC,KAAK,CAACnB,gBAAgBoB,MAAM,CAAC,IAAA,CAAA,CAAA,CAAO7B,OAAO,CAAC,IAAA,CAAA;;
|
|
1
|
+
{"version":3,"file":"model-configuration.js","sources":["../../../../server/src/controllers/validation/model-configuration.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\nimport { getService } from '../../utils';\nimport { isListable, hasEditableAttribute } from '../../services/utils/configuration/attributes';\nimport { isValidDefaultSort } from '../../services/utils/configuration/settings';\n\n/**\n * Creates the validation schema for content-type configurations\n */\nexport default (schema: any, opts = {}) =>\n yup\n .object()\n .shape({\n settings: createSettingsSchema(schema).default(null).nullable(),\n metadatas: createMetadasSchema(schema).default(null).nullable(),\n layouts: createLayoutsSchema(schema, opts).default(null).nullable(),\n options: yup.object().optional(),\n })\n .noUnknown();\n\nconst createSettingsSchema = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n return yup\n .object()\n .shape({\n bulkable: yup.boolean().required(),\n filterable: yup.boolean().required(),\n pageSize: yup.number().integer().min(10).max(100).required(),\n searchable: yup.boolean().required(),\n // should be reset when the type changes\n mainField: yup.string().oneOf(validAttributes.concat('id')).default('id'),\n // should be reset when the type changes\n defaultSortBy: yup\n .string()\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder\n .test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value) =>\n isValidDefaultSort(schema, value)\n )\n .default('id'),\n defaultSortOrder: yup.string().oneOf(['ASC', 'DESC']).default('ASC'),\n relationOpenMode: yup.string().oneOf(['modal', 'page', 'newTab']).default('modal'),\n })\n .noUnknown();\n};\n\nconst createMetadasSchema = (schema: any) => {\n return yup.object().shape(\n Object.keys(schema.attributes).reduce((acc: any, key) => {\n acc[key] = yup\n .object()\n .shape({\n edit: yup\n .object()\n .shape({\n label: yup.string(),\n description: yup.string().nullable(),\n placeholder: yup.string().nullable(),\n editable: yup.boolean(),\n visible: yup.boolean(),\n mainField: yup.lazy((value) => {\n if (!value) {\n return yup.string();\n }\n\n const targetSchema = getService('content-types').findContentType(\n schema.attributes[key].targetModel\n );\n\n if (!targetSchema) {\n return yup.string();\n }\n\n const validAttributes = Object.keys(targetSchema.attributes).filter((key) =>\n isListable(targetSchema, key)\n );\n\n return yup.string().oneOf(validAttributes.concat('id')).default('id');\n }),\n })\n .noUnknown()\n .required(),\n list: yup\n .object()\n .shape({\n label: yup.string(),\n searchable: yup.boolean(),\n sortable: yup.boolean(),\n })\n .noUnknown()\n .required(),\n })\n .noUnknown();\n\n return acc;\n }, {})\n );\n};\n\nconst createArrayTest = ({ allowUndefined = false } = {}) => ({\n name: 'isArray',\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder\n message: '${path} is required and must be an array',\n test: (val: any) => (allowUndefined === true && val === undefined ? true : Array.isArray(val)),\n});\n\nconst createLayoutsSchema = (schema: any, opts = {}) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const editAttributes = Object.keys(schema.attributes).filter((key) =>\n hasEditableAttribute(schema, key)\n );\n\n return yup.object().shape({\n edit: yup\n .array()\n .of(\n yup.array().of(\n yup\n .object()\n .shape({\n name: yup.string().oneOf(editAttributes).required(),\n size: yup.number().integer().positive().required(),\n })\n .noUnknown()\n )\n )\n .test(createArrayTest(opts)),\n list: yup.array().of(yup.string().oneOf(validAttributes)).test(createArrayTest(opts)),\n });\n};\n"],"names":["schema","opts","yup","object","shape","settings","createSettingsSchema","default","nullable","metadatas","createMetadasSchema","layouts","createLayoutsSchema","options","optional","noUnknown","validAttributes","Object","keys","attributes","filter","key","isListable","bulkable","boolean","required","filterable","pageSize","number","integer","min","max","searchable","mainField","string","oneOf","concat","defaultSortBy","test","value","isValidDefaultSort","defaultSortOrder","relationOpenMode","reduce","acc","edit","label","description","placeholder","editable","visible","lazy","targetSchema","getService","findContentType","targetModel","list","sortable","createArrayTest","allowUndefined","name","message","val","undefined","Array","isArray","editAttributes","hasEditableAttribute","array","of","size","positive"],"mappings":"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"}
|
|
@@ -21,7 +21,8 @@ const createSettingsSchema = (schema)=>{
|
|
|
21
21
|
// should be reset when the type changes
|
|
22
22
|
mainField: yup.string().oneOf(validAttributes.concat('id')).default('id'),
|
|
23
23
|
// should be reset when the type changes
|
|
24
|
-
defaultSortBy: yup.string()
|
|
24
|
+
defaultSortBy: yup.string()// eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder
|
|
25
|
+
.test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value)=>isValidDefaultSort(schema, value)).default('id'),
|
|
25
26
|
defaultSortOrder: yup.string().oneOf([
|
|
26
27
|
'ASC',
|
|
27
28
|
'DESC'
|
|
@@ -65,6 +66,7 @@ const createMetadasSchema = (schema)=>{
|
|
|
65
66
|
};
|
|
66
67
|
const createArrayTest = ({ allowUndefined = false } = {})=>({
|
|
67
68
|
name: 'isArray',
|
|
69
|
+
// eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder
|
|
68
70
|
message: '${path} is required and must be an array',
|
|
69
71
|
test: (val)=>allowUndefined === true && val === undefined ? true : Array.isArray(val)
|
|
70
72
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-configuration.mjs","sources":["../../../../server/src/controllers/validation/model-configuration.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\nimport { getService } from '../../utils';\nimport { isListable, hasEditableAttribute } from '../../services/utils/configuration/attributes';\nimport { isValidDefaultSort } from '../../services/utils/configuration/settings';\n\n/**\n * Creates the validation schema for content-type configurations\n */\nexport default (schema: any, opts = {}) =>\n yup\n .object()\n .shape({\n settings: createSettingsSchema(schema).default(null).nullable(),\n metadatas: createMetadasSchema(schema).default(null).nullable(),\n layouts: createLayoutsSchema(schema, opts).default(null).nullable(),\n options: yup.object().optional(),\n })\n .noUnknown();\n\nconst createSettingsSchema = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n return yup\n .object()\n .shape({\n bulkable: yup.boolean().required(),\n filterable: yup.boolean().required(),\n pageSize: yup.number().integer().min(10).max(100).required(),\n searchable: yup.boolean().required(),\n // should be reset when the type changes\n mainField: yup.string().oneOf(validAttributes.concat('id')).default('id'),\n // should be reset when the type changes\n defaultSortBy: yup\n .string()\n .test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value) =>\n isValidDefaultSort(schema, value)\n )\n .default('id'),\n defaultSortOrder: yup.string().oneOf(['ASC', 'DESC']).default('ASC'),\n relationOpenMode: yup.string().oneOf(['modal', 'page', 'newTab']).default('modal'),\n })\n .noUnknown();\n};\n\nconst createMetadasSchema = (schema: any) => {\n return yup.object().shape(\n Object.keys(schema.attributes).reduce((acc: any, key) => {\n acc[key] = yup\n .object()\n .shape({\n edit: yup\n .object()\n .shape({\n label: yup.string(),\n description: yup.string().nullable(),\n placeholder: yup.string().nullable(),\n editable: yup.boolean(),\n visible: yup.boolean(),\n mainField: yup.lazy((value) => {\n if (!value) {\n return yup.string();\n }\n\n const targetSchema = getService('content-types').findContentType(\n schema.attributes[key].targetModel\n );\n\n if (!targetSchema) {\n return yup.string();\n }\n\n const validAttributes = Object.keys(targetSchema.attributes).filter((key) =>\n isListable(targetSchema, key)\n );\n\n return yup.string().oneOf(validAttributes.concat('id')).default('id');\n }),\n })\n .noUnknown()\n .required(),\n list: yup\n .object()\n .shape({\n label: yup.string(),\n searchable: yup.boolean(),\n sortable: yup.boolean(),\n })\n .noUnknown()\n .required(),\n })\n .noUnknown();\n\n return acc;\n }, {})\n );\n};\n\nconst createArrayTest = ({ allowUndefined = false } = {}) => ({\n name: 'isArray',\n message: '${path} is required and must be an array',\n test: (val: any) => (allowUndefined === true && val === undefined ? true : Array.isArray(val)),\n});\n\nconst createLayoutsSchema = (schema: any, opts = {}) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const editAttributes = Object.keys(schema.attributes).filter((key) =>\n hasEditableAttribute(schema, key)\n );\n\n return yup.object().shape({\n edit: yup\n .array()\n .of(\n yup.array().of(\n yup\n .object()\n .shape({\n name: yup.string().oneOf(editAttributes).required(),\n size: yup.number().integer().positive().required(),\n })\n .noUnknown()\n )\n )\n .test(createArrayTest(opts)),\n list: yup.array().of(yup.string().oneOf(validAttributes)).test(createArrayTest(opts)),\n });\n};\n"],"names":["schema","opts","yup","object","shape","settings","createSettingsSchema","default","nullable","metadatas","createMetadasSchema","layouts","createLayoutsSchema","options","optional","noUnknown","validAttributes","Object","keys","attributes","filter","key","isListable","bulkable","boolean","required","filterable","pageSize","number","integer","min","max","searchable","mainField","string","oneOf","concat","defaultSortBy","test","value","isValidDefaultSort","defaultSortOrder","relationOpenMode","reduce","acc","edit","label","description","placeholder","editable","visible","lazy","targetSchema","getService","findContentType","targetModel","list","sortable","createArrayTest","allowUndefined","name","message","val","undefined","Array","isArray","editAttributes","hasEditableAttribute","array","of","size","positive"],"mappings":";;;;;AAKA;;AAEC,IACD,qCAAe,CAAA,CAACA,MAAAA,EAAaC,IAAAA,GAAO,EAAE,GACpCC,GAAAA,CACGC,MAAM,EAAA,CACNC,KAAK,CAAC;AACLC,QAAAA,QAAAA,EAAUC,oBAAAA,CAAqBN,MAAAA,CAAAA,CAAQO,OAAO,CAAC,MAAMC,QAAQ,EAAA;AAC7DC,QAAAA,SAAAA,EAAWC,mBAAAA,CAAoBV,MAAAA,CAAAA,CAAQO,OAAO,CAAC,MAAMC,QAAQ,EAAA;AAC7DG,QAAAA,OAAAA,EAASC,oBAAoBZ,MAAAA,EAAQC,IAAAA,CAAAA,CAAMM,OAAO,CAAC,MAAMC,QAAQ,EAAA;QACjEK,OAAAA,EAASX,GAAAA,CAAIC,MAAM,EAAA,CAAGW,QAAQ;KAChC,CAAA,CACCC,SAAS,EAAC;AAEf,MAAMT,uBAAuB,CAACN,MAAAA,GAAAA;AAC5B,IAAA,MAAMgB,eAAAA,GAAkBC,MAAAA,CAAOC,IAAI,CAAClB,MAAAA,CAAOmB,UAAU,CAAA,CAAEC,MAAM,CAAC,CAACC,GAAAA,GAAQC,UAAAA,CAAWtB,MAAAA,EAAQqB,GAAAA,CAAAA,CAAAA;AAE1F,IAAA,OAAOnB,GAAAA,CACJC,MAAM,EAAA,CACNC,KAAK,CAAC;QACLmB,QAAAA,EAAUrB,GAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;QAChCC,UAAAA,EAAYxB,GAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;QAClCE,QAAAA,EAAUzB,GAAAA,CAAI0B,MAAM,EAAA,CAAGC,OAAO,EAAA,CAAGC,GAAG,CAAC,EAAA,CAAA,CAAIC,GAAG,CAAC,GAAA,CAAA,CAAKN,QAAQ,EAAA;QAC1DO,UAAAA,EAAY9B,GAAAA,CAAIsB,OAAO,EAAA,CAAGC,QAAQ,EAAA;;QAElCQ,SAAAA,EAAW/B,GAAAA,CAAIgC,MAAM,EAAA,CAAGC,KAAK,CAACnB,gBAAgBoB,MAAM,CAAC,IAAA,CAAA,CAAA,CAAO7B,OAAO,CAAC,IAAA,CAAA;;
|
|
1
|
+
{"version":3,"file":"model-configuration.mjs","sources":["../../../../server/src/controllers/validation/model-configuration.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\nimport { getService } from '../../utils';\nimport { isListable, hasEditableAttribute } from '../../services/utils/configuration/attributes';\nimport { isValidDefaultSort } from '../../services/utils/configuration/settings';\n\n/**\n * Creates the validation schema for content-type configurations\n */\nexport default (schema: any, opts = {}) =>\n yup\n .object()\n .shape({\n settings: createSettingsSchema(schema).default(null).nullable(),\n metadatas: createMetadasSchema(schema).default(null).nullable(),\n layouts: createLayoutsSchema(schema, opts).default(null).nullable(),\n options: yup.object().optional(),\n })\n .noUnknown();\n\nconst createSettingsSchema = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n return yup\n .object()\n .shape({\n bulkable: yup.boolean().required(),\n filterable: yup.boolean().required(),\n pageSize: yup.number().integer().min(10).max(100).required(),\n searchable: yup.boolean().required(),\n // should be reset when the type changes\n mainField: yup.string().oneOf(validAttributes.concat('id')).default('id'),\n // should be reset when the type changes\n defaultSortBy: yup\n .string()\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder\n .test('is-valid-sort-attribute', '${path} is not a valid sort attribute', async (value) =>\n isValidDefaultSort(schema, value)\n )\n .default('id'),\n defaultSortOrder: yup.string().oneOf(['ASC', 'DESC']).default('ASC'),\n relationOpenMode: yup.string().oneOf(['modal', 'page', 'newTab']).default('modal'),\n })\n .noUnknown();\n};\n\nconst createMetadasSchema = (schema: any) => {\n return yup.object().shape(\n Object.keys(schema.attributes).reduce((acc: any, key) => {\n acc[key] = yup\n .object()\n .shape({\n edit: yup\n .object()\n .shape({\n label: yup.string(),\n description: yup.string().nullable(),\n placeholder: yup.string().nullable(),\n editable: yup.boolean(),\n visible: yup.boolean(),\n mainField: yup.lazy((value) => {\n if (!value) {\n return yup.string();\n }\n\n const targetSchema = getService('content-types').findContentType(\n schema.attributes[key].targetModel\n );\n\n if (!targetSchema) {\n return yup.string();\n }\n\n const validAttributes = Object.keys(targetSchema.attributes).filter((key) =>\n isListable(targetSchema, key)\n );\n\n return yup.string().oneOf(validAttributes.concat('id')).default('id');\n }),\n })\n .noUnknown()\n .required(),\n list: yup\n .object()\n .shape({\n label: yup.string(),\n searchable: yup.boolean(),\n sortable: yup.boolean(),\n })\n .noUnknown()\n .required(),\n })\n .noUnknown();\n\n return acc;\n }, {})\n );\n};\n\nconst createArrayTest = ({ allowUndefined = false } = {}) => ({\n name: 'isArray',\n // eslint-disable-next-line no-template-curly-in-string -- Yup interpolation placeholder\n message: '${path} is required and must be an array',\n test: (val: any) => (allowUndefined === true && val === undefined ? true : Array.isArray(val)),\n});\n\nconst createLayoutsSchema = (schema: any, opts = {}) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const editAttributes = Object.keys(schema.attributes).filter((key) =>\n hasEditableAttribute(schema, key)\n );\n\n return yup.object().shape({\n edit: yup\n .array()\n .of(\n yup.array().of(\n yup\n .object()\n .shape({\n name: yup.string().oneOf(editAttributes).required(),\n size: yup.number().integer().positive().required(),\n })\n .noUnknown()\n )\n )\n .test(createArrayTest(opts)),\n list: yup.array().of(yup.string().oneOf(validAttributes)).test(createArrayTest(opts)),\n });\n};\n"],"names":["schema","opts","yup","object","shape","settings","createSettingsSchema","default","nullable","metadatas","createMetadasSchema","layouts","createLayoutsSchema","options","optional","noUnknown","validAttributes","Object","keys","attributes","filter","key","isListable","bulkable","boolean","required","filterable","pageSize","number","integer","min","max","searchable","mainField","string","oneOf","concat","defaultSortBy","test","value","isValidDefaultSort","defaultSortOrder","relationOpenMode","reduce","acc","edit","label","description","placeholder","editable","visible","lazy","targetSchema","getService","findContentType","targetModel","list","sortable","createArrayTest","allowUndefined","name","message","val","undefined","Array","isArray","editAttributes","hasEditableAttribute","array","of","size","positive"],"mappings":"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"}
|
|
@@ -7,6 +7,14 @@ const createHomepageService = ({ strapi })=>{
|
|
|
7
7
|
const MAX_DOCUMENTS = 4;
|
|
8
8
|
const metadataService = strapi.plugin('content-manager').service('document-metadata');
|
|
9
9
|
const permissionService = strapi.admin.services.permission;
|
|
10
|
+
const getRegisteredContentType = (uid)=>{
|
|
11
|
+
const contentType = strapi.contentTypes[uid];
|
|
12
|
+
if (contentType === undefined) {
|
|
13
|
+
strapi.log.warn(`Skipping homepage content type "${uid}" because it is no longer registered.`);
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return contentType;
|
|
17
|
+
};
|
|
10
18
|
const getConfiguration = async (contentTypeUids)=>{
|
|
11
19
|
/**
|
|
12
20
|
* Don't use the strapi.store util because we need to make
|
|
@@ -38,7 +46,14 @@ const createHomepageService = ({ strapi })=>{
|
|
|
38
46
|
// per role the user belongs to, so a multi-role user gets duplicate subjects.
|
|
39
47
|
// Using a Set collapses them to unique content type UID.
|
|
40
48
|
return [
|
|
41
|
-
...new Set(readPermissions.map((permission)=>permission.subject).filter(
|
|
49
|
+
...new Set(readPermissions.map((permission)=>permission.subject).filter((subject)=>{
|
|
50
|
+
if (!subject) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const contentType = strapi.contentTypes[subject];
|
|
54
|
+
const contentTypeOptions = contentType?.pluginOptions?.['content-manager'];
|
|
55
|
+
return contentTypeOptions?.visible !== false;
|
|
56
|
+
}))
|
|
42
57
|
];
|
|
43
58
|
};
|
|
44
59
|
const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');
|
|
@@ -47,20 +62,24 @@ const createHomepageService = ({ strapi })=>{
|
|
|
47
62
|
model: uid
|
|
48
63
|
});
|
|
49
64
|
const getContentTypesMeta = (allowedContentTypeUids, configurations)=>{
|
|
50
|
-
return allowedContentTypeUids.
|
|
65
|
+
return allowedContentTypeUids.reduce((acc, uid)=>{
|
|
51
66
|
const configuration = configurations.find((config)=>config.uid === uid);
|
|
52
|
-
const contentType =
|
|
67
|
+
const contentType = getRegisteredContentType(uid);
|
|
68
|
+
if (contentType === undefined) {
|
|
69
|
+
return acc;
|
|
70
|
+
}
|
|
53
71
|
const mainField = homepageQueryUtils.resolveReadableMainField(contentType, configuration, getPermissionChecker(uid));
|
|
54
72
|
const fields = homepageQueryUtils.buildHomepageQueryFields(contentType, mainField);
|
|
55
73
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(contentType);
|
|
56
|
-
|
|
74
|
+
acc.push({
|
|
57
75
|
fields,
|
|
58
76
|
mainField,
|
|
59
77
|
contentType,
|
|
60
78
|
hasDraftAndPublish,
|
|
61
79
|
uid
|
|
62
|
-
};
|
|
63
|
-
|
|
80
|
+
});
|
|
81
|
+
return acc;
|
|
82
|
+
}, []);
|
|
64
83
|
};
|
|
65
84
|
const formatDocuments = (documents, meta, populate)=>{
|
|
66
85
|
return documents.map((document)=>{
|
|
@@ -118,7 +137,8 @@ const createHomepageService = ({ strapi })=>{
|
|
|
118
137
|
async queryLastDocuments (additionalQueryParams, draftAndPublishOnly) {
|
|
119
138
|
const permittedContentTypes = await getPermittedContentTypes();
|
|
120
139
|
const allowedContentTypeUids = draftAndPublishOnly ? permittedContentTypes.filter((uid)=>{
|
|
121
|
-
|
|
140
|
+
const contentType = getRegisteredContentType(uid);
|
|
141
|
+
return contentType !== undefined && strapiUtils.contentTypes.hasDraftAndPublish(contentType);
|
|
122
142
|
}) : permittedContentTypes;
|
|
123
143
|
// Fetch the configuration for each content type in a single query
|
|
124
144
|
const configurations = await getConfiguration(allowedContentTypeUids);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homepage.js","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n // Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row\n // per role the user belongs to, so a multi-role user gets duplicate subjects.\n // Using a Set collapses them to unique content type UID.\n return [\n ...new Set(\n readPermissions\n .map((permission) => permission.subject)\n .filter(Boolean) as RecentDocument['contentTypeUid'][]\n ),\n ];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.map((uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = strapi.contentType(uid);\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n return {\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n };\n });\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n return contentTypes.hasDraftAndPublish(strapi.contentType(uid));\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","contentType","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","Set","subject","filter","Boolean","permissionCheckerService","getPermissionChecker","uid","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","contentTypes","formatDocuments","documents","meta","populate","document","additionalFields","reduce","acc","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","undefined","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"homepage.js","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n const getRegisteredContentType = (uid: RecentDocument['contentTypeUid']) => {\n const contentType = strapi.contentTypes[uid];\n\n if (contentType === undefined) {\n strapi.log.warn(\n `Skipping homepage content type \"${uid}\" because it is no longer registered.`\n );\n return undefined;\n }\n\n return contentType;\n };\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n // Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row\n // per role the user belongs to, so a multi-role user gets duplicate subjects.\n // Using a Set collapses them to unique content type UID.\n return [\n ...new Set(\n readPermissions\n .map((permission) => permission.subject)\n .filter((subject): subject is RecentDocument['contentTypeUid'] => {\n if (!subject) {\n return false;\n }\n\n const contentType = strapi.contentTypes[subject as keyof typeof strapi.contentTypes];\n const contentTypeOptions = contentType?.pluginOptions?.['content-manager'] as\n | { visible?: boolean }\n | undefined;\n\n return contentTypeOptions?.visible !== false;\n })\n ),\n ];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.reduce<ContentTypeMeta[]>((acc, uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = getRegisteredContentType(uid);\n\n if (contentType === undefined) {\n return acc;\n }\n\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n acc.push({\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n });\n\n return acc;\n }, []);\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n const contentType = getRegisteredContentType(uid);\n\n return contentType !== undefined && contentTypes.hasDraftAndPublish(contentType);\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getRegisteredContentType","uid","contentType","contentTypes","undefined","log","warn","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","Set","subject","filter","contentTypeOptions","pluginOptions","visible","permissionCheckerService","getPermissionChecker","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","reduce","acc","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","push","formatDocuments","documents","meta","populate","document","additionalFields","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
@@ -5,6 +5,14 @@ const createHomepageService = ({ strapi })=>{
|
|
|
5
5
|
const MAX_DOCUMENTS = 4;
|
|
6
6
|
const metadataService = strapi.plugin('content-manager').service('document-metadata');
|
|
7
7
|
const permissionService = strapi.admin.services.permission;
|
|
8
|
+
const getRegisteredContentType = (uid)=>{
|
|
9
|
+
const contentType = strapi.contentTypes[uid];
|
|
10
|
+
if (contentType === undefined) {
|
|
11
|
+
strapi.log.warn(`Skipping homepage content type "${uid}" because it is no longer registered.`);
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return contentType;
|
|
15
|
+
};
|
|
8
16
|
const getConfiguration = async (contentTypeUids)=>{
|
|
9
17
|
/**
|
|
10
18
|
* Don't use the strapi.store util because we need to make
|
|
@@ -36,7 +44,14 @@ const createHomepageService = ({ strapi })=>{
|
|
|
36
44
|
// per role the user belongs to, so a multi-role user gets duplicate subjects.
|
|
37
45
|
// Using a Set collapses them to unique content type UID.
|
|
38
46
|
return [
|
|
39
|
-
...new Set(readPermissions.map((permission)=>permission.subject).filter(
|
|
47
|
+
...new Set(readPermissions.map((permission)=>permission.subject).filter((subject)=>{
|
|
48
|
+
if (!subject) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const contentType = strapi.contentTypes[subject];
|
|
52
|
+
const contentTypeOptions = contentType?.pluginOptions?.['content-manager'];
|
|
53
|
+
return contentTypeOptions?.visible !== false;
|
|
54
|
+
}))
|
|
40
55
|
];
|
|
41
56
|
};
|
|
42
57
|
const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');
|
|
@@ -45,20 +60,24 @@ const createHomepageService = ({ strapi })=>{
|
|
|
45
60
|
model: uid
|
|
46
61
|
});
|
|
47
62
|
const getContentTypesMeta = (allowedContentTypeUids, configurations)=>{
|
|
48
|
-
return allowedContentTypeUids.
|
|
63
|
+
return allowedContentTypeUids.reduce((acc, uid)=>{
|
|
49
64
|
const configuration = configurations.find((config)=>config.uid === uid);
|
|
50
|
-
const contentType =
|
|
65
|
+
const contentType = getRegisteredContentType(uid);
|
|
66
|
+
if (contentType === undefined) {
|
|
67
|
+
return acc;
|
|
68
|
+
}
|
|
51
69
|
const mainField = resolveReadableMainField(contentType, configuration, getPermissionChecker(uid));
|
|
52
70
|
const fields = buildHomepageQueryFields(contentType, mainField);
|
|
53
71
|
const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);
|
|
54
|
-
|
|
72
|
+
acc.push({
|
|
55
73
|
fields,
|
|
56
74
|
mainField,
|
|
57
75
|
contentType,
|
|
58
76
|
hasDraftAndPublish,
|
|
59
77
|
uid
|
|
60
|
-
};
|
|
61
|
-
|
|
78
|
+
});
|
|
79
|
+
return acc;
|
|
80
|
+
}, []);
|
|
62
81
|
};
|
|
63
82
|
const formatDocuments = (documents, meta, populate)=>{
|
|
64
83
|
return documents.map((document)=>{
|
|
@@ -116,7 +135,8 @@ const createHomepageService = ({ strapi })=>{
|
|
|
116
135
|
async queryLastDocuments (additionalQueryParams, draftAndPublishOnly) {
|
|
117
136
|
const permittedContentTypes = await getPermittedContentTypes();
|
|
118
137
|
const allowedContentTypeUids = draftAndPublishOnly ? permittedContentTypes.filter((uid)=>{
|
|
119
|
-
|
|
138
|
+
const contentType = getRegisteredContentType(uid);
|
|
139
|
+
return contentType !== undefined && contentTypes.hasDraftAndPublish(contentType);
|
|
120
140
|
}) : permittedContentTypes;
|
|
121
141
|
// Fetch the configuration for each content type in a single query
|
|
122
142
|
const configurations = await getConfiguration(allowedContentTypeUids);
|