@strapi/content-manager 5.59.0 → 5.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/admin/history/components/VersionInputRenderer.js +2 -1
  2. package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
  3. package/dist/admin/history/components/VersionInputRenderer.mjs +2 -1
  4. package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
  5. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +1 -0
  6. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  7. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +1 -0
  8. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  9. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +1 -0
  10. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  11. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +1 -0
  12. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  13. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +2 -0
  14. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  15. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +2 -0
  16. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  17. package/dist/admin/pages/EditView/components/FormLayout.js +1 -0
  18. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  19. package/dist/admin/pages/EditView/components/FormLayout.mjs +1 -0
  20. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  21. package/dist/admin/pages/EditView/components/InputRenderer.js +3 -1
  22. package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
  23. package/dist/admin/pages/EditView/components/InputRenderer.mjs +3 -1
  24. package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
  25. package/dist/admin/preview/components/PreviewSidePanel.js +2 -1
  26. package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
  27. package/dist/admin/preview/components/PreviewSidePanel.mjs +2 -1
  28. package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
  29. package/dist/admin/preview/utils/getPreviewUrlStatus.js +17 -0
  30. package/dist/admin/preview/utils/getPreviewUrlStatus.js.map +1 -0
  31. package/dist/admin/preview/utils/getPreviewUrlStatus.mjs +15 -0
  32. package/dist/admin/preview/utils/getPreviewUrlStatus.mjs.map +1 -0
  33. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +3 -1
  34. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -0
  35. package/dist/admin/src/preview/utils/getPreviewUrlStatus.d.ts +6 -0
  36. package/dist/server/controllers/relations.js +48 -16
  37. package/dist/server/controllers/relations.js.map +1 -1
  38. package/dist/server/controllers/relations.mjs +49 -17
  39. package/dist/server/controllers/relations.mjs.map +1 -1
  40. package/dist/server/history/services/history.js +1 -1
  41. package/dist/server/history/services/history.js.map +1 -1
  42. package/dist/server/history/services/history.mjs +1 -1
  43. package/dist/server/history/services/history.mjs.map +1 -1
  44. package/dist/server/mcp/schemas/filters-schema.js +10 -2
  45. package/dist/server/mcp/schemas/filters-schema.js.map +1 -1
  46. package/dist/server/mcp/schemas/filters-schema.mjs +10 -2
  47. package/dist/server/mcp/schemas/filters-schema.mjs.map +1 -1
  48. package/dist/server/preview/controllers/validation/preview.js +1 -1
  49. package/dist/server/preview/controllers/validation/preview.js.map +1 -1
  50. package/dist/server/preview/controllers/validation/preview.mjs +2 -2
  51. package/dist/server/preview/controllers/validation/preview.mjs.map +1 -1
  52. package/dist/server/services/document-metadata.js +1 -1
  53. package/dist/server/services/document-metadata.js.map +1 -1
  54. package/dist/server/services/document-metadata.mjs +1 -1
  55. package/dist/server/services/document-metadata.mjs.map +1 -1
  56. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  57. package/dist/server/src/mcp/schemas/filters-schema.d.ts.map +1 -1
  58. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniqBy, concat, flow, isEmpty } from 'lodash';\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 // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(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 property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, '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\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\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: [...new Set(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(concat(sanitizedRes.results, res.results), 'id');\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","isSourceLocalized","localization","isLocalizedContentType","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","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$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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"}
