@strapi/content-manager 0.0.0-next.d65d44102fd32871728c0d74ec4f2519b7cc0a16 → 0.0.0-next.dad3c50630ca4fd9eccdcbe549ee632fc572e23d

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-UduDBv3m.js → ComponentConfigurationPage-BLWQy8ru.js} +4 -5
  4. package/dist/_chunks/{ComponentConfigurationPage-UduDBv3m.js.map → ComponentConfigurationPage-BLWQy8ru.js.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-DhWA-JzT.mjs → ComponentConfigurationPage-CtIa3aa2.mjs} +3 -3
  6. package/dist/_chunks/{ComponentConfigurationPage-DhWA-JzT.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-5tmx_7Hp.mjs → EditConfigurationPage-DsPR2DVk.mjs} +3 -3
  11. package/dist/_chunks/{EditConfigurationPage-5tmx_7Hp.mjs.map → EditConfigurationPage-DsPR2DVk.mjs.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-Cp9UzUfs.js → EditConfigurationPage-RQkymxCy.js} +4 -5
  13. package/dist/_chunks/{EditConfigurationPage-Cp9UzUfs.js.map → EditConfigurationPage-RQkymxCy.js.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-C7l2Emuj.js → EditViewPage-B-kExt8C.js} +4 -5
  15. package/dist/_chunks/{EditViewPage-C7l2Emuj.js.map → EditViewPage-B-kExt8C.js.map} +1 -1
  16. package/dist/_chunks/{EditViewPage-BKoISUOu.mjs → EditViewPage-BPyVuPfM.mjs} +3 -3
  17. package/dist/_chunks/{EditViewPage-BKoISUOu.mjs.map → EditViewPage-BPyVuPfM.mjs.map} +1 -1
  18. package/dist/_chunks/{Field-BPSJpDfE.js → Field-DPIsQRre.js} +139 -103
  19. package/dist/_chunks/Field-DPIsQRre.js.map +1 -0
  20. package/dist/_chunks/{Field-BZxzYf1x.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-DLkqDd2G.js → Form-BFi4MXMT.js} +5 -6
  25. package/dist/_chunks/{Form-DLkqDd2G.js.map → Form-BFi4MXMT.js.map} +1 -1
  26. package/dist/_chunks/{Form-8qyOU6YG.mjs → Form-C1IcWm1u.mjs} +3 -3
  27. package/dist/_chunks/{Form-8qyOU6YG.mjs.map → Form-C1IcWm1u.mjs.map} +1 -1
  28. package/dist/_chunks/{History-N_kRb1Yr.mjs → History-04ChQ4pl.mjs} +32 -8
  29. package/dist/_chunks/History-04ChQ4pl.mjs.map +1 -0
  30. package/dist/_chunks/{History-DYMicybF.js → History-wjcK4L0C.js} +33 -10
  31. package/dist/_chunks/History-wjcK4L0C.js.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-BM3qVxug.mjs → ListConfigurationPage-BYqPYLSU.mjs} +3 -3
  33. package/dist/_chunks/{ListConfigurationPage-BM3qVxug.mjs.map → ListConfigurationPage-BYqPYLSU.mjs.map} +1 -1
  34. package/dist/_chunks/{ListConfigurationPage-rUF9iGWq.js → ListConfigurationPage-CRbxIC3J.js} +4 -5
  35. package/dist/_chunks/{ListConfigurationPage-rUF9iGWq.js.map → ListConfigurationPage-CRbxIC3J.js.map} +1 -1
  36. package/dist/_chunks/{ListViewPage-BSLzd7cZ.js → ListViewPage-D5NY9183.js} +4 -5
  37. package/dist/_chunks/{ListViewPage-BSLzd7cZ.js.map → ListViewPage-D5NY9183.js.map} +1 -1
  38. package/dist/_chunks/{ListViewPage-CWilGbZb.mjs → ListViewPage-FU2LBuhl.mjs} +3 -3
  39. package/dist/_chunks/{ListViewPage-CWilGbZb.mjs.map → ListViewPage-FU2LBuhl.mjs.map} +1 -1
  40. package/dist/_chunks/{NoContentTypePage-CQccVhIX.js → NoContentTypePage-BgQVE_Qb.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-CQccVhIX.js.map → NoContentTypePage-BgQVE_Qb.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-VWYlePwI.mjs → NoContentTypePage-DCKUkwb8.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-VWYlePwI.mjs.map → NoContentTypePage-DCKUkwb8.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-Af32Gg2m.js → NoPermissionsPage-C5jwn70o.js} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-Af32Gg2m.js.map → NoPermissionsPage-C5jwn70o.js.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-CS2tCmfr.mjs → NoPermissionsPage-jqve7C8l.mjs} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-CS2tCmfr.mjs.map → NoPermissionsPage-jqve7C8l.mjs.map} +1 -1
  48. package/dist/_chunks/{Preview-kPkuZbBJ.mjs → Preview-BMYN548c.mjs} +33 -11
  49. package/dist/_chunks/Preview-BMYN548c.mjs.map +1 -0
  50. package/dist/_chunks/{Preview-D4KzuJFL.js → Preview-DaOihysv.js} +33 -12
  51. package/dist/_chunks/Preview-DaOihysv.js.map +1 -0
  52. package/dist/_chunks/{Relations-D_Ki5aVM.js → Relations-CTGM7Hv5.js} +7 -10
  53. package/dist/_chunks/{Relations-D_Ki5aVM.js.map → Relations-CTGM7Hv5.js.map} +1 -1
  54. package/dist/_chunks/{Relations-5k27Rh54.mjs → Relations-gscPkxjF.mjs} +6 -8
  55. package/dist/_chunks/{Relations-5k27Rh54.mjs.map → Relations-gscPkxjF.mjs.map} +1 -1
  56. package/dist/_chunks/{en-BK8Xyl5I.js → en-BzQmavmK.js} +7 -2
  57. package/dist/_chunks/{en-BK8Xyl5I.js.map → en-BzQmavmK.js.map} +1 -1
  58. package/dist/_chunks/{en-Dtk_ot79.mjs → en-CSxLmrh1.mjs} +7 -2
  59. package/dist/_chunks/{en-Dtk_ot79.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
  60. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  61. package/dist/_chunks/{index-DwOsF7wF.js → index-Ca7YWlAA.js} +207 -128
  62. package/dist/_chunks/index-Ca7YWlAA.js.map +1 -0
  63. package/dist/_chunks/{index-BLPa8Dq-.mjs → index-DqasUQ6Q.mjs} +206 -126
  64. package/dist/_chunks/index-DqasUQ6Q.mjs.map +1 -0
  65. package/dist/_chunks/{layout-CN2bFL9V.js → layout-BW80JSCd.js} +5 -6
  66. package/dist/_chunks/{layout-CN2bFL9V.js.map → layout-BW80JSCd.js.map} +1 -1
  67. package/dist/_chunks/{layout-2Si0j0jO.mjs → layout-W3clJSCy.mjs} +4 -4
  68. package/dist/_chunks/{layout-2Si0j0jO.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-CAxDjUJF.mjs → relations-BlDkoeWh.mjs} +2 -2
  72. package/dist/_chunks/{relations-CAxDjUJF.mjs.map → relations-BlDkoeWh.mjs.map} +1 -1
  73. package/dist/_chunks/{relations-B0E0XUY7.js → relations-C9Usz9k5.js} +2 -2
  74. package/dist/_chunks/{relations-B0E0XUY7.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 +9 -7
  126. package/dist/_chunks/Field-BPSJpDfE.js.map +0 -1
  127. package/dist/_chunks/Field-BZxzYf1x.mjs.map +0 -1
  128. package/dist/_chunks/History-DYMicybF.js.map +0 -1
  129. package/dist/_chunks/History-N_kRb1Yr.mjs.map +0 -1
  130. package/dist/_chunks/Preview-D4KzuJFL.js.map +0 -1
  131. package/dist/_chunks/Preview-kPkuZbBJ.mjs.map +0 -1
  132. package/dist/_chunks/index-BLPa8Dq-.mjs.map +0 -1
  133. package/dist/_chunks/index-DwOsF7wF.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
@@ -1,4 +1,4 @@
1
- import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
1
+ import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, traverseEntity, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, pagination } from "@strapi/utils";
2
2
  import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
3
3
  import "@strapi/types";
4
4
  import * as yup from "yup";
@@ -141,8 +141,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
141
141
  };
