@strapi/content-manager 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4 → 0.0.0-experimental.39bf1ab0d2e327b0a192d2f5adcb4182de865411

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 (212) hide show
  1. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
  2. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-CzVt9QCC.mjs} +4 -4
  4. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-CzVt9QCC.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-DYq8aqos.js} +5 -6
  6. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-DYq8aqos.js.map} +1 -1
  7. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  9. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  10. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-C9IATpr0.js} +5 -6
  11. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-C9IATpr0.js.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs → EditConfigurationPage-CLDwrUv5.mjs} +4 -4
  13. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-CLDwrUv5.mjs.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-Ch-uBvbv.js} +63 -13
  15. package/dist/_chunks/EditViewPage-Ch-uBvbv.js.map +1 -0
  16. package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-DtKM7Jgw.mjs} +63 -12
  17. package/dist/_chunks/EditViewPage-DtKM7Jgw.mjs.map +1 -0
  18. package/dist/_chunks/{Field-Bfph5SOd.js → Field-B9ADaInZ.js} +235 -164
  19. package/dist/_chunks/Field-B9ADaInZ.js.map +1 -0
  20. package/dist/_chunks/{Field-Cs7duwWd.mjs → Field-Bn1jgMeF.mjs} +232 -160
  21. package/dist/_chunks/Field-Bn1jgMeF.mjs.map +1 -0
  22. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  23. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  24. package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-BB5i9Pxl.mjs} +37 -18
  25. package/dist/_chunks/Form-BB5i9Pxl.mjs.map +1 -0
  26. package/dist/_chunks/{Form-CPYqIWDG.js → Form-C3kjKrPw.js} +39 -21
  27. package/dist/_chunks/Form-C3kjKrPw.js.map +1 -0
  28. package/dist/_chunks/{History-DNQkXANT.js → History-AwrK0-SA.js} +42 -100
  29. package/dist/_chunks/History-AwrK0-SA.js.map +1 -0
  30. package/dist/_chunks/{History-wrnHqf09.mjs → History-Cw2Q7OQL.mjs} +43 -100
  31. package/dist/_chunks/History-Cw2Q7OQL.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-B47JIu1e.mjs} +19 -8
  33. package/dist/_chunks/ListConfigurationPage-B47JIu1e.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-CNTJ0DBm.js} +19 -9
  35. package/dist/_chunks/ListConfigurationPage-CNTJ0DBm.js.map +1 -0
  36. package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-Be_UEBar.js} +109 -78
  37. package/dist/_chunks/ListViewPage-Be_UEBar.js.map +1 -0
  38. package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-DuvjX6ra.mjs} +106 -74
  39. package/dist/_chunks/ListViewPage-DuvjX6ra.mjs.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-B1J0KUCO.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-B1J0KUCO.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-C6M-Q0Tv.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-C6M-Q0Tv.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-CAi3zCAD.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-CAi3zCAD.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-CN34TlEE.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-CN34TlEE.js.map} +1 -1
  48. package/dist/_chunks/Preview-BrBRcL10.mjs +293 -0
  49. package/dist/_chunks/Preview-BrBRcL10.mjs.map +1 -0
  50. package/dist/_chunks/Preview-DOqm5jcJ.js +311 -0
  51. package/dist/_chunks/Preview-DOqm5jcJ.js.map +1 -0
  52. package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-_K-HYOiM.mjs} +76 -42
  53. package/dist/_chunks/Relations-_K-HYOiM.mjs.map +1 -0
  54. package/dist/_chunks/{Relations-CtELXYIK.js → Relations-xtKZHtTN.js} +76 -43
  55. package/dist/_chunks/Relations-xtKZHtTN.js.map +1 -0
  56. package/dist/_chunks/{en-uOUIxfcQ.js → en-BK8Xyl5I.js} +28 -15
  57. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BK8Xyl5I.js.map} +1 -1
  58. package/dist/_chunks/{en-BrCTWlZv.mjs → en-Dtk_ot79.mjs} +28 -15
  59. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
  60. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  61. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  62. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  63. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  64. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
  65. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
  66. package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
  67. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
  68. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  69. package/dist/_chunks/{index-OerGjbAN.js → index-BlX-OdHL.js} +1092 -758
  70. package/dist/_chunks/index-BlX-OdHL.js.map +1 -0
  71. package/dist/_chunks/{index-c_5DdJi-.mjs → index-tETMKK2G.mjs} +1110 -776
  72. package/dist/_chunks/index-tETMKK2G.mjs.map +1 -0
  73. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  74. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  75. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  76. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  77. package/dist/_chunks/{layout-oPBiO7RY.mjs → layout-BaQBaz56.mjs} +23 -10
  78. package/dist/_chunks/layout-BaQBaz56.mjs.map +1 -0
  79. package/dist/_chunks/{layout-Ci7qHlFb.js → layout-D8Sz3KxF.js} +23 -11
  80. package/dist/_chunks/layout-D8Sz3KxF.js.map +1 -0
  81. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  82. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  83. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  84. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  85. package/dist/_chunks/{relations-COBpStiF.js → relations-CAbbX8Sa.js} +6 -7
  86. package/dist/_chunks/relations-CAbbX8Sa.js.map +1 -0
  87. package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-CsfmCqOU.mjs} +6 -7
  88. package/dist/_chunks/relations-CsfmCqOU.mjs.map +1 -0
  89. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  90. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  91. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  92. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  93. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  94. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  95. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  96. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  97. package/dist/admin/index.js +2 -1
  98. package/dist/admin/index.js.map +1 -1
  99. package/dist/admin/index.mjs +5 -4
  100. package/dist/admin/src/content-manager.d.ts +3 -2
  101. package/dist/admin/src/exports.d.ts +1 -1
  102. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  103. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  104. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  105. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  106. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
  107. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  108. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  109. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  110. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  111. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  112. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  113. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  114. package/dist/admin/src/preview/constants.d.ts +1 -0
  115. package/dist/admin/src/preview/index.d.ts +4 -0
  116. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  117. package/dist/admin/src/preview/routes.d.ts +3 -0
  118. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  119. package/dist/admin/src/router.d.ts +1 -1
  120. package/dist/admin/src/services/api.d.ts +1 -1
  121. package/dist/admin/src/services/components.d.ts +2 -2
  122. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  123. package/dist/admin/src/services/documents.d.ts +19 -20
  124. package/dist/admin/src/services/init.d.ts +1 -1
  125. package/dist/admin/src/services/relations.d.ts +2 -2
  126. package/dist/admin/src/services/uid.d.ts +3 -3
  127. package/dist/admin/src/utils/validation.d.ts +4 -1
  128. package/dist/server/index.js +578 -271
  129. package/dist/server/index.js.map +1 -1
  130. package/dist/server/index.mjs +578 -270
  131. package/dist/server/index.mjs.map +1 -1
  132. package/dist/server/src/bootstrap.d.ts.map +1 -1
  133. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  134. package/dist/server/src/controllers/index.d.ts.map +1 -1
  135. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  136. package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
  137. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  138. package/dist/server/src/history/services/history.d.ts.map +1 -1
  139. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  140. package/dist/server/src/history/services/utils.d.ts +4 -4
  141. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  142. package/dist/server/src/index.d.ts +4 -4
  143. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  144. package/dist/server/src/preview/constants.d.ts +2 -0
  145. package/dist/server/src/preview/constants.d.ts.map +1 -0
  146. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  147. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  148. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  149. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  150. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  151. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  152. package/dist/server/src/preview/index.d.ts +4 -0
  153. package/dist/server/src/preview/index.d.ts.map +1 -0
  154. package/dist/server/src/preview/routes/index.d.ts +8 -0
  155. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  156. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  157. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  158. package/dist/server/src/preview/services/index.d.ts +16 -0
  159. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  160. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  161. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  162. package/dist/server/src/preview/services/preview.d.ts +12 -0
  163. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  164. package/dist/server/src/preview/utils.d.ts +19 -0
  165. package/dist/server/src/preview/utils.d.ts.map +1 -0
  166. package/dist/server/src/register.d.ts.map +1 -1
  167. package/dist/server/src/routes/index.d.ts.map +1 -1
  168. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  169. package/dist/server/src/services/document-metadata.d.ts +8 -8
  170. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  171. package/dist/server/src/services/index.d.ts +4 -4
  172. package/dist/server/src/services/index.d.ts.map +1 -1
  173. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  174. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  175. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  176. package/dist/server/src/utils/index.d.ts +2 -0
  177. package/dist/server/src/utils/index.d.ts.map +1 -1
  178. package/dist/shared/contracts/collection-types.d.ts +3 -1
  179. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  180. package/dist/shared/contracts/index.d.ts +1 -0
  181. package/dist/shared/contracts/index.d.ts.map +1 -1
  182. package/dist/shared/contracts/preview.d.ts +27 -0
  183. package/dist/shared/contracts/preview.d.ts.map +1 -0
  184. package/dist/shared/index.js +4 -0
  185. package/dist/shared/index.js.map +1 -1
  186. package/dist/shared/index.mjs +4 -0
  187. package/dist/shared/index.mjs.map +1 -1
  188. package/package.json +15 -15
  189. package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +0 -1
  190. package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
  191. package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
  192. package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
  193. package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
  194. package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
  195. package/dist/_chunks/History-DNQkXANT.js.map +0 -1
  196. package/dist/_chunks/History-wrnHqf09.mjs.map +0 -1
  197. package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
  198. package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
  199. package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
  200. package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
  201. package/dist/_chunks/Relations-BZr8tL0R.mjs.map +0 -1
  202. package/dist/_chunks/Relations-CtELXYIK.js.map +0 -1
  203. package/dist/_chunks/index-OerGjbAN.js.map +0 -1
  204. package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
  205. package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
  206. package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
  207. package/dist/_chunks/relations-BIdWFjdq.mjs.map +0 -1
  208. package/dist/_chunks/relations-COBpStiF.js.map +0 -1
  209. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  210. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  211. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  212. package/strapi-server.js +0 -3
