@strapi/core 5.57.0 → 5.59.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 (135) hide show
  1. package/dist/Strapi.d.ts +28 -0
  2. package/dist/Strapi.d.ts.map +1 -1
  3. package/dist/Strapi.js +5 -0
  4. package/dist/Strapi.js.map +1 -1
  5. package/dist/Strapi.mjs +5 -0
  6. package/dist/Strapi.mjs.map +1 -1
  7. package/dist/ee/entitlements.d.ts +44 -0
  8. package/dist/ee/entitlements.d.ts.map +1 -0
  9. package/dist/ee/entitlements.js +54 -0
  10. package/dist/ee/entitlements.js.map +1 -0
  11. package/dist/ee/entitlements.mjs +51 -0
  12. package/dist/ee/entitlements.mjs.map +1 -0
  13. package/dist/ee/index.d.ts +33 -0
  14. package/dist/ee/index.d.ts.map +1 -1
  15. package/dist/ee/index.js +70 -3
  16. package/dist/ee/index.js.map +1 -1
  17. package/dist/ee/index.mjs +71 -4
  18. package/dist/ee/index.mjs.map +1 -1
  19. package/dist/ee/license.d.ts +10 -0
  20. package/dist/ee/license.d.ts.map +1 -1
  21. package/dist/ee/license.js +25 -1
  22. package/dist/ee/license.js.map +1 -1
  23. package/dist/ee/license.mjs +25 -2
  24. package/dist/ee/license.mjs.map +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/loaders/apis.d.ts.map +1 -1
  31. package/dist/loaders/apis.js.map +1 -1
  32. package/dist/loaders/apis.mjs.map +1 -1
  33. package/dist/loaders/plugins/get-enabled-plugins.js +2 -2
  34. package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
  35. package/dist/loaders/plugins/get-enabled-plugins.mjs +2 -2
  36. package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
  37. package/dist/middlewares/cors.d.ts.map +1 -1
  38. package/dist/middlewares/cors.js.map +1 -1
  39. package/dist/middlewares/cors.mjs.map +1 -1
  40. package/dist/migrations/database/5.0.0-discard-drafts.js +1 -1
  41. package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
  42. package/dist/migrations/database/5.0.0-discard-drafts.mjs +1 -1
  43. package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
  44. package/dist/migrations/first-published-at.js +1 -1
  45. package/dist/migrations/first-published-at.js.map +1 -1
  46. package/dist/migrations/first-published-at.mjs +1 -1
  47. package/dist/migrations/first-published-at.mjs.map +1 -1
  48. package/dist/package.json.js +18 -17
  49. package/dist/package.json.js.map +1 -1
  50. package/dist/package.json.mjs +18 -17
  51. package/dist/package.json.mjs.map +1 -1
  52. package/dist/registries/controllers.d.ts.map +1 -1
  53. package/dist/registries/controllers.js.map +1 -1
  54. package/dist/registries/controllers.mjs.map +1 -1
  55. package/dist/services/content-source-maps.js +6 -6
  56. package/dist/services/content-source-maps.js.map +1 -1
  57. package/dist/services/content-source-maps.mjs +6 -6
  58. package/dist/services/content-source-maps.mjs.map +1 -1
  59. package/dist/services/document-service/components.d.ts +13 -11
  60. package/dist/services/document-service/components.d.ts.map +1 -1
  61. package/dist/services/document-service/components.js +115 -66
  62. package/dist/services/document-service/components.js.map +1 -1
  63. package/dist/services/document-service/components.mjs +116 -67
  64. package/dist/services/document-service/components.mjs.map +1 -1
  65. package/dist/services/document-service/events.d.ts.map +1 -1
  66. package/dist/services/document-service/events.js +5 -1
  67. package/dist/services/document-service/events.js.map +1 -1
  68. package/dist/services/document-service/events.mjs +5 -1
  69. package/dist/services/document-service/events.mjs.map +1 -1
  70. package/dist/services/document-service/repository.d.ts.map +1 -1
  71. package/dist/services/document-service/repository.js +26 -7
  72. package/dist/services/document-service/repository.js.map +1 -1
  73. package/dist/services/document-service/repository.mjs +27 -8
  74. package/dist/services/document-service/repository.mjs.map +1 -1
  75. package/dist/services/document-service/transform/data.d.ts.map +1 -1
  76. package/dist/services/document-service/transform/data.js.map +1 -1
  77. package/dist/services/document-service/transform/data.mjs.map +1 -1
  78. package/dist/services/document-service/transform/fields.d.ts.map +1 -1
  79. package/dist/services/document-service/transform/fields.js +7 -1
  80. package/dist/services/document-service/transform/fields.js.map +1 -1
  81. package/dist/services/document-service/transform/fields.mjs +7 -1
  82. package/dist/services/document-service/transform/fields.mjs.map +1 -1
  83. package/dist/services/document-service/transform/populate.d.ts.map +1 -1
  84. package/dist/services/document-service/transform/populate.js +8 -1
  85. package/dist/services/document-service/transform/populate.js.map +1 -1
  86. package/dist/services/document-service/transform/populate.mjs +8 -1
  87. package/dist/services/document-service/transform/populate.mjs.map +1 -1
  88. package/dist/services/document-service/transform/relations/transform/default-locale.d.ts +4 -1
  89. package/dist/services/document-service/transform/relations/transform/default-locale.d.ts.map +1 -1
  90. package/dist/services/document-service/transform/relations/transform/default-locale.js +12 -9
  91. package/dist/services/document-service/transform/relations/transform/default-locale.js.map +1 -1
  92. package/dist/services/document-service/transform/relations/transform/default-locale.mjs +12 -10
  93. package/dist/services/document-service/transform/relations/transform/default-locale.mjs.map +1 -1
  94. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts.map +1 -1
  95. package/dist/services/document-service/transform/relations/utils/map-relation.js +10 -4
  96. package/dist/services/document-service/transform/relations/utils/map-relation.js.map +1 -1
  97. package/dist/services/document-service/transform/relations/utils/map-relation.mjs +10 -4
  98. package/dist/services/document-service/transform/relations/utils/map-relation.mjs.map +1 -1
  99. package/dist/services/document-service/utils/clone-relations.d.ts +21 -4
  100. package/dist/services/document-service/utils/clone-relations.d.ts.map +1 -1
  101. package/dist/services/document-service/utils/clone-relations.js +619 -34
  102. package/dist/services/document-service/utils/clone-relations.js.map +1 -1
  103. package/dist/services/document-service/utils/clone-relations.mjs +619 -36
  104. package/dist/services/document-service/utils/clone-relations.mjs.map +1 -1
  105. package/dist/services/document-service/utils/unidirectional-relations.d.ts +4 -2
  106. package/dist/services/document-service/utils/unidirectional-relations.d.ts.map +1 -1
  107. package/dist/services/document-service/utils/unidirectional-relations.js +1 -10
  108. package/dist/services/document-service/utils/unidirectional-relations.js.map +1 -1
  109. package/dist/services/document-service/utils/unidirectional-relations.mjs +1 -10
  110. package/dist/services/document-service/utils/unidirectional-relations.mjs.map +1 -1
  111. package/dist/services/event-hub.d.ts.map +1 -1
  112. package/dist/services/event-hub.js +23 -5
  113. package/dist/services/event-hub.js.map +1 -1
  114. package/dist/services/event-hub.mjs +23 -5
  115. package/dist/services/event-hub.mjs.map +1 -1
  116. package/dist/services/webhook-store.js +2 -2
  117. package/dist/services/webhook-store.js.map +1 -1
  118. package/dist/services/webhook-store.mjs +2 -2
  119. package/dist/services/webhook-store.mjs.map +1 -1
  120. package/dist/utils/detect-customizations.d.ts +31 -0
  121. package/dist/utils/detect-customizations.d.ts.map +1 -0
  122. package/dist/utils/detect-customizations.js +173 -0
  123. package/dist/utils/detect-customizations.js.map +1 -0
  124. package/dist/utils/detect-customizations.mjs +165 -0
  125. package/dist/utils/detect-customizations.mjs.map +1 -0
  126. package/dist/utils/fetch.d.ts.map +1 -1
  127. package/dist/utils/fetch.js +44 -8
  128. package/dist/utils/fetch.js.map +1 -1
  129. package/dist/utils/fetch.mjs +37 -8
  130. package/dist/utils/fetch.mjs.map +1 -1
  131. package/dist/utils/transform-content-types-to-models.js +5 -5
  132. package/dist/utils/transform-content-types-to-models.js.map +1 -1
  133. package/dist/utils/transform-content-types-to-models.mjs +5 -5
  134. package/dist/utils/transform-content-types-to-models.mjs.map +1 -1
  135. package/package.json +18 -17
@@ -1,6 +1,6 @@
1
1
  import _, { curry, omit, assign, has } from 'lodash';
2
2
  import { contentTypes, async, errors } from '@strapi/utils';
3
- import { getComponentJoinTableName, getComponentJoinColumnEntityName, getComponentJoinColumnInverseName, getComponentTypeColumn } from '../../utils/transform-content-types-to-models.mjs';
3
+ import { getComponentJoinColumnEntityName, getComponentJoinColumnInverseName, getComponentTypeColumn, getComponentJoinTableName } from '../../utils/transform-content-types-to-models.mjs';
4
4
 
