@strapi/content-manager 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6 → 0.0.0-experimental.f49f46a1c17445a39e8af3f63124bcccf73842e6

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 (197) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-BNxtMIfV.js → ComponentConfigurationPage-ClKl_TA2.js} +4 -4
  2. package/dist/_chunks/{ComponentConfigurationPage-BNxtMIfV.js.map → ComponentConfigurationPage-ClKl_TA2.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BWOQWCv2.mjs → ComponentConfigurationPage-D3ZWDAHG.mjs} +4 -4
  4. package/dist/_chunks/{ComponentConfigurationPage-BWOQWCv2.mjs.map → ComponentConfigurationPage-D3ZWDAHG.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-GTp-Ucnw.mjs → EditConfigurationPage-BYCBSJxP.mjs} +4 -4
  6. package/dist/_chunks/{EditConfigurationPage-GTp-Ucnw.mjs.map → EditConfigurationPage-BYCBSJxP.mjs.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-D340bYlT.js → EditConfigurationPage-OWez0Kxp.js} +4 -4
  8. package/dist/_chunks/{EditConfigurationPage-D340bYlT.js.map → EditConfigurationPage-OWez0Kxp.js.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-BVMS5hT-.mjs → EditViewPage-5pdbvsO_.mjs} +63 -12
  10. package/dist/_chunks/EditViewPage-5pdbvsO_.mjs.map +1 -0
  11. package/dist/_chunks/{EditViewPage-CXkmnAvI.js → EditViewPage-BEs5iGDi.js} +62 -11
  12. package/dist/_chunks/EditViewPage-BEs5iGDi.js.map +1 -0
  13. package/dist/_chunks/{Field-Ibi32diw.js → Field-DNHm4wHx.js} +210 -119
  14. package/dist/_chunks/Field-DNHm4wHx.js.map +1 -0
  15. package/dist/_chunks/{Field-nNgv5bpd.mjs → Field-DcKuFHYK.mjs} +208 -117
  16. package/dist/_chunks/Field-DcKuFHYK.mjs.map +1 -0
  17. package/dist/_chunks/{Form-DodJsI2A.mjs → Form-CGwM_-5c.mjs} +36 -17
  18. package/dist/_chunks/Form-CGwM_-5c.mjs.map +1 -0
  19. package/dist/_chunks/{Form-Dhnh34ym.js → Form-CoRxWJOz.js} +36 -17
  20. package/dist/_chunks/Form-CoRxWJOz.js.map +1 -0
  21. package/dist/_chunks/{History-C9auUkDi.js → History-BcUTQrfG.js} +40 -97
  22. package/dist/_chunks/History-BcUTQrfG.js.map +1 -0
  23. package/dist/_chunks/{History-CKCSQXz_.mjs → History-DEvr3Q_V.mjs} +42 -99
  24. package/dist/_chunks/History-DEvr3Q_V.mjs.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-Bg4rWUjX.js → ListConfigurationPage-BE_Ho7tV.js} +17 -6
  26. package/dist/_chunks/ListConfigurationPage-BE_Ho7tV.js.map +1 -0
  27. package/dist/_chunks/{ListConfigurationPage-CKEC4ttG.mjs → ListConfigurationPage-BM4zZZcM.mjs} +18 -7
  28. package/dist/_chunks/ListConfigurationPage-BM4zZZcM.mjs.map +1 -0
  29. package/dist/_chunks/{ListViewPage-B7_WJUjG.mjs → ListViewPage-BK2mkrql.mjs} +65 -39
  30. package/dist/_chunks/ListViewPage-BK2mkrql.mjs.map +1 -0
  31. package/dist/_chunks/{ListViewPage-C2gIeYHG.js → ListViewPage-BkT8Eao0.js} +68 -42
  32. package/dist/_chunks/ListViewPage-BkT8Eao0.js.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-Ckem6Ll6.mjs → NoContentTypePage-BvcAutu9.mjs} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-Ckem6Ll6.mjs.map → NoContentTypePage-BvcAutu9.mjs.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-DqgdUfyn.js → NoContentTypePage-C8mtyc4H.js} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-DqgdUfyn.js.map → NoContentTypePage-C8mtyc4H.js.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-CF29Q-sW.js → NoPermissionsPage-B5Y9Y78B.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-CF29Q-sW.js.map → NoPermissionsPage-B5Y9Y78B.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-BO-GEjA4.mjs → NoPermissionsPage-BmbRz7PR.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-BO-GEjA4.mjs.map → NoPermissionsPage-BmbRz7PR.mjs.map} +1 -1
  41. package/dist/_chunks/Preview-BF8ZDYqS.js +286 -0
  42. package/dist/_chunks/Preview-BF8ZDYqS.js.map +1 -0
  43. package/dist/_chunks/Preview-DcexhKJE.mjs +267 -0
  44. package/dist/_chunks/Preview-DcexhKJE.mjs.map +1 -0
  45. package/dist/_chunks/{Relations-C0uC9J4f.js → Relations-BKnoK1R0.js} +72 -36
  46. package/dist/_chunks/Relations-BKnoK1R0.js.map +1 -0
  47. package/dist/_chunks/{Relations-DItV5eow.mjs → Relations-BjIzc4EK.mjs} +73 -37
  48. package/dist/_chunks/Relations-BjIzc4EK.mjs.map +1 -0
  49. package/dist/_chunks/{en-BrCTWlZv.mjs → en-CfIXaZf9.mjs} +26 -14
  50. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-CfIXaZf9.mjs.map} +1 -1
  51. package/dist/_chunks/{en-uOUIxfcQ.js → en-DTWPCdTS.js} +26 -14
  52. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-DTWPCdTS.js.map} +1 -1
  53. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  54. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  55. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  56. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  57. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
  58. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
  59. package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
  60. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
  61. package/dist/_chunks/{index-DrNe6ctw.mjs → index-BW-rXkjn.mjs} +1027 -761
  62. package/dist/_chunks/index-BW-rXkjn.mjs.map +1 -0
  63. package/dist/_chunks/{index-Dd0nXyJF.js → index-DOzAG2cq.js} +1008 -741
  64. package/dist/_chunks/index-DOzAG2cq.js.map +1 -0
  65. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  66. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  67. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  68. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  69. package/dist/_chunks/{layout-B3ez7kvr.mjs → layout-DFVbgjp2.mjs} +8 -7
  70. package/dist/_chunks/layout-DFVbgjp2.mjs.map +1 -0
  71. package/dist/_chunks/{layout-CLLtt_5O.js → layout-RC3W2obV.js} +8 -7
  72. package/dist/_chunks/layout-RC3W2obV.js.map +1 -0
  73. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  74. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  75. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  76. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  77. package/dist/_chunks/{relations-B0hlsUU_.mjs → relations-Dogh8HWI.mjs} +6 -7
  78. package/dist/_chunks/relations-Dogh8HWI.mjs.map +1 -0
  79. package/dist/_chunks/{relations-bRxcNv1q.js → relations-zam7-5H7.js} +6 -7
  80. package/dist/_chunks/relations-zam7-5H7.js.map +1 -0
  81. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  82. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  83. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  84. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  85. package/dist/admin/index.js +2 -1
  86. package/dist/admin/index.js.map +1 -1
  87. package/dist/admin/index.mjs +5 -4
  88. package/dist/admin/src/exports.d.ts +1 -1
  89. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  90. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  91. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  92. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
  93. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  94. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  95. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  96. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  97. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  98. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  99. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  100. package/dist/admin/src/preview/constants.d.ts +1 -0
  101. package/dist/admin/src/preview/index.d.ts +4 -0
  102. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  103. package/dist/admin/src/preview/routes.d.ts +3 -0
  104. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  105. package/dist/admin/src/router.d.ts +1 -1
  106. package/dist/admin/src/services/api.d.ts +1 -1
  107. package/dist/admin/src/services/components.d.ts +2 -2
  108. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  109. package/dist/admin/src/services/documents.d.ts +19 -17
  110. package/dist/admin/src/services/init.d.ts +1 -1
  111. package/dist/admin/src/services/relations.d.ts +2 -2
  112. package/dist/admin/src/services/uid.d.ts +3 -3
  113. package/dist/admin/src/utils/validation.d.ts +4 -1
  114. package/dist/server/index.js +421 -183
  115. package/dist/server/index.js.map +1 -1
  116. package/dist/server/index.mjs +421 -183
  117. package/dist/server/index.mjs.map +1 -1
  118. package/dist/server/src/bootstrap.d.ts.map +1 -1
  119. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  120. package/dist/server/src/controllers/index.d.ts.map +1 -1
  121. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  122. package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
  123. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  124. package/dist/server/src/history/services/history.d.ts.map +1 -1
  125. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  126. package/dist/server/src/history/services/utils.d.ts +3 -3
  127. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  128. package/dist/server/src/index.d.ts +4 -4
  129. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  130. package/dist/server/src/preview/constants.d.ts +2 -0
  131. package/dist/server/src/preview/constants.d.ts.map +1 -0
  132. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  133. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  134. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  135. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  136. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  137. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  138. package/dist/server/src/preview/index.d.ts +4 -0
  139. package/dist/server/src/preview/index.d.ts.map +1 -0
  140. package/dist/server/src/preview/routes/index.d.ts +8 -0
  141. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  142. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  143. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  144. package/dist/server/src/preview/services/index.d.ts +15 -0
  145. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  146. package/dist/server/src/preview/services/preview-config.d.ts +30 -0
  147. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  148. package/dist/server/src/preview/services/preview.d.ts +12 -0
  149. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  150. package/dist/server/src/preview/utils.d.ts +18 -0
  151. package/dist/server/src/preview/utils.d.ts.map +1 -0
  152. package/dist/server/src/routes/index.d.ts.map +1 -1
  153. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  154. package/dist/server/src/services/document-metadata.d.ts +8 -8
  155. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  156. package/dist/server/src/services/index.d.ts +4 -4
  157. package/dist/server/src/services/index.d.ts.map +1 -1
  158. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  159. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  160. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  161. package/dist/server/src/utils/index.d.ts +2 -0
  162. package/dist/server/src/utils/index.d.ts.map +1 -1
  163. package/dist/shared/contracts/collection-types.d.ts +3 -1
  164. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  165. package/dist/shared/contracts/index.d.ts +1 -0
  166. package/dist/shared/contracts/index.d.ts.map +1 -1
  167. package/dist/shared/contracts/preview.d.ts +27 -0
  168. package/dist/shared/contracts/preview.d.ts.map +1 -0
  169. package/dist/shared/index.js +4 -0
  170. package/dist/shared/index.js.map +1 -1
  171. package/dist/shared/index.mjs +4 -0
  172. package/dist/shared/index.mjs.map +1 -1
  173. package/package.json +14 -14
  174. package/dist/_chunks/EditViewPage-BVMS5hT-.mjs.map +0 -1
  175. package/dist/_chunks/EditViewPage-CXkmnAvI.js.map +0 -1
  176. package/dist/_chunks/Field-Ibi32diw.js.map +0 -1
  177. package/dist/_chunks/Field-nNgv5bpd.mjs.map +0 -1
  178. package/dist/_chunks/Form-Dhnh34ym.js.map +0 -1
  179. package/dist/_chunks/Form-DodJsI2A.mjs.map +0 -1
  180. package/dist/_chunks/History-C9auUkDi.js.map +0 -1
  181. package/dist/_chunks/History-CKCSQXz_.mjs.map +0 -1
  182. package/dist/_chunks/ListConfigurationPage-Bg4rWUjX.js.map +0 -1
  183. package/dist/_chunks/ListConfigurationPage-CKEC4ttG.mjs.map +0 -1
  184. package/dist/_chunks/ListViewPage-B7_WJUjG.mjs.map +0 -1
  185. package/dist/_chunks/ListViewPage-C2gIeYHG.js.map +0 -1
  186. package/dist/_chunks/Relations-C0uC9J4f.js.map +0 -1
  187. package/dist/_chunks/Relations-DItV5eow.mjs.map +0 -1
  188. package/dist/_chunks/index-Dd0nXyJF.js.map +0 -1
  189. package/dist/_chunks/index-DrNe6ctw.mjs.map +0 -1
  190. package/dist/_chunks/layout-B3ez7kvr.mjs.map +0 -1
  191. package/dist/_chunks/layout-CLLtt_5O.js.map +0 -1
  192. package/dist/_chunks/relations-B0hlsUU_.mjs.map +0 -1
  193. package/dist/_chunks/relations-bRxcNv1q.js.map +0 -1
  194. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  195. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  196. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  197. package/strapi-server.js +0 -3