@@ -10,8 +10,7 @@ const qs = require("qs");
10
10
  const slugify = require("@sindresorhus/slugify");
11
11
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
12
  function _interopNamespace(e) {
13
- if (e && e.__esModule)
14
- return e;
13
+ if (e && e.__esModule) return e;
15
14
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
16
15
  if (e) {
17
16
  for (const k in e) {
@@ -33,10 +32,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
33
32
  const ___default = /* @__PURE__ */ _interopDefault(_);
34
33
  const qs__default = /* @__PURE__ */ _interopDefault(qs);
35
34
  const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
36
- const getService$1 = (name) => {
35
+ const getService$2 = (name) => {
37
36
  return strapi.plugin("content-manager").service(name);
38
37
  };
39
- function getService(strapi2, name) {
38
+ function getService$1(strapi2, name) {
40
39
  return strapi2.service(`plugin::content-manager.${name}`);
41
40
  }
42
41
  const historyRestoreVersionSchema = yup__namespace.object().shape({
@@ -72,7 +71,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
72
71
  if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
73
72
  throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
74
73
  }
75
- const permissionChecker2 = getService$1("permission-checker").create({
74
+ const permissionChecker2 = getService$2("permission-checker").create({
76
75
  userAbility: ctx.state.userAbility,
77
76
  model: ctx.query.contentType
78
77
  });
@@ -80,7 +79,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
80
79
  return ctx.forbidden();
81
80
  }
82
81
  const query = await permissionChecker2.sanitizeQuery(ctx.query);
83
- const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
82
+ const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
84
83
  query: {
85
84
  ...query,
86
85
  ...getValidPagination({ page: query.page, pageSize: query.pageSize })
@@ -105,14 +104,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
105
104
  async restoreVersion(ctx) {
106
105
  const request = ctx.request;
107
106
  await validateRestoreVersion(request.body, "contentType is required");
108
- const permissionChecker2 = getService$1("permission-checker").create({
107
+ const permissionChecker2 = getService$2("permission-checker").create({
109
108
  userAbility: ctx.state.userAbility,
110
109
  model: request.body.contentType
111
110
  });
112
111
  if (permissionChecker2.cannot.update()) {
113
112
  throw new strapiUtils.errors.ForbiddenError();
114
113
  }
115
- const restoredDocument = await getService(strapi2, "history").restoreVersion(
114
+ const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
116
115
  request.params.versionId
117
116
  );
118
117
  return {
@@ -121,7 +120,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
121
120
  }
122
121
  };
123
122
  };
124
- const controllers$1 = {
123
+ const controllers$2 = {
125
124
  "history-version": createHistoryVersionController
126
125
  /**
127
126
  * Casting is needed because the types aren't aware that Strapi supports
@@ -167,8 +166,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
167
166
  };
168
167
  const getRelationRestoreValue = async (versionRelationData, attribute) => {
169
168
  if (Array.isArray(versionRelationData)) {
170
- if (versionRelationData.length === 0)
171
- return versionRelationData;
169
+ if (versionRelationData.length === 0) return versionRelationData;
172
170
  const existingAndMissingRelations = await Promise.all(
173
171
  versionRelationData.map((relation) => {
174
172
  return strapi2.documents(attribute.target).findOne({
@@ -199,10 +197,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
199
197
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
200
198
  };
201
199
  const localesService = strapi2.plugin("i18n")?.service("locales");
200
+ const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
202
201
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
202
+ const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
203
203
  const getLocaleDictionary = async () => {
204
- if (!localesService)
205
- return {};
204
+ if (!localesService) return {};
206
205
  const locales = await localesService.find() || [];
207
206
  return locales.reduce(
208
207
  (acc, locale) => {
@@ -226,9 +225,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
226
225
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
227
226
  return documentMetadataService.getStatus(document, meta.availableStatus);
228
227
  };
229
- const getDeepPopulate2 = (uid2) => {
228
+ const getComponentFields = (componentUID) => {
229
+ return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
230
+ (fieldsAcc, [key, attribute]) => {
231
+ if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
232
+ fieldsAcc.push(key);
233
+ }
234
+ return fieldsAcc;
235
+ },
236
+ []
237
+ );
238
+ };
239
+ const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
230
240
  const model = strapi2.getModel(uid2);
231
241
  const attributes = Object.entries(model.attributes);
242
+ const fieldSelector = useDatabaseSyntax ? "select" : "fields";
232
243
  return attributes.reduce((acc, [attributeName, attribute]) => {
233
244
  switch (attribute.type) {
234
245
  case "relation": {
@@ -238,23 +249,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
238
249
  }
239
250
  const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
240
251
  if (isVisible2) {
241
- acc[attributeName] = { fields: ["documentId", "locale", "publishedAt"] };
252
+ acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
242
253
  }
243
254
  break;
244
255
  }
245
256
  case "media": {
246
- acc[attributeName] = { fields: ["id"] };
257
+ acc[attributeName] = { [fieldSelector]: ["id"] };
247
258
  break;
248
259
  }
249
260
  case "component": {
250
261
  const populate = getDeepPopulate2(attribute.component);
251
- acc[attributeName] = { populate };
262
+ acc[attributeName] = {
263
+ populate,
264
+ [fieldSelector]: getComponentFields(attribute.component)
265
+ };
252
266
  break;
253
267
  }
254
268
  case "dynamiczone": {
255
269
  const populatedComponents = (attribute.components || []).reduce(
256
270
  (acc2, componentUID) => {
257
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
271
+ acc2[componentUID] = {
272
+ populate: getDeepPopulate2(componentUID),
273
+ [fieldSelector]: getComponentFields(componentUID)
274
+ };
258
275
  return acc2;
259
276
  },
260
277
  {}
@@ -316,6 +333,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
316
333
  getRelationRestoreValue,
317
334
  getMediaRestoreValue,
318
335
  getDefaultLocale,
336
+ isLocalizedContentType,
319
337
  getLocaleDictionary,
320
338
  getRetentionDays,
321
339
  getVersionStatus,
@@ -338,7 +356,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
338
356
  });
339
357
  },
340
358
  async findVersionsPage(params) {
341
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
359
+ const model = strapi2.getModel(params.query.contentType);
360
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
361
+ const defaultLocale = await serviceUtils.getDefaultLocale();
362
+ let locale = null;
363
+ if (isLocalizedContentType) {
364
+ locale = params.query.locale || defaultLocale;
365
+ }
342
366
  const [{ results, pagination }, localeDictionary] = await Promise.all([
343
367
  query.findPage({
344
368
  ...params.query,
@@ -360,7 +384,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
360
384
  const attributeValue = entry.data[attributeKey];
361
385
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
362
386
  if (attributeSchema.type === "media") {
363
- const permissionChecker2 = getService$1("permission-checker").create({
387
+ const permissionChecker2 = getService$2("permission-checker").create({
364
388
  userAbility: params.state.userAbility,
365
389
  model: "plugin::upload.file"
366
390
  });
@@ -383,7 +407,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
383
407
  if (userToPopulate == null) {
384
408
  return null;
385
409
  }
386
- return strapi2.query("admin::user").findOne({ where: { id: userToPopulate.id } });
410
+ return strapi2.query("admin::user").findOne({
411
+ where: {
412
+ ...userToPopulate.id ? { id: userToPopulate.id } : {},
413
+ ...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
414
+ }
415
+ });
387
416
  })
388
417
  );
389
418
  return {
@@ -396,7 +425,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
396
425
  [attributeKey]: adminUsers
397
426
  };
398
427
  }
399
- const permissionChecker2 = getService$1("permission-checker").create({
428
+ const permissionChecker2 = getService$2("permission-checker").create({
400
429
  userAbility: params.state.userAbility,
401
430
  model: attributeSchema.target
402
431
  });
@@ -494,6 +523,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
494
523
  }
495
524
  };
496
525
  };
526
+ const shouldCreateHistoryVersion = (context) => {
527
+ if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
528
+ return false;
529
+ }
530
+ if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
531
+ return false;
532
+ }
533
+ if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
534
+ return false;
535
+ }
536
+ if (!context.contentType.uid.startsWith("api::")) {
537
+ return false;
538
+ }
539
+ return true;
540
+ };
541
+ const getSchemas = (uid2) => {
542
+ const attributesSchema = strapi.getModel(uid2).attributes;
543
+ const componentsSchemas = Object.keys(attributesSchema).reduce(
544
+ (currentComponentSchemas, key) => {
545
+ const fieldSchema = attributesSchema[key];
546
+ if (fieldSchema.type === "component") {
547
+ const componentSchema = strapi.getModel(fieldSchema.component).attributes;
548
+ return {
549
+ ...currentComponentSchemas,
550
+ [fieldSchema.component]: componentSchema
551
+ };
552
+ }
553
+ return currentComponentSchemas;
554
+ },
555
+ {}
556
+ );
557
+ return {
558
+ schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
559
+ componentsSchemas
560
+ };
561
+ };
497
562
  const createLifecyclesService = ({ strapi: strapi2 }) => {
498
563
  const state = {
499
564
  deleteExpiredJob: null,
@@ -506,76 +571,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
506
571
  return;
507
572
  }
508
573
  strapi2.documents.use(async (context, next) => {
509
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
510
- return next();
511
- }
512
- if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
513
- return next();
514
- }
515
- if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
516
- return next();
517
- }
518
- const contentTypeUid = context.contentType.uid;
519
- if (!contentTypeUid.startsWith("api::")) {
520
- return next();
521
- }
522
574
  const result = await next();
523
- const documentContext = {
524
- documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
525
- locale: context.params?.locale
526
- };
575
+ if (!shouldCreateHistoryVersion(context)) {
576
+ return result;
577
+ }
578
+ const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
527
579
  const defaultLocale = await serviceUtils.getDefaultLocale();
528
- const locale = documentContext.locale || defaultLocale;
529
- if (Array.isArray(locale)) {
530
- strapi2.log.warn(
531
- "[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
532
- );
533
- return next();
580
+ const locales = fp.castArray(context.params?.locale || defaultLocale);
581
+ if (!locales.length) {
582
+ return result;
534
583
  }
535
- const document = await strapi2.documents(contentTypeUid).findOne({
536
- documentId: documentContext.documentId,
537
- locale,
538
- populate: serviceUtils.getDeepPopulate(contentTypeUid)
584
+ const uid2 = context.contentType.uid;
585
+ const schemas = getSchemas(uid2);
586
+ const model = strapi2.getModel(uid2);
587
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
588
+ const localeEntries = await strapi2.db.query(uid2).findMany({
589
+ where: {
590
+ documentId,
591
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
592
+ ...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
593
+ },
594
+ populate: serviceUtils.getDeepPopulate(
595
+ uid2,
596
+ true
597
+ /* use database syntax */
598
+ )
539
599
  });
540
- const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
541
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
542
- const componentsSchemas = Object.keys(
543
- attributesSchema
544
- ).reduce((currentComponentSchemas, key) => {
545
- const fieldSchema = attributesSchema[key];
546
- if (fieldSchema.type === "component") {
547
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
548
- return {
549
- ...currentComponentSchemas,
550
- [fieldSchema.component]: componentSchema
551
- };
552
- }
553
- return currentComponentSchemas;
554
- }, {});
555
600
  await strapi2.db.transaction(async ({ onCommit }) => {
556
- onCommit(() => {
557
- getService(strapi2, "history").createVersion({
558
- contentType: contentTypeUid,
559
- data: fp.omit(FIELDS_TO_IGNORE, document),
560
- schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
561
- componentsSchemas,
562
- relatedDocumentId: documentContext.documentId,
563
- locale,
564
- status
565
- });
601
+ onCommit(async () => {
602
+ for (const entry of localeEntries) {
603
+ const status = await serviceUtils.getVersionStatus(uid2, entry);
604
+ await getService$1(strapi2, "history").createVersion({
605
+ contentType: uid2,
606
+ data: fp.omit(FIELDS_TO_IGNORE, entry),
607
+ relatedDocumentId: documentId,
608
+ locale: entry.locale,
609
+ status,
610
+ ...schemas
611
+ });
612
+ }
566
613
  });
567
614
  });
568
615
  return result;
569
616
  });
570
- state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
617
+ state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
571
618
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
572
619
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
573
620
  strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
574
621
  where: {
575
622
  created_at: {
576
- $lt: expirationDate.toISOString()
623
+ $lt: expirationDate
577
624
  }
578
625
  }
626
+ }).catch((error) => {
627
+ if (error instanceof Error) {
628
+ strapi2.log.error("Error deleting expired history versions", error.message);
629
+ }
579
630
  });
580
631
  });
581
632
  state.isInitialized = true;
@@ -587,17 +638,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
587
638
  }
588
639
  };
589
640
  };
590
- const services$1 = {
641
+ const services$2 = {
591
642
  history: createHistoryService,
592
643
  lifecycles: createLifecyclesService
593
644
  };
594
- const info = { pluginName: "content-manager", type: "admin" };
645
+ const info$1 = { pluginName: "content-manager", type: "admin" };
595
646
  const historyVersionRouter = {
596
647
  type: "admin",
597
648
  routes: [
598
649
  {
599
650
  method: "GET",
600
- info,
651
+ info: info$1,
601
652
  path: "/history-versions",
602
653
  handler: "history-version.findMany",
603
654
  config: {
@@ -606,7 +657,7 @@ const historyVersionRouter = {
606
657
  },
607
658
  {
608
659
  method: "PUT",
609
- info,
660
+ info: info$1,
610
661
  path: "/history-versions/:versionId/restore",
611
662
  handler: "history-version.restoreVersion",
612
663
  config: {
@@ -615,7 +666,7 @@ const historyVersionRouter = {
615
666
  }
616
667
  ]
617
668
  };
618
- const routes$1 = {
669
+ const routes$2 = {
619
670
  "history-version": historyVersionRouter
620
671
  };
621
672
  const historyVersion = {
@@ -662,21 +713,21 @@ const historyVersion = {
662
713
  }
663
714
  }
664
715
  };
665
- const getFeature = () => {
716
+ const getFeature$1 = () => {
666
717
  if (strapi.ee.features.isEnabled("cms-content-history")) {
667
718
  return {
668
719
  register({ strapi: strapi2 }) {
669
720
  strapi2.get("models").add(historyVersion);
670
721
  },
671
722
  bootstrap({ strapi: strapi2 }) {
672
- getService(strapi2, "lifecycles").bootstrap();
723
+ getService$1(strapi2, "lifecycles").bootstrap();
673
724
  },
674
725
  destroy({ strapi: strapi2 }) {
675
- getService(strapi2, "lifecycles").destroy();
726
+ getService$1(strapi2, "lifecycles").destroy();
676
727
  },
677
- controllers: controllers$1,
678
- services: services$1,
679
- routes: routes$1
728
+ controllers: controllers$2,
729
+ services: services$2,
730
+ routes: routes$2
680
731
  };
681
732
  }
682
733
  return {
@@ -685,9 +736,205 @@ const getFeature = () => {
685
736
  }
686
737
  };
687
738
  };
688
- const history = getFeature();
739
+ const history = getFeature$1();
740
+ const FEATURE_ID = "preview";
741
+ const info = { pluginName: "content-manager", type: "admin" };
742
+ const previewRouter = {
743
+ type: "admin",
744
+ routes: [
745
+ {
746
+ method: "GET",
747
+ info,
748
+ path: "/preview/url/:contentType",
749
+ handler: "preview.getPreviewUrl",
750
+ config: {
751
+ policies: ["admin::isAuthenticatedAdmin"]
752
+ }
753
+ }
754
+ ]
755
+ };
756
+ const routes$1 = {
757
+ preview: previewRouter
758
+ };
759
+ function getService(strapi2, name) {
760
+ return strapi2.service(`plugin::content-manager.${name}`);
761
+ }
762
+ const getPreviewUrlSchema = yup__namespace.object().shape({
763
+ // Will be undefined for single types
764
+ documentId: yup__namespace.string(),
765
+ locale: yup__namespace.string().nullable(),
766
+ status: yup__namespace.string()
767
+ }).required();
768
+ const validatePreviewUrl = async (strapi2, uid2, params) => {
769
+ await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
770
+ const newParams = fp.pick(["documentId", "locale", "status"], params);
771
+ const model = strapi2.getModel(uid2);
772
+ if (!model || model.modelType !== "contentType") {
773
+ throw new strapiUtils.errors.ValidationError("Invalid content type");
774
+ }
775
+ const isSingleType = model?.kind === "singleType";
776
+ if (!isSingleType && !params.documentId) {
777
+ throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
778
+ }
779
+ if (isSingleType) {
780
+ const doc = await strapi2.documents(uid2).findFirst();
781
+ if (!doc) {
782
+ throw new strapiUtils.errors.NotFoundError("Document not found");
783
+ }
784
+ newParams.documentId = doc?.documentId;
785
+ }
786
+ if (!newParams.status) {
787
+ const isDPEnabled = model?.options?.draftAndPublish;
788
+ newParams.status = isDPEnabled ? "draft" : "published";
789
+ }
790
+ return newParams;
791
+ };
792
+ const createPreviewController = () => {
793
+ return {
794
+ /**
795
+ * Transforms an entry into a preview URL, so that it can be previewed
796
+ * in the Content Manager.
797
+ */
798
+ async getPreviewUrl(ctx) {
799
+ const uid2 = ctx.params.contentType;
800
+ const query = ctx.request.query;
801
+ const params = await validatePreviewUrl(strapi, uid2, query);
802
+ const previewService = getService(strapi, "preview");
803
+ const url = await previewService.getPreviewUrl(uid2, params);
804
+ if (!url) {
805
+ ctx.status = 204;
806
+ }
807
+ return {
808
+ data: { url }
809
+ };
810
+ }
811
+ };
812
+ };
813
+ const controllers$1 = {
814
+ preview: createPreviewController
815
+ /**
816
+ * Casting is needed because the types aren't aware that Strapi supports
817
+ * passing a controller factory as the value, instead of a controller object directly
818
+ */
819
+ };
820
+ const createPreviewService = ({ strapi: strapi2 }) => {
821
+ const config = getService(strapi2, "preview-config");
822
+ return {
823
+ async getPreviewUrl(uid2, params) {
824
+ const handler = config.getPreviewHandler();
825
+ try {
826
+ return handler(uid2, params);
827
+ } catch (error) {
828
+ strapi2.log.error(`Failed to get preview URL: ${error}`);
829
+ throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
830
+ }
831
+ return;
832
+ }
833
+ };
834
+ };
835
+ const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
836
+ const middlewares = strapi.config.get("middlewares");
837
+ const configuredMiddlewares = middlewares.map((currentMiddleware) => {
838
+ if (currentMiddleware === middleware.name) {
839
+ return middleware;
840
+ }
841
+ if (currentMiddleware.name === middleware.name) {
842
+ return fp.mergeWith(
843
+ (objValue, srcValue) => {
844
+ if (Array.isArray(objValue)) {
845
+ return objValue.concat(srcValue);
846
+ }
847
+ return void 0;
848
+ },
849
+ currentMiddleware,
850
+ middleware
851
+ );
852
+ }
853
+ return currentMiddleware;
854
+ });
855
+ strapi.config.set("middlewares", configuredMiddlewares);
856
+ };
857
+ const createPreviewConfigService = ({ strapi: strapi2 }) => {
858
+ return {
859
+ register() {
860
+ if (!this.isEnabled()) {
861
+ return;
862
+ }
863
+ const config = strapi2.config.get("admin.preview");
864
+ if (config.config?.allowedOrigins) {
865
+ extendMiddlewareConfiguration({
866
+ name: "strapi::security",
867
+ config: {
868
+ contentSecurityPolicy: {
869
+ directives: {
870
+ "frame-src": config.config.allowedOrigins
871
+ }
872
+ }
873
+ }
874
+ });
875
+ }
876
+ },
877
+ isEnabled() {
878
+ const config = strapi2.config.get("admin.preview");
879
+ if (!config) {
880
+ return false;
881
+ }
882
+ return config?.enabled ?? true;
883
+ },
884
+ /**
885
+ * Validate if the configuration is valid
886
+ */
887
+ validate() {
888
+ if (!this.isEnabled()) {
889
+ return;
890
+ }
891
+ const handler = this.getPreviewHandler();
892
+ if (typeof handler !== "function") {
893
+ throw new strapiUtils.errors.ValidationError(
894
+ "Preview configuration is invalid. Handler must be a function"
895
+ );
896
+ }
897
+ },
898
+ /**
899
+ * Utility to get the preview handler from the configuration
900
+ */
901
+ getPreviewHandler() {
902
+ const config = strapi2.config.get("admin.preview");
903
+ const emptyHandler = () => {
904
+ return void 0;
905
+ };
906
+ if (!this.isEnabled()) {
907
+ return emptyHandler;
908
+ }
909
+ return config?.config?.handler || emptyHandler;
910
+ }
911
+ };
912
+ };
913
+ const services$1 = {
914
+ preview: createPreviewService,
915
+ "preview-config": createPreviewConfigService
916
+ };
917
+ const getFeature = () => {
918
+ if (!strapi.features.future.isEnabled(FEATURE_ID)) {
919
+ return {};
920
+ }
921
+ return {
922
+ register() {
923
+ const config = getService(strapi, "preview-config");
924
+ config.validate();
925
+ config.register();
926
+ },
927
+ bootstrap() {
928
+ },
929
+ routes: routes$1,
930
+ controllers: controllers$1,
931
+ services: services$1
932
+ };
933
+ };
934
+ const preview = getFeature();
689
935
  const register = async ({ strapi: strapi2 }) => {
690
936
  await history.register?.({ strapi: strapi2 });
937
+ await preview.register?.({ strapi: strapi2 });
691
938
  };
692
939
  const ALLOWED_WEBHOOK_EVENTS = {
693
940
  ENTRY_PUBLISH: "entry.publish",
@@ -697,11 +944,12 @@ const bootstrap = async () => {
697
944
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
698
945
  strapi.get("webhookStore").addAllowedEvent(key, value);
699
946
  });
700
- getService$1("field-sizes").setCustomFieldInputSizes();
701
- await getService$1("components").syncConfigurations();
702
- await getService$1("content-types").syncConfigurations();
703
- await getService$1("permission").registerPermissions();
947
+ getService$2("field-sizes").setCustomFieldInputSizes();
948
+ await getService$2("components").syncConfigurations();
949
+ await getService$2("content-types").syncConfigurations();
950
+ await getService$2("permission").registerPermissions();
704
951
  await history.bootstrap?.({ strapi });
952
+ await preview.bootstrap?.({ strapi });
705
953
  };
706
954
  const destroy = async ({ strapi: strapi2 }) => {
707
955
  await history.destroy?.({ strapi: strapi2 });
@@ -1191,7 +1439,8 @@ const admin = {
1191
1439
  };
1192
1440
  const routes = {
1193
1441
  admin,
1194
- ...history.routes ? history.routes : {}
1442
+ ...history.routes ? history.routes : {},
1443
+ ...preview.routes ? preview.routes : {}
1195
1444
  };
1196
1445
  const hasPermissionsSchema = strapiUtils.yup.object({
1197
1446
  actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
@@ -1202,6 +1451,11 @@ const { createPolicy } = strapiUtils.policy;
1202
1451
  const hasPermissions = createPolicy({
1203
1452
  name: "plugin::content-manager.hasPermissions",
1204
1453
  validator: validateHasPermissionsInput,
1454
+ /**
1455
+ * NOTE: Action aliases are currently not checked at this level (policy).
1456
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1457
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1458
+ */
1205
1459
  handler(ctx, config = {}) {
1206
1460
  const { actions = [], hasAtLeastOne = false } = config;
1207
1461
  const { userAbility } = ctx.state;
@@ -1249,8 +1503,7 @@ const isSortable = (schema, name) => {
1249
1503
  if (!___default.default.has(schema.attributes, name)) {
1250
1504
  return false;
1251
1505
  }
1252
- if (schema.modelType === "component" && name === "id")
1253
- return false;
1506
+ if (schema.modelType === "component" && name === "id") return false;
1254
1507
  const attribute = schema.attributes[name];
1255
1508
  if (NON_SORTABLES.includes(attribute.type)) {
1256
1509
  return false;
@@ -1395,8 +1648,7 @@ const createDefaultSettings = async (schema) => {
1395
1648
  };
1396
1649
  };
1397
1650
  const syncSettings = async (configuration, schema) => {
1398
- if (fp.isEmpty(configuration.settings))
1399
- return createDefaultSettings(schema);
1651
+ if (fp.isEmpty(configuration.settings)) return createDefaultSettings(schema);
1400
1652
  const defaultField = getDefaultMainField(schema);
1401
1653
  const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
1402
1654
  return {
@@ -1443,7 +1695,7 @@ const createMetadasSchema = (schema) => {
1443
1695
  if (!value) {
1444
1696
  return strapiUtils.yup.string();
1445
1697
  }
1446
- const targetSchema = getService$1("content-types").findContentType(
1698
+ const targetSchema = getService$2("content-types").findContentType(
1447
1699
  schema.attributes[key].targetModel
1448
1700
  );
1449
1701
  if (!targetSchema) {
@@ -1572,8 +1824,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1572
1824
  }
1573
1825
  switch (attribute.type) {
1574
1826
  case "relation": {
1575
- if (canCreate(attributePath))
1576
- return body2;
1827
+ if (canCreate(attributePath)) return body2;
1577
1828
  return fp.set(attributePath, { set: [] }, body2);
1578
1829
  }
1579
1830
  case "component": {
@@ -1583,8 +1834,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1583
1834
  ]);
1584
1835
  }
1585
1836
  default: {
1586
- if (canCreate(attributePath))
1587
- return body2;
1837
+ if (canCreate(attributePath)) return body2;
1588
1838
  return fp.set(attributePath, null, body2);
1589
1839
  }
1590
1840
  }
@@ -1612,7 +1862,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
1612
1862
  }
1613
1863
  };
1614
1864
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1615
- const documentMetadata2 = getService$1("document-metadata");
1865
+ const documentMetadata2 = getService$2("document-metadata");
1616
1866
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1617
1867
  let {
1618
1868
  meta: { availableLocales, availableStatus }
@@ -1638,8 +1888,8 @@ const createDocument = async (ctx, opts) => {
1638
1888
  const { userAbility, user } = ctx.state;
1639
1889
  const { model } = ctx.params;
1640
1890
  const { body } = ctx.request;
1641
- const documentManager2 = getService$1("document-manager");
1642
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1891
+ const documentManager2 = getService$2("document-manager");
1892
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1643
1893
  if (permissionChecker2.cannot.create()) {
1644
1894
  throw new strapiUtils.errors.ForbiddenError();
1645
1895
  }
@@ -1659,13 +1909,13 @@ const updateDocument = async (ctx, opts) => {
1659
1909
  const { userAbility, user } = ctx.state;
1660
1910
  const { id, model } = ctx.params;
1661
1911
  const { body } = ctx.request;
1662
- const documentManager2 = getService$1("document-manager");
1663
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1912
+ const documentManager2 = getService$2("document-manager");
1913
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1664
1914
  if (permissionChecker2.cannot.update()) {
1665
1915
  throw new strapiUtils.errors.ForbiddenError();
1666
1916
  }
1667
1917
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1668
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1918
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1669
1919
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1670
1920
  const [documentVersion, documentExists] = await Promise.all([
1671
1921
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
@@ -1682,7 +1932,7 @@ const updateDocument = async (ctx, opts) => {
1682
1932
  throw new strapiUtils.errors.ForbiddenError();
1683
1933
  }
1684
1934
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1685
- const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
1935
+ const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
1686
1936
  const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
1687
1937
  const sanitizedBody = await sanitizeFn(body);
1688
1938
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1696,14 +1946,14 @@ const collectionTypes = {
1696
1946
  const { userAbility } = ctx.state;
1697
1947
  const { model } = ctx.params;
1698
1948
  const { query } = ctx.request;
1699
- const documentMetadata2 = getService$1("document-metadata");
1700
- const documentManager2 = getService$1("document-manager");
1701
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1949
+ const documentMetadata2 = getService$2("document-metadata");
1950
+ const documentManager2 = getService$2("document-manager");
1951
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1702
1952
  if (permissionChecker2.cannot.read()) {
1703
1953
  return ctx.forbidden();
1704
1954
  }
1705
1955
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1706
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1956
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1707
1957
  const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1708
1958
  const { results: documents, pagination } = await documentManager2.findPage(
1709
1959
  { ...permissionQuery, populate, locale, status },
@@ -1732,13 +1982,13 @@ const collectionTypes = {
1732
1982
  async findOne(ctx) {
1733
1983
  const { userAbility } = ctx.state;
1734
1984
  const { model, id } = ctx.params;
1735
- const documentManager2 = getService$1("document-manager");
1736
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1985
+ const documentManager2 = getService$2("document-manager");
1986
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1737
1987
  if (permissionChecker2.cannot.read()) {
1738
1988
  return ctx.forbidden();
1739
1989
  }
1740
1990
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1741
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1991
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1742
1992
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1743
1993
  const version = await documentManager2.findOne(id, model, {
1744
1994
  populate,
@@ -1754,7 +2004,7 @@ const collectionTypes = {
1754
2004
  permissionChecker2,
1755
2005
  model,
1756
2006
  // @ts-expect-error TODO: fix
1757
- { id, locale, publishedAt: null },
2007
+ { documentId: id, locale, publishedAt: null },
1758
2008
  { availableLocales: true, availableStatus: false }
1759
2009
  );
1760
2010
  ctx.body = { data: {}, meta };
@@ -1769,7 +2019,7 @@ const collectionTypes = {
1769
2019
  async create(ctx) {
1770
2020
  const { userAbility } = ctx.state;
1771
2021
  const { model } = ctx.params;
1772
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2022
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1773
2023
  const [totalEntries, document] = await Promise.all([
1774
2024
  strapi.db.query(model).count(),
1775
2025
  createDocument(ctx)
@@ -1790,7 +2040,7 @@ const collectionTypes = {
1790
2040
  async update(ctx) {
1791
2041
  const { userAbility } = ctx.state;
1792
2042
  const { model } = ctx.params;
1793
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2043
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1794
2044
  const updatedVersion = await updateDocument(ctx);
1795
2045
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1796
2046
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1799,13 +2049,13 @@ const collectionTypes = {
1799
2049
  const { userAbility, user } = ctx.state;
1800
2050
  const { model, sourceId: id } = ctx.params;
1801
2051
  const { body } = ctx.request;
1802
- const documentManager2 = getService$1("document-manager");
1803
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2052
+ const documentManager2 = getService$2("document-manager");
2053
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1804
2054
  if (permissionChecker2.cannot.create()) {
1805
2055
  return ctx.forbidden();
1806
2056
  }
1807
2057
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1808
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2058
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1809
2059
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1810
2060
  const document = await documentManager2.findOne(id, model, {
1811
2061
  populate,
@@ -1844,13 +2094,13 @@ const collectionTypes = {
1844
2094
  async delete(ctx) {
1845
2095
  const { userAbility } = ctx.state;
1846
2096
  const { id, model } = ctx.params;
1847
- const documentManager2 = getService$1("document-manager");
1848
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2097
+ const documentManager2 = getService$2("document-manager");
2098
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1849
2099
  if (permissionChecker2.cannot.delete()) {
1850
2100
  return ctx.forbidden();
1851
2101
  }
1852
2102
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1853
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2103
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1854
2104
  const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1855
2105
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1856
2106
  if (documentLocales.length === 0) {
@@ -1872,19 +2122,42 @@ const collectionTypes = {
1872
2122
  const { userAbility } = ctx.state;
1873
2123
  const { id, model } = ctx.params;
1874
2124
  const { body } = ctx.request;
1875
- const documentManager2 = getService$1("document-manager");
1876
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2125
+ const documentManager2 = getService$2("document-manager");
2126
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1877
2127
  if (permissionChecker2.cannot.publish()) {
1878
2128
  return ctx.forbidden();
1879
2129
  }
1880
2130
  const publishedDocument = await strapi.db.transaction(async () => {
1881
2131
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1882
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1883
- const document = id ? await updateDocument(ctx, { populate }) : await createDocument(ctx, { populate });
2132
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2133
+ let document;
2134
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2135
+ const isCreate = fp.isNil(id);
2136
+ if (isCreate) {
2137
+ if (permissionChecker2.cannot.create()) {
2138
+ throw new strapiUtils.errors.ForbiddenError();
2139
+ }
2140
+ document = await createDocument(ctx, { populate });
2141
+ }
2142
+ const isUpdate = !isCreate;
2143
+ if (isUpdate) {
2144
+ const documentExists = documentManager2.exists(model, id);
2145
+ if (!documentExists) {
2146
+ throw new strapiUtils.errors.NotFoundError("Document not found");
2147
+ }
2148
+ document = await documentManager2.findOne(id, model, { populate, locale });
2149
+ if (!document) {
2150
+ if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
2151
+ throw new strapiUtils.errors.ForbiddenError();
2152
+ }
2153
+ document = await updateDocument(ctx);
2154
+ } else if (permissionChecker2.can.update(document)) {
2155
+ await updateDocument(ctx);
2156
+ }
2157
+ }
1884
2158
  if (permissionChecker2.cannot.publish(document)) {
1885
2159
  throw new strapiUtils.errors.ForbiddenError();
1886
2160
  }
1887
- const { locale } = await getDocumentLocaleAndStatus(body, model);
1888
2161
  const publishResult = await documentManager2.publish(document.documentId, model, {
1889
2162
  locale
1890
2163
  // TODO: Allow setting creator fields on publish
@@ -1904,13 +2177,13 @@ const collectionTypes = {
1904
2177
  const { body } = ctx.request;
1905
2178
  const { documentIds } = body;
1906
2179
  await validateBulkActionInput(body);
1907
- const documentManager2 = getService$1("document-manager");
1908
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2180
+ const documentManager2 = getService$2("document-manager");
2181
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1909
2182
  if (permissionChecker2.cannot.publish()) {
1910
2183
  return ctx.forbidden();
1911
2184
  }
1912
2185
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1913
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2186
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1914
2187
  const { locale } = await getDocumentLocaleAndStatus(body, model, {
1915
2188
  allowMultipleLocales: true
1916
2189
  });
@@ -1935,12 +2208,14 @@ const collectionTypes = {
1935
2208
  const { body } = ctx.request;
1936
2209
  const { documentIds } = body;
1937
2210
  await validateBulkActionInput(body);
1938
- const documentManager2 = getService$1("document-manager");
1939
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2211
+ const documentManager2 = getService$2("document-manager");
2212
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1940
2213
  if (permissionChecker2.cannot.unpublish()) {
1941
2214
  return ctx.forbidden();
1942
2215
  }
1943
- const { locale } = await getDocumentLocaleAndStatus(body, model);
2216
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2217
+ allowMultipleLocales: true
2218
+ });
1944
2219
  const entityPromises = documentIds.map(
1945
2220
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1946
2221
  );
@@ -1963,8 +2238,8 @@ const collectionTypes = {
1963
2238
  const {
1964
2239
  body: { discardDraft, ...body }
1965
2240
  } = ctx.request;
1966
- const documentManager2 = getService$1("document-manager");
1967
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2241
+ const documentManager2 = getService$2("document-manager");
2242
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1968
2243
  if (permissionChecker2.cannot.unpublish()) {
1969
2244
  return ctx.forbidden();
1970
2245
  }
@@ -1972,7 +2247,7 @@ const collectionTypes = {
1972
2247
  return ctx.forbidden();
1973
2248
  }
1974
2249
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
1975
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2250
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1976
2251
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1977
2252
  const document = await documentManager2.findOne(id, model, {
1978
2253
  populate,
@@ -2003,13 +2278,13 @@ const collectionTypes = {
2003
2278
  const { userAbility } = ctx.state;
2004
2279
  const { id, model } = ctx.params;
2005
2280
  const { body } = ctx.request;
2006
- const documentManager2 = getService$1("document-manager");
2007
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2281
+ const documentManager2 = getService$2("document-manager");
2282
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2008
2283
  if (permissionChecker2.cannot.discard()) {
2009
2284
  return ctx.forbidden();
2010
2285
  }
2011
2286
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
2012
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2287
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2013
2288
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2014
2289
  const document = await documentManager2.findOne(id, model, {
2015
2290
  populate,
@@ -2034,13 +2309,13 @@ const collectionTypes = {
2034
2309
  const { query, body } = ctx.request;
2035
2310
  const { documentIds } = body;
2036
2311
  await validateBulkActionInput(body);
2037
- const documentManager2 = getService$1("document-manager");
2038
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2312
+ const documentManager2 = getService$2("document-manager");
2313
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2039
2314
  if (permissionChecker2.cannot.delete()) {
2040
2315
  return ctx.forbidden();
2041
2316
  }
2042
2317
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2043
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2318
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2044
2319
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2045
2320
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2046
2321
  populate,
@@ -2061,13 +2336,13 @@ const collectionTypes = {
2061
2336
  async countDraftRelations(ctx) {
2062
2337
  const { userAbility } = ctx.state;
2063
2338
  const { model, id } = ctx.params;
2064
- const documentManager2 = getService$1("document-manager");
2065
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2339
+ const documentManager2 = getService$2("document-manager");
2340
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2066
2341
  if (permissionChecker2.cannot.read()) {
2067
2342
  return ctx.forbidden();
2068
2343
  }
2069
2344
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2070
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2345
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2071
2346
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2072
2347
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2073
2348
  if (!entity) {
@@ -2086,8 +2361,8 @@ const collectionTypes = {
2086
2361
  const ids = ctx.request.query.documentIds;
2087
2362
  const locale = ctx.request.query.locale;
2088
2363
  const { model } = ctx.params;
2089
- const documentManager2 = getService$1("document-manager");
2090
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2364
+ const documentManager2 = getService$2("document-manager");
2365
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2091
2366
  if (permissionChecker2.cannot.read()) {
2092
2367
  return ctx.forbidden();
2093
2368
  }
@@ -2111,13 +2386,13 @@ const collectionTypes = {
2111
2386
  };
2112
2387
  const components$1 = {
2113
2388
  findComponents(ctx) {
2114
- const components2 = getService$1("components").findAllComponents();
2115
- const { toDto } = getService$1("data-mapper");
2389
+ const components2 = getService$2("components").findAllComponents();
2390
+ const { toDto } = getService$2("data-mapper");
2116
2391
  ctx.body = { data: components2.map(toDto) };
2117
2392
  },
2118
2393
  async findComponentConfiguration(ctx) {
2119
2394
  const { uid: uid2 } = ctx.params;
2120
- const componentService = getService$1("components");
2395
+ const componentService = getService$2("components");
2121
2396
  const component = componentService.findComponent(uid2);
2122
2397
  if (!component) {
2123
2398
  return ctx.notFound("component.notFound");
@@ -2134,7 +2409,7 @@ const components$1 = {
2134
2409
  async updateComponentConfiguration(ctx) {
2135
2410
  const { uid: uid2 } = ctx.params;
2136
2411
  const { body } = ctx.request;
2137
- const componentService = getService$1("components");
2412
+ const componentService = getService$2("components");
2138
2413
  const component = componentService.findComponent(uid2);
2139
2414
  if (!component) {
2140
2415
  return ctx.notFound("component.notFound");
@@ -2168,12 +2443,12 @@ const contentTypes = {
2168
2443
  } catch (error) {
2169
2444
  return ctx.send({ error }, 400);
2170
2445
  }
2171
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2172
- const { toDto } = getService$1("data-mapper");
2446
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2447
+ const { toDto } = getService$2("data-mapper");
2173
2448
  ctx.body = { data: contentTypes2.map(toDto) };
2174
2449
  },
2175
2450
  async findContentTypesSettings(ctx) {
2176
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2451
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2177
2452
  const contentTypes2 = await findAllContentTypes();
2178
2453
  const configurations = await Promise.all(
2179
2454
  contentTypes2.map(async (contentType) => {
@@ -2187,7 +2462,7 @@ const contentTypes = {
2187
2462
  },
2188
2463
  async findContentTypeConfiguration(ctx) {
2189
2464
  const { uid: uid2 } = ctx.params;
2190
- const contentTypeService = getService$1("content-types");
2465
+ const contentTypeService = getService$2("content-types");
2191
2466
  const contentType = await contentTypeService.findContentType(uid2);
2192
2467
  if (!contentType) {
2193
2468
  return ctx.notFound("contentType.notFound");
@@ -2209,13 +2484,13 @@ const contentTypes = {
2209
2484
  const { userAbility } = ctx.state;
2210
2485
  const { uid: uid2 } = ctx.params;
2211
2486
  const { body } = ctx.request;
2212
- const contentTypeService = getService$1("content-types");
2213
- const metricsService = getService$1("metrics");
2487
+ const contentTypeService = getService$2("content-types");
2488
+ const metricsService = getService$2("metrics");
2214
2489
  const contentType = await contentTypeService.findContentType(uid2);
2215
2490
  if (!contentType) {
2216
2491
  return ctx.notFound("contentType.notFound");
2217
2492
  }
2218
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2493
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2219
2494
  return ctx.forbidden();
2220
2495
  }
2221
2496
  let input;
@@ -2248,10 +2523,10 @@ const contentTypes = {
2248
2523
  };
2249
2524
  const init = {
2250
2525
  getInitData(ctx) {
2251
- const { toDto } = getService$1("data-mapper");
2252
- const { findAllComponents } = getService$1("components");
2253
- const { getAllFieldSizes } = getService$1("field-sizes");
2254
- const { findAllContentTypes } = getService$1("content-types");
2526
+ const { toDto } = getService$2("data-mapper");
2527
+ const { findAllComponents } = getService$2("components");
2528
+ const { getAllFieldSizes } = getService$2("field-sizes");
2529
+ const { findAllContentTypes } = getService$2("content-types");
2255
2530
  ctx.body = {
2256
2531
  data: {
2257
2532
  fieldSizes: getAllFieldSizes(),
@@ -2287,36 +2562,41 @@ const addFiltersClause = (params, filtersClause) => {
2287
2562
  params.filters.$and.push(filtersClause);
2288
2563
  };
2289
2564
  const sanitizeMainField = (model, mainField, userAbility) => {
2290
- const permissionChecker2 = getService$1("permission-checker").create({
2565
+ const permissionChecker2 = getService$2("permission-checker").create({
2291
2566
  userAbility,
2292
2567
  model: model.uid
2293
2568
  });
2294
- if (!isListable(model, mainField)) {
2569
+ const isMainFieldListable = isListable(model, mainField);
2570
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2571
+ if (!isMainFieldListable || !canReadMainField) {
2295
2572
  return "id";
2296
2573
  }
2297
- if (permissionChecker2.cannot.read(null, mainField)) {
2298
- if (model.uid === "plugin::users-permissions.role") {
2299
- const userPermissionChecker = getService$1("permission-checker").create({
2300
- userAbility,
2301
- model: "plugin::users-permissions.user"
2302
- });
2303
- if (userPermissionChecker.can.read()) {
2304
- return "name";
2305
- }
2306
- }
2307
- return "id";
2574
+ if (model.uid === "plugin::users-permissions.role") {
2575
+ return "name";
2308
2576
  }
2309
2577
  return mainField;
2310
2578
  };
2311
- const addStatusToRelations = async (uid2, relations2) => {
2312
- if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2579
+ const addStatusToRelations = async (targetUid, relations2) => {
2580
+ if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
2581
+ return relations2;
2582
+ }
2583
+ const documentMetadata2 = getService$2("document-metadata");
2584
+ if (!relations2.length) {
2313
2585
  return relations2;
2314
2586
  }
2315
- const documentMetadata2 = getService$1("document-metadata");
2316
- const documentsAvailableStatus = await documentMetadata2.getManyAvailableStatus(uid2, relations2);
2587
+ const firstRelation = relations2[0];
2588
+ const filters = {
2589
+ documentId: { $in: relations2.map((r) => r.documentId) },
2590
+ // NOTE: find the "opposite" status
2591
+ publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
2592
+ };
2593
+ const availableStatus = await strapi.query(targetUid).findMany({
2594
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
2595
+ filters
2596
+ });
2317
2597
  return relations2.map((relation) => {
2318
- const availableStatuses = documentsAvailableStatus.filter(
2319
- (availableDocument) => availableDocument.documentId === relation.documentId
2598
+ const availableStatuses = availableStatus.filter(
2599
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2320
2600
  );
2321
2601
  return {
2322
2602
  ...relation,
@@ -2337,11 +2617,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2337
2617
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2338
2618
  const isSourceLocalized = isLocalized(sourceModel);
2339
2619
  const isTargetLocalized = isLocalized(targetModel);
2340
- let validatedLocale = locale;
2341
- if (!targetModel || !isTargetLocalized)
2342
- validatedLocale = void 0;
2343
2620
  return {
2344
- locale: validatedLocale,
2621
+ locale,
2345
2622
  isSourceLocalized,
2346
2623
  isTargetLocalized
2347
2624
  };
@@ -2350,8 +2627,7 @@ const validateStatus = (sourceUid, status) => {
2350
2627
  const sourceModel = strapi.getModel(sourceUid);
2351
2628
  const isDP = strapiUtils.contentTypes.hasDraftAndPublish;
2352
2629
  const isSourceDP = isDP(sourceModel);
2353
- if (!isSourceDP)
2354
- return { status: void 0 };
2630
+ if (!isSourceDP) return { status: void 0 };
2355
2631
  switch (status) {
2356
2632
  case "published":
2357
2633
  return { status: "published" };
@@ -2381,7 +2657,7 @@ const relations = {
2381
2657
  ctx.request?.query?.locale
2382
2658
  );
2383
2659
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2384
- const permissionChecker2 = getService$1("permission-checker").create({
2660
+ const permissionChecker2 = getService$2("permission-checker").create({
2385
2661
  userAbility,
2386
2662
  model
2387
2663
  });
@@ -2406,7 +2682,7 @@ const relations = {
2406
2682
  where.id = id;
2407
2683
  }
2408
2684
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2409
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2685
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2410
2686
  const currentEntity = await strapi.db.query(model).findOne({
2411
2687
  where,
2412
2688
  populate
@@ -2421,7 +2697,7 @@ const relations = {
2421
2697
  }
2422
2698
  entryId = currentEntity.id;
2423
2699
  }
2424
- const modelConfig = isComponent2 ? await getService$1("components").findConfiguration(sourceSchema) : await getService$1("content-types").findConfiguration(sourceSchema);
2700
+ const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
2425
2701
  const targetSchema = strapi.getModel(targetUid);
2426
2702
  const mainField = fp.flow(
2427
2703
  fp.prop(`metadatas.${targetField}.edit.mainField`),
@@ -2444,7 +2720,7 @@ const relations = {
2444
2720
  attribute,
2445
2721
  fieldsToSelect,
2446
2722
  mainField,
2447
- source: { schema: sourceSchema },
2723
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2448
2724
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2449
2725
  sourceSchema,
2450
2726
  targetSchema,
@@ -2466,7 +2742,8 @@ const relations = {
2466
2742
  fieldsToSelect,
2467
2743
  mainField,
2468
2744
  source: {
2469
- schema: { uid: sourceUid, modelType: sourceModelType }
2745
+ schema: { uid: sourceUid, modelType: sourceModelType },
2746
+ isLocalized: isSourceLocalized
2470
2747
  },
2471
2748
  target: {
2472
2749
  schema: { uid: targetUid },
@@ -2474,7 +2751,7 @@ const relations = {
2474
2751
  }
2475
2752
  } = await this.extractAndValidateRequestInfo(ctx, id);
2476
2753
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2477
- const permissionChecker2 = getService$1("permission-checker").create({
2754
+ const permissionChecker2 = getService$2("permission-checker").create({
2478
2755
  userAbility: ctx.state.userAbility,
2479
2756
  model: targetUid
2480
2757
  });
@@ -2504,12 +2781,16 @@ const relations = {
2504
2781
  } else {
2505
2782
  where.id = id;
2506
2783
  }
2507
- if (status) {
2508
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2784
+ const publishedAt = getPublishedAtClause(status, targetUid);
2785
+ if (!fp.isEmpty(publishedAt)) {
2786
+ where[`${alias}.published_at`] = publishedAt;
2509
2787
  }
2510
- if (filterByLocale) {
2788
+ if (isTargetLocalized && locale) {
2511
2789
  where[`${alias}.locale`] = locale;
2512
2790
  }
2791
+ if (isSourceLocalized && locale) {
2792
+ where.locale = locale;
2793
+ }
2513
2794
  if ((idsToInclude?.length ?? 0) !== 0) {
2514
2795
  where[`${alias}.id`].$notIn = idsToInclude;
2515
2796
  }
@@ -2527,7 +2808,8 @@ const relations = {
2527
2808
  id: { $notIn: fp.uniq(idsToOmit) }
2528
2809
  });
2529
2810
  }
2530
- const res = await strapi.db.query(targetUid).findPage(strapi.get("query-params").transform(targetUid, queryParams));
2811
+ const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
2812
+ const res = await strapi.db.query(targetUid).findPage(dbQuery);
2531
2813
  ctx.body = {
2532
2814
  ...res,
2533
2815
  results: await addStatusToRelations(targetUid, res.results)
@@ -2542,29 +2824,39 @@ const relations = {
2542
2824
  attribute,
2543
2825
  targetField,
2544
2826
  fieldsToSelect,
2545
- source: {
2546
- schema: { uid: sourceUid }
2547
- },
2548
- target: {
2549
- schema: { uid: targetUid }
2550
- }
2827
+ status,
2828
+ source: { schema: sourceSchema },
2829
+ target: { schema: targetSchema }
2551
2830
  } = await this.extractAndValidateRequestInfo(ctx, id);
2552
- const permissionQuery = await getService$1("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2831
+ const { uid: sourceUid } = sourceSchema;
2832
+ const { uid: targetUid } = targetSchema;
2833
+ const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2553
2834
  const dbQuery = strapi.db.query(sourceUid);
2554
2835
  const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
2836
+ const filters = {};
2837
+ if (sourceSchema?.options?.draftAndPublish) {
2838
+ if (targetSchema?.options?.draftAndPublish) {
2839
+ if (status === "published") {
2840
+ filters.publishedAt = { $notNull: true };
2841
+ } else {
2842
+ filters.publishedAt = { $null: true };
2843
+ }
2844
+ }
2845
+ } else if (targetSchema?.options?.draftAndPublish) {
2846
+ filters.publishedAt = { $null: true };
2847
+ }
2555
2848
  const res = await loadRelations({ id: entryId }, targetField, {
2556
- select: ["id", "documentId", "locale", "publishedAt"],
2849
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2557
2850
  ordering: "desc",
2558
2851
  page: ctx.request.query.page,
2559
- pageSize: ctx.request.query.pageSize
2852
+ pageSize: ctx.request.query.pageSize,
2853
+ filters
2560
2854
  });
2561
2855
  const loadedIds = res.results.map((item) => item.id);
2562
2856
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2563
2857
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2564
2858
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2565
- ordering: "desc",
2566
- page: ctx.request.query.page,
2567
- pageSize: ctx.request.query.pageSize
2859
+ ordering: "desc"
2568
2860
  });
2569
2861
  const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
2570
2862
  ctx.body = {
@@ -2579,10 +2871,10 @@ const relations = {
2579
2871
  }
2580
2872
  };
2581
2873
  const buildPopulateFromQuery = async (query, model) => {
2582
- return getService$1("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2874
+ return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2583
2875
  };
2584
2876
  const findDocument = async (query, uid2, opts = {}) => {
2585
- const documentManager2 = getService$1("document-manager");
2877
+ const documentManager2 = getService$2("document-manager");
2586
2878
  const populate = await buildPopulateFromQuery(query, uid2);
2587
2879
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2588
2880
  };
@@ -2590,8 +2882,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
2590
2882
  const { user, userAbility } = ctx.state;
2591
2883
  const { model } = ctx.params;
2592
2884
  const { body, query } = ctx.request;
2593
- const documentManager2 = getService$1("document-manager");
2594
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2885
+ const documentManager2 = getService$2("document-manager");
2886
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2595
2887
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2596
2888
  throw new strapiUtils.errors.ForbiddenError();
2597
2889
  }
@@ -2632,7 +2924,7 @@ const singleTypes = {
2632
2924
  const { userAbility } = ctx.state;
2633
2925
  const { model } = ctx.params;
2634
2926
  const { query = {} } = ctx.request;
2635
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2927
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2636
2928
  if (permissionChecker2.cannot.read()) {
2637
2929
  return ctx.forbidden();
2638
2930
  }
@@ -2651,7 +2943,7 @@ const singleTypes = {
2651
2943
  permissionChecker2,
2652
2944
  model,
2653
2945
  // @ts-expect-error - fix types
2654
- { id: document.documentId, locale, publishedAt: null },
2946
+ { documentId: document.documentId, locale, publishedAt: null },
2655
2947
  { availableLocales: true, availableStatus: false }
2656
2948
  );
2657
2949
  ctx.body = { data: {}, meta };
@@ -2666,7 +2958,7 @@ const singleTypes = {
2666
2958
  async createOrUpdate(ctx) {
2667
2959
  const { userAbility } = ctx.state;
2668
2960
  const { model } = ctx.params;
2669
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2961
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2670
2962
  const document = await createOrUpdateDocument(ctx);
2671
2963
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2672
2964
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2675,8 +2967,8 @@ const singleTypes = {
2675
2967
  const { userAbility } = ctx.state;
2676
2968
  const { model } = ctx.params;
2677
2969
  const { query = {} } = ctx.request;
2678
- const documentManager2 = getService$1("document-manager");
2679
- 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 });
2680
2972
  if (permissionChecker2.cannot.delete()) {
2681
2973
  return ctx.forbidden();
2682
2974
  }
@@ -2704,8 +2996,8 @@ const singleTypes = {
2704
2996
  const { userAbility } = ctx.state;
2705
2997
  const { model } = ctx.params;
2706
2998
  const { query = {} } = ctx.request;
2707
- const documentManager2 = getService$1("document-manager");
2708
- 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 });
2709
3001
  if (permissionChecker2.cannot.publish()) {
2710
3002
  return ctx.forbidden();
2711
3003
  }
@@ -2733,8 +3025,8 @@ const singleTypes = {
2733
3025
  body: { discardDraft, ...body },
2734
3026
  query = {}
2735
3027
  } = ctx.request;
2736
- const documentManager2 = getService$1("document-manager");
2737
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3028
+ const documentManager2 = getService$2("document-manager");
3029
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2738
3030
  if (permissionChecker2.cannot.unpublish()) {
2739
3031
  return ctx.forbidden();
2740
3032
  }
@@ -2768,8 +3060,8 @@ const singleTypes = {
2768
3060
  const { userAbility } = ctx.state;
2769
3061
  const { model } = ctx.params;
2770
3062
  const { body, query = {} } = ctx.request;
2771
- const documentManager2 = getService$1("document-manager");
2772
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3063
+ const documentManager2 = getService$2("document-manager");
3064
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2773
3065
  if (permissionChecker2.cannot.discard()) {
2774
3066
  return ctx.forbidden();
2775
3067
  }
@@ -2792,8 +3084,8 @@ const singleTypes = {
2792
3084
  const { userAbility } = ctx.state;
2793
3085
  const { model } = ctx.params;
2794
3086
  const { query } = ctx.request;
2795
- const documentManager2 = getService$1("document-manager");
2796
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3087
+ const documentManager2 = getService$2("document-manager");
3088
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2797
3089
  const { locale } = await getDocumentLocaleAndStatus(query, model);
2798
3090
  if (permissionChecker2.cannot.read()) {
2799
3091
  return ctx.forbidden();
@@ -2817,7 +3109,7 @@ const uid$1 = {
2817
3109
  const { query = {} } = ctx.request;
2818
3110
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2819
3111
  await validateUIDField(contentTypeUID, field);
2820
- const uidService = getService$1("uid");
3112
+ const uidService = getService$2("uid");
2821
3113
  ctx.body = {
2822
3114
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2823
3115
  };
@@ -2829,7 +3121,7 @@ const uid$1 = {
2829
3121
  const { query = {} } = ctx.request;
2830
3122
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2831
3123
  await validateUIDField(contentTypeUID, field);
2832
- const uidService = getService$1("uid");
3124
+ const uidService = getService$2("uid");
2833
3125
  const isAvailable = await uidService.checkUIDAvailability({
2834
3126
  contentTypeUID,
2835
3127
  field,
@@ -2850,7 +3142,8 @@ const controllers = {
2850
3142
  relations,
2851
3143
  "single-types": singleTypes,
2852
3144
  uid: uid$1,
2853
- ...history.controllers ? history.controllers : {}
3145
+ ...history.controllers ? history.controllers : {},
3146
+ ...preview.controllers ? preview.controllers : {}
2854
3147
  };
2855
3148
  const keys = {
2856
3149
  CONFIGURATION: "configuration"
@@ -2979,18 +3272,15 @@ async function syncMetadatas(configuration, schema) {
2979
3272
  ___default.default.set(updatedMeta, ["list", "searchable"], false);
2980
3273
  ___default.default.set(acc, [key], updatedMeta);
2981
3274
  }
2982
- if (!___default.default.has(edit, "mainField"))
2983
- return acc;
3275
+ if (!___default.default.has(edit, "mainField")) return acc;
2984
3276
  if (!isRelation$1(attr)) {
2985
3277
  ___default.default.set(updatedMeta, "edit", ___default.default.omit(edit, ["mainField"]));
2986
3278
  ___default.default.set(acc, [key], updatedMeta);
2987
3279
  return acc;
2988
3280
  }
2989
- if (edit.mainField === "id")
2990
- return acc;
3281
+ if (edit.mainField === "id") return acc;
2991
3282
  const targetSchema = getTargetSchema(attr.targetModel);
2992
- if (!targetSchema)
2993
- return acc;
3283
+ if (!targetSchema) return acc;
2994
3284
  if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
2995
3285
  ___default.default.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
2996
3286
  ___default.default.set(acc, [key], updatedMeta);
@@ -3001,12 +3291,12 @@ async function syncMetadatas(configuration, schema) {
3001
3291
  return ___default.default.assign(metasWithDefaults, updatedMetas);
3002
3292
  }
3003
3293
  const getTargetSchema = (targetModel) => {
3004
- return getService$1("content-types").findContentType(targetModel);
3294
+ return getService$2("content-types").findContentType(targetModel);
3005
3295
  };
3006
3296
  const DEFAULT_LIST_LENGTH = 4;
3007
3297
  const MAX_ROW_SIZE = 12;
3008
3298
  const isAllowedFieldSize = (type, size) => {
3009
- const { getFieldSize } = getService$1("field-sizes");
3299
+ const { getFieldSize } = getService$2("field-sizes");
3010
3300
  const fieldSize = getFieldSize(type);
3011
3301
  if (!fieldSize.isResizable && size !== fieldSize.default) {
3012
3302
  return false;
@@ -3014,7 +3304,7 @@ const isAllowedFieldSize = (type, size) => {
3014
3304
  return size <= MAX_ROW_SIZE;
3015
3305
  };
3016
3306
  const getDefaultFieldSize = (attribute) => {
3017
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3307
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
3018
3308
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
3019
3309
  };
3020
3310
  async function createDefaultLayouts(schema) {
@@ -3035,8 +3325,7 @@ function createDefaultEditLayout(schema) {
3035
3325
  return appendToEditLayout([], keys2, schema);
3036
3326
  }
3037
3327
  function syncLayouts(configuration, schema) {
3038
- if (___default.default.isEmpty(configuration.layouts))
3039
- return createDefaultLayouts(schema);
3328
+ if (___default.default.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
3040
3329
  const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
3041
3330
  let cleanList = list.filter((attr) => isListable(schema, attr));
3042
3331
  const cleanEditRelations = editRelations.filter(
@@ -3047,9 +3336,8 @@ function syncLayouts(configuration, schema) {
3047
3336
  for (const row of edit) {
3048
3337
  const newRow = [];
3049
3338
  for (const el of row) {
3050
- if (!hasEditableAttribute(schema, el.name))
3051
- continue;
3052
- const { hasFieldSize } = getService$1("field-sizes");
3339
+ if (!hasEditableAttribute(schema, el.name)) continue;
3340
+ const { hasFieldSize } = getService$2("field-sizes");
3053
3341
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3054
3342
  if (!isAllowedFieldSize(fieldType, el.size)) {
3055
3343
  elementsToReAppend.push(el.name);
@@ -3079,8 +3367,7 @@ function syncLayouts(configuration, schema) {
3079
3367
  };
3080
3368
  }
3081
3369
  const appendToEditLayout = (layout = [], keysToAppend, schema) => {
3082
- if (keysToAppend.length === 0)
3083
- return layout;
3370
+ if (keysToAppend.length === 0) return layout;
3084
3371
  let currentRowIndex = Math.max(layout.length - 1, 0);
3085
3372
  if (!layout[currentRowIndex]) {
3086
3373
  layout[currentRowIndex] = [];
@@ -3189,17 +3476,17 @@ const configurationService$1 = createConfigurationService({
3189
3476
  isComponent: true,
3190
3477
  prefix: STORE_KEY_PREFIX,
3191
3478
  getModels() {
3192
- const { toContentManagerModel } = getService$1("data-mapper");
3479
+ const { toContentManagerModel } = getService$2("data-mapper");
3193
3480
  return fp.mapValues(toContentManagerModel, strapi.components);
3194
3481
  }
3195
3482
  });
3196
3483
  const components = ({ strapi: strapi2 }) => ({
3197
3484
  findAllComponents() {
3198
- const { toContentManagerModel } = getService$1("data-mapper");
3485
+ const { toContentManagerModel } = getService$2("data-mapper");
3199
3486
  return Object.values(strapi2.components).map(toContentManagerModel);
3200
3487
  },
3201
3488
  findComponent(uid2) {
3202
- const { toContentManagerModel } = getService$1("data-mapper");
3489
+ const { toContentManagerModel } = getService$2("data-mapper");
3203
3490
  const component = strapi2.components[uid2];
3204
3491
  return fp.isNil(component) ? component : toContentManagerModel(component);
3205
3492
  },
@@ -3250,17 +3537,17 @@ const configurationService = createConfigurationService({
3250
3537
  storeUtils,
3251
3538
  prefix: "content_types",
3252
3539
  getModels() {
3253
- const { toContentManagerModel } = getService$1("data-mapper");
3540
+ const { toContentManagerModel } = getService$2("data-mapper");
3254
3541
  return fp.mapValues(toContentManagerModel, strapi.contentTypes);
3255
3542
  }
3256
3543
  });
3257
3544
  const service = ({ strapi: strapi2 }) => ({
3258
3545
  findAllContentTypes() {
3259
- const { toContentManagerModel } = getService$1("data-mapper");
3546
+ const { toContentManagerModel } = getService$2("data-mapper");
3260
3547
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3261
3548
  },
3262
3549
  findContentType(uid2) {
3263
- const { toContentManagerModel } = getService$1("data-mapper");
3550
+ const { toContentManagerModel } = getService$2("data-mapper");
3264
3551
  const contentType = strapi2.contentTypes[uid2];
3265
3552
  return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
3266
3553
  },
@@ -3289,7 +3576,7 @@ const service = ({ strapi: strapi2 }) => ({
3289
3576
  return this.findConfiguration(contentType);
3290
3577
  },
3291
3578
  findComponentsConfigurations(contentType) {
3292
- return getService$1("components").findComponentsConfigurations(contentType);
3579
+ return getService$2("components").findComponentsConfigurations(contentType);
3293
3580
  },
3294
3581
  syncConfigurations() {
3295
3582
  return configurationService.syncConfigurations();
@@ -3470,12 +3757,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3470
3757
  ability: userAbility,
3471
3758
  model
3472
3759
  });
3473
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3760
+ const { actionProvider } = strapi2.service("admin::permission");
3761
+ const toSubject = (entity) => {
3762
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3763
+ };
3474
3764
  const can = (action, entity, field) => {
3475
- return userAbility.can(action, toSubject(entity), field);
3765
+ const subject = toSubject(entity);
3766
+ const aliases = actionProvider.unstable_aliases(action, model);
3767
+ return (
3768
+ // Test the original action to see if it passes
3769
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3770
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3771
+ );
3476
3772
  };
3477
3773
  const cannot = (action, entity, field) => {
3478
- return userAbility.cannot(action, toSubject(entity), field);
3774
+ const subject = toSubject(entity);
3775
+ const aliases = actionProvider.unstable_aliases(action, model);
3776
+ return (
3777
+ // Test both the original action
3778
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3779
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3780
+ );
3479
3781
  };
3480
3782
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3481
3783
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3546,7 +3848,7 @@ const permission = ({ strapi: strapi2 }) => ({
3546
3848
  return userAbility.can(action);
3547
3849
  },
3548
3850
  async registerPermissions() {
3549
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3851
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3550
3852
  const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
3551
3853
  const actions = [
3552
3854
  {
@@ -3822,7 +4124,7 @@ const getQueryPopulate = async (uid2, query) => {
3822
4124
  return populateQuery;
3823
4125
  };
3824
4126
  const buildDeepPopulate = (uid2) => {
3825
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4127
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3826
4128
  };
3827
4129
  const populateBuilder = (uid2) => {
3828
4130
  let getInitialPopulate = async () => {
@@ -4007,7 +4309,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4007
4309
  */
4008
4310
  async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4009
4311
  const versionsByLocale = fp.groupBy("locale", allVersions);
4010
- delete versionsByLocale[version.locale];
4312
+ if (version.locale) {
4313
+ delete versionsByLocale[version.locale];
4314
+ }
4011
4315
  const model = strapi2.getModel(uid2);
4012
4316
  const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4013
4317
  const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
@@ -4054,8 +4358,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4054
4358
  const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
4055
4359
  return matchLocale && matchStatus;
4056
4360
  });
4057
- if (!availableStatus)
4058
- return availableStatus;
4361
+ if (!availableStatus) return availableStatus;
4059
4362
  return fp.pick(AVAILABLE_STATUS_FIELDS, availableStatus);
4060
4363
  },
4061
4364
  /**
@@ -4065,8 +4368,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4065
4368
  * @returns
4066
4369
  */
4067
4370
  async getManyAvailableStatus(uid2, documents) {
4068
- if (!documents.length)
4069
- return [];
4371
+ if (!documents.length) return [];
4070
4372
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4071
4373
  const locale = documents[0]?.locale;
4072
4374
  const otherStatus = status === "published" ? "draft" : "published";
@@ -4093,10 +4395,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4093
4395
  } else if (otherVersion) {
4094
4396
  draftVersion = otherVersion;
4095
4397
  }
4096
- if (!draftVersion)
4097
- return CONTENT_MANAGER_STATUS.PUBLISHED;
4098
- if (!publishedVersion)
4099
- return CONTENT_MANAGER_STATUS.DRAFT;
4398
+ if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
4399
+ if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
4100
4400
  const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
4101
4401
  return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
4102
4402
  },
@@ -4133,7 +4433,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4133
4433
  */
4134
4434
  async formatDocumentWithMetadata(uid2, document, opts = {}) {
4135
4435
  if (!document) {
4136
- return document;
4436
+ return {
4437
+ data: document,
4438
+ meta: {
4439
+ availableLocales: [],
4440
+ availableStatus: []
4441
+ }
4442
+ };
4137
4443
  }
4138
4444
  const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
4139
4445
  if (!hasDraftAndPublish) {
@@ -4357,7 +4663,8 @@ const services = {
4357
4663
  permission,
4358
4664
  "populate-builder": populateBuilder$1,
4359
4665
  uid,
4360
- ...history.services ? history.services : {}
4666
+ ...history.services ? history.services : {},
4667
+ ...preview.services ? preview.services : {}
4361
4668
  };
4362
4669
  const index = () => {
4363
4670
  return {