@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.8e52d29d243dccc7c24beb53412cf1c9c0b36d11

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 (207) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage--MCP7Aew.js} +4 -4
  3. package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage--MCP7Aew.js.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-DT41asyM.mjs} +4 -4
  5. package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-DT41asyM.mjs.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-DznPxn9p.mjs} +4 -4
  7. package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-DznPxn9p.mjs.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-qgnNvv_u.js} +4 -4
  9. package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-qgnNvv_u.js.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-B_k7z288.mjs} +72 -50
  11. package/dist/_chunks/EditViewPage-B_k7z288.mjs.map +1 -0
  12. package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-Bb4S7p8c.js} +70 -48
  13. package/dist/_chunks/EditViewPage-Bb4S7p8c.js.map +1 -0
  14. package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-ByR1mllE.js} +582 -230
  15. package/dist/_chunks/Field-ByR1mllE.js.map +1 -0
  16. package/dist/_chunks/{Field-Cz_J9551.mjs → Field-DmwbE0TL.mjs} +580 -228
  17. package/dist/_chunks/Field-DmwbE0TL.mjs.map +1 -0
  18. package/dist/_chunks/{Form-Bpig5rch.js → Form-BpeyAyS1.js} +52 -34
  19. package/dist/_chunks/Form-BpeyAyS1.js.map +1 -0
  20. package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-Dvt5eouJ.mjs} +54 -36
  21. package/dist/_chunks/Form-Dvt5eouJ.mjs.map +1 -0
  22. package/dist/_chunks/{History-BZP8n7KT.mjs → History-CAERKpYl.mjs} +171 -77
  23. package/dist/_chunks/History-CAERKpYl.mjs.map +1 -0
  24. package/dist/_chunks/{History-BfX6XmZK.js → History-d-IgDGPl.js} +170 -76
  25. package/dist/_chunks/History-d-IgDGPl.js.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-CVVT45M8.mjs} +59 -49
  27. package/dist/_chunks/ListConfigurationPage-CVVT45M8.mjs.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-DSX98CYb.js} +58 -47
  29. package/dist/_chunks/ListConfigurationPage-DSX98CYb.js.map +1 -0
  30. package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-C9gPPp-V.js} +117 -105
  31. package/dist/_chunks/ListViewPage-C9gPPp-V.js.map +1 -0
  32. package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-Q4g6kHDl.mjs} +115 -103
  33. package/dist/_chunks/ListViewPage-Q4g6kHDl.mjs.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-BY4YRGs0.mjs} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-BY4YRGs0.mjs.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-D09gppmy.js} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-D09gppmy.js.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-32WgThJG.js} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-32WgThJG.js.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-CyM16RKL.mjs} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-CyM16RKL.mjs.map} +1 -1
  42. package/dist/_chunks/Preview-C2WFq4S8.mjs +267 -0
  43. package/dist/_chunks/Preview-C2WFq4S8.mjs.map +1 -0
  44. package/dist/_chunks/Preview-PpV3g9wJ.js +286 -0
  45. package/dist/_chunks/Preview-PpV3g9wJ.js.map +1 -0
  46. package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-B_Yn9xGB.mjs} +73 -37
  47. package/dist/_chunks/Relations-B_Yn9xGB.mjs.map +1 -0
  48. package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-mWaebC5t.js} +72 -36
  49. package/dist/_chunks/Relations-mWaebC5t.js.map +1 -0
  50. package/dist/_chunks/{en-BN1bvFK7.js → en-CHOp_xJv.js} +30 -16
  51. package/dist/_chunks/{en-BN1bvFK7.js.map → en-CHOp_xJv.js.map} +1 -1
  52. package/dist/_chunks/{en-Dzv55oQw.mjs → en-D_BMf0hT.mjs} +30 -16
  53. package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-D_BMf0hT.mjs.map} +1 -1
  54. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  55. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  56. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  57. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  58. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
  59. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
  60. package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
  61. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
  62. package/dist/_chunks/{index-VHviNMeW.mjs → index-CbytGVdz.mjs} +1154 -887
  63. package/dist/_chunks/index-CbytGVdz.mjs.map +1 -0
  64. package/dist/_chunks/{index-DzN3kBgx.js → index-iun2i4xv.js} +1133 -865
  65. package/dist/_chunks/index-iun2i4xv.js.map +1 -0
  66. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  67. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  68. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  69. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  70. package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-Btu_cMRF.mjs} +41 -23
  71. package/dist/_chunks/layout-Btu_cMRF.mjs.map +1 -0
  72. package/dist/_chunks/{layout-b91XRlD2.js → layout-CkaP4K5_.js} +39 -21
  73. package/dist/_chunks/layout-CkaP4K5_.js.map +1 -0
  74. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  75. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  76. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  77. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  78. package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-Cn5re8ia.mjs} +6 -7
  79. package/dist/_chunks/relations-Cn5re8ia.mjs.map +1 -0
  80. package/dist/_chunks/{relations-CA7IYmcP.js → relations-O_v9g0v_.js} +6 -7
  81. package/dist/_chunks/relations-O_v9g0v_.js.map +1 -0
  82. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  83. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  84. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  85. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  86. package/dist/admin/index.js +2 -1
  87. package/dist/admin/index.js.map +1 -1
  88. package/dist/admin/index.mjs +8 -7
  89. package/dist/admin/src/exports.d.ts +1 -1
  90. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
  91. package/dist/admin/src/history/index.d.ts +3 -0
  92. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  93. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  94. package/dist/admin/src/index.d.ts +1 -0
  95. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  96. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
  98. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  99. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  100. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  101. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +6 -58
  102. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  103. package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
  104. package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
  105. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  106. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  107. package/dist/admin/src/preview/constants.d.ts +1 -0
  108. package/dist/admin/src/preview/index.d.ts +4 -0
  109. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  110. package/dist/admin/src/preview/routes.d.ts +3 -0
  111. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  112. package/dist/admin/src/services/api.d.ts +1 -1
  113. package/dist/admin/src/services/components.d.ts +2 -2
  114. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  115. package/dist/admin/src/services/documents.d.ts +19 -17
  116. package/dist/admin/src/services/init.d.ts +1 -1
  117. package/dist/admin/src/services/relations.d.ts +2 -2
  118. package/dist/admin/src/services/uid.d.ts +3 -3
  119. package/dist/admin/src/utils/validation.d.ts +4 -1
  120. package/dist/server/index.js +551 -263
  121. package/dist/server/index.js.map +1 -1
  122. package/dist/server/index.mjs +552 -264
  123. package/dist/server/index.mjs.map +1 -1
  124. package/dist/server/src/bootstrap.d.ts.map +1 -1
  125. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  126. package/dist/server/src/controllers/index.d.ts.map +1 -1
  127. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  128. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  129. package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
  130. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  131. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  132. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  133. package/dist/server/src/history/services/history.d.ts.map +1 -1
  134. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  135. package/dist/server/src/history/services/utils.d.ts +4 -4
  136. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  137. package/dist/server/src/index.d.ts +4 -4
  138. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  139. package/dist/server/src/preview/constants.d.ts +2 -0
  140. package/dist/server/src/preview/constants.d.ts.map +1 -0
  141. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  142. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  143. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  144. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  145. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  146. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  147. package/dist/server/src/preview/index.d.ts +4 -0
  148. package/dist/server/src/preview/index.d.ts.map +1 -0
  149. package/dist/server/src/preview/routes/index.d.ts +8 -0
  150. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  151. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  152. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  153. package/dist/server/src/preview/services/index.d.ts +15 -0
  154. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  155. package/dist/server/src/preview/services/preview-config.d.ts +30 -0
  156. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  157. package/dist/server/src/preview/services/preview.d.ts +12 -0
  158. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  159. package/dist/server/src/preview/utils.d.ts +18 -0
  160. package/dist/server/src/preview/utils.d.ts.map +1 -0
  161. package/dist/server/src/routes/index.d.ts.map +1 -1
  162. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  163. package/dist/server/src/services/document-metadata.d.ts +8 -8
  164. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  165. package/dist/server/src/services/index.d.ts +4 -4
  166. package/dist/server/src/services/index.d.ts.map +1 -1
  167. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  168. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  169. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  170. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  171. package/dist/server/src/utils/index.d.ts +2 -0
  172. package/dist/server/src/utils/index.d.ts.map +1 -1
  173. package/dist/shared/contracts/collection-types.d.ts +3 -1
  174. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  175. package/dist/shared/contracts/index.d.ts +1 -0
  176. package/dist/shared/contracts/index.d.ts.map +1 -1
  177. package/dist/shared/contracts/preview.d.ts +27 -0
  178. package/dist/shared/contracts/preview.d.ts.map +1 -0
  179. package/dist/shared/index.js +4 -0
  180. package/dist/shared/index.js.map +1 -1
  181. package/dist/shared/index.mjs +4 -0
  182. package/dist/shared/index.mjs.map +1 -1
  183. package/package.json +13 -13
  184. package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
  185. package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
  186. package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
  187. package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
  188. package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
  189. package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
  190. package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
  191. package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
  192. package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
  193. package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
  194. package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
  195. package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
  196. package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
  197. package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
  198. package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
  199. package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
  200. package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
  201. package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
  202. package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
  203. package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
  204. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  205. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  206. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  207. 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, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, isNil as isNil$1, getOr, propEq, merge, groupBy, castArray } from "lodash/fp";
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";
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
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
173
173
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
174
174
  };