@@ -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,6 +202,17 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
200
202
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
201
203
  return documentMetadataService.getStatus(document, meta.availableStatus);
202
204
  };
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
+ };
203
216
  const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
204
217
  const model = strapi2.getModel(uid2);
205
218
  const attributes = Object.entries(model.attributes);
@@ -223,13 +236,19 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
223
236
  }
224
237
  case "component": {
225
238
  const populate = getDeepPopulate2(attribute.component);
226
- acc[attributeName] = { populate };
239
+ acc[attributeName] = {
240
+ populate,
241
+ [fieldSelector]: getComponentFields(attribute.component)
242
+ };
227
243
  break;
228
244
  }
229
245
  case "dynamiczone": {
230
246
  const populatedComponents = (attribute.components || []).reduce(
231
247
  (acc2, componentUID) => {
232
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
248
+ acc2[componentUID] = {
249
+ populate: getDeepPopulate2(componentUID),
250
+ [fieldSelector]: getComponentFields(componentUID)
251
+ };
233
252
  return acc2;
234
253
  },
235
254
  {}
@@ -291,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
291
310
  getRelationRestoreValue,
292
311
  getMediaRestoreValue,
293
312
  getDefaultLocale,
313
+ isLocalizedContentType,
294
314
  getLocaleDictionary,
295
315
  getRetentionDays,
296
316
  getVersionStatus,
@@ -313,7 +333,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
313
333
  });