5
5
  const omitComponentData = curry((schema, data)=>{
6
6
  const { attributes } = schema;
@@ -273,50 +273,75 @@ const deleteComponent = async (uid, componentToDelete)=>{
273
273
  const assignComponentData = curry((schema, componentData, data)=>{
274
274
  return assign({}, componentData, omitComponentData(schema, data));
275
275
  });
276
- /** *************************
277
- Component relation handling for document operations
278
- ************************** */ /**
279
- * Find the parent entry of a component instance.
276
+ // Component instance ids are bound as query parameters, so look them up in batches that stay
277
+ // well below the bind parameter limit of every supported database
278
+ const PARENT_LOOKUP_BATCH_SIZE = 500;
279
+ /**
280
+ * Find the parent entries of many instances of the same component.
280
281
  *
281
- * Given a component model, a specific component instance id, and the list of
282
- * possible parent content types (those that can embed this component),
283
- * this function checks each parent's *_cmps join table to see if the component
284
- * instance is linked to a parent entity.
282
+ * Given a component model, component instance ids, and the list of possible parent
283
+ * content types and components (those that can embed this component), this function
284
+ * checks each parent's *_cmps join table to see which instances it links to a parent.
285
+ * Parents are checked in order and the first one linking an instance is its parent.
285
286
  *
286
- * - Returns the parent uid, parent table name, and parent id if found.
287
- * - Returns null if no parent relationship exists.
288
- */ const findComponentParent = async (componentSchema, componentId, parentSchemasForComponent, opts)=>{
289
- if (!componentSchema?.uid) return null;
290
- const schemaBuilder = strapi.db.getSchemaConnection(opts?.trx);
287
+ * Each parent costs one query per batch of instances rather than one query per instance,
288
+ * and parents are no longer checked once every instance has been found.
289
+ *
290
+ * - Returns a map from component instance id (as a string) to its parent uid, parent table
291
+ * name and parent id.
292
+ * - Instances without a parent are not in the map.
293
+ */ const findComponentParents = async (componentSchema, componentIds, parentSchemasForComponent, opts)=>{
294
+ const parents = new Map();
295
+ if (!componentSchema?.uid) return parents;
291
296
  const withTrx = (qb)=>opts?.trx ? qb.transacting(opts.trx) : qb;
297
+ // Use the exact same functions that create the columns
298
+ const identifiers = strapi.db.metadata.identifiers;
299
+ const entityIdColumn = getComponentJoinColumnEntityName(identifiers);
300
+ const componentIdColumn = getComponentJoinColumnInverseName(identifiers);
301
+ const componentTypeColumn = getComponentTypeColumn(identifiers);
302
+ let pendingIds = _.uniqBy(componentIds.filter((id)=>id !== undefined && id !== null), String);
292
303
  for (const parent of parentSchemasForComponent){
304
+ if (pendingIds.length === 0) break;
293
305
  if (!parent.collectionName) continue;
294
306
  // Use the exact same functions that create the tables
295
- const identifiers = strapi.db.metadata.identifiers;
296
307
  const joinTableName = getComponentJoinTableName(parent.collectionName, identifiers);
297
- try {
298
- const tableExists = await schemaBuilder.hasTable(joinTableName);
299
- if (!tableExists) continue;
300
- // Use the exact same functions that create the columns
301
- const entityIdColumn = getComponentJoinColumnEntityName(identifiers);
302
- const componentIdColumn = getComponentJoinColumnInverseName(identifiers);
303
- const componentTypeColumn = getComponentTypeColumn(identifiers);
304
- const parentRow = await withTrx(strapi.db.getConnection(joinTableName)).where({
305
- [componentIdColumn]: componentId,
306
- [componentTypeColumn]: componentSchema.uid
307
- }).first(entityIdColumn);
308
- if (parentRow) {
309
- return {
310
- uid: parent.uid,
311
- table: parent.collectionName,
312
- parentId: parentRow[entityIdColumn]
313
- };
308
+ // The join table is registered as a model of its own (see createCompoLinkModel) and schema
309
+ // sync creates every registered model, so the metadata knows whether it exists without
310
+ // querying the database schema
311
+ if (!strapi.db.metadata.has(joinTableName)) continue;
312
+ for (const batch of _.chunk(pendingIds, PARENT_LOOKUP_BATCH_SIZE)){
313
+ try {
314
+ const parentRows = await withTrx(strapi.db.getConnection(joinTableName)).select(entityIdColumn, componentIdColumn).where(componentTypeColumn, componentSchema.uid).whereIn(componentIdColumn, batch);
315
+ for (const parentRow of parentRows){
316
+ const componentId = String(parentRow[componentIdColumn]);
317
+ if (!parents.has(componentId)) {
318
+ parents.set(componentId, {
319
+ uid: parent.uid,
320
+ table: parent.collectionName,
321
+ parentId: parentRow[entityIdColumn]
322
+ });
323
+ }
324
+ }
325
+ } catch {
326
+ continue;
314
327
  }
315
- } catch {
316
- continue;
317
328
  }
329
+ pendingIds = pendingIds.filter((id)=>!parents.has(String(id)));
318
330
  }
319
- return null;
331
+ return parents;
332
+ };
333
+ /**
334
+ * Find the parent entry of a component instance.
335
+ *
336
+ * Single-instance form of `findComponentParents`.
337
+ *
338
+ * - Returns the parent uid, parent table name, and parent id if found.
339
+ * - Returns null if no parent relationship exists.
340
+ */ const findComponentParent = async (componentSchema, componentId, parentSchemasForComponent, opts)=>{
341
+ const parents = await findComponentParents(componentSchema, [
342
+ componentId
343
+ ], parentSchemasForComponent, opts);
344
+ return parents.get(String(componentId)) ?? null;
320
345
  };
321
346
  /**
322
347
  * Finds content types that contain the given component and have draft & publish enabled.
@@ -333,49 +358,73 @@ const assignComponentData = curry((schema, componentData, data)=>{
333
358
  });
334
359
  };
335
360
  /**
336
- * Determines if a component relation should be propagated to a new document version
337
- * when a document with draft and publish is updated.
338
- */ const shouldPropagateComponentRelationToNewVersion = async (componentRelation, componentSchema, parentSchemasForComponent, trx)=>{
339
- // Get the component ID column name using the actual component model name
340
- const componentIdColumn = strapi.db.metadata.identifiers.getJoinColumnAttributeIdName(_.snakeCase(componentSchema.modelName));
341
- const componentId = componentRelation[componentIdColumn] ?? componentRelation.parentId;
342
- const parent = await findComponentParent(componentSchema, componentId, parentSchemasForComponent, {
361
+ * Finds which of the given component instances belong to an entry of a content type with
362
+ * draft and publish enabled, either directly or through parent components.
363
+ *
364
+ * Instances are resolved one nesting level at a time, so the number of queries depends on
365
+ * the schema rather than on the number of instances.
366
+ *
367
+ * - Returns the ids (as strings) of the instances owned by a draft and publish entry.
368
+ * - Instances without a parent, or owned by an entry without draft and publish, are not included.
369
+ */ const findInstancesOwnedByDraftAndPublishEntries = async (componentSchema, componentIds, trx)=>{
370
+ const ownedIds = new Set();
371
+ const parentSchemas = getParentSchemasForComponent(componentSchema);
372
+ if (parentSchemas.length === 0) {
373
+ return ownedIds;
374
+ }
375
+ const parents = await findComponentParents(componentSchema, componentIds, parentSchemas, {
343
376
  trx
344
377
  });
345
- // Keep relation if component has no parent entry
346
- if (!parent?.uid) {
347
- return true;
348
- }
349
- if (strapi.components[parent.uid]) {
350
- // If the parent is a component, we need to check its parents recursively
351
- const parentComponentSchema = strapi.components[parent.uid];
352
- const grandParentSchemas = getParentSchemasForComponent(parentComponentSchema);
353
- return shouldPropagateComponentRelationToNewVersion(parent, parentComponentSchema, grandParentSchemas, trx);
378
+ // Instances nested in another component, grouped by that component and its instance id
379
+ const nestedInstances = new Map();
380
+ for (const [componentId, parent] of parents){
381
+ if (strapi.components[parent.uid]) {
382
+ const parentUid = parent.uid;
383
+ const parentKey = String(parent.parentId);
384
+ if (!nestedInstances.has(parentUid)) {
385
+ nestedInstances.set(parentUid, new Map());
386
+ }
387
+ const instancesByParent = nestedInstances.get(parentUid);
388
+ if (!instancesByParent.has(parentKey)) {
389
+ instancesByParent.set(parentKey, {
390
+ parentId: parent.parentId,
391
+ componentIds: []
392
+ });
393
+ }
394
+ instancesByParent.get(parentKey).componentIds.push(componentId);
395
+ continue;
396
+ }
397
+ if (strapi.contentTypes[parent.uid]?.options?.draftAndPublish) {
398
+ ownedIds.add(componentId);
399
+ }
354
400
  }
355
- const parentContentType = strapi.contentTypes[parent.uid];
356
- // Keep relation if parent doesn't have draft & publish enabled
357
- if (!parentContentType?.options?.draftAndPublish) {
358
- return true;
401
+ // If the parent is a component, its own parents decide, so check them a level up
402
+ for (const [parentUid, instancesByParent] of nestedInstances){
403
+ const ownedParentIds = await findInstancesOwnedByDraftAndPublishEntries(strapi.components[parentUid], Array.from(instancesByParent.values(), ({ parentId })=>parentId), trx);
404
+ for (const parentKey of ownedParentIds){
405
+ instancesByParent.get(parentKey)?.componentIds.forEach((id)=>ownedIds.add(id));
406
+ }
359
407
  }
360
- // Discard relation if parent has draft & publish enabled
361
- return false;
408
+ return ownedIds;
362
409
  };
363
410
  /**
364
411
  * Creates a filter function for component relations that can be passed to the generic
365
- * unidirectional relations utility
412
+ * unidirectional relations utility.
413
+ *
414
+ * A relation of a component instance is propagated to the new document version unless the
415
+ * instance belongs to an entry with draft and publish enabled: that entry's new version gets
416
+ * its own copy of the component.
366
417
  */ const createComponentRelationFilter = ()=>{
367
- return async (relation, model, trx)=>{
418
+ return async (relations, model, trx)=>{
368
419
  // Only apply component-specific filtering for components
369
- if (model.modelType !== 'component') {
370
- return true;
420
+ if (model.modelType !== 'component' || relations.length === 0) {
421
+ return relations;
371
422
  }
372
423
  const componentSchema = model;
373
- const parentSchemas = getParentSchemasForComponent(componentSchema);
374
- // Exit if no draft & publish parent types exist
375
- if (parentSchemas.length === 0) {
376
- return true;
377
- }
378
- return shouldPropagateComponentRelationToNewVersion(relation, componentSchema, parentSchemas, trx);
424
+ // Get the component ID column name using the actual component model name
425
+ const componentIdColumn = strapi.db.metadata.identifiers.getJoinColumnAttributeIdName(_.snakeCase(componentSchema.modelName));
426
+ const ownedIds = await findInstancesOwnedByDraftAndPublishEntries(componentSchema, relations.map((relation)=>relation[componentIdColumn]), trx);
427
+ return relations.filter((relation)=>!ownedIds.has(String(relation[componentIdColumn])));
379
428
  };
380
429
  };
381
430
 
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","sources":["../../../src/services/document-service/components.ts"],"sourcesContent":["import _, { assign, curry, has, omit } from 'lodash';\nimport type { Utils, UID, Schema, Data, Modules } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async, errors } from '@strapi/utils';\nimport {\n getComponentJoinTableName,\n getComponentJoinColumnEntityName,\n getComponentJoinColumnInverseName,\n getComponentTypeColumn,\n} from '../../utils/transform-content-types-to-models';\n\n// type aliases for readability\ntype Input<T extends UID.Schema> = Modules.Documents.Params.Data.Input<T>;\n\ntype LoadedComponents<TUID extends UID.Schema> = Data.Entity<\n TUID,\n Schema.AttributeNamesByType<TUID, 'component' | 'dynamiczone'>\n>;\n\ntype SingleComponentValue = Schema.Attribute.ComponentValue<UID.Component, false>;\ntype RepeatableComponentValue = Schema.Attribute.ComponentValue<UID.Component, true>;\n\ntype ComponentValue = SingleComponentValue | RepeatableComponentValue;\n\ntype DynamicZoneValue = Schema.Attribute.DynamicZoneValue<UID.Component[]>;\n\ntype ComponentBody = {\n [key: string]: ComponentValue | DynamicZoneValue;\n};\n\nconst omitComponentData = curry(\n (schema: Schema.Schema, data: Input<UID.Schema>): Partial<Input<UID.Schema>> => {\n const { attributes } = schema;\n const componentAttributes = Object.keys(attributes).filter((attributeName) =>\n contentTypesUtils.isComponentAttribute(attributes[attributeName])\n );\n\n return omit(data, componentAttributes);\n }\n);\n\n// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer\nconst createComponents = async <TUID extends UID.Schema, TData extends Input<TUID>>(\n uid: TUID,\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (!has(data, attributeName) || !contentTypesUtils.isComponentAttribute(attribute)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData];\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>\n createComponent(componentUID, value)\n );\n\n componentBody[attributeName] = components.map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await createComponent(\n componentUID,\n componentValue as Input<UID.Component>\n );\n\n componentBody[attributeName] = {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as Modules.EntityService.Params.Attribute.GetValue<Schema.Attribute.DynamicZone>;\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const createDynamicZoneComponents = async (\n value: Utils.Array.Values<typeof dynamiczoneValues>\n ) => {\n const { id } = await createComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n };\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await async.map(\n dynamiczoneValues,\n createDynamicZoneComponents\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst getComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n entity: { id: Modules.EntityService.Params.Attribute.ID }\n): Promise<LoadedComponents<TUID>> => {\n const componentAttributes = contentTypesUtils.getComponentAttributes(strapi.getModel(uid));\n\n if (_.isEmpty(componentAttributes)) {\n return {} as LoadedComponents<TUID>;\n }\n\n return strapi.db.query(uid).load(entity, componentAttributes) as Promise<LoadedComponents<TUID>>;\n};\n\n/*\n delete old components\n create or update\n*/\nconst updateComponents = async <TUID extends UID.Schema, TData extends Partial<Input<TUID>>>(\n uid: TUID,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n if (!has(data, attributeName)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData] as ComponentValue;\n await deleteOldComponents(uid, componentUID, entityToUpdate, attributeName, componentValue);\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>\n updateOrCreateComponent(componentUID, value)\n );\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await updateOrCreateComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n } else if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[attributeName as keyof TData] as DynamicZoneValue;\n\n await deleteOldDZComponents(uid, entityToUpdate, attributeName, dynamiczoneValues);\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await async.map(dynamiczoneValues, async (value: any) => {\n const { id } = await updateOrCreateComponent(value.__component, value);\n\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n });\n }\n }\n\n return componentBody;\n};\n\nconst pickStringifiedId = ({\n id,\n}: {\n id: Modules.EntityService.Params.Attribute.ID;\n}): Modules.EntityService.Params.Attribute.ID & string => {\n if (typeof id === 'string') {\n return id;\n }\n\n return `${id}`;\n};\n\nconst deleteOldComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n componentUID: UID.Component,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n attributeName: string,\n componentValue: ComponentValue\n) => {\n const previousValue = (await strapi.db\n .query(uid)\n .load(entityToUpdate, attributeName)) as ComponentValue;\n const idsToKeep = _.castArray(componentValue)\n .filter((value) => has(value, 'id'))\n .map(pickStringifiedId);\n const allIds = _.castArray(previousValue)\n .filter((value) => has(value, 'id'))\n .map(pickStringifiedId);\n\n idsToKeep.forEach((id) => {\n if (!allIds.includes(id)) {\n throw new errors.ApplicationError(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n }\n });\n\n const idsToDelete = _.difference(allIds, idsToKeep);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n await deleteComponent(componentUID, { id: idToDelete });\n }\n }\n};\n\nconst deleteOldDZComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n attributeName: string,\n dynamiczoneValues: DynamicZoneValue\n) => {\n const previousValue = (await strapi.db\n .query(uid)\n .load(entityToUpdate, attributeName)) as DynamicZoneValue;\n\n const idsToKeep = _.castArray(dynamiczoneValues)\n .filter((value) => has(value, 'id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n const allIds = _.castArray(previousValue)\n .filter((value) => has(value, 'id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n idsToKeep.forEach(({ id, __component: componentUID }) => {\n if (!allIds.find((el) => el.id === id && el.__component === componentUID)) {\n const err = new Error(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n\n Object.assign(err, { status: 400 });\n throw err;\n }\n });\n\n type IdsToDelete = DynamicZoneValue;\n\n const idsToDelete = allIds.reduce((acc, { id, __component: componentUID }) => {\n if (!idsToKeep.find((el) => el.id === id && el.__component === componentUID)) {\n acc.push({ id, __component: componentUID });\n }\n\n return acc;\n }, [] as IdsToDelete);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n const { id, __component: componentUID } = idToDelete;\n await deleteComponent(componentUID, { id });\n }\n }\n};\n\nconst deleteComponents = async <TUID extends UID.Schema, TEntity extends Data.Entity<TUID>>(\n uid: TUID,\n entityToDelete: TEntity,\n { loadComponents = true } = {}\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute.type === 'component' || attribute.type === 'dynamiczone') {\n let value;\n\n if (loadComponents) {\n value = await strapi.db.query(uid).load(entityToDelete, attributeName);\n } else {\n value = entityToDelete[attributeName as keyof TEntity];\n }\n\n if (!value) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID } = attribute;\n await async.map(_.castArray(value), (subValue: any) =>\n deleteComponent(componentUID, subValue)\n );\n } else {\n await async.map(_.castArray(value), (subValue: any) =>\n deleteComponent(subValue.__component, subValue)\n );\n }\n\n continue;\n }\n }\n};\n\n/** *************************\n Component queries\n************************** */\n\n// components can have nested compos so this must be recursive\nconst createComponent = async <TUID extends UID.Component>(\n uid: TUID,\n data: Input<TUID>\n): Promise<Data.Component<TUID>> => {\n const schema = strapi.getModel(uid);\n\n const componentData = await createComponents(uid, data);\n\n // Make sure we don't save the component with a pre-defined ID.\n const entryData = assignComponentData(schema, componentData, omit(data, 'id'));\n\n return strapi.db.query(uid).create({ data: entryData });\n};\n\n// components can have nested compos so this must be recursive\nconst updateComponent = async <TUID extends UID.Component>(\n uid: TUID,\n componentToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n data: Input<TUID>\n) => {\n const schema = strapi.getModel(uid);\n\n const componentData = await updateComponents(uid, componentToUpdate, data);\n\n return strapi.db.query(uid).update({\n where: {\n id: componentToUpdate.id,\n },\n data: assignComponentData(schema, componentData, data),\n });\n};\n\nconst updateOrCreateComponent = <TUID extends UID.Component>(\n componentUID: TUID,\n value: Input<TUID>\n) => {\n if (value === null) {\n return null;\n }\n\n // update\n if ('id' in value && typeof value.id !== 'undefined') {\n // TODO: verify the compo is associated with the entity\n return updateComponent(componentUID, { id: value.id }, value);\n }\n\n // create\n return createComponent(componentUID, value);\n};\n\nconst deleteComponent = async <TUID extends UID.Component>(\n uid: TUID,\n componentToDelete: Data.Component<TUID>\n) => {\n await deleteComponents(uid, componentToDelete);\n await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });\n};\n\nconst assignComponentData = curry(\n (schema: Schema.Schema, componentData: ComponentBody, data: Input<UID.Schema>) => {\n return assign({}, componentData, omitComponentData(schema, data));\n }\n);\n\n/** *************************\n Component relation handling for document operations\n************************** */\n\n/**\n * Find the parent entry of a component instance.\n *\n * Given a component model, a specific component instance id, and the list of\n * possible parent content types (those that can embed this component),\n * this function checks each parent's *_cmps join table to see if the component\n * instance is linked to a parent entity.\n *\n * - Returns the parent uid, parent table name, and parent id if found.\n * - Returns null if no parent relationship exists.\n */\nconst findComponentParent = async (\n componentSchema: Schema.Component,\n componentId: number | string,\n parentSchemasForComponent: (Schema.ContentType | Schema.Component)[],\n opts?: { trx?: any }\n): Promise<{ uid: string; table: string; parentId: number | string } | null> => {\n if (!componentSchema?.uid) return null;\n\n const schemaBuilder = strapi.db.getSchemaConnection(opts?.trx);\n const withTrx = (qb: any) => (opts?.trx ? qb.transacting(opts.trx) : qb);\n\n for (const parent of parentSchemasForComponent) {\n if (!parent.collectionName) continue;\n\n // Use the exact same functions that create the tables\n const identifiers = strapi.db.metadata.identifiers;\n const joinTableName = getComponentJoinTableName(parent.collectionName, identifiers);\n\n try {\n const tableExists = await schemaBuilder.hasTable(joinTableName);\n if (!tableExists) continue;\n\n // Use the exact same functions that create the columns\n const entityIdColumn = getComponentJoinColumnEntityName(identifiers);\n const componentIdColumn = getComponentJoinColumnInverseName(identifiers);\n const componentTypeColumn = getComponentTypeColumn(identifiers);\n\n const parentRow = await withTrx(strapi.db.getConnection(joinTableName))\n .where({\n [componentIdColumn]: componentId,\n [componentTypeColumn]: componentSchema.uid,\n })\n .first(entityIdColumn);\n\n if (parentRow) {\n return {\n uid: parent.uid,\n table: parent.collectionName,\n parentId: parentRow[entityIdColumn],\n };\n }\n } catch {\n continue;\n }\n }\n\n return null;\n};\n\n/**\n * Finds content types that contain the given component and have draft & publish enabled.\n */\nconst getParentSchemasForComponent = (\n componentSchema: Schema.Component\n): Array<Schema.ContentType | Schema.Component> => {\n // Find direct parents in contentTypes and components\n return [...Object.values(strapi.contentTypes), ...Object.values(strapi.components)].filter(\n (schema: any) => {\n if (!schema?.attributes) return false;\n return Object.values(schema.attributes).some((attr: any) => {\n return (\n (attr.type === 'component' && attr.component === componentSchema.uid) ||\n (attr.type === 'dynamiczone' && attr.components?.includes(componentSchema.uid))\n );\n });\n }\n );\n};\n\n/**\n * Determines if a component relation should be propagated to a new document version\n * when a document with draft and publish is updated.\n */\nconst shouldPropagateComponentRelationToNewVersion = async (\n componentRelation: Record<string, any>,\n componentSchema: Schema.Component,\n parentSchemasForComponent: (Schema.ContentType | Schema.Component)[],\n trx: any\n): Promise<boolean> => {\n // Get the component ID column name using the actual component model name\n const componentIdColumn = strapi.db.metadata.identifiers.getJoinColumnAttributeIdName(\n _.snakeCase(componentSchema.modelName)\n );\n\n const componentId = componentRelation[componentIdColumn] ?? componentRelation.parentId;\n\n const parent = await findComponentParent(\n componentSchema,\n componentId,\n parentSchemasForComponent,\n { trx }\n );\n\n // Keep relation if component has no parent entry\n if (!parent?.uid) {\n return true;\n }\n\n if (strapi.components[parent.uid as UID.Component]) {\n // If the parent is a component, we need to check its parents recursively\n const parentComponentSchema = strapi.components[parent.uid as UID.Component];\n const grandParentSchemas = getParentSchemasForComponent(parentComponentSchema);\n return shouldPropagateComponentRelationToNewVersion(\n parent,\n parentComponentSchema,\n grandParentSchemas,\n trx\n );\n }\n\n const parentContentType = strapi.contentTypes[parent.uid as UID.ContentType];\n\n // Keep relation if parent doesn't have draft & publish enabled\n if (!parentContentType?.options?.draftAndPublish) {\n return true;\n }\n\n // Discard relation if parent has draft & publish enabled\n return false;\n};\n\n/**\n * Creates a filter function for component relations that can be passed to the generic\n * unidirectional relations utility\n */\nconst createComponentRelationFilter = () => {\n return async (\n relation: Record<string, any>,\n model: Schema.Component | Schema.ContentType,\n trx: any\n ): Promise<boolean> => {\n // Only apply component-specific filtering for components\n if (model.modelType !== 'component') {\n return true;\n }\n\n const componentSchema = model as Schema.Component;\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n\n // Exit if no draft & publish parent types exist\n if (parentSchemas.length === 0) {\n return true;\n }\n\n return shouldPropagateComponentRelationToNewVersion(\n relation,\n componentSchema,\n parentSchemas,\n trx\n );\n };\n};\n\nexport {\n omitComponentData,\n assignComponentData,\n getComponents,\n createComponents,\n updateComponents,\n deleteComponents,\n deleteComponent,\n createComponentRelationFilter,\n findComponentParent,\n getParentSchemasForComponent,\n};\n"],"names":["omitComponentData","curry","schema","data","attributes","componentAttributes","Object","keys","filter","attributeName","contentTypesUtils","isComponentAttribute","omit","createComponents","uid","strapi","getModel","componentBody","attributeNames","attribute","has","type","component","componentUID","repeatable","componentValue","Array","isArray","Error","components","async","map","value","createComponent","id","__pivot","field","component_type","dynamiczoneValues","createDynamicZoneComponents","__component","getComponents","entity","getComponentAttributes","_","isEmpty","db","query","load","updateComponents","entityToUpdate","deleteOldComponents","updateOrCreateComponent","negate","isNil","deleteOldDZComponents","pickStringifiedId","previousValue","idsToKeep","castArray","allIds","forEach","includes","errors","ApplicationError","idsToDelete","difference","length","idToDelete","deleteComponent","v","find","el","err","assign","status","reduce","acc","push","deleteComponents","entityToDelete","loadComponents","subValue","componentData","entryData","assignComponentData","create","updateComponent","componentToUpdate","update","where","componentToDelete","delete","findComponentParent","componentSchema","componentId","parentSchemasForComponent","opts","schemaBuilder","getSchemaConnection","trx","withTrx","qb","transacting","parent","collectionName","identifiers","metadata","joinTableName","getComponentJoinTableName","tableExists","hasTable","entityIdColumn","getComponentJoinColumnEntityName","componentIdColumn","getComponentJoinColumnInverseName","componentTypeColumn","getComponentTypeColumn","parentRow","getConnection","first","table","parentId","getParentSchemasForComponent","values","contentTypes","some","attr","shouldPropagateComponentRelationToNewVersion","componentRelation","getJoinColumnAttributeIdName","snakeCase","modelName","parentComponentSchema","grandParentSchemas","parentContentType","options","draftAndPublish","createComponentRelationFilter","relation","model","modelType","parentSchemas"],"mappings":"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"}
1
+ {"version":3,"file":"components.mjs","sources":["../../../src/services/document-service/components.ts"],"sourcesContent":["import _, { assign, curry, has, omit } from 'lodash';\nimport type { Utils, UID, Schema, Data, Modules } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, async, errors } from '@strapi/utils';\nimport {\n getComponentJoinTableName,\n getComponentJoinColumnEntityName,\n getComponentJoinColumnInverseName,\n getComponentTypeColumn,\n} from '../../utils/transform-content-types-to-models';\n\n// type aliases for readability\ntype Input<T extends UID.Schema> = Modules.Documents.Params.Data.Input<T>;\n\ntype LoadedComponents<TUID extends UID.Schema> = Data.Entity<\n TUID,\n Schema.AttributeNamesByType<TUID, 'component' | 'dynamiczone'>\n>;\n\ntype SingleComponentValue = Schema.Attribute.ComponentValue<UID.Component, false>;\ntype RepeatableComponentValue = Schema.Attribute.ComponentValue<UID.Component, true>;\n\ntype ComponentValue = SingleComponentValue | RepeatableComponentValue;\n\ntype DynamicZoneValue = Schema.Attribute.DynamicZoneValue<UID.Component[]>;\n\ntype ComponentBody = {\n [key: string]: ComponentValue | DynamicZoneValue;\n};\n\nconst omitComponentData = curry(\n (schema: Schema.Schema, data: Input<UID.Schema>): Partial<Input<UID.Schema>> => {\n const { attributes } = schema;\n const componentAttributes = Object.keys(attributes).filter((attributeName) =>\n contentTypesUtils.isComponentAttribute(attributes[attributeName])\n );\n\n return omit(data, componentAttributes);\n }\n);\n\n// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer\nconst createComponents = async <TUID extends UID.Schema, TData extends Input<TUID>>(\n uid: TUID,\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (!has(data, attributeName) || !contentTypesUtils.isComponentAttribute(attribute)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData];\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>\n createComponent(componentUID, value)\n );\n\n componentBody[attributeName] = components.map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await createComponent(\n componentUID,\n componentValue as Input<UID.Component>\n );\n\n componentBody[attributeName] = {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as Modules.EntityService.Params.Attribute.GetValue<Schema.Attribute.DynamicZone>;\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const createDynamicZoneComponents = async (\n value: Utils.Array.Values<typeof dynamiczoneValues>\n ) => {\n const { id } = await createComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n };\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await async.map(\n dynamiczoneValues,\n createDynamicZoneComponents\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst getComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n entity: { id: Modules.EntityService.Params.Attribute.ID }\n): Promise<LoadedComponents<TUID>> => {\n const componentAttributes = contentTypesUtils.getComponentAttributes(strapi.getModel(uid));\n\n if (_.isEmpty(componentAttributes)) {\n return {} as LoadedComponents<TUID>;\n }\n\n return strapi.db.query(uid).load(entity, componentAttributes) as Promise<LoadedComponents<TUID>>;\n};\n\n/*\n delete old components\n create or update\n*/\nconst updateComponents = async <TUID extends UID.Schema, TData extends Partial<Input<TUID>>>(\n uid: TUID,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n if (!has(data, attributeName)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData] as ComponentValue;\n await deleteOldComponents(uid, componentUID, entityToUpdate, attributeName, componentValue);\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>\n updateOrCreateComponent(componentUID, value)\n );\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await updateOrCreateComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n } else if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[attributeName as keyof TData] as DynamicZoneValue;\n\n await deleteOldDZComponents(uid, entityToUpdate, attributeName, dynamiczoneValues);\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await async.map(dynamiczoneValues, async (value: any) => {\n const { id } = await updateOrCreateComponent(value.__component, value);\n\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n });\n }\n }\n\n return componentBody;\n};\n\nconst pickStringifiedId = ({\n id,\n}: {\n id: Modules.EntityService.Params.Attribute.ID;\n}): Modules.EntityService.Params.Attribute.ID & string => {\n if (typeof id === 'string') {\n return id;\n }\n\n return `${id}`;\n};\n\nconst deleteOldComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n componentUID: UID.Component,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n attributeName: string,\n componentValue: ComponentValue\n) => {\n const previousValue = (await strapi.db\n .query(uid)\n .load(entityToUpdate, attributeName)) as ComponentValue;\n const idsToKeep = _.castArray(componentValue)\n .filter((value) => has(value, 'id'))\n .map(pickStringifiedId);\n const allIds = _.castArray(previousValue)\n .filter((value) => has(value, 'id'))\n .map(pickStringifiedId);\n\n idsToKeep.forEach((id) => {\n if (!allIds.includes(id)) {\n throw new errors.ApplicationError(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n }\n });\n\n const idsToDelete = _.difference(allIds, idsToKeep);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n await deleteComponent(componentUID, { id: idToDelete });\n }\n }\n};\n\nconst deleteOldDZComponents = async <TUID extends UID.Schema>(\n uid: TUID,\n entityToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n attributeName: string,\n dynamiczoneValues: DynamicZoneValue\n) => {\n const previousValue = (await strapi.db\n .query(uid)\n .load(entityToUpdate, attributeName)) as DynamicZoneValue;\n\n const idsToKeep = _.castArray(dynamiczoneValues)\n .filter((value) => has(value, 'id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n const allIds = _.castArray(previousValue)\n .filter((value) => has(value, 'id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n idsToKeep.forEach(({ id, __component: componentUID }) => {\n if (!allIds.find((el) => el.id === id && el.__component === componentUID)) {\n const err = new Error(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n\n Object.assign(err, { status: 400 });\n throw err;\n }\n });\n\n type IdsToDelete = DynamicZoneValue;\n\n const idsToDelete = allIds.reduce((acc, { id, __component: componentUID }) => {\n if (!idsToKeep.find((el) => el.id === id && el.__component === componentUID)) {\n acc.push({ id, __component: componentUID });\n }\n\n return acc;\n }, [] as IdsToDelete);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n const { id, __component: componentUID } = idToDelete;\n await deleteComponent(componentUID, { id });\n }\n }\n};\n\nconst deleteComponents = async <TUID extends UID.Schema, TEntity extends Data.Entity<TUID>>(\n uid: TUID,\n entityToDelete: TEntity,\n { loadComponents = true } = {}\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute.type === 'component' || attribute.type === 'dynamiczone') {\n let value;\n\n if (loadComponents) {\n value = await strapi.db.query(uid).load(entityToDelete, attributeName);\n } else {\n value = entityToDelete[attributeName as keyof TEntity];\n }\n\n if (!value) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID } = attribute;\n await async.map(_.castArray(value), (subValue: any) =>\n deleteComponent(componentUID, subValue)\n );\n } else {\n await async.map(_.castArray(value), (subValue: any) =>\n deleteComponent(subValue.__component, subValue)\n );\n }\n\n continue;\n }\n }\n};\n\n/** *************************\n Component queries\n************************** */\n\n// components can have nested compos so this must be recursive\nconst createComponent = async <TUID extends UID.Component>(\n uid: TUID,\n data: Input<TUID>\n): Promise<Data.Component<TUID>> => {\n const schema = strapi.getModel(uid);\n\n const componentData = await createComponents(uid, data);\n\n // Make sure we don't save the component with a pre-defined ID.\n const entryData = assignComponentData(schema, componentData, omit(data, 'id'));\n\n return strapi.db.query(uid).create({ data: entryData });\n};\n\n// components can have nested compos so this must be recursive\nconst updateComponent = async <TUID extends UID.Component>(\n uid: TUID,\n componentToUpdate: { id: Modules.EntityService.Params.Attribute.ID },\n data: Input<TUID>\n) => {\n const schema = strapi.getModel(uid);\n\n const componentData = await updateComponents(uid, componentToUpdate, data);\n\n return strapi.db.query(uid).update({\n where: {\n id: componentToUpdate.id,\n },\n data: assignComponentData(schema, componentData, data),\n });\n};\n\nconst updateOrCreateComponent = <TUID extends UID.Component>(\n componentUID: TUID,\n value: Input<TUID>\n) => {\n if (value === null) {\n return null;\n }\n\n // update\n if ('id' in value && typeof value.id !== 'undefined') {\n // TODO: verify the compo is associated with the entity\n return updateComponent(componentUID, { id: value.id }, value);\n }\n\n // create\n return createComponent(componentUID, value);\n};\n\nconst deleteComponent = async <TUID extends UID.Component>(\n uid: TUID,\n componentToDelete: Data.Component<TUID>\n) => {\n await deleteComponents(uid, componentToDelete);\n await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });\n};\n\nconst assignComponentData = curry(\n (schema: Schema.Schema, componentData: ComponentBody, data: Input<UID.Schema>) => {\n return assign({}, componentData, omitComponentData(schema, data));\n }\n);\n\n/** *************************\n Component relation handling for document operations\n************************** */\n\ntype ComponentParent = { uid: string; table: string; parentId: number | string };\n\n// Component instance ids are bound as query parameters, so look them up in batches that stay\n// well below the bind parameter limit of every supported database\nconst PARENT_LOOKUP_BATCH_SIZE = 500;\n\n/**\n * Find the parent entries of many instances of the same component.\n *\n * Given a component model, component instance ids, and the list of possible parent\n * content types and components (those that can embed this component), this function\n * checks each parent's *_cmps join table to see which instances it links to a parent.\n * Parents are checked in order and the first one linking an instance is its parent.\n *\n * Each parent costs one query per batch of instances rather than one query per instance,\n * and parents are no longer checked once every instance has been found.\n *\n * - Returns a map from component instance id (as a string) to its parent uid, parent table\n * name and parent id.\n * - Instances without a parent are not in the map.\n */\nconst findComponentParents = async (\n componentSchema: Schema.Component,\n componentIds: (number | string)[],\n parentSchemasForComponent: (Schema.ContentType | Schema.Component)[],\n opts?: { trx?: any }\n): Promise<Map<string, ComponentParent>> => {\n const parents = new Map<string, ComponentParent>();\n if (!componentSchema?.uid) return parents;\n\n const withTrx = (qb: any) => (opts?.trx ? qb.transacting(opts.trx) : qb);\n\n // Use the exact same functions that create the columns\n const identifiers = strapi.db.metadata.identifiers;\n const entityIdColumn = getComponentJoinColumnEntityName(identifiers);\n const componentIdColumn = getComponentJoinColumnInverseName(identifiers);\n const componentTypeColumn = getComponentTypeColumn(identifiers);\n\n let pendingIds = _.uniqBy(\n componentIds.filter((id) => id !== undefined && id !== null),\n String\n );\n\n for (const parent of parentSchemasForComponent) {\n if (pendingIds.length === 0) break;\n if (!parent.collectionName) continue;\n\n // Use the exact same functions that create the tables\n const joinTableName = getComponentJoinTableName(parent.collectionName, identifiers);\n\n // The join table is registered as a model of its own (see createCompoLinkModel) and schema\n // sync creates every registered model, so the metadata knows whether it exists without\n // querying the database schema\n if (!strapi.db.metadata.has(joinTableName)) continue;\n\n for (const batch of _.chunk(pendingIds, PARENT_LOOKUP_BATCH_SIZE)) {\n try {\n const parentRows = await withTrx(strapi.db.getConnection(joinTableName))\n .select(entityIdColumn, componentIdColumn)\n .where(componentTypeColumn, componentSchema.uid)\n .whereIn(componentIdColumn, batch);\n\n for (const parentRow of parentRows) {\n const componentId = String(parentRow[componentIdColumn]);\n\n if (!parents.has(componentId)) {\n parents.set(componentId, {\n uid: parent.uid,\n table: parent.collectionName,\n parentId: parentRow[entityIdColumn],\n });\n }\n }\n } catch {\n continue;\n }\n }\n\n pendingIds = pendingIds.filter((id) => !parents.has(String(id)));\n }\n\n return parents;\n};\n\n/**\n * Find the parent entry of a component instance.\n *\n * Single-instance form of `findComponentParents`.\n *\n * - Returns the parent uid, parent table name, and parent id if found.\n * - Returns null if no parent relationship exists.\n */\nconst findComponentParent = async (\n componentSchema: Schema.Component,\n componentId: number | string,\n parentSchemasForComponent: (Schema.ContentType | Schema.Component)[],\n opts?: { trx?: any }\n): Promise<ComponentParent | null> => {\n const parents = await findComponentParents(\n componentSchema,\n [componentId],\n parentSchemasForComponent,\n opts\n );\n\n return parents.get(String(componentId)) ?? null;\n};\n\n/**\n * Finds content types that contain the given component and have draft & publish enabled.\n */\nconst getParentSchemasForComponent = (\n componentSchema: Schema.Component\n): Array<Schema.ContentType | Schema.Component> => {\n // Find direct parents in contentTypes and components\n return [...Object.values(strapi.contentTypes), ...Object.values(strapi.components)].filter(\n (schema: any) => {\n if (!schema?.attributes) return false;\n return Object.values(schema.attributes).some((attr: any) => {\n return (\n (attr.type === 'component' && attr.component === componentSchema.uid) ||\n (attr.type === 'dynamiczone' && attr.components?.includes(componentSchema.uid))\n );\n });\n }\n );\n};\n\n/**\n * Finds which of the given component instances belong to an entry of a content type with\n * draft and publish enabled, either directly or through parent components.\n *\n * Instances are resolved one nesting level at a time, so the number of queries depends on\n * the schema rather than on the number of instances.\n *\n * - Returns the ids (as strings) of the instances owned by a draft and publish entry.\n * - Instances without a parent, or owned by an entry without draft and publish, are not included.\n */\nconst findInstancesOwnedByDraftAndPublishEntries = async (\n componentSchema: Schema.Component,\n componentIds: (number | string)[],\n trx: any\n): Promise<Set<string>> => {\n const ownedIds = new Set<string>();\n\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n if (parentSchemas.length === 0) {\n return ownedIds;\n }\n\n const parents = await findComponentParents(componentSchema, componentIds, parentSchemas, {\n trx,\n });\n\n // Instances nested in another component, grouped by that component and its instance id\n const nestedInstances = new Map<\n UID.Component,\n Map<string, { parentId: number | string; componentIds: string[] }>\n >();\n\n for (const [componentId, parent] of parents) {\n if (strapi.components[parent.uid as UID.Component]) {\n const parentUid = parent.uid as UID.Component;\n const parentKey = String(parent.parentId);\n\n if (!nestedInstances.has(parentUid)) {\n nestedInstances.set(parentUid, new Map());\n }\n\n const instancesByParent = nestedInstances.get(parentUid)!;\n if (!instancesByParent.has(parentKey)) {\n instancesByParent.set(parentKey, { parentId: parent.parentId, componentIds: [] });\n }\n\n instancesByParent.get(parentKey)!.componentIds.push(componentId);\n continue;\n }\n\n if (strapi.contentTypes[parent.uid as UID.ContentType]?.options?.draftAndPublish) {\n ownedIds.add(componentId);\n }\n }\n\n // If the parent is a component, its own parents decide, so check them a level up\n for (const [parentUid, instancesByParent] of nestedInstances) {\n const ownedParentIds = await findInstancesOwnedByDraftAndPublishEntries(\n strapi.components[parentUid],\n Array.from(instancesByParent.values(), ({ parentId }) => parentId),\n trx\n );\n\n for (const parentKey of ownedParentIds) {\n instancesByParent.get(parentKey)?.componentIds.forEach((id) => ownedIds.add(id));\n }\n }\n\n return ownedIds;\n};\n\n/**\n * Creates a filter function for component relations that can be passed to the generic\n * unidirectional relations utility.\n *\n * A relation of a component instance is propagated to the new document version unless the\n * instance belongs to an entry with draft and publish enabled: that entry's new version gets\n * its own copy of the component.\n */\nconst createComponentRelationFilter = () => {\n return async (\n relations: Record<string, any>[],\n model: Schema.Component | Schema.ContentType,\n trx: any\n ): Promise<Record<string, any>[]> => {\n // Only apply component-specific filtering for components\n if (model.modelType !== 'component' || relations.length === 0) {\n return relations;\n }\n\n const componentSchema = model as Schema.Component;\n\n // Get the component ID column name using the actual component model name\n const componentIdColumn = strapi.db.metadata.identifiers.getJoinColumnAttributeIdName(\n _.snakeCase(componentSchema.modelName)\n );\n\n const ownedIds = await findInstancesOwnedByDraftAndPublishEntries(\n componentSchema,\n relations.map((relation) => relation[componentIdColumn]),\n trx\n );\n\n return relations.filter((relation) => !ownedIds.has(String(relation[componentIdColumn])));\n };\n};\n\nexport {\n omitComponentData,\n assignComponentData,\n getComponents,\n createComponents,\n updateComponents,\n deleteComponents,\n deleteComponent,\n createComponentRelationFilter,\n findComponentParent,\n getParentSchemasForComponent,\n};\n"],"names":["omitComponentData","curry","schema","data","attributes","componentAttributes","Object","keys","filter","attributeName","contentTypesUtils","isComponentAttribute","omit","createComponents","uid","strapi","getModel","componentBody","attributeNames","attribute","has","type","component","componentUID","repeatable","componentValue","Array","isArray","Error","components","async","map","value","createComponent","id","__pivot","field","component_type","dynamiczoneValues","createDynamicZoneComponents","__component","getComponents","entity","getComponentAttributes","_","isEmpty","db","query","load","updateComponents","entityToUpdate","deleteOldComponents","updateOrCreateComponent","negate","isNil","deleteOldDZComponents","pickStringifiedId","previousValue","idsToKeep","castArray","allIds","forEach","includes","errors","ApplicationError","idsToDelete","difference","length","idToDelete","deleteComponent","v","find","el","err","assign","status","reduce","acc","push","deleteComponents","entityToDelete","loadComponents","subValue","componentData","entryData","assignComponentData","create","updateComponent","componentToUpdate","update","where","componentToDelete","delete","PARENT_LOOKUP_BATCH_SIZE","findComponentParents","componentSchema","componentIds","parentSchemasForComponent","opts","parents","Map","withTrx","qb","trx","transacting","identifiers","metadata","entityIdColumn","getComponentJoinColumnEntityName","componentIdColumn","getComponentJoinColumnInverseName","componentTypeColumn","getComponentTypeColumn","pendingIds","uniqBy","undefined","String","parent","collectionName","joinTableName","getComponentJoinTableName","batch","chunk","parentRows","getConnection","select","whereIn","parentRow","componentId","set","table","parentId","findComponentParent","get","getParentSchemasForComponent","values","contentTypes","some","attr","findInstancesOwnedByDraftAndPublishEntries","ownedIds","Set","parentSchemas","nestedInstances","parentUid","parentKey","instancesByParent","options","draftAndPublish","add","ownedParentIds","from","createComponentRelationFilter","relations","model","modelType","getJoinColumnAttributeIdName","snakeCase","modelName","relation"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAK/D,QAAA,MAAM,MAAM;;;;;;;CAOX,CAAC;AAEF,KAAK,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,GAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,MAAM;IA2B5D;;;OAGG;yBACkB,SAAS,SAAS,OAAO,CAAC,SAAS,CAAC,WAAW;CAMvE,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAK/D,QAAA,MAAM,MAAM;;;;;;;CAOX,CAAC;AAEF,KAAK,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,GAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,MAAM;IA2B5D;;;OAGG;yBACkB,SAAS,SAAS,OAAO,CAAC,SAAS,CAAC,WAAW;CAYvE,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -44,7 +44,11 @@ const EVENTS = {
44
44
  * so this is executed after that transaction is committed.
45
45
  */ emitEvent (eventName, entry) {
46
46
  strapi.db.transaction(({ onCommit })=>{
47
- onCommit(()=>emitEvent(eventName, entry));
47
+ // The transaction runner discards the callback result, so a failure here
48
+ // (e.g. the re-read of the entry) would be an unhandled rejection.
49
+ onCommit(()=>emitEvent(eventName, entry).catch((error)=>{
50
+ strapi.log.error(`Could not emit ${eventName} for ${uid}: ${error?.message ?? error}`);
51
+ }));
48
52
  });
49
53
  }
50
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sources":["../../../src/services/document-service/events.ts"],"sourcesContent":["import type { UID, Utils, Modules, Core } from '@strapi/types';\nimport { sanitize } from '@strapi/utils';\n\nimport { getDeepPopulate } from './utils/populate';\n\nconst EVENTS = {\n ENTRY_CREATE: 'entry.create',\n ENTRY_UPDATE: 'entry.update',\n ENTRY_DELETE: 'entry.delete',\n ENTRY_PUBLISH: 'entry.publish',\n ENTRY_UNPUBLISH: 'entry.unpublish',\n ENTRY_DRAFT_DISCARD: 'entry.draft-discard',\n};\n\ntype EventName = Utils.Object.Values<typeof EVENTS>;\n\n/**\n * Manager to trigger entry related events\n *\n * It will populate the entry if it is not a delete event.\n * So the event payload will contain the full entry.\n */\nconst createEventManager = (strapi: Core.Strapi, uid: UID.Schema) => {\n const populate = getDeepPopulate(uid, {});\n const model = strapi.getModel(uid);\n\n const emitEvent = async (eventName: EventName, entry: Modules.Documents.AnyDocument) => {\n // There is no need to populate the entry if it has been deleted\n let populatedEntry = entry;\n if (![EVENTS.ENTRY_DELETE, EVENTS.ENTRY_UNPUBLISH].includes(eventName)) {\n populatedEntry = await strapi.db.query(uid).findOne({ where: { id: entry.id }, populate });\n }\n\n const sanitizedEntry = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: model,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n populatedEntry\n );\n\n await strapi.eventHub.emit(eventName, {\n model: model.modelName,\n uid: model.uid,\n entry: sanitizedEntry,\n });\n };\n\n return {\n /**\n * strapi.db.query might reuse the transaction used in the doc service request,\n * so this is executed after that transaction is committed.\n */\n emitEvent(eventName: EventName, entry: Modules.Documents.AnyDocument) {\n strapi.db.transaction(({ onCommit }) => {\n onCommit(() => emitEvent(eventName, entry));\n });\n },\n };\n};\n\nexport { createEventManager };\n"],"names":["EVENTS","ENTRY_DELETE","ENTRY_UNPUBLISH","createEventManager","strapi","uid","populate","getDeepPopulate","model","getModel","emitEvent","eventName","entry","populatedEntry","includes","db","query","findOne","where","id","sanitizedEntry","sanitize","sanitizers","defaultSanitizeOutput","schema","eventHub","emit","modelName","transaction","onCommit"],"mappings":";;;;;AAKA,MAAMA,MAAAA,GAAS;IAGbC,YAAAA,EAAc,cAAA;IAEdC,eAAAA,EAAiB,iBAEnB,CAAA;AAIA;;;;;IAMA,MAAMC,kBAAAA,GAAqB,CAACC,MAAAA,EAAqBC,GAAAA,GAAAA;IAC/C,MAAMC,UAAAA,GAAWC,wBAAAA,CAAgBF,GAAAA,EAAK,EAAC,CAAA;IACvC,MAAMG,KAAAA,GAAQJ,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA,CAAAA;IAE9B,MAAMK,SAAAA,GAAY,OAAOC,SAAAA,EAAsBC,KAAAA,GAAAA;;AAE7C,QAAA,IAAIC,cAAAA,GAAiBD,KAAAA;AACrB,QAAA,IAAI,CAAC;AAACZ,YAAAA,MAAAA,CAAOC,YAAY;AAAED,YAAAA,MAAAA,CAAOE;SAAgB,CAACY,QAAQ,CAACH,SAAAA,CAAAA,EAAY;YACtEE,cAAAA,GAAiB,MAAMT,OAAOW,EAAE,CAACC,KAAK,CAACX,GAAAA,CAAAA,CAAKY,OAAO,CAAC;gBAAEC,KAAAA,EAAO;AAAEC,oBAAAA,EAAAA,EAAIP,MAAMO;AAAG,iBAAA;AAAGb,0BAAAA;AAAS,aAAA,CAAA;AAC1F,QAAA;AAEA,QAAA,MAAMc,iBAAiB,MAAMC,oBAAAA,CAASC,UAAU,CAACC,qBAAqB,CACpE;YACEC,MAAAA,EAAQhB,KAAAA;AACRC,YAAAA,QAAAA,EAAU,CAACJ,GAAAA,GAAQD,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA;SACrC,EACAQ,cAAAA,CAAAA;AAGF,QAAA,MAAMT,MAAAA,CAAOqB,QAAQ,CAACC,IAAI,CAACf,SAAAA,EAAW;AACpCH,YAAAA,KAAAA,EAAOA,MAAMmB,SAAS;AACtBtB,YAAAA,GAAAA,EAAKG,MAAMH,GAAG;YACdO,KAAAA,EAAOQ;AACT,SAAA,CAAA;AACF,IAAA,CAAA;IAEA,OAAO;AACL;;;QAIAV,SAAAA,CAAAA,CAAUC,SAAoB,EAAEC,KAAoC,EAAA;AAClER,YAAAA,MAAAA,CAAOW,EAAE,CAACa,WAAW,CAAC,CAAC,EAAEC,QAAQ,EAAE,GAAA;gBACjCA,QAAAA,CAAS,IAAMnB,UAAUC,SAAAA,EAAWC,KAAAA,CAAAA,CAAAA;AACtC,YAAA,CAAA,CAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"events.js","sources":["../../../src/services/document-service/events.ts"],"sourcesContent":["import type { UID, Utils, Modules, Core } from '@strapi/types';\nimport { sanitize } from '@strapi/utils';\n\nimport { getDeepPopulate } from './utils/populate';\n\nconst EVENTS = {\n ENTRY_CREATE: 'entry.create',\n ENTRY_UPDATE: 'entry.update',\n ENTRY_DELETE: 'entry.delete',\n ENTRY_PUBLISH: 'entry.publish',\n ENTRY_UNPUBLISH: 'entry.unpublish',\n ENTRY_DRAFT_DISCARD: 'entry.draft-discard',\n};\n\ntype EventName = Utils.Object.Values<typeof EVENTS>;\n\n/**\n * Manager to trigger entry related events\n *\n * It will populate the entry if it is not a delete event.\n * So the event payload will contain the full entry.\n */\nconst createEventManager = (strapi: Core.Strapi, uid: UID.Schema) => {\n const populate = getDeepPopulate(uid, {});\n const model = strapi.getModel(uid);\n\n const emitEvent = async (eventName: EventName, entry: Modules.Documents.AnyDocument) => {\n // There is no need to populate the entry if it has been deleted\n let populatedEntry = entry;\n if (![EVENTS.ENTRY_DELETE, EVENTS.ENTRY_UNPUBLISH].includes(eventName)) {\n populatedEntry = await strapi.db.query(uid).findOne({ where: { id: entry.id }, populate });\n }\n\n const sanitizedEntry = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: model,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n populatedEntry\n );\n\n await strapi.eventHub.emit(eventName, {\n model: model.modelName,\n uid: model.uid,\n entry: sanitizedEntry,\n });\n };\n\n return {\n /**\n * strapi.db.query might reuse the transaction used in the doc service request,\n * so this is executed after that transaction is committed.\n */\n emitEvent(eventName: EventName, entry: Modules.Documents.AnyDocument) {\n strapi.db.transaction(({ onCommit }) => {\n // The transaction runner discards the callback result, so a failure here\n // (e.g. the re-read of the entry) would be an unhandled rejection.\n onCommit(() =>\n emitEvent(eventName, entry).catch((error) => {\n strapi.log.error(`Could not emit ${eventName} for ${uid}: ${error?.message ?? error}`);\n })\n );\n });\n },\n };\n};\n\nexport { createEventManager };\n"],"names":["EVENTS","ENTRY_DELETE","ENTRY_UNPUBLISH","createEventManager","strapi","uid","populate","getDeepPopulate","model","getModel","emitEvent","eventName","entry","populatedEntry","includes","db","query","findOne","where","id","sanitizedEntry","sanitize","sanitizers","defaultSanitizeOutput","schema","eventHub","emit","modelName","transaction","onCommit","catch","error","log","message"],"mappings":";;;;;AAKA,MAAMA,MAAAA,GAAS;IAGbC,YAAAA,EAAc,cAAA;IAEdC,eAAAA,EAAiB,iBAEnB,CAAA;AAIA;;;;;IAMA,MAAMC,kBAAAA,GAAqB,CAACC,MAAAA,EAAqBC,GAAAA,GAAAA;IAC/C,MAAMC,UAAAA,GAAWC,wBAAAA,CAAgBF,GAAAA,EAAK,EAAC,CAAA;IACvC,MAAMG,KAAAA,GAAQJ,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA,CAAAA;IAE9B,MAAMK,SAAAA,GAAY,OAAOC,SAAAA,EAAsBC,KAAAA,GAAAA;;AAE7C,QAAA,IAAIC,cAAAA,GAAiBD,KAAAA;AACrB,QAAA,IAAI,CAAC;AAACZ,YAAAA,MAAAA,CAAOC,YAAY;AAAED,YAAAA,MAAAA,CAAOE;SAAgB,CAACY,QAAQ,CAACH,SAAAA,CAAAA,EAAY;YACtEE,cAAAA,GAAiB,MAAMT,OAAOW,EAAE,CAACC,KAAK,CAACX,GAAAA,CAAAA,CAAKY,OAAO,CAAC;gBAAEC,KAAAA,EAAO;AAAEC,oBAAAA,EAAAA,EAAIP,MAAMO;AAAG,iBAAA;AAAGb,0BAAAA;AAAS,aAAA,CAAA;AAC1F,QAAA;AAEA,QAAA,MAAMc,iBAAiB,MAAMC,oBAAAA,CAASC,UAAU,CAACC,qBAAqB,CACpE;YACEC,MAAAA,EAAQhB,KAAAA;AACRC,YAAAA,QAAAA,EAAU,CAACJ,GAAAA,GAAQD,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA;SACrC,EACAQ,cAAAA,CAAAA;AAGF,QAAA,MAAMT,MAAAA,CAAOqB,QAAQ,CAACC,IAAI,CAACf,SAAAA,EAAW;AACpCH,YAAAA,KAAAA,EAAOA,MAAMmB,SAAS;AACtBtB,YAAAA,GAAAA,EAAKG,MAAMH,GAAG;YACdO,KAAAA,EAAOQ;AACT,SAAA,CAAA;AACF,IAAA,CAAA;IAEA,OAAO;AACL;;;QAIAV,SAAAA,CAAAA,CAAUC,SAAoB,EAAEC,KAAoC,EAAA;AAClER,YAAAA,MAAAA,CAAOW,EAAE,CAACa,WAAW,CAAC,CAAC,EAAEC,QAAQ,EAAE,GAAA;;;AAGjCA,gBAAAA,QAAAA,CAAS,IACPnB,SAAAA,CAAUC,SAAAA,EAAWC,KAAAA,CAAAA,CAAOkB,KAAK,CAAC,CAACC,KAAAA,GAAAA;AACjC3B,wBAAAA,MAAAA,CAAO4B,GAAG,CAACD,KAAK,CAAC,CAAC,eAAe,EAAEpB,SAAAA,CAAU,KAAK,EAAEN,GAAAA,CAAI,EAAE,EAAE0B,KAAAA,EAAOE,WAAWF,KAAAA,CAAAA,CAAO,CAAA;AACvF,oBAAA,CAAA,CAAA,CAAA;AAEJ,YAAA,CAAA,CAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
@@ -42,7 +42,11 @@ const EVENTS = {
42
42
  * so this is executed after that transaction is committed.
43
43
  */ emitEvent (eventName, entry) {
44
44
  strapi.db.transaction(({ onCommit })=>{
45
- onCommit(()=>emitEvent(eventName, entry));
45
+ // The transaction runner discards the callback result, so a failure here
46
+ // (e.g. the re-read of the entry) would be an unhandled rejection.
47
+ onCommit(()=>emitEvent(eventName, entry).catch((error)=>{
48
+ strapi.log.error(`Could not emit ${eventName} for ${uid}: ${error?.message ?? error}`);
49
+ }));
46
50
  });
47
51
  }
48
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"events.mjs","sources":["../../../src/services/document-service/events.ts"],"sourcesContent":["import type { UID, Utils, Modules, Core } from '@strapi/types';\nimport { sanitize } from '@strapi/utils';\n\nimport { getDeepPopulate } from './utils/populate';\n\nconst EVENTS = {\n ENTRY_CREATE: 'entry.create',\n ENTRY_UPDATE: 'entry.update',\n ENTRY_DELETE: 'entry.delete',\n ENTRY_PUBLISH: 'entry.publish',\n ENTRY_UNPUBLISH: 'entry.unpublish',\n ENTRY_DRAFT_DISCARD: 'entry.draft-discard',\n};\n\ntype EventName = Utils.Object.Values<typeof EVENTS>;\n\n/**\n * Manager to trigger entry related events\n *\n * It will populate the entry if it is not a delete event.\n * So the event payload will contain the full entry.\n */\nconst createEventManager = (strapi: Core.Strapi, uid: UID.Schema) => {\n const populate = getDeepPopulate(uid, {});\n const model = strapi.getModel(uid);\n\n const emitEvent = async (eventName: EventName, entry: Modules.Documents.AnyDocument) => {\n // There is no need to populate the entry if it has been deleted\n let populatedEntry = entry;\n if (![EVENTS.ENTRY_DELETE, EVENTS.ENTRY_UNPUBLISH].includes(eventName)) {\n populatedEntry = await strapi.db.query(uid).findOne({ where: { id: entry.id }, populate });\n }\n\n const sanitizedEntry = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: model,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n populatedEntry\n );\n\n await strapi.eventHub.emit(eventName, {\n model: model.modelName,\n uid: model.uid,\n entry: sanitizedEntry,\n });\n };\n\n return {\n /**\n * strapi.db.query might reuse the transaction used in the doc service request,\n * so this is executed after that transaction is committed.\n */\n emitEvent(eventName: EventName, entry: Modules.Documents.AnyDocument) {\n strapi.db.transaction(({ onCommit }) => {\n onCommit(() => emitEvent(eventName, entry));\n });\n },\n };\n};\n\nexport { createEventManager };\n"],"names":["EVENTS","ENTRY_DELETE","ENTRY_UNPUBLISH","createEventManager","strapi","uid","populate","getDeepPopulate","model","getModel","emitEvent","eventName","entry","populatedEntry","includes","db","query","findOne","where","id","sanitizedEntry","sanitize","sanitizers","defaultSanitizeOutput","schema","eventHub","emit","modelName","transaction","onCommit"],"mappings":";;;AAKA,MAAMA,MAAAA,GAAS;IAGbC,YAAAA,EAAc,cAAA;IAEdC,eAAAA,EAAiB,iBAEnB,CAAA;AAIA;;;;;IAMA,MAAMC,kBAAAA,GAAqB,CAACC,MAAAA,EAAqBC,GAAAA,GAAAA;IAC/C,MAAMC,QAAAA,GAAWC,eAAAA,CAAgBF,GAAAA,EAAK,EAAC,CAAA;IACvC,MAAMG,KAAAA,GAAQJ,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA,CAAAA;IAE9B,MAAMK,SAAAA,GAAY,OAAOC,SAAAA,EAAsBC,KAAAA,GAAAA;;AAE7C,QAAA,IAAIC,cAAAA,GAAiBD,KAAAA;AACrB,QAAA,IAAI,CAAC;AAACZ,YAAAA,MAAAA,CAAOC,YAAY;AAAED,YAAAA,MAAAA,CAAOE;SAAgB,CAACY,QAAQ,CAACH,SAAAA,CAAAA,EAAY;YACtEE,cAAAA,GAAiB,MAAMT,OAAOW,EAAE,CAACC,KAAK,CAACX,GAAAA,CAAAA,CAAKY,OAAO,CAAC;gBAAEC,KAAAA,EAAO;AAAEC,oBAAAA,EAAAA,EAAIP,MAAMO;AAAG,iBAAA;AAAGb,gBAAAA;AAAS,aAAA,CAAA;AAC1F,QAAA;AAEA,QAAA,MAAMc,iBAAiB,MAAMC,QAAAA,CAASC,UAAU,CAACC,qBAAqB,CACpE;YACEC,MAAAA,EAAQhB,KAAAA;AACRC,YAAAA,QAAAA,EAAU,CAACJ,GAAAA,GAAQD,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA;SACrC,EACAQ,cAAAA,CAAAA;AAGF,QAAA,MAAMT,MAAAA,CAAOqB,QAAQ,CAACC,IAAI,CAACf,SAAAA,EAAW;AACpCH,YAAAA,KAAAA,EAAOA,MAAMmB,SAAS;AACtBtB,YAAAA,GAAAA,EAAKG,MAAMH,GAAG;YACdO,KAAAA,EAAOQ;AACT,SAAA,CAAA;AACF,IAAA,CAAA;IAEA,OAAO;AACL;;;QAIAV,SAAAA,CAAAA,CAAUC,SAAoB,EAAEC,KAAoC,EAAA;AAClER,YAAAA,MAAAA,CAAOW,EAAE,CAACa,WAAW,CAAC,CAAC,EAAEC,QAAQ,EAAE,GAAA;gBACjCA,QAAAA,CAAS,IAAMnB,UAAUC,SAAAA,EAAWC,KAAAA,CAAAA,CAAAA;AACtC,YAAA,CAAA,CAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"events.mjs","sources":["../../../src/services/document-service/events.ts"],"sourcesContent":["import type { UID, Utils, Modules, Core } from '@strapi/types';\nimport { sanitize } from '@strapi/utils';\n\nimport { getDeepPopulate } from './utils/populate';\n\nconst EVENTS = {\n ENTRY_CREATE: 'entry.create',\n ENTRY_UPDATE: 'entry.update',\n ENTRY_DELETE: 'entry.delete',\n ENTRY_PUBLISH: 'entry.publish',\n ENTRY_UNPUBLISH: 'entry.unpublish',\n ENTRY_DRAFT_DISCARD: 'entry.draft-discard',\n};\n\ntype EventName = Utils.Object.Values<typeof EVENTS>;\n\n/**\n * Manager to trigger entry related events\n *\n * It will populate the entry if it is not a delete event.\n * So the event payload will contain the full entry.\n */\nconst createEventManager = (strapi: Core.Strapi, uid: UID.Schema) => {\n const populate = getDeepPopulate(uid, {});\n const model = strapi.getModel(uid);\n\n const emitEvent = async (eventName: EventName, entry: Modules.Documents.AnyDocument) => {\n // There is no need to populate the entry if it has been deleted\n let populatedEntry = entry;\n if (![EVENTS.ENTRY_DELETE, EVENTS.ENTRY_UNPUBLISH].includes(eventName)) {\n populatedEntry = await strapi.db.query(uid).findOne({ where: { id: entry.id }, populate });\n }\n\n const sanitizedEntry = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: model,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n populatedEntry\n );\n\n await strapi.eventHub.emit(eventName, {\n model: model.modelName,\n uid: model.uid,\n entry: sanitizedEntry,\n });\n };\n\n return {\n /**\n * strapi.db.query might reuse the transaction used in the doc service request,\n * so this is executed after that transaction is committed.\n */\n emitEvent(eventName: EventName, entry: Modules.Documents.AnyDocument) {\n strapi.db.transaction(({ onCommit }) => {\n // The transaction runner discards the callback result, so a failure here\n // (e.g. the re-read of the entry) would be an unhandled rejection.\n onCommit(() =>\n emitEvent(eventName, entry).catch((error) => {\n strapi.log.error(`Could not emit ${eventName} for ${uid}: ${error?.message ?? error}`);\n })\n );\n });\n },\n };\n};\n\nexport { createEventManager };\n"],"names":["EVENTS","ENTRY_DELETE","ENTRY_UNPUBLISH","createEventManager","strapi","uid","populate","getDeepPopulate","model","getModel","emitEvent","eventName","entry","populatedEntry","includes","db","query","findOne","where","id","sanitizedEntry","sanitize","sanitizers","defaultSanitizeOutput","schema","eventHub","emit","modelName","transaction","onCommit","catch","error","log","message"],"mappings":";;;AAKA,MAAMA,MAAAA,GAAS;IAGbC,YAAAA,EAAc,cAAA;IAEdC,eAAAA,EAAiB,iBAEnB,CAAA;AAIA;;;;;IAMA,MAAMC,kBAAAA,GAAqB,CAACC,MAAAA,EAAqBC,GAAAA,GAAAA;IAC/C,MAAMC,QAAAA,GAAWC,eAAAA,CAAgBF,GAAAA,EAAK,EAAC,CAAA;IACvC,MAAMG,KAAAA,GAAQJ,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA,CAAAA;IAE9B,MAAMK,SAAAA,GAAY,OAAOC,SAAAA,EAAsBC,KAAAA,GAAAA;;AAE7C,QAAA,IAAIC,cAAAA,GAAiBD,KAAAA;AACrB,QAAA,IAAI,CAAC;AAACZ,YAAAA,MAAAA,CAAOC,YAAY;AAAED,YAAAA,MAAAA,CAAOE;SAAgB,CAACY,QAAQ,CAACH,SAAAA,CAAAA,EAAY;YACtEE,cAAAA,GAAiB,MAAMT,OAAOW,EAAE,CAACC,KAAK,CAACX,GAAAA,CAAAA,CAAKY,OAAO,CAAC;gBAAEC,KAAAA,EAAO;AAAEC,oBAAAA,EAAAA,EAAIP,MAAMO;AAAG,iBAAA;AAAGb,gBAAAA;AAAS,aAAA,CAAA;AAC1F,QAAA;AAEA,QAAA,MAAMc,iBAAiB,MAAMC,QAAAA,CAASC,UAAU,CAACC,qBAAqB,CACpE;YACEC,MAAAA,EAAQhB,KAAAA;AACRC,YAAAA,QAAAA,EAAU,CAACJ,GAAAA,GAAQD,MAAAA,CAAOK,QAAQ,CAACJ,GAAAA;SACrC,EACAQ,cAAAA,CAAAA;AAGF,QAAA,MAAMT,MAAAA,CAAOqB,QAAQ,CAACC,IAAI,CAACf,SAAAA,EAAW;AACpCH,YAAAA,KAAAA,EAAOA,MAAMmB,SAAS;AACtBtB,YAAAA,GAAAA,EAAKG,MAAMH,GAAG;YACdO,KAAAA,EAAOQ;AACT,SAAA,CAAA;AACF,IAAA,CAAA;IAEA,OAAO;AACL;;;QAIAV,SAAAA,CAAAA,CAAUC,SAAoB,EAAEC,KAAoC,EAAA;AAClER,YAAAA,MAAAA,CAAOW,EAAE,CAACa,WAAW,CAAC,CAAC,EAAEC,QAAQ,EAAE,GAAA;;;AAGjCA,gBAAAA,QAAAA,CAAS,IACPnB,SAAAA,CAAUC,SAAAA,EAAWC,KAAAA,CAAAA,CAAOkB,KAAK,CAAC,CAACC,KAAAA,GAAAA;AACjC3B,wBAAAA,MAAAA,CAAO4B,GAAG,CAACD,KAAK,CAAC,CAAC,eAAe,EAAEpB,SAAAA,CAAU,KAAK,EAAEN,GAAAA,CAAI,EAAE,EAAE0B,KAAAA,EAAOE,WAAWF,KAAAA,CAAAA,CAAO,CAAA;AACvF,oBAAA,CAAA,CAAA,CAAA;AAEJ,YAAA,CAAA,CAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/repository.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AA2C3E,eAAO,MAAM,2BAA2B,EAAE,uBAiuBzC,CAAC"}
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/repository.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AA+C3E,eAAO,MAAM,2BAA2B,EAAE,uBAmwBzC,CAAC"}
@@ -335,7 +335,7 @@ const createContentTypeRepository = (uid, validator = index)=>{
335
335
  'createdAt',
336
336
  'updatedAt'
337
337
  ]);
338
- const { data, relationsToCopy } = await cloneRelations.prepareCloneData(originalData, queryParams.data, contentType, (modelUid)=>strapi.getModel(modelUid));
338
+ const { data, deferredCopies, postCloneUpdates } = await cloneRelations.prepareCloneData(originalData, queryParams.data, contentType, (modelUid)=>strapi.getModel(modelUid));
339
339
  const dataWithDocumentId = {
340
340
  ...data,
341
341
  documentId: newDocumentId
@@ -345,14 +345,33 @@ const createContentTypeRepository = (uid, validator = index)=>{
345
345
  data: dataWithDocumentId,
346
346
  status: 'draft'
347
347
  });
348
- await cloneRelations.copyCloneRelationRows(strapi, uid, sourceEntryId, doc.id, relationsToCopy);
349
- if (relationsToCopy.length === 0) {
350
- return doc;
351
- }
348
+ const needsRelationFollowUp = deferredCopies.length > 0 || postCloneUpdates.length > 0;
352
349
  const selectionQuery = query.transformParamsToQuery(uid, params.pickSelectionParams({
353
350
  ...queryParams,
354
351
  status: 'draft'
355
352
  }));
353
+ const clonedEntry = needsRelationFollowUp ? await strapi.db.query(uid).findOne({
354
+ ...selectionQuery,
355
+ where: {
356
+ id: doc.id
357
+ },
358
+ populate: populate.getDeepPopulate(uid, {
359
+ relationalFields: [
360
+ 'id'
361
+ ]
362
+ })
363
+ }) : doc;
364
+ if (clonedEntry) {
365
+ await cloneRelations.applyDeferredCloneRelationCopies(strapi, uid, sourceEntryId, doc.id, originalData, clonedEntry, deferredCopies);
366
+ await cloneRelations.applyPostCloneRelationUpdates(strapi, uid, sourceEntryId, doc.id, {
367
+ ...clonedEntry,
368
+ documentId: doc.documentId,
369
+ locale: entryToClone.locale ?? queryParams.locale ?? queryParams.data?.locale
370
+ }, originalData, postCloneUpdates);
371
+ }
372
+ if (!needsRelationFollowUp) {
373
+ return doc;
374
+ }
356
375
  return strapi.db.query(uid).findOne({
357
376
  ...selectionQuery,
358
377
  where: {
@@ -455,7 +474,7 @@ const createContentTypeRepository = (uid, validator = index)=>{
455
474
  newVersions: draftsToPublish,
456
475
  oldVersions: oldPublishedVersions
457
476
  }, {
458
- shouldPropagateRelation: components.createComponentRelationFilter()
477
+ filterRelationsToPropagate: components.createComponentRelationFilter()
459
478
  });
460
479
  const bidirectionalRelationsToSync = await bidirectionalRelations.load(uid, {
461
480
  newVersions: draftsToPublish,
@@ -548,7 +567,7 @@ const createContentTypeRepository = (uid, validator = index)=>{
548
567
  newVersions: versionsToDraft,
549
568
  oldVersions: oldDrafts
550
569
  }, {
551
- shouldPropagateRelation: components.createComponentRelationFilter()
570
+ filterRelationsToPropagate: components.createComponentRelationFilter()
552
571
  });
553
572
  const bidirectionalRelationsToSync = await bidirectionalRelations.load(uid, {
554
573
  newVersions: versionsToDraft,