175
175
  const localesService = strapi2.plugin("i18n")?.service("locales");
176
+ const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
176
177
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
178
+ const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
177
179
  const getLocaleDictionary = async () => {
178
180
  if (!localesService)
179
181
  return {};
@@ -200,31 +202,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
200
202
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
201
203
  return documentMetadataService.getStatus(document, meta.availableStatus);
202
204
  };
203
- const getDeepPopulate2 = (uid2) => {
205
+ const getComponentFields = (componentUID) => {
206
+ return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
207
+ (fieldsAcc, [key, attribute]) => {
208
+ if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
209
+ fieldsAcc.push(key);
210
+ }
211
+ return fieldsAcc;
212
+ },
213
+ []
214
+ );
215
+ };
216
+ const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
204
217
  const model = strapi2.getModel(uid2);
205
218
  const attributes = Object.entries(model.attributes);
219
+ const fieldSelector = useDatabaseSyntax ? "select" : "fields";
206
220
  return attributes.reduce((acc, [attributeName, attribute]) => {
207
221
  switch (attribute.type) {
208
222
  case "relation": {
223
+ const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
224
+ if (isMorphRelation) {
225
+ break;
226
+ }
209
227
  const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
210
228
  if (isVisible2) {
211
- acc[attributeName] = { fields: ["documentId", "locale", "publishedAt"] };
229
+ acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
212
230
  }
213
231
  break;
214
232
  }
215
233
  case "media": {
216
- acc[attributeName] = { fields: ["id"] };
234
+ acc[attributeName] = { [fieldSelector]: ["id"] };
217
235
  break;
218
236
  }
219
237
  case "component": {
220
238
  const populate = getDeepPopulate2(attribute.component);
221
- acc[attributeName] = { populate };
239
+ acc[attributeName] = {
240
+ populate,
241
+ [fieldSelector]: getComponentFields(attribute.component)
242
+ };
222
243
  break;
223
244
  }
224
245
  case "dynamiczone": {
225
246
  const populatedComponents = (attribute.components || []).reduce(
226
247
  (acc2, componentUID) => {
227
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
248
+ acc2[componentUID] = {
249
+ populate: getDeepPopulate2(componentUID),
250
+ [fieldSelector]: getComponentFields(componentUID)
251
+ };
228
252
  return acc2;
229
253
  },
230
254
  {}
@@ -286,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
286
310
  getRelationRestoreValue,
287
311
  getMediaRestoreValue,
288
312
  getDefaultLocale,
313
+ isLocalizedContentType,
289
314
  getLocaleDictionary,
290
315
  getRetentionDays,
291
316
  getVersionStatus,
@@ -308,7 +333,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
308
333
  });
309
334
  },
310
335
  async findVersionsPage(params) {
311
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
336
+ const model = strapi2.getModel(params.query.contentType);
337
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
338
+ const defaultLocale = await serviceUtils.getDefaultLocale();
339
+ let locale = null;
340
+ if (isLocalizedContentType) {
341
+ locale = params.query.locale || defaultLocale;
342
+ }
312
343
  const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
313
344
  query.findPage({
314
345
  ...params.query,
@@ -330,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
330
361
  const attributeValue = entry.data[attributeKey];
331
362
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
332
363
  if (attributeSchema.type === "media") {
333
- const permissionChecker2 = getService$1("permission-checker").create({
364
+ const permissionChecker2 = getService$2("permission-checker").create({
334
365
  userAbility: params.state.userAbility,
335
366
  model: "plugin::upload.file"
336
367
  });
@@ -353,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
353
384
  if (userToPopulate == null) {
354
385
  return null;
355
386
  }
356
- return strapi2.query("admin::user").findOne({ where: { id: userToPopulate.id } });
387
+ return strapi2.query("admin::user").findOne({
388
+ where: {
389
+ ...userToPopulate.id ? { id: userToPopulate.id } : {},
390
+ ...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
391
+ }
392
+ });
357
393
  })
358
394
  );
359
395
  return {
@@ -366,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
366
402
  [attributeKey]: adminUsers
367
403
  };
368
404
  }
369
- const permissionChecker2 = getService$1("permission-checker").create({
405
+ const permissionChecker2 = getService$2("permission-checker").create({
370
406
  userAbility: params.state.userAbility,
371
407
  model: attributeSchema.target
372
408
  });
@@ -464,13 +500,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
464
500
  }
465
501
  };
466
502
  };
503
+ const shouldCreateHistoryVersion = (context) => {
504
+ if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
505
+ return false;
506
+ }
507
+ if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
508
+ return false;
509
+ }
510
+ if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
511
+ return false;
512
+ }
513
+ if (!context.contentType.uid.startsWith("api::")) {
514
+ return false;
515
+ }
516
+ return true;
517
+ };
518
+ const getSchemas = (uid2) => {
519
+ const attributesSchema = strapi.getModel(uid2).attributes;
520
+ const componentsSchemas = Object.keys(attributesSchema).reduce(
521
+ (currentComponentSchemas, key) => {
522
+ const fieldSchema = attributesSchema[key];
523
+ if (fieldSchema.type === "component") {
524
+ const componentSchema = strapi.getModel(fieldSchema.component).attributes;
525
+ return {
526
+ ...currentComponentSchemas,
527
+ [fieldSchema.component]: componentSchema
528
+ };
529
+ }
530
+ return currentComponentSchemas;
531
+ },
532
+ {}
533
+ );
534
+ return {
535
+ schema: omit(FIELDS_TO_IGNORE, attributesSchema),
536
+ componentsSchemas
537
+ };
538
+ };
467
539
  const createLifecyclesService = ({ strapi: strapi2 }) => {
468
540
  const state = {
469
541
  deleteExpiredJob: null,
470
542
  isInitialized: false
471
543
  };
472
- const query = strapi2.db.query(HISTORY_VERSION_UID);
473
- const historyService = getService(strapi2, "history");
474
544
  const serviceUtils = createServiceUtils({ strapi: strapi2 });
475
545
  return {
476
546
  async bootstrap() {
@@ -478,73 +548,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
478
548
  return;
479
549
  }
480
550
  strapi2.documents.use(async (context, next) => {
481
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
482
- return next();
483
- }
484
- if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
485
- return next();
486
- }
487
- const contentTypeUid = context.contentType.uid;
488
- if (!contentTypeUid.startsWith("api::")) {
489
- return next();
490
- }
491
551
  const result = await next();
492
- const documentContext = {
493
- documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
494
- locale: context.params?.locale
495
- };
552
+ if (!shouldCreateHistoryVersion(context)) {
553
+ return result;
554
+ }
555
+ const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
496
556
  const defaultLocale = await serviceUtils.getDefaultLocale();
497
- const locale = documentContext.locale || defaultLocale;
498
- if (Array.isArray(locale)) {
499
- strapi2.log.warn(
500
- "[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
501
- );
502
- return next();
557
+ const locales = castArray(context.params?.locale || defaultLocale);
558
+ if (!locales.length) {
559
+ return result;
503
560
  }
504
- const document = await strapi2.documents(contentTypeUid).findOne({
505
- documentId: documentContext.documentId,
506
- locale,
507
- populate: serviceUtils.getDeepPopulate(contentTypeUid)
561
+ const uid2 = context.contentType.uid;
562
+ const schemas = getSchemas(uid2);
563
+ const model = strapi2.getModel(uid2);
564
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
565
+ const localeEntries = await strapi2.db.query(uid2).findMany({
566
+ where: {
567
+ documentId,
568
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
569
+ ...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
570
+ },
571
+ populate: serviceUtils.getDeepPopulate(
572
+ uid2,
573
+ true
574
+ /* use database syntax */
575
+ )
508
576
  });
509
- const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
510
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
511
- const componentsSchemas = Object.keys(
512
- attributesSchema
513
- ).reduce((currentComponentSchemas, key) => {
514
- const fieldSchema = attributesSchema[key];
515
- if (fieldSchema.type === "component") {
516
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
517
- return {
518
- ...currentComponentSchemas,
519
- [fieldSchema.component]: componentSchema
520
- };
521
- }
522
- return currentComponentSchemas;
523
- }, {});
524
577
  await strapi2.db.transaction(async ({ onCommit }) => {
525
- onCommit(() => {
526
- historyService.createVersion({
527
- contentType: contentTypeUid,
528
- data: omit(FIELDS_TO_IGNORE, document),
529
- schema: omit(FIELDS_TO_IGNORE, attributesSchema),
530
- componentsSchemas,
531
- relatedDocumentId: documentContext.documentId,
532
- locale,
533
- status
534
- });
578
+ onCommit(async () => {
579
+ for (const entry of localeEntries) {
580
+ const status = await serviceUtils.getVersionStatus(uid2, entry);
581
+ await getService$1(strapi2, "history").createVersion({
582
+ contentType: uid2,
583
+ data: omit(FIELDS_TO_IGNORE, entry),
584
+ relatedDocumentId: documentId,
585
+ locale: entry.locale,
586
+ status,
587
+ ...schemas
588
+ });
589
+ }
535
590
  });
536
591
  });
537
592
  return result;
538
593
  });
539
- state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
594
+ state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
540
595
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
541
596
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
542
- query.deleteMany({
597
+ strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
543
598
  where: {
544
599
  created_at: {
545
- $lt: expirationDate.toISOString()
600
+ $lt: expirationDate
546
601
  }
547
602
  }
603
+ }).catch((error) => {
604
+ if (error instanceof Error) {
605
+ strapi2.log.error("Error deleting expired history versions", error.message);
606
+ }
548
607
  });
549
608
  });
550
609
  state.isInitialized = true;
@@ -556,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
556
615
  }
557
616
  };
558
617
  };
