@strapi/content-manager 0.0.0-next.2dcec09530c87d7b3b453630c2d76a967476338d → 0.0.0-next.33da70177d156ccbea5cfcbeed769bf25f8a7adc

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 (118) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-BXIWJOkp.js → ComponentConfigurationPage-BLWQy8ru.js} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-BXIWJOkp.js.map → ComponentConfigurationPage-BLWQy8ru.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BRpuqCO2.mjs → ComponentConfigurationPage-CtIa3aa2.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-BRpuqCO2.mjs.map → ComponentConfigurationPage-CtIa3aa2.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-CK_3d9D1.mjs → EditConfigurationPage-DsPR2DVk.mjs} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-CK_3d9D1.mjs.map → EditConfigurationPage-DsPR2DVk.mjs.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-BIyaNgiu.js → EditConfigurationPage-RQkymxCy.js} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-BIyaNgiu.js.map → EditConfigurationPage-RQkymxCy.js.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-G_rDXQB6.js → EditViewPage-B-kExt8C.js} +3 -3
  10. package/dist/_chunks/{EditViewPage-G_rDXQB6.js.map → EditViewPage-B-kExt8C.js.map} +1 -1
  11. package/dist/_chunks/{EditViewPage-D_YtFeQf.mjs → EditViewPage-BPyVuPfM.mjs} +3 -3
  12. package/dist/_chunks/{EditViewPage-D_YtFeQf.mjs.map → EditViewPage-BPyVuPfM.mjs.map} +1 -1
  13. package/dist/_chunks/{Field-DkB0mrLn.js → Field-DPIsQRre.js} +115 -59
  14. package/dist/_chunks/Field-DPIsQRre.js.map +1 -0
  15. package/dist/_chunks/{Field-DbKNY11A.mjs → Field-Dltnt1km.mjs} +114 -59
  16. package/dist/_chunks/Field-Dltnt1km.mjs.map +1 -0
  17. package/dist/_chunks/{Form-rj1Lhzth.js → Form-BFi4MXMT.js} +2 -2
  18. package/dist/_chunks/{Form-rj1Lhzth.js.map → Form-BFi4MXMT.js.map} +1 -1
  19. package/dist/_chunks/{Form-BqFnTO7j.mjs → Form-C1IcWm1u.mjs} +2 -2
  20. package/dist/_chunks/{Form-BqFnTO7j.mjs.map → Form-C1IcWm1u.mjs.map} +1 -1
  21. package/dist/_chunks/{History-By_Dt8Ic.mjs → History-04ChQ4pl.mjs} +32 -8
  22. package/dist/_chunks/History-04ChQ4pl.mjs.map +1 -0
  23. package/dist/_chunks/{History-BkcR8j3W.js → History-wjcK4L0C.js} +32 -8
  24. package/dist/_chunks/History-wjcK4L0C.js.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-BKuvGTnq.mjs → ListConfigurationPage-BYqPYLSU.mjs} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-BKuvGTnq.mjs.map → ListConfigurationPage-BYqPYLSU.mjs.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-B2F3iLSN.js → ListConfigurationPage-CRbxIC3J.js} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-B2F3iLSN.js.map → ListConfigurationPage-CRbxIC3J.js.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-C3Z_WX-I.js → ListViewPage-D5NY9183.js} +3 -3
  30. package/dist/_chunks/{ListViewPage-C3Z_WX-I.js.map → ListViewPage-D5NY9183.js.map} +1 -1
  31. package/dist/_chunks/{ListViewPage--tbvSafE.mjs → ListViewPage-FU2LBuhl.mjs} +3 -3
  32. package/dist/_chunks/{ListViewPage--tbvSafE.mjs.map → ListViewPage-FU2LBuhl.mjs.map} +1 -1
  33. package/dist/_chunks/{NoContentTypePage-BR5_n0mp.js → NoContentTypePage-BgQVE_Qb.js} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-BR5_n0mp.js.map → NoContentTypePage-BgQVE_Qb.js.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-C6Vge6Lk.mjs → NoContentTypePage-DCKUkwb8.mjs} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-C6Vge6Lk.mjs.map → NoContentTypePage-DCKUkwb8.mjs.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-OrFm1kPU.js → NoPermissionsPage-C5jwn70o.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-OrFm1kPU.js.map → NoPermissionsPage-C5jwn70o.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-DeZjpGiX.mjs → NoPermissionsPage-jqve7C8l.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-DeZjpGiX.mjs.map → NoPermissionsPage-jqve7C8l.mjs.map} +1 -1
  41. package/dist/_chunks/{Preview-CS4KH49a.mjs → Preview-BMYN548c.mjs} +33 -11
  42. package/dist/_chunks/Preview-BMYN548c.mjs.map +1 -0
  43. package/dist/_chunks/{Preview-DiUzYyBe.js → Preview-DaOihysv.js} +32 -10
  44. package/dist/_chunks/Preview-DaOihysv.js.map +1 -0
  45. package/dist/_chunks/{Relations-D1GMLvGT.js → Relations-CTGM7Hv5.js} +3 -3
  46. package/dist/_chunks/{Relations-D1GMLvGT.js.map → Relations-CTGM7Hv5.js.map} +1 -1
  47. package/dist/_chunks/{Relations-CLmySGRe.mjs → Relations-gscPkxjF.mjs} +3 -3
  48. package/dist/_chunks/{Relations-CLmySGRe.mjs.map → Relations-gscPkxjF.mjs.map} +1 -1
  49. package/dist/_chunks/{en-BK8Xyl5I.js → en-BzQmavmK.js} +7 -2
  50. package/dist/_chunks/{en-BK8Xyl5I.js.map → en-BzQmavmK.js.map} +1 -1
  51. package/dist/_chunks/{en-Dtk_ot79.mjs → en-CSxLmrh1.mjs} +7 -2
  52. package/dist/_chunks/{en-Dtk_ot79.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
  53. package/dist/_chunks/{index-DWW8Uk8g.js → index-Ca7YWlAA.js} +58 -33
  54. package/dist/_chunks/index-Ca7YWlAA.js.map +1 -0
  55. package/dist/_chunks/{index-OUqkGrKe.mjs → index-DqasUQ6Q.mjs} +58 -33
  56. package/dist/_chunks/index-DqasUQ6Q.mjs.map +1 -0
  57. package/dist/_chunks/{layout-DSlB2Oox.js → layout-BW80JSCd.js} +3 -3
  58. package/dist/_chunks/{layout-DSlB2Oox.js.map → layout-BW80JSCd.js.map} +1 -1
  59. package/dist/_chunks/{layout-Chxcrwu3.mjs → layout-W3clJSCy.mjs} +3 -3
  60. package/dist/_chunks/{layout-Chxcrwu3.mjs.map → layout-W3clJSCy.mjs.map} +1 -1
  61. package/dist/_chunks/{relations-Dom2NHwd.mjs → relations-BlDkoeWh.mjs} +2 -2
  62. package/dist/_chunks/{relations-Dom2NHwd.mjs.map → relations-BlDkoeWh.mjs.map} +1 -1
  63. package/dist/_chunks/{relations-B8DGfIFQ.js → relations-C9Usz9k5.js} +2 -2
  64. package/dist/_chunks/{relations-B8DGfIFQ.js.map → relations-C9Usz9k5.js.map} +1 -1
  65. package/dist/admin/index.js +2 -1
  66. package/dist/admin/index.js.map +1 -1
  67. package/dist/admin/index.mjs +2 -1
  68. package/dist/admin/src/exports.d.ts +1 -0
  69. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  70. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +1 -1
  71. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  72. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  73. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  74. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  75. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  76. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  77. package/dist/admin/src/services/api.d.ts +1 -1
  78. package/dist/admin/src/services/components.d.ts +2 -2
  79. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  80. package/dist/admin/src/services/documents.d.ts +16 -16
  81. package/dist/admin/src/services/init.d.ts +1 -1
  82. package/dist/admin/src/services/relations.d.ts +2 -2
  83. package/dist/admin/src/services/uid.d.ts +3 -3
  84. package/dist/server/index.js +156 -142
  85. package/dist/server/index.js.map +1 -1
  86. package/dist/server/index.mjs +157 -143
  87. package/dist/server/index.mjs.map +1 -1
  88. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  89. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  90. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  91. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  92. package/dist/server/src/history/services/history.d.ts +3 -3
  93. package/dist/server/src/history/services/history.d.ts.map +1 -1
  94. package/dist/server/src/history/services/utils.d.ts +6 -10
  95. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  96. package/dist/server/src/index.d.ts +3 -2
  97. package/dist/server/src/index.d.ts.map +1 -1
  98. package/dist/server/src/preview/index.d.ts.map +1 -1
  99. package/dist/server/src/services/document-metadata.d.ts +4 -2
  100. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  101. package/dist/server/src/services/index.d.ts +3 -2
  102. package/dist/server/src/services/index.d.ts.map +1 -1
  103. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  104. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  105. package/dist/server/src/services/utils/populate.d.ts +2 -2
  106. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  107. package/package.json +8 -6
  108. package/dist/_chunks/Field-DbKNY11A.mjs.map +0 -1
  109. package/dist/_chunks/Field-DkB0mrLn.js.map +0 -1
  110. package/dist/_chunks/History-BkcR8j3W.js.map +0 -1
  111. package/dist/_chunks/History-By_Dt8Ic.mjs.map +0 -1
  112. package/dist/_chunks/Preview-CS4KH49a.mjs.map +0 -1
  113. package/dist/_chunks/Preview-DiUzYyBe.js.map +0 -1
  114. package/dist/_chunks/index-DWW8Uk8g.js.map +0 -1
  115. package/dist/_chunks/index-OUqkGrKe.mjs.map +0 -1
  116. package/dist/admin/src/preview/constants.d.ts +0 -1
  117. package/dist/server/src/preview/constants.d.ts +0 -2
  118. 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";
@@ -150,19 +150,16 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
150
150
  });