1
+ {"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniq, uniqBy, concat, flow, isEmpty } from 'lodash';\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\n/**\n * Fields every relation returned by findExisting carries, whatever the user's permissions.\n */\nconst RELATION_BASE_FIELDS = ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'];\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.db.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 // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(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 property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, '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\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\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: [...new Set(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 const pageParams = {\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n };\n\n const defaultPagination = (total: number) => ({ page: 1, pageCount: 1, pageSize: 10, total });\n\n /**\n * The permission query only carries row-level conditions when the user's read permission on\n * the target has conditions (e.g. \"only entries I created\"). Without them it only restricts\n * the fields, so a single load returns exactly what the two-step flow below would: the\n * relations of the page with the fields the user is allowed to read.\n */\n if (isEmpty(permissionQuery.filters)) {\n const { select } = strapi.get('query-params').transform(targetUid, permissionQuery);\n const permittedFields = Array.isArray(select) ? select : [];\n\n const res = await loadRelations({ id: entryId }, targetField, {\n select: uniq([...RELATION_BASE_FIELDS, ...permittedFields]),\n ordering: 'desc',\n ...pageParams,\n filters,\n });\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(res.results.length),\n results: await addStatusToRelations(targetUid, res.results),\n };\n\n return;\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: RELATION_BASE_FIELDS,\n ordering: 'desc',\n ...pageParams,\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(concat(sanitizedRes.results, res.results), 'id');\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(relationsUnion.length),\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","RELATION_BASE_FIELDS","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","db","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isSourceLocalized","localization","isLocalizedContentType","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","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","pageParams","page","pageSize","defaultPagination","total","pageCount","permittedFields","Array","isArray","uniq","ordering","pagination","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat"],"mappings":"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"}
@@ -96,7 +96,7 @@ const createHistoryService = ({ strapi })=>{
96
96
  if (userToPopulate == null) {
97
97
  return null;
98
98
  }
99
- return strapi.query('admin::user').findOne({
99
+ return strapi.db.query('admin::user').findOne({
100
100
  where: {
101
101
  ...userToPopulate.id ? {
102
102
  id: userToPopulate.id
@@ -1 +1 @@
1
- {"version":3,"file":"history.js","sources":["../../../../server/src/history/services/history.ts"],"sourcesContent":["import type { Core, Data, Modules, Schema } from '@strapi/types';\nimport { errors, traverseEntity } from '@strapi/utils';\nimport { omit } from 'lodash';\n\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\nimport type { HistoryVersions } from '../../../../shared/contracts';\nimport type {\n CreateHistoryVersion,\n HistoryVersionDataResponse,\n} from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\nimport { getService as getContentManagerService } from '../../utils';\n\n// Needed because the query engine doesn't return any types yet\ntype HistoryVersionQueryResult = Omit<HistoryVersionDataResponse, 'locale'> &\n Pick<CreateHistoryVersion, 'locale'>;\n\nconst createHistoryService = ({ strapi }: { strapi: Core.Strapi }) => {\n const query = strapi.db.query(HISTORY_VERSION_UID);\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async createVersion(historyVersionData: HistoryVersions.CreateHistoryVersion) {\n await query.create({\n data: {\n ...historyVersionData,\n createdAt: new Date(),\n createdBy: strapi.requestContext.get()?.state?.user.id,\n },\n });\n },\n\n async findVersionsPage(params: HistoryVersions.GetHistoryVersions.Request): Promise<{\n results: HistoryVersions.HistoryVersionDataResponse[];\n pagination: HistoryVersions.Pagination;\n }> {\n const schema = strapi.getModel(params.query.contentType);\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);\n const defaultLocale = await serviceUtils.getDefaultLocale();\n\n let locale = null;\n if (isLocalizedContentType) {\n locale = params.query.locale || defaultLocale;\n }\n\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27393\n const [{ results: versionRows, pagination }, localeDictionary] = await Promise.all([\n query.findPage({\n ...params.query,\n select: ['id'],\n where: {\n $and: [\n { contentType: params.query.contentType },\n ...(params.query.documentId ? [{ relatedDocumentId: params.query.documentId }] : []),\n ...(locale ? [{ locale }] : []),\n ],\n },\n orderBy: [{ createdAt: 'desc' }],\n }),\n serviceUtils.getLocaleDictionary(),\n ]);\n\n const ids = versionRows.map((version) => version.id);\n const versions = ids.length\n ? await query.findMany({\n where: { id: { $in: ids } },\n populate: ['createdBy'],\n })\n : [];\n const versionsById = new Map(versions.map((version) => [version.id, version]));\n const results = ids.map((id) => versionsById.get(id)).filter(Boolean);\n\n const populateEntry = async (entry: HistoryVersionQueryResult) => {\n return traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n if (!options.value) return;\n\n const currentValue: any[] = Array.isArray(options.value)\n ? options.value\n : [options.value];\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (options.attribute.target === 'admin::user') {\n const adminUsers = await Promise.all(\n currentValue.map((userToPopulate) => {\n if (userToPopulate == null) {\n return null;\n }\n\n return strapi.query('admin::user').findOne({\n where: {\n ...(userToPopulate.id ? { id: userToPopulate.id } : {}),\n ...(userToPopulate.documentId\n ? { documentId: userToPopulate.documentId }\n : {}),\n },\n });\n })\n );\n\n utils.set(options.key, adminUsers as any);\n }\n\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: options.attribute.target,\n });\n\n const response = await serviceUtils.buildRelationReponse(\n currentValue,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n\n if (options.attribute.type === 'media') {\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: 'plugin::upload.file',\n });\n\n const response = await serviceUtils.buildMediaResponse(currentValue);\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n entry.data\n );\n };\n\n const formattedResults: any[] = await Promise.all(\n (results as HistoryVersionQueryResult[]).map(async (result) => {\n return {\n ...result,\n data: await populateEntry(result),\n meta: {\n unknownAttributes: serviceUtils.getSchemaAttributesDiff(\n result.schema,\n strapi.getModel(params.query.contentType).attributes\n ),\n },\n locale: result.locale ? localeDictionary[result.locale] : null,\n };\n })\n );\n\n return {\n results: formattedResults,\n pagination,\n };\n },\n\n async restoreVersion(versionId: Data.ID) {\n const version = await query.findOne({ where: { id: versionId } });\n const contentTypeSchemaAttributes = strapi.getModel(version.contentType).attributes;\n const schemaDiff = serviceUtils.getSchemaAttributesDiff(\n version.schema,\n contentTypeSchemaAttributes\n );\n\n // Set all added attribute values to null\n const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(\n (currentData, addedKey) => {\n currentData[addedKey] = null;\n return currentData;\n },\n // Clone to avoid mutating the original version data\n structuredClone(version.data)\n );\n\n // Remove the schema attributes history should ignore\n const schema = structuredClone(version.schema);\n schema.attributes = omit(contentTypeSchemaAttributes, FIELDS_TO_IGNORE);\n\n const dataWithoutMissingRelations = await traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n\n if (options.attribute.repeatable && options.value === null) {\n // Repeatable Components should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (options.attribute.type === 'dynamiczone') {\n if (options.value === null) {\n // Dynamic zones should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (!options.value) return;\n\n const data = await serviceUtils.getRelationRestoreValue(\n options.value as Modules.Documents.AnyDocument,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n\n utils.set(options.key, data as Modules.Documents.AnyDocument);\n }\n\n if (options.attribute.type === 'media') {\n if (!options.value) return;\n\n const data = await serviceUtils.getMediaRestoreValue(\n options.value as Modules.Documents.AnyDocument\n );\n\n utils.set(options.key, data);\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n dataWithoutAddedAttributes\n );\n\n const data = omit(dataWithoutMissingRelations, ['id', ...Object.keys(schemaDiff.removed)]);\n const restoredDocument = await strapi.documents(version.contentType).update({\n documentId: version.relatedDocumentId,\n locale: version.locale,\n data,\n });\n\n if (!restoredDocument) {\n throw new errors.ApplicationError('Failed to restore version');\n }\n\n return restoredDocument;\n },\n };\n};\n\nexport { createHistoryService };\n"],"names":["createHistoryService","strapi","query","db","HISTORY_VERSION_UID","serviceUtils","createServiceUtils","createVersion","historyVersionData","create","data","createdAt","Date","createdBy","requestContext","get","state","user","id","findVersionsPage","params","schema","getModel","contentType","isLocalizedContentType","defaultLocale","getDefaultLocale","locale","results","versionRows","pagination","localeDictionary","Promise","all","findPage","select","where","$and","documentId","relatedDocumentId","orderBy","getLocaleDictionary","ids","map","version","versions","length","findMany","$in","populate","versionsById","Map","filter","Boolean","populateEntry","entry","traverseEntity","options","utils","attribute","value","currentValue","Array","isArray","type","remove","relation","target","adminUsers","userToPopulate","findOne","set","key","permissionChecker","getContentManagerService","userAbility","model","response","buildRelationReponse","sanitizedResults","media","sanitizeOutput","meta","buildMediaResponse","bind","formattedResults","result","unknownAttributes","getSchemaAttributesDiff","attributes","restoreVersion","versionId","contentTypeSchemaAttributes","schemaDiff","dataWithoutAddedAttributes","Object","keys","added","reduce","currentData","addedKey","structuredClone","omit","FIELDS_TO_IGNORE","dataWithoutMissingRelations","repeatable","getRelationRestoreValue","getMediaRestoreValue","removed","restoredDocument","documents","update","errors","ApplicationError"],"mappings":"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"}
1
+ {"version":3,"file":"history.js","sources":["../../../../server/src/history/services/history.ts"],"sourcesContent":["import type { Core, Data, Modules, Schema } from '@strapi/types';\nimport { errors, traverseEntity } from '@strapi/utils';\nimport { omit } from 'lodash';\n\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\nimport type { HistoryVersions } from '../../../../shared/contracts';\nimport type {\n CreateHistoryVersion,\n HistoryVersionDataResponse,\n} from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\nimport { getService as getContentManagerService } from '../../utils';\n\n// Needed because the query engine doesn't return any types yet\ntype HistoryVersionQueryResult = Omit<HistoryVersionDataResponse, 'locale'> &\n Pick<CreateHistoryVersion, 'locale'>;\n\nconst createHistoryService = ({ strapi }: { strapi: Core.Strapi }) => {\n const query = strapi.db.query(HISTORY_VERSION_UID);\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async createVersion(historyVersionData: HistoryVersions.CreateHistoryVersion) {\n await query.create({\n data: {\n ...historyVersionData,\n createdAt: new Date(),\n createdBy: strapi.requestContext.get()?.state?.user.id,\n },\n });\n },\n\n async findVersionsPage(params: HistoryVersions.GetHistoryVersions.Request): Promise<{\n results: HistoryVersions.HistoryVersionDataResponse[];\n pagination: HistoryVersions.Pagination;\n }> {\n const schema = strapi.getModel(params.query.contentType);\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);\n const defaultLocale = await serviceUtils.getDefaultLocale();\n\n let locale = null;\n if (isLocalizedContentType) {\n locale = params.query.locale || defaultLocale;\n }\n\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27393\n const [{ results: versionRows, pagination }, localeDictionary] = await Promise.all([\n query.findPage({\n ...params.query,\n select: ['id'],\n where: {\n $and: [\n { contentType: params.query.contentType },\n ...(params.query.documentId ? [{ relatedDocumentId: params.query.documentId }] : []),\n ...(locale ? [{ locale }] : []),\n ],\n },\n orderBy: [{ createdAt: 'desc' }],\n }),\n serviceUtils.getLocaleDictionary(),\n ]);\n\n const ids = versionRows.map((version) => version.id);\n const versions = ids.length\n ? await query.findMany({\n where: { id: { $in: ids } },\n populate: ['createdBy'],\n })\n : [];\n const versionsById = new Map(versions.map((version) => [version.id, version]));\n const results = ids.map((id) => versionsById.get(id)).filter(Boolean);\n\n const populateEntry = async (entry: HistoryVersionQueryResult) => {\n return traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n if (!options.value) return;\n\n const currentValue: any[] = Array.isArray(options.value)\n ? options.value\n : [options.value];\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (options.attribute.target === 'admin::user') {\n const adminUsers = await Promise.all(\n currentValue.map((userToPopulate) => {\n if (userToPopulate == null) {\n return null;\n }\n\n return strapi.db.query('admin::user').findOne({\n where: {\n ...(userToPopulate.id ? { id: userToPopulate.id } : {}),\n ...(userToPopulate.documentId\n ? { documentId: userToPopulate.documentId }\n : {}),\n },\n });\n })\n );\n\n utils.set(options.key, adminUsers as any);\n }\n\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: options.attribute.target,\n });\n\n const response = await serviceUtils.buildRelationReponse(\n currentValue,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n\n if (options.attribute.type === 'media') {\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: 'plugin::upload.file',\n });\n\n const response = await serviceUtils.buildMediaResponse(currentValue);\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n entry.data\n );\n };\n\n const formattedResults: any[] = await Promise.all(\n (results as HistoryVersionQueryResult[]).map(async (result) => {\n return {\n ...result,\n data: await populateEntry(result),\n meta: {\n unknownAttributes: serviceUtils.getSchemaAttributesDiff(\n result.schema,\n strapi.getModel(params.query.contentType).attributes\n ),\n },\n locale: result.locale ? localeDictionary[result.locale] : null,\n };\n })\n );\n\n return {\n results: formattedResults,\n pagination,\n };\n },\n\n async restoreVersion(versionId: Data.ID) {\n const version = await query.findOne({ where: { id: versionId } });\n const contentTypeSchemaAttributes = strapi.getModel(version.contentType).attributes;\n const schemaDiff = serviceUtils.getSchemaAttributesDiff(\n version.schema,\n contentTypeSchemaAttributes\n );\n\n // Set all added attribute values to null\n const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(\n (currentData, addedKey) => {\n currentData[addedKey] = null;\n return currentData;\n },\n // Clone to avoid mutating the original version data\n structuredClone(version.data)\n );\n\n // Remove the schema attributes history should ignore\n const schema = structuredClone(version.schema);\n schema.attributes = omit(contentTypeSchemaAttributes, FIELDS_TO_IGNORE);\n\n const dataWithoutMissingRelations = await traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n\n if (options.attribute.repeatable && options.value === null) {\n // Repeatable Components should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (options.attribute.type === 'dynamiczone') {\n if (options.value === null) {\n // Dynamic zones should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (!options.value) return;\n\n const data = await serviceUtils.getRelationRestoreValue(\n options.value as Modules.Documents.AnyDocument,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n\n utils.set(options.key, data as Modules.Documents.AnyDocument);\n }\n\n if (options.attribute.type === 'media') {\n if (!options.value) return;\n\n const data = await serviceUtils.getMediaRestoreValue(\n options.value as Modules.Documents.AnyDocument\n );\n\n utils.set(options.key, data);\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n dataWithoutAddedAttributes\n );\n\n const data = omit(dataWithoutMissingRelations, ['id', ...Object.keys(schemaDiff.removed)]);\n const restoredDocument = await strapi.documents(version.contentType).update({\n documentId: version.relatedDocumentId,\n locale: version.locale,\n data,\n });\n\n if (!restoredDocument) {\n throw new errors.ApplicationError('Failed to restore version');\n }\n\n return restoredDocument;\n },\n };\n};\n\nexport { createHistoryService };\n"],"names":["createHistoryService","strapi","query","db","HISTORY_VERSION_UID","serviceUtils","createServiceUtils","createVersion","historyVersionData","create","data","createdAt","Date","createdBy","requestContext","get","state","user","id","findVersionsPage","params","schema","getModel","contentType","isLocalizedContentType","defaultLocale","getDefaultLocale","locale","results","versionRows","pagination","localeDictionary","Promise","all","findPage","select","where","$and","documentId","relatedDocumentId","orderBy","getLocaleDictionary","ids","map","version","versions","length","findMany","$in","populate","versionsById","Map","filter","Boolean","populateEntry","entry","traverseEntity","options","utils","attribute","value","currentValue","Array","isArray","type","remove","relation","target","adminUsers","userToPopulate","findOne","set","key","permissionChecker","getContentManagerService","userAbility","model","response","buildRelationReponse","sanitizedResults","media","sanitizeOutput","meta","buildMediaResponse","bind","formattedResults","result","unknownAttributes","getSchemaAttributesDiff","attributes","restoreVersion","versionId","contentTypeSchemaAttributes","schemaDiff","dataWithoutAddedAttributes","Object","keys","added","reduce","currentData","addedKey","structuredClone","omit","FIELDS_TO_IGNORE","dataWithoutMissingRelations","repeatable","getRelationRestoreValue","getMediaRestoreValue","removed","restoredDocument","documents","update","errors","ApplicationError"],"mappings":"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"}
@@ -94,7 +94,7 @@ const createHistoryService = ({ strapi })=>{
94
94
  if (userToPopulate == null) {
95
95
  return null;
96
96
  }
97
- return strapi.query('admin::user').findOne({
97
+ return strapi.db.query('admin::user').findOne({
98
98
  where: {
99
99
  ...userToPopulate.id ? {
100
100
  id: userToPopulate.id
@@ -1 +1 @@
1
- {"version":3,"file":"history.mjs","sources":["../../../../server/src/history/services/history.ts"],"sourcesContent":["import type { Core, Data, Modules, Schema } from '@strapi/types';\nimport { errors, traverseEntity } from '@strapi/utils';\nimport { omit } from 'lodash';\n\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\nimport type { HistoryVersions } from '../../../../shared/contracts';\nimport type {\n CreateHistoryVersion,\n HistoryVersionDataResponse,\n} from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\nimport { getService as getContentManagerService } from '../../utils';\n\n// Needed because the query engine doesn't return any types yet\ntype HistoryVersionQueryResult = Omit<HistoryVersionDataResponse, 'locale'> &\n Pick<CreateHistoryVersion, 'locale'>;\n\nconst createHistoryService = ({ strapi }: { strapi: Core.Strapi }) => {\n const query = strapi.db.query(HISTORY_VERSION_UID);\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async createVersion(historyVersionData: HistoryVersions.CreateHistoryVersion) {\n await query.create({\n data: {\n ...historyVersionData,\n createdAt: new Date(),\n createdBy: strapi.requestContext.get()?.state?.user.id,\n },\n });\n },\n\n async findVersionsPage(params: HistoryVersions.GetHistoryVersions.Request): Promise<{\n results: HistoryVersions.HistoryVersionDataResponse[];\n pagination: HistoryVersions.Pagination;\n }> {\n const schema = strapi.getModel(params.query.contentType);\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);\n const defaultLocale = await serviceUtils.getDefaultLocale();\n\n let locale = null;\n if (isLocalizedContentType) {\n locale = params.query.locale || defaultLocale;\n }\n\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27393\n const [{ results: versionRows, pagination }, localeDictionary] = await Promise.all([\n query.findPage({\n ...params.query,\n select: ['id'],\n where: {\n $and: [\n { contentType: params.query.contentType },\n ...(params.query.documentId ? [{ relatedDocumentId: params.query.documentId }] : []),\n ...(locale ? [{ locale }] : []),\n ],\n },\n orderBy: [{ createdAt: 'desc' }],\n }),\n serviceUtils.getLocaleDictionary(),\n ]);\n\n const ids = versionRows.map((version) => version.id);\n const versions = ids.length\n ? await query.findMany({\n where: { id: { $in: ids } },\n populate: ['createdBy'],\n })\n : [];\n const versionsById = new Map(versions.map((version) => [version.id, version]));\n const results = ids.map((id) => versionsById.get(id)).filter(Boolean);\n\n const populateEntry = async (entry: HistoryVersionQueryResult) => {\n return traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n if (!options.value) return;\n\n const currentValue: any[] = Array.isArray(options.value)\n ? options.value\n : [options.value];\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (options.attribute.target === 'admin::user') {\n const adminUsers = await Promise.all(\n currentValue.map((userToPopulate) => {\n if (userToPopulate == null) {\n return null;\n }\n\n return strapi.query('admin::user').findOne({\n where: {\n ...(userToPopulate.id ? { id: userToPopulate.id } : {}),\n ...(userToPopulate.documentId\n ? { documentId: userToPopulate.documentId }\n : {}),\n },\n });\n })\n );\n\n utils.set(options.key, adminUsers as any);\n }\n\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: options.attribute.target,\n });\n\n const response = await serviceUtils.buildRelationReponse(\n currentValue,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n\n if (options.attribute.type === 'media') {\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: 'plugin::upload.file',\n });\n\n const response = await serviceUtils.buildMediaResponse(currentValue);\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n entry.data\n );\n };\n\n const formattedResults: any[] = await Promise.all(\n (results as HistoryVersionQueryResult[]).map(async (result) => {\n return {\n ...result,\n data: await populateEntry(result),\n meta: {\n unknownAttributes: serviceUtils.getSchemaAttributesDiff(\n result.schema,\n strapi.getModel(params.query.contentType).attributes\n ),\n },\n locale: result.locale ? localeDictionary[result.locale] : null,\n };\n })\n );\n\n return {\n results: formattedResults,\n pagination,\n };\n },\n\n async restoreVersion(versionId: Data.ID) {\n const version = await query.findOne({ where: { id: versionId } });\n const contentTypeSchemaAttributes = strapi.getModel(version.contentType).attributes;\n const schemaDiff = serviceUtils.getSchemaAttributesDiff(\n version.schema,\n contentTypeSchemaAttributes\n );\n\n // Set all added attribute values to null\n const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(\n (currentData, addedKey) => {\n currentData[addedKey] = null;\n return currentData;\n },\n // Clone to avoid mutating the original version data\n structuredClone(version.data)\n );\n\n // Remove the schema attributes history should ignore\n const schema = structuredClone(version.schema);\n schema.attributes = omit(contentTypeSchemaAttributes, FIELDS_TO_IGNORE);\n\n const dataWithoutMissingRelations = await traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n\n if (options.attribute.repeatable && options.value === null) {\n // Repeatable Components should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (options.attribute.type === 'dynamiczone') {\n if (options.value === null) {\n // Dynamic zones should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (!options.value) return;\n\n const data = await serviceUtils.getRelationRestoreValue(\n options.value as Modules.Documents.AnyDocument,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n\n utils.set(options.key, data as Modules.Documents.AnyDocument);\n }\n\n if (options.attribute.type === 'media') {\n if (!options.value) return;\n\n const data = await serviceUtils.getMediaRestoreValue(\n options.value as Modules.Documents.AnyDocument\n );\n\n utils.set(options.key, data);\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n dataWithoutAddedAttributes\n );\n\n const data = omit(dataWithoutMissingRelations, ['id', ...Object.keys(schemaDiff.removed)]);\n const restoredDocument = await strapi.documents(version.contentType).update({\n documentId: version.relatedDocumentId,\n locale: version.locale,\n data,\n });\n\n if (!restoredDocument) {\n throw new errors.ApplicationError('Failed to restore version');\n }\n\n return restoredDocument;\n },\n };\n};\n\nexport { createHistoryService };\n"],"names":["createHistoryService","strapi","query","db","HISTORY_VERSION_UID","serviceUtils","createServiceUtils","createVersion","historyVersionData","create","data","createdAt","Date","createdBy","requestContext","get","state","user","id","findVersionsPage","params","schema","getModel","contentType","isLocalizedContentType","defaultLocale","getDefaultLocale","locale","results","versionRows","pagination","localeDictionary","Promise","all","findPage","select","where","$and","documentId","relatedDocumentId","orderBy","getLocaleDictionary","ids","map","version","versions","length","findMany","$in","populate","versionsById","Map","filter","Boolean","populateEntry","entry","traverseEntity","options","utils","attribute","value","currentValue","Array","isArray","type","remove","relation","target","adminUsers","userToPopulate","findOne","set","key","permissionChecker","getContentManagerService","userAbility","model","response","buildRelationReponse","sanitizedResults","media","sanitizeOutput","meta","buildMediaResponse","bind","formattedResults","result","unknownAttributes","getSchemaAttributesDiff","attributes","restoreVersion","versionId","contentTypeSchemaAttributes","schemaDiff","dataWithoutAddedAttributes","Object","keys","added","reduce","currentData","addedKey","structuredClone","omit","FIELDS_TO_IGNORE","dataWithoutMissingRelations","repeatable","getRelationRestoreValue","getMediaRestoreValue","removed","restoredDocument","documents","update","errors","ApplicationError"],"mappings":"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"}
1
+ {"version":3,"file":"history.mjs","sources":["../../../../server/src/history/services/history.ts"],"sourcesContent":["import type { Core, Data, Modules, Schema } from '@strapi/types';\nimport { errors, traverseEntity } from '@strapi/utils';\nimport { omit } from 'lodash';\n\nimport { FIELDS_TO_IGNORE, HISTORY_VERSION_UID } from '../constants';\nimport type { HistoryVersions } from '../../../../shared/contracts';\nimport type {\n CreateHistoryVersion,\n HistoryVersionDataResponse,\n} from '../../../../shared/contracts/history-versions';\nimport { createServiceUtils } from './utils';\nimport { getService as getContentManagerService } from '../../utils';\n\n// Needed because the query engine doesn't return any types yet\ntype HistoryVersionQueryResult = Omit<HistoryVersionDataResponse, 'locale'> &\n Pick<CreateHistoryVersion, 'locale'>;\n\nconst createHistoryService = ({ strapi }: { strapi: Core.Strapi }) => {\n const query = strapi.db.query(HISTORY_VERSION_UID);\n const serviceUtils = createServiceUtils({ strapi });\n\n return {\n async createVersion(historyVersionData: HistoryVersions.CreateHistoryVersion) {\n await query.create({\n data: {\n ...historyVersionData,\n createdAt: new Date(),\n createdBy: strapi.requestContext.get()?.state?.user.id,\n },\n });\n },\n\n async findVersionsPage(params: HistoryVersions.GetHistoryVersions.Request): Promise<{\n results: HistoryVersions.HistoryVersionDataResponse[];\n pagination: HistoryVersions.Pagination;\n }> {\n const schema = strapi.getModel(params.query.contentType);\n const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);\n const defaultLocale = await serviceUtils.getDefaultLocale();\n\n let locale = null;\n if (isLocalizedContentType) {\n locale = params.query.locale || defaultLocale;\n }\n\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27393\n const [{ results: versionRows, pagination }, localeDictionary] = await Promise.all([\n query.findPage({\n ...params.query,\n select: ['id'],\n where: {\n $and: [\n { contentType: params.query.contentType },\n ...(params.query.documentId ? [{ relatedDocumentId: params.query.documentId }] : []),\n ...(locale ? [{ locale }] : []),\n ],\n },\n orderBy: [{ createdAt: 'desc' }],\n }),\n serviceUtils.getLocaleDictionary(),\n ]);\n\n const ids = versionRows.map((version) => version.id);\n const versions = ids.length\n ? await query.findMany({\n where: { id: { $in: ids } },\n populate: ['createdBy'],\n })\n : [];\n const versionsById = new Map(versions.map((version) => [version.id, version]));\n const results = ids.map((id) => versionsById.get(id)).filter(Boolean);\n\n const populateEntry = async (entry: HistoryVersionQueryResult) => {\n return traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n if (!options.value) return;\n\n const currentValue: any[] = Array.isArray(options.value)\n ? options.value\n : [options.value];\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (options.attribute.target === 'admin::user') {\n const adminUsers = await Promise.all(\n currentValue.map((userToPopulate) => {\n if (userToPopulate == null) {\n return null;\n }\n\n return strapi.db.query('admin::user').findOne({\n where: {\n ...(userToPopulate.id ? { id: userToPopulate.id } : {}),\n ...(userToPopulate.documentId\n ? { documentId: userToPopulate.documentId }\n : {}),\n },\n });\n })\n );\n\n utils.set(options.key, adminUsers as any);\n }\n\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: options.attribute.target,\n });\n\n const response = await serviceUtils.buildRelationReponse(\n currentValue,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n\n if (options.attribute.type === 'media') {\n const permissionChecker = getContentManagerService('permission-checker').create({\n userAbility: params.state.userAbility,\n model: 'plugin::upload.file',\n });\n\n const response = await serviceUtils.buildMediaResponse(currentValue);\n const sanitizedResults = await Promise.all(\n response.results.map((media) => permissionChecker.sanitizeOutput(media))\n );\n\n utils.set(options.key, {\n results: sanitizedResults,\n meta: response.meta,\n });\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n entry.data\n );\n };\n\n const formattedResults: any[] = await Promise.all(\n (results as HistoryVersionQueryResult[]).map(async (result) => {\n return {\n ...result,\n data: await populateEntry(result),\n meta: {\n unknownAttributes: serviceUtils.getSchemaAttributesDiff(\n result.schema,\n strapi.getModel(params.query.contentType).attributes\n ),\n },\n locale: result.locale ? localeDictionary[result.locale] : null,\n };\n })\n );\n\n return {\n results: formattedResults,\n pagination,\n };\n },\n\n async restoreVersion(versionId: Data.ID) {\n const version = await query.findOne({ where: { id: versionId } });\n const contentTypeSchemaAttributes = strapi.getModel(version.contentType).attributes;\n const schemaDiff = serviceUtils.getSchemaAttributesDiff(\n version.schema,\n contentTypeSchemaAttributes\n );\n\n // Set all added attribute values to null\n const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(\n (currentData, addedKey) => {\n currentData[addedKey] = null;\n return currentData;\n },\n // Clone to avoid mutating the original version data\n structuredClone(version.data)\n );\n\n // Remove the schema attributes history should ignore\n const schema = structuredClone(version.schema);\n schema.attributes = omit(contentTypeSchemaAttributes, FIELDS_TO_IGNORE);\n\n const dataWithoutMissingRelations = await traverseEntity(\n async (options, utils) => {\n if (!options.attribute) return;\n\n if (options.attribute.type === 'component') {\n // Ids on components throw an error when restoring\n utils.remove('id');\n\n if (options.attribute.repeatable && options.value === null) {\n // Repeatable Components should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (options.attribute.type === 'dynamiczone') {\n if (options.value === null) {\n // Dynamic zones should always be an array\n utils.set(options.key, [] as any);\n }\n }\n\n if (\n options.attribute.type === 'relation' &&\n // TODO: handle polymorphic relations\n options.attribute.relation !== 'morphToOne' &&\n options.attribute.relation !== 'morphToMany'\n ) {\n if (!options.value) return;\n\n const data = await serviceUtils.getRelationRestoreValue(\n options.value as Modules.Documents.AnyDocument,\n options.attribute as Schema.Attribute.RelationWithTarget\n );\n\n utils.set(options.key, data as Modules.Documents.AnyDocument);\n }\n\n if (options.attribute.type === 'media') {\n if (!options.value) return;\n\n const data = await serviceUtils.getMediaRestoreValue(\n options.value as Modules.Documents.AnyDocument\n );\n\n utils.set(options.key, data);\n }\n },\n {\n schema,\n getModel: strapi.getModel.bind(strapi),\n },\n dataWithoutAddedAttributes\n );\n\n const data = omit(dataWithoutMissingRelations, ['id', ...Object.keys(schemaDiff.removed)]);\n const restoredDocument = await strapi.documents(version.contentType).update({\n documentId: version.relatedDocumentId,\n locale: version.locale,\n data,\n });\n\n if (!restoredDocument) {\n throw new errors.ApplicationError('Failed to restore version');\n }\n\n return restoredDocument;\n },\n };\n};\n\nexport { createHistoryService };\n"],"names":["createHistoryService","strapi","query","db","HISTORY_VERSION_UID","serviceUtils","createServiceUtils","createVersion","historyVersionData","create","data","createdAt","Date","createdBy","requestContext","get","state","user","id","findVersionsPage","params","schema","getModel","contentType","isLocalizedContentType","defaultLocale","getDefaultLocale","locale","results","versionRows","pagination","localeDictionary","Promise","all","findPage","select","where","$and","documentId","relatedDocumentId","orderBy","getLocaleDictionary","ids","map","version","versions","length","findMany","$in","populate","versionsById","Map","filter","Boolean","populateEntry","entry","traverseEntity","options","utils","attribute","value","currentValue","Array","isArray","type","remove","relation","target","adminUsers","userToPopulate","findOne","set","key","permissionChecker","getContentManagerService","userAbility","model","response","buildRelationReponse","sanitizedResults","media","sanitizeOutput","meta","buildMediaResponse","bind","formattedResults","result","unknownAttributes","getSchemaAttributesDiff","attributes","restoreVersion","versionId","contentTypeSchemaAttributes","schemaDiff","dataWithoutAddedAttributes","Object","keys","added","reduce","currentData","addedKey","structuredClone","omit","FIELDS_TO_IGNORE","dataWithoutMissingRelations","repeatable","getRelationRestoreValue","getMediaRestoreValue","removed","restoredDocument","documents","update","errors","ApplicationError"],"mappings":"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"}
@@ -79,8 +79,15 @@ var sortSchema = require('./sort-schema.js');
79
79
  if (scalarKeys.length === 0) {
80
80
  return strapiUtils.z.never();
81
81
  }
82
- // Lazy reference for recursion ($and / $or / $not)
82
+ // Lazy reference for recursion ($and / $or / $not).
83
+ // The getter is memoized: zod's JSON Schema conversion calls `def.getter()` directly for every
84
+ // node that reaches the lazy, bypassing zod's own cache, so an unmemoized getter rebuilds the
85
+ // whole object (fields x operators) many times per conversion.
86
+ let resolvedFiltersObject;
83
87
  const filtersSchema = strapiUtils.z.lazy(()=>{
88
+ if (resolvedFiltersObject !== undefined) {
89
+ return resolvedFiltersObject;
90
+ }
84
91
  const fieldShapes = {};
85
92
  for (const key of scalarKeys){
86
93
  const attr = attributes[key];
@@ -95,12 +102,13 @@ var sortSchema = require('./sort-schema.js');
95
102
  operatorObject
96
103
  ]).optional();
97
104
  }
98
- return strapiUtils.z.object({
105
+ resolvedFiltersObject = strapiUtils.z.object({
99
106
  $and: strapiUtils.z.array(filtersSchema).optional(),
100
107
  $or: strapiUtils.z.array(filtersSchema).optional(),
101
108
  $not: filtersSchema.optional(),
102
109
  ...fieldShapes
103
110
  }).strict();
111
+ return resolvedFiltersObject;
104
112
  });
105
113
  return filtersSchema.optional().describe(`Filter object. Supports logical operators ($and, $or, $not) and field operators ` + `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`);
106
114
  };
@@ -1 +1 @@
1
- {"version":3,"file":"filters-schema.js","sources":["../../../../server/src/mcp/schemas/filters-schema.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Schema, Struct } from '@strapi/types';\nimport { getScalarAttributeKeys } from './sort-schema';\n\n/**\n * Maps a scalar Strapi attribute type to the appropriate Zod leaf value schema\n * used inside filter operator objects (e.g. { $eq: <value> }).\n */\nexport const attributeTypeToFilterValue = (attr: Schema.Attribute.AnyAttribute): z.ZodTypeAny => {\n switch (attr.type) {\n case 'integer':\n case 'biginteger':\n case 'decimal':\n case 'float':\n return z.union([z.number(), z.array(z.number())]);\n case 'boolean':\n return z.boolean();\n case 'enumeration': {\n const enumAttr = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(enumAttr.enum) && enumAttr.enum.length > 0) {\n return z.union([\n z.enum(enumAttr.enum as [string, ...string[]]),\n z.array(z.enum(enumAttr.enum as [string, ...string[]])),\n ]);\n }\n return z.union([z.string(), z.array(z.string())]);\n }\n default:\n // string, text, richtext, email, password, uid, date, datetime, time, timestamp\n return z.union([z.string(), z.array(z.string()), z.null()]);\n }\n};\n\n/** All supported Strapi filter operators (excludes the experimental `$jsonSupersetOf`). */\nexport const FILTER_OPERATORS = [\n '$eq',\n '$eqi',\n '$ne',\n '$nei',\n '$in',\n '$notIn',\n '$lt',\n '$lte',\n '$gt',\n '$gte',\n '$between',\n '$contains',\n '$notContains',\n '$containsi',\n '$notContainsi',\n '$startsWith',\n '$startsWithi',\n '$endsWith',\n '$endsWithi',\n '$null',\n '$notNull',\n] as const;\n\n/**\n * Builds a per-content-type recursive filters Zod schema.\n *\n * Shape:\n * - Logical operators: $and, $or accept an array of filter objects.\n * - Logical operator: $not accepts a single filter object.\n * - Field keys (scalar attrs only): accept either a direct value (implicit $eq)\n * or an operator object { $eq, $contains, $gt, … }.\n *\n * If the model has no scalar attributes, the schema is z.never() (filters not allowed).\n */\nexport const buildFiltersSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const scalarKeys = getScalarAttributeKeys(attributes, permittedFields);\n\n if (scalarKeys.length === 0) {\n return z.never();\n }\n\n // Lazy reference for recursion ($and / $or / $not)\n const filtersSchema: z.ZodTypeAny = z.lazy(() => {\n const fieldShapes: Record<string, z.ZodTypeAny> = {};\n\n for (const key of scalarKeys) {\n const attr = attributes[key];\n const valueSchema = attributeTypeToFilterValue(attr);\n const operatorObject = z.object(\n Object.fromEntries(FILTER_OPERATORS.map((op) => [op, valueSchema.optional()]))\n );\n // Field accepts either a direct value (implicit $eq) or operator object\n fieldShapes[key] = z.union([valueSchema, operatorObject]).optional();\n }\n\n return z\n .object({\n $and: z.array(filtersSchema).optional(),\n $or: z.array(filtersSchema).optional(),\n $not: filtersSchema.optional(),\n ...fieldShapes,\n })\n .strict();\n });\n\n return filtersSchema\n .optional()\n .describe(\n `Filter object. Supports logical operators ($and, $or, $not) and field operators ` +\n `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`\n );\n};\n"],"names":["attributeTypeToFilterValue","attr","type","z","union","number","array","boolean","enumAttr","Array","isArray","enum","length","string","null","FILTER_OPERATORS","buildFiltersSchema","attributes","permittedFields","scalarKeys","getScalarAttributeKeys","never","filtersSchema","lazy","fieldShapes","key","valueSchema","operatorObject","object","Object","fromEntries","map","op","optional","$and","$or","$not","strict","describe","join"],"mappings":"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"}
1
+ {"version":3,"file":"filters-schema.js","sources":["../../../../server/src/mcp/schemas/filters-schema.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Schema, Struct } from '@strapi/types';\nimport { getScalarAttributeKeys } from './sort-schema';\n\n/**\n * Maps a scalar Strapi attribute type to the appropriate Zod leaf value schema\n * used inside filter operator objects (e.g. { $eq: <value> }).\n */\nexport const attributeTypeToFilterValue = (attr: Schema.Attribute.AnyAttribute): z.ZodTypeAny => {\n switch (attr.type) {\n case 'integer':\n case 'biginteger':\n case 'decimal':\n case 'float':\n return z.union([z.number(), z.array(z.number())]);\n case 'boolean':\n return z.boolean();\n case 'enumeration': {\n const enumAttr = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(enumAttr.enum) && enumAttr.enum.length > 0) {\n return z.union([\n z.enum(enumAttr.enum as [string, ...string[]]),\n z.array(z.enum(enumAttr.enum as [string, ...string[]])),\n ]);\n }\n return z.union([z.string(), z.array(z.string())]);\n }\n default:\n // string, text, richtext, email, password, uid, date, datetime, time, timestamp\n return z.union([z.string(), z.array(z.string()), z.null()]);\n }\n};\n\n/** All supported Strapi filter operators (excludes the experimental `$jsonSupersetOf`). */\nexport const FILTER_OPERATORS = [\n '$eq',\n '$eqi',\n '$ne',\n '$nei',\n '$in',\n '$notIn',\n '$lt',\n '$lte',\n '$gt',\n '$gte',\n '$between',\n '$contains',\n '$notContains',\n '$containsi',\n '$notContainsi',\n '$startsWith',\n '$startsWithi',\n '$endsWith',\n '$endsWithi',\n '$null',\n '$notNull',\n] as const;\n\n/**\n * Builds a per-content-type recursive filters Zod schema.\n *\n * Shape:\n * - Logical operators: $and, $or accept an array of filter objects.\n * - Logical operator: $not accepts a single filter object.\n * - Field keys (scalar attrs only): accept either a direct value (implicit $eq)\n * or an operator object { $eq, $contains, $gt, … }.\n *\n * If the model has no scalar attributes, the schema is z.never() (filters not allowed).\n */\nexport const buildFiltersSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const scalarKeys = getScalarAttributeKeys(attributes, permittedFields);\n\n if (scalarKeys.length === 0) {\n return z.never();\n }\n\n // Lazy reference for recursion ($and / $or / $not).\n // The getter is memoized: zod's JSON Schema conversion calls `def.getter()` directly for every\n // node that reaches the lazy, bypassing zod's own cache, so an unmemoized getter rebuilds the\n // whole object (fields x operators) many times per conversion.\n let resolvedFiltersObject: z.ZodTypeAny | undefined;\n const filtersSchema: z.ZodTypeAny = z.lazy(() => {\n if (resolvedFiltersObject !== undefined) {\n return resolvedFiltersObject;\n }\n\n const fieldShapes: Record<string, z.ZodTypeAny> = {};\n\n for (const key of scalarKeys) {\n const attr = attributes[key];\n const valueSchema = attributeTypeToFilterValue(attr);\n const operatorObject = z.object(\n Object.fromEntries(FILTER_OPERATORS.map((op) => [op, valueSchema.optional()]))\n );\n // Field accepts either a direct value (implicit $eq) or operator object\n fieldShapes[key] = z.union([valueSchema, operatorObject]).optional();\n }\n\n resolvedFiltersObject = z\n .object({\n $and: z.array(filtersSchema).optional(),\n $or: z.array(filtersSchema).optional(),\n $not: filtersSchema.optional(),\n ...fieldShapes,\n })\n .strict();\n\n return resolvedFiltersObject;\n });\n\n return filtersSchema\n .optional()\n .describe(\n `Filter object. Supports logical operators ($and, $or, $not) and field operators ` +\n `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`\n );\n};\n"],"names":["attributeTypeToFilterValue","attr","type","z","union","number","array","boolean","enumAttr","Array","isArray","enum","length","string","null","FILTER_OPERATORS","buildFiltersSchema","attributes","permittedFields","scalarKeys","getScalarAttributeKeys","never","resolvedFiltersObject","filtersSchema","lazy","undefined","fieldShapes","key","valueSchema","operatorObject","object","Object","fromEntries","map","op","optional","$and","$or","$not","strict","describe","join"],"mappings":"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"}
@@ -77,8 +77,15 @@ import { getScalarAttributeKeys } from './sort-schema.mjs';
77
77
  if (scalarKeys.length === 0) {
78
78
  return z.never();
79
79
  }
80
- // Lazy reference for recursion ($and / $or / $not)
80
+ // Lazy reference for recursion ($and / $or / $not).
81
+ // The getter is memoized: zod's JSON Schema conversion calls `def.getter()` directly for every
82
+ // node that reaches the lazy, bypassing zod's own cache, so an unmemoized getter rebuilds the
83
+ // whole object (fields x operators) many times per conversion.
84
+ let resolvedFiltersObject;
81
85
  const filtersSchema = z.lazy(()=>{
86
+ if (resolvedFiltersObject !== undefined) {
87
+ return resolvedFiltersObject;
88
+ }
82
89
  const fieldShapes = {};
83
90
  for (const key of scalarKeys){
84
91
  const attr = attributes[key];
@@ -93,12 +100,13 @@ import { getScalarAttributeKeys } from './sort-schema.mjs';
93
100
  operatorObject
94
101
  ]).optional();
95
102
  }
96
- return z.object({
103
+ resolvedFiltersObject = z.object({
97
104
  $and: z.array(filtersSchema).optional(),
98
105
  $or: z.array(filtersSchema).optional(),
99
106
  $not: filtersSchema.optional(),
100
107
  ...fieldShapes
101
108
  }).strict();
109
+ return resolvedFiltersObject;
102
110
  });
103
111
  return filtersSchema.optional().describe(`Filter object. Supports logical operators ($and, $or, $not) and field operators ` + `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`);
104
112
  };
@@ -1 +1 @@
1
- {"version":3,"file":"filters-schema.mjs","sources":["../../../../server/src/mcp/schemas/filters-schema.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Schema, Struct } from '@strapi/types';\nimport { getScalarAttributeKeys } from './sort-schema';\n\n/**\n * Maps a scalar Strapi attribute type to the appropriate Zod leaf value schema\n * used inside filter operator objects (e.g. { $eq: <value> }).\n */\nexport const attributeTypeToFilterValue = (attr: Schema.Attribute.AnyAttribute): z.ZodTypeAny => {\n switch (attr.type) {\n case 'integer':\n case 'biginteger':\n case 'decimal':\n case 'float':\n return z.union([z.number(), z.array(z.number())]);\n case 'boolean':\n return z.boolean();\n case 'enumeration': {\n const enumAttr = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(enumAttr.enum) && enumAttr.enum.length > 0) {\n return z.union([\n z.enum(enumAttr.enum as [string, ...string[]]),\n z.array(z.enum(enumAttr.enum as [string, ...string[]])),\n ]);\n }\n return z.union([z.string(), z.array(z.string())]);\n }\n default:\n // string, text, richtext, email, password, uid, date, datetime, time, timestamp\n return z.union([z.string(), z.array(z.string()), z.null()]);\n }\n};\n\n/** All supported Strapi filter operators (excludes the experimental `$jsonSupersetOf`). */\nexport const FILTER_OPERATORS = [\n '$eq',\n '$eqi',\n '$ne',\n '$nei',\n '$in',\n '$notIn',\n '$lt',\n '$lte',\n '$gt',\n '$gte',\n '$between',\n '$contains',\n '$notContains',\n '$containsi',\n '$notContainsi',\n '$startsWith',\n '$startsWithi',\n '$endsWith',\n '$endsWithi',\n '$null',\n '$notNull',\n] as const;\n\n/**\n * Builds a per-content-type recursive filters Zod schema.\n *\n * Shape:\n * - Logical operators: $and, $or accept an array of filter objects.\n * - Logical operator: $not accepts a single filter object.\n * - Field keys (scalar attrs only): accept either a direct value (implicit $eq)\n * or an operator object { $eq, $contains, $gt, … }.\n *\n * If the model has no scalar attributes, the schema is z.never() (filters not allowed).\n */\nexport const buildFiltersSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const scalarKeys = getScalarAttributeKeys(attributes, permittedFields);\n\n if (scalarKeys.length === 0) {\n return z.never();\n }\n\n // Lazy reference for recursion ($and / $or / $not)\n const filtersSchema: z.ZodTypeAny = z.lazy(() => {\n const fieldShapes: Record<string, z.ZodTypeAny> = {};\n\n for (const key of scalarKeys) {\n const attr = attributes[key];\n const valueSchema = attributeTypeToFilterValue(attr);\n const operatorObject = z.object(\n Object.fromEntries(FILTER_OPERATORS.map((op) => [op, valueSchema.optional()]))\n );\n // Field accepts either a direct value (implicit $eq) or operator object\n fieldShapes[key] = z.union([valueSchema, operatorObject]).optional();\n }\n\n return z\n .object({\n $and: z.array(filtersSchema).optional(),\n $or: z.array(filtersSchema).optional(),\n $not: filtersSchema.optional(),\n ...fieldShapes,\n })\n .strict();\n });\n\n return filtersSchema\n .optional()\n .describe(\n `Filter object. Supports logical operators ($and, $or, $not) and field operators ` +\n `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`\n );\n};\n"],"names":["attributeTypeToFilterValue","attr","type","z","union","number","array","boolean","enumAttr","Array","isArray","enum","length","string","null","FILTER_OPERATORS","buildFiltersSchema","attributes","permittedFields","scalarKeys","getScalarAttributeKeys","never","filtersSchema","lazy","fieldShapes","key","valueSchema","operatorObject","object","Object","fromEntries","map","op","optional","$and","$or","$not","strict","describe","join"],"mappings":";;;AAIA;;;IAIO,MAAMA,0BAAAA,GAA6B,CAACC,IAAAA,GAAAA;AACzC,IAAA,OAAQA,KAAKC,IAAI;QACf,KAAK,SAAA;QACL,KAAK,YAAA;QACL,KAAK,SAAA;QACL,KAAK,OAAA;YACH,OAAOC,CAAAA,CAAEC,KAAK,CAAC;AAACD,gBAAAA,CAAAA,CAAEE,MAAM,EAAA;gBAAIF,CAAAA,CAAEG,KAAK,CAACH,CAAAA,CAAEE,MAAM,EAAA;AAAI,aAAA,CAAA;QAClD,KAAK,SAAA;AACH,YAAA,OAAOF,EAAEI,OAAO,EAAA;QAClB,KAAK,aAAA;AAAe,YAAA;AAClB,gBAAA,MAAMC,QAAAA,GAAWP,IAAAA;gBACjB,IAAIQ,KAAAA,CAAMC,OAAO,CAACF,QAAAA,CAASG,IAAI,CAAA,IAAKH,QAAAA,CAASG,IAAI,CAACC,MAAM,GAAG,CAAA,EAAG;oBAC5D,OAAOT,CAAAA,CAAEC,KAAK,CAAC;wBACbD,CAAAA,CAAEQ,IAAI,CAACH,QAAAA,CAASG,IAAI,CAAA;AACpBR,wBAAAA,CAAAA,CAAEG,KAAK,CAACH,CAAAA,CAAEQ,IAAI,CAACH,SAASG,IAAI,CAAA;AAC7B,qBAAA,CAAA;AACH,gBAAA;gBACA,OAAOR,CAAAA,CAAEC,KAAK,CAAC;AAACD,oBAAAA,CAAAA,CAAEU,MAAM,EAAA;oBAAIV,CAAAA,CAAEG,KAAK,CAACH,CAAAA,CAAEU,MAAM,EAAA;AAAI,iBAAA,CAAA;AAClD,YAAA;AACA,QAAA;;YAEE,OAAOV,CAAAA,CAAEC,KAAK,CAAC;AAACD,gBAAAA,CAAAA,CAAEU,MAAM,EAAA;gBAAIV,CAAAA,CAAEG,KAAK,CAACH,CAAAA,CAAEU,MAAM,EAAA,CAAA;AAAKV,gBAAAA,CAAAA,CAAEW,IAAI;AAAG,aAAA,CAAA;AAC9D;AACF;AAEA,4FACO,MAAMC,gBAAAA,GAAmB;AAC9B,IAAA,KAAA;AACA,IAAA,MAAA;AACA,IAAA,KAAA;AACA,IAAA,MAAA;AACA,IAAA,KAAA;AACA,IAAA,QAAA;AACA,IAAA,KAAA;AACA,IAAA,MAAA;AACA,IAAA,KAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,WAAA;AACA,IAAA,cAAA;AACA,IAAA,YAAA;AACA,IAAA,eAAA;AACA,IAAA,aAAA;AACA,IAAA,cAAA;AACA,IAAA,WAAA;AACA,IAAA,YAAA;AACA,IAAA,OAAA;AACA,IAAA;;AAGF;;;;;;;;;;AAUC,IACM,MAAMC,kBAAAA,GAAqB,CAChCC,UAAAA,EACAC,eAAAA,GAAAA;IAEA,MAAMC,UAAAA,GAAaC,uBAAuBH,UAAAA,EAAYC,eAAAA,CAAAA;IAEtD,IAAIC,UAAAA,CAAWP,MAAM,KAAK,CAAA,EAAG;AAC3B,QAAA,OAAOT,EAAEkB,KAAK,EAAA;AAChB,IAAA;;IAGA,MAAMC,aAAAA,GAA8BnB,CAAAA,CAAEoB,IAAI,CAAC,IAAA;AACzC,QAAA,MAAMC,cAA4C,EAAC;QAEnD,KAAK,MAAMC,OAAON,UAAAA,CAAY;YAC5B,MAAMlB,IAAAA,GAAOgB,UAAU,CAACQ,GAAAA,CAAI;AAC5B,YAAA,MAAMC,cAAc1B,0BAAAA,CAA2BC,IAAAA,CAAAA;YAC/C,MAAM0B,cAAAA,GAAiBxB,CAAAA,CAAEyB,MAAM,CAC7BC,MAAAA,CAAOC,WAAW,CAACf,gBAAAA,CAAiBgB,GAAG,CAAC,CAACC,EAAAA,GAAO;AAACA,oBAAAA,EAAAA;AAAIN,oBAAAA,WAAAA,CAAYO,QAAQ;AAAG,iBAAA,CAAA,CAAA,CAAA;;AAG9ET,YAAAA,WAAW,CAACC,GAAAA,CAAI,GAAGtB,CAAAA,CAAEC,KAAK,CAAC;AAACsB,gBAAAA,WAAAA;AAAaC,gBAAAA;AAAe,aAAA,CAAA,CAAEM,QAAQ,EAAA;AACpE,QAAA;QAEA,OAAO9B,CAAAA,CACJyB,MAAM,CAAC;AACNM,YAAAA,IAAAA,EAAM/B,CAAAA,CAAEG,KAAK,CAACgB,aAAAA,CAAAA,CAAeW,QAAQ,EAAA;AACrCE,YAAAA,GAAAA,EAAKhC,CAAAA,CAAEG,KAAK,CAACgB,aAAAA,CAAAA,CAAeW,QAAQ,EAAA;AACpCG,YAAAA,IAAAA,EAAMd,cAAcW,QAAQ,EAAA;AAC5B,YAAA,GAAGT;AACL,SAAA,CAAA,CACCa,MAAM,EAAA;AACX,IAAA,CAAA,CAAA;AAEA,IAAA,OAAOf,cACJW,QAAQ,EAAA,CACRK,QAAQ,CACP,CAAC,gFAAgF,CAAC,GAChF,CAAC,0DAA0D,EAAEnB,UAAAA,CAAWoB,IAAI,CAAC,IAAA,CAAA,CAAM,CAAC,CAAC,CAAA;AAE7F;;;;"}
1
+ {"version":3,"file":"filters-schema.mjs","sources":["../../../../server/src/mcp/schemas/filters-schema.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Schema, Struct } from '@strapi/types';\nimport { getScalarAttributeKeys } from './sort-schema';\n\n/**\n * Maps a scalar Strapi attribute type to the appropriate Zod leaf value schema\n * used inside filter operator objects (e.g. { $eq: <value> }).\n */\nexport const attributeTypeToFilterValue = (attr: Schema.Attribute.AnyAttribute): z.ZodTypeAny => {\n switch (attr.type) {\n case 'integer':\n case 'biginteger':\n case 'decimal':\n case 'float':\n return z.union([z.number(), z.array(z.number())]);\n case 'boolean':\n return z.boolean();\n case 'enumeration': {\n const enumAttr = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(enumAttr.enum) && enumAttr.enum.length > 0) {\n return z.union([\n z.enum(enumAttr.enum as [string, ...string[]]),\n z.array(z.enum(enumAttr.enum as [string, ...string[]])),\n ]);\n }\n return z.union([z.string(), z.array(z.string())]);\n }\n default:\n // string, text, richtext, email, password, uid, date, datetime, time, timestamp\n return z.union([z.string(), z.array(z.string()), z.null()]);\n }\n};\n\n/** All supported Strapi filter operators (excludes the experimental `$jsonSupersetOf`). */\nexport const FILTER_OPERATORS = [\n '$eq',\n '$eqi',\n '$ne',\n '$nei',\n '$in',\n '$notIn',\n '$lt',\n '$lte',\n '$gt',\n '$gte',\n '$between',\n '$contains',\n '$notContains',\n '$containsi',\n '$notContainsi',\n '$startsWith',\n '$startsWithi',\n '$endsWith',\n '$endsWithi',\n '$null',\n '$notNull',\n] as const;\n\n/**\n * Builds a per-content-type recursive filters Zod schema.\n *\n * Shape:\n * - Logical operators: $and, $or accept an array of filter objects.\n * - Logical operator: $not accepts a single filter object.\n * - Field keys (scalar attrs only): accept either a direct value (implicit $eq)\n * or an operator object { $eq, $contains, $gt, … }.\n *\n * If the model has no scalar attributes, the schema is z.never() (filters not allowed).\n */\nexport const buildFiltersSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const scalarKeys = getScalarAttributeKeys(attributes, permittedFields);\n\n if (scalarKeys.length === 0) {\n return z.never();\n }\n\n // Lazy reference for recursion ($and / $or / $not).\n // The getter is memoized: zod's JSON Schema conversion calls `def.getter()` directly for every\n // node that reaches the lazy, bypassing zod's own cache, so an unmemoized getter rebuilds the\n // whole object (fields x operators) many times per conversion.\n let resolvedFiltersObject: z.ZodTypeAny | undefined;\n const filtersSchema: z.ZodTypeAny = z.lazy(() => {\n if (resolvedFiltersObject !== undefined) {\n return resolvedFiltersObject;\n }\n\n const fieldShapes: Record<string, z.ZodTypeAny> = {};\n\n for (const key of scalarKeys) {\n const attr = attributes[key];\n const valueSchema = attributeTypeToFilterValue(attr);\n const operatorObject = z.object(\n Object.fromEntries(FILTER_OPERATORS.map((op) => [op, valueSchema.optional()]))\n );\n // Field accepts either a direct value (implicit $eq) or operator object\n fieldShapes[key] = z.union([valueSchema, operatorObject]).optional();\n }\n\n resolvedFiltersObject = z\n .object({\n $and: z.array(filtersSchema).optional(),\n $or: z.array(filtersSchema).optional(),\n $not: filtersSchema.optional(),\n ...fieldShapes,\n })\n .strict();\n\n return resolvedFiltersObject;\n });\n\n return filtersSchema\n .optional()\n .describe(\n `Filter object. Supports logical operators ($and, $or, $not) and field operators ` +\n `($eq, $ne, $in, $contains, $gt, $lt, etc.). Valid fields: ${scalarKeys.join(', ')}.`\n );\n};\n"],"names":["attributeTypeToFilterValue","attr","type","z","union","number","array","boolean","enumAttr","Array","isArray","enum","length","string","null","FILTER_OPERATORS","buildFiltersSchema","attributes","permittedFields","scalarKeys","getScalarAttributeKeys","never","resolvedFiltersObject","filtersSchema","lazy","undefined","fieldShapes","key","valueSchema","operatorObject","object","Object","fromEntries","map","op","optional","$and","$or","$not","strict","describe","join"],"mappings":"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"}
@@ -7,7 +7,7 @@ const getPreviewUrlSchema = strapiUtils.z.object({
7
7
  // Will be undefined for single types
8
8
  documentId: strapiUtils.z.string().optional(),
9
9
  locale: strapiUtils.z.string().nullable().optional(),
10
- status: strapiUtils.z.string().optional()
10
+ status: strapiUtils.statusSchema.optional()
11
11
  });
12
12
  const validatePreviewUrl = async (strapi, uid, params)=>{
13
13
  // Validate the request parameters format
@@ -1 +1 @@
1
- {"version":3,"file":"preview.js","sources":["../../../../../server/src/preview/controllers/validation/preview.ts"],"sourcesContent":["import { pick } from 'lodash';\n\nimport type { Core, UID } from '@strapi/types';\nimport { z, validateZodSchema, errors } from '@strapi/utils';\n\nimport { Preview } from '../../../../../shared/contracts';\nimport type { HandlerParams } from '../../services/preview-config';\n\nconst getPreviewUrlSchema = z.object({\n // Will be undefined for single types\n documentId: z.string().optional(),\n locale: z.string().nullable().optional(),\n status: z.string().optional(),\n});\n\nexport const validatePreviewUrl = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n params: Preview.GetPreviewUrl.Request['query']\n): Promise<HandlerParams> => {\n // Validate the request parameters format\n validateZodSchema(getPreviewUrlSchema)(params);\n\n const newParams = pick(params, ['documentId', 'locale', 'status']) as HandlerParams;\n const model = strapi.getModel(uid);\n\n // If it's not a collection type or single type\n if (!model || model.modelType !== 'contentType') {\n throw new errors.ValidationError('Invalid content type');\n }\n\n // Document id is not required for single types\n const isSingleType = model?.kind === 'singleType';\n if (!isSingleType && !params.documentId) {\n throw new errors.ValidationError('documentId is required for Collection Types');\n }\n\n // Fill the documentId if it's a single type\n if (isSingleType) {\n const doc = await strapi.documents(uid).findFirst();\n\n if (!doc) {\n throw new errors.NotFoundError('Document not found');\n }\n\n newParams.documentId = doc?.documentId;\n }\n\n /**\n * If status is not specified, follow the following rules:\n * - D&P disabled: status is considered published\n * - D&P enabled: status is considered draft\n */\n if (!newParams.status) {\n const isDPEnabled = model?.options?.draftAndPublish;\n newParams.status = isDPEnabled ? 'draft' : 'published';\n }\n\n return newParams;\n};\n"],"names":["getPreviewUrlSchema","z","object","documentId","string","optional","locale","nullable","status","validatePreviewUrl","strapi","uid","params","validateZodSchema","newParams","pick","model","getModel","modelType","errors","ValidationError","isSingleType","kind","doc","documents","findFirst","NotFoundError","isDPEnabled","options","draftAndPublish"],"mappings":";;;;;AAQA,MAAMA,mBAAAA,GAAsBC,aAAAA,CAAEC,MAAM,CAAC;;IAEnCC,UAAAA,EAAYF,aAAAA,CAAEG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,MAAAA,EAAQL,aAAAA,CAAEG,MAAM,EAAA,CAAGG,QAAQ,GAAGF,QAAQ,EAAA;IACtCG,MAAAA,EAAQP,aAAAA,CAAEG,MAAM,EAAA,CAAGC,QAAQ;AAC7B,CAAA,CAAA;AAEO,MAAMI,kBAAAA,GAAqB,OAChCC,MAAAA,EACAC,GAAAA,EACAC,MAAAA,GAAAA;;AAGAC,IAAAA,6BAAAA,CAAkBb,mBAAAA,CAAAA,CAAqBY,MAAAA,CAAAA;IAEvC,MAAME,SAAAA,GAAYC,OAAKH,MAAAA,EAAQ;AAAC,QAAA,YAAA;AAAc,QAAA,QAAA;AAAU,QAAA;AAAS,KAAA,CAAA;IACjE,MAAMI,KAAAA,GAAQN,MAAAA,CAAOO,QAAQ,CAACN,GAAAA,CAAAA;;AAG9B,IAAA,IAAI,CAACK,KAAAA,IAASA,KAAAA,CAAME,SAAS,KAAK,aAAA,EAAe;QAC/C,MAAM,IAAIC,kBAAAA,CAAOC,eAAe,CAAC,sBAAA,CAAA;AACnC,IAAA;;IAGA,MAAMC,YAAAA,GAAeL,OAAOM,IAAAA,KAAS,YAAA;AACrC,IAAA,IAAI,CAACD,YAAAA,IAAgB,CAACT,MAAAA,CAAOT,UAAU,EAAE;QACvC,MAAM,IAAIgB,kBAAAA,CAAOC,eAAe,CAAC,6CAAA,CAAA;AACnC,IAAA;;AAGA,IAAA,IAAIC,YAAAA,EAAc;AAChB,QAAA,MAAME,MAAM,MAAMb,MAAAA,CAAOc,SAAS,CAACb,KAAKc,SAAS,EAAA;AAEjD,QAAA,IAAI,CAACF,GAAAA,EAAK;YACR,MAAM,IAAIJ,kBAAAA,CAAOO,aAAa,CAAC,oBAAA,CAAA;AACjC,QAAA;QAEAZ,SAAAA,CAAUX,UAAU,GAAGoB,GAAAA,EAAKpB,UAAAA;AAC9B,IAAA;AAEA;;;;AAIC,MACD,IAAI,CAACW,SAAAA,CAAUN,MAAM,EAAE;QACrB,MAAMmB,WAAAA,GAAcX,OAAOY,OAAAA,EAASC,eAAAA;QACpCf,SAAAA,CAAUN,MAAM,GAAGmB,WAAAA,GAAc,OAAA,GAAU,WAAA;AAC7C,IAAA;IAEA,OAAOb,SAAAA;AACT;;;;"}
1
+ {"version":3,"file":"preview.js","sources":["../../../../../server/src/preview/controllers/validation/preview.ts"],"sourcesContent":["import { pick } from 'lodash';\n\nimport type { Core, UID } from '@strapi/types';\nimport { z, validateZodSchema, errors, statusSchema } from '@strapi/utils';\n\nimport { Preview } from '../../../../../shared/contracts';\nimport type { HandlerParams } from '../../services/preview-config';\n\nconst getPreviewUrlSchema = z.object({\n // Will be undefined for single types\n documentId: z.string().optional(),\n locale: z.string().nullable().optional(),\n status: statusSchema.optional(),\n});\n\nexport const validatePreviewUrl = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n params: Preview.GetPreviewUrl.Request['query']\n): Promise<HandlerParams> => {\n // Validate the request parameters format\n validateZodSchema(getPreviewUrlSchema)(params);\n\n const newParams = pick(params, ['documentId', 'locale', 'status']) as HandlerParams;\n const model = strapi.getModel(uid);\n\n // If it's not a collection type or single type\n if (!model || model.modelType !== 'contentType') {\n throw new errors.ValidationError('Invalid content type');\n }\n\n // Document id is not required for single types\n const isSingleType = model?.kind === 'singleType';\n if (!isSingleType && !params.documentId) {\n throw new errors.ValidationError('documentId is required for Collection Types');\n }\n\n // Fill the documentId if it's a single type\n if (isSingleType) {\n const doc = await strapi.documents(uid).findFirst();\n\n if (!doc) {\n throw new errors.NotFoundError('Document not found');\n }\n\n newParams.documentId = doc?.documentId;\n }\n\n /**\n * If status is not specified, follow the following rules:\n * - D&P disabled: status is considered published\n * - D&P enabled: status is considered draft\n */\n if (!newParams.status) {\n const isDPEnabled = model?.options?.draftAndPublish;\n newParams.status = isDPEnabled ? 'draft' : 'published';\n }\n\n return newParams;\n};\n"],"names":["getPreviewUrlSchema","z","object","documentId","string","optional","locale","nullable","status","statusSchema","validatePreviewUrl","strapi","uid","params","validateZodSchema","newParams","pick","model","getModel","modelType","errors","ValidationError","isSingleType","kind","doc","documents","findFirst","NotFoundError","isDPEnabled","options","draftAndPublish"],"mappings":";;;;;AAQA,MAAMA,mBAAAA,GAAsBC,aAAAA,CAAEC,MAAM,CAAC;;IAEnCC,UAAAA,EAAYF,aAAAA,CAAEG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,MAAAA,EAAQL,aAAAA,CAAEG,MAAM,EAAA,CAAGG,QAAQ,GAAGF,QAAQ,EAAA;AACtCG,IAAAA,MAAAA,EAAQC,yBAAaJ,QAAQ;AAC/B,CAAA,CAAA;AAEO,MAAMK,kBAAAA,GAAqB,OAChCC,MAAAA,EACAC,GAAAA,EACAC,MAAAA,GAAAA;;AAGAC,IAAAA,6BAAAA,CAAkBd,mBAAAA,CAAAA,CAAqBa,MAAAA,CAAAA;IAEvC,MAAME,SAAAA,GAAYC,OAAKH,MAAAA,EAAQ;AAAC,QAAA,YAAA;AAAc,QAAA,QAAA;AAAU,QAAA;AAAS,KAAA,CAAA;IACjE,MAAMI,KAAAA,GAAQN,MAAAA,CAAOO,QAAQ,CAACN,GAAAA,CAAAA;;AAG9B,IAAA,IAAI,CAACK,KAAAA,IAASA,KAAAA,CAAME,SAAS,KAAK,aAAA,EAAe;QAC/C,MAAM,IAAIC,kBAAAA,CAAOC,eAAe,CAAC,sBAAA,CAAA;AACnC,IAAA;;IAGA,MAAMC,YAAAA,GAAeL,OAAOM,IAAAA,KAAS,YAAA;AACrC,IAAA,IAAI,CAACD,YAAAA,IAAgB,CAACT,MAAAA,CAAOV,UAAU,EAAE;QACvC,MAAM,IAAIiB,kBAAAA,CAAOC,eAAe,CAAC,6CAAA,CAAA;AACnC,IAAA;;AAGA,IAAA,IAAIC,YAAAA,EAAc;AAChB,QAAA,MAAME,MAAM,MAAMb,MAAAA,CAAOc,SAAS,CAACb,KAAKc,SAAS,EAAA;AAEjD,QAAA,IAAI,CAACF,GAAAA,EAAK;YACR,MAAM,IAAIJ,kBAAAA,CAAOO,aAAa,CAAC,oBAAA,CAAA;AACjC,QAAA;QAEAZ,SAAAA,CAAUZ,UAAU,GAAGqB,GAAAA,EAAKrB,UAAAA;AAC9B,IAAA;AAEA;;;;AAIC,MACD,IAAI,CAACY,SAAAA,CAAUP,MAAM,EAAE;QACrB,MAAMoB,WAAAA,GAAcX,OAAOY,OAAAA,EAASC,eAAAA;QACpCf,SAAAA,CAAUP,MAAM,GAAGoB,WAAAA,GAAc,OAAA,GAAU,WAAA;AAC7C,IAAA;IAEA,OAAOb,SAAAA;AACT;;;;"}
@@ -1,11 +1,11 @@
1
1
  import { pick } from 'lodash';
2
- import { z, validateZodSchema, errors } from '@strapi/utils';
2
+ import { z, statusSchema, validateZodSchema, errors } from '@strapi/utils';
3
3
 
4
4
  const getPreviewUrlSchema = z.object({
5
5
  // Will be undefined for single types
6
6
  documentId: z.string().optional(),
7
7
  locale: z.string().nullable().optional(),
8
- status: z.string().optional()
8
+ status: statusSchema.optional()
9
9
  });
10
10
  const validatePreviewUrl = async (strapi, uid, params)=>{
11
11
  // Validate the request parameters format