314
334
  },
315
335
  async findVersionsPage(params) {
316
- 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
+ }
317
343
  const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
318
344
  query.findPage({
319
345
  ...params.query,
@@ -335,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
335
361
  const attributeValue = entry.data[attributeKey];
336
362
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
337
363
  if (attributeSchema.type === "media") {
338
- const permissionChecker2 = getService$1("permission-checker").create({
364
+ const permissionChecker2 = getService$2("permission-checker").create({
339
365
  userAbility: params.state.userAbility,
340
366
  model: "plugin::upload.file"
341
367
  });
@@ -358,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
358
384
  if (userToPopulate == null) {
359
385
  return null;
360
386
  }
361
- 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
+ });
362
393
  })
363
394
  );
364
395
  return {
@@ -371,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
371
402
  [attributeKey]: adminUsers
372
403
  };
373
404
  }
374
- const permissionChecker2 = getService$1("permission-checker").create({
405
+ const permissionChecker2 = getService$2("permission-checker").create({
375
406
  userAbility: params.state.userAbility,
376
407
  model: attributeSchema.target
377
408
  });
@@ -529,11 +560,13 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
529
560
  }
530
561
  const uid2 = context.contentType.uid;
531
562
  const schemas = getSchemas(uid2);
563
+ const model = strapi2.getModel(uid2);
564
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
532
565
  const localeEntries = await strapi2.db.query(uid2).findMany({
533
566
  where: {
534
567
  documentId,
535
- locale: { $in: locales },
536
- publishedAt: null
568
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
569
+ ...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
537
570
  },
538
571
  populate: serviceUtils.getDeepPopulate(
539
572
  uid2,
@@ -545,7 +578,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
545
578
  onCommit(async () => {
546
579
  for (const entry of localeEntries) {
547
580
  const status = await serviceUtils.getVersionStatus(uid2, entry);
548
- await getService(strapi2, "history").createVersion({
581
+ await getService$1(strapi2, "history").createVersion({
549
582
  contentType: uid2,
550
583
  data: omit(FIELDS_TO_IGNORE, entry),
551
584
  relatedDocumentId: documentId,
@@ -558,15 +591,19 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
558
591
  });
559
592
  return result;
560
593
  });
561
- state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
594
+ state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
562
595
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
563
596
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
564
597
  strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
565
598
  where: {
566
599
  created_at: {
567
- $lt: expirationDate.toISOString()
600
+ $lt: expirationDate
568
601
  }
569
602
  }
603
+ }).catch((error) => {
604
+ if (error instanceof Error) {
605
+ strapi2.log.error("Error deleting expired history versions", error.message);
606
+ }
570
607
  });
571
608
  });
572
609
  state.isInitialized = true;
@@ -578,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
578
615
  }
579
616
  };
580
617
  };