559
- const services$1 = {
618
+ const services$2 = {
560
619
  history: createHistoryService,
561
620
  lifecycles: createLifecyclesService
562
621
  };
563
- const info = { pluginName: "content-manager", type: "admin" };
622
+ const info$1 = { pluginName: "content-manager", type: "admin" };
564
623
  const historyVersionRouter = {
565
624
  type: "admin",
566
625
  routes: [
567
626
  {
568
627
  method: "GET",
569
- info,
628
+ info: info$1,
570
629
  path: "/history-versions",
571
630
  handler: "history-version.findMany",
572
631
  config: {
@@ -575,7 +634,7 @@ const historyVersionRouter = {
575
634
  },
576
635
  {
577
636
  method: "PUT",
578
- info,
637
+ info: info$1,
579
638
  path: "/history-versions/:versionId/restore",
580
639
  handler: "history-version.restoreVersion",
581
640
  config: {
@@ -584,7 +643,7 @@ const historyVersionRouter = {
584
643
  }
585
644
  ]
586
645
  };
587
- const routes$1 = {
646
+ const routes$2 = {
588
647
  "history-version": historyVersionRouter
589
648
  };
590
649
  const historyVersion = {
@@ -631,21 +690,21 @@ const historyVersion = {
631
690
  }
632
691
  }
633
692
  };
634
- const getFeature = () => {
693
+ const getFeature$1 = () => {
635
694
  if (strapi.ee.features.isEnabled("cms-content-history")) {
636
695
  return {
637
696
  register({ strapi: strapi2 }) {
638
697
  strapi2.get("models").add(historyVersion);
639
698
  },
640
699
  bootstrap({ strapi: strapi2 }) {
641
- getService(strapi2, "lifecycles").bootstrap();
700
+ getService$1(strapi2, "lifecycles").bootstrap();
642
701
  },
643
702
  destroy({ strapi: strapi2 }) {
644
- getService(strapi2, "lifecycles").destroy();
703
+ getService$1(strapi2, "lifecycles").destroy();
645
704
  },
646
- controllers: controllers$1,
647
- services: services$1,
648
- routes: routes$1
705
+ controllers: controllers$2,
706
+ services: services$2,
707
+ routes: routes$2
649
708
  };
650
709
  }
651
710
  return {
@@ -654,7 +713,7 @@ const getFeature = () => {
654
713
  }
655
714
  };
656
715
  };
657
- const history = getFeature();
716
+ const history = getFeature$1();
658
717
  const register = async ({ strapi: strapi2 }) => {
659
718
  await history.register?.({ strapi: strapi2 });
660
719
  };
@@ -662,15 +721,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
662
721
  ENTRY_PUBLISH: "entry.publish",
663
722
  ENTRY_UNPUBLISH: "entry.unpublish"
664
723
  };
724
+ const FEATURE_ID = "preview";
725
+ const info = { pluginName: "content-manager", type: "admin" };
726
+ const previewRouter = {
727
+ type: "admin",
728
+ routes: [
729
+ {
730
+ method: "GET",
731
+ info,
732
+ path: "/preview/url/:contentType",
733
+ handler: "preview.getPreviewUrl",
734
+ config: {
735
+ policies: ["admin::isAuthenticatedAdmin"]
736
+ }
737
+ }
738
+ ]
739
+ };
740
+ const routes$1 = {
741
+ preview: previewRouter
742
+ };
743
+ function getService(strapi2, name) {
744
+ return strapi2.service(`plugin::content-manager.${name}`);
745
+ }
746
+ const getPreviewUrlSchema = yup.object().shape({
747
+ // Will be undefined for single types
748
+ documentId: yup.string(),
749
+ locale: yup.string().nullable(),
750
+ status: yup.string()
751
+ }).required();
752
+ const validatePreviewUrl = async (strapi2, uid2, params) => {
753
+ await validateYupSchema(getPreviewUrlSchema)(params);
754
+ const newParams = pick(["documentId", "locale", "status"], params);
755
+ const model = strapi2.getModel(uid2);
756
+ if (!model || model.modelType !== "contentType") {
757
+ throw new errors.ValidationError("Invalid content type");
758
+ }
759
+ const isSingleType = model?.kind === "singleType";
760
+ if (!isSingleType && !params.documentId) {
761
+ throw new errors.ValidationError("documentId is required for Collection Types");
762
+ }
763
+ if (isSingleType) {
764
+ const doc = await strapi2.documents(uid2).findFirst();
765
+ if (!doc) {
766
+ throw new errors.NotFoundError("Document not found");
767
+ }
768
+ newParams.documentId = doc?.documentId;
769
+ }
770
+ return newParams;
771
+ };
772
+ const createPreviewController = () => {
773
+ return {
774
+ /**
775
+ * Transforms an entry into a preview URL, so that it can be previewed
776
+ * in the Content Manager.
777
+ */
778
+ async getPreviewUrl(ctx) {
779
+ const uid2 = ctx.params.contentType;
780
+ const query = ctx.request.query;
781
+ const params = await validatePreviewUrl(strapi, uid2, query);
782
+ const previewService = getService(strapi, "preview");
783
+ const url = await previewService.getPreviewUrl(uid2, params);
784
+ if (!url) {
785
+ ctx.status = 204;
786
+ }
787
+ return {
788
+ data: { url }
789
+ };
790
+ }
791
+ };
792
+ };
793
+ const controllers$1 = {
794
+ preview: createPreviewController
795
+ /**
796
+ * Casting is needed because the types aren't aware that Strapi supports
797
+ * passing a controller factory as the value, instead of a controller object directly
798
+ */
799
+ };
800
+ const createPreviewService = ({ strapi: strapi2 }) => {
801
+ const config = getService(strapi2, "preview-config");
802
+ return {
803
+ async getPreviewUrl(uid2, params) {
804
+ const handler = config.getPreviewHandler();
805
+ try {
806
+ return handler(uid2, params);
807
+ } catch (error) {
808
+ strapi2.log.error(`Failed to get preview URL: ${error}`);
809
+ throw new errors.ApplicationError("Failed to get preview URL");
810
+ }
811
+ return;
812
+ }
813
+ };
814
+ };
815
+ const createPreviewConfigService = ({ strapi: strapi2 }) => {
816
+ return {
817
+ isEnabled() {
818
+ const config = strapi2.config.get("admin.preview");
819
+ if (!config) {
820
+ return false;
821
+ }
822
+ return config?.enabled ?? true;
823
+ },
824
+ /**
825
+ * Validate if the configuration is valid
826
+ */
827
+ validate() {
828
+ if (!this.isEnabled()) {
829
+ return;
830
+ }
831
+ const handler = this.getPreviewHandler();
832
+ if (typeof handler !== "function") {
833
+ throw new errors.ValidationError(
834
+ "Preview configuration is invalid. Handler must be a function"
835
+ );
836
+ }
837
+ },
838
+ /**
839
+ * Utility to get the preview handler from the configuration
840
+ */
841
+ getPreviewHandler() {
842
+ const config = strapi2.config.get("admin.preview");
843
+ const emptyHandler = () => {
844
+ return void 0;
845
+ };
846
+ if (!this.isEnabled()) {
847
+ return emptyHandler;
848
+ }
849
+ return config?.config?.handler || emptyHandler;
850
+ }
851
+ };
852
+ };
853
+ const services$1 = {
854
+ preview: createPreviewService,
855
+ "preview-config": createPreviewConfigService
856
+ };
857
+ const getFeature = () => {
858
+ if (!strapi.features.future.isEnabled(FEATURE_ID)) {
859
+ return {};
860
+ }
861
+ return {
862
+ bootstrap() {
863
+ console.log("Bootstrapping preview server");
864
+ const config = getService(strapi, "preview-config");
865
+ config.validate();
866
+ },
867
+ routes: routes$1,
868
+ controllers: controllers$1,
869
+ services: services$1
870
+ };
871
+ };
872
+ const preview = getFeature();
665
873
  const bootstrap = async () => {
666
874
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
667
875
  strapi.get("webhookStore").addAllowedEvent(key, value);
668
876
  });
669
- getService$1("field-sizes").setCustomFieldInputSizes();
670
- await getService$1("components").syncConfigurations();
671
- await getService$1("content-types").syncConfigurations();
672
- await getService$1("permission").registerPermissions();
877
+ getService$2("field-sizes").setCustomFieldInputSizes();
878
+ await getService$2("components").syncConfigurations();
879
+ await getService$2("content-types").syncConfigurations();
880
+ await getService$2("permission").registerPermissions();
673
881
  await history.bootstrap?.({ strapi });
882
+ await preview.bootstrap?.({ strapi });
674
883
  };
675
884
  const destroy = async ({ strapi: strapi2 }) => {
676
885
  await history.destroy?.({ strapi: strapi2 });
@@ -1160,7 +1369,8 @@ const admin = {
1160
1369
  };
1161
1370
  const routes = {
1162
1371
  admin,
1163
- ...history.routes ? history.routes : {}
1372
+ ...history.routes ? history.routes : {},
1373
+ ...preview.routes ? preview.routes : {}
1164
1374
  };
1165
1375
  const hasPermissionsSchema = yup$1.object({
1166
1376
  actions: yup$1.array().of(yup$1.string()),
@@ -1171,6 +1381,11 @@ const { createPolicy } = policy;
1171
1381
  const hasPermissions = createPolicy({
1172
1382
  name: "plugin::content-manager.hasPermissions",
1173
1383
  validator: validateHasPermissionsInput,
1384
+ /**
1385
+ * NOTE: Action aliases are currently not checked at this level (policy).
1386
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1387
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1388
+ */
1174
1389
  handler(ctx, config = {}) {
1175
1390
  const { actions = [], hasAtLeastOne = false } = config;
1176
1391
  const { userAbility } = ctx.state;
@@ -1412,7 +1627,7 @@ const createMetadasSchema = (schema) => {
1412
1627
  if (!value) {
1413
1628
  return yup$1.string();
1414
1629
  }
1415
- const targetSchema = getService$1("content-types").findContentType(
1630
+ const targetSchema = getService$2("content-types").findContentType(
1416
1631
  schema.attributes[key].targetModel
1417
1632
  );
1418
1633
  if (!targetSchema) {
@@ -1564,9 +1779,11 @@ const multipleLocaleSchema = yup$1.lazy(
1564
1779
  (value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
1565
1780
  );
1566
1781
  const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
1567
- const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
1782
+ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
1568
1783
  const { allowMultipleLocales } = opts;
1569
- const { locale, status, ...rest } = request || {};
1784
+ const { locale, status: providedStatus, ...rest } = request || {};
1785
+ const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
1786
+ const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
1570
1787
  const schema = yup$1.object().shape({
1571
1788
  locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
1572
1789
  status: statusSchema
@@ -1579,7 +1796,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
1579
1796
  }
1580
1797
  };
1581
1798
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1582
- const documentMetadata2 = getService$1("document-metadata");
1799
+ const documentMetadata2 = getService$2("document-metadata");
1583
1800
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1584
1801
  let {
1585
1802
  meta: { availableLocales, availableStatus }
@@ -1605,8 +1822,8 @@ const createDocument = async (ctx, opts) => {
1605
1822
  const { userAbility, user } = ctx.state;
1606
1823
  const { model } = ctx.params;
1607
1824
  const { body } = ctx.request;
1608
- const documentManager2 = getService$1("document-manager");
1609
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1825
+ const documentManager2 = getService$2("document-manager");
1826
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1610
1827
  if (permissionChecker2.cannot.create()) {
1611
1828
  throw new errors.ForbiddenError();
1612
1829
  }
@@ -1614,7 +1831,7 @@ const createDocument = async (ctx, opts) => {
1614
1831
  const setCreator = setCreatorFields({ user });
1615
1832
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1616
1833
  const sanitizedBody = await sanitizeFn(body);
1617
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(body);
1834
+ const { locale, status } = await getDocumentLocaleAndStatus(body, model);
1618
1835
  return documentManager2.create(model, {
1619
1836
  data: sanitizedBody,
1620
1837
  locale,
@@ -1626,14 +1843,14 @@ const updateDocument = async (ctx, opts) => {
1626
1843
  const { userAbility, user } = ctx.state;
1627
1844
  const { id, model } = ctx.params;
1628
1845
  const { body } = ctx.request;
1629
- const documentManager2 = getService$1("document-manager");
1630
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1846
+ const documentManager2 = getService$2("document-manager");
1847
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1631
1848
  if (permissionChecker2.cannot.update()) {
1632
1849
  throw new errors.ForbiddenError();
1633
1850
  }
1634
1851
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1635
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1636
- const { locale } = await getDocumentLocaleAndStatus(body);
1852
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1853
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1637
1854
  const [documentVersion, documentExists] = await Promise.all([
1638
1855
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
1639
1856
  documentManager2.exists(model, id)
@@ -1649,7 +1866,7 @@ const updateDocument = async (ctx, opts) => {
1649
1866
  throw new errors.ForbiddenError();
1650
1867
  }
1651
1868
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1652
- const setCreator = setCreatorFields({ user, isEdition: true });
1869
+ const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
1653
1870
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1654
1871
  const sanitizedBody = await sanitizeFn(body);
1655
1872
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1663,15 +1880,15 @@ const collectionTypes = {
1663
1880
  const { userAbility } = ctx.state;
1664
1881
  const { model } = ctx.params;
1665
1882
  const { query } = ctx.request;
1666
- const documentMetadata2 = getService$1("document-metadata");
1667
- const documentManager2 = getService$1("document-manager");
1668
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1883
+ const documentMetadata2 = getService$2("document-metadata");
1884
+ const documentManager2 = getService$2("document-manager");
1885
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1669
1886
  if (permissionChecker2.cannot.read()) {
1670
1887
  return ctx.forbidden();
1671
1888
  }
1672
1889
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1673
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1674
- const { locale, status } = await getDocumentLocaleAndStatus(query);
1890
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1891
+ const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1675
1892
  const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
1676
1893
  { ...permissionQuery, populate, locale, status },
1677
1894
  model
@@ -1699,14 +1916,14 @@ const collectionTypes = {
1699
1916
  async findOne(ctx) {
1700
1917
  const { userAbility } = ctx.state;
1701
1918
  const { model, id } = ctx.params;
1702
- const documentManager2 = getService$1("document-manager");
1703
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1919
+ const documentManager2 = getService$2("document-manager");
1920
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1704
1921
  if (permissionChecker2.cannot.read()) {
1705
1922
  return ctx.forbidden();
1706
1923
  }
1707
1924
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1708
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1709
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
1925
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1926
+ const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1710
1927
  const version = await documentManager2.findOne(id, model, {
1711
1928
  populate,
1712
1929
  locale,
@@ -1721,7 +1938,7 @@ const collectionTypes = {
1721
1938
  permissionChecker2,
1722
1939
  model,
1723
1940
  // @ts-expect-error TODO: fix
1724
- { id, locale, publishedAt: null },
1941
+ { documentId: id, locale, publishedAt: null },
1725
1942
  { availableLocales: true, availableStatus: false }
1726
1943
  );
1727
1944
  ctx.body = { data: {}, meta };
@@ -1736,7 +1953,7 @@ const collectionTypes = {
1736
1953
  async create(ctx) {
1737
1954
  const { userAbility } = ctx.state;
1738
1955
  const { model } = ctx.params;
1739
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1956
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1740
1957
  const [totalEntries, document] = await Promise.all([
1741
1958
  strapi.db.query(model).count(),
1742
1959
  createDocument(ctx)
@@ -1757,7 +1974,7 @@ const collectionTypes = {
1757
1974
  async update(ctx) {
1758
1975
  const { userAbility } = ctx.state;
1759
1976
  const { model } = ctx.params;
1760
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1977
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1761
1978
  const updatedVersion = await updateDocument(ctx);
1762
1979
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1763
1980
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1766,14 +1983,14 @@ const collectionTypes = {
1766
1983
  const { userAbility, user } = ctx.state;
1767
1984
  const { model, sourceId: id } = ctx.params;
1768
1985
  const { body } = ctx.request;
1769
- const documentManager2 = getService$1("document-manager");
1770
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1986
+ const documentManager2 = getService$2("document-manager");
1987
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1771
1988
  if (permissionChecker2.cannot.create()) {
1772
1989
  return ctx.forbidden();
1773
1990
  }
1774
1991
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1775
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1776
- const { locale } = await getDocumentLocaleAndStatus(body);
1992
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1993
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1777
1994
  const document = await documentManager2.findOne(id, model, {
1778
1995
  populate,
1779
1996
  locale,
@@ -1811,14 +2028,14 @@ const collectionTypes = {
1811
2028
  async delete(ctx) {
1812
2029
  const { userAbility } = ctx.state;
1813
2030
  const { id, model } = ctx.params;
1814
- const documentManager2 = getService$1("document-manager");
1815
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2031
+ const documentManager2 = getService$2("document-manager");
2032
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1816
2033
  if (permissionChecker2.cannot.delete()) {
1817
2034
  return ctx.forbidden();
1818
2035
  }
1819
2036
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1820
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1821
- const { locale } = await getDocumentLocaleAndStatus(ctx.query);
2037
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2038
+ const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1822
2039
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1823
2040
  if (documentLocales.length === 0) {
1824
2041
  return ctx.notFound();
@@ -1839,19 +2056,42 @@ const collectionTypes = {
1839
2056
  const { userAbility } = ctx.state;
1840
2057
  const { id, model } = ctx.params;
1841
2058
  const { body } = ctx.request;
1842
- const documentManager2 = getService$1("document-manager");
1843
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2059
+ const documentManager2 = getService$2("document-manager");
2060
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1844
2061
  if (permissionChecker2.cannot.publish()) {
1845
2062
  return ctx.forbidden();
1846
2063
  }
1847
2064
  const publishedDocument = await strapi.db.transaction(async () => {
1848
2065
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1849
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1850
- const document = id ? await updateDocument(ctx, { populate }) : await createDocument(ctx, { populate });
2066
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2067
+ let document;
2068
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2069
+ const isCreate = isNil$1(id);
2070
+ if (isCreate) {
2071
+ if (permissionChecker2.cannot.create()) {
2072
+ throw new errors.ForbiddenError();
2073
+ }
2074
+ document = await createDocument(ctx, { populate });
2075
+ }
2076
+ const isUpdate = !isCreate;
2077
+ if (isUpdate) {
2078
+ const documentExists = documentManager2.exists(model, id);
2079
+ if (!documentExists) {
2080
+ throw new errors.NotFoundError("Document not found");
2081
+ }
2082
+ document = await documentManager2.findOne(id, model, { populate, locale });
2083
+ if (!document) {
2084
+ if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
2085
+ throw new errors.ForbiddenError();
2086
+ }
2087
+ document = await updateDocument(ctx);
2088
+ } else if (permissionChecker2.can.update(document)) {
2089
+ await updateDocument(ctx);
2090
+ }
2091
+ }
1851
2092
  if (permissionChecker2.cannot.publish(document)) {
1852
2093
  throw new errors.ForbiddenError();
1853
2094
  }
1854
- const { locale } = await getDocumentLocaleAndStatus(body);
1855
2095
  const publishResult = await documentManager2.publish(document.documentId, model, {
1856
2096
  locale
1857
2097
  // TODO: Allow setting creator fields on publish
@@ -1871,14 +2111,16 @@ const collectionTypes = {
1871
2111
  const { body } = ctx.request;
1872
2112
  const { documentIds } = body;
1873
2113
  await validateBulkActionInput(body);
1874
- const documentManager2 = getService$1("document-manager");
1875
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2114
+ const documentManager2 = getService$2("document-manager");
2115
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1876
2116
  if (permissionChecker2.cannot.publish()) {
1877
2117
  return ctx.forbidden();
1878
2118
  }
1879
2119
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1880
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1881
- const { locale } = await getDocumentLocaleAndStatus(body, { allowMultipleLocales: true });
2120
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2121
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2122
+ allowMultipleLocales: true
2123
+ });
1882
2124
  const entityPromises = documentIds.map(
1883
2125
  (documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
1884
2126
  );
@@ -1900,12 +2142,14 @@ const collectionTypes = {
1900
2142
  const { body } = ctx.request;
1901
2143
  const { documentIds } = body;
1902
2144
  await validateBulkActionInput(body);
1903
- const documentManager2 = getService$1("document-manager");
1904
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2145
+ const documentManager2 = getService$2("document-manager");
2146
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1905
2147
  if (permissionChecker2.cannot.unpublish()) {
1906
2148
  return ctx.forbidden();
1907
2149
  }
1908
- const { locale } = await getDocumentLocaleAndStatus(body);
2150
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2151
+ allowMultipleLocales: true
2152
+ });
1909
2153
  const entityPromises = documentIds.map(
1910
2154
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1911
2155
  );
@@ -1928,8 +2172,8 @@ const collectionTypes = {
1928
2172
  const {
1929
2173
  body: { discardDraft, ...body }
1930
2174
  } = ctx.request;
1931
- const documentManager2 = getService$1("document-manager");
1932
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2175
+ const documentManager2 = getService$2("document-manager");
2176
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1933
2177
  if (permissionChecker2.cannot.unpublish()) {
1934
2178
  return ctx.forbidden();
1935
2179
  }
@@ -1937,8 +2181,8 @@ const collectionTypes = {
1937
2181
  return ctx.forbidden();
1938
2182
  }
1939
2183
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
1940
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1941
- const { locale } = await getDocumentLocaleAndStatus(body);
2184
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2185
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1942
2186
  const document = await documentManager2.findOne(id, model, {
1943
2187
  populate,
1944
2188
  locale,
@@ -1968,14 +2212,14 @@ const collectionTypes = {
1968
2212
  const { userAbility } = ctx.state;
1969
2213
  const { id, model } = ctx.params;
1970
2214
  const { body } = ctx.request;
1971
- const documentManager2 = getService$1("document-manager");
1972
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2215
+ const documentManager2 = getService$2("document-manager");
2216
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1973
2217
  if (permissionChecker2.cannot.discard()) {
1974
2218
  return ctx.forbidden();
1975
2219
  }
1976
2220
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
1977
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1978
- const { locale } = await getDocumentLocaleAndStatus(body);
2221
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2222
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1979
2223
  const document = await documentManager2.findOne(id, model, {
1980
2224
  populate,
1981
2225
  locale,
@@ -1999,14 +2243,14 @@ const collectionTypes = {
1999
2243
  const { query, body } = ctx.request;
2000
2244
  const { documentIds } = body;
2001
2245
  await validateBulkActionInput(body);
2002
- const documentManager2 = getService$1("document-manager");
2003
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2246
+ const documentManager2 = getService$2("document-manager");
2247
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2004
2248
  if (permissionChecker2.cannot.delete()) {
2005
2249
  return ctx.forbidden();
2006
2250
  }
2007
2251
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2008
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2009
- const { locale } = await getDocumentLocaleAndStatus(body);
2252
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2253
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2010
2254
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2011
2255
  populate,
2012
2256
  locale
@@ -2026,14 +2270,14 @@ const collectionTypes = {
2026
2270
  async countDraftRelations(ctx) {
2027
2271
  const { userAbility } = ctx.state;
2028
2272
  const { model, id } = ctx.params;
2029
- const documentManager2 = getService$1("document-manager");
2030
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2273
+ const documentManager2 = getService$2("document-manager");
2274
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2031
2275
  if (permissionChecker2.cannot.read()) {
2032
2276
  return ctx.forbidden();
2033
2277
  }
2034
2278
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2035
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2036
- const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
2279
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2280
+ const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2037
2281
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2038
2282
  if (!entity) {
2039
2283
  return ctx.notFound();
@@ -2051,12 +2295,12 @@ const collectionTypes = {
2051
2295
  const ids = ctx.request.query.documentIds;
2052
2296
  const locale = ctx.request.query.locale;
2053
2297
  const { model } = ctx.params;
2054
- const documentManager2 = getService$1("document-manager");
2055
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2298
+ const documentManager2 = getService$2("document-manager");
2299
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2056
2300
  if (permissionChecker2.cannot.read()) {
2057
2301
  return ctx.forbidden();
2058
2302
  }
2059
- const entities = await documentManager2.findMany(
2303
+ const documents = await documentManager2.findMany(
2060
2304
  {
2061
2305
  filters: {
2062
2306
  documentId: ids
@@ -2065,7 +2309,7 @@ const collectionTypes = {
2065
2309
  },
2066
2310
  model
2067
2311
  );
2068
- if (!entities) {
2312
+ if (!documents) {
2069
2313
  return ctx.notFound();
2070
2314
  }
2071
2315
  const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
@@ -2076,13 +2320,13 @@ const collectionTypes = {
2076
2320
  };
2077
2321
  const components$1 = {
2078
2322
  findComponents(ctx) {
2079
- const components2 = getService$1("components").findAllComponents();
2080
- const { toDto } = getService$1("data-mapper");
2323
+ const components2 = getService$2("components").findAllComponents();
2324
+ const { toDto } = getService$2("data-mapper");
2081
2325
  ctx.body = { data: components2.map(toDto) };
2082
2326
  },
2083
2327
  async findComponentConfiguration(ctx) {
2084
2328
  const { uid: uid2 } = ctx.params;
2085
- const componentService = getService$1("components");
2329
+ const componentService = getService$2("components");
2086
2330
  const component = componentService.findComponent(uid2);
2087
2331
  if (!component) {
2088
2332
  return ctx.notFound("component.notFound");
@@ -2099,7 +2343,7 @@ const components$1 = {
2099
2343
  async updateComponentConfiguration(ctx) {
2100
2344
  const { uid: uid2 } = ctx.params;
2101
2345
  const { body } = ctx.request;
2102
- const componentService = getService$1("components");
2346
+ const componentService = getService$2("components");
2103
2347
  const component = componentService.findComponent(uid2);
2104
2348
  if (!component) {
2105
2349
  return ctx.notFound("component.notFound");
@@ -2133,12 +2377,12 @@ const contentTypes = {
2133
2377
  } catch (error) {
2134
2378
  return ctx.send({ error }, 400);
2135
2379
  }
2136
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2137
- const { toDto } = getService$1("data-mapper");
2380
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2381
+ const { toDto } = getService$2("data-mapper");
2138
2382
  ctx.body = { data: contentTypes2.map(toDto) };
2139
2383
  },
2140
2384
  async findContentTypesSettings(ctx) {
2141
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2385
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2142
2386
  const contentTypes2 = await findAllContentTypes();
2143
2387
  const configurations = await Promise.all(
2144
2388
  contentTypes2.map(async (contentType) => {
@@ -2152,7 +2396,7 @@ const contentTypes = {
2152
2396
  },
2153
2397
  async findContentTypeConfiguration(ctx) {
2154
2398
  const { uid: uid2 } = ctx.params;
2155
- const contentTypeService = getService$1("content-types");
2399
+ const contentTypeService = getService$2("content-types");
2156
2400
  const contentType = await contentTypeService.findContentType(uid2);
2157
2401
  if (!contentType) {
2158
2402
  return ctx.notFound("contentType.notFound");
@@ -2174,13 +2418,13 @@ const contentTypes = {
2174
2418
  const { userAbility } = ctx.state;
2175
2419
  const { uid: uid2 } = ctx.params;
2176
2420
  const { body } = ctx.request;
2177
- const contentTypeService = getService$1("content-types");
2178
- const metricsService = getService$1("metrics");
2421
+ const contentTypeService = getService$2("content-types");
2422
+ const metricsService = getService$2("metrics");
2179
2423
  const contentType = await contentTypeService.findContentType(uid2);
2180
2424
  if (!contentType) {
2181
2425
  return ctx.notFound("contentType.notFound");
2182
2426
  }
2183
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2427
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2184
2428
  return ctx.forbidden();
2185
2429
  }
2186
2430
  let input;
@@ -2213,10 +2457,10 @@ const contentTypes = {
2213
2457
  };
2214
2458
  const init = {
2215
2459
  getInitData(ctx) {
2216
- const { toDto } = getService$1("data-mapper");
2217
- const { findAllComponents } = getService$1("components");
2218
- const { getAllFieldSizes } = getService$1("field-sizes");
2219
- const { findAllContentTypes } = getService$1("content-types");
2460
+ const { toDto } = getService$2("data-mapper");
2461
+ const { findAllComponents } = getService$2("components");
2462
+ const { getAllFieldSizes } = getService$2("field-sizes");
2463
+ const { findAllContentTypes } = getService$2("content-types");
2220
2464
  ctx.body = {
2221
2465
  data: {
2222
2466
  fieldSizes: getAllFieldSizes(),
@@ -2252,36 +2496,41 @@ const addFiltersClause = (params, filtersClause) => {
2252
2496
  params.filters.$and.push(filtersClause);
2253
2497
  };
2254
2498
  const sanitizeMainField = (model, mainField, userAbility) => {
2255
- const permissionChecker2 = getService$1("permission-checker").create({
2499
+ const permissionChecker2 = getService$2("permission-checker").create({
2256
2500
  userAbility,
2257
2501
  model: model.uid
2258
2502
  });
2259
- if (!isListable(model, mainField)) {
2503
+ const isMainFieldListable = isListable(model, mainField);
2504
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2505
+ if (!isMainFieldListable || !canReadMainField) {
2260
2506
  return "id";
2261
2507
  }
2262
- if (permissionChecker2.cannot.read(null, mainField)) {
2263
- if (model.uid === "plugin::users-permissions.role") {
2264
- const userPermissionChecker = getService$1("permission-checker").create({
2265
- userAbility,
2266
- model: "plugin::users-permissions.user"
2267
- });
2268
- if (userPermissionChecker.can.read()) {
2269
- return "name";
2270
- }
2271
- }
2272
- return "id";
2508
+ if (model.uid === "plugin::users-permissions.role") {
2509
+ return "name";
2273
2510
  }
2274
2511
  return mainField;
2275
2512
  };
2276
- const addStatusToRelations = async (uid2, relations2) => {
2277
- if (!contentTypes$1.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2513
+ const addStatusToRelations = async (targetUid, relations2) => {
2514
+ if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
2278
2515
  return relations2;
2279
2516
  }
2280
- const documentMetadata2 = getService$1("document-metadata");
2281
- const documentsAvailableStatus = await documentMetadata2.getManyAvailableStatus(uid2, relations2);
2517
+ const documentMetadata2 = getService$2("document-metadata");
2518
+ if (!relations2.length) {
2519
+ return relations2;
2520
+ }
2521
+ const firstRelation = relations2[0];
2522
+ const filters = {
2523
+ documentId: { $in: relations2.map((r) => r.documentId) },
2524
+ // NOTE: find the "opposite" status
2525
+ publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
2526
+ };
2527
+ const availableStatus = await strapi.query(targetUid).findMany({
2528
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
2529
+ filters
2530
+ });
2282
2531
  return relations2.map((relation) => {
2283
- const availableStatuses = documentsAvailableStatus.filter(
2284
- (availableDocument) => availableDocument.documentId === relation.documentId
2532
+ const availableStatuses = availableStatus.filter(
2533
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2285
2534
  );
2286
2535
  return {
2287
2536
  ...relation,
@@ -2302,11 +2551,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2302
2551
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2303
2552
  const isSourceLocalized = isLocalized(sourceModel);
2304
2553
  const isTargetLocalized = isLocalized(targetModel);
2305
- let validatedLocale = locale;
2306
- if (!targetModel || !isTargetLocalized)
2307
- validatedLocale = void 0;
2308
2554
  return {
2309
- locale: validatedLocale,
2555
+ locale,
2310
2556
  isSourceLocalized,
2311
2557
  isTargetLocalized
2312
2558
  };
@@ -2346,7 +2592,7 @@ const relations = {
2346
2592
  ctx.request?.query?.locale
2347
2593
  );
2348
2594
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2349
- const permissionChecker2 = getService$1("permission-checker").create({
2595
+ const permissionChecker2 = getService$2("permission-checker").create({
2350
2596
  userAbility,
2351
2597
  model
2352
2598
  });
@@ -2371,7 +2617,7 @@ const relations = {
2371
2617
  where.id = id;
2372
2618
  }
2373
2619
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2374
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2620
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2375
2621
  const currentEntity = await strapi.db.query(model).findOne({
2376
2622
  where,
2377
2623
  populate
@@ -2386,7 +2632,7 @@ const relations = {
2386
2632
  }
2387
2633
  entryId = currentEntity.id;
2388
2634
  }
2389
- const modelConfig = isComponent2 ? await getService$1("components").findConfiguration(sourceSchema) : await getService$1("content-types").findConfiguration(sourceSchema);
2635
+ const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
2390
2636
  const targetSchema = strapi.getModel(targetUid);
2391
2637
  const mainField = flow(
2392
2638
  prop(`metadatas.${targetField}.edit.mainField`),
@@ -2409,7 +2655,7 @@ const relations = {
2409
2655
  attribute,
2410
2656
  fieldsToSelect,
2411
2657
  mainField,
2412
- source: { schema: sourceSchema },
2658
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2413
2659
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2414
2660
  sourceSchema,
2415
2661
  targetSchema,
@@ -2431,7 +2677,8 @@ const relations = {
2431
2677
  fieldsToSelect,
2432
2678
  mainField,
2433
2679
  source: {
2434
- schema: { uid: sourceUid, modelType: sourceModelType }
2680
+ schema: { uid: sourceUid, modelType: sourceModelType },
2681
+ isLocalized: isSourceLocalized
2435
2682
  },
2436
2683
  target: {
2437
2684
  schema: { uid: targetUid },
@@ -2439,7 +2686,7 @@ const relations = {
2439
2686
  }
2440
2687
  } = await this.extractAndValidateRequestInfo(ctx, id);
2441
2688
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2442
- const permissionChecker2 = getService$1("permission-checker").create({
2689
+ const permissionChecker2 = getService$2("permission-checker").create({
2443
2690
  userAbility: ctx.state.userAbility,
2444
2691
  model: targetUid
2445
2692
  });
@@ -2469,12 +2716,16 @@ const relations = {
2469
2716
  } else {
2470
2717
  where.id = id;
2471
2718
  }
2472
- if (status) {
2473
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2719
+ const publishedAt = getPublishedAtClause(status, targetUid);
2720
+ if (!isEmpty(publishedAt)) {
2721
+ where[`${alias}.published_at`] = publishedAt;
2474
2722
  }
2475
- if (filterByLocale) {
2723
+ if (isTargetLocalized && locale) {
2476
2724
  where[`${alias}.locale`] = locale;
2477
2725
  }
2726
+ if (isSourceLocalized && locale) {
2727
+ where.locale = locale;
2728
+ }
2478
2729
  if ((idsToInclude?.length ?? 0) !== 0) {
2479
2730
  where[`${alias}.id`].$notIn = idsToInclude;
2480
2731
  }
@@ -2492,7 +2743,8 @@ const relations = {
2492
2743
  id: { $notIn: uniq(idsToOmit) }
2493
2744
  });
2494
2745
  }
2495
- const res = await strapi.db.query(targetUid).findPage(strapi.get("query-params").transform(targetUid, queryParams));
2746
+ const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
2747
+ const res = await strapi.db.query(targetUid).findPage(dbQuery);
2496
2748
  ctx.body = {
2497
2749
  ...res,
2498
2750
  results: await addStatusToRelations(targetUid, res.results)
@@ -2507,29 +2759,39 @@ const relations = {
2507
2759
  attribute,
2508
2760
  targetField,
2509
2761
  fieldsToSelect,
2510
- source: {
2511
- schema: { uid: sourceUid }
2512
- },
2513
- target: {
2514
- schema: { uid: targetUid }
2515
- }
2762
+ status,
2763
+ source: { schema: sourceSchema },
2764
+ target: { schema: targetSchema }
2516
2765
  } = await this.extractAndValidateRequestInfo(ctx, id);
2517
- const permissionQuery = await getService$1("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2766
+ const { uid: sourceUid } = sourceSchema;
2767
+ const { uid: targetUid } = targetSchema;
2768
+ const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2518
2769
  const dbQuery = strapi.db.query(sourceUid);
2519
2770
  const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
2771
+ const filters = {};
2772
+ if (sourceSchema?.options?.draftAndPublish) {
2773
+ if (targetSchema?.options?.draftAndPublish) {
2774
+ if (status === "published") {
2775
+ filters.publishedAt = { $notNull: true };
2776
+ } else {
2777
+ filters.publishedAt = { $null: true };
2778
+ }
2779
+ }
2780
+ } else if (targetSchema?.options?.draftAndPublish) {
2781
+ filters.publishedAt = { $null: true };
2782
+ }
2520
2783
  const res = await loadRelations({ id: entryId }, targetField, {
2521
- select: ["id", "documentId", "locale", "publishedAt"],
2784
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2522
2785
  ordering: "desc",
2523
2786
  page: ctx.request.query.page,
2524
- pageSize: ctx.request.query.pageSize
2787
+ pageSize: ctx.request.query.pageSize,
2788
+ filters
2525
2789
  });
2526
2790
  const loadedIds = res.results.map((item) => item.id);
2527
2791
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2528
2792
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2529
2793
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2530
- ordering: "desc",
2531
- page: ctx.request.query.page,
2532
- pageSize: ctx.request.query.pageSize
2794
+ ordering: "desc"
2533
2795
  });
2534
2796
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2535
2797
  ctx.body = {
@@ -2544,10 +2806,10 @@ const relations = {
2544
2806
  }
2545
2807
  };
2546
2808
  const buildPopulateFromQuery = async (query, model) => {
2547
- return getService$1("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2809
+ return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2548
2810
  };
2549
2811
  const findDocument = async (query, uid2, opts = {}) => {
2550
- const documentManager2 = getService$1("document-manager");
2812
+ const documentManager2 = getService$2("document-manager");
2551
2813
  const populate = await buildPopulateFromQuery(query, uid2);
2552
2814
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2553
2815
  };
@@ -2555,13 +2817,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
2555
2817
  const { user, userAbility } = ctx.state;
2556
2818
  const { model } = ctx.params;
2557
2819
  const { body, query } = ctx.request;
2558
- const documentManager2 = getService$1("document-manager");
2559
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2820
+ const documentManager2 = getService$2("document-manager");
2821
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2560
2822
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2561
2823
  throw new errors.ForbiddenError();
2562
2824
  }
2563
2825
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
2564
- const { locale } = await getDocumentLocaleAndStatus(body);
2826
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2565
2827
  const [documentVersion, otherDocumentVersion] = await Promise.all([
2566
2828
  findDocument(sanitizedQuery, model, { locale, status: "draft" }),
2567
2829
  // Find the first document to check if it exists
@@ -2597,12 +2859,12 @@ const singleTypes = {
2597
2859
  const { userAbility } = ctx.state;
2598
2860
  const { model } = ctx.params;
2599
2861
  const { query = {} } = ctx.request;
2600
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2862
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2601
2863
  if (permissionChecker2.cannot.read()) {
2602
2864
  return ctx.forbidden();
2603
2865
  }
2604
2866
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
2605
- const { locale, status } = await getDocumentLocaleAndStatus(query);
2867
+ const { locale, status } = await getDocumentLocaleAndStatus(query, model);
2606
2868
  const version = await findDocument(permissionQuery, model, { locale, status });
2607
2869
  if (!version) {
2608
2870
  if (permissionChecker2.cannot.create()) {
@@ -2616,7 +2878,7 @@ const singleTypes = {
2616
2878
  permissionChecker2,
2617
2879
  model,
2618
2880
  // @ts-expect-error - fix types
2619
- { id: document.documentId, locale, publishedAt: null },
2881
+ { documentId: document.documentId, locale, publishedAt: null },
2620
2882
  { availableLocales: true, availableStatus: false }
2621
2883
  );
2622
2884
  ctx.body = { data: {}, meta };
@@ -2631,7 +2893,7 @@ const singleTypes = {
2631
2893
  async createOrUpdate(ctx) {
2632
2894
  const { userAbility } = ctx.state;
2633
2895
  const { model } = ctx.params;
2634
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2896
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2635
2897
  const document = await createOrUpdateDocument(ctx);
2636
2898
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2637
2899
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2640,14 +2902,14 @@ const singleTypes = {
2640
2902
  const { userAbility } = ctx.state;
2641
2903
  const { model } = ctx.params;
2642
2904
  const { query = {} } = ctx.request;
2643
- const documentManager2 = getService$1("document-manager");
2644
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2905
+ const documentManager2 = getService$2("document-manager");
2906
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2645
2907
  if (permissionChecker2.cannot.delete()) {
2646
2908
  return ctx.forbidden();
2647
2909
  }
2648
2910
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
2649
2911
  const populate = await buildPopulateFromQuery(sanitizedQuery, model);
2650
- const { locale } = await getDocumentLocaleAndStatus(query);
2912
+ const { locale } = await getDocumentLocaleAndStatus(query, model);
2651
2913
  const documentLocales = await documentManager2.findLocales(void 0, model, {
2652
2914
  populate,
2653
2915
  locale
@@ -2669,8 +2931,8 @@ const singleTypes = {
2669
2931
  const { userAbility } = ctx.state;
2670
2932
  const { model } = ctx.params;
2671
2933
  const { query = {} } = ctx.request;
2672
- const documentManager2 = getService$1("document-manager");
2673
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2934
+ const documentManager2 = getService$2("document-manager");
2935
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2674
2936
  if (permissionChecker2.cannot.publish()) {
2675
2937
  return ctx.forbidden();
2676
2938
  }
@@ -2684,7 +2946,7 @@ const singleTypes = {
2684
2946
  if (permissionChecker2.cannot.publish(document)) {
2685
2947
  throw new errors.ForbiddenError();
2686
2948
  }
2687
- const { locale } = await getDocumentLocaleAndStatus(document);
2949
+ const { locale } = await getDocumentLocaleAndStatus(document, model);
2688
2950
  const publishResult = await documentManager2.publish(document.documentId, model, { locale });
2689
2951
  return publishResult.at(0);
2690
2952
  });
@@ -2698,8 +2960,8 @@ const singleTypes = {
2698
2960
  body: { discardDraft, ...body },
2699
2961
  query = {}
2700
2962
  } = ctx.request;
2701
- const documentManager2 = getService$1("document-manager");
2702
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2963
+ const documentManager2 = getService$2("document-manager");
2964
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2703
2965
  if (permissionChecker2.cannot.unpublish()) {
2704
2966
  return ctx.forbidden();
2705
2967
  }
@@ -2707,7 +2969,7 @@ const singleTypes = {
2707
2969
  return ctx.forbidden();
2708
2970
  }
2709
2971
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
2710
- const { locale } = await getDocumentLocaleAndStatus(body);
2972
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2711
2973
  const document = await findDocument(sanitizedQuery, model, { locale });
2712
2974
  if (!document) {
2713
2975
  return ctx.notFound();
@@ -2733,13 +2995,13 @@ const singleTypes = {
2733
2995
  const { userAbility } = ctx.state;
2734
2996
  const { model } = ctx.params;
2735
2997
  const { body, query = {} } = ctx.request;
2736
- const documentManager2 = getService$1("document-manager");
2737
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2998
+ const documentManager2 = getService$2("document-manager");
2999
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2738
3000
  if (permissionChecker2.cannot.discard()) {
2739
3001
  return ctx.forbidden();
2740
3002
  }
2741
3003
  const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
2742
- const { locale } = await getDocumentLocaleAndStatus(body);
3004
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
2743
3005
  const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
2744
3006
  if (!document) {
2745
3007
  return ctx.notFound();
@@ -2757,9 +3019,9 @@ const singleTypes = {
2757
3019
  const { userAbility } = ctx.state;
2758
3020
  const { model } = ctx.params;
2759
3021
  const { query } = ctx.request;
2760
- const documentManager2 = getService$1("document-manager");
2761
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2762
- const { locale } = await getDocumentLocaleAndStatus(query);
3022
+ const documentManager2 = getService$2("document-manager");
3023
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
3024
+ const { locale } = await getDocumentLocaleAndStatus(query, model);
2763
3025
  if (permissionChecker2.cannot.read()) {
2764
3026
  return ctx.forbidden();
2765
3027
  }
@@ -2780,9 +3042,9 @@ const uid$1 = {
2780
3042
  async generateUID(ctx) {
2781
3043
  const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
2782
3044
  const { query = {} } = ctx.request;
2783
- const { locale } = await getDocumentLocaleAndStatus(query);
3045
+ const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2784
3046
  await validateUIDField(contentTypeUID, field);
2785
- const uidService = getService$1("uid");
3047
+ const uidService = getService$2("uid");
2786
3048
  ctx.body = {
2787
3049
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2788
3050
  };
@@ -2792,9 +3054,9 @@ const uid$1 = {
2792
3054
  ctx.request.body
2793
3055
  );
2794
3056
  const { query = {} } = ctx.request;
2795
- const { locale } = await getDocumentLocaleAndStatus(query);
3057
+ const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2796
3058
  await validateUIDField(contentTypeUID, field);
2797
- const uidService = getService$1("uid");
3059
+ const uidService = getService$2("uid");
2798
3060
  const isAvailable = await uidService.checkUIDAvailability({
2799
3061
  contentTypeUID,
2800
3062
  field,
@@ -2815,7 +3077,8 @@ const controllers = {
2815
3077
  relations,
2816
3078
  "single-types": singleTypes,
2817
3079
  uid: uid$1,
2818
- ...history.controllers ? history.controllers : {}
3080
+ ...history.controllers ? history.controllers : {},
3081
+ ...preview.controllers ? preview.controllers : {}
2819
3082
  };
2820
3083
  const keys = {
2821
3084
  CONFIGURATION: "configuration"
@@ -2966,12 +3229,12 @@ async function syncMetadatas(configuration, schema) {
2966
3229
  return _.assign(metasWithDefaults, updatedMetas);
2967
3230
  }
2968
3231
  const getTargetSchema = (targetModel) => {
2969
- return getService$1("content-types").findContentType(targetModel);
3232
+ return getService$2("content-types").findContentType(targetModel);
2970
3233
  };
2971
3234
  const DEFAULT_LIST_LENGTH = 4;
2972
3235
  const MAX_ROW_SIZE = 12;
2973
3236
  const isAllowedFieldSize = (type, size) => {
2974
- const { getFieldSize } = getService$1("field-sizes");
3237
+ const { getFieldSize } = getService$2("field-sizes");
2975
3238
  const fieldSize = getFieldSize(type);
2976
3239
  if (!fieldSize.isResizable && size !== fieldSize.default) {
2977
3240
  return false;
@@ -2979,7 +3242,7 @@ const isAllowedFieldSize = (type, size) => {
2979
3242
  return size <= MAX_ROW_SIZE;
2980
3243
  };
2981
3244
  const getDefaultFieldSize = (attribute) => {
2982
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3245
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
2983
3246
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
2984
3247
  };
2985
3248
  async function createDefaultLayouts(schema) {
@@ -3014,7 +3277,7 @@ function syncLayouts(configuration, schema) {
3014
3277
  for (const el of row) {
3015
3278
  if (!hasEditableAttribute(schema, el.name))
3016
3279
  continue;
3017
- const { hasFieldSize } = getService$1("field-sizes");
3280
+ const { hasFieldSize } = getService$2("field-sizes");
3018
3281
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3019
3282
  if (!isAllowedFieldSize(fieldType, el.size)) {
3020
3283
  elementsToReAppend.push(el.name);
@@ -3154,17 +3417,17 @@ const configurationService$1 = createConfigurationService({
3154
3417
  isComponent: true,
3155
3418
  prefix: STORE_KEY_PREFIX,
3156
3419
  getModels() {
3157
- const { toContentManagerModel } = getService$1("data-mapper");
3420
+ const { toContentManagerModel } = getService$2("data-mapper");
3158
3421
  return mapValues(toContentManagerModel, strapi.components);
3159
3422
  }
3160
3423
  });
3161
3424
  const components = ({ strapi: strapi2 }) => ({
3162
3425
  findAllComponents() {
3163
- const { toContentManagerModel } = getService$1("data-mapper");
3426
+ const { toContentManagerModel } = getService$2("data-mapper");
3164
3427
  return Object.values(strapi2.components).map(toContentManagerModel);
3165
3428
  },
3166
3429
  findComponent(uid2) {
3167
- const { toContentManagerModel } = getService$1("data-mapper");
3430
+ const { toContentManagerModel } = getService$2("data-mapper");
3168
3431
  const component = strapi2.components[uid2];
3169
3432
  return isNil$1(component) ? component : toContentManagerModel(component);
3170
3433
  },
@@ -3215,17 +3478,17 @@ const configurationService = createConfigurationService({
3215
3478
  storeUtils,
3216
3479
  prefix: "content_types",
3217
3480
  getModels() {
3218
- const { toContentManagerModel } = getService$1("data-mapper");
3481
+ const { toContentManagerModel } = getService$2("data-mapper");
3219
3482
  return mapValues(toContentManagerModel, strapi.contentTypes);
3220
3483
  }
3221
3484
  });
3222
3485
  const service = ({ strapi: strapi2 }) => ({
3223
3486
  findAllContentTypes() {
3224
- const { toContentManagerModel } = getService$1("data-mapper");
3487
+ const { toContentManagerModel } = getService$2("data-mapper");
3225
3488
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3226
3489
  },
3227
3490
  findContentType(uid2) {
3228
- const { toContentManagerModel } = getService$1("data-mapper");
3491
+ const { toContentManagerModel } = getService$2("data-mapper");
3229
3492
  const contentType = strapi2.contentTypes[uid2];
3230
3493
  return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
3231
3494
  },
@@ -3254,7 +3517,7 @@ const service = ({ strapi: strapi2 }) => ({
3254
3517
  return this.findConfiguration(contentType);
3255
3518
  },
3256
3519
  findComponentsConfigurations(contentType) {
3257
- return getService$1("components").findComponentsConfigurations(contentType);
3520
+ return getService$2("components").findComponentsConfigurations(contentType);
3258
3521
  },
3259
3522
  syncConfigurations() {
3260
3523
  return configurationService.syncConfigurations();
@@ -3435,12 +3698,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3435
3698
  ability: userAbility,
3436
3699
  model
3437
3700
  });
3438
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3701
+ const { actionProvider } = strapi2.service("admin::permission");
3702
+ const toSubject = (entity) => {
3703
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3704
+ };
3439
3705
  const can = (action, entity, field) => {
3440
- return userAbility.can(action, toSubject(entity), field);
3706
+ const subject = toSubject(entity);
3707
+ const aliases = actionProvider.unstable_aliases(action, model);
3708
+ return (
3709
+ // Test the original action to see if it passes
3710
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3711
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3712
+ );
3441
3713
  };
3442
3714
  const cannot = (action, entity, field) => {
3443
- return userAbility.cannot(action, toSubject(entity), field);
3715
+ const subject = toSubject(entity);
3716
+ const aliases = actionProvider.unstable_aliases(action, model);
3717
+ return (
3718
+ // Test both the original action
3719
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3720
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3721
+ );
3444
3722
  };
3445
3723
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3446
3724
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3511,7 +3789,7 @@ const permission = ({ strapi: strapi2 }) => ({
3511
3789
  return userAbility.can(action);
3512
3790
  },
3513
3791
  async registerPermissions() {
3514
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3792
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3515
3793
  const contentTypesUids = displayedContentTypes.map(prop("uid"));
3516
3794
  const actions = [
3517
3795
  {
@@ -3717,6 +3995,10 @@ const getDeepPopulateDraftCount = (uid2) => {
3717
3995
  const attribute = model.attributes[attributeName];
3718
3996
  switch (attribute.type) {
3719
3997
  case "relation": {
3998
+ const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
3999
+ if (isMorphRelation) {
4000
+ break;
4001
+ }
3720
4002
  if (isVisibleAttribute$1(model, attributeName)) {
3721
4003
  populateAcc[attributeName] = {
3722
4004
  count: true,
@@ -3783,7 +4065,7 @@ const getQueryPopulate = async (uid2, query) => {
3783
4065
  return populateQuery;
3784
4066
  };
3785
4067
  const buildDeepPopulate = (uid2) => {
3786
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4068
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3787
4069
  };
3788
4070
  const populateBuilder = (uid2) => {
3789
4071
  let getInitialPopulate = async () => {
@@ -3968,7 +4250,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
3968
4250
  */
3969
4251
  async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
3970
4252
  const versionsByLocale = groupBy("locale", allVersions);
3971
- delete versionsByLocale[version.locale];
4253
+ if (version.locale) {
4254
+ delete versionsByLocale[version.locale];
4255
+ }
3972
4256
  const model = strapi2.getModel(uid2);
3973
4257
  const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
3974
4258
  const traversalFunction = async (localeVersion) => traverseEntity(
@@ -4094,7 +4378,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4094
4378
  */
4095
4379
  async formatDocumentWithMetadata(uid2, document, opts = {}) {
4096
4380
  if (!document) {
4097
- return document;
4381
+ return {
4382
+ data: document,
4383
+ meta: {
4384
+ availableLocales: [],
4385
+ availableStatus: []
4386
+ }
4387
+ };
4098
4388
  }
4099
4389
  const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
4100
4390
  if (!hasDraftAndPublish) {
@@ -4202,10 +4492,7 @@ const documentManager = ({ strapi: strapi2 }) => {
4202
4492
  async clone(id, body, uid2) {
4203
4493
  const populate = await buildDeepPopulate(uid2);
4204
4494
  const params = {
4205
- data: {
4206
- ...omitIdField(body),
4207
- [PUBLISHED_AT_ATTRIBUTE]: null
4208
- },
4495
+ data: omitIdField(body),
4209
4496
  populate
4210
4497
  };
4211
4498
  return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
@@ -4321,7 +4608,8 @@ const services = {
4321
4608
  permission,
4322
4609
  "populate-builder": populateBuilder$1,
4323
4610
  uid,
4324
- ...history.services ? history.services : {}
4611
+ ...history.services ? history.services : {},
4612
+ ...preview.services ? preview.services : {}
4325
4613
  };
4326
4614
  const index = () => {
4327
4615
  return {