142
142
  const getRelationRestoreValue = async (versionRelationData, attribute) => {
143
143
  if (Array.isArray(versionRelationData)) {
144
- if (versionRelationData.length === 0)
145
- return versionRelationData;
144
+ if (versionRelationData.length === 0) return versionRelationData;
146
145
  const existingAndMissingRelations = await Promise.all(
147
146
  versionRelationData.map((relation) => {
148
147
  return strapi2.documents(attribute.target).findOne({
@@ -151,19 +150,16 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
151
150
  });
152
151
  })
153
152
  );
154
- return existingAndMissingRelations.filter(
155
- (relation) => relation !== null
156
- );
153
+ return existingAndMissingRelations.filter((relation) => relation !== null);
157
154
  }
158
155
  return strapi2.documents(attribute.target).findOne({
159
156
  documentId: versionRelationData.documentId,
160
157
  locale: versionRelationData.locale || void 0
161
158
  });
162
159
  };
163
- const getMediaRestoreValue = async (versionRelationData, attribute) => {
164
- if (attribute.multiple) {
160
+ const getMediaRestoreValue = async (versionRelationData) => {
161
+ if (Array.isArray(versionRelationData)) {
165
162
  const existingAndMissingMedias = await Promise.all(
166
- // @ts-expect-error Fix the type definitions so this isn't any
167
163
  versionRelationData.map((media) => {
168
164
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
169
165
  })
@@ -177,8 +173,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
177
173
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
178
174
  const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
179
175
  const getLocaleDictionary = async () => {
180
- if (!localesService)
181
- return {};
176
+ if (!localesService) return {};
182
177
  const locales = await localesService.find() || [];
183
178
  return locales.reduce(
184
179
  (acc, locale) => {
@@ -333,8 +328,8 @@ const createHistoryService = ({ strapi: strapi2 }) => {
333
328
  });
334
329
  },
335
330
  async findVersionsPage(params) {
336
- const model = strapi2.getModel(params.query.contentType);
337
- const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
331
+ const schema = strapi2.getModel(params.query.contentType);
332
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);
338
333
  const defaultLocale = await serviceUtils.getDefaultLocale();
339
334
  let locale = null;
340
335
  if (isLocalizedContentType) {
@@ -355,32 +350,20 @@ const createHistoryService = ({ strapi: strapi2 }) => {
355
350
  }),
356
351
  serviceUtils.getLocaleDictionary()
357
352
  ]);
358
- const populateEntryRelations = async (entry) => {
359
- const entryWithRelations = await Object.entries(entry.schema).reduce(
360
- async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
361
- const attributeValue = entry.data[attributeKey];
362
- const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
363
- if (attributeSchema.type === "media") {
364
- const permissionChecker2 = getService$2("permission-checker").create({
365
- userAbility: params.state.userAbility,
366
- model: "plugin::upload.file"
367
- });
368
- const response = await serviceUtils.buildMediaResponse(attributeValues);
369
- const sanitizedResults = await Promise.all(
370
- response.results.map((media) => permissionChecker2.sanitizeOutput(media))
371
- );
372
- return {
373
- ...await currentDataWithRelations,
374
- [attributeKey]: {
375
- results: sanitizedResults,
376
- meta: response.meta
377
- }
378
- };
353
+ const populateEntry = async (entry) => {
354
+ return traverseEntity(
355
+ async (options, utils) => {
356
+ if (!options.attribute) return;
357
+ if (!options.value) return;
358
+ const currentValue = Array.isArray(options.value) ? options.value : [options.value];
359
+ if (options.attribute.type === "component") {
360
+ utils.remove("id");
379
361
  }
380
- if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
381
- if (attributeSchema.target === "admin::user") {
362
+ if (options.attribute.type === "relation" && // TODO: handle polymorphic relations
363
+ options.attribute.relation !== "morphToOne" && options.attribute.relation !== "morphToMany") {
364
+ if (options.attribute.target === "admin::user") {
382
365
  const adminUsers = await Promise.all(
383
- attributeValues.map((userToPopulate) => {
366
+ currentValue.map((userToPopulate) => {
384
367
  if (userToPopulate == null) {
385
368
  return null;
386
369
  }
@@ -392,46 +375,51 @@ const createHistoryService = ({ strapi: strapi2 }) => {
392
375
  });
393
376
  })
394
377
  );
395
- return {
396
- ...await currentDataWithRelations,
397
- /**
398
- * Ideally we would return the same "{results: [], meta: {}}" shape, however,
399
- * when sanitizing the data as a whole in the controller before sending to the client,
400
- * the data for admin relation user is completely sanitized if we return an object here as opposed to an array.
401
- */
402
- [attributeKey]: adminUsers
403
- };
378
+ utils.set(options.key, adminUsers);
404
379
  }
405
380
  const permissionChecker2 = getService$2("permission-checker").create({
406
381
  userAbility: params.state.userAbility,
407
- model: attributeSchema.target
382
+ model: options.attribute.target
408
383
  });
409
384
  const response = await serviceUtils.buildRelationReponse(
410
- attributeValues,
411
- attributeSchema
385
+ currentValue,
386
+ options.attribute
412
387
  );
413
388
  const sanitizedResults = await Promise.all(
414
389
  response.results.map((media) => permissionChecker2.sanitizeOutput(media))
415
390
  );
416
- return {
417
- ...await currentDataWithRelations,
418
- [attributeKey]: {
419
- results: sanitizedResults,
420
- meta: response.meta
421
- }
422
- };
391
+ utils.set(options.key, {
392
+ results: sanitizedResults,
393
+ meta: response.meta
394
+ });
395
+ }
396
+ if (options.attribute.type === "media") {
397
+ const permissionChecker2 = getService$2("permission-checker").create({
398
+ userAbility: params.state.userAbility,
399
+ model: "plugin::upload.file"
400
+ });
401
+ const response = await serviceUtils.buildMediaResponse(currentValue);
402
+ const sanitizedResults = await Promise.all(
403
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
404
+ );
405
+ utils.set(options.key, {
406
+ results: sanitizedResults,
407
+ meta: response.meta
408
+ });
423
409
  }
424
- return currentDataWithRelations;
425
410
  },
426
- Promise.resolve(entry.data)
411
+ {
412
+ schema,
413
+ getModel: strapi2.getModel.bind(strapi2)
414
+ },
415
+ entry.data
427
416
  );
428
- return entryWithRelations;
429
417
  };
430
418
  const formattedResults = await Promise.all(
431
419
  results.map(async (result) => {
432
420
  return {
433
421
  ...result,
434
- data: await populateEntryRelations(result),
422
+ data: await populateEntry(result),
435
423
  meta: {
436
424
  unknownAttributes: serviceUtils.getSchemaAttributesDiff(
437
425
  result.schema,
@@ -462,30 +450,44 @@ const createHistoryService = ({ strapi: strapi2 }) => {
462
450
  // Clone to avoid mutating the original version data
463
451
  structuredClone(version.data)
464
452
  );
465
- const sanitizedSchemaAttributes = omit(
466
- FIELDS_TO_IGNORE,
467
- contentTypeSchemaAttributes
468
- );
469
- const reducer = async.reduce(Object.entries(sanitizedSchemaAttributes));
470
- const dataWithoutMissingRelations = await reducer(
471
- async (previousRelationAttributes, [name, attribute]) => {
472
- const versionRelationData = version.data[name];
473
- if (!versionRelationData) {
474
- return previousRelationAttributes;
453
+ const schema = structuredClone(version.schema);
454
+ schema.attributes = omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
455
+ const dataWithoutMissingRelations = await traverseEntity(
456
+ async (options, utils) => {
457
+ if (!options.attribute) return;
458
+ if (options.attribute.type === "component") {
459
+ utils.remove("id");
460
+ if (options.attribute.repeatable && options.value === null) {
461
+ utils.set(options.key, []);
462
+ }
475
463
  }
476
- if (attribute.type === "relation" && // TODO: handle polymorphic relations
477
- attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
478
- const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
479
- previousRelationAttributes[name] = data2;
464
+ if (options.attribute.type === "dynamiczone") {
465
+ if (options.value === null) {
466
+ utils.set(options.key, []);
467
+ }
480
468
  }
481
- if (attribute.type === "media") {
482
- const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
483
- previousRelationAttributes[name] = data2;
469
+ if (options.attribute.type === "relation" && // TODO: handle polymorphic relations
470
+ options.attribute.relation !== "morphToOne" && options.attribute.relation !== "morphToMany") {
471
+ if (!options.value) return;
472
+ const data2 = await serviceUtils.getRelationRestoreValue(
473
+ options.value,
474
+ options.attribute
475
+ );
476
+ utils.set(options.key, data2);
477
+ }
478
+ if (options.attribute.type === "media") {
479
+ if (!options.value) return;
480
+ const data2 = await serviceUtils.getMediaRestoreValue(
481
+ options.value
482
+ );
483
+ utils.set(options.key, data2);
484
484
  }
485
- return previousRelationAttributes;
486
485
  },
487
- // Clone to avoid mutating the original version data
488
- structuredClone(dataWithoutAddedAttributes)
486
+ {
487
+ schema,
488
+ getModel: strapi2.getModel.bind(strapi2)
489
+ },
490
+ dataWithoutAddedAttributes
489
491
  );
490
492
  const data = omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
491
493
  const restoredDocument = await strapi2.documents(version.contentType).update({
@@ -714,7 +716,6 @@ const getFeature$1 = () => {
714
716
  };
715
717
  };
716
718
  const history = getFeature$1();
717
- const FEATURE_ID = "preview";
718
719
  const info = { pluginName: "content-manager", type: "admin" };
719
720
  const previewRouter = {
720
721
  type: "admin",
@@ -892,9 +893,6 @@ const services$1 = {
892
893
  "preview-config": createPreviewConfigService
893
894
  };
894
895
  const getFeature = () => {
895
- if (!strapi.features.future.isEnabled(FEATURE_ID)) {
896
- return {};
897
- }
898
896
  return {
899
897
  register() {
900
898
  const config = getService(strapi, "preview-config");
@@ -1480,8 +1478,7 @@ const isSortable = (schema, name) => {
1480
1478
  if (!_.has(schema.attributes, name)) {
1481
1479
  return false;
1482
1480
  }
1483
- if (schema.modelType === "component" && name === "id")
1484
- return false;
1481
+ if (schema.modelType === "component" && name === "id") return false;
1485
1482
  const attribute = schema.attributes[name];
1486
1483
  if (NON_SORTABLES.includes(attribute.type)) {
1487
1484
  return false;
@@ -1626,8 +1623,7 @@ const createDefaultSettings = async (schema) => {
1626
1623
  };
1627
1624
  };
1628
1625
  const syncSettings = async (configuration, schema) => {
1629
- if (isEmpty(configuration.settings))
1630
- return createDefaultSettings(schema);
1626
+ if (isEmpty(configuration.settings)) return createDefaultSettings(schema);
1631
1627
  const defaultField = getDefaultMainField(schema);
1632
1628
  const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
1633
1629
  return {
@@ -1803,8 +1799,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1803
1799
  }
1804
1800
  switch (attribute.type) {
1805
1801
  case "relation": {
1806
- if (canCreate(attributePath))
1807
- return body2;
1802
+ if (canCreate(attributePath)) return body2;
1808
1803
  return set(attributePath, { set: [] }, body2);
1809
1804
  }
1810
1805
  case "component": {
@@ -1814,8 +1809,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1814
1809
  ]);
1815
1810
  }
1816
1811
  default: {
1817
- if (canCreate(attributePath))
1818
- return body2;
1812
+ if (canCreate(attributePath)) return body2;
1819
1813
  return set(attributePath, null, body2);
1820
1814
  }
1821
1815
  }
@@ -2608,8 +2602,7 @@ const validateStatus = (sourceUid, status) => {
2608
2602
  const sourceModel = strapi.getModel(sourceUid);
2609
2603
  const isDP = contentTypes$1.hasDraftAndPublish;
2610
2604
  const isSourceDP = isDP(sourceModel);
2611
- if (!isSourceDP)
2612
- return { status: void 0 };
2605
+ if (!isSourceDP) return { status: void 0 };
2613
2606
  switch (status) {
2614
2607
  case "published":
2615
2608
  return { status: "published" };
@@ -3254,18 +3247,15 @@ async function syncMetadatas(configuration, schema) {
3254
3247
  _.set(updatedMeta, ["list", "searchable"], false);
3255
3248
  _.set(acc, [key], updatedMeta);
3256
3249
  }
3257
- if (!_.has(edit, "mainField"))
3258
- return acc;
3250
+ if (!_.has(edit, "mainField")) return acc;
3259
3251
  if (!isRelation$1(attr)) {
3260
3252
  _.set(updatedMeta, "edit", _.omit(edit, ["mainField"]));
3261
3253
  _.set(acc, [key], updatedMeta);
3262
3254
  return acc;
3263
3255
  }
3264
- if (edit.mainField === "id")
3265
- return acc;
3256
+ if (edit.mainField === "id") return acc;
3266
3257
  const targetSchema = getTargetSchema(attr.targetModel);
3267
- if (!targetSchema)
3268
- return acc;
3258
+ if (!targetSchema) return acc;
3269
3259
  if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
3270
3260
  _.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
3271
3261
  _.set(acc, [key], updatedMeta);
@@ -3310,8 +3300,7 @@ function createDefaultEditLayout(schema) {
3310
3300
  return appendToEditLayout([], keys2, schema);
3311
3301
  }
3312
3302
  function syncLayouts(configuration, schema) {
3313
- if (_.isEmpty(configuration.layouts))
3314
- return createDefaultLayouts(schema);
3303
+ if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
3315
3304
  const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
3316
3305
  let cleanList = list.filter((attr) => isListable(schema, attr));
3317
3306
  const cleanEditRelations = editRelations.filter(
@@ -3322,8 +3311,7 @@ function syncLayouts(configuration, schema) {
3322
3311
  for (const row of edit) {
3323
3312
  const newRow = [];
3324
3313
  for (const el of row) {
3325
- if (!hasEditableAttribute(schema, el.name))
3326
- continue;
3314
+ if (!hasEditableAttribute(schema, el.name)) continue;
3327
3315
  const { hasFieldSize } = getService$2("field-sizes");
3328
3316
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3329
3317
  if (!isAllowedFieldSize(fieldType, el.size)) {
@@ -3354,8 +3342,7 @@ function syncLayouts(configuration, schema) {
3354
3342
  };
3355
3343
  }
3356
3344
  const appendToEditLayout = (layout = [], keysToAppend, schema) => {
3357
- if (keysToAppend.length === 0)
3358
- return layout;
3345
+ if (keysToAppend.length === 0) return layout;
3359
3346
  let currentRowIndex = Math.max(layout.length - 1, 0);
3360
3347
  if (!layout[currentRowIndex]) {
3361
3348
  layout[currentRowIndex] = [];
@@ -3921,6 +3908,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
3921
3908
  if (initialPopulate) {
3922
3909
  return initialPopulate;
3923
3910
  }
3911
+ if (attributeName === "localizations") {
3912
+ const validationPopulate = getPopulateForValidation(model.uid);
3913
+ return {
3914
+ populate: validationPopulate.populate
3915
+ };
3916
+ }
3924
3917
  if (!isVisibleAttribute$1(model, attributeName)) {
3925
3918
  return true;
3926
3919
  }
@@ -3980,6 +3973,9 @@ const getDeepPopulate = (uid2, {
3980
3973
  return {};
3981
3974
  }
3982
3975
  const model = strapi.getModel(uid2);
3976
+ if (!model) {
3977
+ return {};
3978
+ }
3983
3979
  return Object.keys(model.attributes).reduce(
3984
3980
  (populateAcc, attributeName) => merge(
3985
3981
  populateAcc,
@@ -3999,40 +3995,46 @@ const getDeepPopulate = (uid2, {
3999
3995
  {}
4000
3996
  );
4001
3997
  };
4002
- const getValidatableFieldsPopulate = (uid2, {
4003
- initialPopulate = {},
4004
- countMany = false,
4005
- countOne = false,
4006
- maxLevel = Infinity
4007
- } = {}, level = 1) => {
4008
- if (level > maxLevel) {
3998
+ const getPopulateForValidation = (uid2) => {
3999
+ const model = strapi.getModel(uid2);
4000
+ if (!model) {
4009
4001
  return {};
4010
4002
  }
4011
- const model = strapi.getModel(uid2);
4012
4003
  return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
4013
- if (!getDoesAttributeRequireValidation(attribute)) {
4004
+ if (isScalarAttribute(attribute)) {
4005
+ if (getDoesAttributeRequireValidation(attribute)) {
4006
+ populateAcc.fields = populateAcc.fields || [];
4007
+ populateAcc.fields.push(attributeName);
4008
+ }
4014
4009
  return populateAcc;
4015
4010
  }
4016
- if (isScalarAttribute(attribute)) {
4017
- return merge(populateAcc, {
4018
- [attributeName]: true
4019
- });
4011
+ if (isComponent(attribute)) {
4012
+ const component = attribute.component;
4013
+ const componentResult = getPopulateForValidation(component);
4014
+ if (Object.keys(componentResult).length > 0) {
4015
+ populateAcc.populate = populateAcc.populate || {};
4016
+ populateAcc.populate[attributeName] = componentResult;
4017
+ }
4018
+ return populateAcc;
4020
4019
  }
4021
- return merge(
4022
- populateAcc,
4023
- getPopulateFor(
4024
- attributeName,
4025
- model,
4026
- {
4027
- // @ts-expect-error - improve types
4028
- initialPopulate: initialPopulate?.[attributeName],
4029
- countMany,
4030
- countOne,
4031
- maxLevel
4020
+ if (isDynamicZone(attribute)) {
4021
+ const components2 = attribute.components;
4022
+ const componentsResult = (components2 || []).reduce(
4023
+ (acc, componentUID) => {
4024
+ const componentResult = getPopulateForValidation(componentUID);
4025
+ if (Object.keys(componentResult).length > 0) {
4026
+ acc[componentUID] = componentResult;
4027
+ }
4028
+ return acc;
4032
4029
  },
4033
- level
4034
- )
4035
- );
4030
+ {}
4031
+ );
4032
+ if (Object.keys(componentsResult).length > 0) {
4033
+ populateAcc.populate = populateAcc.populate || {};
4034
+ populateAcc.populate[attributeName] = { on: componentsResult };
4035
+ }
4036
+ }
4037
+ return populateAcc;
4036
4038
  }, {});
4037
4039
  };
4038
4040
  const getDeepPopulateDraftCount = (uid2) => {
@@ -4274,7 +4276,6 @@ const AVAILABLE_LOCALES_FIELDS = [
4274
4276
  "locale",
4275
4277
  "updatedAt",
4276
4278
  "createdAt",
4277
- "status",
4278
4279
  "publishedAt",
4279
4280
  "documentId"
4280
4281
  ];
@@ -4295,36 +4296,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4295
4296
  /**
4296
4297
  * Returns available locales of a document for the current status
4297
4298
  */
4298
- async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4299
+ async getAvailableLocales(uid2, version, allVersions) {
4299
4300
  const versionsByLocale = groupBy("locale", allVersions);
4300
4301
  if (version.locale) {
4301
4302
  delete versionsByLocale[version.locale];
4302
4303
  }
4303
4304
  const model = strapi2.getModel(uid2);
4304
- const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4305
- const traversalFunction = async (localeVersion) => traverseEntity(
4306
- ({ key }, { remove }) => {
4307
- if (keysToKeep.includes(key)) {
4308
- return;
4309
- }
4310
- remove(key);
4311
- },
4312
- { schema: model, getModel: strapi2.getModel.bind(strapi2) },
4313
- // @ts-expect-error fix types DocumentVersion incompatible with Data
4314
- localeVersion
4315
- );
4316
4305
  const mappingResult = await async.map(
4317
4306
  Object.values(versionsByLocale),
4318
4307
  async (localeVersions) => {
4319
- const mappedLocaleVersions = await async.map(
4320
- localeVersions,
4321
- traversalFunction
4322
- );
4323
4308
  if (!contentTypes$1.hasDraftAndPublish(model)) {
4324
- return mappedLocaleVersions[0];
4309
+ return localeVersions[0];
4325
4310
  }
4326
- const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
4327
- const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
4311
+ const draftVersion = localeVersions.find((v) => v.publishedAt === null);
4312
+ const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);
4328
4313
  if (!draftVersion) {
4329
4314
  return;
4330
4315
  }
@@ -4346,8 +4331,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4346
4331
  const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
4347
4332
  return matchLocale && matchStatus;
4348
4333
  });
4349
- if (!availableStatus)
4350
- return availableStatus;
4334
+ if (!availableStatus) return availableStatus;
4351
4335
  return pick(AVAILABLE_STATUS_FIELDS, availableStatus);
4352
4336
  },
4353
4337
  /**
@@ -4357,18 +4341,19 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4357
4341
  * @returns
4358
4342
  */
4359
4343
  async getManyAvailableStatus(uid2, documents) {
4360
- if (!documents.length)
4361
- return [];
4344
+ if (!documents.length) return [];
4362
4345
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4363
- const locale = documents[0]?.locale;
4364
- const otherStatus = status === "published" ? "draft" : "published";
4365
- return strapi2.documents(uid2).findMany({
4366
- filters: {
4367
- documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) }
4368
- },
4369
- status: otherStatus,
4370
- locale,
4371
- fields: ["documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4346
+ const locales = documents.map((d) => d.locale).filter(Boolean);
4347
+ const where = {
4348
+ documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },
4349
+ publishedAt: { $null: status === "published" }
4350
+ };
4351
+ if (locales.length) {
4352
+ where.locale = { $in: locales };
4353
+ }
4354
+ return strapi2.query(uid2).findMany({
4355
+ where,
4356
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4372
4357
  });
4373
4358
  },
4374
4359
  getStatus(version, otherDocumentStatuses) {
@@ -4385,10 +4370,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4385
4370
  } else if (otherVersion) {
4386
4371
  draftVersion = otherVersion;
4387
4372
  }
4388
- if (!draftVersion)
4389
- return CONTENT_MANAGER_STATUS.PUBLISHED;
4390
- if (!publishedVersion)
4391
- return CONTENT_MANAGER_STATUS.DRAFT;
4373
+ if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
4374
+ if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
4392
4375
  const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
4393
4376
  return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
4394
4377
  },
@@ -4396,11 +4379,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4396
4379
  // We could refactor this so the locales are only loaded when they're
4397
4380
  // needed. e.g. in the bulk locale action modal.
4398
4381
  async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
4399
- const populate = getValidatableFieldsPopulate(uid2);
4400
- const versions = await strapi2.db.query(uid2).findMany({
4401
- where: { documentId: version.documentId },
4382
+ const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
4383
+ const params = {
4402
4384
  populate: {
4403
- // Populate only fields that require validation for bulk locale actions
4404
4385
  ...populate,
4405
4386
  // NOTE: creator fields are selected in this way to avoid exposing sensitive data
4406
4387
  createdBy: {
@@ -4409,9 +4390,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4409
4390
  updatedBy: {
4410
4391
  select: ["id", "firstname", "lastname", "email"]
4411
4392
  }
4393
+ },
4394
+ fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
4395
+ filters: {
4396
+ documentId: version.documentId
4412
4397
  }
4413
- });
4414
- const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
4398
+ };
4399
+ const dbParams = strapi2.get("query-params").transform(uid2, params);
4400
+ const versions = await strapi2.db.query(uid2).findMany(dbParams);
4401
+ const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions) : [];
4415
4402
  const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
4416
4403
  return {
4417
4404
  availableLocales: availableLocalesResult,
@@ -4438,6 +4425,16 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4438
4425
  opts.availableStatus = false;
4439
4426
  }
4440
4427
  const meta = await this.getMetadata(uid2, document, opts);
4428
+ if (document.localizations) {
4429
+ const otherStatus = await this.getManyAvailableStatus(uid2, document.localizations);
4430
+ document.localizations = document.localizations.map((d) => {
4431
+ const status = otherStatus.find((s) => s.documentId === d.documentId);
4432
+ return {
4433
+ ...d,
4434
+ status: this.getStatus(d, status ? [status] : [])
4435
+ };
4436
+ });
4437
+ }
4441
4438
  return {
4442
4439
  data: {
4443
4440
  ...document,