581
- const services$1 = {
618
+ const services$2 = {
582
619
  history: createHistoryService,
583
620
  lifecycles: createLifecyclesService
584
621
  };
585
- const info = { pluginName: "content-manager", type: "admin" };
622
+ const info$1 = { pluginName: "content-manager", type: "admin" };
586
623
  const historyVersionRouter = {
587
624
  type: "admin",
588
625
  routes: [
589
626
  {
590
627
  method: "GET",
591
- info,
628
+ info: info$1,
592
629
  path: "/history-versions",
593
630
  handler: "history-version.findMany",
594
631
  config: {
@@ -597,7 +634,7 @@ const historyVersionRouter = {
597
634
  },
598
635
  {
599
636
  method: "PUT",
600
- info,
637
+ info: info$1,
601
638
  path: "/history-versions/:versionId/restore",
602
639
  handler: "history-version.restoreVersion",
603
640
  config: {
@@ -606,7 +643,7 @@ const historyVersionRouter = {
606
643
  }
607
644
  ]
608
645
  };
609
- const routes$1 = {
646
+ const routes$2 = {
610
647
  "history-version": historyVersionRouter
611
648
  };
612
649
  const historyVersion = {
@@ -653,21 +690,21 @@ const historyVersion = {
653
690
  }
654
691
  }
655
692
  };
656
- const getFeature = () => {
693
+ const getFeature$1 = () => {
657
694
  if (strapi.ee.features.isEnabled("cms-content-history")) {
658
695
  return {
659
696
  register({ strapi: strapi2 }) {
660
697
  strapi2.get("models").add(historyVersion);
661
698
  },
662
699
  bootstrap({ strapi: strapi2 }) {
663
- getService(strapi2, "lifecycles").bootstrap();
700
+ getService$1(strapi2, "lifecycles").bootstrap();
664
701
  },
665
702
  destroy({ strapi: strapi2 }) {
666
- getService(strapi2, "lifecycles").destroy();
703
+ getService$1(strapi2, "lifecycles").destroy();
667
704
  },
668
- controllers: controllers$1,
669
- services: services$1,
670
- routes: routes$1
705
+ controllers: controllers$2,
706
+ services: services$2,
707
+ routes: routes$2
671
708
  };
672
709
  }
673
710
  return {
@@ -676,7 +713,7 @@ const getFeature = () => {
676
713
  }
677
714
  };
678
715
  };
679
- const history = getFeature();
716
+ const history = getFeature$1();
680
717
  const register = async ({ strapi: strapi2 }) => {
681
718
  await history.register?.({ strapi: strapi2 });
682
719
  };
@@ -684,15 +721,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
684
721
  ENTRY_PUBLISH: "entry.publish",
685
722
  ENTRY_UNPUBLISH: "entry.unpublish"
686
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();
687
873
  const bootstrap = async () => {
688
874
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
689
875
  strapi.get("webhookStore").addAllowedEvent(key, value);
690
876
  });
691
- getService$1("field-sizes").setCustomFieldInputSizes();
692
- await getService$1("components").syncConfigurations();
693
- await getService$1("content-types").syncConfigurations();
694
- await getService$1("permission").registerPermissions();
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();
695
881
  await history.bootstrap?.({ strapi });
882
+ await preview.bootstrap?.({ strapi });
696
883
  };
697
884
  const destroy = async ({ strapi: strapi2 }) => {
698
885
  await history.destroy?.({ strapi: strapi2 });
@@ -1182,7 +1369,8 @@ const admin = {
1182
1369
  };
1183
1370
  const routes = {
1184
1371
  admin,
1185
- ...history.routes ? history.routes : {}
1372
+ ...history.routes ? history.routes : {},
1373
+ ...preview.routes ? preview.routes : {}
1186
1374
  };
1187
1375
  const hasPermissionsSchema = yup$1.object({
1188
1376
  actions: yup$1.array().of(yup$1.string()),
@@ -1193,6 +1381,11 @@ const { createPolicy } = policy;
1193
1381
  const hasPermissions = createPolicy({
1194
1382
  name: "plugin::content-manager.hasPermissions",
1195
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
+ */
1196
1389
  handler(ctx, config = {}) {
1197
1390
  const { actions = [], hasAtLeastOne = false } = config;
1198
1391
  const { userAbility } = ctx.state;
@@ -1434,7 +1627,7 @@ const createMetadasSchema = (schema) => {
1434
1627
  if (!value) {
1435
1628
  return yup$1.string();
1436
1629
  }
1437
- const targetSchema = getService$1("content-types").findContentType(
1630
+ const targetSchema = getService$2("content-types").findContentType(
1438
1631
  schema.attributes[key].targetModel
1439
1632
  );
1440
1633
  if (!targetSchema) {
@@ -1603,7 +1796,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
1603
1796
  }
1604
1797
  };
1605
1798
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1606
- const documentMetadata2 = getService$1("document-metadata");
1799
+ const documentMetadata2 = getService$2("document-metadata");
1607
1800
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1608
1801
  let {
1609
1802
  meta: { availableLocales, availableStatus }
@@ -1629,8 +1822,8 @@ const createDocument = async (ctx, opts) => {
1629
1822
  const { userAbility, user } = ctx.state;
1630
1823
  const { model } = ctx.params;
1631
1824
  const { body } = ctx.request;
1632
- const documentManager2 = getService$1("document-manager");
1633
- 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 });
1634
1827
  if (permissionChecker2.cannot.create()) {
1635
1828
  throw new errors.ForbiddenError();
1636
1829
  }
@@ -1650,13 +1843,13 @@ const updateDocument = async (ctx, opts) => {
1650
1843
  const { userAbility, user } = ctx.state;
1651
1844
  const { id, model } = ctx.params;
1652
1845
  const { body } = ctx.request;
1653
- const documentManager2 = getService$1("document-manager");
1654
- 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 });
1655
1848
  if (permissionChecker2.cannot.update()) {
1656
1849
  throw new errors.ForbiddenError();
1657
1850
  }
1658
1851
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1659
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1852
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1660
1853
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1661
1854
  const [documentVersion, documentExists] = await Promise.all([
1662
1855
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
@@ -1673,7 +1866,7 @@ const updateDocument = async (ctx, opts) => {
1673
1866
  throw new errors.ForbiddenError();
1674
1867
  }
1675
1868
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1676
- const setCreator = setCreatorFields({ user, isEdition: true });
1869
+ const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
1677
1870
  const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
1678
1871
  const sanitizedBody = await sanitizeFn(body);
1679
1872
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1687,14 +1880,14 @@ const collectionTypes = {
1687
1880
  const { userAbility } = ctx.state;
1688
1881
  const { model } = ctx.params;
1689
1882
  const { query } = ctx.request;
1690
- const documentMetadata2 = getService$1("document-metadata");
1691
- const documentManager2 = getService$1("document-manager");
1692
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1883
+ const documentMetadata2 = getService$2("document-metadata");
1884
+ const documentManager2 = getService$2("document-manager");
1885
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1693
1886
  if (permissionChecker2.cannot.read()) {
1694
1887
  return ctx.forbidden();
1695
1888
  }
1696
1889
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1697
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1890
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1698
1891
  const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1699
1892
  const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
1700
1893
  { ...permissionQuery, populate, locale, status },
@@ -1723,13 +1916,13 @@ const collectionTypes = {
1723
1916
  async findOne(ctx) {
1724
1917
  const { userAbility } = ctx.state;
1725
1918
  const { model, id } = ctx.params;
1726
- const documentManager2 = getService$1("document-manager");
1727
- 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 });
1728
1921
  if (permissionChecker2.cannot.read()) {
1729
1922
  return ctx.forbidden();
1730
1923
  }
1731
1924
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1732
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1925
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1733
1926
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1734
1927
  const version = await documentManager2.findOne(id, model, {
1735
1928
  populate,
@@ -1745,7 +1938,7 @@ const collectionTypes = {
1745
1938
  permissionChecker2,
1746
1939
  model,
1747
1940
  // @ts-expect-error TODO: fix
1748
- { id, locale, publishedAt: null },
1941
+ { documentId: id, locale, publishedAt: null },
1749
1942
  { availableLocales: true, availableStatus: false }
1750
1943
  );
1751
1944
  ctx.body = { data: {}, meta };
@@ -1760,7 +1953,7 @@ const collectionTypes = {
1760
1953
  async create(ctx) {
1761
1954
  const { userAbility } = ctx.state;
1762
1955
  const { model } = ctx.params;
1763
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1956
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1764
1957
  const [totalEntries, document] = await Promise.all([
1765
1958
  strapi.db.query(model).count(),
1766
1959
  createDocument(ctx)
@@ -1781,7 +1974,7 @@ const collectionTypes = {
1781
1974
  async update(ctx) {
1782
1975
  const { userAbility } = ctx.state;
1783
1976
  const { model } = ctx.params;
1784
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1977
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1785
1978
  const updatedVersion = await updateDocument(ctx);
1786
1979
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1787
1980
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1790,13 +1983,13 @@ const collectionTypes = {
1790
1983
  const { userAbility, user } = ctx.state;
1791
1984
  const { model, sourceId: id } = ctx.params;
1792
1985
  const { body } = ctx.request;
1793
- const documentManager2 = getService$1("document-manager");
1794
- 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 });
1795
1988
  if (permissionChecker2.cannot.create()) {
1796
1989
  return ctx.forbidden();
1797
1990
  }
1798
1991
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1799
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1992
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1800
1993
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1801
1994
  const document = await documentManager2.findOne(id, model, {
1802
1995
  populate,
@@ -1835,13 +2028,13 @@ const collectionTypes = {
1835
2028
  async delete(ctx) {
1836
2029
  const { userAbility } = ctx.state;
1837
2030
  const { id, model } = ctx.params;
1838
- const documentManager2 = getService$1("document-manager");
1839
- 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 });
1840
2033
  if (permissionChecker2.cannot.delete()) {
1841
2034
  return ctx.forbidden();
1842
2035
  }
1843
2036
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1844
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2037
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1845
2038
  const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1846
2039
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1847
2040
  if (documentLocales.length === 0) {
@@ -1863,14 +2056,14 @@ const collectionTypes = {
1863
2056
  const { userAbility } = ctx.state;
1864
2057
  const { id, model } = ctx.params;
1865
2058
  const { body } = ctx.request;
1866
- const documentManager2 = getService$1("document-manager");
1867
- 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 });
1868
2061
  if (permissionChecker2.cannot.publish()) {
1869
2062
  return ctx.forbidden();
1870
2063
  }
1871
2064
  const publishedDocument = await strapi.db.transaction(async () => {
1872
2065
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1873
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2066
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1874
2067
  let document;
1875
2068
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1876
2069
  const isCreate = isNil$1(id);
@@ -1882,11 +2075,17 @@ const collectionTypes = {
1882
2075
  }
1883
2076
  const isUpdate = !isCreate;
1884
2077
  if (isUpdate) {
1885
- document = await documentManager2.findOne(id, model, { populate, locale });
1886
- if (!document) {
2078
+ const documentExists = documentManager2.exists(model, id);
2079
+ if (!documentExists) {
1887
2080
  throw new errors.NotFoundError("Document not found");
1888
2081
  }
1889
- if (permissionChecker2.can.update(document)) {
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)) {
1890
2089
  await updateDocument(ctx);
1891
2090
  }
1892
2091
  }
@@ -1912,13 +2111,13 @@ const collectionTypes = {
1912
2111
  const { body } = ctx.request;
1913
2112
  const { documentIds } = body;
1914
2113
  await validateBulkActionInput(body);
1915
- const documentManager2 = getService$1("document-manager");
1916
- 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 });
1917
2116
  if (permissionChecker2.cannot.publish()) {
1918
2117
  return ctx.forbidden();
1919
2118
  }
1920
2119
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1921
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2120
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1922
2121
  const { locale } = await getDocumentLocaleAndStatus(body, model, {
1923
2122
  allowMultipleLocales: true
1924
2123
  });
@@ -1943,12 +2142,14 @@ const collectionTypes = {
1943
2142
  const { body } = ctx.request;
1944
2143
  const { documentIds } = body;
1945
2144
  await validateBulkActionInput(body);
1946
- const documentManager2 = getService$1("document-manager");
1947
- 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 });
1948
2147
  if (permissionChecker2.cannot.unpublish()) {
1949
2148
  return ctx.forbidden();
1950
2149
  }
1951
- const { locale } = await getDocumentLocaleAndStatus(body, model);
2150
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2151
+ allowMultipleLocales: true
2152
+ });
1952
2153
  const entityPromises = documentIds.map(
1953
2154
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1954
2155
  );
@@ -1971,8 +2172,8 @@ const collectionTypes = {
1971
2172
  const {
1972
2173
  body: { discardDraft, ...body }
1973
2174
  } = ctx.request;
1974
- const documentManager2 = getService$1("document-manager");
1975
- 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 });
1976
2177
  if (permissionChecker2.cannot.unpublish()) {
1977
2178
  return ctx.forbidden();
1978
2179
  }
@@ -1980,7 +2181,7 @@ const collectionTypes = {
1980
2181
  return ctx.forbidden();
1981
2182
  }
1982
2183
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
1983
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2184
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1984
2185
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1985
2186
  const document = await documentManager2.findOne(id, model, {
1986
2187
  populate,
@@ -2011,13 +2212,13 @@ const collectionTypes = {
2011
2212
  const { userAbility } = ctx.state;
2012
2213
  const { id, model } = ctx.params;
2013
2214
  const { body } = ctx.request;
2014
- const documentManager2 = getService$1("document-manager");
2015
- 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 });
2016
2217
  if (permissionChecker2.cannot.discard()) {
2017
2218
  return ctx.forbidden();
2018
2219
  }
2019
2220
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
2020
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2221
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2021
2222
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2022
2223
  const document = await documentManager2.findOne(id, model, {
2023
2224
  populate,
@@ -2042,13 +2243,13 @@ const collectionTypes = {
2042
2243
  const { query, body } = ctx.request;
2043
2244
  const { documentIds } = body;
2044
2245
  await validateBulkActionInput(body);
2045
- const documentManager2 = getService$1("document-manager");
2046
- 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 });
2047
2248
  if (permissionChecker2.cannot.delete()) {
2048
2249
  return ctx.forbidden();
2049
2250
  }
2050
2251
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2051
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2252
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2052
2253
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2053
2254
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2054
2255
  populate,
@@ -2069,13 +2270,13 @@ const collectionTypes = {
2069
2270
  async countDraftRelations(ctx) {
2070
2271
  const { userAbility } = ctx.state;
2071
2272
  const { model, id } = ctx.params;
2072
- const documentManager2 = getService$1("document-manager");
2073
- 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 });
2074
2275
  if (permissionChecker2.cannot.read()) {
2075
2276
  return ctx.forbidden();
2076
2277
  }
2077
2278
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2078
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2279
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2079
2280
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2080
2281
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2081
2282
  if (!entity) {
@@ -2094,8 +2295,8 @@ const collectionTypes = {
2094
2295
  const ids = ctx.request.query.documentIds;
2095
2296
  const locale = ctx.request.query.locale;
2096
2297
  const { model } = ctx.params;
2097
- const documentManager2 = getService$1("document-manager");
2098
- 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 });
2099
2300
  if (permissionChecker2.cannot.read()) {
2100
2301
  return ctx.forbidden();
2101
2302
  }
@@ -2119,13 +2320,13 @@ const collectionTypes = {
2119
2320
  };
2120
2321
  const components$1 = {
2121
2322
  findComponents(ctx) {
2122
- const components2 = getService$1("components").findAllComponents();
2123
- const { toDto } = getService$1("data-mapper");
2323
+ const components2 = getService$2("components").findAllComponents();
2324
+ const { toDto } = getService$2("data-mapper");
2124
2325
  ctx.body = { data: components2.map(toDto) };
2125
2326
  },
2126
2327
  async findComponentConfiguration(ctx) {
2127
2328
  const { uid: uid2 } = ctx.params;
2128
- const componentService = getService$1("components");
2329
+ const componentService = getService$2("components");
2129
2330
  const component = componentService.findComponent(uid2);
2130
2331
  if (!component) {
2131
2332
  return ctx.notFound("component.notFound");
@@ -2142,7 +2343,7 @@ const components$1 = {
2142
2343
  async updateComponentConfiguration(ctx) {
2143
2344
  const { uid: uid2 } = ctx.params;
2144
2345
  const { body } = ctx.request;
2145
- const componentService = getService$1("components");
2346
+ const componentService = getService$2("components");
2146
2347
  const component = componentService.findComponent(uid2);
2147
2348
  if (!component) {
2148
2349
  return ctx.notFound("component.notFound");
@@ -2176,12 +2377,12 @@ const contentTypes = {
2176
2377
  } catch (error) {
2177
2378
  return ctx.send({ error }, 400);
2178
2379
  }
2179
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2180
- const { toDto } = getService$1("data-mapper");
2380
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2381
+ const { toDto } = getService$2("data-mapper");
2181
2382
  ctx.body = { data: contentTypes2.map(toDto) };
2182
2383
  },
2183
2384
  async findContentTypesSettings(ctx) {
2184
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2385
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2185
2386
  const contentTypes2 = await findAllContentTypes();
2186
2387
  const configurations = await Promise.all(
2187
2388
  contentTypes2.map(async (contentType) => {
@@ -2195,7 +2396,7 @@ const contentTypes = {
2195
2396
  },
2196
2397
  async findContentTypeConfiguration(ctx) {
2197
2398
  const { uid: uid2 } = ctx.params;
2198
- const contentTypeService = getService$1("content-types");
2399
+ const contentTypeService = getService$2("content-types");
2199
2400
  const contentType = await contentTypeService.findContentType(uid2);
2200
2401
  if (!contentType) {
2201
2402
  return ctx.notFound("contentType.notFound");
@@ -2217,13 +2418,13 @@ const contentTypes = {
2217
2418
  const { userAbility } = ctx.state;
2218
2419
  const { uid: uid2 } = ctx.params;
2219
2420
  const { body } = ctx.request;
2220
- const contentTypeService = getService$1("content-types");
2221
- const metricsService = getService$1("metrics");
2421
+ const contentTypeService = getService$2("content-types");
2422
+ const metricsService = getService$2("metrics");
2222
2423
  const contentType = await contentTypeService.findContentType(uid2);
2223
2424
  if (!contentType) {
2224
2425
  return ctx.notFound("contentType.notFound");
2225
2426
  }
2226
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2427
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2227
2428
  return ctx.forbidden();
2228
2429
  }
2229
2430
  let input;
@@ -2256,10 +2457,10 @@ const contentTypes = {
2256
2457
  };
2257
2458
  const init = {
2258
2459
  getInitData(ctx) {
2259
- const { toDto } = getService$1("data-mapper");
2260
- const { findAllComponents } = getService$1("components");
2261
- const { getAllFieldSizes } = getService$1("field-sizes");
2262
- const { findAllContentTypes } = getService$1("content-types");
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");
2263
2464
  ctx.body = {
2264
2465
  data: {
2265
2466
  fieldSizes: getAllFieldSizes(),
@@ -2295,36 +2496,41 @@ const addFiltersClause = (params, filtersClause) => {
2295
2496
  params.filters.$and.push(filtersClause);
2296
2497
  };
2297
2498
  const sanitizeMainField = (model, mainField, userAbility) => {
2298
- const permissionChecker2 = getService$1("permission-checker").create({
2499
+ const permissionChecker2 = getService$2("permission-checker").create({
2299
2500
  userAbility,
2300
2501
  model: model.uid
2301
2502
  });
2302
- if (!isListable(model, mainField)) {
2503
+ const isMainFieldListable = isListable(model, mainField);
2504
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2505
+ if (!isMainFieldListable || !canReadMainField) {
2303
2506
  return "id";
2304
2507
  }
2305
- if (permissionChecker2.cannot.read(null, mainField)) {
2306
- if (model.uid === "plugin::users-permissions.role") {
2307
- const userPermissionChecker = getService$1("permission-checker").create({
2308
- userAbility,
2309
- model: "plugin::users-permissions.user"
2310
- });
2311
- if (userPermissionChecker.can.read()) {
2312
- return "name";
2313
- }
2314
- }
2315
- return "id";
2508
+ if (model.uid === "plugin::users-permissions.role") {
2509
+ return "name";
2316
2510
  }
2317
2511
  return mainField;
2318
2512
  };
2319
- const addStatusToRelations = async (uid2, relations2) => {
2320
- if (!contentTypes$1.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2513
+ const addStatusToRelations = async (targetUid, relations2) => {
2514
+ if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
2321
2515
  return relations2;
2322
2516
  }
2323
- const documentMetadata2 = getService$1("document-metadata");
2324
- 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
+ });
2325
2531
  return relations2.map((relation) => {
2326
- const availableStatuses = documentsAvailableStatus.filter(
2327
- (availableDocument) => availableDocument.documentId === relation.documentId
2532
+ const availableStatuses = availableStatus.filter(
2533
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2328
2534
  );
2329
2535
  return {
2330
2536
  ...relation,
@@ -2345,11 +2551,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2345
2551
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2346
2552
  const isSourceLocalized = isLocalized(sourceModel);
2347
2553
  const isTargetLocalized = isLocalized(targetModel);
2348
- let validatedLocale = locale;
2349
- if (!targetModel || !isTargetLocalized)
2350
- validatedLocale = void 0;
2351
2554
  return {
2352
- locale: validatedLocale,
2555
+ locale,
2353
2556
  isSourceLocalized,
2354
2557
  isTargetLocalized
2355
2558
  };
@@ -2389,7 +2592,7 @@ const relations = {
2389
2592
  ctx.request?.query?.locale
2390
2593
  );
2391
2594
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2392
- const permissionChecker2 = getService$1("permission-checker").create({
2595
+ const permissionChecker2 = getService$2("permission-checker").create({
2393
2596
  userAbility,
2394
2597
  model
2395
2598
  });
@@ -2414,7 +2617,7 @@ const relations = {
2414
2617
  where.id = id;
2415
2618
  }
2416
2619
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2417
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2620
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2418
2621
  const currentEntity = await strapi.db.query(model).findOne({
2419
2622
  where,
2420
2623
  populate
@@ -2429,7 +2632,7 @@ const relations = {
2429
2632
  }
2430
2633
  entryId = currentEntity.id;
2431
2634
  }
2432
- 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);
2433
2636
  const targetSchema = strapi.getModel(targetUid);
2434
2637
  const mainField = flow(
2435
2638
  prop(`metadatas.${targetField}.edit.mainField`),
@@ -2452,7 +2655,7 @@ const relations = {
2452
2655
  attribute,
2453
2656
  fieldsToSelect,
2454
2657
  mainField,
2455
- source: { schema: sourceSchema },
2658
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2456
2659
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2457
2660
  sourceSchema,
2458
2661
  targetSchema,
@@ -2474,7 +2677,8 @@ const relations = {
2474
2677
  fieldsToSelect,
2475
2678
  mainField,
2476
2679
  source: {
2477
- schema: { uid: sourceUid, modelType: sourceModelType }
2680
+ schema: { uid: sourceUid, modelType: sourceModelType },
2681
+ isLocalized: isSourceLocalized
2478
2682
  },
2479
2683
  target: {
2480
2684
  schema: { uid: targetUid },
@@ -2482,7 +2686,7 @@ const relations = {
2482
2686
  }
2483
2687
  } = await this.extractAndValidateRequestInfo(ctx, id);
2484
2688
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2485
- const permissionChecker2 = getService$1("permission-checker").create({
2689
+ const permissionChecker2 = getService$2("permission-checker").create({
2486
2690
  userAbility: ctx.state.userAbility,
2487
2691
  model: targetUid
2488
2692
  });
@@ -2512,12 +2716,16 @@ const relations = {
2512
2716
  } else {
2513
2717
  where.id = id;
2514
2718
  }
2515
- if (status) {
2516
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2719
+ const publishedAt = getPublishedAtClause(status, targetUid);
2720
+ if (!isEmpty(publishedAt)) {
2721
+ where[`${alias}.published_at`] = publishedAt;
2517
2722
  }
2518
- if (filterByLocale) {
2723
+ if (isTargetLocalized && locale) {
2519
2724
  where[`${alias}.locale`] = locale;
2520
2725
  }
2726
+ if (isSourceLocalized && locale) {
2727
+ where.locale = locale;
2728
+ }
2521
2729
  if ((idsToInclude?.length ?? 0) !== 0) {
2522
2730
  where[`${alias}.id`].$notIn = idsToInclude;
2523
2731
  }
@@ -2535,7 +2743,8 @@ const relations = {
2535
2743
  id: { $notIn: uniq(idsToOmit) }
2536
2744
  });
2537
2745
  }
2538
- 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);
2539
2748
  ctx.body = {
2540
2749
  ...res,
2541
2750
  results: await addStatusToRelations(targetUid, res.results)
@@ -2550,29 +2759,39 @@ const relations = {
2550
2759
  attribute,
2551
2760
  targetField,
2552
2761
  fieldsToSelect,
2553
- source: {
2554
- schema: { uid: sourceUid }
2555
- },
2556
- target: {
2557
- schema: { uid: targetUid }
2558
- }
2762
+ status,
2763
+ source: { schema: sourceSchema },
2764
+ target: { schema: targetSchema }
2559
2765
  } = await this.extractAndValidateRequestInfo(ctx, id);
2560
- 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 });
2561
2769
  const dbQuery = strapi.db.query(sourceUid);
2562
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
+ }
2563
2783
  const res = await loadRelations({ id: entryId }, targetField, {
2564
- select: ["id", "documentId", "locale", "publishedAt"],
2784
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2565
2785
  ordering: "desc",
2566
2786
  page: ctx.request.query.page,
2567
- pageSize: ctx.request.query.pageSize
2787
+ pageSize: ctx.request.query.pageSize,
2788
+ filters
2568
2789
  });
2569
2790
  const loadedIds = res.results.map((item) => item.id);
2570
2791
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2571
2792
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2572
2793
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2573
- ordering: "desc",
2574
- page: ctx.request.query.page,
2575
- pageSize: ctx.request.query.pageSize
2794
+ ordering: "desc"
2576
2795
  });
2577
2796
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2578
2797
  ctx.body = {
@@ -2587,10 +2806,10 @@ const relations = {
2587
2806
  }
2588
2807
  };
2589
2808
  const buildPopulateFromQuery = async (query, model) => {
2590
- 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();
2591
2810
  };
2592
2811
  const findDocument = async (query, uid2, opts = {}) => {
2593
- const documentManager2 = getService$1("document-manager");
2812
+ const documentManager2 = getService$2("document-manager");
2594
2813
  const populate = await buildPopulateFromQuery(query, uid2);
2595
2814
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2596
2815
  };
@@ -2598,8 +2817,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
2598
2817
  const { user, userAbility } = ctx.state;
2599
2818
  const { model } = ctx.params;
2600
2819
  const { body, query } = ctx.request;
2601
- const documentManager2 = getService$1("document-manager");
2602
- 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 });
2603
2822
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2604
2823
  throw new errors.ForbiddenError();
2605
2824
  }
@@ -2640,7 +2859,7 @@ const singleTypes = {
2640
2859
  const { userAbility } = ctx.state;
2641
2860
  const { model } = ctx.params;
2642
2861
  const { query = {} } = ctx.request;
2643
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2862
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2644
2863
  if (permissionChecker2.cannot.read()) {
2645
2864
  return ctx.forbidden();
2646
2865
  }
@@ -2659,7 +2878,7 @@ const singleTypes = {
2659
2878
  permissionChecker2,
2660
2879
  model,
2661
2880
  // @ts-expect-error - fix types
2662
- { id: document.documentId, locale, publishedAt: null },
2881
+ { documentId: document.documentId, locale, publishedAt: null },
2663
2882
  { availableLocales: true, availableStatus: false }
2664
2883
  );
2665
2884
  ctx.body = { data: {}, meta };
@@ -2674,7 +2893,7 @@ const singleTypes = {
2674
2893
  async createOrUpdate(ctx) {
2675
2894
  const { userAbility } = ctx.state;
2676
2895
  const { model } = ctx.params;
2677
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2896
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2678
2897
  const document = await createOrUpdateDocument(ctx);
2679
2898
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2680
2899
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2683,8 +2902,8 @@ const singleTypes = {
2683
2902
  const { userAbility } = ctx.state;
2684
2903
  const { model } = ctx.params;
2685
2904
  const { query = {} } = ctx.request;
2686
- const documentManager2 = getService$1("document-manager");
2687
- 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 });
2688
2907
  if (permissionChecker2.cannot.delete()) {
2689
2908
  return ctx.forbidden();
2690
2909
  }
@@ -2712,8 +2931,8 @@ const singleTypes = {
2712
2931
  const { userAbility } = ctx.state;
2713
2932
  const { model } = ctx.params;
2714
2933
  const { query = {} } = ctx.request;
2715
- const documentManager2 = getService$1("document-manager");
2716
- 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 });
2717
2936
  if (permissionChecker2.cannot.publish()) {
2718
2937
  return ctx.forbidden();
2719
2938
  }
@@ -2741,8 +2960,8 @@ const singleTypes = {
2741
2960
  body: { discardDraft, ...body },
2742
2961
  query = {}
2743
2962
  } = ctx.request;
2744
- const documentManager2 = getService$1("document-manager");
2745
- 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 });
2746
2965
  if (permissionChecker2.cannot.unpublish()) {
2747
2966
  return ctx.forbidden();
2748
2967
  }
@@ -2776,8 +2995,8 @@ const singleTypes = {
2776
2995
  const { userAbility } = ctx.state;
2777
2996
  const { model } = ctx.params;
2778
2997
  const { body, query = {} } = ctx.request;
2779
- const documentManager2 = getService$1("document-manager");
2780
- 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 });
2781
3000
  if (permissionChecker2.cannot.discard()) {
2782
3001
  return ctx.forbidden();
2783
3002
  }
@@ -2800,8 +3019,8 @@ const singleTypes = {
2800
3019
  const { userAbility } = ctx.state;
2801
3020
  const { model } = ctx.params;
2802
3021
  const { query } = ctx.request;
2803
- const documentManager2 = getService$1("document-manager");
2804
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3022
+ const documentManager2 = getService$2("document-manager");
3023
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2805
3024
  const { locale } = await getDocumentLocaleAndStatus(query, model);
2806
3025
  if (permissionChecker2.cannot.read()) {
2807
3026
  return ctx.forbidden();
@@ -2825,7 +3044,7 @@ const uid$1 = {
2825
3044
  const { query = {} } = ctx.request;
2826
3045
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2827
3046
  await validateUIDField(contentTypeUID, field);
2828
- const uidService = getService$1("uid");
3047
+ const uidService = getService$2("uid");
2829
3048
  ctx.body = {
2830
3049
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2831
3050
  };
@@ -2837,7 +3056,7 @@ const uid$1 = {
2837
3056
  const { query = {} } = ctx.request;
2838
3057
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2839
3058
  await validateUIDField(contentTypeUID, field);
2840
- const uidService = getService$1("uid");
3059
+ const uidService = getService$2("uid");
2841
3060
  const isAvailable = await uidService.checkUIDAvailability({
2842
3061
  contentTypeUID,
2843
3062
  field,
@@ -2858,7 +3077,8 @@ const controllers = {
2858
3077
  relations,
2859
3078
  "single-types": singleTypes,
2860
3079
  uid: uid$1,
2861
- ...history.controllers ? history.controllers : {}
3080
+ ...history.controllers ? history.controllers : {},
3081
+ ...preview.controllers ? preview.controllers : {}
2862
3082
  };
2863
3083
  const keys = {
2864
3084
  CONFIGURATION: "configuration"
@@ -3009,12 +3229,12 @@ async function syncMetadatas(configuration, schema) {
3009
3229
  return _.assign(metasWithDefaults, updatedMetas);
3010
3230
  }
3011
3231
  const getTargetSchema = (targetModel) => {
3012
- return getService$1("content-types").findContentType(targetModel);
3232
+ return getService$2("content-types").findContentType(targetModel);
3013
3233
  };
3014
3234
  const DEFAULT_LIST_LENGTH = 4;
3015
3235
  const MAX_ROW_SIZE = 12;
3016
3236
  const isAllowedFieldSize = (type, size) => {
3017
- const { getFieldSize } = getService$1("field-sizes");
3237
+ const { getFieldSize } = getService$2("field-sizes");
3018
3238
  const fieldSize = getFieldSize(type);
3019
3239
  if (!fieldSize.isResizable && size !== fieldSize.default) {
3020
3240
  return false;
@@ -3022,7 +3242,7 @@ const isAllowedFieldSize = (type, size) => {
3022
3242
  return size <= MAX_ROW_SIZE;
3023
3243
  };
3024
3244
  const getDefaultFieldSize = (attribute) => {
3025
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3245
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
3026
3246
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
3027
3247
  };
3028
3248
  async function createDefaultLayouts(schema) {
@@ -3057,7 +3277,7 @@ function syncLayouts(configuration, schema) {
3057
3277
  for (const el of row) {
3058
3278
  if (!hasEditableAttribute(schema, el.name))
3059
3279
  continue;
3060
- const { hasFieldSize } = getService$1("field-sizes");
3280
+ const { hasFieldSize } = getService$2("field-sizes");
3061
3281
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3062
3282
  if (!isAllowedFieldSize(fieldType, el.size)) {
3063
3283
  elementsToReAppend.push(el.name);
@@ -3197,17 +3417,17 @@ const configurationService$1 = createConfigurationService({
3197
3417
  isComponent: true,
3198
3418
  prefix: STORE_KEY_PREFIX,
3199
3419
  getModels() {
3200
- const { toContentManagerModel } = getService$1("data-mapper");
3420
+ const { toContentManagerModel } = getService$2("data-mapper");
3201
3421
  return mapValues(toContentManagerModel, strapi.components);
3202
3422
  }
3203
3423
  });
3204
3424
  const components = ({ strapi: strapi2 }) => ({
3205
3425
  findAllComponents() {
3206
- const { toContentManagerModel } = getService$1("data-mapper");
3426
+ const { toContentManagerModel } = getService$2("data-mapper");
3207
3427
  return Object.values(strapi2.components).map(toContentManagerModel);
3208
3428
  },
3209
3429
  findComponent(uid2) {
3210
- const { toContentManagerModel } = getService$1("data-mapper");
3430
+ const { toContentManagerModel } = getService$2("data-mapper");
3211
3431
  const component = strapi2.components[uid2];
3212
3432
  return isNil$1(component) ? component : toContentManagerModel(component);
3213
3433
  },
@@ -3258,17 +3478,17 @@ const configurationService = createConfigurationService({
3258
3478
  storeUtils,
3259
3479
  prefix: "content_types",
3260
3480
  getModels() {
3261
- const { toContentManagerModel } = getService$1("data-mapper");
3481
+ const { toContentManagerModel } = getService$2("data-mapper");
3262
3482
  return mapValues(toContentManagerModel, strapi.contentTypes);
3263
3483
  }
3264
3484
  });
3265
3485
  const service = ({ strapi: strapi2 }) => ({
3266
3486
  findAllContentTypes() {
3267
- const { toContentManagerModel } = getService$1("data-mapper");
3487
+ const { toContentManagerModel } = getService$2("data-mapper");
3268
3488
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3269
3489
  },
3270
3490
  findContentType(uid2) {
3271
- const { toContentManagerModel } = getService$1("data-mapper");
3491
+ const { toContentManagerModel } = getService$2("data-mapper");
3272
3492
  const contentType = strapi2.contentTypes[uid2];
3273
3493
  return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
3274
3494
  },
@@ -3297,7 +3517,7 @@ const service = ({ strapi: strapi2 }) => ({
3297
3517
  return this.findConfiguration(contentType);
3298
3518
  },
3299
3519
  findComponentsConfigurations(contentType) {
3300
- return getService$1("components").findComponentsConfigurations(contentType);
3520
+ return getService$2("components").findComponentsConfigurations(contentType);
3301
3521
  },
3302
3522
  syncConfigurations() {
3303
3523
  return configurationService.syncConfigurations();
@@ -3478,12 +3698,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3478
3698
  ability: userAbility,
3479
3699
  model
3480
3700
  });
3481
- 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
+ };
3482
3705
  const can = (action, entity, field) => {
3483
- 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
+ );
3484
3713
  };
3485
3714
  const cannot = (action, entity, field) => {
3486
- 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
+ );
3487
3722
  };
3488
3723
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3489
3724
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3554,7 +3789,7 @@ const permission = ({ strapi: strapi2 }) => ({
3554
3789
  return userAbility.can(action);
3555
3790
  },
3556
3791
  async registerPermissions() {
3557
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3792
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3558
3793
  const contentTypesUids = displayedContentTypes.map(prop("uid"));
3559
3794
  const actions = [
3560
3795
  {
@@ -3830,7 +4065,7 @@ const getQueryPopulate = async (uid2, query) => {
3830
4065
  return populateQuery;
3831
4066
  };
3832
4067
  const buildDeepPopulate = (uid2) => {
3833
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4068
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3834
4069
  };
3835
4070
  const populateBuilder = (uid2) => {
3836
4071
  let getInitialPopulate = async () => {
@@ -4015,7 +4250,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4015
4250
  */
4016
4251
  async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4017
4252
  const versionsByLocale = groupBy("locale", allVersions);
4018
- delete versionsByLocale[version.locale];
4253
+ if (version.locale) {
4254
+ delete versionsByLocale[version.locale];
4255
+ }
4019
4256
  const model = strapi2.getModel(uid2);
4020
4257
  const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4021
4258
  const traversalFunction = async (localeVersion) => traverseEntity(
@@ -4371,7 +4608,8 @@ const services = {
4371
4608
  permission,
4372
4609
  "populate-builder": populateBuilder$1,
4373
4610
  uid,
4374
- ...history.services ? history.services : {}
4611
+ ...history.services ? history.services : {},
4612
+ ...preview.services ? preview.services : {}
4375
4613
  };
4376
4614
  const index = () => {
4377
4615
  return {