@strapi/content-manager 0.0.0-experimental.9df68962083938acba06546a7901c68a63266aec → 0.0.0-experimental.9f812af47f0e9db3d5531382c836c2ac0776afdf

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 (220) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
  3. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-BSEZcJVB.js} +5 -6
  5. package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-BSEZcJVB.js.map} +1 -1
  6. package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-BiASGi7x.mjs} +4 -4
  7. package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-BiASGi7x.mjs.map} +1 -1
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  9. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  10. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  11. package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-D2rtvneE.js} +5 -6
  12. package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-D2rtvneE.js.map} +1 -1
  13. package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-vN4zupij.mjs} +4 -4
  14. package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-vN4zupij.mjs.map} +1 -1
  15. package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-BwisF04Q.js} +63 -13
  16. package/dist/_chunks/EditViewPage-BwisF04Q.js.map +1 -0
  17. package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-_A31Cl4g.mjs} +63 -12
  18. package/dist/_chunks/EditViewPage-_A31Cl4g.mjs.map +1 -0
  19. package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-CvIunNOj.mjs} +405 -256
  20. package/dist/_chunks/Field-CvIunNOj.mjs.map +1 -0
  21. package/dist/_chunks/{Field-Boxf9Ajp.js → Field-Dsu6-FrM.js} +409 -260
  22. package/dist/_chunks/Field-Dsu6-FrM.js.map +1 -0
  23. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  24. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  25. package/dist/_chunks/{Form-DHrru2AV.mjs → Form-DK0fG0Gj.mjs} +37 -18
  26. package/dist/_chunks/Form-DK0fG0Gj.mjs.map +1 -0
  27. package/dist/_chunks/{Form-y5g1SRsh.js → Form-DUwWcCmA.js} +39 -21
  28. package/dist/_chunks/Form-DUwWcCmA.js.map +1 -0
  29. package/dist/_chunks/{History-CqN6K7SX.js → History-CeCDhoJG.js} +81 -114
  30. package/dist/_chunks/History-CeCDhoJG.js.map +1 -0
  31. package/dist/_chunks/{History-Bru_KoeP.mjs → History-DP8gmXpm.mjs} +82 -114
  32. package/dist/_chunks/History-DP8gmXpm.mjs.map +1 -0
  33. package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BCkO5iuN.mjs} +25 -12
  34. package/dist/_chunks/ListConfigurationPage-BCkO5iuN.mjs.map +1 -0
  35. package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-C-bAd44a.js} +25 -13
  36. package/dist/_chunks/ListConfigurationPage-C-bAd44a.js.map +1 -0
  37. package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-BKTZFhsM.js} +121 -81
  38. package/dist/_chunks/ListViewPage-BKTZFhsM.js.map +1 -0
  39. package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-Cf_DgaFV.mjs} +118 -77
  40. package/dist/_chunks/ListViewPage-Cf_DgaFV.mjs.map +1 -0
  41. package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-D3Cm3v3q.js} +2 -2
  42. package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-D3Cm3v3q.js.map} +1 -1
  43. package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-nHIyvJcB.mjs} +2 -2
  44. package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-nHIyvJcB.mjs.map} +1 -1
  45. package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-BALVSJ7x.mjs} +2 -2
  46. package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-BALVSJ7x.mjs.map} +1 -1
  47. package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-CChGWBj5.js} +2 -2
  48. package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-CChGWBj5.js.map} +1 -1
  49. package/dist/_chunks/Preview-C4NBzKUV.mjs +294 -0
  50. package/dist/_chunks/Preview-C4NBzKUV.mjs.map +1 -0
  51. package/dist/_chunks/Preview-CT28Ckpg.js +312 -0
  52. package/dist/_chunks/Preview-CT28Ckpg.js.map +1 -0
  53. package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-C8uC89cT.mjs} +76 -42
  54. package/dist/_chunks/Relations-C8uC89cT.mjs.map +1 -0
  55. package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-CvkPCng_.js} +76 -43
  56. package/dist/_chunks/Relations-CvkPCng_.js.map +1 -0
  57. package/dist/_chunks/{en-fbKQxLGn.js → en-BK8Xyl5I.js} +32 -18
  58. package/dist/_chunks/{en-fbKQxLGn.js.map → en-BK8Xyl5I.js.map} +1 -1
  59. package/dist/_chunks/{en-Ux26r5pl.mjs → en-Dtk_ot79.mjs} +32 -18
  60. package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
  61. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  62. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  63. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  64. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  65. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
  66. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
  67. package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
  68. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
  69. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  70. package/dist/_chunks/{index-DVPWZkbS.js → index-CnX_j5h-.js} +1235 -746
  71. package/dist/_chunks/index-CnX_j5h-.js.map +1 -0
  72. package/dist/_chunks/{index-DJXJw9V5.mjs → index-Dh2aGTGJ.mjs} +1252 -763
  73. package/dist/_chunks/index-Dh2aGTGJ.mjs.map +1 -0
  74. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  75. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  76. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  77. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  78. package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-B5qsPihj.mjs} +26 -13
  79. package/dist/_chunks/layout-B5qsPihj.mjs.map +1 -0
  80. package/dist/_chunks/{layout-Dm6fbiQj.js → layout-B_qdWGny.js} +26 -14
  81. package/dist/_chunks/layout-B_qdWGny.js.map +1 -0
  82. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  83. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  84. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  85. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  86. package/dist/_chunks/{relations-CKnpRgrN.js → relations-ChcieiF5.js} +6 -7
  87. package/dist/_chunks/relations-ChcieiF5.js.map +1 -0
  88. package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-DMXpNY-e.mjs} +6 -7
  89. package/dist/_chunks/relations-DMXpNY-e.mjs.map +1 -0
  90. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  91. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  92. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  93. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  94. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  95. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  96. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  97. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  98. package/dist/admin/index.js +2 -1
  99. package/dist/admin/index.js.map +1 -1
  100. package/dist/admin/index.mjs +5 -4
  101. package/dist/admin/src/content-manager.d.ts +3 -2
  102. package/dist/admin/src/exports.d.ts +1 -1
  103. package/dist/admin/src/history/index.d.ts +3 -0
  104. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  105. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  106. package/dist/admin/src/index.d.ts +1 -0
  107. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  108. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +2 -1
  109. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
  110. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  111. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  112. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  113. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  114. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  115. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  116. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  117. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  118. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  119. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  120. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  121. package/dist/admin/src/preview/index.d.ts +4 -0
  122. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  123. package/dist/admin/src/preview/routes.d.ts +3 -0
  124. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  125. package/dist/admin/src/router.d.ts +1 -1
  126. package/dist/admin/src/services/api.d.ts +1 -1
  127. package/dist/admin/src/services/components.d.ts +2 -2
  128. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  129. package/dist/admin/src/services/documents.d.ts +19 -20
  130. package/dist/admin/src/services/init.d.ts +1 -1
  131. package/dist/admin/src/services/relations.d.ts +2 -2
  132. package/dist/admin/src/services/uid.d.ts +3 -3
  133. package/dist/admin/src/utils/validation.d.ts +4 -1
  134. package/dist/server/index.js +686 -360
  135. package/dist/server/index.js.map +1 -1
  136. package/dist/server/index.mjs +687 -360
  137. package/dist/server/index.mjs.map +1 -1
  138. package/dist/server/src/bootstrap.d.ts.map +1 -1
  139. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  140. package/dist/server/src/controllers/index.d.ts.map +1 -1
  141. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  142. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  143. package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
  144. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  145. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  146. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  147. package/dist/server/src/history/services/history.d.ts.map +1 -1
  148. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  149. package/dist/server/src/history/services/utils.d.ts +4 -4
  150. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  151. package/dist/server/src/index.d.ts +7 -6
  152. package/dist/server/src/index.d.ts.map +1 -1
  153. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  154. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  155. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  156. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  157. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  158. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  159. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  160. package/dist/server/src/preview/index.d.ts +4 -0
  161. package/dist/server/src/preview/index.d.ts.map +1 -0
  162. package/dist/server/src/preview/routes/index.d.ts +8 -0
  163. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  164. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  165. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  166. package/dist/server/src/preview/services/index.d.ts +16 -0
  167. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  168. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  169. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  170. package/dist/server/src/preview/services/preview.d.ts +12 -0
  171. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  172. package/dist/server/src/preview/utils.d.ts +19 -0
  173. package/dist/server/src/preview/utils.d.ts.map +1 -0
  174. package/dist/server/src/register.d.ts.map +1 -1
  175. package/dist/server/src/routes/index.d.ts.map +1 -1
  176. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  177. package/dist/server/src/services/document-metadata.d.ts +12 -10
  178. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  179. package/dist/server/src/services/index.d.ts +7 -6
  180. package/dist/server/src/services/index.d.ts.map +1 -1
  181. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  182. package/dist/server/src/services/utils/populate.d.ts +2 -2
  183. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  184. package/dist/server/src/utils/index.d.ts +2 -0
  185. package/dist/server/src/utils/index.d.ts.map +1 -1
  186. package/dist/shared/contracts/collection-types.d.ts +3 -1
  187. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  188. package/dist/shared/contracts/index.d.ts +1 -0
  189. package/dist/shared/contracts/index.d.ts.map +1 -1
  190. package/dist/shared/contracts/preview.d.ts +27 -0
  191. package/dist/shared/contracts/preview.d.ts.map +1 -0
  192. package/dist/shared/index.js +4 -0
  193. package/dist/shared/index.js.map +1 -1
  194. package/dist/shared/index.mjs +4 -0
  195. package/dist/shared/index.mjs.map +1 -1
  196. package/package.json +17 -15
  197. package/dist/_chunks/EditViewPage-CPj61RMh.mjs.map +0 -1
  198. package/dist/_chunks/EditViewPage-zT3fBr4Y.js.map +0 -1
  199. package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
  200. package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
  201. package/dist/_chunks/Form-DHrru2AV.mjs.map +0 -1
  202. package/dist/_chunks/Form-y5g1SRsh.js.map +0 -1
  203. package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
  204. package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
  205. package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
  206. package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
  207. package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
  208. package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
  209. package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
  210. package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
  211. package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
  212. package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
  213. package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
  214. package/dist/_chunks/layout-Dm6fbiQj.js.map +0 -1
  215. package/dist/_chunks/relations-BH_kBSJ0.mjs.map +0 -1
  216. package/dist/_chunks/relations-CKnpRgrN.js.map +0 -1
  217. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  218. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  219. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  220. package/strapi-server.js +0 -3
@@ -1,5 +1,5 @@
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";
2
- import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, isNil as isNil$1, getOr, propEq, merge, groupBy, castArray } from "lodash/fp";
1
+ import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, pagination } from "@strapi/utils";
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";
5
5
  import { scheduleJob } from "node-schedule";
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
7
7
  import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
8
8
  import qs from "qs";
9
9
  import slugify from "@sindresorhus/slugify";
