@strapi/content-manager 0.0.0-experimental.cb311d9fcfbd8e441f790aea232f0a39bdd90e16 → 0.0.0-experimental.cfda358b7f27015e34e739b8742a2962ae2e7aee

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-DL1MHO8i.js → ComponentConfigurationPage-BTR_hQow.js} +5 -6
  4. package/dist/_chunks/{ComponentConfigurationPage-DL1MHO8i.js.map → ComponentConfigurationPage-BTR_hQow.js.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-D0dyDTwq.mjs → ComponentConfigurationPage-bLQr82ce.mjs} +4 -4
  6. package/dist/_chunks/{ComponentConfigurationPage-D0dyDTwq.mjs.map → ComponentConfigurationPage-bLQr82ce.mjs.map} +1 -1
  7. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  9. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  10. package/dist/_chunks/{EditConfigurationPage-13b7S5Cq.mjs → EditConfigurationPage-BhRSnUsL.mjs} +4 -4
  11. package/dist/_chunks/{EditConfigurationPage-13b7S5Cq.mjs.map → EditConfigurationPage-BhRSnUsL.mjs.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-CMaOf-A-.js → EditConfigurationPage-z39Wv3E6.js} +5 -6
  13. package/dist/_chunks/{EditConfigurationPage-CMaOf-A-.js.map → EditConfigurationPage-z39Wv3E6.js.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-C3tIZ8F5.mjs → EditViewPage-BCjNxNlY.mjs} +63 -12
  15. package/dist/_chunks/EditViewPage-BCjNxNlY.mjs.map +1 -0
  16. package/dist/_chunks/{EditViewPage-BSVmMpRd.js → EditViewPage-wujOq90c.js} +63 -13
  17. package/dist/_chunks/EditViewPage-wujOq90c.js.map +1 -0
  18. package/dist/_chunks/{Field-DUCVth4C.js → Field-B5QXnctJ.js} +320 -169
  19. package/dist/_chunks/Field-B5QXnctJ.js.map +1 -0
  20. package/dist/_chunks/{Field-BvuT8cGL.mjs → Field-Byr3mPTl.mjs} +316 -165
  21. package/dist/_chunks/Field-Byr3mPTl.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-BZmDNVr9.mjs → Form-BZgvE8C8.mjs} +37 -18
  25. package/dist/_chunks/Form-BZgvE8C8.mjs.map +1 -0
  26. package/dist/_chunks/{Form-Cpl4W1ak.js → Form-D7mexvm3.js} +39 -21
  27. package/dist/_chunks/Form-D7mexvm3.js.map +1 -0
  28. package/dist/_chunks/{History-Cq_Hrzuu.mjs → History-CqNgxkqK.mjs} +43 -100
  29. package/dist/_chunks/History-CqNgxkqK.mjs.map +1 -0
  30. package/dist/_chunks/{History-D4U2YISB.js → History-DYl2A8Z_.js} +42 -100
  31. package/dist/_chunks/History-DYl2A8Z_.js.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-Bny6CdWe.js → ListConfigurationPage-BXnu_OoY.js} +19 -9
  33. package/dist/_chunks/ListConfigurationPage-BXnu_OoY.js.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-W-KQHmBv.mjs → ListConfigurationPage-BbQjzKkQ.mjs} +19 -8
  35. package/dist/_chunks/ListConfigurationPage-BbQjzKkQ.mjs.map +1 -0
  36. package/dist/_chunks/{ListViewPage-O8F1pBJo.js → ListViewPage-BtSi8C1l.js} +103 -77
  37. package/dist/_chunks/ListViewPage-BtSi8C1l.js.map +1 -0
  38. package/dist/_chunks/{ListViewPage-HBBnJa8K.mjs → ListViewPage-D4ofkbjR.mjs} +99 -72
  39. package/dist/_chunks/ListViewPage-D4ofkbjR.mjs.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-CQWChGPw.js → NoContentTypePage-CitJeOq4.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-CQWChGPw.js.map → NoContentTypePage-CitJeOq4.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-B-gIhHWM.mjs → NoContentTypePage-DyUx5mXh.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-B-gIhHWM.mjs.map → NoContentTypePage-DyUx5mXh.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-XhOPl8wx.mjs → NoPermissionsPage-DhIiyWkk.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-XhOPl8wx.mjs.map → NoPermissionsPage-DhIiyWkk.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-CY46zxnM.js → NoPermissionsPage-DzgWz0M-.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-CY46zxnM.js.map → NoPermissionsPage-DzgWz0M-.js.map} +1 -1
  48. package/dist/_chunks/Preview-BaYGJ0nb.mjs +293 -0
  49. package/dist/_chunks/Preview-BaYGJ0nb.mjs.map +1 -0
  50. package/dist/_chunks/Preview-DfNx8Ke-.js +311 -0
  51. package/dist/_chunks/Preview-DfNx8Ke-.js.map +1 -0
  52. package/dist/_chunks/{Relations-vFZ6Wasg.mjs → Relations-DM2yUTST.mjs} +76 -42
  53. package/dist/_chunks/Relations-DM2yUTST.mjs.map +1 -0
  54. package/dist/_chunks/{Relations-C4gGfZRv.js → Relations-DuKCaXrv.js} +76 -43
  55. package/dist/_chunks/Relations-DuKCaXrv.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-5EMXLEM_.js → index-BUWEmX8m.js} +1320 -996
  70. package/dist/_chunks/index-BUWEmX8m.js.map +1 -0
  71. package/dist/_chunks/{index-Dpxg3ctD.mjs → index-DVAIIsOs.mjs} +1338 -1014
  72. package/dist/_chunks/index-DVAIIsOs.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-C0INpKap.mjs → layout-Bxsv5mP7.mjs} +9 -8
  78. package/dist/_chunks/layout-Bxsv5mP7.mjs.map +1 -0
  79. package/dist/_chunks/{layout-P3eKO1Qy.js → layout-C3fN7Ejz.js} +10 -10
  80. package/dist/_chunks/layout-C3fN7Ejz.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-B1y0K6LE.js → relations-BPZKAoEY.js} +6 -7
  86. package/dist/_chunks/relations-BPZKAoEY.js.map +1 -0
  87. package/dist/_chunks/{relations-FBRRBWeO.mjs → relations-o3pPhzY4.mjs} +6 -7
  88. package/dist/_chunks/relations-o3pPhzY4.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/BlocksInput/Blocks/Code.d.ts +7 -0
  108. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  109. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  110. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  111. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  112. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  113. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  114. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  115. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  116. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  117. package/dist/admin/src/preview/index.d.ts +4 -0
  118. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  119. package/dist/admin/src/preview/routes.d.ts +3 -0
  120. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  121. package/dist/admin/src/router.d.ts +1 -1
  122. package/dist/admin/src/services/api.d.ts +1 -1
  123. package/dist/admin/src/services/components.d.ts +2 -2
  124. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  125. package/dist/admin/src/services/documents.d.ts +19 -20
  126. package/dist/admin/src/services/init.d.ts +1 -1
  127. package/dist/admin/src/services/relations.d.ts +2 -2
  128. package/dist/admin/src/services/uid.d.ts +3 -3
  129. package/dist/admin/src/utils/validation.d.ts +4 -1
  130. package/dist/server/index.js +482 -219
  131. package/dist/server/index.js.map +1 -1
  132. package/dist/server/index.mjs +482 -218
  133. package/dist/server/index.mjs.map +1 -1
  134. package/dist/server/src/bootstrap.d.ts.map +1 -1
  135. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  136. package/dist/server/src/controllers/index.d.ts.map +1 -1
  137. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  138. package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
  139. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  140. package/dist/server/src/history/services/history.d.ts.map +1 -1
  141. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  142. package/dist/server/src/history/services/utils.d.ts +3 -3
  143. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  144. package/dist/server/src/index.d.ts +4 -4
  145. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  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 +17 -15
  189. package/dist/_chunks/EditViewPage-BSVmMpRd.js.map +0 -1
  190. package/dist/_chunks/EditViewPage-C3tIZ8F5.mjs.map +0 -1
  191. package/dist/_chunks/Field-BvuT8cGL.mjs.map +0 -1
  192. package/dist/_chunks/Field-DUCVth4C.js.map +0 -1
  193. package/dist/_chunks/Form-BZmDNVr9.mjs.map +0 -1
  194. package/dist/_chunks/Form-Cpl4W1ak.js.map +0 -1
  195. package/dist/_chunks/History-Cq_Hrzuu.mjs.map +0 -1
  196. package/dist/_chunks/History-D4U2YISB.js.map +0 -1
  197. package/dist/_chunks/ListConfigurationPage-Bny6CdWe.js.map +0 -1
  198. package/dist/_chunks/ListConfigurationPage-W-KQHmBv.mjs.map +0 -1
  199. package/dist/_chunks/ListViewPage-HBBnJa8K.mjs.map +0 -1
  200. package/dist/_chunks/ListViewPage-O8F1pBJo.js.map +0 -1
  201. package/dist/_chunks/Relations-C4gGfZRv.js.map +0 -1
  202. package/dist/_chunks/Relations-vFZ6Wasg.mjs.map +0 -1
  203. package/dist/_chunks/index-5EMXLEM_.js.map +0 -1
  204. package/dist/_chunks/index-Dpxg3ctD.mjs.map +0 -1
  205. package/dist/_chunks/layout-C0INpKap.mjs.map +0 -1
  206. package/dist/_chunks/layout-P3eKO1Qy.js.map +0 -1
  207. package/dist/_chunks/relations-B1y0K6LE.js.map +0 -1
  208. package/dist/_chunks/relations-FBRRBWeO.mjs.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