151
151
  })
152
152
  );
153
- return existingAndMissingRelations.filter(
154
- (relation) => relation !== null
155
- );
153
+ return existingAndMissingRelations.filter((relation) => relation !== null);
156
154
  }
157
155
  return strapi2.documents(attribute.target).findOne({
158
156
  documentId: versionRelationData.documentId,
159
157
  locale: versionRelationData.locale || void 0
160
158
  });
161
159
  };
162
- const getMediaRestoreValue = async (versionRelationData, attribute) => {
163
- if (attribute.multiple) {
160
+ const getMediaRestoreValue = async (versionRelationData) => {
161
+ if (Array.isArray(versionRelationData)) {
164
162
  const existingAndMissingMedias = await Promise.all(
165
- // @ts-expect-error Fix the type definitions so this isn't any
166
163
  versionRelationData.map((media) => {
167
164
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
168
165
  })
@@ -331,8 +328,8 @@ const createHistoryService = ({ strapi: strapi2 }) => {
331
328
  });
332
329
  },
333
330
  async findVersionsPage(params) {
334
- const model = strapi2.getModel(params.query.contentType);
335
- const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
331
+ const schema = strapi2.getModel(params.query.contentType);
332
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(schema);
336
333
  const defaultLocale = await serviceUtils.getDefaultLocale();
337
334
  let locale = null;
338
335
  if (isLocalizedContentType) {
@@ -353,32 +350,20 @@ const createHistoryService = ({ strapi: strapi2 }) => {
353
350
  }),
354
351
  serviceUtils.getLocaleDictionary()
355
352
  ]);
356
- const populateEntryRelations = async (entry) => {
357
- const entryWithRelations = await Object.entries(entry.schema).reduce(
358
- async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
359
- const attributeValue = entry.data[attributeKey];
360
- const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
361
- if (attributeSchema.type === "media") {
362
- const permissionChecker2 = getService$2("permission-checker").create({
363
- userAbility: params.state.userAbility,
364
- model: "plugin::upload.file"
365
- });
366
- const response = await serviceUtils.buildMediaResponse(attributeValues);
367
- const sanitizedResults = await Promise.all(
368
- response.results.map((media) => permissionChecker2.sanitizeOutput(media))
369
- );
370
- return {
371
- ...await currentDataWithRelations,
372
- [attributeKey]: {
373
- results: sanitizedResults,
374
- meta: response.meta
375
- }
376
- };
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");
377
361
  }
378
- if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
379
- 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") {
380
365
  const adminUsers = await Promise.all(
381
- attributeValues.map((userToPopulate) => {
366
+ currentValue.map((userToPopulate) => {
382
367
  if (userToPopulate == null) {
383
368
  return null;
384
369
  }
@@ -390,46 +375,51 @@ const createHistoryService = ({ strapi: strapi2 }) => {
390
375
  });
391
376
  })
392
377
  );
393
- return {
394
- ...await currentDataWithRelations,
395
- /**
396
- * Ideally we would return the same "{results: [], meta: {}}" shape, however,
397
- * when sanitizing the data as a whole in the controller before sending to the client,
398
- * the data for admin relation user is completely sanitized if we return an object here as opposed to an array.
399
- */
400
- [attributeKey]: adminUsers
401
- };
378
+ utils.set(options.key, adminUsers);
402
379
  }
403
380
  const permissionChecker2 = getService$2("permission-checker").create({
404
381
  userAbility: params.state.userAbility,
405
- model: attributeSchema.target
382
+ model: options.attribute.target
406
383
  });
407
384
  const response = await serviceUtils.buildRelationReponse(
408
- attributeValues,
409
- attributeSchema
385
+ currentValue,
386
+ options.attribute
410
387
  );
411
388
  const sanitizedResults = await Promise.all(
412
389
  response.results.map((media) => permissionChecker2.sanitizeOutput(media))
413
390
  );
414
- return {
415
- ...await currentDataWithRelations,
416
- [attributeKey]: {
417
- results: sanitizedResults,
418
- meta: response.meta
419
- }
420
- };
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
+ });
421
409
  }
422
- return currentDataWithRelations;
423
410
  },
