@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
@@ -33,10 +33,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
33
33
  const ___default = /* @__PURE__ */ _interopDefault(_);
34
34
  const qs__default = /* @__PURE__ */ _interopDefault(qs);
35
35
  const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
36
- const getService$1 = (name) => {
36
+ const getService$2 = (name) => {
37
37
  return strapi.plugin("content-manager").service(name);
38
38
  };
39
- function getService(strapi2, name) {
39
+ function getService$1(strapi2, name) {
40
40
  return strapi2.service(`plugin::content-manager.${name}`);
41
41
  }
42
42
  const historyRestoreVersionSchema = yup__namespace.object().shape({
@@ -72,7 +72,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
72
72
  if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
73
73
  throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
74
74
  }
75
- const permissionChecker2 = getService$1("permission-checker").create({
75
+ const permissionChecker2 = getService$2("permission-checker").create({
76
76
  userAbility: ctx.state.userAbility,
77
77
  model: ctx.query.contentType
78
78
  });
@@ -80,7 +80,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
80
80
  return ctx.forbidden();
81
81
  }
82
82
  const query = await permissionChecker2.sanitizeQuery(ctx.query);
83
- const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
83
+ const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
84
84
  query: {
85
85
  ...query,
86
86
  ...getValidPagination({ page: query.page, pageSize: query.pageSize })
@@ -105,14 +105,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
105
105
  async restoreVersion(ctx) {
106
106
  const request = ctx.request;
107
107
  await validateRestoreVersion(request.body, "contentType is required");
108
- const permissionChecker2 = getService$1("permission-checker").create({
108
+ const permissionChecker2 = getService$2("permission-checker").create({
109
109
  userAbility: ctx.state.userAbility,
110
110
  model: request.body.contentType
111
111
  });
112
112
  if (permissionChecker2.cannot.update()) {
113
113
  throw new strapiUtils.errors.ForbiddenError();
114
114
  }
115
- const restoredDocument = await getService(strapi2, "history").restoreVersion(
115
+ const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
116
116
  request.params.versionId
117
117
  );
118
118
  return {
@@ -121,7 +121,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
121
121
  }
122
122
  };
123
123
  };
124
- const controllers$1 = {
124
+ const controllers$2 = {
125
125
  "history-version": createHistoryVersionController
126
126
  /**
127
127
  * Casting is needed because the types aren't aware that Strapi supports
@@ -199,7 +199,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
199
199
  return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
200
200
  };
201
201
  const localesService = strapi2.plugin("i18n")?.service("locales");
202
+ const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
202
203
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
204
+ const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
203
205
  const getLocaleDictionary = async () => {
204
206
  if (!localesService)
205
207
  return {};
@@ -226,6 +228,17 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
226
228
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
227
229
  return documentMetadataService.getStatus(document, meta.availableStatus);
228
230
  };
231
+ const getComponentFields = (componentUID) => {
232
+ return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
233
+ (fieldsAcc, [key, attribute]) => {
234
+ if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
235
+ fieldsAcc.push(key);
236
+ }
237
+ return fieldsAcc;
238
+ },
239
+ []
240
+ );
241
+ };
229
242
  const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
230
243
  const model = strapi2.getModel(uid2);
231
244
  const attributes = Object.entries(model.attributes);
@@ -249,13 +262,19 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
249
262
  }
250
263
  case "component": {
251
264
  const populate = getDeepPopulate2(attribute.component);
252
- acc[attributeName] = { populate };
265
+ acc[attributeName] = {
266
+ populate,
267
+ [fieldSelector]: getComponentFields(attribute.component)
268
+ };
253
269
  break;
254
270
  }
255
271
  case "dynamiczone": {
256
272
  const populatedComponents = (attribute.components || []).reduce(
257
273
  (acc2, componentUID) => {
258
- acc2[componentUID] = { populate: getDeepPopulate2(componentUID) };
274
+ acc2[componentUID] = {
275
+ populate: getDeepPopulate2(componentUID),
276
+ [fieldSelector]: getComponentFields(componentUID)
277
+ };
259
278
  return acc2;
260
279
  },
261
280
  {}
@@ -317,6 +336,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
317
336
  getRelationRestoreValue,
318
337
  getMediaRestoreValue,
319
338
  getDefaultLocale,
339
+ isLocalizedContentType,
320
340
  getLocaleDictionary,
321
341
  getRetentionDays,
322
342
  getVersionStatus,
@@ -339,7 +359,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
339
359
  });
340
360
  },
341
361
  async findVersionsPage(params) {
342
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
362
+ const model = strapi2.getModel(params.query.contentType);
363
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
364
+ const defaultLocale = await serviceUtils.getDefaultLocale();
365
+ let locale = null;
366
+ if (isLocalizedContentType) {
367
+ locale = params.query.locale || defaultLocale;
368
+ }
343
369
  const [{ results, pagination }, localeDictionary] = await Promise.all([
344
370
  query.findPage({
345
371
  ...params.query,
@@ -361,7 +387,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
361
387
  const attributeValue = entry.data[attributeKey];
362
388
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
363
389
  if (attributeSchema.type === "media") {
364
- const permissionChecker2 = getService$1("permission-checker").create({
390
+ const permissionChecker2 = getService$2("permission-checker").create({
365
391
  userAbility: params.state.userAbility,
366
392
  model: "plugin::upload.file"
367
393
  });
@@ -384,7 +410,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
384
410
  if (userToPopulate == null) {
385
411
  return null;
386
412
  }
387
- return strapi2.query("admin::user").findOne({ where: { id: userToPopulate.id } });
413
+ return strapi2.query("admin::user").findOne({
414
+ where: {
415
+ ...userToPopulate.id ? { id: userToPopulate.id } : {},
416
+ ...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
417
+ }
418
+ });
388
419
  })
389
420
  );
390
421
  return {
@@ -397,7 +428,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
397
428
  [attributeKey]: adminUsers
398
429
  };
399
430
  }
400
- const permissionChecker2 = getService$1("permission-checker").create({
431
+ const permissionChecker2 = getService$2("permission-checker").create({
401
432
  userAbility: params.state.userAbility,
402
433
  model: attributeSchema.target
403
434
  });
@@ -555,11 +586,13 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
555
586
  }
556
587
  const uid2 = context.contentType.uid;
557
588
  const schemas = getSchemas(uid2);
589
+ const model = strapi2.getModel(uid2);
590
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
558
591
  const localeEntries = await strapi2.db.query(uid2).findMany({
559
592
  where: {
560
593
  documentId,
561
- locale: { $in: locales },
562
- publishedAt: null
594
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
595
+ ...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
563
596
  },
564
597
  populate: serviceUtils.getDeepPopulate(
565
598
  uid2,
@@ -571,7 +604,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
571
604
  onCommit(async () => {
572
605
  for (const entry of localeEntries) {
573
606
  const status = await serviceUtils.getVersionStatus(uid2, entry);
574
- await getService(strapi2, "history").createVersion({
607
+ await getService$1(strapi2, "history").createVersion({
575
608
  contentType: uid2,
576
609
  data: fp.omit(FIELDS_TO_IGNORE, entry),
577
610
  relatedDocumentId: documentId,
@@ -584,15 +617,19 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
584
617
  });
585
618
  return result;
586
619
  });
587
- state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
620
+ state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
588
621
  const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
589
622
  const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
590
623
  strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
591
624
  where: {
592
625
  created_at: {
593
- $lt: expirationDate.toISOString()
626
+ $lt: expirationDate
594
627
  }
595
628
  }
629
+ }).catch((error) => {
630
+ if (error instanceof Error) {
631
+ strapi2.log.error("Error deleting expired history versions", error.message);
632
+ }
596
633
  });
597
634
  });
598
635
  state.isInitialized = true;
@@ -604,17 +641,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
604
641
  }
605
642
  };
606
643
  };
607
- const services$1 = {
644
+ const services$2 = {
608
645
  history: createHistoryService,
609
646
  lifecycles: createLifecyclesService
610
647
  };
611
- const info = { pluginName: "content-manager", type: "admin" };
648
+ const info$1 = { pluginName: "content-manager", type: "admin" };
612
649
  const historyVersionRouter = {
613
650
  type: "admin",
614
651
  routes: [
615
652
  {
616
653
  method: "GET",
617
- info,
654
+ info: info$1,
618
655
  path: "/history-versions",
619
656
  handler: "history-version.findMany",
620
657
  config: {
@@ -623,7 +660,7 @@ const historyVersionRouter = {
623
660
  },
624
661
  {
625
662
  method: "PUT",
626
- info,
663
+ info: info$1,
627
664
  path: "/history-versions/:versionId/restore",
628
665
  handler: "history-version.restoreVersion",
629
666
  config: {
@@ -632,7 +669,7 @@ const historyVersionRouter = {
632
669
  }
633
670
  ]
634
671
  };
635
- const routes$1 = {
672
+ const routes$2 = {
636
673
  "history-version": historyVersionRouter
637
674
  };
638
675
  const historyVersion = {
@@ -679,21 +716,21 @@ const historyVersion = {
679
716
  }
680
717
  }
681
718
  };
682
- const getFeature = () => {
719
+ const getFeature$1 = () => {
683
720
  if (strapi.ee.features.isEnabled("cms-content-history")) {
684
721
  return {
685
722
  register({ strapi: strapi2 }) {
686
723
  strapi2.get("models").add(historyVersion);
687
724
  },
688
725
  bootstrap({ strapi: strapi2 }) {
689
- getService(strapi2, "lifecycles").bootstrap();
726
+ getService$1(strapi2, "lifecycles").bootstrap();
690
727
  },
691
728
  destroy({ strapi: strapi2 }) {
692
- getService(strapi2, "lifecycles").destroy();
729
+ getService$1(strapi2, "lifecycles").destroy();
693
730
  },
694
- controllers: controllers$1,
695
- services: services$1,
696
- routes: routes$1
731
+ controllers: controllers$2,
732
+ services: services$2,
733
+ routes: routes$2
697
734
  };
698
735
  }
699
736
  return {
@@ -702,7 +739,7 @@ const getFeature = () => {
702
739
  }
703
740
  };
704
741
  };
705
- const history = getFeature();
742
+ const history = getFeature$1();
706
743
  const register = async ({ strapi: strapi2 }) => {
707
744
  await history.register?.({ strapi: strapi2 });
708
745
  };
@@ -710,15 +747,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
710
747
  ENTRY_PUBLISH: "entry.publish",
711
748
  ENTRY_UNPUBLISH: "entry.unpublish"
712
749
  };
750
+ const FEATURE_ID = "preview";
751
+ const info = { pluginName: "content-manager", type: "admin" };
752
+ const previewRouter = {
753
+ type: "admin",
754
+ routes: [
755
+ {
756
+ method: "GET",
757
+ info,
758
+ path: "/preview/url/:contentType",
759
+ handler: "preview.getPreviewUrl",
760
+ config: {
761
+ policies: ["admin::isAuthenticatedAdmin"]
762
+ }
763
+ }
764
+ ]
765
+ };
766
+ const routes$1 = {
767
+ preview: previewRouter
768
+ };
769
+ function getService(strapi2, name) {
770
+ return strapi2.service(`plugin::content-manager.${name}`);
771
+ }
772
+ const getPreviewUrlSchema = yup__namespace.object().shape({
773
+ // Will be undefined for single types
774
+ documentId: yup__namespace.string(),
775
+ locale: yup__namespace.string().nullable(),
776
+ status: yup__namespace.string()
777
+ }).required();
778
+ const validatePreviewUrl = async (strapi2, uid2, params) => {
779
+ await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
780
+ const newParams = fp.pick(["documentId", "locale", "status"], params);
781
+ const model = strapi2.getModel(uid2);
782
+ if (!model || model.modelType !== "contentType") {
783
+ throw new strapiUtils.errors.ValidationError("Invalid content type");
784
+ }
785
+ const isSingleType = model?.kind === "singleType";
786
+ if (!isSingleType && !params.documentId) {
787
+ throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
788
+ }
789
+ if (isSingleType) {
790
+ const doc = await strapi2.documents(uid2).findFirst();
791
+ if (!doc) {
792
+ throw new strapiUtils.errors.NotFoundError("Document not found");
793
+ }
794
+ newParams.documentId = doc?.documentId;
795
+ }
796
+ return newParams;
797
+ };
798
+ const createPreviewController = () => {
799
+ return {
800
+ /**
801
+ * Transforms an entry into a preview URL, so that it can be previewed
802
+ * in the Content Manager.
803
+ */
804
+ async getPreviewUrl(ctx) {
805
+ const uid2 = ctx.params.contentType;
806
+ const query = ctx.request.query;
807
+ const params = await validatePreviewUrl(strapi, uid2, query);
808
+ const previewService = getService(strapi, "preview");
809
+ const url = await previewService.getPreviewUrl(uid2, params);
810
+ if (!url) {
811
+ ctx.status = 204;
812
+ }
813
+ return {
814
+ data: { url }
815
+ };
816
+ }
817
+ };
818
+ };
819
+ const controllers$1 = {
820
+ preview: createPreviewController
821
+ /**
822
+ * Casting is needed because the types aren't aware that Strapi supports
823
+ * passing a controller factory as the value, instead of a controller object directly
824
+ */
825
+ };
826
+ const createPreviewService = ({ strapi: strapi2 }) => {
827
+ const config = getService(strapi2, "preview-config");
828
+ return {
829
+ async getPreviewUrl(uid2, params) {
830
+ const handler = config.getPreviewHandler();
831
+ try {
832
+ return handler(uid2, params);
833
+ } catch (error) {
834
+ strapi2.log.error(`Failed to get preview URL: ${error}`);
835
+ throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
836
+ }
837
+ return;
838
+ }
839
+ };
840
+ };
841
+ const createPreviewConfigService = ({ strapi: strapi2 }) => {
842
+ return {
843
+ isEnabled() {
844
+ const config = strapi2.config.get("admin.preview");
845
+ if (!config) {
846
+ return false;
847
+ }
848
+ return config?.enabled ?? true;
849
+ },
850
+ /**
851
+ * Validate if the configuration is valid
852
+ */
853
+ validate() {
854
+ if (!this.isEnabled()) {
855
+ return;
856
+ }
857
+ const handler = this.getPreviewHandler();
858
+ if (typeof handler !== "function") {
859
+ throw new strapiUtils.errors.ValidationError(
860
+ "Preview configuration is invalid. Handler must be a function"
861
+ );
862
+ }
863
+ },
864
+ /**
865
+ * Utility to get the preview handler from the configuration
866
+ */
867
+ getPreviewHandler() {
868
+ const config = strapi2.config.get("admin.preview");
869
+ const emptyHandler = () => {
870
+ return void 0;
871
+ };
872
+ if (!this.isEnabled()) {
873
+ return emptyHandler;
874
+ }
875
+ return config?.config?.handler || emptyHandler;
876
+ }
877
+ };
878
+ };
879
+ const services$1 = {
880
+ preview: createPreviewService,
881
+ "preview-config": createPreviewConfigService
882
+ };
883
+ const getFeature = () => {
884
+ if (!strapi.features.future.isEnabled(FEATURE_ID)) {
885
+ return {};
886
+ }
887
+ return {
888
+ bootstrap() {
889
+ console.log("Bootstrapping preview server");
890
+ const config = getService(strapi, "preview-config");
891
+ config.validate();
892
+ },
893
+ routes: routes$1,
894
+ controllers: controllers$1,
895
+ services: services$1
896
+ };
897
+ };
898
+ const preview = getFeature();
713
899
  const bootstrap = async () => {
714
900
  Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
715
901
  strapi.get("webhookStore").addAllowedEvent(key, value);
716
902
  });
717
- getService$1("field-sizes").setCustomFieldInputSizes();
718
- await getService$1("components").syncConfigurations();
719
- await getService$1("content-types").syncConfigurations();
720
- await getService$1("permission").registerPermissions();
903
+ getService$2("field-sizes").setCustomFieldInputSizes();
904
+ await getService$2("components").syncConfigurations();
905
+ await getService$2("content-types").syncConfigurations();
906
+ await getService$2("permission").registerPermissions();
721
907
  await history.bootstrap?.({ strapi });
908
+ await preview.bootstrap?.({ strapi });
722
909
  };
723
910
  const destroy = async ({ strapi: strapi2 }) => {
724
911
  await history.destroy?.({ strapi: strapi2 });
@@ -1208,7 +1395,8 @@ const admin = {
1208
1395
  };
1209
1396
  const routes = {
1210
1397
  admin,
1211
- ...history.routes ? history.routes : {}
1398
+ ...history.routes ? history.routes : {},
1399
+ ...preview.routes ? preview.routes : {}
1212
1400
  };
1213
1401
  const hasPermissionsSchema = strapiUtils.yup.object({
1214
1402
  actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
@@ -1219,6 +1407,11 @@ const { createPolicy } = strapiUtils.policy;
1219
1407
  const hasPermissions = createPolicy({
1220
1408
  name: "plugin::content-manager.hasPermissions",
1221
1409
  validator: validateHasPermissionsInput,
1410
+ /**
1411
+ * NOTE: Action aliases are currently not checked at this level (policy).
1412
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1413
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1414
+ */
1222
1415
  handler(ctx, config = {}) {
1223
1416
  const { actions = [], hasAtLeastOne = false } = config;
1224
1417
  const { userAbility } = ctx.state;
@@ -1460,7 +1653,7 @@ const createMetadasSchema = (schema) => {
1460
1653
  if (!value) {
1461
1654
  return strapiUtils.yup.string();
1462
1655
  }
1463
- const targetSchema = getService$1("content-types").findContentType(
1656
+ const targetSchema = getService$2("content-types").findContentType(
1464
1657
  schema.attributes[key].targetModel
1465
1658
  );
1466
1659
  if (!targetSchema) {
@@ -1629,7 +1822,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
1629
1822
  }
1630
1823
  };
1631
1824
  const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
1632
- const documentMetadata2 = getService$1("document-metadata");
1825
+ const documentMetadata2 = getService$2("document-metadata");
1633
1826
  const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
1634
1827
  let {
1635
1828
  meta: { availableLocales, availableStatus }
@@ -1655,8 +1848,8 @@ const createDocument = async (ctx, opts) => {
1655
1848
  const { userAbility, user } = ctx.state;
1656
1849
  const { model } = ctx.params;
1657
1850
  const { body } = ctx.request;
1658
- const documentManager2 = getService$1("document-manager");
1659
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1851
+ const documentManager2 = getService$2("document-manager");
1852
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1660
1853
  if (permissionChecker2.cannot.create()) {
1661
1854
  throw new strapiUtils.errors.ForbiddenError();
1662
1855
  }
@@ -1676,13 +1869,13 @@ const updateDocument = async (ctx, opts) => {
1676
1869
  const { userAbility, user } = ctx.state;
1677
1870
  const { id, model } = ctx.params;
1678
1871
  const { body } = ctx.request;
1679
- const documentManager2 = getService$1("document-manager");
1680
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1872
+ const documentManager2 = getService$2("document-manager");
1873
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1681
1874
  if (permissionChecker2.cannot.update()) {
1682
1875
  throw new strapiUtils.errors.ForbiddenError();
1683
1876
  }
1684
1877
  const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
1685
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1878
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1686
1879
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1687
1880
  const [documentVersion, documentExists] = await Promise.all([
1688
1881
  documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
@@ -1699,7 +1892,7 @@ const updateDocument = async (ctx, opts) => {
1699
1892
  throw new strapiUtils.errors.ForbiddenError();
1700
1893
  }
1701
1894
  const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
1702
- const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
1895
+ const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
1703
1896
  const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
1704
1897
  const sanitizedBody = await sanitizeFn(body);
1705
1898
  return documentManager2.update(documentVersion?.documentId || id, model, {
@@ -1713,14 +1906,14 @@ const collectionTypes = {
1713
1906
  const { userAbility } = ctx.state;
1714
1907
  const { model } = ctx.params;
1715
1908
  const { query } = ctx.request;
1716
- const documentMetadata2 = getService$1("document-metadata");
1717
- const documentManager2 = getService$1("document-manager");
1718
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1909
+ const documentMetadata2 = getService$2("document-metadata");
1910
+ const documentManager2 = getService$2("document-manager");
1911
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1719
1912
  if (permissionChecker2.cannot.read()) {
1720
1913
  return ctx.forbidden();
1721
1914
  }
1722
1915
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1723
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1916
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1724
1917
  const { locale, status } = await getDocumentLocaleAndStatus(query, model);
1725
1918
  const { results: documents, pagination } = await documentManager2.findPage(
1726
1919
  { ...permissionQuery, populate, locale, status },
@@ -1749,13 +1942,13 @@ const collectionTypes = {
1749
1942
  async findOne(ctx) {
1750
1943
  const { userAbility } = ctx.state;
1751
1944
  const { model, id } = ctx.params;
1752
- const documentManager2 = getService$1("document-manager");
1753
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1945
+ const documentManager2 = getService$2("document-manager");
1946
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1754
1947
  if (permissionChecker2.cannot.read()) {
1755
1948
  return ctx.forbidden();
1756
1949
  }
1757
1950
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
1758
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1951
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1759
1952
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
1760
1953
  const version = await documentManager2.findOne(id, model, {
1761
1954
  populate,
@@ -1771,7 +1964,7 @@ const collectionTypes = {
1771
1964
  permissionChecker2,
1772
1965
  model,
1773
1966
  // @ts-expect-error TODO: fix
1774
- { id, locale, publishedAt: null },
1967
+ { documentId: id, locale, publishedAt: null },
1775
1968
  { availableLocales: true, availableStatus: false }
1776
1969
  );
1777
1970
  ctx.body = { data: {}, meta };
@@ -1786,7 +1979,7 @@ const collectionTypes = {
1786
1979
  async create(ctx) {
1787
1980
  const { userAbility } = ctx.state;
1788
1981
  const { model } = ctx.params;
1789
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1982
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1790
1983
  const [totalEntries, document] = await Promise.all([
1791
1984
  strapi.db.query(model).count(),
1792
1985
  createDocument(ctx)
@@ -1807,7 +2000,7 @@ const collectionTypes = {
1807
2000
  async update(ctx) {
1808
2001
  const { userAbility } = ctx.state;
1809
2002
  const { model } = ctx.params;
1810
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2003
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1811
2004
  const updatedVersion = await updateDocument(ctx);
1812
2005
  const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
1813
2006
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
@@ -1816,13 +2009,13 @@ const collectionTypes = {
1816
2009
  const { userAbility, user } = ctx.state;
1817
2010
  const { model, sourceId: id } = ctx.params;
1818
2011
  const { body } = ctx.request;
1819
- const documentManager2 = getService$1("document-manager");
1820
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2012
+ const documentManager2 = getService$2("document-manager");
2013
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1821
2014
  if (permissionChecker2.cannot.create()) {
1822
2015
  return ctx.forbidden();
1823
2016
  }
1824
2017
  const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
1825
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2018
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1826
2019
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1827
2020
  const document = await documentManager2.findOne(id, model, {
1828
2021
  populate,
@@ -1861,13 +2054,13 @@ const collectionTypes = {
1861
2054
  async delete(ctx) {
1862
2055
  const { userAbility } = ctx.state;
1863
2056
  const { id, model } = ctx.params;
1864
- const documentManager2 = getService$1("document-manager");
1865
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2057
+ const documentManager2 = getService$2("document-manager");
2058
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1866
2059
  if (permissionChecker2.cannot.delete()) {
1867
2060
  return ctx.forbidden();
1868
2061
  }
1869
2062
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
1870
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2063
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
1871
2064
  const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
1872
2065
  const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
1873
2066
  if (documentLocales.length === 0) {
@@ -1889,14 +2082,14 @@ const collectionTypes = {
1889
2082
  const { userAbility } = ctx.state;
1890
2083
  const { id, model } = ctx.params;
1891
2084
  const { body } = ctx.request;
1892
- const documentManager2 = getService$1("document-manager");
1893
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2085
+ const documentManager2 = getService$2("document-manager");
2086
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1894
2087
  if (permissionChecker2.cannot.publish()) {
1895
2088
  return ctx.forbidden();
1896
2089
  }
1897
2090
  const publishedDocument = await strapi.db.transaction(async () => {
1898
2091
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1899
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2092
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1900
2093
  let document;
1901
2094
  const { locale } = await getDocumentLocaleAndStatus(body, model);
1902
2095
  const isCreate = fp.isNil(id);
@@ -1908,11 +2101,17 @@ const collectionTypes = {
1908
2101
  }
1909
2102
  const isUpdate = !isCreate;
1910
2103
  if (isUpdate) {
1911
- document = await documentManager2.findOne(id, model, { populate, locale });
1912
- if (!document) {
2104
+ const documentExists = documentManager2.exists(model, id);
2105
+ if (!documentExists) {
1913
2106
  throw new strapiUtils.errors.NotFoundError("Document not found");
1914
2107
  }
1915
- if (permissionChecker2.can.update(document)) {
2108
+ document = await documentManager2.findOne(id, model, { populate, locale });
2109
+ if (!document) {
2110
+ if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
2111
+ throw new strapiUtils.errors.ForbiddenError();
2112
+ }
2113
+ document = await updateDocument(ctx);
2114
+ } else if (permissionChecker2.can.update(document)) {
1916
2115
  await updateDocument(ctx);
1917
2116
  }
1918
2117
  }
@@ -1938,13 +2137,13 @@ const collectionTypes = {
1938
2137
  const { body } = ctx.request;
1939
2138
  const { documentIds } = body;
1940
2139
  await validateBulkActionInput(body);
1941
- const documentManager2 = getService$1("document-manager");
1942
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2140
+ const documentManager2 = getService$2("document-manager");
2141
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1943
2142
  if (permissionChecker2.cannot.publish()) {
1944
2143
  return ctx.forbidden();
1945
2144
  }
1946
2145
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1947
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
2146
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1948
2147
  const { locale } = await getDocumentLocaleAndStatus(body, model, {
1949
2148
  allowMultipleLocales: true
1950
2149
  });
@@ -1969,12 +2168,14 @@ const collectionTypes = {
1969
2168
  const { body } = ctx.request;
1970
2169
  const { documentIds } = body;
1971
2170
  await validateBulkActionInput(body);
1972
- const documentManager2 = getService$1("document-manager");
1973
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2171
+ const documentManager2 = getService$2("document-manager");
2172
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
1974
2173
  if (permissionChecker2.cannot.unpublish()) {
1975
2174
  return ctx.forbidden();
1976
2175
  }
1977
- const { locale } = await getDocumentLocaleAndStatus(body, model);
2176
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
2177
+ allowMultipleLocales: true
2178
+ });
1978
2179
  const entityPromises = documentIds.map(
1979
2180
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1980
2181
  );
@@ -1997,8 +2198,8 @@ const collectionTypes = {
1997
2198
  const {
1998
2199
  body: { discardDraft, ...body }
1999
2200
  } = ctx.request;
2000
- const documentManager2 = getService$1("document-manager");
2001
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2201
+ const documentManager2 = getService$2("document-manager");
2202
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2002
2203
  if (permissionChecker2.cannot.unpublish()) {
2003
2204
  return ctx.forbidden();
2004
2205
  }
@@ -2006,7 +2207,7 @@ const collectionTypes = {
2006
2207
  return ctx.forbidden();
2007
2208
  }
2008
2209
  const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
2009
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2210
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2010
2211
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2011
2212
  const document = await documentManager2.findOne(id, model, {
2012
2213
  populate,
@@ -2037,13 +2238,13 @@ const collectionTypes = {
2037
2238
  const { userAbility } = ctx.state;
2038
2239
  const { id, model } = ctx.params;
2039
2240
  const { body } = ctx.request;
2040
- const documentManager2 = getService$1("document-manager");
2041
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2241
+ const documentManager2 = getService$2("document-manager");
2242
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2042
2243
  if (permissionChecker2.cannot.discard()) {
2043
2244
  return ctx.forbidden();
2044
2245
  }
2045
2246
  const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
2046
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2247
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2047
2248
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2048
2249
  const document = await documentManager2.findOne(id, model, {
2049
2250
  populate,
@@ -2068,13 +2269,13 @@ const collectionTypes = {
2068
2269
  const { query, body } = ctx.request;
2069
2270
  const { documentIds } = body;
2070
2271
  await validateBulkActionInput(body);
2071
- const documentManager2 = getService$1("document-manager");
2072
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2272
+ const documentManager2 = getService$2("document-manager");
2273
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2073
2274
  if (permissionChecker2.cannot.delete()) {
2074
2275
  return ctx.forbidden();
2075
2276
  }
2076
2277
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
2077
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2278
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2078
2279
  const { locale } = await getDocumentLocaleAndStatus(body, model);
2079
2280
  const documentLocales = await documentManager2.findLocales(documentIds, model, {
2080
2281
  populate,
@@ -2095,13 +2296,13 @@ const collectionTypes = {
2095
2296
  async countDraftRelations(ctx) {
2096
2297
  const { userAbility } = ctx.state;
2097
2298
  const { model, id } = ctx.params;
2098
- const documentManager2 = getService$1("document-manager");
2099
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2299
+ const documentManager2 = getService$2("document-manager");
2300
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2100
2301
  if (permissionChecker2.cannot.read()) {
2101
2302
  return ctx.forbidden();
2102
2303
  }
2103
2304
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2104
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2305
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2105
2306
  const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
2106
2307
  const entity = await documentManager2.findOne(id, model, { populate, locale, status });
2107
2308
  if (!entity) {
@@ -2120,8 +2321,8 @@ const collectionTypes = {
2120
2321
  const ids = ctx.request.query.documentIds;
2121
2322
  const locale = ctx.request.query.locale;
2122
2323
  const { model } = ctx.params;
2123
- const documentManager2 = getService$1("document-manager");
2124
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2324
+ const documentManager2 = getService$2("document-manager");
2325
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2125
2326
  if (permissionChecker2.cannot.read()) {
2126
2327
  return ctx.forbidden();
2127
2328
  }
@@ -2145,13 +2346,13 @@ const collectionTypes = {
2145
2346
  };
2146
2347
  const components$1 = {
2147
2348
  findComponents(ctx) {
2148
- const components2 = getService$1("components").findAllComponents();
2149
- const { toDto } = getService$1("data-mapper");
2349
+ const components2 = getService$2("components").findAllComponents();
2350
+ const { toDto } = getService$2("data-mapper");
2150
2351
  ctx.body = { data: components2.map(toDto) };
2151
2352
  },
2152
2353
  async findComponentConfiguration(ctx) {
2153
2354
  const { uid: uid2 } = ctx.params;
2154
- const componentService = getService$1("components");
2355
+ const componentService = getService$2("components");
2155
2356
  const component = componentService.findComponent(uid2);
2156
2357
  if (!component) {
2157
2358
  return ctx.notFound("component.notFound");
@@ -2168,7 +2369,7 @@ const components$1 = {
2168
2369
  async updateComponentConfiguration(ctx) {
2169
2370
  const { uid: uid2 } = ctx.params;
2170
2371
  const { body } = ctx.request;
2171
- const componentService = getService$1("components");
2372
+ const componentService = getService$2("components");
2172
2373
  const component = componentService.findComponent(uid2);
2173
2374
  if (!component) {
2174
2375
  return ctx.notFound("component.notFound");
@@ -2202,12 +2403,12 @@ const contentTypes = {
2202
2403
  } catch (error) {
2203
2404
  return ctx.send({ error }, 400);
2204
2405
  }
2205
- const contentTypes2 = getService$1("content-types").findContentTypesByKind(kind);
2206
- const { toDto } = getService$1("data-mapper");
2406
+ const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
2407
+ const { toDto } = getService$2("data-mapper");
2207
2408
  ctx.body = { data: contentTypes2.map(toDto) };
2208
2409
  },
2209
2410
  async findContentTypesSettings(ctx) {
2210
- const { findAllContentTypes, findConfiguration } = getService$1("content-types");
2411
+ const { findAllContentTypes, findConfiguration } = getService$2("content-types");
2211
2412
  const contentTypes2 = await findAllContentTypes();
2212
2413
  const configurations = await Promise.all(
2213
2414
  contentTypes2.map(async (contentType) => {
@@ -2221,7 +2422,7 @@ const contentTypes = {
2221
2422
  },
2222
2423
  async findContentTypeConfiguration(ctx) {
2223
2424
  const { uid: uid2 } = ctx.params;
2224
- const contentTypeService = getService$1("content-types");
2425
+ const contentTypeService = getService$2("content-types");
2225
2426
  const contentType = await contentTypeService.findContentType(uid2);
2226
2427
  if (!contentType) {
2227
2428
  return ctx.notFound("contentType.notFound");
@@ -2243,13 +2444,13 @@ const contentTypes = {
2243
2444
  const { userAbility } = ctx.state;
2244
2445
  const { uid: uid2 } = ctx.params;
2245
2446
  const { body } = ctx.request;
2246
- const contentTypeService = getService$1("content-types");
2247
- const metricsService = getService$1("metrics");
2447
+ const contentTypeService = getService$2("content-types");
2448
+ const metricsService = getService$2("metrics");
2248
2449
  const contentType = await contentTypeService.findContentType(uid2);
2249
2450
  if (!contentType) {
2250
2451
  return ctx.notFound("contentType.notFound");
2251
2452
  }
2252
- if (!getService$1("permission").canConfigureContentType({ userAbility, contentType })) {
2453
+ if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
2253
2454
  return ctx.forbidden();
2254
2455
  }
2255
2456
  let input;
@@ -2282,10 +2483,10 @@ const contentTypes = {
2282
2483
  };
2283
2484
  const init = {
2284
2485
  getInitData(ctx) {
2285
- const { toDto } = getService$1("data-mapper");
2286
- const { findAllComponents } = getService$1("components");
2287
- const { getAllFieldSizes } = getService$1("field-sizes");
2288
- const { findAllContentTypes } = getService$1("content-types");
2486
+ const { toDto } = getService$2("data-mapper");
2487
+ const { findAllComponents } = getService$2("components");
2488
+ const { getAllFieldSizes } = getService$2("field-sizes");
2489
+ const { findAllContentTypes } = getService$2("content-types");
2289
2490
  ctx.body = {
2290
2491
  data: {
2291
2492
  fieldSizes: getAllFieldSizes(),
@@ -2321,36 +2522,41 @@ const addFiltersClause = (params, filtersClause) => {
2321
2522
  params.filters.$and.push(filtersClause);
2322
2523
  };
2323
2524
  const sanitizeMainField = (model, mainField, userAbility) => {
2324
- const permissionChecker2 = getService$1("permission-checker").create({
2525
+ const permissionChecker2 = getService$2("permission-checker").create({
2325
2526
  userAbility,
2326
2527
  model: model.uid
2327
2528
  });
2328
- if (!isListable(model, mainField)) {
2529
+ const isMainFieldListable = isListable(model, mainField);
2530
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2531
+ if (!isMainFieldListable || !canReadMainField) {
2329
2532
  return "id";
2330
2533
  }
2331
- if (permissionChecker2.cannot.read(null, mainField)) {
2332
- if (model.uid === "plugin::users-permissions.role") {
2333
- const userPermissionChecker = getService$1("permission-checker").create({
2334
- userAbility,
2335
- model: "plugin::users-permissions.user"
2336
- });
2337
- if (userPermissionChecker.can.read()) {
2338
- return "name";
2339
- }
2340
- }
2341
- return "id";
2534
+ if (model.uid === "plugin::users-permissions.role") {
2535
+ return "name";
2342
2536
  }
2343
2537
  return mainField;
2344
2538
  };
2345
- const addStatusToRelations = async (uid2, relations2) => {
2346
- if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.contentTypes[uid2])) {
2539
+ const addStatusToRelations = async (targetUid, relations2) => {
2540
+ if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
2347
2541
  return relations2;
2348
2542
  }
2349
- const documentMetadata2 = getService$1("document-metadata");
2350
- const documentsAvailableStatus = await documentMetadata2.getManyAvailableStatus(uid2, relations2);
2543
+ const documentMetadata2 = getService$2("document-metadata");
2544
+ if (!relations2.length) {
2545
+ return relations2;
2546
+ }
2547
+ const firstRelation = relations2[0];
2548
+ const filters = {
2549
+ documentId: { $in: relations2.map((r) => r.documentId) },
2550
+ // NOTE: find the "opposite" status
2551
+ publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
2552
+ };
2553
+ const availableStatus = await strapi.query(targetUid).findMany({
2554
+ select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
2555
+ filters
2556
+ });
2351
2557
  return relations2.map((relation) => {
2352
- const availableStatuses = documentsAvailableStatus.filter(
2353
- (availableDocument) => availableDocument.documentId === relation.documentId
2558
+ const availableStatuses = availableStatus.filter(
2559
+ (availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
2354
2560
  );
2355
2561
  return {
2356
2562
  ...relation,
@@ -2371,11 +2577,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
2371
2577
  const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
2372
2578
  const isSourceLocalized = isLocalized(sourceModel);
2373
2579
  const isTargetLocalized = isLocalized(targetModel);
2374
- let validatedLocale = locale;
2375
- if (!targetModel || !isTargetLocalized)
2376
- validatedLocale = void 0;
2377
2580
  return {
2378
- locale: validatedLocale,
2581
+ locale,
2379
2582
  isSourceLocalized,
2380
2583
  isTargetLocalized
2381
2584
  };
@@ -2415,7 +2618,7 @@ const relations = {
2415
2618
  ctx.request?.query?.locale
2416
2619
  );
2417
2620
  const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
2418
- const permissionChecker2 = getService$1("permission-checker").create({
2621
+ const permissionChecker2 = getService$2("permission-checker").create({
2419
2622
  userAbility,
2420
2623
  model
2421
2624
  });
@@ -2440,7 +2643,7 @@ const relations = {
2440
2643
  where.id = id;
2441
2644
  }
2442
2645
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
2443
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
2646
+ const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
2444
2647
  const currentEntity = await strapi.db.query(model).findOne({
2445
2648
  where,
2446
2649
  populate
@@ -2455,7 +2658,7 @@ const relations = {
2455
2658
  }
2456
2659
  entryId = currentEntity.id;
2457
2660
  }
2458
- const modelConfig = isComponent2 ? await getService$1("components").findConfiguration(sourceSchema) : await getService$1("content-types").findConfiguration(sourceSchema);
2661
+ const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
2459
2662
  const targetSchema = strapi.getModel(targetUid);
2460
2663
  const mainField = fp.flow(
2461
2664
  fp.prop(`metadatas.${targetField}.edit.mainField`),
@@ -2478,7 +2681,7 @@ const relations = {
2478
2681
  attribute,
2479
2682
  fieldsToSelect,
2480
2683
  mainField,
2481
- source: { schema: sourceSchema },
2684
+ source: { schema: sourceSchema, isLocalized: isSourceLocalized },
2482
2685
  target: { schema: targetSchema, isLocalized: isTargetLocalized },
2483
2686
  sourceSchema,
2484
2687
  targetSchema,
@@ -2500,7 +2703,8 @@ const relations = {
2500
2703
  fieldsToSelect,
2501
2704
  mainField,
2502
2705
  source: {
2503
- schema: { uid: sourceUid, modelType: sourceModelType }
2706
+ schema: { uid: sourceUid, modelType: sourceModelType },
2707
+ isLocalized: isSourceLocalized
2504
2708
  },
2505
2709
  target: {
2506
2710
  schema: { uid: targetUid },
@@ -2508,7 +2712,7 @@ const relations = {
2508
2712
  }
2509
2713
  } = await this.extractAndValidateRequestInfo(ctx, id);
2510
2714
  const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
2511
- const permissionChecker2 = getService$1("permission-checker").create({
2715
+ const permissionChecker2 = getService$2("permission-checker").create({
2512
2716
  userAbility: ctx.state.userAbility,
2513
2717
  model: targetUid
2514
2718
  });
@@ -2538,12 +2742,16 @@ const relations = {
2538
2742
  } else {
2539
2743
  where.id = id;
2540
2744
  }
2541
- if (status) {
2542
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2745
+ const publishedAt = getPublishedAtClause(status, targetUid);
2746
+ if (!fp.isEmpty(publishedAt)) {
2747
+ where[`${alias}.published_at`] = publishedAt;
2543
2748
  }
2544
- if (filterByLocale) {
2749
+ if (isTargetLocalized && locale) {
2545
2750
  where[`${alias}.locale`] = locale;
2546
2751
  }
2752
+ if (isSourceLocalized && locale) {
2753
+ where.locale = locale;
2754
+ }
2547
2755
  if ((idsToInclude?.length ?? 0) !== 0) {
2548
2756
  where[`${alias}.id`].$notIn = idsToInclude;
2549
2757
  }
@@ -2561,7 +2769,8 @@ const relations = {
2561
2769
  id: { $notIn: fp.uniq(idsToOmit) }
2562
2770
  });
2563
2771
  }
2564
- const res = await strapi.db.query(targetUid).findPage(strapi.get("query-params").transform(targetUid, queryParams));
2772
+ const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
2773
+ const res = await strapi.db.query(targetUid).findPage(dbQuery);
2565
2774
  ctx.body = {
2566
2775
  ...res,
2567
2776
  results: await addStatusToRelations(targetUid, res.results)
@@ -2576,29 +2785,39 @@ const relations = {
2576
2785
  attribute,
2577
2786
  targetField,
2578
2787
  fieldsToSelect,
2579
- source: {
2580
- schema: { uid: sourceUid }
2581
- },
2582
- target: {
2583
- schema: { uid: targetUid }
2584
- }
2788
+ status,
2789
+ source: { schema: sourceSchema },
2790
+ target: { schema: targetSchema }
2585
2791
  } = await this.extractAndValidateRequestInfo(ctx, id);
2586
- const permissionQuery = await getService$1("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2792
+ const { uid: sourceUid } = sourceSchema;
2793
+ const { uid: targetUid } = targetSchema;
2794
+ const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
2587
2795
  const dbQuery = strapi.db.query(sourceUid);
2588
2796
  const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
2797
+ const filters = {};
2798
+ if (sourceSchema?.options?.draftAndPublish) {
2799
+ if (targetSchema?.options?.draftAndPublish) {
2800
+ if (status === "published") {
2801
+ filters.publishedAt = { $notNull: true };
2802
+ } else {
2803
+ filters.publishedAt = { $null: true };
2804
+ }
2805
+ }
2806
+ } else if (targetSchema?.options?.draftAndPublish) {
2807
+ filters.publishedAt = { $null: true };
2808
+ }
2589
2809
  const res = await loadRelations({ id: entryId }, targetField, {
2590
- select: ["id", "documentId", "locale", "publishedAt"],
2810
+ select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
2591
2811
  ordering: "desc",
2592
2812
  page: ctx.request.query.page,
2593
- pageSize: ctx.request.query.pageSize
2813
+ pageSize: ctx.request.query.pageSize,
2814
+ filters
2594
2815
  });
2595
2816
  const loadedIds = res.results.map((item) => item.id);
2596
2817
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2597
2818
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2598
2819
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2599
- ordering: "desc",
2600
- page: ctx.request.query.page,
2601
- pageSize: ctx.request.query.pageSize
2820
+ ordering: "desc"
2602
2821
  });
2603
2822
  const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
2604
2823
  ctx.body = {
@@ -2613,10 +2832,10 @@ const relations = {
2613
2832
  }
2614
2833
  };
2615
2834
  const buildPopulateFromQuery = async (query, model) => {
2616
- return getService$1("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2835
+ return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
2617
2836
  };
2618
2837
  const findDocument = async (query, uid2, opts = {}) => {
2619
- const documentManager2 = getService$1("document-manager");
2838
+ const documentManager2 = getService$2("document-manager");
2620
2839
  const populate = await buildPopulateFromQuery(query, uid2);
2621
2840
  return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
2622
2841
  };
@@ -2624,8 +2843,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
2624
2843
  const { user, userAbility } = ctx.state;
2625
2844
  const { model } = ctx.params;
2626
2845
  const { body, query } = ctx.request;
2627
- const documentManager2 = getService$1("document-manager");
2628
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2846
+ const documentManager2 = getService$2("document-manager");
2847
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2629
2848
  if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
2630
2849
  throw new strapiUtils.errors.ForbiddenError();
2631
2850
  }
@@ -2666,7 +2885,7 @@ const singleTypes = {
2666
2885
  const { userAbility } = ctx.state;
2667
2886
  const { model } = ctx.params;
2668
2887
  const { query = {} } = ctx.request;
2669
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2888
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2670
2889
  if (permissionChecker2.cannot.read()) {
2671
2890
  return ctx.forbidden();
2672
2891
  }
@@ -2685,7 +2904,7 @@ const singleTypes = {
2685
2904
  permissionChecker2,
2686
2905
  model,
2687
2906
  // @ts-expect-error - fix types
2688
- { id: document.documentId, locale, publishedAt: null },
2907
+ { documentId: document.documentId, locale, publishedAt: null },
2689
2908
  { availableLocales: true, availableStatus: false }
2690
2909
  );
2691
2910
  ctx.body = { data: {}, meta };
@@ -2700,7 +2919,7 @@ const singleTypes = {
2700
2919
  async createOrUpdate(ctx) {
2701
2920
  const { userAbility } = ctx.state;
2702
2921
  const { model } = ctx.params;
2703
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2922
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2704
2923
  const document = await createOrUpdateDocument(ctx);
2705
2924
  const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
2706
2925
  ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
@@ -2709,8 +2928,8 @@ const singleTypes = {
2709
2928
  const { userAbility } = ctx.state;
2710
2929
  const { model } = ctx.params;
2711
2930
  const { query = {} } = ctx.request;
2712
- const documentManager2 = getService$1("document-manager");
2713
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2931
+ const documentManager2 = getService$2("document-manager");
2932
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2714
2933
  if (permissionChecker2.cannot.delete()) {
2715
2934
  return ctx.forbidden();
2716
2935
  }
@@ -2738,8 +2957,8 @@ const singleTypes = {
2738
2957
  const { userAbility } = ctx.state;
2739
2958
  const { model } = ctx.params;
2740
2959
  const { query = {} } = ctx.request;
2741
- const documentManager2 = getService$1("document-manager");
2742
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2960
+ const documentManager2 = getService$2("document-manager");
2961
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2743
2962
  if (permissionChecker2.cannot.publish()) {
2744
2963
  return ctx.forbidden();
2745
2964
  }
@@ -2767,8 +2986,8 @@ const singleTypes = {
2767
2986
  body: { discardDraft, ...body },
2768
2987
  query = {}
2769
2988
  } = ctx.request;
2770
- const documentManager2 = getService$1("document-manager");
2771
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
2989
+ const documentManager2 = getService$2("document-manager");
2990
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2772
2991
  if (permissionChecker2.cannot.unpublish()) {
2773
2992
  return ctx.forbidden();
2774
2993
  }
@@ -2802,8 +3021,8 @@ const singleTypes = {
2802
3021
  const { userAbility } = ctx.state;
2803
3022
  const { model } = ctx.params;
2804
3023
  const { body, query = {} } = ctx.request;
2805
- const documentManager2 = getService$1("document-manager");
2806
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3024
+ const documentManager2 = getService$2("document-manager");
3025
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2807
3026
  if (permissionChecker2.cannot.discard()) {
2808
3027
  return ctx.forbidden();
2809
3028
  }
@@ -2826,8 +3045,8 @@ const singleTypes = {
2826
3045
  const { userAbility } = ctx.state;
2827
3046
  const { model } = ctx.params;
2828
3047
  const { query } = ctx.request;
2829
- const documentManager2 = getService$1("document-manager");
2830
- const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
3048
+ const documentManager2 = getService$2("document-manager");
3049
+ const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
2831
3050
  const { locale } = await getDocumentLocaleAndStatus(query, model);
2832
3051
  if (permissionChecker2.cannot.read()) {
2833
3052
  return ctx.forbidden();
@@ -2851,7 +3070,7 @@ const uid$1 = {
2851
3070
  const { query = {} } = ctx.request;
2852
3071
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2853
3072
  await validateUIDField(contentTypeUID, field);
2854
- const uidService = getService$1("uid");
3073
+ const uidService = getService$2("uid");
2855
3074
  ctx.body = {
2856
3075
  data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
2857
3076
  };
@@ -2863,7 +3082,7 @@ const uid$1 = {
2863
3082
  const { query = {} } = ctx.request;
2864
3083
  const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
2865
3084
  await validateUIDField(contentTypeUID, field);
2866
- const uidService = getService$1("uid");
3085
+ const uidService = getService$2("uid");
2867
3086
  const isAvailable = await uidService.checkUIDAvailability({
2868
3087
  contentTypeUID,
2869
3088
  field,
@@ -2884,7 +3103,8 @@ const controllers = {
2884
3103
  relations,
2885
3104
  "single-types": singleTypes,
2886
3105
  uid: uid$1,
2887
- ...history.controllers ? history.controllers : {}
3106
+ ...history.controllers ? history.controllers : {},
3107
+ ...preview.controllers ? preview.controllers : {}
2888
3108
  };
2889
3109
  const keys = {
2890
3110
  CONFIGURATION: "configuration"
@@ -3035,12 +3255,12 @@ async function syncMetadatas(configuration, schema) {
3035
3255
  return ___default.default.assign(metasWithDefaults, updatedMetas);
3036
3256
  }
3037
3257
  const getTargetSchema = (targetModel) => {
3038
- return getService$1("content-types").findContentType(targetModel);
3258
+ return getService$2("content-types").findContentType(targetModel);
3039
3259
  };
3040
3260
  const DEFAULT_LIST_LENGTH = 4;
3041
3261
  const MAX_ROW_SIZE = 12;
3042
3262
  const isAllowedFieldSize = (type, size) => {
3043
- const { getFieldSize } = getService$1("field-sizes");
3263
+ const { getFieldSize } = getService$2("field-sizes");
3044
3264
  const fieldSize = getFieldSize(type);
3045
3265
  if (!fieldSize.isResizable && size !== fieldSize.default) {
3046
3266
  return false;
@@ -3048,7 +3268,7 @@ const isAllowedFieldSize = (type, size) => {
3048
3268
  return size <= MAX_ROW_SIZE;
3049
3269
  };
3050
3270
  const getDefaultFieldSize = (attribute) => {
3051
- const { hasFieldSize, getFieldSize } = getService$1("field-sizes");
3271
+ const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
3052
3272
  return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
3053
3273
  };
3054
3274
  async function createDefaultLayouts(schema) {
@@ -3083,7 +3303,7 @@ function syncLayouts(configuration, schema) {
3083
3303
  for (const el of row) {
3084
3304
  if (!hasEditableAttribute(schema, el.name))
3085
3305
  continue;
3086
- const { hasFieldSize } = getService$1("field-sizes");
3306
+ const { hasFieldSize } = getService$2("field-sizes");
3087
3307
  const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
3088
3308
  if (!isAllowedFieldSize(fieldType, el.size)) {
3089
3309
  elementsToReAppend.push(el.name);
@@ -3223,17 +3443,17 @@ const configurationService$1 = createConfigurationService({
3223
3443
  isComponent: true,
3224
3444
  prefix: STORE_KEY_PREFIX,
3225
3445
  getModels() {
3226
- const { toContentManagerModel } = getService$1("data-mapper");
3446
+ const { toContentManagerModel } = getService$2("data-mapper");
3227
3447
  return fp.mapValues(toContentManagerModel, strapi.components);
3228
3448
  }
3229
3449
  });
3230
3450
  const components = ({ strapi: strapi2 }) => ({
3231
3451
  findAllComponents() {
3232
- const { toContentManagerModel } = getService$1("data-mapper");
3452
+ const { toContentManagerModel } = getService$2("data-mapper");
3233
3453
  return Object.values(strapi2.components).map(toContentManagerModel);
3234
3454
  },
3235
3455
  findComponent(uid2) {
3236
- const { toContentManagerModel } = getService$1("data-mapper");
3456
+ const { toContentManagerModel } = getService$2("data-mapper");
3237
3457
  const component = strapi2.components[uid2];
3238
3458
  return fp.isNil(component) ? component : toContentManagerModel(component);
3239
3459
  },
@@ -3284,17 +3504,17 @@ const configurationService = createConfigurationService({
3284
3504
  storeUtils,
3285
3505
  prefix: "content_types",
3286
3506
  getModels() {
3287
- const { toContentManagerModel } = getService$1("data-mapper");
3507
+ const { toContentManagerModel } = getService$2("data-mapper");
3288
3508
  return fp.mapValues(toContentManagerModel, strapi.contentTypes);
3289
3509
  }
3290
3510
  });
3291
3511
  const service = ({ strapi: strapi2 }) => ({
3292
3512
  findAllContentTypes() {
3293
- const { toContentManagerModel } = getService$1("data-mapper");
3513
+ const { toContentManagerModel } = getService$2("data-mapper");
3294
3514
  return Object.values(strapi2.contentTypes).map(toContentManagerModel);
3295
3515
  },
3296
3516
  findContentType(uid2) {
3297
- const { toContentManagerModel } = getService$1("data-mapper");
3517
+ const { toContentManagerModel } = getService$2("data-mapper");
3298
3518
  const contentType = strapi2.contentTypes[uid2];
3299
3519
  return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
3300
3520
  },
@@ -3323,7 +3543,7 @@ const service = ({ strapi: strapi2 }) => ({
3323
3543
  return this.findConfiguration(contentType);
3324
3544
  },
3325
3545
  findComponentsConfigurations(contentType) {
3326
- return getService$1("components").findComponentsConfigurations(contentType);
3546
+ return getService$2("components").findComponentsConfigurations(contentType);
3327
3547
  },
3328
3548
  syncConfigurations() {
3329
3549
  return configurationService.syncConfigurations();
@@ -3504,12 +3724,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3504
3724
  ability: userAbility,
3505
3725
  model
3506
3726
  });
3507
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3727
+ const { actionProvider } = strapi2.service("admin::permission");
3728
+ const toSubject = (entity) => {
3729
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3730
+ };
3508
3731
  const can = (action, entity, field) => {
3509
- return userAbility.can(action, toSubject(entity), field);
3732
+ const subject = toSubject(entity);
3733
+ const aliases = actionProvider.unstable_aliases(action, model);
3734
+ return (
3735
+ // Test the original action to see if it passes
3736
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3737
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3738
+ );
3510
3739
  };
3511
3740
  const cannot = (action, entity, field) => {
3512
- return userAbility.cannot(action, toSubject(entity), field);
3741
+ const subject = toSubject(entity);
3742
+ const aliases = actionProvider.unstable_aliases(action, model);
3743
+ return (
3744
+ // Test both the original action
3745
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3746
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3747
+ );
3513
3748
  };
3514
3749
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3515
3750
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -3580,7 +3815,7 @@ const permission = ({ strapi: strapi2 }) => ({
3580
3815
  return userAbility.can(action);
3581
3816
  },
3582
3817
  async registerPermissions() {
3583
- const displayedContentTypes = getService$1("content-types").findDisplayedContentTypes();
3818
+ const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
3584
3819
  const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
3585
3820
  const actions = [
3586
3821
  {
@@ -3856,7 +4091,7 @@ const getQueryPopulate = async (uid2, query) => {
3856
4091
  return populateQuery;
3857
4092
  };
3858
4093
  const buildDeepPopulate = (uid2) => {
3859
- return getService$1("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
4094
+ return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
3860
4095
  };
3861
4096
  const populateBuilder = (uid2) => {
3862
4097
  let getInitialPopulate = async () => {
@@ -4041,7 +4276,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4041
4276
  */
4042
4277
  async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
4043
4278
  const versionsByLocale = fp.groupBy("locale", allVersions);
4044
- delete versionsByLocale[version.locale];
4279
+ if (version.locale) {
4280
+ delete versionsByLocale[version.locale];
4281
+ }
4045
4282
  const model = strapi2.getModel(uid2);
4046
4283
  const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
4047
4284
  const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
@@ -4397,7 +4634,8 @@ const services = {
4397
4634
  permission,
4398
4635
  "populate-builder": populateBuilder$1,
4399
4636
  uid,
4400
- ...history.services ? history.services : {}
4637
+ ...history.services ? history.services : {},
4638
+ ...preview.services ? preview.services : {}
4401
4639
  };
4402
4640
  const index = () => {
4403
4641
  return {