@@ -1,5 +1,5 @@
1
1
  import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
2
- import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
2
+ import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
3
3
  import "@strapi/types";
4
4
  import * as yup from "yup";
5
5
  import { scheduleJob } from "node-schedule";
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
7
7
  import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
8
8
  import qs from "qs";
9
9
  import slugify from "@sindresorhus/slugify";
10
- const getService$1 = (name) => {
10
+ const getService$2 = (name) => {
11
11
  return strapi.plugin("content-manager").service(name);
12
12
  };
13
- function getService(strapi2, name) {
13
+ function getService$1(strapi2, name) {
14
14
  return strapi2.service(`plugin::content-manager.${name}`);
15
15
  }
16
16
  const historyRestoreVersionSchema = yup.object().shape({
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
46
46
  if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
47
47
  throw new errors.ForbiddenError("contentType and documentId are required");
48
48
  }
49
- const permissionChecker2 = getService$1("permission-checker").create({
49
+ const permissionChecker2 = getService$2("permission-checker").create({
50
50
  userAbility: ctx.state.userAbility,
51
51
  model: ctx.query.contentType
52
52
  });
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
54
54
  return ctx.forbidden();
55
55
  }
56
56
  const query = await permissionChecker2.sanitizeQuery(ctx.query);
57
- const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
57
+ const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
58
58
  query: {
59
59
  ...query,
60
60
  ...getValidPagination({ page: query.page, pageSize: query.pageSize })
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
79
79
  async restoreVersion(ctx) {
80
80
  const request = ctx.request;
81
81
  await validateRestoreVersion(request.body, "contentType is required");
82
- const permissionChecker2 = getService$1("permission-checker").create({
82
+ const permissionChecker2 = getService$2("permission-checker").create({
83
83
  userAbility: ctx.state.userAbility,
84
84
  model: request.body.contentType
85
85
  });
86
86
  if (permissionChecker2.cannot.update()) {
87
87
  throw new errors.ForbiddenError();
88
88
  }
89
- const restoredDocument = await getService(strapi2, "history").restoreVersion(
89
+ const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
90
90
  request.params.versionId
91
91
  );
92
92
  return {
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
95
95
  }
96
96
  };
97
97
  };
98
- const controllers$1 = {
98
+ const controllers$2 = {
99
99
  "history-version": createHistoryVersionController
100
100
  /**
101
101
  * Casting is needed because the types aren't aware that Strapi supports
@@ -141,8 +141,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
141
141
  };
142
142
  const getRelationRestoreValue = async (versionRelationData, attribute) => {
143
143
  if (Array.isArray(versionRelationData)) {
144
- if (versionRelationData.length === 0)
145
- return versionRelationData;
144
+ if (versionRelationData.length === 0) return versionRelationData;
146
145
  const existingAndMissingRelations = await Promise.all(
147
146
  versionRelationData.map((relation) => {
148
147
  return strapi2.documents(attribute.target).findOne({
@@ -173,10 +172,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
173
172
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
174
173
  };
175
174
  const localesService = strapi2.plugin("i18n")?.service("locales");
175
+ const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
176
176
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
177
+ const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
177
178
  const getLocaleDictionary = async () => {
178
- if (!localesService)
179
- return {};
179
+ if (!localesService) return {};
180
180
  const locales = await localesService.find() || [];
181
181
  return locales.reduce(
182
182
  (acc, locale) => {
@@ -200,6 +200,17 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
200
200
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
201
201
  return documentMetadataService.getStatus(document, meta.availableStatus);
202
202
  };
203
+ const getComponentFields = (componentUID) => {
204
+ return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
205
+ (fieldsAcc, [key, attribute]) => {
206
+ if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
207
+ fieldsAcc.push(key);
208
+ }
209
+ return fieldsAcc;
210
+ },
211
+ []
212
+ );
213
+ };
203
214
  const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
204
215
  const model = strapi2.getModel(uid2);
205
216
  const attributes = Object.entries(model.attributes);
@@ -223,13 +234,19 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
223
234
  }
224
235
  case "component": {
225
236
  const populate = getDeepPopulate2(attribute.component);
226
- acc[attributeName] = { populate };
237
+ acc[attributeName] = {
238
+ populate,
239
+ [fieldSelector]: getComponentFields(attribute.component)
240
+ };
227
241
  break;
228
242
  }
229
243
  case "dynamiczone": {
230
244
  const populatedComponents = (attribute.components || []).reduce(
231
245
  (acc2, componentUID) => {
232
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
246
+ acc2[componentUID] = {
247
+ populate: getDeepPopulate2(componentUID),
248
+ [fieldSelector]: getComponentFields(componentUID)
249
+ };
233
250
  return acc2;
234
251
  },
235
252
  {}
@@ -291,6 +308,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
291
308
  getRelationRestoreValue,
292
309
  getMediaRestoreValue,
293
310
  getDefaultLocale,
311
+ isLocalizedContentType,
294
312
  getLocaleDictionary,
295
313
  getRetentionDays,
296
314
  getVersionStatus,
@@ -313,7 +331,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
313
331
  });
314
332
  },
315
333
  async findVersionsPage(params) {
316
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
334
+ const model = strapi2.getModel(params.query.contentType);
335
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
336
+ const defaultLocale = await serviceUtils.getDefaultLocale();
337
+ let locale = null;
338
+ if (isLocalizedContentType) {
339
+ locale = params.query.locale || defaultLocale;
340
+ }
317
341
  const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
318
342
  query.findPage({
319
343
  ...params.query,
@@ -335,7 +359,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
335
359
  const attributeValue = entry.data[attributeKey];
336
360
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
337
361
  if (attributeSchema.type === "media") {
338
- const permissionChecker2 = getService$1("permission-checker").create({
362
+ const permissionChecker2 = getService$2("permission-checker").create({
339
363
  userAbility: params.state.userAbility,
340
364
  model: "plugin::upload.file"
341
365
  });
@@ -358,7 +382,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
358
382
  if (userToPopulate == null) {
359
383
  return null;
360
384
  }
361
- return strapi2.query("admin::user").findOne({ where: { id: userToPopulate.id } });
385
+ return strapi2.query("admin::user").findOne({
386
+ where: {
387
+ ...userToPopulate.id ? { id: userToPopulate.id } : {},
388
+ ...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
389
+ }
390
+ });
362
391
  })
363
392
  );
364
393
  return {
@@ -371,7 +400,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
371
400
  [attributeKey]: adminUsers
372
401
  };
373
402
  }
374
- const permissionChecker2 = getService$1("permission-checker").create({
403
+ const permissionChecker2 = getService$2("permission-checker").create({
375
404
  userAbility: params.state.userAbility,
376
405
  model: attributeSchema.target
377
406
  });
@@ -529,11 +558,13 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
529
558
  }
530
559
  const uid2 = context.contentType.uid;
531
560
  const schemas = getSchemas(uid2);
561
+ const model = strapi2.getModel(uid2);
562
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
532
563
  const localeEntries = await strapi2.db.query(uid2).findMany({
533
564
  where: {
534
565
  documentId,
535
- locale: { $in: locales },
536
- publishedAt: null
566
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
567
+ ...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
537
568
  },
538
569
  populate: serviceUtils.getDeepPopulate(
539
570
  uid2,
@@ -545,7 +576,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
545
576
  onCommit(async () => {
546
577
  for (const entry of localeEntries) {
547
578
  const status = await serviceUtils.getVersionStatus(uid2, entry);
548
- await getService(strapi2, "history").createVersion({
579
+ await getService$1(strapi2, "history").createVersion({
549
580
  contentType: uid2,
550
581
  data: omit(FIELDS_TO_IGNORE, entry),
551
582
  relatedDocumentId: documentId,
@@ -558,15 +589,19 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
558
589
  });
559
590
  return result;
560
591
  });
561
- state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
592
+ state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
562
593
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
563
594
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
564
595
  strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
565
596
  where: {
566
597
  created_at: {
567
- $lt: expirationDate.toISOString()
598
+ $lt: expirationDate
568
599
  }
569
600
  }
601
+ }).catch((error) => {
602
+ if (error instanceof Error) {
603
+ strapi2.log.error("Error deleting expired history versions", error.message);
604
+ }
570
605
  });
571
606
  });
572
607
  state.isInitialized = true;
@@ -578,17 +613,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
578
613
  }
579
614
  };
580
615
  };
581
- const services$1 = {
616
+ const services$2 = {
582
617
  history: createHistoryService,
583
618
  lifecycles: createLifecyclesService
584
619
  };
585
- const info = { pluginName: "content-manager", type: "admin" };
620
+ const info$1 = { pluginName: "content-manager", type: "admin" };
586
621
  const historyVersionRouter = {
587
622
  type: "admin",
588
623
  routes: [
589
624
  {
590
625
  method: "GET",
591
- info,
626
+ info: info$1,
592
627
  path: "/history-versions",
593
628
  handler: "history-version.findMany",
594
629
  config: {
@@ -597,7 +632,7 @@ const historyVersionRouter = {
597
632
  },
598
633
  {
599
634
  method: "PUT",
600
- info,
635
+ info: info$1,
601
636
  path: "/history-versions/:versionId/restore",
602
637
  handler: "history-version.restoreVersion",
603
638
  config: {
@@ -606,7 +641,7 @@ const historyVersionRouter = {
606
641
  }
607
642
  ]
608
643
  };
609
- const routes$1 = {
644
+ const routes$2 = {
610
645
  "history-version": historyVersionRouter
611
646
  };
612
647
  const historyVersion = {
@@ -653,21 +688,21 @@ const historyVersion = {
653
688
  }
654
689
  }
655
690
  };
656
- const getFeature = () => {
691
+ const getFeature$1 = () => {
657
692
  if (strapi.ee.features.isEnabled("cms-content-history")) {
658
693
  return {
659
694
  register({ strapi: strapi2 }) {
660
695
  strapi2.get("models").add(historyVersion);
661
696
  },
662
697
  bootstrap({ strapi: strapi2 }) {
663
- getService(strapi2, "lifecycles").bootstrap();
698
+ getService$1(strapi2, "lifecycles").bootstrap();
664
699
  },
665
700
  destroy({ strapi: strapi2 }) {
666
- getService(strapi2, "lifecycles").destroy();
701
+ getService$1(strapi2, "lifecycles").destroy();
667
702
  },
668
- controllers: controllers$1,
669
- services: services$1,
670
- routes: routes$1
703
+ controllers: controllers$2,
704
+ services: services$2,
705
+ routes: routes$2
671
706
  };
672
707
  }
673
708
  return {
@@ -676,9 +711,201 @@ const getFeature = () => {
676
711
  }
677
712
  };
678
713
  };
679
- const history = getFeature();
714
+ const history = getFeature$1();
715
+ const info = { pluginName: "content-manager", type: "admin" };
716
+ const previewRouter = {
717
+ type: "admin",
718
+ routes: [
719
+ {
720
+ method: "GET",
721
+ info,
722
+ path: "/preview/url/:contentType",
723
+ handler: "preview.getPreviewUrl",
724
+ config: {
725
+ policies: ["admin::isAuthenticatedAdmin"]
726
+ }
727
+ }
728
+ ]
729
+ };
730
+ const routes$1 = {
731
+ preview: previewRouter
732
+ };
733
+ function getService(strapi2, name) {
734
+ return strapi2.service(`plugin::content-manager.${name}`);
735
+ }
736
+ const getPreviewUrlSchema = yup.object().shape({
737
+ // Will be undefined for single types
738
+ documentId: yup.string(),
739
+ locale: yup.string().nullable(),
740
+ status: yup.string()
741
+ }).required();
742
+ const validatePreviewUrl = async (strapi2, uid2, params) => {
743
+ await validateYupSchema(getPreviewUrlSchema)(params);
744
+ const newParams = pick(["documentId", "locale", "status"], params);
745
+ const model = strapi2.getModel(uid2);
746
+ if (!model || model.modelType !== "contentType") {
747
+ throw new errors.ValidationError("Invalid content type");
748
+ }
749
+ const isSingleType = model?.kind === "singleType";
750
+ if (!isSingleType && !params.documentId) {
751
+ throw new errors.ValidationError("documentId is required for Collection Types");
752
+ }
753
+ if (isSingleType) {
754
+ const doc = await strapi2.documents(uid2).findFirst();
755
+ if (!doc) {
756
+ throw new errors.NotFoundError("Document not found");
757
+ }
758
+ newParams.documentId = doc?.documentId;
759
+ }
760
+ if (!newParams.status) {
761
+ const isDPEnabled = model?.options?.draftAndPublish;
762
+ newParams.status = isDPEnabled ? "draft" : "published";
763
+ }
764
+ return newParams;
765
+ };
766
+ const createPreviewController = () => {
767
+ return {
768
+ /**
769
+ * Transforms an entry into a preview URL, so that it can be previewed
770
+ * in the Content Manager.
771
+ */
772
+ async getPreviewUrl(ctx) {
773
+ const uid2 = ctx.params.contentType;
774
+ const query = ctx.request.query;
775
+ const params = await validatePreviewUrl(strapi, uid2, query);
776
+ const previewService = getService(strapi, "preview");
777
+ const url = await previewService.getPreviewUrl(uid2, params);
778
+ if (!url) {
779
+ ctx.status = 204;
780
+ }
781
+ return {
782
+ data: { url }
783
+ };
784
+ }
785
+ };
786
+ };
787
+ const controllers$1 = {
788
+ preview: createPreviewController
789
+ /**
790
+ * Casting is needed because the types aren't aware that Strapi supports
791
+ * passing a controller factory as the value, instead of a controller object directly
792
+ */
793
+ };
794
+ const createPreviewService = ({ strapi: strapi2 }) => {
795
+ const config = getService(strapi2, "preview-config");
796
+ return {
797
+ async getPreviewUrl(uid2, params) {
798
+ const handler = config.getPreviewHandler();
799
+ try {
800
+ return handler(uid2, params);
801
+ } catch (error) {
802
+ strapi2.log.error(`Failed to get preview URL: ${error}`);
803
+ throw new errors.ApplicationError("Failed to get preview URL");
804
+ }
805
+ return;
806
+ }
807
+ };
808
+ };
809
+ const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
810
+ const middlewares = strapi.config.get("middlewares");
811
+ const configuredMiddlewares = middlewares.map((currentMiddleware) => {
812
+ if (currentMiddleware === middleware.name) {
813
+ return middleware;
814
+ }
815
+ if (currentMiddleware.name === middleware.name) {
816
+ return mergeWith(
817
+ (objValue, srcValue) => {
818
+ if (Array.isArray(objValue)) {
819
+ return objValue.concat(srcValue);
820
+ }
821
+ return void 0;
822
+ },
823
+ currentMiddleware,
824
+ middleware
825
+ );
826
+ }
827
+ return currentMiddleware;
828
+ });
829
+ strapi.config.set("middlewares", configuredMiddlewares);
830
+ };
831
+ const createPreviewConfigService = ({ strapi: strapi2 }) => {
832
+ return {
833
+ register() {
834
+ if (!this.isEnabled()) {
835
+ return;
836
+ }
837
+ const config = strapi2.config.get("admin.preview");
838
+ if (config.config?.allowedOrigins) {
839
+ extendMiddlewareConfiguration({
840
+ name: "strapi::security",
841
+ config: {
842
+ contentSecurityPolicy: {
843
+ directives: {
844
+ "frame-src": config.config.allowedOrigins
845
+ }
846
+ }
847
+ }
848
+ });
849
+ }
850
+ },
851
+ isEnabled() {
852
+ const config = strapi2.config.get("admin.preview");
853
+ if (!config) {
854
+ return false;
855
+ }
856
+ return config?.enabled ?? true;
857
+ },
858
+ /**
859
+ * Validate if the configuration is valid
860
+ */
861
+ validate() {
862
+ if (!this.isEnabled()) {
863
+ return;
864
+ }
865
+ const handler = this.getPreviewHandler();
866
+ if (typeof handler !== "function") {
867
+ throw new errors.ValidationError(
868
+ "Preview configuration is invalid. Handler must be a function"
869
+ );
870
+ }
871
+ },
872
+ /**
873
+ * Utility to get the preview handler from the configuration
874
+ */
875
+ getPreviewHandler() {
876
+ const config = strapi2.config.get("admin.preview");
877
+ const emptyHandler = () => {
878
+ return void 0;
879
+ };
880
+ if (!this.isEnabled()) {
881
+ return emptyHandler;
882
+ }
883
+ return config?.config?.handler || emptyHandler;
884
+ }
885
+ };
886
+ };
887
+ const services$1 = {
888
+ preview: createPreviewService,
889
+ "preview-config": createPreviewConfigService
890
+ };
891
+ const getFeature = () => {
892
+ return {
893
+ register() {
894
+ const config = getService(strapi, "preview-config");
895
+ config.validate();
896
+ config.register();
897
+ },
898
+ bootstrap() {
899
+ },
900
+ routes: routes$1,
901
+ controllers: controllers$1,
902
+ services: services$1
903
+ };
904
+ };
905
+ const preview = getFeature();
680
906
  const register = async ({ strapi: strapi2 }) => {
681
907
  await history.register?.({ strapi: strapi2 });
908
+ await preview.register?.({ strapi: strapi2 });
682
909
  };
683
910
  const ALLOWED_WEBHOOK_EVENTS = {
684
911
  ENTRY_PUBLISH: "entry.publish",
@@ -688,11 +915,12 @@ const bootstrap = async () => {
688
915
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
689
916
  strapi.get("webhookStore").addAllowedEvent(key, value);
690
917
  });
691
- getService$1("field-sizes").setCustomFieldInputSizes();
692
- await getService$1("components").syncConfigurations();
693
- await getService$1("content-types").syncConfigurations();
694
- await getService$1("permission").registerPermissions();
918
+ getService$2("field-sizes").setCustomFieldInputSizes();
919
+ await getService$2("components").syncConfigurations();
920
+ await getService$2("content-types").syncConfigurations();
921
+ await getService$2("permission").registerPermissions();
695
922
  await history.bootstrap?.({ strapi });
923
+ await preview.bootstrap?.({ strapi });
696
924
  };
697
925
  const destroy = async ({ strapi: strapi2 }) => {
698
926
  await history.destroy?.({ strapi: strapi2 });
@@ -1182,7 +1410,8 @@ const admin = {
1182
1410
  };
1183
1411
  const routes = {
1184
1412
  admin,
1185
- ...history.routes ? history.routes : {}
1413
+ ...history.routes ? history.routes : {},
1414
+ ...preview.routes ? preview.routes : {}
1186
1415
  };
1187
1416
  const hasPermissionsSchema = yup$1.object({
1188
1417
  actions: yup$1.array().of(yup$1.string()),
@@ -1193,6 +1422,11 @@ const { createPolicy } = policy;
1193
1422
  const hasPermissions = createPolicy({
1194
1423
  name: "plugin::content-manager.hasPermissions",
1195
1424
  validator: validateHasPermissionsInput,
1425
+ /**
1426
+ * NOTE: Action aliases are currently not checked at this level (policy).
1427
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1428
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1429
+ */
1196
1430
  handler(ctx, config = {}) {
1197
1431
  const { actions = [], hasAtLeastOne = false } = config;
1198
1432
  const { userAbility } = ctx.state;
@@ -1240,8 +1474,7 @@ const isSortable = (schema, name) => {
1240
1474
  if (!_.has(schema.attributes, name)) {
1241
1475
  return false;
1242
1476
  }
1243
- if (schema.modelType === "component" && name === "id")
1244
- return false;
1477
+ if (schema.modelType === "component" && name === "id") return false;
1245
1478
  const attribute = schema.attributes[name];
1246
1479
  if (NON_SORTABLES.includes(attribute.type)) {
1247
1480
  return false;
@@ -1386,8 +1619,7 @@ const createDefaultSettings = async (schema) => {
1386
1619
  };
1387
1620
  };
1388
1621
  const syncSettings = async (configuration, schema) => {
1389
- if (isEmpty(configuration.settings))
1390
- return createDefaultSettings(schema);
1622
+ if (isEmpty(configuration.settings)) return createDefaultSettings(schema);
1391
1623
  const defaultField = getDefaultMainField(schema);
1392
1624
  const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
1393
1625
  return {
@@ -1434,7 +1666,7 @@ const createMetadasSchema = (schema) => {
1434
1666
  if (!value) {
1435
1667
  return yup$1.string();
1436
1668
  }
1437
- const targetSchema = getService$1("content-types").findContentType(
1669
+ const targetSchema = getService$2("content-types").findContentType(
1438
1670
  schema.attributes[key].targetModel
1439
1671
  );
1440
1672
  if (!targetSchema) {
@@ -1563,8 +1795,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1563
1795
  }
1564
1796
  switch (attribute.type) {
1565
1797
  case "relation": {
1566
- if (canCreate(attributePath))
1567
- return body2;
1798
+ if (canCreate(attributePath)) return body2;
1568
1799
  return set(attributePath, { set: [] }, body2);
1569
1800
  }
1570
1801
  case "component": {
@@ -1574,8 +1805,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
1574
1805
  ]);
1575
1806
  }
1576
1807
  default: {
1577
- if (canCreate(attributePath))
1578
- return body2;
1808
+ if (canCreate(attributePath)) return body2;
1579
1809
  return set(attributePath, null, body2);
1580
1810
  }
1581
1811
  }
@@ -1603,7 +1833,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
1603
1833
  }
1604
1834
  };
1605
1835
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1606
- const documentMetadata2 = getService$1("document-metadata");
1836
+ const documentMetadata2 = getService$2("document-metadata");
1607
1837
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1608
1838
  let {
1609
1839
  meta: { availableLocales, availableStatus }
@@ -1629,8 +1859,8 @@ const createDocument = async (ctx, opts) => {
1629
1859
  const { userAbility, user } = ctx.state;
1630
1860
  const { model } = ctx.params;
1631
1861
  const { body } = ctx.request;
1632
- const documentManager2 = getService$1("document-manager");
1633
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1862
+ const documentManager2 = getService$2("document-manager");
1863
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1634
1864
  if (permissionChecker2.cannot.create()) {
1635
1865
  throw new errors.ForbiddenError();
1636
1866
  }
@@ -1650,13 +1880,13 @@ const updateDocument = async (ctx, opts) => {
1650
1880
  const { userAbility, user } = ctx.state;
1651
1881
  const { id, model } = ctx.params;
1652
1882
  const { body } = ctx.request;
1653
- const documentManager2 = getService$1("document-manager");
1654
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1883
+ const documentManager2 = getService$2("document-manager");
1884
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1655
1885
  if (permissionChecker2.cannot.update()) {
1656
1886
  throw new errors.ForbiddenError();
1657
1887
  }
1658
1888
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1659
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1889
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1660
1890
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1661
1891
  const [documentVersion, documentExists] = await Promise.all([
1662
1892
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
@@ -1673,7 +1903,7 @@ const updateDocument = async (ctx, opts) => {
1673
1903
  throw new errors.ForbiddenError();
1674
1904
  }
1675
1905
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1676
- const setCreator = setCreatorFields({ user, isEdition: true });
1906
+ const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
1677
1907
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1678
1908
  const sanitizedBody = await sanitizeFn(body);
1679
1909
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1687,14 +1917,14 @@ const collectionTypes = {
1687
1917
  const { userAbility } = ctx.state;
1688
1918
  const { model } = ctx.params;
1689
1919
  const { query } = ctx.request;
1690
- const documentMetadata2 = getService$1("document-metadata");
1691
- const documentManager2 = getService$1("document-manager");
1692
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1920
+ const documentMetadata2 = getService$2("document-metadata");
1921
+ const documentManager2 = getService$2("document-manager");
1922
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1693
1923
  if (permissionChecker2.cannot.read()) {
1694
1924
  return ctx.forbidden();
1695
1925
  }
1696
1926
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1697
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1927
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1698
1928
  const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1699
1929
  const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
1700
1930
  { ...permissionQuery, populate, locale, status },
@@ -1723,13 +1953,13 @@ const collectionTypes = {
1723
1953
  async findOne(ctx) {
1724
1954
  const { userAbility } = ctx.state;
1725
1955
  const { model, id } = ctx.params;
1726
- const documentManager2 = getService$1("document-manager");
1727
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1956
+ const documentManager2 = getService$2("document-manager");
1957
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1728
1958
  if (permissionChecker2.cannot.read()) {
1729
1959
  return ctx.forbidden();
1730
1960
  }
1731
1961
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1732
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1962
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1733
1963
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1734
1964
  const version = await documentManager2.findOne(id, model, {
1735
1965
  populate,
@@ -1745,7 +1975,7 @@ const collectionTypes = {
1745
1975
  permissionChecker2,
1746
1976
  model,
1747
1977
  // @ts-expect-error TODO: fix
1748
- { id, locale, publishedAt: null },
1978
+ { documentId: id, locale, publishedAt: null },
1749
1979
  { availableLocales: true, availableStatus: false }
1750
1980
  );
1751
1981
  ctx.body = { data: {}, meta };
@@ -1760,7 +1990,7 @@ const collectionTypes = {
1760
1990
  async create(ctx) {
1761
1991
  const { userAbility } = ctx.state;
1762
1992
  const { model } = ctx.params;
1763
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1993
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1764
1994
  const [totalEntries, document] = await Promise.all([
1765
1995
  strapi.db.query(model).count(),
1766
1996
  createDocument(ctx)
@@ -1781,7 +2011,7 @@ const collectionTypes = {
1781
2011
  async update(ctx) {
1782
2012
  const { userAbility } = ctx.state;
1783
2013
  const { model } = ctx.params;
1784
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2014
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1785
2015
  const updatedVersion = await updateDocument(ctx);
1786
2016
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1787
2017
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1790,13 +2020,13 @@ const collectionTypes = {
1790
2020
  const { userAbility, user } = ctx.state;
1791
2021
  const { model, sourceId: id } = ctx.params;
1792
2022
  const { body } = ctx.request;
1793
- const documentManager2 = getService$1("document-manager");
1794
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2023
+ const documentManager2 = getService$2("document-manager");
2024
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1795
2025
  if (permissionChecker2.cannot.create()) {
1796
2026
  return ctx.forbidden();
1797
2027
  }
1798
2028
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1799
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2029
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1800
2030
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1801
2031
  const document = await documentManager2.findOne(id, model, {
1802
2032
  populate,
@@ -1835,13 +2065,13 @@ const collectionTypes = {
1835
2065
  async delete(ctx) {
1836
2066
  const { userAbility } = ctx.state;
1837
2067
  const { id, model } = ctx.params;
1838
- const documentManager2 = getService$1("document-manager");
1839
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2068
+ const documentManager2 = getService$2("document-manager");
2069
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1840
2070
  if (permissionChecker2.cannot.delete()) {
1841
2071
  return ctx.forbidden();
1842
2072
  }
1843
2073
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1844
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2074
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1845
2075
  const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1846
2076
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1847
2077
  if (documentLocales.length === 0) {
@@ -1863,14 +2093,14 @@ const collectionTypes = {
1863
2093
  const { userAbility } = ctx.state;
1864
2094
  const { id, model } = ctx.params;
1865
2095
  const { body } = ctx.request;
1866
- const documentManager2 = getService$1("document-manager");
1867
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2096
+ const documentManager2 = getService$2("document-manager");
2097
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1868
2098
  if (permissionChecker2.cannot.publish()) {
1869
2099
  return ctx.forbidden();
1870
2100
  }
1871
2101
  const publishedDocument = await strapi.db.transaction(async () => {
1872
2102
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1873
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2103
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1874
2104
  let document;
1875
2105
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1876
2106
  const isCreate = isNil$1(id);
@@ -1882,11 +2112,17 @@ const collectionTypes = {
1882
2112
  }
1883
2113
  const isUpdate = !isCreate;
1884
2114
  if (isUpdate) {
1885
- document = await documentManager2.findOne(id, model, { populate, locale });
1886
- if (!document) {
2115
+ const documentExists = documentManager2.exists(model, id);
2116
+ if (!documentExists) {
1887
2117
  throw new errors.NotFoundError("Document not found");
1888
2118
  }
1889
- if (permissionChecker2.can.update(document)) {
2119
+ document = await documentManager2.findOne(id, model, { populate, locale });
2120
+ if (!document) {
2121
+ if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
2122
+ throw new errors.ForbiddenError();
2123
+ }
2124
+ document = await updateDocument(ctx);
2125
+ } else if (permissionChecker2.can.update(document)) {
1890
2126
  await updateDocument(ctx);
1891
2127
  }
1892
2128
  }
@@ -1912,13 +2148,13 @@ const collectionTypes = {
1912
2148
  const { body } = ctx.request;
1913
2149
  const { documentIds } = body;
1914
2150
  await validateBulkActionInput(body);
1915
- const documentManager2 = getService$1("document-manager");
1916
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2151
+ const documentManager2 = getService$2("document-manager");
2152
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1917
2153
  if (permissionChecker2.cannot.publish()) {
1918
2154
  return ctx.forbidden();
1919
2155
  }
1920
2156
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1921
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2157
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1922
2158
  const { locale } = await getDocumentLocaleAndStatus(body, model, {
1923
2159
  allowMultipleLocales: true
1924
2160
  });
@@ -1943,12 +2179,14 @@ const collectionTypes = {
1943
2179
  const { body } = ctx.request;
1944
2180
  const { documentIds } = body;
1945
2181
  await validateBulkActionInput(body);
1946
- const documentManager2 = getService$1("document-manager");
1947
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2182
+ const documentManager2 = getService$2("document-manager");
2183
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1948
2184
  if (permissionChecker2.cannot.unpublish()) {
1949
2185
  return ctx.forbidden();
1950
2186
  }
1951
- const { locale } = await getDocumentLocaleAndStatus(body, model);
2187
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2188
+ allowMultipleLocales: true
2189
+ });
1952
2190
  const entityPromises = documentIds.map(
1953
2191
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1954
2192
  );
@@ -1971,8 +2209,8 @@ const collectionTypes = {
1971
2209
  const {
1972
2210
  body: { discardDraft, ...body }
1973
2211
  } = ctx.request;
1974
- const documentManager2 = getService$1("document-manager");
1975
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2212
+ const documentManager2 = getService$2("document-manager");
2213
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1976
2214
  if (permissionChecker2.cannot.unpublish()) {
1977
2215
  return ctx.forbidden();
1978
2216
  }
@@ -1980,7 +2218,7 @@ const collectionTypes = {
1980
2218
  return ctx.forbidden();
1981
2219
  }
1982
2220
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
1983
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2221
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1984
2222
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1985
2223
  const document = await documentManager2.findOne(id, model, {
1986
2224
  populate,
@@ -2011,13 +2249,13 @@ const collectionTypes = {
2011
2249
  const { userAbility } = ctx.state;
2012
2250
  const { id, model } = ctx.params;
2013
2251
  const { body } = ctx.request;
2014
- const documentManager2 = getService$1("document-manager");
2015
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2252
+ const documentManager2 = getService$2("document-manager");
2253
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2016
2254
  if (permissionChecker2.cannot.discard()) {
2017
2255
  return ctx.forbidden();
2018
2256
  }
2019
2257
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
2020
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2258
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2021
2259
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2022
2260
  const document = await documentManager2.findOne(id, model, {
2023
2261
  populate,
@@ -2042,13 +2280,13 @@ const collectionTypes = {
2042
2280
  const { query, body } = ctx.request;
2043
2281
  const { documentIds } = body;
2044
2282
  await validateBulkActionInput(body);
2045
- const documentManager2 = getService$1("document-manager");
2046
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2283
+ const documentManager2 = getService$2("document-manager");
2284
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2047
2285
  if (permissionChecker2.cannot.delete()) {
2048
2286
  return ctx.forbidden();
2049
2287
  }
2050
2288
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2051
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2289
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2052
2290
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2053
2291
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2054
2292
  populate,
@@ -2069,13 +2307,13 @@ const collectionTypes = {
2069
2307
  async countDraftRelations(ctx) {
2070
2308
  const { userAbility } = ctx.state;
2071
2309
  const { model, id } = ctx.params;
2072
- const documentManager2 = getService$1("document-manager");
2073
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2310
+ const documentManager2 = getService$2("document-manager");
2311
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2074
2312
  if (permissionChecker2.cannot.read()) {
2075
2313
  return ctx.forbidden();
2076
2314
  }
2077
2315
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2078
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2316
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2079
2317
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2080
2318
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2081
2319
  if (!entity) {
@@ -2094,8 +2332,8 @@ const collectionTypes = {
2094
2332
  const ids = ctx.request.query.documentIds;
2095
2333
  const locale = ctx.request.query.locale;
2096
2334
  const { model } = ctx.params;
2097
- const documentManager2 = getService$1("document-manager");
2098
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2335
+ const documentManager2 = getService$2("document-manager");
2336
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2099
2337
  if (permissionChecker2.cannot.read()) {
2100
2338
  return ctx.forbidden();
2101
2339
  }
@@ -2119,13 +2357,13 @@ const collectionTypes = {
2119
2357
  };
2120
2358
  const components$1 = {
2121
2359
  findComponents(ctx) {
2122
- const components2 = getService$1("components").findAllComponents();
2123
- const { toDto } = getService$1("data-mapper");
2360
+ const components2 = getService$2("components").findAllComponents();
2361
+ const { toDto } = getService$2("data-mapper");
2124
2362
  ctx.body = { data: components2.map(toDto) };
2125
2363
  },
2126
2364
  async findComponentConfiguration(ctx) {
2127
2365
  const { uid: uid2 } = ctx.params;
2128
- const componentService = getService$1("components");
2366
+ const componentService = getService$2("components");
2129
2367
  const component = componentService.findComponent(uid2);
2130
2368
  if (!component) {
2131
2369
  return ctx.notFound("component.notFound");
@@ -2142,7 +2380,7 @@ const components$1 = {
2142
2380
  async updateComponentConfiguration(ctx) {
2143
2381
  const { uid: uid2 } = ctx.params;
2144
2382
  const { body } = ctx.request;
2145
- const componentService = getService$1("components");
2383
+ const componentService = getService$2("components");
2146
2384
  const component = componentService.findComponent(uid2);
2147
2385
  if (!component) {
2148
2386
  return ctx.notFound("component.notFound");
@@ -2176,12 +2414,12 @@ const contentTypes = {
2176
2414
  } catch (error) {
2177
2415
  return ctx.send({ error }, 400);
2178
2416
  }
2179
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2180
- const { toDto } = getService$1("data-mapper");
2417
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2418
+ const { toDto } = getService$2("data-mapper");
2181
2419
  ctx.body = { data: contentTypes2.map(toDto) };
2182
2420
  },
2183
2421
  async findContentTypesSettings(ctx) {
2184
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2422
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2185
2423
  const contentTypes2 = await findAllContentTypes();
2186
2424
  const configurations = await Promise.all(
2187
2425
  contentTypes2.map(async (contentType) => {
@@ -2195,7 +2433,7 @@ const contentTypes = {
2195
2433
  },
2196
2434
  async findContentTypeConfiguration(ctx) {
2197
2435
  const { uid: uid2 } = ctx.params;
2198
- const contentTypeService = getService$1("content-types");
2436
+ const contentTypeService = getService$2("content-types");
2199
2437
  const contentType = await contentTypeService.findContentType(uid2);
2200
2438
  if (!contentType) {
2201
2439
  return ctx.notFound("contentType.notFound");
@@ -2217,13 +2455,13 @@ const contentTypes = {
2217
2455
  const { userAbility } = ctx.state;
2218
2456
  const { uid: uid2 } = ctx.params;
2219
2457
  const { body } = ctx.request;
2220
- const contentTypeService = getService$1("content-types");
2221
- const metricsService = getService$1("metrics");
2458
+ const contentTypeService = getService$2("content-types");
2459
+ const metricsService = getService$2("metrics");
2222
2460
  const contentType = await contentTypeService.findContentType(uid2);
2223
2461
  if (!contentType) {
2224
2462
  return ctx.notFound("contentType.notFound");
2225
2463
  }
2226
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2464
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2227
2465
  return ctx.forbidden();
2228
2466
  }
2229
2467
  let input;
@@ -2256,10 +2494,10 @@ const contentTypes = {
2256
2494
  };
2257
2495
  const init = {
2258
2496
  getInitData(ctx) {
2259
- const { toDto } = getService$1("data-mapper");
2260
- const { findAllComponents } = getService$1("components");
2261
- const { getAllFieldSizes } = getService$1("field-sizes");
2262
- const { findAllContentTypes } = getService$1("content-types");
2497
+ const { toDto } = getService$2("data-mapper");
2498
+ const { findAllComponents } = getService$2("components");
2499
+ const { getAllFieldSizes } = getService$2("field-sizes");
2500
+ const { findAllContentTypes } = getService$2("content-types");
2263
2501
  ctx.body = {
2264
2502
  data: {
2265
2503
  fieldSizes: getAllFieldSizes(),
@@ -2295,36 +2533,41 @@ const addFiltersClause = (params, filtersClause) => {
2295
2533
  params.filters.$and.push(filtersClause);
2296
2534
  };
2297
2535
  const sanitizeMainField = (model, mainField, userAbility) => {
2298
- const permissionChecker2 = getService$1("permission-checker").create({
2536
+ const permissionChecker2 = getService$2("permission-checker").create({
2299
2537
  userAbility,
2300
2538
  model: model.uid
2301
2539
  });
2302
- if (!isListable(model, mainField)) {
2540
+ const isMainFieldListable = isListable(model, mainField);
2541
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2542
+ if (!isMainFieldListable || !canReadMainField) {
2303
2543
  return "id";
2304
2544
  }
2305
- if (permissionChecker2.cannot.read(null, mainField)) {
2306
- if (model.uid === "plugin::users-permissions.role") {
2307
- const userPermissionChecker = getService$1("permission-checker").create({
2308
- userAbility,
2309
- model: "plugin::users-permissions.user"
2310
- });
2311
- if (userPermissionChecker.can.read()) {
2312
- return "name";
2313
- }
2314
- }
2315
- return "id";
2545
+ if (model.uid === "plugin::users-permissions.role") {
2546
+ return "name";
2316
2547
  }
2317
2548
  return mainField;
2318
2549
  };
2319
- const addStatusToRelations = async (uid2, relations2) => {
2320
- if (!contentTypes$1.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2550
+ const addStatusToRelations = async (targetUid, relations2) => {
2551
+ if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
2321
2552
  return relations2;
2322
2553
  }
2323
- const documentMetadata2 = getService$1("document-metadata");
2324
- const documentsAvailableStatus = await documentMetadata2.getManyAvailableStatus(uid2, relations2);
2554
+ const documentMetadata2 = getService$2("document-metadata");
2555
+ if (!relations2.length) {
2556
+ return relations2;
2557
+ }
2558
+ const firstRelation = relations2[0];
2559
+ const filters = {
2560
+ documentId: { $in: relations2.map((r) => r.documentId) },
2561
+ // NOTE: find the "opposite" status
2562
+ publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
2563
+ };
2564
+ const availableStatus = await strapi.query(targetUid).findMany({
2565
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
2566
+ filters
2567
+ });
2325
2568
  return relations2.map((relation) => {
2326
- const availableStatuses = documentsAvailableStatus.filter(
2327
- (availableDocument) => availableDocument.documentId === relation.documentId
2569
+ const availableStatuses = availableStatus.filter(
2570
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2328
2571
  );
2329
2572
  return {
2330
2573
  ...relation,
@@ -2345,11 +2588,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2345
2588
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2346
2589
  const isSourceLocalized = isLocalized(sourceModel);
2347
2590
  const isTargetLocalized = isLocalized(targetModel);
2348
- let validatedLocale = locale;
2349
- if (!targetModel || !isTargetLocalized)
2350
- validatedLocale = void 0;
2351
2591
  return {
2352
- locale: validatedLocale,
2592
+ locale,
2353
2593
  isSourceLocalized,
2354
2594
  isTargetLocalized
2355
2595
  };
@@ -2358,8 +2598,7 @@ const validateStatus = (sourceUid, status) => {
2358
2598
  const sourceModel = strapi.getModel(sourceUid);
2359
2599
  const isDP = contentTypes$1.hasDraftAndPublish;
2360
2600
  const isSourceDP = isDP(sourceModel);
2361
- if (!isSourceDP)
2362
- return { status: void 0 };
2601
+ if (!isSourceDP) return { status: void 0 };
2363
2602
  switch (status) {
2364
2603
  case "published":
2365
2604
  return { status: "published" };
@@ -2389,7 +2628,7 @@ const relations = {
2389
2628
  ctx.request?.query?.locale
2390
2629
  );
2391
2630
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2392
- const permissionChecker2 = getService$1("permission-checker").create({
2631
+ const permissionChecker2 = getService$2("permission-checker").create({
2393
2632
  userAbility,
2394
2633
  model
2395
2634
  });
@@ -2414,7 +2653,7 @@ const relations = {
2414
2653
  where.id = id;
2415
2654
  }
2416
2655
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2417
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2656
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2418
2657
  const currentEntity = await strapi.db.query(model).findOne({
2419
2658
  where,
2420
2659
  populate
@@ -2429,7 +2668,7 @@ const relations = {
2429
2668
  }
2430
2669
  entryId = currentEntity.id;
2431
2670
  }
2432
- const modelConfig = isComponent2 ? await getService$1("components").findConfiguration(sourceSchema) : await getService$1("content-types").findConfiguration(sourceSchema);
2671
+ const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
2433
2672
  const targetSchema = strapi.getModel(targetUid);
2434
2673
  const mainField = flow(
2435
2674
  prop(`metadatas.${targetField}.edit.mainField`),
@@ -2452,7 +2691,7 @@ const relations = {
2452
2691
  attribute,
2453
2692
  fieldsToSelect,
2454
2693
  mainField,
2455
- source: { schema: sourceSchema },
2694
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2456
2695
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2457
2696
  sourceSchema,
2458
2697
  targetSchema,
@@ -2474,7 +2713,8 @@ const relations = {
2474
2713
  fieldsToSelect,
2475
2714
  mainField,
2476
2715
  source: {
2477
- schema: { uid: sourceUid, modelType: sourceModelType }
2716
+ schema: { uid: sourceUid, modelType: sourceModelType },
2717
+ isLocalized: isSourceLocalized
2478
2718
  },
2479
2719
  target: {
2480
2720
  schema: { uid: targetUid },
@@ -2482,7 +2722,7 @@ const relations = {
2482
2722
  }
2483
2723
  } = await this.extractAndValidateRequestInfo(ctx, id);
2484
2724
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2485
- const permissionChecker2 = getService$1("permission-checker").create({
2725
+ const permissionChecker2 = getService$2("permission-checker").create({
2486
2726
  userAbility: ctx.state.userAbility,
2487
2727
  model: targetUid
2488
2728
  });
@@ -2512,12 +2752,16 @@ const relations = {
2512
2752
  } else {
2513
2753
  where.id = id;
2514
2754
  }
2515
- if (status) {
2516
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2755
+ const publishedAt = getPublishedAtClause(status, targetUid);
2756
+ if (!isEmpty(publishedAt)) {
2757
+ where[`${alias}.published_at`] = publishedAt;
2517
2758
  }
2518
- if (filterByLocale) {
2759
+ if (isTargetLocalized && locale) {
2519
2760
  where[`${alias}.locale`] = locale;
2520
2761
  }
2762
+ if (isSourceLocalized && locale) {
2763
+ where.locale = locale;
2764
+ }
2521
2765
  if ((idsToInclude?.length ?? 0) !== 0) {
2522
2766
  where[`${alias}.id`].$notIn = idsToInclude;
2523
2767
  }
@@ -2535,7 +2779,8 @@ const relations = {
2535
2779
  id: { $notIn: uniq(idsToOmit) }
2536
2780
  });
2537
2781
  }
2538
- const res = await strapi.db.query(targetUid).findPage(strapi.get("query-params").transform(targetUid, queryParams));
2782
+ const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
2783
+ const res = await strapi.db.query(targetUid).findPage(dbQuery);
2539
2784
  ctx.body = {
2540
2785
  ...res,
2541
2786
  results: await addStatusToRelations(targetUid, res.results)
@@ -2550,29 +2795,39 @@ const relations = {
2550
2795
  attribute,
2551
2796
  targetField,
2552
2797
  fieldsToSelect,
2553
- source: {
2554
- schema: { uid: sourceUid }
2555
- },
2556
- target: {
2557
- schema: { uid: targetUid }
2558
- }
2798
+ status,
2799
+ source: { schema: sourceSchema },
2800
+ target: { schema: targetSchema }
2559
2801
  } = await this.extractAndValidateRequestInfo(ctx, id);
2560
- const permissionQuery = await getService$1("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2802
+ const { uid: sourceUid } = sourceSchema;
2803
+ const { uid: targetUid } = targetSchema;
2804
+ const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2561
2805
  const dbQuery = strapi.db.query(sourceUid);
2562
2806
  const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
2807
+ const filters = {};
2808
+ if (sourceSchema?.options?.draftAndPublish) {
2809
+ if (targetSchema?.options?.draftAndPublish) {
2810
+ if (status === "published") {
2811
+ filters.publishedAt = { $notNull: true };
2812
+ } else {
2813
+ filters.publishedAt = { $null: true };
2814
+ }
2815
+ }
2816
+ } else if (targetSchema?.options?.draftAndPublish) {
2817
+ filters.publishedAt = { $null: true };
2818
+ }
2563
2819
  const res = await loadRelations({ id: entryId }, targetField, {
2564
- select: ["id", "documentId", "locale", "publishedAt"],
2820
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2565
2821
  ordering: "desc",
2566
2822
  page: ctx.request.query.page,
2567
- pageSize: ctx.request.query.pageSize
2823
+ pageSize: ctx.request.query.pageSize,
2824
+ filters
2568
2825
  });
2569
2826
  const loadedIds = res.results.map((item) => item.id);
2570
2827
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2571
2828
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2572
2829
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2573
- ordering: "desc",
2574
- page: ctx.request.query.page,
2575
- pageSize: ctx.request.query.pageSize
2830
+ ordering: "desc"
2576
2831
  });
2577
2832
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2578
2833
  ctx.body = {
@@ -2587,10 +2842,10 @@ const relations = {
2587
2842
  }
2588
2843
  };
2589
2844
  const buildPopulateFromQuery = async (query, model) => {
2590
- return getService$1("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2845
+ return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2591
2846
  };
2592
2847
  const findDocument = async (query, uid2, opts = {}) => {
2593
- const documentManager2 = getService$1("document-manager");
2848
+ const documentManager2 = getService$2("document-manager");
2594
2849
  const populate = await buildPopulateFromQuery(query, uid2);
2595
2850
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2596
2851
  };
@@ -2598,8 +2853,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
2598
2853
  const { user, userAbility } = ctx.state;
2599
2854
  const { model } = ctx.params;
2600
2855
  const { body, query } = ctx.request;
2601
- const documentManager2 = getService$1("document-manager");
2602
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2856
+ const documentManager2 = getService$2("document-manager");
2857
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2603
2858
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2604
2859
  throw new errors.ForbiddenError();
2605
2860
  }
@@ -2640,7 +2895,7 @@ const singleTypes = {
2640
2895
  const { userAbility } = ctx.state;
2641
2896
  const { model } = ctx.params;
2642
2897
  const { query = {} } = ctx.request;
2643
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2898
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2644
2899
  if (permissionChecker2.cannot.read()) {
2645
2900
  return ctx.forbidden();
2646
2901
  }
@@ -2659,7 +2914,7 @@ const singleTypes = {
2659
2914
  permissionChecker2,
2660
2915
  model,
2661
2916
  // @ts-expect-error - fix types
2662
- { id: document.documentId, locale, publishedAt: null },
2917
+ { documentId: document.documentId, locale, publishedAt: null },
2663
2918
  { availableLocales: true, availableStatus: false }
2664
2919
  );
2665
2920
  ctx.body = { data: {}, meta };
@@ -2674,7 +2929,7 @@ const singleTypes = {
2674
2929
  async createOrUpdate(ctx) {
2675
2930
  const { userAbility } = ctx.state;
2676
2931
  const { model } = ctx.params;
2677
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2932
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2678
2933
  const document = await createOrUpdateDocument(ctx);
2679
2934
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2680
2935
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2683,8 +2938,8 @@ const singleTypes = {
2683
2938
  const { userAbility } = ctx.state;
2684
2939
  const { model } = ctx.params;
2685
2940
  const { query = {} } = ctx.request;
2686
- const documentManager2 = getService$1("document-manager");
2687
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2941
+ const documentManager2 = getService$2("document-manager");
2942
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2688
2943
  if (permissionChecker2.cannot.delete()) {
2689
2944
  return ctx.forbidden();
2690
2945
  }
@@ -2712,8 +2967,8 @@ const singleTypes = {
2712
2967
  const { userAbility } = ctx.state;
2713
2968
  const { model } = ctx.params;
2714
2969
  const { query = {} } = ctx.request;
2715
- const documentManager2 = getService$1("document-manager");
2716
- 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 });
2717
2972
  if (permissionChecker2.cannot.publish()) {
2718
2973
  return ctx.forbidden();
2719
2974
  }
@@ -2741,8 +2996,8 @@ const singleTypes = {
2741
2996
  body: { discardDraft, ...body },
2742
2997
  query = {}
2743
2998
  } = ctx.request;
2744
- const documentManager2 = getService$1("document-manager");
2745
- 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 });
2746
3001
  if (permissionChecker2.cannot.unpublish()) {
2747
3002
  return ctx.forbidden();
2748
3003
  }
@@ -2776,8 +3031,8 @@ const singleTypes = {
2776
3031
  const { userAbility } = ctx.state;
2777
3032
  const { model } = ctx.params;
2778
3033
  const { body, query = {} } = ctx.request;
2779
- const documentManager2 = getService$1("document-manager");
2780
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3034
+ const documentManager2 = getService$2("document-manager");
3035
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2781
3036
  if (permissionChecker2.cannot.discard()) {
2782
3037
  return ctx.forbidden();
2783
3038
  }
@@ -2800,8 +3055,8 @@ const singleTypes = {
2800
3055
  const { userAbility } = ctx.state;
2801
3056
  const { model } = ctx.params;
2802
3057
  const { query } = ctx.request;
2803
- const documentManager2 = getService$1("document-manager");
2804
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3058
+ const documentManager2 = getService$2("document-manager");
3059
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2805
3060
  const { locale } = await getDocumentLocaleAndStatus(query, model);
2806
3061
  if (permissionChecker2.cannot.read()) {
2807
3062
  return ctx.forbidden();
@@ -2825,7 +3080,7 @@ const uid$1 = {
2825
3080
  const { query = {} } = ctx.request;
2826
3081
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2827
3082
  await validateUIDField(contentTypeUID, field);
2828
- const uidService = getService$1("uid");
3083
+ const uidService = getService$2("uid");
2829
3084
  ctx.body = {
2830
3085
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2831
3086
  };
@@ -2837,7 +3092,7 @@ const uid$1 = {
2837
3092
  const { query = {} } = ctx.request;
2838
3093
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2839
3094
  await validateUIDField(contentTypeUID, field);
2840
- const uidService = getService$1("uid");
3095
+ const uidService = getService$2("uid");
2841
3096
  const isAvailable = await uidService.checkUIDAvailability({
2842
3097
  contentTypeUID,
2843
3098
  field,
@@ -2858,7 +3113,8 @@ const controllers = {
2858
3113
  relations,
2859
3114
  "single-types": singleTypes,
2860
3115
  uid: uid$1,
2861
- ...history.controllers ? history.controllers : {}
3116
+ ...history.controllers ? history.controllers : {},
3117
+ ...preview.controllers ? preview.controllers : {}
2862
3118
  };
2863
3119
  const keys = {
2864
3120
  CONFIGURATION: "configuration"
@@ -2987,18 +3243,15 @@ async function syncMetadatas(configuration, schema) {
2987
3243
  _.set(updatedMeta, ["list", "searchable"], false);
2988
3244
  _.set(acc, [key], updatedMeta);
2989
3245
  }
2990
- if (!_.has(edit, "mainField"))
2991
- return acc;
3246
+ if (!_.has(edit, "mainField")) return acc;
2992
3247
  if (!isRelation$1(attr)) {
2993
3248
  _.set(updatedMeta, "edit", _.omit(edit, ["mainField"]));
2994
3249
  _.set(acc, [key], updatedMeta);
2995
3250
  return acc;
2996
3251
  }
2997
- if (edit.mainField === "id")
2998
- return acc;
3252
+ if (edit.mainField === "id") return acc;
2999
3253
  const targetSchema = getTargetSchema(attr.targetModel);
3000
- if (!targetSchema)
3001
- return acc;
3254
+ if (!targetSchema) return acc;
3002
3255
  if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
3003
3256
  _.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
3004
3257
  _.set(acc, [key], updatedMeta);
@@ -3009,12 +3262,12 @@ async function syncMetadatas(configuration, schema) {
3009
3262
  return _.assign(metasWithDefaults, updatedMetas);
3010
3263
  }
3011
3264
  const getTargetSchema = (targetModel) => {
3012
- return getService$1("content-types").findContentType(targetModel);
3265
+ return getService$2("content-types").findContentType(targetModel);
3013
3266
  };
3014
3267
  const DEFAULT_LIST_LENGTH = 4;
3015
3268
  const MAX_ROW_SIZE = 12;
3016
3269
  const isAllowedFieldSize = (type, size) => {
3017
- const { getFieldSize } = getService$1("field-sizes");
3270
+ const { getFieldSize } = getService$2("field-sizes");
3018
3271
  const fieldSize = getFieldSize(type);
3019
3272
  if (!fieldSize.isResizable && size !== fieldSize.default) {
3020
3273
  return false;
@@ -3022,7 +3275,7 @@ const isAllowedFieldSize = (type, size) => {
3022
3275
  return size <= MAX_ROW_SIZE;
3023
3276
  };
3024
3277
  const getDefaultFieldSize = (attribute) => {
3025
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3278
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
3026
3279
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
3027
3280
  };
3028
3281
  async function createDefaultLayouts(schema) {
@@ -3043,8 +3296,7 @@ function createDefaultEditLayout(schema) {
3043
3296
  return appendToEditLayout([], keys2, schema);
3044
3297
  }
3045
3298
  function syncLayouts(configuration, schema) {
3046
- if (_.isEmpty(configuration.layouts))
3047
- return createDefaultLayouts(schema);
3299
+ if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
3048
3300
  const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
3049
3301
  let cleanList = list.filter((attr) => isListable(schema, attr));
3050
3302
  const cleanEditRelations = editRelations.filter(
@@ -3055,9 +3307,8 @@ function syncLayouts(configuration, schema) {
3055
3307
  for (const row of edit) {
3056
3308
  const newRow = [];
3057
3309
  for (const el of row) {
3058
- if (!hasEditableAttribute(schema, el.name))
3059
- continue;
3060
- const { hasFieldSize } = getService$1("field-sizes");
3310
+ if (!hasEditableAttribute(schema, el.name)) continue;
3311
+ const { hasFieldSize } = getService$2("field-sizes");
3061
3312
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3062
3313
  if (!isAllowedFieldSize(fieldType, el.size)) {
3063
3314
  elementsToReAppend.push(el.name);
@@ -3087,8 +3338,7 @@ function syncLayouts(configuration, schema) {
3087
3338
  };
3088
3339
  }
3089
3340
  const appendToEditLayout = (layout = [], keysToAppend, schema) => {
3090
- if (keysToAppend.length === 0)
3091
- return layout;
3341
+ if (keysToAppend.length === 0) return layout;
3092
3342
  let currentRowIndex = Math.max(layout.length - 1, 0);
3093
3343
  if (!layout[currentRowIndex]) {
3094
3344
  layout[currentRowIndex] = [];
@@ -3197,17 +3447,17 @@ const configurationService$1 = createConfigurationService({
3197
3447
  isComponent: true,
3198
3448
  prefix: STORE_KEY_PREFIX,
3199
3449
  getModels() {
3200
- const { toContentManagerModel } = getService$1("data-mapper");
3450
+ const { toContentManagerModel } = getService$2("data-mapper");
3201
3451
  return mapValues(toContentManagerModel, strapi.components);
3202
3452
  }
3203
3453
  });
3204
3454
  const components = ({ strapi: strapi2 }) => ({
3205
3455
  findAllComponents() {
3206
- const { toContentManagerModel } = getService$1("data-mapper");
3456
+ const { toContentManagerModel } = getService$2("data-mapper");
3207
3457
  return Object.values(strapi2.components).map(toContentManagerModel);
3208
3458
  },
3209
3459
  findComponent(uid2) {
3210
- const { toContentManagerModel } = getService$1("data-mapper");
3460
+ const { toContentManagerModel } = getService$2("data-mapper");
3211
3461
  const component = strapi2.components[uid2];
3212
3462
  return isNil$1(component) ? component : toContentManagerModel(component);
3213
3463
  },
@@ -3258,17 +3508,17 @@ const configurationService = createConfigurationService({
3258
3508
  storeUtils,
3259
3509
  prefix: "content_types",
3260
3510
  getModels() {
3261
- const { toContentManagerModel } = getService$1("data-mapper");
3511
+ const { toContentManagerModel } = getService$2("data-mapper");
3262
3512
  return mapValues(toContentManagerModel, strapi.contentTypes);
3263
3513
  }
3264
3514
  });
3265
3515
  const service = ({ strapi: strapi2 }) => ({
3266
3516
  findAllContentTypes() {
3267
- const { toContentManagerModel } = getService$1("data-mapper");
3517
+ const { toContentManagerModel } = getService$2("data-mapper");
3268
3518
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3269
3519
  },
3270
3520
  findContentType(uid2) {
3271
- const { toContentManagerModel } = getService$1("data-mapper");
3521
+ const { toContentManagerModel } = getService$2("data-mapper");
3272
3522
  const contentType = strapi2.contentTypes[uid2];
3273
3523
  return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
3274
3524
  },
@@ -3297,7 +3547,7 @@ const service = ({ strapi: strapi2 }) => ({
3297
3547
  return this.findConfiguration(contentType);
3298
3548
  },
3299
3549
  findComponentsConfigurations(contentType) {
3300
- return getService$1("components").findComponentsConfigurations(contentType);
3550
+ return getService$2("components").findComponentsConfigurations(contentType);
3301
3551
  },
3302
3552
  syncConfigurations() {
3303
3553
  return configurationService.syncConfigurations();
@@ -3478,12 +3728,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3478
3728
  ability: userAbility,
3479
3729
  model
3480
3730
  });
3481
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3731
+ const { actionProvider } = strapi2.service("admin::permission");
3732
+ const toSubject = (entity) => {
3733
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3734
+ };
3482
3735
  const can = (action, entity, field) => {
3483
- return userAbility.can(action, toSubject(entity), field);
3736
+ const subject = toSubject(entity);
3737
+ const aliases = actionProvider.unstable_aliases(action, model);
3738
+ return (
3739
+ // Test the original action to see if it passes
3740
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3741
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3742
+ );
3484
3743
  };
3485
3744
  const cannot = (action, entity, field) => {
3486
- return userAbility.cannot(action, toSubject(entity), field);
3745
+ const subject = toSubject(entity);
3746
+ const aliases = actionProvider.unstable_aliases(action, model);
3747
+ return (
3748
+ // Test both the original action
3749
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3750
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3751
+ );
3487
3752
  };
3488
3753
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3489
3754
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3554,7 +3819,7 @@ const permission = ({ strapi: strapi2 }) => ({
3554
3819
  return userAbility.can(action);
3555
3820
  },
3556
3821
  async registerPermissions() {
3557
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3822
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3558
3823
  const contentTypesUids = displayedContentTypes.map(prop("uid"));
3559
3824
  const actions = [
3560
3825
  {
@@ -3830,7 +4095,7 @@ const getQueryPopulate = async (uid2, query) => {
3830
4095
  return populateQuery;
3831
4096
  };
3832
4097
  const buildDeepPopulate = (uid2) => {
3833
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4098
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3834
4099
  };
3835
4100
  const populateBuilder = (uid2) => {
3836
4101
  let getInitialPopulate = async () => {
@@ -4015,7 +4280,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4015
4280
  */
4016
4281
  async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4017
4282
  const versionsByLocale = groupBy("locale", allVersions);
4018
- delete versionsByLocale[version.locale];
4283
+ if (version.locale) {
4284
+ delete versionsByLocale[version.locale];
4285
+ }
4019
4286
  const model = strapi2.getModel(uid2);
4020
4287
  const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4021
4288
  const traversalFunction = async (localeVersion) => traverseEntity(
@@ -4062,8 +4329,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4062
4329
  const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
4063
4330
  return matchLocale && matchStatus;
4064
4331
  });
4065
- if (!availableStatus)
4066
- return availableStatus;
4332
+ if (!availableStatus) return availableStatus;
4067
4333
  return pick(AVAILABLE_STATUS_FIELDS, availableStatus);
4068
4334
  },
4069
4335
  /**
@@ -4073,8 +4339,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4073
4339
  * @returns
4074
4340
  */
4075
4341
  async getManyAvailableStatus(uid2, documents) {
4076
- if (!documents.length)
4077
- return [];
4342
+ if (!documents.length) return [];
4078
4343
  const status = documents[0].publishedAt !== null ? "published" : "draft";
4079
4344
  const locale = documents[0]?.locale;
4080
4345
  const otherStatus = status === "published" ? "draft" : "published";
@@ -4101,10 +4366,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4101
4366
  } else if (otherVersion) {
4102
4367
  draftVersion = otherVersion;
4103
4368
  }
4104
- if (!draftVersion)
4105
- return CONTENT_MANAGER_STATUS.PUBLISHED;
4106
- if (!publishedVersion)
4107
- return CONTENT_MANAGER_STATUS.DRAFT;
4369
+ if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
4370
+ if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
4108
4371
  const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
4109
4372
  return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
4110
4373
  },
@@ -4371,7 +4634,8 @@ const services = {
4371
4634
  permission,
4372
4635
  "populate-builder": populateBuilder$1,
4373
4636
  uid,
4374
- ...history.services ? history.services : {}
4637
+ ...history.services ? history.services : {},
4638
+ ...preview.services ? preview.services : {}
4375
4639
  };
4376
4640
  const index = () => {
4377
4641
  return {