424
- Promise.resolve(entry.data)
411
+ {
412
+ schema,
413
+ getModel: strapi2.getModel.bind(strapi2)
414
+ },
415
+ entry.data
425
416
  );
426
- return entryWithRelations;
427
417
  };
428
418
  const formattedResults = await Promise.all(
429
419
  results.map(async (result) => {
430
420
  return {
431
421
  ...result,
432
- data: await populateEntryRelations(result),
422
+ data: await populateEntry(result),
433
423
  meta: {
434
424
  unknownAttributes: serviceUtils.getSchemaAttributesDiff(
435
425
  result.schema,
@@ -460,30 +450,44 @@ const createHistoryService = ({ strapi: strapi2 }) => {
460
450
  // Clone to avoid mutating the original version data
461
451
  structuredClone(version.data)
462
452
  );
463
- const sanitizedSchemaAttributes = omit(
464
- FIELDS_TO_IGNORE,
465
- contentTypeSchemaAttributes
466
- );
467
- const reducer = async.reduce(Object.entries(sanitizedSchemaAttributes));
468
- const dataWithoutMissingRelations = await reducer(
469
- async (previousRelationAttributes, [name, attribute]) => {
470
- const versionRelationData = version.data[name];
471
- if (!versionRelationData) {
472
- 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
+ }
463
+ }
464
+ if (options.attribute.type === "dynamiczone") {
465
+ if (options.value === null) {
466
+ utils.set(options.key, []);
467
+ }
473
468
  }
474
- if (attribute.type === "relation" && // TODO: handle polymorphic relations
475
- attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
476
- const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
477
- 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);
478
477
  }
479
- if (attribute.type === "media") {
480
- const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
481
- previousRelationAttributes[name] = data2;
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);
482
484
  }
483
- return previousRelationAttributes;
484
485
  },
485
- // Clone to avoid mutating the original version data
486
- structuredClone(dataWithoutAddedAttributes)
486
+ {
487
+ schema,
488
+ getModel: strapi2.getModel.bind(strapi2)
489
+ },
490
+ dataWithoutAddedAttributes
487
491
  );
488
492
  const data = omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
489
493
  const restoredDocument = await strapi2.documents(version.contentType).update({
@@ -712,7 +716,6 @@ const getFeature$1 = () => {
712
716
  };
713
717
  };
714
718
  const history = getFeature$1();
715
- const FEATURE_ID = "preview";
716
719
  const info = { pluginName: "content-manager", type: "admin" };
717
720
  const previewRouter = {
718
721
  type: "admin",
@@ -890,9 +893,6 @@ const services$1 = {
890
893
  "preview-config": createPreviewConfigService
891
894
  };
892
895
  const getFeature = () => {
893
- if (!strapi.features.future.isEnabled(FEATURE_ID)) {
894
- return {};
895
- }
896
896
  return {
897
897
  register() {
898
898
  const config = getService(strapi, "preview-config");
@@ -3908,6 +3908,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
3908
3908
  if (initialPopulate) {
3909
3909
  return initialPopulate;
3910
3910
  }
3911
+ if (attributeName === "localizations") {
3912
+ const validationPopulate = getPopulateForValidation(model.uid);
3913
+ return {
3914
+ populate: validationPopulate.populate
3915
+ };
3916
+ }
3911
3917
  if (!isVisibleAttribute$1(model, attributeName)) {
3912
3918
  return true;
3913
3919
  }
@@ -3967,6 +3973,9 @@ const getDeepPopulate = (uid2, {
3967
3973
  return {};
3968
3974
  }
3969
3975
  const model = strapi.getModel(uid2);
3976
+ if (!model) {
3977
+ return {};
3978
+ }
3970
3979
  return Object.keys(model.attributes).reduce(
3971
3980
  (populateAcc, attributeName) => merge(
3972
3981
  populateAcc,
@@ -3986,40 +3995,46 @@ const getDeepPopulate = (uid2, {
3986
3995
  {}
3987
3996
  );
3988
3997
  };
3989
- const getValidatableFieldsPopulate = (uid2, {
3990
- initialPopulate = {},
3991
- countMany = false,
3992
- countOne = false,
3993
- maxLevel = Infinity
3994
- } = {}, level = 1) => {
3995
- if (level > maxLevel) {
3998
+ const getPopulateForValidation = (uid2) => {
3999
+ const model = strapi.getModel(uid2);
4000
+ if (!model) {
3996
4001
  return {};
3997
4002
  }
3998
- const model = strapi.getModel(uid2);
3999
4003
  return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
4000
- if (!getDoesAttributeRequireValidation(attribute)) {
4004
+ if (isScalarAttribute(attribute)) {
4005
+ if (getDoesAttributeRequireValidation(attribute)) {
4006
+ populateAcc.fields = populateAcc.fields || [];
4007
+ populateAcc.fields.push(attributeName);
4008
+ }
4001
4009
  return populateAcc;
4002
4010
  }
4003
- if (isScalarAttribute(attribute)) {
4004
- return merge(populateAcc, {
4005
- [attributeName]: true
4006
- });
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;
4007
4019
  }
4008
- return merge(
4009
- populateAcc,
4010
- getPopulateFor(
4011
- attributeName,
4012
- model,
4013
- {
4014
- // @ts-expect-error - improve types
4015
- initialPopulate: initialPopulate?.[attributeName],
4016
- countMany,
4017
- countOne,
4018
- 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;
4019
4029
  },
4020
- level
4021
- )
4022
- );
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;
4023
4038
  }, {});
4024
4039
  };
4025
4040
  const getDeepPopulateDraftCount = (uid2) => {
@@ -4261,7 +4276,6 @@ const AVAILABLE_LOCALES_FIELDS = [
4261
4276
  "locale",
4262
4277
  "updatedAt",
4263
4278
  "createdAt",
4264
- "status",
4265
4279
  "publishedAt",
4266
4280
  "documentId"
4267
4281
  ];
@@ -4282,36 +4296,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4282
4296
  /**
4283
4297
  * Returns available locales of a document for the current status
4284
4298
  */
4285
- async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4299
+ async getAvailableLocales(uid2, version, allVersions) {
4286
4300
  const versionsByLocale = groupBy("locale", allVersions);
4287
4301
  if (version.locale) {
4288
4302
  delete versionsByLocale[version.locale];
4289
4303
  }
4290
4304
  const model = strapi2.getModel(uid2);
4291
- const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4292
- const traversalFunction = async (localeVersion) => traverseEntity(
4293
- ({ key }, { remove }) => {
4294
- if (keysToKeep.includes(key)) {
4295
- return;
4296
- }
4297
- remove(key);
4298
- },
4299
- { schema: model, getModel: strapi2.getModel.bind(strapi2) },
4300
- // @ts-expect-error fix types DocumentVersion incompatible with Data
4301
- localeVersion
4302
- );
4303
4305
  const mappingResult = await async.map(
4304
4306
  Object.values(versionsByLocale),
4305
4307
  async (localeVersions) => {
4306
- const mappedLocaleVersions = await async.map(
4307
- localeVersions,
4308
- traversalFunction
4309
- );
4310
4308
  if (!contentTypes$1.hasDraftAndPublish(model)) {
4311
- return mappedLocaleVersions[0];
4309
+ return localeVersions[0];
4312
4310
  }
4313
- const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
4314
- 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);
4315
4313
  if (!draftVersion) {
4316
4314
  return;
4317
4315
  }
@@ -4345,15 +4343,17 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4345
4343
  async getManyAvailableStatus(uid2, documents) {
4346
4344
  if (!documents.length) return [];
4347
4345
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4348
- const locale = documents[0]?.locale;
4349
- const otherStatus = status === "published" ? "draft" : "published";
4350
- return strapi2.documents(uid2).findMany({
4351
- filters: {
4352
- documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) }
4353
- },
4354
- status: otherStatus,
4355
- locale,
4356
- 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"]
4357
4357
  });
4358
4358
  },
4359
4359
  getStatus(version, otherDocumentStatuses) {
@@ -4379,11 +4379,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4379
4379
  // We could refactor this so the locales are only loaded when they're
4380
4380
  // needed. e.g. in the bulk locale action modal.
4381
4381
  async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
4382
- const populate = getValidatableFieldsPopulate(uid2);
4383
- const versions = await strapi2.db.query(uid2).findMany({
4384
- where: { documentId: version.documentId },
4382
+ const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
4383
+ const params = {
4385
4384
  populate: {
4386
- // Populate only fields that require validation for bulk locale actions
4387
4385
  ...populate,
4388
4386
  // NOTE: creator fields are selected in this way to avoid exposing sensitive data
4389
4387
  createdBy: {
@@ -4392,9 +4390,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4392
4390
  updatedBy: {
4393
4391
  select: ["id", "firstname", "lastname", "email"]
4394
4392
  }
4393
+ },
4394
+ fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
4395
+ filters: {
4396
+ documentId: version.documentId
4395
4397
  }
4396
- });
4397
- 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) : [];
4398
4402
  const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
4399
4403
  return {
4400
4404
  availableLocales: availableLocalesResult,
@@ -4421,6 +4425,16 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4421
4425
  opts.availableStatus = false;
4422
4426
  }
4423
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
+ }
4424
4438
  return {
4425
4439
  data: {
4426
4440
  ...document,