10
- const getService$1 = (name) => {
10
+ const getService$2 = (name) => {
11
11
  return strapi.plugin("content-manager").service(name);
12
12
  };
13
- function getService(strapi2, name) {
13
+ function getService$1(strapi2, name) {
14
14
  return strapi2.service(`plugin::content-manager.${name}`);
15
15
  }
16
16
  const historyRestoreVersionSchema = yup.object().shape({
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
46
46
  if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
47
47
  throw new errors.ForbiddenError("contentType and documentId are required");
48
48
  }
49
- const permissionChecker2 = getService$1("permission-checker").create({
49
+ const permissionChecker2 = getService$2("permission-checker").create({
50
50
  userAbility: ctx.state.userAbility,
51
51
  model: ctx.query.contentType
52
52
  });
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
54
54
  return ctx.forbidden();
55
55
  }
56
56
  const query = await permissionChecker2.sanitizeQuery(ctx.query);
57
- const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
57
+ const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
58
58
  query: {
59
59
  ...query,
60
60
  ...getValidPagination({ page: query.page, pageSize: query.pageSize })
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
79
79
  async restoreVersion(ctx) {
80
80
  const request = ctx.request;
81
81
  await validateRestoreVersion(request.body, "contentType is required");
82
- const permissionChecker2 = getService$1("permission-checker").create({
82
+ const permissionChecker2 = getService$2("permission-checker").create({
83
83
  userAbility: ctx.state.userAbility,
84
84
  model: request.body.contentType
85
85
  });
86
86
  if (permissionChecker2.cannot.update()) {
87
87
  throw new errors.ForbiddenError();
88
88
  }
89
- const restoredDocument = await getService(strapi2, "history").restoreVersion(
89
+ const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
90
90
  request.params.versionId
91
91
  );
92
92
  return {
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
95
95
  }
96
96
  };
97
97
  };
98
- const controllers$1 = {
98
+ const controllers$2 = {
99
99
  "history-version": createHistoryVersionController
100
100
  /**
101
101
  * Casting is needed because the types aren't aware that Strapi supports
@@ -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({
@@ -173,10 +172,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
173
172
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
174
173
  };
175
174
  const localesService = strapi2.plugin("i18n")?.service("locales");
175
+ const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
176
176
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
177
+ const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
177
178
  const getLocaleDictionary = async () => {
178
- if (!localesService)
179
- return {};
179
+ if (!localesService) return {};
180
180
  const locales = await localesService.find() || [];
181
181
  return locales.reduce(
182
182
  (acc, locale) => {
@@ -200,31 +200,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
200
200
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
201
201
  return documentMetadataService.getStatus(document, meta.availableStatus);
202
202
  };
203
- const getDeepPopulate2 = (uid2) => {
203
+ const getComponentFields = (componentUID) => {
204
+ return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
205
+ (fieldsAcc, [key, attribute]) => {
206
+ if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
207
+ fieldsAcc.push(key);
208
+ }
209
+ return fieldsAcc;
210
+ },
211
+ []
212
+ );
213
+ };
214
+ const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
204
215
  const model = strapi2.getModel(uid2);
205
216
  const attributes = Object.entries(model.attributes);
217
+ const fieldSelector = useDatabaseSyntax ? "select" : "fields";
206
218
  return attributes.reduce((acc, [attributeName, attribute]) => {
207
219
  switch (attribute.type) {
208
220
  case "relation": {
221
+ const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
222
+ if (isMorphRelation) {
223
+ break;
224
+ }
209
225
  const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
210
226
  if (isVisible2) {
211
- acc[attributeName] = { fields: ["documentId", "locale", "publishedAt"] };
227
+ acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
212
228
  }
213
229
  break;
214
230
  }
215
231
  case "media": {
216
- acc[attributeName] = { fields: ["id"] };
232
+ acc[attributeName] = { [fieldSelector]: ["id"] };
217
233
  break;
218
234
  }
219
235
  case "component": {
220
236
  const populate = getDeepPopulate2(attribute.component);
221
- acc[attributeName] = { populate };
237
+ acc[attributeName] = {
238
+ populate,
239
+ [fieldSelector]: getComponentFields(attribute.component)
240
+ };
222
241
  break;
223
242
  }
224
243
  case "dynamiczone": {
225
244
  const populatedComponents = (attribute.components || []).reduce(
226
245
  (acc2, componentUID) => {
227
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
246
+ acc2[componentUID] = {
247
+ populate: getDeepPopulate2(componentUID),
248
+ [fieldSelector]: getComponentFields(componentUID)
249
+ };
228
250
  return acc2;
229
251
  },
230
252
  {}
@@ -286,6 +308,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
286
308
  getRelationRestoreValue,
287
309
  getMediaRestoreValue,
288
310
  getDefaultLocale,
311
+ isLocalizedContentType,
289
312
  getLocaleDictionary,
290
313
  getRetentionDays,
291
314
  getVersionStatus,
@@ -308,7 +331,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
308
331
  });
309
332
  },
310
333
  async findVersionsPage(params) {
311
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
334
+ const model = strapi2.getModel(params.query.contentType);
335
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
336
+ const defaultLocale = await serviceUtils.getDefaultLocale();
337
+ let locale = null;
338
+ if (isLocalizedContentType) {
339
+ locale = params.query.locale || defaultLocale;
340
+ }
312
341
  const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
313
342
  query.findPage({
314
343
  ...params.query,
@@ -330,7 +359,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
330
359
  const attributeValue = entry.data[attributeKey];
331
360
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
332
361
  if (attributeSchema.type === "media") {
333
- const permissionChecker2 = getService$1("permission-checker").create({
362
+ const permissionChecker2 = getService$2("permission-checker").create({
334
363
  userAbility: params.state.userAbility,
335
364
  model: "plugin::upload.file"
336
365
  });
@@ -353,7 +382,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
353
382
  if (userToPopulate == null) {
354
383
  return null;
355
384
  }
356
- return strapi2.query("admin::user").findOne({ where: { id: userToPopulate.id } });
385
+ return strapi2.query("admin::user").findOne({
386
+ where: {
387
+ ...userToPopulate.id ? { id: userToPopulate.id } : {},
388
+ ...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
389
+ }
390
+ });
357
391
  })
358
392
  );
359
393
  return {
@@ -366,7 +400,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
366
400
  [attributeKey]: adminUsers
367
401
  };
368
402
  }
369
- const permissionChecker2 = getService$1("permission-checker").create({
403
+ const permissionChecker2 = getService$2("permission-checker").create({
370
404
  userAbility: params.state.userAbility,
371
405
  model: attributeSchema.target
372
406
  });
@@ -464,6 +498,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
464
498
  }
465
499
  };
466
500
  };
501
+ const shouldCreateHistoryVersion = (context) => {
502
+ if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
503
+ return false;
504
+ }
505
+ if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
506
+ return false;
507
+ }
508
+ if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
509
+ return false;
510
+ }
511
+ if (!context.contentType.uid.startsWith("api::")) {
512
+ return false;
513
+ }
514
+ return true;
515
+ };
516
+ const getSchemas = (uid2) => {
517
+ const attributesSchema = strapi.getModel(uid2).attributes;
518
+ const componentsSchemas = Object.keys(attributesSchema).reduce(
519
+ (currentComponentSchemas, key) => {
520
+ const fieldSchema = attributesSchema[key];
521
+ if (fieldSchema.type === "component") {
522
+ const componentSchema = strapi.getModel(fieldSchema.component).attributes;
523
+ return {
524
+ ...currentComponentSchemas,
525
+ [fieldSchema.component]: componentSchema
526
+ };
527
+ }
528
+ return currentComponentSchemas;
529
+ },
530
+ {}
531
+ );
532
+ return {
533
+ schema: omit(FIELDS_TO_IGNORE, attributesSchema),
534
+ componentsSchemas
535
+ };
536
+ };
467
537
  const createLifecyclesService = ({ strapi: strapi2 }) => {
468
538
  const state = {
469
539
  deleteExpiredJob: null,
@@ -476,76 +546,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
476
546
  return;
477
547
  }
478
548
  strapi2.documents.use(async (context, next) => {
479
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
480
- return next();
481
- }
482
- if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
483
- return next();
484
- }
485
- if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
486
- return next();
487
- }
488
- const contentTypeUid = context.contentType.uid;
489
- if (!contentTypeUid.startsWith("api::")) {
490
- return next();
491
- }
492
549
  const result = await next();
493
- const documentContext = {
494
- documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
495
- locale: context.params?.locale
496
- };
550
+ if (!shouldCreateHistoryVersion(context)) {
551
+ return result;
552
+ }
553
+ const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
497
554
  const defaultLocale = await serviceUtils.getDefaultLocale();
498
- const locale = documentContext.locale || defaultLocale;
499
- if (Array.isArray(locale)) {
500
- strapi2.log.warn(
501
- "[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
502
- );
503
- return next();
555
+ const locales = castArray(context.params?.locale || defaultLocale);
556
+ if (!locales.length) {
557
+ return result;
504
558
  }
505
- const document = await strapi2.documents(contentTypeUid).findOne({
506
- documentId: documentContext.documentId,
507
- locale,
508
- populate: serviceUtils.getDeepPopulate(contentTypeUid)
559
+ const uid2 = context.contentType.uid;
560
+ const schemas = getSchemas(uid2);
561
+ const model = strapi2.getModel(uid2);
562
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
563
+ const localeEntries = await strapi2.db.query(uid2).findMany({
564
+ where: {
565
+ documentId,
566
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
567
+ ...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
568
+ },
569
+ populate: serviceUtils.getDeepPopulate(
570
+ uid2,
571
+ true
572
+ /* use database syntax */
573
+ )
509
574
  });
510
- const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
511
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
512
- const componentsSchemas = Object.keys(
513
- attributesSchema
514
- ).reduce((currentComponentSchemas, key) => {
515
- const fieldSchema = attributesSchema[key];
516
- if (fieldSchema.type === "component") {
517
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
518
- return {
519
- ...currentComponentSchemas,
520
- [fieldSchema.component]: componentSchema
521
- };
522
- }
523
- return currentComponentSchemas;
524
- }, {});
525
575
  await strapi2.db.transaction(async ({ onCommit }) => {
526
- onCommit(() => {
527
- getService(strapi2, "history").createVersion({
528
- contentType: contentTypeUid,
529
- data: omit(FIELDS_TO_IGNORE, document),
530
- schema: omit(FIELDS_TO_IGNORE, attributesSchema),
531
- componentsSchemas,
532
- relatedDocumentId: documentContext.documentId,
533
- locale,
534
- status
535
- });
576
+ onCommit(async () => {
577
+ for (const entry of localeEntries) {
578
+ const status = await serviceUtils.getVersionStatus(uid2, entry);
579
+ await getService$1(strapi2, "history").createVersion({
580
+ contentType: uid2,
581
+ data: omit(FIELDS_TO_IGNORE, entry),
582
+ relatedDocumentId: documentId,
583
+ locale: entry.locale,
584
+ status,
585
+ ...schemas
586
+ });
587
+ }
536
588
  });
537
589
  });
538
590
  return result;
539
591
  });
540
- state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
592
+ state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
541
593
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
542
594
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
543
595
  strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
544
596
  where: {
545
597
  created_at: {
546
- $lt: expirationDate.toISOString()
598
+ $lt: expirationDate
547
599
  }
548
600
  }
601
+ }).catch((error) => {
602
+ if (error instanceof Error) {
603
+ strapi2.log.error("Error deleting expired history versions", error.message);
604
+ }
549
605
  });
550
606
  });
551
607
  state.isInitialized = true;
@@ -557,17 +613,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
557
613
  }
558
614
  };
559
615
  };
