@strapi/content-manager 0.0.0-next.c9f32f6f0c2be1b88323373117f12eb33219d20e → 0.0.0-next.cb666fde52df857549ddd0e7bf1f6888f5d06951

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 (136) hide show
  1. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
  2. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-N-CTtgQa.js → ComponentConfigurationPage-BLWQy8ru.js} +4 -5
  4. package/dist/_chunks/{ComponentConfigurationPage-N-CTtgQa.js.map → ComponentConfigurationPage-BLWQy8ru.js.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-BaJMOQyq.mjs → ComponentConfigurationPage-CtIa3aa2.mjs} +3 -3
  6. package/dist/_chunks/{ComponentConfigurationPage-BaJMOQyq.mjs.map → ComponentConfigurationPage-CtIa3aa2.mjs.map} +1 -1
  7. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  9. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  10. package/dist/_chunks/{EditConfigurationPage-CKK-5LfX.mjs → EditConfigurationPage-DsPR2DVk.mjs} +3 -3
  11. package/dist/_chunks/{EditConfigurationPage-CKK-5LfX.mjs.map → EditConfigurationPage-DsPR2DVk.mjs.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-BHkjAbxH.js → EditConfigurationPage-RQkymxCy.js} +4 -5
  13. package/dist/_chunks/{EditConfigurationPage-BHkjAbxH.js.map → EditConfigurationPage-RQkymxCy.js.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-QPUftxUd.js → EditViewPage-B-kExt8C.js} +4 -5
  15. package/dist/_chunks/{EditViewPage-QPUftxUd.js.map → EditViewPage-B-kExt8C.js.map} +1 -1
  16. package/dist/_chunks/{EditViewPage-B11aeMcf.mjs → EditViewPage-BPyVuPfM.mjs} +3 -3
  17. package/dist/_chunks/{EditViewPage-B11aeMcf.mjs.map → EditViewPage-BPyVuPfM.mjs.map} +1 -1
  18. package/dist/_chunks/{Field-DUK83cfh.js → Field-DPIsQRre.js} +139 -103
  19. package/dist/_chunks/Field-DPIsQRre.js.map +1 -0
  20. package/dist/_chunks/{Field-Bj_RgtGo.mjs → Field-Dltnt1km.mjs} +136 -100
  21. package/dist/_chunks/Field-Dltnt1km.mjs.map +1 -0
  22. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  23. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  24. package/dist/_chunks/{Form-DHmBRlHd.js → Form-BFi4MXMT.js} +5 -6
  25. package/dist/_chunks/{Form-DHmBRlHd.js.map → Form-BFi4MXMT.js.map} +1 -1
  26. package/dist/_chunks/{Form-DLMSoXV7.mjs → Form-C1IcWm1u.mjs} +3 -3
  27. package/dist/_chunks/{Form-DLMSoXV7.mjs.map → Form-C1IcWm1u.mjs.map} +1 -1
  28. package/dist/_chunks/{History-CfCSNlG9.mjs → History-04ChQ4pl.mjs} +32 -8
  29. package/dist/_chunks/History-04ChQ4pl.mjs.map +1 -0
  30. package/dist/_chunks/{History-Di3zm4HT.js → History-wjcK4L0C.js} +33 -10
  31. package/dist/_chunks/History-wjcK4L0C.js.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-0mtv_iqk.mjs → ListConfigurationPage-BYqPYLSU.mjs} +3 -3
  33. package/dist/_chunks/{ListConfigurationPage-0mtv_iqk.mjs.map → ListConfigurationPage-BYqPYLSU.mjs.map} +1 -1
  34. package/dist/_chunks/{ListConfigurationPage-Cq361KIt.js → ListConfigurationPage-CRbxIC3J.js} +4 -5
  35. package/dist/_chunks/{ListConfigurationPage-Cq361KIt.js.map → ListConfigurationPage-CRbxIC3J.js.map} +1 -1
  36. package/dist/_chunks/{ListViewPage-DFDcG8gM.js → ListViewPage-D5NY9183.js} +4 -5
  37. package/dist/_chunks/{ListViewPage-DFDcG8gM.js.map → ListViewPage-D5NY9183.js.map} +1 -1
  38. package/dist/_chunks/{ListViewPage-BxLVROX8.mjs → ListViewPage-FU2LBuhl.mjs} +3 -3
  39. package/dist/_chunks/{ListViewPage-BxLVROX8.mjs.map → ListViewPage-FU2LBuhl.mjs.map} +1 -1
  40. package/dist/_chunks/{NoContentTypePage-BSyvnDZZ.js → NoContentTypePage-BgQVE_Qb.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-BSyvnDZZ.js.map → NoContentTypePage-BgQVE_Qb.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-BRfDd67_.mjs → NoContentTypePage-DCKUkwb8.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-BRfDd67_.mjs.map → NoContentTypePage-DCKUkwb8.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-DyLphsn_.js → NoPermissionsPage-C5jwn70o.js} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-DyLphsn_.js.map → NoPermissionsPage-C5jwn70o.js.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-CV9V8KWa.mjs → NoPermissionsPage-jqve7C8l.mjs} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-CV9V8KWa.mjs.map → NoPermissionsPage-jqve7C8l.mjs.map} +1 -1
  48. package/dist/_chunks/{Preview-C_B1nx3g.mjs → Preview-BMYN548c.mjs} +33 -11
  49. package/dist/_chunks/Preview-BMYN548c.mjs.map +1 -0
  50. package/dist/_chunks/{Preview-D_3aO6Ly.js → Preview-DaOihysv.js} +33 -12
  51. package/dist/_chunks/Preview-DaOihysv.js.map +1 -0
  52. package/dist/_chunks/{Relations-Cne2AlrL.js → Relations-CTGM7Hv5.js} +7 -10
  53. package/dist/_chunks/{Relations-Cne2AlrL.js.map → Relations-CTGM7Hv5.js.map} +1 -1
  54. package/dist/_chunks/{Relations-C6pwmDXh.mjs → Relations-gscPkxjF.mjs} +6 -8
  55. package/dist/_chunks/{Relations-C6pwmDXh.mjs.map → Relations-gscPkxjF.mjs.map} +1 -1
  56. package/dist/_chunks/{en-Ic0kXjxB.js → en-BzQmavmK.js} +8 -2
  57. package/dist/_chunks/{en-Ic0kXjxB.js.map → en-BzQmavmK.js.map} +1 -1
  58. package/dist/_chunks/{en-DhFUjrNW.mjs → en-CSxLmrh1.mjs} +8 -2
  59. package/dist/_chunks/{en-DhFUjrNW.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
  60. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  61. package/dist/_chunks/{index-T-aWjbj2.js → index-Ca7YWlAA.js} +232 -135
  62. package/dist/_chunks/index-Ca7YWlAA.js.map +1 -0
  63. package/dist/_chunks/{index-BpxR3En4.mjs → index-DqasUQ6Q.mjs} +231 -133
  64. package/dist/_chunks/index-DqasUQ6Q.mjs.map +1 -0
  65. package/dist/_chunks/{layout-BEuNwv-F.js → layout-BW80JSCd.js} +5 -6
  66. package/dist/_chunks/{layout-BEuNwv-F.js.map → layout-BW80JSCd.js.map} +1 -1
  67. package/dist/_chunks/{layout-DhMZ_lDx.mjs → layout-W3clJSCy.mjs} +4 -4
  68. package/dist/_chunks/{layout-DhMZ_lDx.mjs.map → layout-W3clJSCy.mjs.map} +1 -1
  69. package/dist/_chunks/objects-BcXOv6_9.js.map +1 -1
  70. package/dist/_chunks/objects-D6yBsdmx.mjs.map +1 -1
  71. package/dist/_chunks/{relations-BdnxoX6f.mjs → relations-BlDkoeWh.mjs} +2 -2
  72. package/dist/_chunks/{relations-BdnxoX6f.mjs.map → relations-BlDkoeWh.mjs.map} +1 -1
  73. package/dist/_chunks/{relations-kLcuobLk.js → relations-C9Usz9k5.js} +2 -2
  74. package/dist/_chunks/{relations-kLcuobLk.js.map → relations-C9Usz9k5.js.map} +1 -1
  75. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -1
  76. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -1
  77. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  78. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  79. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  80. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  81. package/dist/admin/index.js +2 -1
  82. package/dist/admin/index.js.map +1 -1
  83. package/dist/admin/index.mjs +2 -1
  84. package/dist/admin/src/content-manager.d.ts +3 -2
  85. package/dist/admin/src/exports.d.ts +1 -0
  86. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  87. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  88. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +1 -1
  89. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  90. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  91. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  92. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  93. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  94. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  95. package/dist/admin/src/services/api.d.ts +1 -1
  96. package/dist/admin/src/services/components.d.ts +2 -2
  97. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  98. package/dist/admin/src/services/documents.d.ts +16 -16
  99. package/dist/admin/src/services/init.d.ts +1 -1
  100. package/dist/admin/src/services/relations.d.ts +2 -2
  101. package/dist/admin/src/services/uid.d.ts +3 -3
  102. package/dist/server/index.js +174 -178
  103. package/dist/server/index.js.map +1 -1
  104. package/dist/server/index.mjs +174 -177
  105. package/dist/server/index.mjs.map +1 -1
  106. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  107. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  108. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  109. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  110. package/dist/server/src/history/services/history.d.ts +3 -3
  111. package/dist/server/src/history/services/history.d.ts.map +1 -1
  112. package/dist/server/src/history/services/utils.d.ts +6 -10
  113. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  114. package/dist/server/src/index.d.ts +3 -2
  115. package/dist/server/src/index.d.ts.map +1 -1
  116. package/dist/server/src/preview/index.d.ts.map +1 -1
  117. package/dist/server/src/services/document-metadata.d.ts +4 -2
  118. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  119. package/dist/server/src/services/index.d.ts +3 -2
  120. package/dist/server/src/services/index.d.ts.map +1 -1
  121. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  122. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  123. package/dist/server/src/services/utils/populate.d.ts +2 -2
  124. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  125. package/package.json +11 -9
  126. package/dist/_chunks/Field-Bj_RgtGo.mjs.map +0 -1
  127. package/dist/_chunks/Field-DUK83cfh.js.map +0 -1
  128. package/dist/_chunks/History-CfCSNlG9.mjs.map +0 -1
  129. package/dist/_chunks/History-Di3zm4HT.js.map +0 -1
  130. package/dist/_chunks/Preview-C_B1nx3g.mjs.map +0 -1
  131. package/dist/_chunks/Preview-D_3aO6Ly.js.map +0 -1
  132. package/dist/_chunks/index-BpxR3En4.mjs.map +0 -1
  133. package/dist/_chunks/index-T-aWjbj2.js.map +0 -1
  134. package/dist/admin/src/preview/constants.d.ts +0 -1
  135. package/dist/server/src/preview/constants.d.ts +0 -2
  136. package/dist/server/src/preview/constants.d.ts.map +0 -1
@@ -10,8 +10,7 @@ const qs = require("qs");
10
10
  const slugify = require("@sindresorhus/slugify");
11
11
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
12
  function _interopNamespace(e) {
13
- if (e && e.__esModule)
14
- return e;
13
+ if (e && e.__esModule) return e;
15
14
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
16
15
  if (e) {
17
16
  for (const k in e) {
@@ -167,8 +166,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
167
166
  };
168
167
  const getRelationRestoreValue = async (versionRelationData, attribute) => {
169
168
  if (Array.isArray(versionRelationData)) {
170
- if (versionRelationData.length === 0)
171
- return versionRelationData;
169
+ if (versionRelationData.length === 0) return versionRelationData;
172
170
  const existingAndMissingRelations = await Promise.all(
173
171
  versionRelationData.map((relation) => {
174
172
  return strapi2.documents(attribute.target).findOne({
@@ -177,19 +175,16 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
177
175
  });
178
176
  })
179
177
  );
180
- return existingAndMissingRelations.filter(
181
- (relation) => relation !== null
182
- );
178
+ return existingAndMissingRelations.filter((relation) => relation !== null);
183
179
  }
184
180
  return strapi2.documents(attribute.target).findOne({
185
181
  documentId: versionRelationData.documentId,
186
182
  locale: versionRelationData.locale || void 0
187
183
  });
188
184
  };
189
- const getMediaRestoreValue = async (versionRelationData, attribute) => {
190
- if (attribute.multiple) {
185
+ const getMediaRestoreValue = async (versionRelationData) => {
186
+ if (Array.isArray(versionRelationData)) {
191
187
  const existingAndMissingMedias = await Promise.all(
192
- // @ts-expect-error Fix the type definitions so this isn't any
193
188
  versionRelationData.map((media) => {
194
189
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
195
190
  })
@@ -203,8 +198,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
203
198
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
204
199
  const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
205
200
  const getLocaleDictionary = async () => {
206
- if (!localesService)
207
- return {};
201
+ if (!localesService) return {};
208
202
  const locales = await localesService.find() || [];
209
203
  return locales.reduce(
210
204
  (acc, locale) => {
@@ -359,8 +353,8 @@ const createHistoryService = ({ strapi: strapi2 }) => {
359
353
  });
360
354
  },
361
355
  async findVersionsPage(params) {
362
- const model = strapi2.getModel(params.query.contentType);
363
- const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
356
+ const schema = strapi2.getModel(params.query.contentType);
357
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);
364
358
  const defaultLocale = await serviceUtils.getDefaultLocale();
365
359
  let locale = null;
366
360
  if (isLocalizedContentType) {
@@ -381,32 +375,20 @@ const createHistoryService = ({ strapi: strapi2 }) => {
381
375
  }),
382
376
  serviceUtils.getLocaleDictionary()
383
377
  ]);
384
- const populateEntryRelations = async (entry) => {
385
- const entryWithRelations = await Object.entries(entry.schema).reduce(
386
- async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
387
- const attributeValue = entry.data[attributeKey];
388
- const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
389
- if (attributeSchema.type === "media") {
390
- const permissionChecker2 = getService$2("permission-checker").create({
391
- userAbility: params.state.userAbility,
392
- model: "plugin::upload.file"
393
- });
394
- const response = await serviceUtils.buildMediaResponse(attributeValues);
395
- const sanitizedResults = await Promise.all(
396
- response.results.map((media) => permissionChecker2.sanitizeOutput(media))
397
- );
398
- return {
399
- ...await currentDataWithRelations,
400
- [attributeKey]: {
401
- results: sanitizedResults,
402
- meta: response.meta
403
- }
404
- };
378
+ const populateEntry = async (entry) => {
379
+ return strapiUtils.traverseEntity(
380
+ async (options, utils) => {
381
+ if (!options.attribute) return;
382
+ if (!options.value) return;
383
+ const currentValue = Array.isArray(options.value) ? options.value : [options.value];
384
+ if (options.attribute.type === "component") {
385
+ utils.remove("id");
405
386
  }
406
- if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
407
- if (attributeSchema.target === "admin::user") {
387
+ if (options.attribute.type === "relation" && // TODO: handle polymorphic relations
388
+ options.attribute.relation !== "morphToOne" && options.attribute.relation !== "morphToMany") {
389
+ if (options.attribute.target === "admin::user") {
408
390
  const adminUsers = await Promise.all(
409
- attributeValues.map((userToPopulate) => {
391
+ currentValue.map((userToPopulate) => {
410
392
  if (userToPopulate == null) {
411
393
  return null;
412
394
  }
@@ -418,46 +400,51 @@ const createHistoryService = ({ strapi: strapi2 }) => {
418
400
  });
419
401
  })
420
402
  );
421
- return {
422
- ...await currentDataWithRelations,
423
- /**
424
- * Ideally we would return the same "{results: [], meta: {}}" shape, however,
425
- * when sanitizing the data as a whole in the controller before sending to the client,
426
- * the data for admin relation user is completely sanitized if we return an object here as opposed to an array.
427
- */
428
- [attributeKey]: adminUsers
429
- };
403
+ utils.set(options.key, adminUsers);
430
404
  }
431
405
  const permissionChecker2 = getService$2("permission-checker").create({
432
406
  userAbility: params.state.userAbility,
433
- model: attributeSchema.target
407
+ model: options.attribute.target
434
408
  });
435
409
  const response = await serviceUtils.buildRelationReponse(
436
- attributeValues,
437
- attributeSchema
410
+ currentValue,
411
+ options.attribute
438
412
  );
439
413
  const sanitizedResults = await Promise.all(
440
414
  response.results.map((media) => permissionChecker2.sanitizeOutput(media))
441
415
  );
442
- return {
443
- ...await currentDataWithRelations,
444
- [attributeKey]: {
445
- results: sanitizedResults,
446
- meta: response.meta
447
- }
448
- };
416
+ utils.set(options.key, {
417
+ results: sanitizedResults,
418
+ meta: response.meta
419
+ });
420
+ }
421
+ if (options.attribute.type === "media") {
422
+ const permissionChecker2 = getService$2("permission-checker").create({
423
+ userAbility: params.state.userAbility,
424
+ model: "plugin::upload.file"
425
+ });
426
+ const response = await serviceUtils.buildMediaResponse(currentValue);
427
+ const sanitizedResults = await Promise.all(
428
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
429
+ );
430
+ utils.set(options.key, {
431
+ results: sanitizedResults,
432
+ meta: response.meta
433
+ });
449
434
  }
450
- return currentDataWithRelations;
451
435
  },
452
- Promise.resolve(entry.data)
436
+ {
437
+ schema,
438
+ getModel: strapi2.getModel.bind(strapi2)
439
+ },
440
+ entry.data
453
441
  );
454
- return entryWithRelations;
455
442
  };
456
443
  const formattedResults = await Promise.all(
457
444
  results.map(async (result) => {
458
445
  return {
459
446
  ...result,
460
- data: await populateEntryRelations(result),
447
+ data: await populateEntry(result),
461
448
  meta: {
462
449
  unknownAttributes: serviceUtils.getSchemaAttributesDiff(
463
450
  result.schema,
@@ -488,30 +475,44 @@ const createHistoryService = ({ strapi: strapi2 }) => {
488
475
  // Clone to avoid mutating the original version data
489
476
  structuredClone(version.data)
490
477
  );
491
- const sanitizedSchemaAttributes = fp.omit(
492
- FIELDS_TO_IGNORE,
493
- contentTypeSchemaAttributes
494
- );
495
- const reducer = strapiUtils.async.reduce(Object.entries(sanitizedSchemaAttributes));
496
- const dataWithoutMissingRelations = await reducer(
497
- async (previousRelationAttributes, [name, attribute]) => {
498
- const versionRelationData = version.data[name];
499
- if (!versionRelationData) {
500
- return previousRelationAttributes;
478
+ const schema = structuredClone(version.schema);
479
+ schema.attributes = fp.omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
480
+ const dataWithoutMissingRelations = await strapiUtils.traverseEntity(
481
+ async (options, utils) => {
482
+ if (!options.attribute) return;
483
+ if (options.attribute.type === "component") {
484
+ utils.remove("id");
485
+ if (options.attribute.repeatable && options.value === null) {
486
+ utils.set(options.key, []);
487
+ }
501
488
  }
502
- if (attribute.type === "relation" && // TODO: handle polymorphic relations
503
- attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
504
- const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
505
- previousRelationAttributes[name] = data2;
489
+ if (options.attribute.type === "dynamiczone") {
490
+ if (options.value === null) {
491
+ utils.set(options.key, []);
492
+ }
506
493
  }
507
- if (attribute.type === "media") {
508
- const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
509
- previousRelationAttributes[name] = data2;
494
+ if (options.attribute.type === "relation" && // TODO: handle polymorphic relations
495
+ options.attribute.relation !== "morphToOne" && options.attribute.relation !== "morphToMany") {
496
+ if (!options.value) return;
497
+ const data2 = await serviceUtils.getRelationRestoreValue(
498
+ options.value,
499
+ options.attribute
500
+ );
501
+ utils.set(options.key, data2);
502
+ }
503
+ if (options.attribute.type === "media") {
504
+ if (!options.value) return;
505
+ const data2 = await serviceUtils.getMediaRestoreValue(
506
+ options.value
507
+ );
508
+ utils.set(options.key, data2);
510
509
  }
511
- return previousRelationAttributes;
512
510
  },
513
- // Clone to avoid mutating the original version data
514
- structuredClone(dataWithoutAddedAttributes)
511
+ {
512
+ schema,
513
+ getModel: strapi2.getModel.bind(strapi2)
514
+ },
515
+ dataWithoutAddedAttributes
515
516
  );
516
517
  const data = fp.omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
517
518
  const restoredDocument = await strapi2.documents(version.contentType).update({
@@ -740,7 +741,6 @@ const getFeature$1 = () => {
740
741
  };
741
742
  };
742
743
  const history = getFeature$1();
743
- const FEATURE_ID = "preview";
744
744
  const info = { pluginName: "content-manager", type: "admin" };
745
745
  const previewRouter = {
746
746
  type: "admin",
@@ -918,9 +918,6 @@ const services$1 = {
918
918
  "preview-config": createPreviewConfigService
919
919
  };
920
920
  const getFeature = () => {
921
- if (!strapi.features.future.isEnabled(FEATURE_ID)) {
922
- return {};
923
- }
924
921
  return {
925
922
  register() {
926
923
  const config = getService(strapi, "preview-config");
@@ -1506,8 +1503,7 @@ const isSortable = (schema, name) => {
1506
1503
  if (!___default.default.has(schema.attributes, name)) {
1507
1504
  return false;
1508
1505
  }
1509
- if (schema.modelType === "component" && name === "id")
1510
- return false;
1506
+ if (schema.modelType === "component" && name === "id") return false;
1511
1507
  const attribute = schema.attributes[name];
1512
1508
  if (NON_SORTABLES.includes(attribute.type)) {
1513
1509
  return false;
@@ -1652,8 +1648,7 @@ const createDefaultSettings = async (schema) => {
1652
1648
  };
1653
1649
  };
1654
1650
  const syncSettings = async (configuration, schema) => {
1655
- if (fp.isEmpty(configuration.settings))
1656
- return createDefaultSettings(schema);
1651
+ if (fp.isEmpty(configuration.settings)) return createDefaultSettings(schema);
1657
1652
  const defaultField = getDefaultMainField(schema);
1658
1653
  const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
1659
1654
  return {
@@ -1829,8 +1824,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1829
1824
  }
1830
1825
  switch (attribute.type) {
1831
1826
  case "relation": {
1832
- if (canCreate(attributePath))
1833
- return body2;
1827
+ if (canCreate(attributePath)) return body2;
1834
1828
  return fp.set(attributePath, { set: [] }, body2);
1835
1829
  }
1836
1830
  case "component": {
@@ -1840,8 +1834,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1840
1834
  ]);
1841
1835
  }
1842
1836
  default: {
1843
- if (canCreate(attributePath))
1844
- return body2;
1837
+ if (canCreate(attributePath)) return body2;
1845
1838
  return fp.set(attributePath, null, body2);
1846
1839
  }
1847
1840
  }
@@ -2634,8 +2627,7 @@ const validateStatus = (sourceUid, status) => {
2634
2627
  const sourceModel = strapi.getModel(sourceUid);
2635
2628
  const isDP = strapiUtils.contentTypes.hasDraftAndPublish;
2636
2629
  const isSourceDP = isDP(sourceModel);
2637
- if (!isSourceDP)
2638
- return { status: void 0 };
2630
+ if (!isSourceDP) return { status: void 0 };
2639
2631
  switch (status) {
2640
2632
  case "published":
2641
2633
  return { status: "published" };
@@ -3280,18 +3272,15 @@ async function syncMetadatas(configuration, schema) {
3280
3272
  ___default.default.set(updatedMeta, ["list", "searchable"], false);
3281
3273
  ___default.default.set(acc, [key], updatedMeta);
3282
3274
  }
3283
- if (!___default.default.has(edit, "mainField"))
3284
- return acc;
3275
+ if (!___default.default.has(edit, "mainField")) return acc;
3285
3276
  if (!isRelation$1(attr)) {
3286
3277
  ___default.default.set(updatedMeta, "edit", ___default.default.omit(edit, ["mainField"]));
3287
3278
  ___default.default.set(acc, [key], updatedMeta);
3288
3279
  return acc;
3289
3280
  }
3290
- if (edit.mainField === "id")
3291
- return acc;
3281
+ if (edit.mainField === "id") return acc;
3292
3282
  const targetSchema = getTargetSchema(attr.targetModel);
3293
- if (!targetSchema)
3294
- return acc;
3283
+ if (!targetSchema) return acc;
3295
3284
  if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
3296
3285
  ___default.default.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
3297
3286
  ___default.default.set(acc, [key], updatedMeta);
@@ -3336,8 +3325,7 @@ function createDefaultEditLayout(schema) {
3336
3325
  return appendToEditLayout([], keys2, schema);
3337
3326
  }
3338
3327
  function syncLayouts(configuration, schema) {
3339
- if (___default.default.isEmpty(configuration.layouts))
3340
- return createDefaultLayouts(schema);
3328
+ if (___default.default.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
3341
3329
  const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
3342
3330
  let cleanList = list.filter((attr) => isListable(schema, attr));
3343
3331
  const cleanEditRelations = editRelations.filter(
@@ -3348,8 +3336,7 @@ function syncLayouts(configuration, schema) {
3348
3336
  for (const row of edit) {
3349
3337
  const newRow = [];
3350
3338
  for (const el of row) {
3351
- if (!hasEditableAttribute(schema, el.name))
3352
- continue;
3339
+ if (!hasEditableAttribute(schema, el.name)) continue;
3353
3340
  const { hasFieldSize } = getService$2("field-sizes");
3354
3341
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3355
3342
  if (!isAllowedFieldSize(fieldType, el.size)) {
@@ -3380,8 +3367,7 @@ function syncLayouts(configuration, schema) {
3380
3367
  };
3381
3368
  }
3382
3369
  const appendToEditLayout = (layout = [], keysToAppend, schema) => {
3383
- if (keysToAppend.length === 0)
3384
- return layout;
3370
+ if (keysToAppend.length === 0) return layout;
3385
3371
  let currentRowIndex = Math.max(layout.length - 1, 0);
3386
3372
  if (!layout[currentRowIndex]) {
3387
3373
  layout[currentRowIndex] = [];
@@ -3947,6 +3933,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
3947
3933
  if (initialPopulate) {
3948
3934
  return initialPopulate;
3949
3935
  }
3936
+ if (attributeName === "localizations") {
3937
+ const validationPopulate = getPopulateForValidation(model.uid);
3938
+ return {
3939
+ populate: validationPopulate.populate
3940
+ };
3941
+ }
3950
3942
  if (!isVisibleAttribute$1(model, attributeName)) {
3951
3943
  return true;
3952
3944
  }
@@ -4006,6 +3998,9 @@ const getDeepPopulate = (uid2, {
4006
3998
  return {};
4007
3999
  }
4008
4000
  const model = strapi.getModel(uid2);
4001
+ if (!model) {
4002
+ return {};
4003
+ }
4009
4004
  return Object.keys(model.attributes).reduce(
4010
4005
  (populateAcc, attributeName) => fp.merge(
4011
4006
  populateAcc,
@@ -4025,40 +4020,46 @@ const getDeepPopulate = (uid2, {
4025
4020
  {}
4026
4021
  );
4027
4022
  };
4028
- const getValidatableFieldsPopulate = (uid2, {
4029
- initialPopulate = {},
4030
- countMany = false,
4031
- countOne = false,
4032
- maxLevel = Infinity
4033
- } = {}, level = 1) => {
4034
- if (level > maxLevel) {
4023
+ const getPopulateForValidation = (uid2) => {
4024
+ const model = strapi.getModel(uid2);
4025
+ if (!model) {
4035
4026
  return {};
4036
4027
  }
4037
- const model = strapi.getModel(uid2);
4038
4028
  return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
4039
- if (!getDoesAttributeRequireValidation(attribute)) {
4029
+ if (isScalarAttribute(attribute)) {
4030
+ if (getDoesAttributeRequireValidation(attribute)) {
4031
+ populateAcc.fields = populateAcc.fields || [];
4032
+ populateAcc.fields.push(attributeName);
4033
+ }
4040
4034
  return populateAcc;
4041
4035
  }
4042
- if (isScalarAttribute(attribute)) {
4043
- return fp.merge(populateAcc, {
4044
- [attributeName]: true
4045
- });
4036
+ if (isComponent(attribute)) {
4037
+ const component = attribute.component;
4038
+ const componentResult = getPopulateForValidation(component);
4039
+ if (Object.keys(componentResult).length > 0) {
4040
+ populateAcc.populate = populateAcc.populate || {};
4041
+ populateAcc.populate[attributeName] = componentResult;
4042
+ }
4043
+ return populateAcc;
4046
4044
  }
4047
- return fp.merge(
4048
- populateAcc,
4049
- getPopulateFor(
4050
- attributeName,
4051
- model,
4052
- {
4053
- // @ts-expect-error - improve types
4054
- initialPopulate: initialPopulate?.[attributeName],
4055
- countMany,
4056
- countOne,
4057
- maxLevel
4045
+ if (isDynamicZone(attribute)) {
4046
+ const components2 = attribute.components;
4047
+ const componentsResult = (components2 || []).reduce(
4048
+ (acc, componentUID) => {
4049
+ const componentResult = getPopulateForValidation(componentUID);
4050
+ if (Object.keys(componentResult).length > 0) {
4051
+ acc[componentUID] = componentResult;
4052
+ }
4053
+ return acc;
4058
4054
  },
4059
- level
4060
- )
4061
- );
4055
+ {}
4056
+ );
4057
+ if (Object.keys(componentsResult).length > 0) {
4058
+ populateAcc.populate = populateAcc.populate || {};
4059
+ populateAcc.populate[attributeName] = { on: componentsResult };
4060
+ }
4061
+ }
4062
+ return populateAcc;
4062
4063
  }, {});
4063
4064
  };
4064
4065
  const getDeepPopulateDraftCount = (uid2) => {
@@ -4300,7 +4301,6 @@ const AVAILABLE_LOCALES_FIELDS = [
4300
4301
  "locale",
4301
4302
  "updatedAt",
4302
4303
  "createdAt",
4303
- "status",
4304
4304
  "publishedAt",
4305
4305
  "documentId"
4306
4306
  ];
@@ -4321,36 +4321,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4321
4321
  /**
4322
4322
  * Returns available locales of a document for the current status
4323
4323
  */
4324
- async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4324
+ async getAvailableLocales(uid2, version, allVersions) {
4325
4325
  const versionsByLocale = fp.groupBy("locale", allVersions);
4326
4326
  if (version.locale) {
4327
4327
  delete versionsByLocale[version.locale];
4328
4328
  }
4329
4329
  const model = strapi2.getModel(uid2);
4330
- const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4331
- const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
4332
- ({ key }, { remove }) => {
4333
- if (keysToKeep.includes(key)) {
4334
- return;
4335
- }
4336
- remove(key);
4337
- },
4338
- { schema: model, getModel: strapi2.getModel.bind(strapi2) },
4339
- // @ts-expect-error fix types DocumentVersion incompatible with Data
4340
- localeVersion
4341
- );
4342
4330
  const mappingResult = await strapiUtils.async.map(
4343
4331
  Object.values(versionsByLocale),
4344
4332
  async (localeVersions) => {
4345
- const mappedLocaleVersions = await strapiUtils.async.map(
4346
- localeVersions,
4347
- traversalFunction
4348
- );
4349
4333
  if (!strapiUtils.contentTypes.hasDraftAndPublish(model)) {
4350
- return mappedLocaleVersions[0];
4334
+ return localeVersions[0];
4351
4335
  }
4352
- const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
4353
- const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
4336
+ const draftVersion = localeVersions.find((v) => v.publishedAt === null);
4337
+ const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);
4354
4338
  if (!draftVersion) {
4355
4339
  return;
4356
4340
  }
@@ -4372,8 +4356,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4372
4356
  const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
4373
4357
  return matchLocale && matchStatus;
4374
4358
  });
4375
- if (!availableStatus)
4376
- return availableStatus;
4359
+ if (!availableStatus) return availableStatus;
4377
4360
  return fp.pick(AVAILABLE_STATUS_FIELDS, availableStatus);
4378
4361
  },
4379
4362
  /**
@@ -4383,18 +4366,19 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4383
4366
  * @returns
4384
4367
  */
4385
4368
  async getManyAvailableStatus(uid2, documents) {
4386
- if (!documents.length)
4387
- return [];
4369
+ if (!documents.length) return [];
4388
4370
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4389
- const locale = documents[0]?.locale;
4390
- const otherStatus = status === "published" ? "draft" : "published";
4391
- return strapi2.documents(uid2).findMany({
4392
- filters: {
4393
- documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) }
4394
- },
4395
- status: otherStatus,
4396
- locale,
4397
- fields: ["documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4371
+ const locales = documents.map((d) => d.locale).filter(Boolean);
4372
+ const where = {
4373
+ documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },
4374
+ publishedAt: { $null: status === "published" }
4375
+ };
4376
+ if (locales.length) {
4377
+ where.locale = { $in: locales };
4378
+ }
4379
+ return strapi2.query(uid2).findMany({
4380
+ where,
4381
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4398
4382
  });
4399
4383
  },
4400
4384
  getStatus(version, otherDocumentStatuses) {
@@ -4411,10 +4395,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4411
4395
  } else if (otherVersion) {
4412
4396
  draftVersion = otherVersion;
4413
4397
  }
4414
- if (!draftVersion)
4415
- return CONTENT_MANAGER_STATUS.PUBLISHED;
4416
- if (!publishedVersion)
4417
- return CONTENT_MANAGER_STATUS.DRAFT;
4398
+ if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
4399
+ if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
4418
4400
  const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
4419
4401
  return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
4420
4402
  },
@@ -4422,11 +4404,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4422
4404
  // We could refactor this so the locales are only loaded when they're
4423
4405
  // needed. e.g. in the bulk locale action modal.
4424
4406
  async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
4425
- const populate = getValidatableFieldsPopulate(uid2);
4426
- const versions = await strapi2.db.query(uid2).findMany({
4427
- where: { documentId: version.documentId },
4407
+ const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
4408
+ const params = {
4428
4409
  populate: {
4429
- // Populate only fields that require validation for bulk locale actions
4430
4410
  ...populate,
4431
4411
  // NOTE: creator fields are selected in this way to avoid exposing sensitive data
4432
4412
  createdBy: {
@@ -4435,9 +4415,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4435
4415
  updatedBy: {
4436
4416
  select: ["id", "firstname", "lastname", "email"]
4437
4417
  }
4418
+ },
4419
+ fields: fp.uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
4420
+ filters: {
4421
+ documentId: version.documentId
4438
4422
  }
4439
- });
4440
- const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
4423
+ };
4424
+ const dbParams = strapi2.get("query-params").transform(uid2, params);
4425
+ const versions = await strapi2.db.query(uid2).findMany(dbParams);
4426
+ const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions) : [];
4441
4427
  const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
4442
4428
  return {
4443
4429
  availableLocales: availableLocalesResult,
@@ -4464,6 +4450,16 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4464
4450
  opts.availableStatus = false;
4465
4451
  }
4466
4452
  const meta = await this.getMetadata(uid2, document, opts);
4453
+ if (document.localizations) {
4454
+ const otherStatus = await this.getManyAvailableStatus(uid2, document.localizations);
4455
+ document.localizations = document.localizations.map((d) => {
4456
+ const status = otherStatus.find((s) => s.documentId === d.documentId);
4457
+ return {
4458
+ ...d,
4459
+ status: this.getStatus(d, status ? [status] : [])
4460
+ };
4461
+ });
4462
+ }
4467
4463
  return {
4468
4464
  data: {
4469
4465
  ...document,