560
- const services$1 = {
616
+ const services$2 = {
561
617
  history: createHistoryService,
562
618
  lifecycles: createLifecyclesService
563
619
  };
564
- const info = { pluginName: "content-manager", type: "admin" };
620
+ const info$1 = { pluginName: "content-manager", type: "admin" };
565
621
  const historyVersionRouter = {
566
622
  type: "admin",
567
623
  routes: [
568
624
  {
569
625
  method: "GET",
570
- info,
626
+ info: info$1,
571
627
  path: "/history-versions",
572
628
  handler: "history-version.findMany",
573
629
  config: {
@@ -576,7 +632,7 @@ const historyVersionRouter = {
576
632
  },
577
633
  {
578
634
  method: "PUT",
579
- info,
635
+ info: info$1,
580
636
  path: "/history-versions/:versionId/restore",
581
637
  handler: "history-version.restoreVersion",
582
638
  config: {
@@ -585,7 +641,7 @@ const historyVersionRouter = {
585
641
  }
586
642
  ]
587
643
  };
588
- const routes$1 = {
644
+ const routes$2 = {
589
645
  "history-version": historyVersionRouter
590
646
  };
591
647
  const historyVersion = {
@@ -632,21 +688,21 @@ const historyVersion = {
632
688
  }
633
689
  }
634
690
  };
635
- const getFeature = () => {
691
+ const getFeature$1 = () => {
636
692
  if (strapi.ee.features.isEnabled("cms-content-history")) {
637
693
  return {
638
694
  register({ strapi: strapi2 }) {
639
695
  strapi2.get("models").add(historyVersion);
640
696
  },
641
697
  bootstrap({ strapi: strapi2 }) {
642
- getService(strapi2, "lifecycles").bootstrap();
698
+ getService$1(strapi2, "lifecycles").bootstrap();
643
699
  },
644
700
  destroy({ strapi: strapi2 }) {
645
- getService(strapi2, "lifecycles").destroy();
701
+ getService$1(strapi2, "lifecycles").destroy();
646
702
  },
647
- controllers: controllers$1,
648
- services: services$1,
649
- routes: routes$1
703
+ controllers: controllers$2,
704
+ services: services$2,
705
+ routes: routes$2
650
706
  };
651
707
  }
652
708
  return {
@@ -655,9 +711,201 @@ const getFeature = () => {
655
711
  }
656
712
  };
657
713
  };
658
- const history = getFeature();
714
+ const history = getFeature$1();
715
+ const info = { pluginName: "content-manager", type: "admin" };
716
+ const previewRouter = {
717
+ type: "admin",
718
+ routes: [
719
+ {
720
+ method: "GET",
721
+ info,
722
+ path: "/preview/url/:contentType",
723
+ handler: "preview.getPreviewUrl",
724
+ config: {
725
+ policies: ["admin::isAuthenticatedAdmin"]
726
+ }
727
+ }
728
+ ]
729
+ };
730
+ const routes$1 = {
731
+ preview: previewRouter
732
+ };
733
+ function getService(strapi2, name) {
734
+ return strapi2.service(`plugin::content-manager.${name}`);
735
+ }
736
+ const getPreviewUrlSchema = yup.object().shape({
737
+ // Will be undefined for single types
738
+ documentId: yup.string(),
739
+ locale: yup.string().nullable(),
740
+ status: yup.string()
741
+ }).required();
742
+ const validatePreviewUrl = async (strapi2, uid2, params) => {
743
+ await validateYupSchema(getPreviewUrlSchema)(params);
744
+ const newParams = pick(["documentId", "locale", "status"], params);
745
+ const model = strapi2.getModel(uid2);
746
+ if (!model || model.modelType !== "contentType") {
747
+ throw new errors.ValidationError("Invalid content type");
748
+ }
749
+ const isSingleType = model?.kind === "singleType";
750
+ if (!isSingleType && !params.documentId) {
751
+ throw new errors.ValidationError("documentId is required for Collection Types");
752
+ }
753
+ if (isSingleType) {
754
+ const doc = await strapi2.documents(uid2).findFirst();
755
+ if (!doc) {
756
+ throw new errors.NotFoundError("Document not found");
757
+ }
758
+ newParams.documentId = doc?.documentId;
759
+ }
760
+ if (!newParams.status) {
761
+ const isDPEnabled = model?.options?.draftAndPublish;
762
+ newParams.status = isDPEnabled ? "draft" : "published";
763
+ }
764
+ return newParams;
765
+ };
766
+ const createPreviewController = () => {
767
+ return {
768
+ /**
769
+ * Transforms an entry into a preview URL, so that it can be previewed
770
+ * in the Content Manager.
771
+ */
772
+ async getPreviewUrl(ctx) {
773
+ const uid2 = ctx.params.contentType;
774
+ const query = ctx.request.query;
775
+ const params = await validatePreviewUrl(strapi, uid2, query);
776
+ const previewService = getService(strapi, "preview");
777
+ const url = await previewService.getPreviewUrl(uid2, params);
778
+ if (!url) {
779
+ ctx.status = 204;
780
+ }
781
+ return {
782
+ data: { url }
783
+ };
784
+ }
785
+ };
786
+ };
787
+ const controllers$1 = {
788
+ preview: createPreviewController
789
+ /**
790
+ * Casting is needed because the types aren't aware that Strapi supports
791
+ * passing a controller factory as the value, instead of a controller object directly
792
+ */
793
+ };
794
+ const createPreviewService = ({ strapi: strapi2 }) => {
795
+ const config = getService(strapi2, "preview-config");
796
+ return {
797
+ async getPreviewUrl(uid2, params) {
798
+ const handler = config.getPreviewHandler();
799
+ try {
800
+ return handler(uid2, params);
801
+ } catch (error) {
802
+ strapi2.log.error(`Failed to get preview URL: ${error}`);
803
+ throw new errors.ApplicationError("Failed to get preview URL");
804
+ }
805
+ return;
806
+ }
807
+ };
808
+ };
809
+ const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
810
+ const middlewares = strapi.config.get("middlewares");
811
+ const configuredMiddlewares = middlewares.map((currentMiddleware) => {
812
+ if (currentMiddleware === middleware.name) {
813
+ return middleware;
814
+ }
815
+ if (currentMiddleware.name === middleware.name) {
816
+ return mergeWith(
817
+ (objValue, srcValue) => {
818
+ if (Array.isArray(objValue)) {
819
+ return objValue.concat(srcValue);
820
+ }
821
+ return void 0;
822
+ },
823
+ currentMiddleware,
824
+ middleware
825
+ );
826
+ }
827
+ return currentMiddleware;
828
+ });
829
+ strapi.config.set("middlewares", configuredMiddlewares);
830
+ };
831
+ const createPreviewConfigService = ({ strapi: strapi2 }) => {
832
+ return {
833
+ register() {
834
+ if (!this.isEnabled()) {
835
+ return;
836
+ }
837
+ const config = strapi2.config.get("admin.preview");
838
+ if (config.config?.allowedOrigins) {
839
+ extendMiddlewareConfiguration({
840
+ name: "strapi::security",
841
+ config: {
842
+ contentSecurityPolicy: {
843
+ directives: {
844
+ "frame-src": config.config.allowedOrigins
845
+ }
846
+ }
847
+ }
848
+ });
849
+ }
850
+ },
851
+ isEnabled() {
852
+ const config = strapi2.config.get("admin.preview");
853
+ if (!config) {
854
+ return false;
855
+ }
856
+ return config?.enabled ?? true;
857
+ },
858
+ /**
859
+ * Validate if the configuration is valid
860
+ */
861
+ validate() {
862
+ if (!this.isEnabled()) {
863
+ return;
864
+ }
865
+ const handler = this.getPreviewHandler();
866
+ if (typeof handler !== "function") {
867
+ throw new errors.ValidationError(
868
+ "Preview configuration is invalid. Handler must be a function"
869
+ );
870
+ }
871
+ },
872
+ /**
873
+ * Utility to get the preview handler from the configuration
874
+ */
875
+ getPreviewHandler() {
876
+ const config = strapi2.config.get("admin.preview");
877
+ const emptyHandler = () => {
878
+ return void 0;
879
+ };
880
+ if (!this.isEnabled()) {
881
+ return emptyHandler;
882
+ }
883
+ return config?.config?.handler || emptyHandler;
884
+ }
885
+ };
886
+ };
887
+ const services$1 = {
888
+ preview: createPreviewService,
889
+ "preview-config": createPreviewConfigService
890
+ };
891
+ const getFeature = () => {
892
+ return {
893
+ register() {
894
+ const config = getService(strapi, "preview-config");
895
+ config.validate();
896
+ config.register();
897
+ },
898
+ bootstrap() {
899
+ },
900
+ routes: routes$1,
901
+ controllers: controllers$1,
902
+ services: services$1
903
+ };
904
+ };
905
+ const preview = getFeature();
659
906
  const register = async ({ strapi: strapi2 }) => {
660
907
  await history.register?.({ strapi: strapi2 });
908
+ await preview.register?.({ strapi: strapi2 });
661
909
  };
662
910
  const ALLOWED_WEBHOOK_EVENTS = {
663
911
  ENTRY_PUBLISH: "entry.publish",
@@ -667,11 +915,12 @@ const bootstrap = async () => {
667
915
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
668
916
  strapi.get("webhookStore").addAllowedEvent(key, value);
669
917
  });
670
- getService$1("field-sizes").setCustomFieldInputSizes();
671
- await getService$1("components").syncConfigurations();
672
- await getService$1("content-types").syncConfigurations();
673
- await getService$1("permission").registerPermissions();
918
+ getService$2("field-sizes").setCustomFieldInputSizes();
919
+ await getService$2("components").syncConfigurations();
920
+ await getService$2("content-types").syncConfigurations();
921
+ await getService$2("permission").registerPermissions();
674
922
  await history.bootstrap?.({ strapi });
923
+ await preview.bootstrap?.({ strapi });
675
924
  };
676
925
  const destroy = async ({ strapi: strapi2 }) => {
677
926
  await history.destroy?.({ strapi: strapi2 });
@@ -1161,7 +1410,8 @@ const admin = {
1161
1410
  };
1162
1411
  const routes = {
1163
1412
  admin,
1164
- ...history.routes ? history.routes : {}
1413
+ ...history.routes ? history.routes : {},
1414
+ ...preview.routes ? preview.routes : {}
1165
1415
  };
1166
1416
  const hasPermissionsSchema = yup$1.object({
1167
1417
  actions: yup$1.array().of(yup$1.string()),
@@ -1172,6 +1422,11 @@ const { createPolicy } = policy;
1172
1422
  const hasPermissions = createPolicy({
1173
1423
  name: "plugin::content-manager.hasPermissions",
1174
1424
  validator: validateHasPermissionsInput,
1425
+ /**
1426
+ * NOTE: Action aliases are currently not checked at this level (policy).
1427
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1428
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1429
+ */
1175
1430
  handler(ctx, config = {}) {
1176
1431
  const { actions = [], hasAtLeastOne = false } = config;
1177
1432
  const { userAbility } = ctx.state;
@@ -1219,8 +1474,7 @@ const isSortable = (schema, name) => {
1219
1474
  if (!_.has(schema.attributes, name)) {
1220
1475
  return false;
1221
1476
  }
1222
- if (schema.modelType === "component" && name === "id")
1223
- return false;
1477
+ if (schema.modelType === "component" && name === "id") return false;
1224
1478
  const attribute = schema.attributes[name];
1225
1479
  if (NON_SORTABLES.includes(attribute.type)) {
1226
1480
  return false;
@@ -1365,8 +1619,7 @@ const createDefaultSettings = async (schema) => {
1365
1619
  };
1366
1620
  };
1367
1621
  const syncSettings = async (configuration, schema) => {
1368
- if (isEmpty(configuration.settings))
1369
- return createDefaultSettings(schema);
1622
+ if (isEmpty(configuration.settings)) return createDefaultSettings(schema);
1370
1623
  const defaultField = getDefaultMainField(schema);
1371
1624
  const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
1372
1625
  return {
@@ -1413,7 +1666,7 @@ const createMetadasSchema = (schema) => {
1413
1666
  if (!value) {
1414
1667
  return yup$1.string();
1415
1668
  }
1416
- const targetSchema = getService$1("content-types").findContentType(
1669
+ const targetSchema = getService$2("content-types").findContentType(
1417
1670
  schema.attributes[key].targetModel
1418
1671
  );
1419
1672
  if (!targetSchema) {
@@ -1542,8 +1795,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1542
1795
  }
1543
1796
  switch (attribute.type) {
1544
1797
  case "relation": {
1545
- if (canCreate(attributePath))
1546
- return body2;
1798
+ if (canCreate(attributePath)) return body2;
1547
1799
  return set(attributePath, { set: [] }, body2);
1548
1800
  }
1549
1801
  case "component": {
@@ -1553,8 +1805,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1553
1805
  ]);
1554
1806
  }
1555
1807
  default: {
1556
- if (canCreate(attributePath))
1557
- return body2;
1808
+ if (canCreate(attributePath)) return body2;
1558
1809
  return set(attributePath, null, body2);
1559
1810
  }
1560
1811
  }
@@ -1565,9 +1816,11 @@ const multipleLocaleSchema = yup$1.lazy(
1565
1816
  (value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
1566
1817
  );
1567
1818
  const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
1568
- const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
1819
+ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
1569
1820
  const { allowMultipleLocales } = opts;
1570
- const { locale, status, ...rest } = request || {};
1821
+ const { locale, status: providedStatus, ...rest } = request || {};
1822
+ const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
1823
+ const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
1571
1824
  const schema = yup$1.object().shape({
1572
1825
  locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
1573
1826
  status: statusSchema
@@ -1580,7 +1833,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
1580
1833
  }
1581
1834
  };
1582
1835
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1583
- const documentMetadata2 = getService$1("document-metadata");
1836
+ const documentMetadata2 = getService$2("document-metadata");
1584
1837
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1585
1838
  let {
1586
1839
  meta: { availableLocales, availableStatus }
@@ -1606,8 +1859,8 @@ const createDocument = async (ctx, opts) => {
1606
1859
  const { userAbility, user } = ctx.state;
1607
1860
  const { model } = ctx.params;
1608
1861
  const { body } = ctx.request;
1609
- const documentManager2 = getService$1("document-manager");
1610
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1862
+ const documentManager2 = getService$2("document-manager");
1863
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1611
1864
  if (permissionChecker2.cannot.create()) {
1612
1865
  throw new errors.ForbiddenError();
1613
1866
  }
@@ -1615,7 +1868,7 @@ const createDocument = async (ctx, opts) => {
1615
1868
  const setCreator = setCreatorFields({ user });
1616
1869
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1617
1870
  const sanitizedBody = await sanitizeFn(body);
1618
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(body);
1871
+ const { locale, status } = await getDocumentLocaleAndStatus(body, model);
1619
1872
  return documentManager2.create(model, {
1620
1873
  data: sanitizedBody,
1621
1874
  locale,
@@ -1627,14 +1880,14 @@ const updateDocument = async (ctx, opts) => {
1627
1880
  const { userAbility, user } = ctx.state;
1628
1881
  const { id, model } = ctx.params;
1629
1882
  const { body } = ctx.request;
1630
- const documentManager2 = getService$1("document-manager");
1631
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1883
+ const documentManager2 = getService$2("document-manager");
1884
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1632
1885
  if (permissionChecker2.cannot.update()) {
1633
1886
  throw new errors.ForbiddenError();
1634
1887
  }
1635
1888
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1636
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1637
- const { locale } = await getDocumentLocaleAndStatus(body);
1889
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1890
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1638
1891
  const [documentVersion, documentExists] = await Promise.all([
1639
1892
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
1640
1893
  documentManager2.exists(model, id)
@@ -1650,7 +1903,7 @@ const updateDocument = async (ctx, opts) => {
1650
1903
  throw new errors.ForbiddenError();
1651
1904
  }
1652
1905
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1653
- const setCreator = setCreatorFields({ user, isEdition: true });
1906
+ const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
1654
1907
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1655
1908
  const sanitizedBody = await sanitizeFn(body);
1656
1909
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1664,15 +1917,15 @@ const collectionTypes = {
1664
1917
  const { userAbility } = ctx.state;
1665
1918
  const { model } = ctx.params;
1666
1919
  const { query } = ctx.request;
1667
- const documentMetadata2 = getService$1("document-metadata");
1668
- const documentManager2 = getService$1("document-manager");
1669
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1920
+ const documentMetadata2 = getService$2("document-metadata");
1921
+ const documentManager2 = getService$2("document-manager");
1922
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1670
1923
  if (permissionChecker2.cannot.read()) {
1671
1924
  return ctx.forbidden();
1672
1925
  }
1673
1926
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1674
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1675
- const { locale, status } = await getDocumentLocaleAndStatus(query);
1927
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1928
+ const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1676
1929
  const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
1677
1930
  { ...permissionQuery, populate, locale, status },
1678
1931
  model
@@ -1700,14 +1953,14 @@ const collectionTypes = {
1700
1953
  async findOne(ctx) {
1701
1954
  const { userAbility } = ctx.state;
1702
1955
  const { model, id } = ctx.params;
1703
- const documentManager2 = getService$1("document-manager");
1704
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1956
+ const documentManager2 = getService$2("document-manager");
1957
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1705
1958
  if (permissionChecker2.cannot.read()) {
1706
1959
  return ctx.forbidden();
1707
1960
  }
1708
1961
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1709
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1710
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
1962
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1963
+ const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1711
1964
  const version = await documentManager2.findOne(id, model, {
1712
1965
  populate,
1713
1966
  locale,
@@ -1722,7 +1975,7 @@ const collectionTypes = {
1722
1975
  permissionChecker2,
1723
1976
  model,
1724
1977
  // @ts-expect-error TODO: fix
1725
- { id, locale, publishedAt: null },
1978
+ { documentId: id, locale, publishedAt: null },
1726
1979
  { availableLocales: true, availableStatus: false }
1727
1980
  );
1728
1981
  ctx.body = { data: {}, meta };
@@ -1737,7 +1990,7 @@ const collectionTypes = {
1737
1990
  async create(ctx) {
1738
1991
  const { userAbility } = ctx.state;
1739
1992
  const { model } = ctx.params;
1740
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1993
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1741
1994
  const [totalEntries, document] = await Promise.all([
1742
1995
  strapi.db.query(model).count(),
1743
1996
  createDocument(ctx)
@@ -1758,7 +2011,7 @@ const collectionTypes = {
1758
2011
  async update(ctx) {
1759
2012
  const { userAbility } = ctx.state;
1760
2013
  const { model } = ctx.params;
1761
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2014
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1762
2015
  const updatedVersion = await updateDocument(ctx);
1763
2016
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1764
2017
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1767,14 +2020,14 @@ const collectionTypes = {
1767
2020
  const { userAbility, user } = ctx.state;
1768
2021
  const { model, sourceId: id } = ctx.params;
1769
2022
  const { body } = ctx.request;
1770
- const documentManager2 = getService$1("document-manager");
1771
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2023
+ const documentManager2 = getService$2("document-manager");
2024
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1772
2025
  if (permissionChecker2.cannot.create()) {
1773
2026
  return ctx.forbidden();
1774
2027
  }
1775
2028
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1776
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1777
- const { locale } = await getDocumentLocaleAndStatus(body);
2029
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2030
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1778
2031
  const document = await documentManager2.findOne(id, model, {
1779
2032
  populate,
1780
2033
  locale,
@@ -1812,14 +2065,14 @@ const collectionTypes = {
1812
2065
  async delete(ctx) {
1813
2066
  const { userAbility } = ctx.state;
1814
2067
  const { id, model } = ctx.params;
1815
- const documentManager2 = getService$1("document-manager");
1816
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2068
+ const documentManager2 = getService$2("document-manager");
2069
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1817
2070
  if (permissionChecker2.cannot.delete()) {
1818
2071
  return ctx.forbidden();
1819
2072
  }
1820
2073
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1821
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1822
- const { locale } = await getDocumentLocaleAndStatus(ctx.query);
2074
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2075
+ const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1823
2076
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1824
2077
  if (documentLocales.length === 0) {
1825
2078
  return ctx.notFound();
@@ -1840,19 +2093,42 @@ const collectionTypes = {
1840
2093
  const { userAbility } = ctx.state;
1841
2094
  const { id, model } = ctx.params;
1842
2095
  const { body } = ctx.request;
1843
- const documentManager2 = getService$1("document-manager");
1844
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2096
+ const documentManager2 = getService$2("document-manager");
2097
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1845
2098
  if (permissionChecker2.cannot.publish()) {
1846
2099
  return ctx.forbidden();
1847
2100
  }
1848
2101
  const publishedDocument = await strapi.db.transaction(async () => {
1849
2102
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1850
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1851
- const document = id ? await updateDocument(ctx, { populate }) : await createDocument(ctx, { populate });
2103
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2104
+ let document;
2105
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2106
+ const isCreate = isNil$1(id);
2107
+ if (isCreate) {
2108
+ if (permissionChecker2.cannot.create()) {
2109
+ throw new errors.ForbiddenError();
2110
+ }
2111
+ document = await createDocument(ctx, { populate });
2112
+ }
2113
+ const isUpdate = !isCreate;
2114
+ if (isUpdate) {
2115
+ const documentExists = documentManager2.exists(model, id);
2116
+ if (!documentExists) {
2117
+ throw new errors.NotFoundError("Document not found");
2118
+ }
2119
+ document = await documentManager2.findOne(id, model, { populate, locale });
2120
+ if (!document) {
2121
+ if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
2122
+ throw new errors.ForbiddenError();
2123
+ }
2124
+ document = await updateDocument(ctx);
2125
+ } else if (permissionChecker2.can.update(document)) {
2126
+ await updateDocument(ctx);
2127
+ }
2128
+ }
1852
2129
  if (permissionChecker2.cannot.publish(document)) {
1853
2130
  throw new errors.ForbiddenError();
1854
2131
  }
1855
- const { locale } = await getDocumentLocaleAndStatus(body);
1856
2132
  const publishResult = await documentManager2.publish(document.documentId, model, {
1857
2133
  locale
1858
2134
  // TODO: Allow setting creator fields on publish
@@ -1872,14 +2148,16 @@ const collectionTypes = {
1872
2148
  const { body } = ctx.request;
1873
2149
  const { documentIds } = body;
1874
2150
  await validateBulkActionInput(body);
1875
- const documentManager2 = getService$1("document-manager");
1876
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2151
+ const documentManager2 = getService$2("document-manager");
2152
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1877
2153
  if (permissionChecker2.cannot.publish()) {
1878
2154
  return ctx.forbidden();
1879
2155
  }
1880
2156
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1881
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1882
- const { locale } = await getDocumentLocaleAndStatus(body, { allowMultipleLocales: true });
2157
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2158
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2159
+ allowMultipleLocales: true
2160
+ });
1883
2161
  const entityPromises = documentIds.map(
1884
2162
  (documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
1885
2163
  );
@@ -1901,12 +2179,14 @@ const collectionTypes = {
1901
2179
  const { body } = ctx.request;
1902
2180
  const { documentIds } = body;
1903
2181
  await validateBulkActionInput(body);
1904
- const documentManager2 = getService$1("document-manager");
1905
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2182
+ const documentManager2 = getService$2("document-manager");
2183
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1906
2184
  if (permissionChecker2.cannot.unpublish()) {
1907
2185
  return ctx.forbidden();
1908
2186
  }
1909
- const { locale } = await getDocumentLocaleAndStatus(body);
2187
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2188
+ allowMultipleLocales: true
2189
+ });
1910
2190
  const entityPromises = documentIds.map(
1911
2191
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1912
2192
  );
@@ -1929,8 +2209,8 @@ const collectionTypes = {
1929
2209
  const {
1930
2210
  body: { discardDraft, ...body }
1931
2211
  } = ctx.request;
1932
- const documentManager2 = getService$1("document-manager");
1933
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2212
+ const documentManager2 = getService$2("document-manager");
2213
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1934
2214
  if (permissionChecker2.cannot.unpublish()) {
1935
2215
  return ctx.forbidden();
1936
2216
  }
@@ -1938,8 +2218,8 @@ const collectionTypes = {
1938
2218
  return ctx.forbidden();
1939
2219
  }
1940
2220
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
1941
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1942
- const { locale } = await getDocumentLocaleAndStatus(body);
2221
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2222
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1943
2223
  const document = await documentManager2.findOne(id, model, {
1944
2224
  populate,
1945
2225
  locale,
@@ -1969,14 +2249,14 @@ const collectionTypes = {
1969
2249
  const { userAbility } = ctx.state;
1970
2250
  const { id, model } = ctx.params;
1971
2251
  const { body } = ctx.request;
1972
- const documentManager2 = getService$1("document-manager");
1973
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2252
+ const documentManager2 = getService$2("document-manager");
2253
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1974
2254
  if (permissionChecker2.cannot.discard()) {
1975
2255
  return ctx.forbidden();
1976
2256
  }
1977
2257
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
1978
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1979
- const { locale } = await getDocumentLocaleAndStatus(body);
2258
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2259
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1980
2260
  const document = await documentManager2.findOne(id, model, {
1981
2261
  populate,
1982
2262
  locale,
@@ -2000,14 +2280,14 @@ const collectionTypes = {
2000
2280
  const { query, body } = ctx.request;
2001
2281
  const { documentIds } = body;
2002
2282
  await validateBulkActionInput(body);
2003
- const documentManager2 = getService$1("document-manager");
2004
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2283
+ const documentManager2 = getService$2("document-manager");
2284
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2005
2285
  if (permissionChecker2.cannot.delete()) {
2006
2286
  return ctx.forbidden();
2007
2287
  }
2008
2288
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2009
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2010
- const { locale } = await getDocumentLocaleAndStatus(body);
2289
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2290
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2011
2291
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2012
2292
  populate,
2013
2293
  locale
@@ -2027,14 +2307,14 @@ const collectionTypes = {
2027
2307
  async countDraftRelations(ctx) {
2028
2308
  const { userAbility } = ctx.state;
2029
2309
  const { model, id } = ctx.params;
2030
- const documentManager2 = getService$1("document-manager");
2031
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2310
+ const documentManager2 = getService$2("document-manager");
2311
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2032
2312
  if (permissionChecker2.cannot.read()) {
2033
2313
  return ctx.forbidden();
2034
2314
  }
2035
2315
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2036
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2037
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
2316
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2317
+ const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2038
2318
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2039
2319
  if (!entity) {
2040
2320
  return ctx.notFound();
@@ -2052,8 +2332,8 @@ const collectionTypes = {
2052
2332
  const ids = ctx.request.query.documentIds;
2053
2333
  const locale = ctx.request.query.locale;
2054
2334
  const { model } = ctx.params;
2055
- const documentManager2 = getService$1("document-manager");
2056
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2335
+ const documentManager2 = getService$2("document-manager");
2336
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2057
2337
  if (permissionChecker2.cannot.read()) {
2058
2338
  return ctx.forbidden();
2059
2339
  }
@@ -2077,13 +2357,13 @@ const collectionTypes = {
2077
2357
  };
2078
2358
  const components$1 = {
2079
2359
  findComponents(ctx) {
2080
- const components2 = getService$1("components").findAllComponents();
2081
- const { toDto } = getService$1("data-mapper");
2360
+ const components2 = getService$2("components").findAllComponents();
2361
+ const { toDto } = getService$2("data-mapper");
2082
2362
  ctx.body = { data: components2.map(toDto) };
2083
2363
  },
2084
2364
  async findComponentConfiguration(ctx) {
2085
2365
  const { uid: uid2 } = ctx.params;
2086
- const componentService = getService$1("components");
2366
+ const componentService = getService$2("components");
2087
2367
  const component = componentService.findComponent(uid2);
2088
2368
  if (!component) {
2089
2369
  return ctx.notFound("component.notFound");
@@ -2100,7 +2380,7 @@ const components$1 = {
2100
2380
  async updateComponentConfiguration(ctx) {
2101
2381
  const { uid: uid2 } = ctx.params;
2102
2382
  const { body } = ctx.request;
2103
- const componentService = getService$1("components");
2383
+ const componentService = getService$2("components");
2104
2384
  const component = componentService.findComponent(uid2);
2105
2385
  if (!component) {
2106
2386
  return ctx.notFound("component.notFound");
@@ -2134,12 +2414,12 @@ const contentTypes = {
2134
2414
  } catch (error) {
2135
2415
  return ctx.send({ error }, 400);
2136
2416
  }
2137
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2138
- const { toDto } = getService$1("data-mapper");
2417
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2418
+ const { toDto } = getService$2("data-mapper");
2139
2419
  ctx.body = { data: contentTypes2.map(toDto) };
2140
2420
  },
2141
2421
  async findContentTypesSettings(ctx) {
2142
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2422
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2143
2423
  const contentTypes2 = await findAllContentTypes();
2144
2424
  const configurations = await Promise.all(
2145
2425
  contentTypes2.map(async (contentType) => {
@@ -2153,7 +2433,7 @@ const contentTypes = {
2153
2433
  },
2154
2434
  async findContentTypeConfiguration(ctx) {
2155
2435
  const { uid: uid2 } = ctx.params;
2156
- const contentTypeService = getService$1("content-types");
2436
+ const contentTypeService = getService$2("content-types");
2157
2437
  const contentType = await contentTypeService.findContentType(uid2);
2158
2438
  if (!contentType) {
2159
2439
  return ctx.notFound("contentType.notFound");
@@ -2175,13 +2455,13 @@ const contentTypes = {
2175
2455
  const { userAbility } = ctx.state;
2176
2456
  const { uid: uid2 } = ctx.params;
2177
2457
  const { body } = ctx.request;
2178
- const contentTypeService = getService$1("content-types");
2179
- const metricsService = getService$1("metrics");
2458
+ const contentTypeService = getService$2("content-types");
2459
+ const metricsService = getService$2("metrics");
2180
2460
  const contentType = await contentTypeService.findContentType(uid2);
2181
2461
  if (!contentType) {
2182
2462
  return ctx.notFound("contentType.notFound");
2183
2463
  }
2184
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2464
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2185
2465
  return ctx.forbidden();
2186
2466
  }
2187
2467
  let input;
@@ -2214,10 +2494,10 @@ const contentTypes = {
2214
2494
  };
2215
2495
  const init = {
2216
2496
  getInitData(ctx) {
2217
- const { toDto } = getService$1("data-mapper");
2218
- const { findAllComponents } = getService$1("components");
2219
- const { getAllFieldSizes } = getService$1("field-sizes");
2220
- const { findAllContentTypes } = getService$1("content-types");
2497
+ const { toDto } = getService$2("data-mapper");
2498
+ const { findAllComponents } = getService$2("components");
2499
+ const { getAllFieldSizes } = getService$2("field-sizes");
2500
+ const { findAllContentTypes } = getService$2("content-types");
2221
2501
  ctx.body = {
2222
2502
  data: {
2223
2503
  fieldSizes: getAllFieldSizes(),
@@ -2253,36 +2533,41 @@ const addFiltersClause = (params, filtersClause) => {
2253
2533
  params.filters.$and.push(filtersClause);
2254
2534
  };
2255
2535
  const sanitizeMainField = (model, mainField, userAbility) => {
2256
- const permissionChecker2 = getService$1("permission-checker").create({
2536
+ const permissionChecker2 = getService$2("permission-checker").create({
2257
2537
  userAbility,
2258
2538
  model: model.uid
2259
2539
  });
2260
- if (!isListable(model, mainField)) {
2540
+ const isMainFieldListable = isListable(model, mainField);
2541
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2542
+ if (!isMainFieldListable || !canReadMainField) {
2261
2543
  return "id";
2262
2544
  }
2263
- if (permissionChecker2.cannot.read(null, mainField)) {
2264
- if (model.uid === "plugin::users-permissions.role") {
2265
- const userPermissionChecker = getService$1("permission-checker").create({
2266
- userAbility,
2267
- model: "plugin::users-permissions.user"
2268
- });
2269
- if (userPermissionChecker.can.read()) {
2270
- return "name";
2271
- }
2272
- }
2273
- return "id";
2545
+ if (model.uid === "plugin::users-permissions.role") {
2546
+ return "name";
2274
2547
  }
2275
2548
  return mainField;
2276
2549
  };
2277
- const addStatusToRelations = async (uid2, relations2) => {
2278
- if (!contentTypes$1.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2550
+ const addStatusToRelations = async (targetUid, relations2) => {
2551
+ if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
2552
+ return relations2;
2553
+ }
2554
+ const documentMetadata2 = getService$2("document-metadata");
2555
+ if (!relations2.length) {
2279
2556
  return relations2;
2280
2557
  }
2281
- const documentMetadata2 = getService$1("document-metadata");
2282
- const documentsAvailableStatus = await documentMetadata2.getManyAvailableStatus(uid2, relations2);
2558
+ const firstRelation = relations2[0];
2559
+ const filters = {
2560
+ documentId: { $in: relations2.map((r) => r.documentId) },
2561
+ // NOTE: find the "opposite" status
2562
+ publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
2563
+ };
2564
+ const availableStatus = await strapi.query(targetUid).findMany({
2565
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
2566
+ filters
2567
+ });
2283
2568
  return relations2.map((relation) => {
2284
- const availableStatuses = documentsAvailableStatus.filter(
2285
- (availableDocument) => availableDocument.documentId === relation.documentId
2569
+ const availableStatuses = availableStatus.filter(
2570
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2286
2571
  );
2287
2572
  return {
2288
2573
  ...relation,
@@ -2303,11 +2588,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2303
2588
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2304
2589
  const isSourceLocalized = isLocalized(sourceModel);
2305
2590
  const isTargetLocalized = isLocalized(targetModel);
2306
- let validatedLocale = locale;
2307
- if (!targetModel || !isTargetLocalized)
2308
- validatedLocale = void 0;
2309
2591
  return {
2310
- locale: validatedLocale,
2592
+ locale,
2311
2593
  isSourceLocalized,
2312
2594
  isTargetLocalized
2313
2595
  };
@@ -2316,8 +2598,7 @@ const validateStatus = (sourceUid, status) => {
2316
2598
  const sourceModel = strapi.getModel(sourceUid);
2317
2599
  const isDP = contentTypes$1.hasDraftAndPublish;
2318
2600
  const isSourceDP = isDP(sourceModel);
2319
- if (!isSourceDP)
2320
- return { status: void 0 };
2601
+ if (!isSourceDP) return { status: void 0 };
2321
2602
  switch (status) {
2322
2603
  case "published":
2323
2604
  return { status: "published" };
@@ -2347,7 +2628,7 @@ const relations = {
2347
2628
  ctx.request?.query?.locale
2348
2629
  );
2349
2630
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2350
- const permissionChecker2 = getService$1("permission-checker").create({
2631
+ const permissionChecker2 = getService$2("permission-checker").create({
2351
2632
  userAbility,
2352
2633
  model
2353
2634
  });
@@ -2372,7 +2653,7 @@ const relations = {
2372
2653
  where.id = id;
2373
2654
  }
2374
2655
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2375
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2656
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2376
2657
  const currentEntity = await strapi.db.query(model).findOne({
2377
2658
  where,
2378
2659
  populate
@@ -2387,7 +2668,7 @@ const relations = {
2387
2668
  }
2388
2669
  entryId = currentEntity.id;
2389
2670
  }
2390
- const modelConfig = isComponent2 ? await getService$1("components").findConfiguration(sourceSchema) : await getService$1("content-types").findConfiguration(sourceSchema);
2671
+ const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
2391
2672
  const targetSchema = strapi.getModel(targetUid);
2392
2673
  const mainField = flow(
2393
2674
  prop(`metadatas.${targetField}.edit.mainField`),
@@ -2410,7 +2691,7 @@ const relations = {
2410
2691
  attribute,
2411
2692
  fieldsToSelect,
2412
2693
  mainField,
2413
- source: { schema: sourceSchema },
2694
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2414
2695
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2415
2696
  sourceSchema,
2416
2697
  targetSchema,
@@ -2432,7 +2713,8 @@ const relations = {
2432
2713
  fieldsToSelect,
2433
2714
  mainField,
2434
2715
  source: {
2435
- schema: { uid: sourceUid, modelType: sourceModelType }
2716
+ schema: { uid: sourceUid, modelType: sourceModelType },
2717
+ isLocalized: isSourceLocalized
2436
2718
  },
2437
2719
  target: {
2438
2720
  schema: { uid: targetUid },
@@ -2440,7 +2722,7 @@ const relations = {
2440
2722
  }
2441
2723
  } = await this.extractAndValidateRequestInfo(ctx, id);
2442
2724
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2443
- const permissionChecker2 = getService$1("permission-checker").create({
2725
+ const permissionChecker2 = getService$2("permission-checker").create({
2444
2726
  userAbility: ctx.state.userAbility,
2445
2727
  model: targetUid
2446
2728
  });
@@ -2470,12 +2752,16 @@ const relations = {
2470
2752
  } else {
2471
2753
  where.id = id;
2472
2754
  }
2473
- if (status) {
2474
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2755
+ const publishedAt = getPublishedAtClause(status, targetUid);
2756
+ if (!isEmpty(publishedAt)) {
2757
+ where[`${alias}.published_at`] = publishedAt;
2475
2758
  }
2476
- if (filterByLocale) {
2759
+ if (isTargetLocalized && locale) {
2477
2760
  where[`${alias}.locale`] = locale;
2478
2761
  }
2762
+ if (isSourceLocalized && locale) {
2763
+ where.locale = locale;
2764
+ }
2479
2765
  if ((idsToInclude?.length ?? 0) !== 0) {
2480
2766
  where[`${alias}.id`].$notIn = idsToInclude;
2481
2767
  }
@@ -2493,7 +2779,8 @@ const relations = {
2493
2779
  id: { $notIn: uniq(idsToOmit) }
2494
2780
  });
2495
2781
  }
2496
- const res = await strapi.db.query(targetUid).findPage(strapi.get("query-params").transform(targetUid, queryParams));
2782
+ const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
2783
+ const res = await strapi.db.query(targetUid).findPage(dbQuery);
2497
2784
  ctx.body = {
2498
2785
  ...res,
2499
2786
  results: await addStatusToRelations(targetUid, res.results)
@@ -2508,29 +2795,39 @@ const relations = {
2508
2795
  attribute,
2509
2796
  targetField,
2510
2797
  fieldsToSelect,
2511
- source: {
2512
- schema: { uid: sourceUid }
2513
- },
2514
- target: {
2515
- schema: { uid: targetUid }
2516
- }
2798
+ status,
2799
+ source: { schema: sourceSchema },
2800
+ target: { schema: targetSchema }
2517
2801
  } = await this.extractAndValidateRequestInfo(ctx, id);
2518
- const permissionQuery = await getService$1("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2802
+ const { uid: sourceUid } = sourceSchema;
2803
+ const { uid: targetUid } = targetSchema;
2804
+ const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2519
2805
  const dbQuery = strapi.db.query(sourceUid);
2520
2806
  const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
2807
+ const filters = {};
2808
+ if (sourceSchema?.options?.draftAndPublish) {
2809
+ if (targetSchema?.options?.draftAndPublish) {
2810
+ if (status === "published") {
2811
+ filters.publishedAt = { $notNull: true };
2812
+ } else {
2813
+ filters.publishedAt = { $null: true };
2814
+ }
2815
+ }
2816
+ } else if (targetSchema?.options?.draftAndPublish) {
2817
+ filters.publishedAt = { $null: true };
2818
+ }
2521
2819
  const res = await loadRelations({ id: entryId }, targetField, {
2522
- select: ["id", "documentId", "locale", "publishedAt"],
2820
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2523
2821
  ordering: "desc",
2524
2822
  page: ctx.request.query.page,
2525
- pageSize: ctx.request.query.pageSize
2823
+ pageSize: ctx.request.query.pageSize,
2824
+ filters
2526
2825
  });
2527
2826
  const loadedIds = res.results.map((item) => item.id);
2528
2827
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2529
2828
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2530
2829
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2531
- ordering: "desc",
2532
- page: ctx.request.query.page,
2533
- pageSize: ctx.request.query.pageSize
2830
+ ordering: "desc"
2534
2831
  });
2535
2832
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2536
2833
  ctx.body = {
@@ -2545,10 +2842,10 @@ const relations = {
2545
2842
  }
2546
2843
  };
2547
2844
  const buildPopulateFromQuery = async (query, model) => {
2548
- return getService$1("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2845
+ return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2549
2846
  };
2550
2847
  const findDocument = async (query, uid2, opts = {}) => {
2551
- const documentManager2 = getService$1("document-manager");
2848
+ const documentManager2 = getService$2("document-manager");
2552
2849
  const populate = await buildPopulateFromQuery(query, uid2);
2553
2850
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2554
2851
  };
@@ -2556,13 +2853,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
2556
2853
  const { user, userAbility } = ctx.state;
2557
2854
  const { model } = ctx.params;
2558
2855
  const { body, query } = ctx.request;
2559
- const documentManager2 = getService$1("document-manager");
2560
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2856
+ const documentManager2 = getService$2("document-manager");
2857
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2561
2858
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2562
2859
  throw new errors.ForbiddenError();
2563
2860
  }
2564
2861
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
2565
- const { locale } = await getDocumentLocaleAndStatus(body);
2862
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2566
2863
  const [documentVersion, otherDocumentVersion] = await Promise.all([
2567
2864
  findDocument(sanitizedQuery, model, { locale, status: "draft" }),
2568
2865
  // Find the first document to check if it exists
@@ -2598,12 +2895,12 @@ const singleTypes = {
2598
2895
  const { userAbility } = ctx.state;
2599
2896
  const { model } = ctx.params;
2600
2897
  const { query = {} } = ctx.request;
2601
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2898
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2602
2899
  if (permissionChecker2.cannot.read()) {
2603
2900
  return ctx.forbidden();
2604
2901
  }
2605
2902
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
2606
- const { locale, status } = await getDocumentLocaleAndStatus(query);
2903
+ const { locale, status } = await getDocumentLocaleAndStatus(query, model);
2607
2904
  const version = await findDocument(permissionQuery, model, { locale, status });
2608
2905
  if (!version) {
2609
2906
  if (permissionChecker2.cannot.create()) {
@@ -2617,7 +2914,7 @@ const singleTypes = {
2617
2914
  permissionChecker2,
2618
2915
  model,
2619
2916
  // @ts-expect-error - fix types
2620
- { id: document.documentId, locale, publishedAt: null },
2917
+ { documentId: document.documentId, locale, publishedAt: null },
2621
2918
  { availableLocales: true, availableStatus: false }
2622
2919
  );
2623
2920
  ctx.body = { data: {}, meta };
@@ -2632,7 +2929,7 @@ const singleTypes = {
2632
2929
  async createOrUpdate(ctx) {
2633
2930
  const { userAbility } = ctx.state;
2634
2931
  const { model } = ctx.params;
2635
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2932
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2636
2933
  const document = await createOrUpdateDocument(ctx);
2637
2934
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2638
2935
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2641,14 +2938,14 @@ const singleTypes = {
2641
2938
  const { userAbility } = ctx.state;
2642
2939
  const { model } = ctx.params;
2643
2940
  const { query = {} } = ctx.request;
2644
- const documentManager2 = getService$1("document-manager");
2645
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2941
+ const documentManager2 = getService$2("document-manager");
2942
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2646
2943
  if (permissionChecker2.cannot.delete()) {
2647
2944
  return ctx.forbidden();
2648
2945
  }
2649
2946
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
2650
2947
  const populate = await buildPopulateFromQuery(sanitizedQuery, model);
2651
- const { locale } = await getDocumentLocaleAndStatus(query);
2948
+ const { locale } = await getDocumentLocaleAndStatus(query, model);
2652
2949
  const documentLocales = await documentManager2.findLocales(void 0, model, {
2653
2950
  populate,
2654
2951
  locale
@@ -2670,8 +2967,8 @@ const singleTypes = {
2670
2967
  const { userAbility } = ctx.state;
2671
2968
  const { model } = ctx.params;
2672
2969
  const { query = {} } = ctx.request;
2673
- const documentManager2 = getService$1("document-manager");
2674
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2970
+ const documentManager2 = getService$2("document-manager");
2971
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2675
2972
  if (permissionChecker2.cannot.publish()) {
2676
2973
  return ctx.forbidden();
2677
2974
  }
@@ -2685,7 +2982,7 @@ const singleTypes = {
2685
2982
  if (permissionChecker2.cannot.publish(document)) {
2686
2983
  throw new errors.ForbiddenError();
2687
2984
  }
2688
- const { locale } = await getDocumentLocaleAndStatus(document);
2985
+ const { locale } = await getDocumentLocaleAndStatus(document, model);
2689
2986
  const publishResult = await documentManager2.publish(document.documentId, model, { locale });
2690
2987
  return publishResult.at(0);
2691
2988
  });
@@ -2699,8 +2996,8 @@ const singleTypes = {
2699
2996
  body: { discardDraft, ...body },
2700
2997
  query = {}
2701
2998
  } = ctx.request;
2702
- const documentManager2 = getService$1("document-manager");
2703
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2999
+ const documentManager2 = getService$2("document-manager");
3000
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2704
3001
  if (permissionChecker2.cannot.unpublish()) {
2705
3002
  return ctx.forbidden();
2706
3003
  }
@@ -2708,7 +3005,7 @@ const singleTypes = {
2708
3005
  return ctx.forbidden();
2709
3006
  }
2710
3007
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
2711
- const { locale } = await getDocumentLocaleAndStatus(body);
3008
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2712
3009
  const document = await findDocument(sanitizedQuery, model, { locale });
2713
3010
  if (!document) {
2714
3011
  return ctx.notFound();
@@ -2734,13 +3031,13 @@ const singleTypes = {
2734
3031
  const { userAbility } = ctx.state;
2735
3032
  const { model } = ctx.params;
2736
3033
  const { body, query = {} } = ctx.request;
2737
- const documentManager2 = getService$1("document-manager");
2738
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3034
+ const documentManager2 = getService$2("document-manager");
3035
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2739
3036
  if (permissionChecker2.cannot.discard()) {
2740
3037
  return ctx.forbidden();
2741
3038
  }
2742
3039
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
2743
- const { locale } = await getDocumentLocaleAndStatus(body);
3040
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2744
3041
  const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
2745
3042
  if (!document) {
2746
3043
  return ctx.notFound();
@@ -2758,9 +3055,9 @@ const singleTypes = {
2758
3055
  const { userAbility } = ctx.state;
2759
3056
  const { model } = ctx.params;
2760
3057
  const { query } = ctx.request;
2761
- const documentManager2 = getService$1("document-manager");
2762
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2763
- const { locale } = await getDocumentLocaleAndStatus(query);
3058
+ const documentManager2 = getService$2("document-manager");
3059
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
3060
+ const { locale } = await getDocumentLocaleAndStatus(query, model);
2764
3061
  if (permissionChecker2.cannot.read()) {
2765
3062
  return ctx.forbidden();
2766
3063
  }
@@ -2781,9 +3078,9 @@ const uid$1 = {
2781
3078
  async generateUID(ctx) {
2782
3079
  const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
2783
3080
  const { query = {} } = ctx.request;
2784
- const { locale } = await getDocumentLocaleAndStatus(query);
3081
+ const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2785
3082
  await validateUIDField(contentTypeUID, field);
2786
- const uidService = getService$1("uid");
3083
+ const uidService = getService$2("uid");
2787
3084
  ctx.body = {
2788
3085
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2789
3086
  };
@@ -2793,9 +3090,9 @@ const uid$1 = {
2793
3090
  ctx.request.body
2794
3091
  );
2795
3092
  const { query = {} } = ctx.request;
2796
- const { locale } = await getDocumentLocaleAndStatus(query);
3093
+ const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2797
3094
  await validateUIDField(contentTypeUID, field);
2798
- const uidService = getService$1("uid");
3095
+ const uidService = getService$2("uid");
2799
3096
  const isAvailable = await uidService.checkUIDAvailability({
2800
3097
  contentTypeUID,
2801
3098
  field,
@@ -2816,7 +3113,8 @@ const controllers = {
2816
3113
  relations,
2817
3114
  "single-types": singleTypes,
2818
3115
  uid: uid$1,
2819
- ...history.controllers ? history.controllers : {}
3116
+ ...history.controllers ? history.controllers : {},
3117
+ ...preview.controllers ? preview.controllers : {}
2820
3118
  };
2821
3119
  const keys = {
2822
3120
  CONFIGURATION: "configuration"
@@ -2945,18 +3243,15 @@ async function syncMetadatas(configuration, schema) {
2945
3243
  _.set(updatedMeta, ["list", "searchable"], false);
2946
3244
  _.set(acc, [key], updatedMeta);
2947
3245
  }
2948
- if (!_.has(edit, "mainField"))
2949
- return acc;
3246
+ if (!_.has(edit, "mainField")) return acc;
2950
3247
  if (!isRelation$1(attr)) {
2951
3248
  _.set(updatedMeta, "edit", _.omit(edit, ["mainField"]));
2952
3249
  _.set(acc, [key], updatedMeta);
2953
3250
  return acc;
2954
3251
  }
2955
- if (edit.mainField === "id")
2956
- return acc;
3252
+ if (edit.mainField === "id") return acc;
2957
3253
  const targetSchema = getTargetSchema(attr.targetModel);
2958
- if (!targetSchema)
2959
- return acc;
3254
+ if (!targetSchema) return acc;
2960
3255
  if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
2961
3256
  _.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
2962
3257
  _.set(acc, [key], updatedMeta);
@@ -2967,12 +3262,12 @@ async function syncMetadatas(configuration, schema) {
2967
3262
  return _.assign(metasWithDefaults, updatedMetas);
2968
3263
  }
2969
3264
  const getTargetSchema = (targetModel) => {
2970
- return getService$1("content-types").findContentType(targetModel);
3265
+ return getService$2("content-types").findContentType(targetModel);
2971
3266
  };
2972
3267
  const DEFAULT_LIST_LENGTH = 4;
2973
3268
  const MAX_ROW_SIZE = 12;
2974
3269
  const isAllowedFieldSize = (type, size) => {
2975
- const { getFieldSize } = getService$1("field-sizes");
3270
+ const { getFieldSize } = getService$2("field-sizes");
2976
3271
  const fieldSize = getFieldSize(type);
2977
3272
  if (!fieldSize.isResizable && size !== fieldSize.default) {
2978
3273
  return false;
@@ -2980,7 +3275,7 @@ const isAllowedFieldSize = (type, size) => {
2980
3275
  return size <= MAX_ROW_SIZE;
2981
3276
  };
2982
3277
  const getDefaultFieldSize = (attribute) => {
2983
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3278
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
2984
3279
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
2985
3280
  };
2986
3281
  async function createDefaultLayouts(schema) {
@@ -3001,8 +3296,7 @@ function createDefaultEditLayout(schema) {
3001
3296
  return appendToEditLayout([], keys2, schema);
3002
3297
  }
3003
3298
  function syncLayouts(configuration, schema) {
3004
- if (_.isEmpty(configuration.layouts))
3005
- return createDefaultLayouts(schema);
3299
+ if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
3006
3300
  const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
3007
3301
  let cleanList = list.filter((attr) => isListable(schema, attr));
3008
3302
  const cleanEditRelations = editRelations.filter(
@@ -3013,9 +3307,8 @@ function syncLayouts(configuration, schema) {
3013
3307
  for (const row of edit) {
3014
3308
  const newRow = [];
3015
3309
  for (const el of row) {
3016
- if (!hasEditableAttribute(schema, el.name))
3017
- continue;
3018
- const { hasFieldSize } = getService$1("field-sizes");
3310
+ if (!hasEditableAttribute(schema, el.name)) continue;
3311
+ const { hasFieldSize } = getService$2("field-sizes");
3019
3312
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3020
3313
  if (!isAllowedFieldSize(fieldType, el.size)) {
3021
3314
  elementsToReAppend.push(el.name);
@@ -3045,8 +3338,7 @@ function syncLayouts(configuration, schema) {
3045
3338
  };
3046
3339
  }
3047
3340
  const appendToEditLayout = (layout = [], keysToAppend, schema) => {
3048
- if (keysToAppend.length === 0)
3049
- return layout;
3341
+ if (keysToAppend.length === 0) return layout;
3050
3342
  let currentRowIndex = Math.max(layout.length - 1, 0);
3051
3343
  if (!layout[currentRowIndex]) {
3052
3344
  layout[currentRowIndex] = [];
@@ -3155,17 +3447,17 @@ const configurationService$1 = createConfigurationService({
3155
3447
  isComponent: true,
3156
3448
  prefix: STORE_KEY_PREFIX,
3157
3449
  getModels() {
3158
- const { toContentManagerModel } = getService$1("data-mapper");
3450
+ const { toContentManagerModel } = getService$2("data-mapper");
3159
3451
  return mapValues(toContentManagerModel, strapi.components);
3160
3452
  }
3161
3453
  });
3162
3454
  const components = ({ strapi: strapi2 }) => ({
3163
3455
  findAllComponents() {
3164
- const { toContentManagerModel } = getService$1("data-mapper");
3456
+ const { toContentManagerModel } = getService$2("data-mapper");
3165
3457
  return Object.values(strapi2.components).map(toContentManagerModel);
3166
3458
  },
3167
3459
  findComponent(uid2) {
3168
- const { toContentManagerModel } = getService$1("data-mapper");
3460
+ const { toContentManagerModel } = getService$2("data-mapper");
3169
3461
  const component = strapi2.components[uid2];
3170
3462
  return isNil$1(component) ? component : toContentManagerModel(component);
3171
3463
  },
@@ -3216,17 +3508,17 @@ const configurationService = createConfigurationService({
3216
3508
  storeUtils,
3217
3509
  prefix: "content_types",
3218
3510
  getModels() {
3219
- const { toContentManagerModel } = getService$1("data-mapper");
3511
+ const { toContentManagerModel } = getService$2("data-mapper");
3220
3512
  return mapValues(toContentManagerModel, strapi.contentTypes);
3221
3513
  }
3222
3514
  });
3223
3515
  const service = ({ strapi: strapi2 }) => ({
3224
3516
  findAllContentTypes() {
3225
- const { toContentManagerModel } = getService$1("data-mapper");
3517
+ const { toContentManagerModel } = getService$2("data-mapper");
3226
3518
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3227
3519
  },
3228
3520
  findContentType(uid2) {
3229
- const { toContentManagerModel } = getService$1("data-mapper");
3521
+ const { toContentManagerModel } = getService$2("data-mapper");
3230
3522
  const contentType = strapi2.contentTypes[uid2];
3231
3523
  return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
3232
3524
  },
@@ -3255,7 +3547,7 @@ const service = ({ strapi: strapi2 }) => ({
3255
3547
  return this.findConfiguration(contentType);
3256
3548
  },
3257
3549
  findComponentsConfigurations(contentType) {
3258
- return getService$1("components").findComponentsConfigurations(contentType);
3550
+ return getService$2("components").findComponentsConfigurations(contentType);
3259
3551
  },
3260
3552
  syncConfigurations() {
3261
3553
  return configurationService.syncConfigurations();
@@ -3436,12 +3728,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3436
3728
  ability: userAbility,
3437
3729
  model
3438
3730
  });
3439
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3731
+ const { actionProvider } = strapi2.service("admin::permission");
3732
+ const toSubject = (entity) => {
3733
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3734
+ };
3440
3735
  const can = (action, entity, field) => {
3441
- return userAbility.can(action, toSubject(entity), field);
3736
+ const subject = toSubject(entity);
3737
+ const aliases = actionProvider.unstable_aliases(action, model);
3738
+ return (
3739
+ // Test the original action to see if it passes
3740
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3741
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3742
+ );
3442
3743
  };
3443
3744
  const cannot = (action, entity, field) => {
3444
- return userAbility.cannot(action, toSubject(entity), field);
3745
+ const subject = toSubject(entity);
3746
+ const aliases = actionProvider.unstable_aliases(action, model);
3747
+ return (
3748
+ // Test both the original action
3749
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3750
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3751
+ );
3445
3752
  };
3446
3753
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3447
3754
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3512,7 +3819,7 @@ const permission = ({ strapi: strapi2 }) => ({
3512
3819
  return userAbility.can(action);
3513
3820
  },
3514
3821
  async registerPermissions() {
3515
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3822
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3516
3823
  const contentTypesUids = displayedContentTypes.map(prop("uid"));
3517
3824
  const actions = [
3518
3825
  {
@@ -3597,6 +3904,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
3597
3904
  if (initialPopulate) {
3598
3905
  return initialPopulate;
3599
3906
  }
3907
+ if (attributeName === "localizations") {
3908
+ const validationPopulate = getPopulateForValidation(model.uid);
3909
+ return {
3910
+ populate: validationPopulate.populate
3911
+ };
3912
+ }
3600
3913
  if (!isVisibleAttribute$1(model, attributeName)) {
3601
3914
  return true;
3602
3915
  }
@@ -3656,6 +3969,9 @@ const getDeepPopulate = (uid2, {
3656
3969
  return {};
3657
3970
  }
3658
3971
  const model = strapi.getModel(uid2);
3972
+ if (!model) {
3973
+ return {};
3974
+ }
3659
3975
  return Object.keys(model.attributes).reduce(
3660
3976
  (populateAcc, attributeName) => merge(
3661
3977
  populateAcc,
@@ -3675,40 +3991,46 @@ const getDeepPopulate = (uid2, {
3675
3991
  {}
3676
3992
  );
3677
3993
  };
3678
- const getValidatableFieldsPopulate = (uid2, {
3679
- initialPopulate = {},
3680
- countMany = false,
3681
- countOne = false,
3682
- maxLevel = Infinity
3683
- } = {}, level = 1) => {
3684
- if (level > maxLevel) {
3994
+ const getPopulateForValidation = (uid2) => {
3995
+ const model = strapi.getModel(uid2);
3996
+ if (!model) {
3685
3997
  return {};
3686
3998
  }
3687
- const model = strapi.getModel(uid2);
3688
3999
  return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
3689
- if (!getDoesAttributeRequireValidation(attribute)) {
4000
+ if (isScalarAttribute(attribute)) {
4001
+ if (getDoesAttributeRequireValidation(attribute)) {
4002
+ populateAcc.fields = populateAcc.fields || [];
4003
+ populateAcc.fields.push(attributeName);
4004
+ }
3690
4005
  return populateAcc;
3691
4006
  }
3692
- if (isScalarAttribute(attribute)) {
3693
- return merge(populateAcc, {
3694
- [attributeName]: true
3695
- });
4007
+ if (isComponent(attribute)) {
4008
+ const component = attribute.component;
4009
+ const componentResult = getPopulateForValidation(component);
4010
+ if (Object.keys(componentResult).length > 0) {
4011
+ populateAcc.populate = populateAcc.populate || {};
4012
+ populateAcc.populate[attributeName] = componentResult;
4013
+ }
4014
+ return populateAcc;
3696
4015
  }
3697
- return merge(
3698
- populateAcc,
3699
- getPopulateFor(
3700
- attributeName,
3701
- model,
3702
- {
3703
- // @ts-expect-error - improve types
3704
- initialPopulate: initialPopulate?.[attributeName],
3705
- countMany,
3706
- countOne,
3707
- maxLevel
4016
+ if (isDynamicZone(attribute)) {
4017
+ const components2 = attribute.components;
4018
+ const componentsResult = (components2 || []).reduce(
4019
+ (acc, componentUID) => {
4020
+ const componentResult = getPopulateForValidation(componentUID);
4021
+ if (Object.keys(componentResult).length > 0) {
4022
+ acc[componentUID] = componentResult;
4023
+ }
4024
+ return acc;
3708
4025
  },
3709
- level
3710
- )
3711
- );
4026
+ {}
4027
+ );
4028
+ if (Object.keys(componentsResult).length > 0) {
4029
+ populateAcc.populate = populateAcc.populate || {};
4030
+ populateAcc.populate[attributeName] = { on: componentsResult };
4031
+ }
4032
+ }
4033
+ return populateAcc;
3712
4034
  }, {});
3713
4035
  };
3714
4036
  const getDeepPopulateDraftCount = (uid2) => {
@@ -3718,6 +4040,10 @@ const getDeepPopulateDraftCount = (uid2) => {
3718
4040
  const attribute = model.attributes[attributeName];
3719
4041
  switch (attribute.type) {
3720
4042
  case "relation": {
4043
+ const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
4044
+ if (isMorphRelation) {
4045
+ break;
4046
+ }
3721
4047
  if (isVisibleAttribute$1(model, attributeName)) {
3722
4048
  populateAcc[attributeName] = {
3723
4049
  count: true,
@@ -3784,7 +4110,7 @@ const getQueryPopulate = async (uid2, query) => {
3784
4110
  return populateQuery;
3785
4111
  };
3786
4112
  const buildDeepPopulate = (uid2) => {
3787
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4113
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3788
4114
  };
3789
4115
  const populateBuilder = (uid2) => {
3790
4116
  let getInitialPopulate = async () => {
@@ -3946,7 +4272,6 @@ const AVAILABLE_LOCALES_FIELDS = [
3946
4272
  "locale",
3947
4273
  "updatedAt",
3948
4274
  "createdAt",
3949
- "status",
3950
4275
  "publishedAt",
3951
4276
  "documentId"
3952
4277
  ];
@@ -3967,34 +4292,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
3967
4292
  /**
3968
4293
  * Returns available locales of a document for the current status
3969
4294
  */
3970
- async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4295
+ async getAvailableLocales(uid2, version, allVersions) {
3971
4296
  const versionsByLocale = groupBy("locale", allVersions);
3972
- delete versionsByLocale[version.locale];
4297
+ if (version.locale) {
4298
+ delete versionsByLocale[version.locale];
4299
+ }
3973
4300
  const model = strapi2.getModel(uid2);
3974
- const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
3975
- const traversalFunction = async (localeVersion) => traverseEntity(
3976
- ({ key }, { remove }) => {
3977
- if (keysToKeep.includes(key)) {
3978
- return;
3979
- }
3980
- remove(key);
3981
- },
3982
- { schema: model, getModel: strapi2.getModel.bind(strapi2) },
3983
- // @ts-expect-error fix types DocumentVersion incompatible with Data
3984
- localeVersion
3985
- );
3986
4301
  const mappingResult = await async.map(
3987
4302
  Object.values(versionsByLocale),
3988
4303
  async (localeVersions) => {
3989
- const mappedLocaleVersions = await async.map(
3990
- localeVersions,
3991
- traversalFunction
3992
- );
3993
4304
  if (!contentTypes$1.hasDraftAndPublish(model)) {
3994
- return mappedLocaleVersions[0];
4305
+ return localeVersions[0];
3995
4306
  }
3996
- const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
3997
- const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
4307
+ const draftVersion = localeVersions.find((v) => v.publishedAt === null);
4308
+ const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);
3998
4309
  if (!draftVersion) {
3999
4310
  return;
4000
4311
  }
@@ -4016,8 +4327,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4016
4327
  const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
4017
4328
  return matchLocale && matchStatus;
4018
4329
  });
4019
- if (!availableStatus)
4020
- return availableStatus;
4330
+ if (!availableStatus) return availableStatus;
4021
4331
  return pick(AVAILABLE_STATUS_FIELDS, availableStatus);
4022
4332
  },
4023
4333
  /**
@@ -4027,18 +4337,19 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4027
4337
  * @returns
4028
4338
  */
4029
4339
  async getManyAvailableStatus(uid2, documents) {
4030
- if (!documents.length)
4031
- return [];
4340
+ if (!documents.length) return [];
4032
4341
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4033
- const locale = documents[0]?.locale;
4034
- const otherStatus = status === "published" ? "draft" : "published";
4035
- return strapi2.documents(uid2).findMany({
4036
- filters: {
4037
- documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) }
4038
- },
4039
- status: otherStatus,
4040
- locale,
4041
- fields: ["documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4342
+ const locales = documents.map((d) => d.locale).filter(Boolean);
4343
+ const where = {
4344
+ documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },
4345
+ publishedAt: { $null: status === "published" }
4346
+ };
4347
+ if (locales.length) {
4348
+ where.locale = { $in: locales };
4349
+ }
4350
+ return strapi2.query(uid2).findMany({
4351
+ where,
4352
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
4042
4353
  });
4043
4354
  },
4044
4355
  getStatus(version, otherDocumentStatuses) {
@@ -4055,10 +4366,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4055
4366
  } else if (otherVersion) {
4056
4367
  draftVersion = otherVersion;
4057
4368
  }
4058
- if (!draftVersion)
4059
- return CONTENT_MANAGER_STATUS.PUBLISHED;
4060
- if (!publishedVersion)
4061
- return CONTENT_MANAGER_STATUS.DRAFT;
4369
+ if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
4370
+ if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
4062
4371
  const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
4063
4372
  return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
4064
4373
  },
@@ -4066,11 +4375,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4066
4375
  // We could refactor this so the locales are only loaded when they're
4067
4376
  // needed. e.g. in the bulk locale action modal.
4068
4377
  async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
4069
- const populate = getValidatableFieldsPopulate(uid2);
4070
- const versions = await strapi2.db.query(uid2).findMany({
4071
- where: { documentId: version.documentId },
4378
+ const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
4379
+ const params = {
4072
4380
  populate: {
4073
- // Populate only fields that require validation for bulk locale actions
4074
4381
  ...populate,
4075
4382
  // NOTE: creator fields are selected in this way to avoid exposing sensitive data
4076
4383
  createdBy: {
@@ -4079,9 +4386,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4079
4386
  updatedBy: {
4080
4387
  select: ["id", "firstname", "lastname", "email"]
4081
4388
  }
4389
+ },
4390
+ fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
4391
+ filters: {
4392
+ documentId: version.documentId
4082
4393
  }
4083
- });
4084
- const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
4394
+ };
4395
+ const dbParams = strapi2.get("query-params").transform(uid2, params);
4396
+ const versions = await strapi2.db.query(uid2).findMany(dbParams);
4397
+ const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions) : [];
4085
4398
  const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
4086
4399
  return {
4087
4400
  availableLocales: availableLocalesResult,
@@ -4095,13 +4408,29 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4095
4408
  */
4096
4409
  async formatDocumentWithMetadata(uid2, document, opts = {}) {
4097
4410
  if (!document) {
4098
- return document;
4411
+ return {
4412
+ data: document,
4413
+ meta: {
4414
+ availableLocales: [],
4415
+ availableStatus: []
4416
+ }
4417
+ };
4099
4418
  }
4100
4419
  const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
4101
4420
  if (!hasDraftAndPublish) {
4102
4421
  opts.availableStatus = false;
4103
4422
  }
4104
4423
  const meta = await this.getMetadata(uid2, document, opts);
4424
+ if (document.localizations) {
4425
+ const otherStatus = await this.getManyAvailableStatus(uid2, document.localizations);
4426
+ document.localizations = document.localizations.map((d) => {
4427
+ const status = otherStatus.find((s) => s.documentId === d.documentId);
4428
+ return {
4429
+ ...d,
4430
+ status: this.getStatus(d, status ? [status] : [])
4431
+ };
4432
+ });
4433
+ }
4105
4434
  return {
4106
4435
  data: {
4107
4436
  ...document,
@@ -4203,10 +4532,7 @@ const documentManager = ({ strapi: strapi2 }) => {
4203
4532
  async clone(id, body, uid2) {
4204
4533
  const populate = await buildDeepPopulate(uid2);
4205
4534
  const params = {
4206
- data: {
4207
- ...omitIdField(body),
4208
- [PUBLISHED_AT_ATTRIBUTE]: null
4209
- },
4535
+ data: omitIdField(body),
4210
4536
  populate
4211
4537
  };
4212
4538
  return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
@@ -4322,7 +4648,8 @@ const services = {
4322
4648
  permission,
4323
4649
  "populate-builder": populateBuilder$1,
4324
4650
  uid,
4325
- ...history.services ? history.services : {}
4651
+ ...history.services ? history.services : {},
4652
+ ...preview.services ? preview.services : {}
4326
4653
  };
4327
4654
  const index = () => {
4328
4655
  return {