@strapi/content-manager 5.0.0-rc.2 → 5.0.0-rc.21

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 (116) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-Bv-IXOYu.js → ComponentConfigurationPage-DnnZJc1F.js} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-Bv-IXOYu.js.map → ComponentConfigurationPage-DnnZJc1F.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BxJCkKZV.mjs → ComponentConfigurationPage-hLMNf7KI.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-BxJCkKZV.mjs.map → ComponentConfigurationPage-hLMNf7KI.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-QZl5zOz-.js → EditConfigurationPage-CpLj5gYZ.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-QZl5zOz-.js.map → EditConfigurationPage-CpLj5gYZ.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-BGwHNypQ.mjs → EditConfigurationPage-Dh6sq-G4.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-BGwHNypQ.mjs.map → EditConfigurationPage-Dh6sq-G4.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-CtdtssrH.mjs → EditViewPage-BU1ugeVi.mjs} +19 -8
  10. package/dist/_chunks/EditViewPage-BU1ugeVi.mjs.map +1 -0
  11. package/dist/_chunks/{EditViewPage-DxKueadW.js → EditViewPage-D2QVRr_2.js} +19 -8
  12. package/dist/_chunks/EditViewPage-D2QVRr_2.js.map +1 -0
  13. package/dist/_chunks/{Field-BPw8fE3W.js → Field-BEDX9i_V.js} +120 -92
  14. package/dist/_chunks/Field-BEDX9i_V.js.map +1 -0
  15. package/dist/_chunks/{Field-BU7_nR4F.mjs → Field-VSPY6uzs.mjs} +118 -90
  16. package/dist/_chunks/Field-VSPY6uzs.mjs.map +1 -0
  17. package/dist/_chunks/{Form-ffghBTPI.mjs → Form-05Oaes1N.mjs} +35 -16
  18. package/dist/_chunks/Form-05Oaes1N.mjs.map +1 -0
  19. package/dist/_chunks/{Form-DtvmbGdZ.js → Form-DCaY8xBX.js} +35 -16
  20. package/dist/_chunks/Form-DCaY8xBX.js.map +1 -0
  21. package/dist/_chunks/{History-D6PRyNcx.mjs → History-BqO2G3MV.mjs} +4 -4
  22. package/dist/_chunks/{History-D6PRyNcx.mjs.map → History-BqO2G3MV.mjs.map} +1 -1
  23. package/dist/_chunks/{History-CSr8y9KM.js → History-BrJ1tUvt.js} +4 -4
  24. package/dist/_chunks/{History-CSr8y9KM.js.map → History-BrJ1tUvt.js.map} +1 -1
  25. package/dist/_chunks/{ListConfigurationPage-BC9bCi9k.mjs → ListConfigurationPage-C6rsFlme.mjs} +14 -4
  26. package/dist/_chunks/ListConfigurationPage-C6rsFlme.mjs.map +1 -0
  27. package/dist/_chunks/{ListConfigurationPage-DsmAQ3YM.js → ListConfigurationPage-Eane5LKE.js} +14 -4
  28. package/dist/_chunks/ListConfigurationPage-Eane5LKE.js.map +1 -0
  29. package/dist/_chunks/{ListViewPage-DqAIb_ie.js → ListViewPage-Coj-RPsx.js} +49 -40
  30. package/dist/_chunks/ListViewPage-Coj-RPsx.js.map +1 -0
  31. package/dist/_chunks/{ListViewPage-B1GyNqfn.mjs → ListViewPage-yE_zYhcI.mjs} +47 -38
  32. package/dist/_chunks/ListViewPage-yE_zYhcI.mjs.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-xjvn5XwY.js → NoContentTypePage-BDJ0dshy.js} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-xjvn5XwY.js.map → NoContentTypePage-BDJ0dshy.js.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-CJ-HJriz.mjs → NoContentTypePage-NW_FSVdY.mjs} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-CJ-HJriz.mjs.map → NoContentTypePage-NW_FSVdY.mjs.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-DObTkKmZ.js → NoPermissionsPage-BOtb5FTM.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-DObTkKmZ.js.map → NoPermissionsPage-BOtb5FTM.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage--afHbbbD.mjs → NoPermissionsPage-h0I3ImsX.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage--afHbbbD.mjs.map → NoPermissionsPage-h0I3ImsX.mjs.map} +1 -1
  41. package/dist/_chunks/{Relations-t4Q0DpqW.js → Relations-CVh0DOKv.js} +4 -4
  42. package/dist/_chunks/{Relations-t4Q0DpqW.js.map → Relations-CVh0DOKv.js.map} +1 -1
  43. package/dist/_chunks/{Relations-heq-nLGU.mjs → Relations-FP0uWpBz.mjs} +4 -4
  44. package/dist/_chunks/{Relations-heq-nLGU.mjs.map → Relations-FP0uWpBz.mjs.map} +1 -1
  45. package/dist/_chunks/{en-uOUIxfcQ.js → en-BlhnxQfj.js} +7 -6
  46. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BlhnxQfj.js.map} +1 -1
  47. package/dist/_chunks/{en-BrCTWlZv.mjs → en-C8YBvRrK.mjs} +7 -6
  48. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-C8YBvRrK.mjs.map} +1 -1
  49. package/dist/_chunks/{index-BcQ8cRyl.mjs → index-CPCHQ3X_.mjs} +1927 -1765
  50. package/dist/_chunks/index-CPCHQ3X_.mjs.map +1 -0
  51. package/dist/_chunks/{index-1zxclxo_.js → index-DTKVhcla.js} +1907 -1745
  52. package/dist/_chunks/index-DTKVhcla.js.map +1 -0
  53. package/dist/_chunks/{layout-Jl9mJFJZ.mjs → layout-B4UhJ8MJ.mjs} +22 -9
  54. package/dist/_chunks/layout-B4UhJ8MJ.mjs.map +1 -0
  55. package/dist/_chunks/{layout-tVvbqota.js → layout-CWgZzMYf.js} +21 -8
  56. package/dist/_chunks/layout-CWgZzMYf.js.map +1 -0
  57. package/dist/_chunks/{relations-f4Pv7Kgo.mjs → relations-B83Ge9a7.mjs} +2 -2
  58. package/dist/_chunks/{relations-f4Pv7Kgo.mjs.map → relations-B83Ge9a7.mjs.map} +1 -1
  59. package/dist/_chunks/{relations-CK2Jd0HM.js → relations-D81a_2zw.js} +2 -2
  60. package/dist/_chunks/{relations-CK2Jd0HM.js.map → relations-D81a_2zw.js.map} +1 -1
  61. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  62. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  63. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  64. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  65. package/dist/admin/index.js +2 -1
  66. package/dist/admin/index.js.map +1 -1
  67. package/dist/admin/index.mjs +5 -4
  68. package/dist/admin/src/exports.d.ts +1 -1
  69. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  70. package/dist/admin/src/hooks/useDocument.d.ts +30 -1
  71. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  72. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  73. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  74. package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
  75. package/dist/admin/src/services/api.d.ts +1 -1
  76. package/dist/admin/src/services/components.d.ts +2 -2
  77. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  78. package/dist/admin/src/services/documents.d.ts +19 -17
  79. package/dist/admin/src/services/init.d.ts +1 -1
  80. package/dist/admin/src/services/relations.d.ts +2 -2
  81. package/dist/admin/src/services/uid.d.ts +3 -3
  82. package/dist/admin/src/utils/validation.d.ts +4 -1
  83. package/dist/server/index.js +147 -82
  84. package/dist/server/index.js.map +1 -1
  85. package/dist/server/index.mjs +148 -83
  86. package/dist/server/index.mjs.map +1 -1
  87. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  88. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  89. package/dist/server/src/history/services/history.d.ts.map +1 -1
  90. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  91. package/dist/server/src/history/services/utils.d.ts +2 -1
  92. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  93. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  94. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  95. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  96. package/dist/shared/contracts/collection-types.d.ts +3 -1
  97. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  98. package/package.json +11 -11
  99. package/dist/_chunks/EditViewPage-CtdtssrH.mjs.map +0 -1
  100. package/dist/_chunks/EditViewPage-DxKueadW.js.map +0 -1
  101. package/dist/_chunks/Field-BPw8fE3W.js.map +0 -1
  102. package/dist/_chunks/Field-BU7_nR4F.mjs.map +0 -1
  103. package/dist/_chunks/Form-DtvmbGdZ.js.map +0 -1
  104. package/dist/_chunks/Form-ffghBTPI.mjs.map +0 -1
  105. package/dist/_chunks/ListConfigurationPage-BC9bCi9k.mjs.map +0 -1
  106. package/dist/_chunks/ListConfigurationPage-DsmAQ3YM.js.map +0 -1
  107. package/dist/_chunks/ListViewPage-B1GyNqfn.mjs.map +0 -1
  108. package/dist/_chunks/ListViewPage-DqAIb_ie.js.map +0 -1
  109. package/dist/_chunks/index-1zxclxo_.js.map +0 -1
  110. package/dist/_chunks/index-BcQ8cRyl.mjs.map +0 -1
  111. package/dist/_chunks/layout-Jl9mJFJZ.mjs.map +0 -1
  112. package/dist/_chunks/layout-tVvbqota.js.map +0 -1
  113. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  114. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  115. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  116. package/strapi-server.js +0 -3
@@ -1,5 +1,5 @@
1
1
  import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
2
- import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, isNil as isNil$1, getOr, propEq, merge, groupBy, castArray } from "lodash/fp";
2
+ import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
3
3
  import "@strapi/types";
4
4
  import * as yup from "yup";
5
5
  import { scheduleJob } from "node-schedule";
@@ -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,9 +202,10 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
200
202
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
201
203
  return documentMetadataService.getStatus(document, meta.availableStatus);
202
204
  };
203
- const getDeepPopulate2 = (uid2) => {
205
+ const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
204
206
  const model = strapi2.getModel(uid2);
205
207
  const attributes = Object.entries(model.attributes);
208
+ const fieldSelector = useDatabaseSyntax ? "select" : "fields";
206
209
  return attributes.reduce((acc, [attributeName, attribute]) => {
207
210
  switch (attribute.type) {
208
211
  case "relation": {
@@ -212,12 +215,12 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
212
215
  }
213
216
  const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
214
217
  if (isVisible2) {
215
- acc[attributeName] = { fields: ["documentId", "locale", "publishedAt"] };
218
+ acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
216
219
  }
217
220
  break;
218
221
  }
219
222
  case "media": {
220
- acc[attributeName] = { fields: ["id"] };
223
+ acc[attributeName] = { [fieldSelector]: ["id"] };
221
224
  break;
222
225
  }
223
226
  case "component": {
@@ -290,6 +293,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
290
293
  getRelationRestoreValue,
291
294
  getMediaRestoreValue,
292
295
  getDefaultLocale,
296
+ isLocalizedContentType,
293
297
  getLocaleDictionary,
294
298
  getRetentionDays,
295
299
  getVersionStatus,
@@ -312,7 +316,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
312
316
  });
313
317
  },
314
318
  async findVersionsPage(params) {
315
- const locale = params.query.locale || await serviceUtils.getDefaultLocale();
319
+ const model = strapi2.getModel(params.query.contentType);
320
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
321
+ const defaultLocale = await serviceUtils.getDefaultLocale();
322
+ let locale = null;
323
+ if (isLocalizedContentType) {
324
+ locale = params.query.locale || defaultLocale;
325
+ }
316
326
  const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
317
327
  query.findPage({
318
328
  ...params.query,
@@ -468,6 +478,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
468
478
  }
469
479
  };
470
480
  };
481
+ const shouldCreateHistoryVersion = (context) => {
482
+ if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
483
+ return false;
484
+ }
485
+ if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
486
+ return false;
487
+ }
488
+ if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
489
+ return false;
490
+ }
491
+ if (!context.contentType.uid.startsWith("api::")) {
492
+ return false;
493
+ }
494
+ return true;
495
+ };
496
+ const getSchemas = (uid2) => {
497
+ const attributesSchema = strapi.getModel(uid2).attributes;
498
+ const componentsSchemas = Object.keys(attributesSchema).reduce(
499
+ (currentComponentSchemas, key) => {
500
+ const fieldSchema = attributesSchema[key];
501
+ if (fieldSchema.type === "component") {
502
+ const componentSchema = strapi.getModel(fieldSchema.component).attributes;
503
+ return {
504
+ ...currentComponentSchemas,
505
+ [fieldSchema.component]: componentSchema
506
+ };
507
+ }
508
+ return currentComponentSchemas;
509
+ },
510
+ {}
511
+ );
512
+ return {
513
+ schema: omit(FIELDS_TO_IGNORE, attributesSchema),
514
+ componentsSchemas
515
+ };
516
+ };
471
517
  const createLifecyclesService = ({ strapi: strapi2 }) => {
472
518
  const state = {
473
519
  deleteExpiredJob: null,
@@ -480,63 +526,45 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
480
526
  return;
481
527
  }
482
528
  strapi2.documents.use(async (context, next) => {
483
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
484
- return next();
485
- }
486
- if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
487
- return next();
488
- }
489
- if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
490
- return next();
491
- }
492
- const contentTypeUid = context.contentType.uid;
493
- if (!contentTypeUid.startsWith("api::")) {
494
- return next();
495
- }
496
529
  const result = await next();
497
- const documentContext = {
498
- documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
499
- locale: context.params?.locale
500
- };
530
+ if (!shouldCreateHistoryVersion(context)) {
531
+ return result;
532
+ }
533
+ const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
501
534
  const defaultLocale = await serviceUtils.getDefaultLocale();
502
- const locale = documentContext.locale || defaultLocale;
503
- if (Array.isArray(locale)) {
504
- strapi2.log.warn(
505
- "[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
506
- );
507
- return next();
535
+ const locales = castArray(context.params?.locale || defaultLocale);
536
+ if (!locales.length) {
537
+ return result;
508
538
  }
509
- const document = await strapi2.documents(contentTypeUid).findOne({
510
- documentId: documentContext.documentId,
511
- locale,
512
- populate: serviceUtils.getDeepPopulate(contentTypeUid)
539
+ const uid2 = context.contentType.uid;
540
+ const schemas = getSchemas(uid2);
541
+ const model = strapi2.getModel(uid2);
542
+ const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
543
+ const localeEntries = await strapi2.db.query(uid2).findMany({
544
+ where: {
545
+ documentId,
546
+ ...isLocalizedContentType ? { locale: { $in: locales } } : {},
547
+ ...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
548
+ },
549
+ populate: serviceUtils.getDeepPopulate(
550
+ uid2,
551
+ true
552
+ /* use database syntax */
553
+ )
513
554
  });
514
- const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
515
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
516
- const componentsSchemas = Object.keys(
517
- attributesSchema
518
- ).reduce((currentComponentSchemas, key) => {
519
- const fieldSchema = attributesSchema[key];
520
- if (fieldSchema.type === "component") {
521
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
522
- return {
523
- ...currentComponentSchemas,
524
- [fieldSchema.component]: componentSchema
525
- };
526
- }
527
- return currentComponentSchemas;
528
- }, {});
529
555
  await strapi2.db.transaction(async ({ onCommit }) => {
530
- onCommit(() => {
531
- getService(strapi2, "history").createVersion({
532
- contentType: contentTypeUid,
533
- data: omit(FIELDS_TO_IGNORE, document),
534
- schema: omit(FIELDS_TO_IGNORE, attributesSchema),
535
- componentsSchemas,
536
- relatedDocumentId: documentContext.documentId,
537
- locale,
538
- status
539
- });
556
+ onCommit(async () => {
557
+ for (const entry of localeEntries) {
558
+ const status = await serviceUtils.getVersionStatus(uid2, entry);
559
+ await getService(strapi2, "history").createVersion({
560
+ contentType: uid2,
561
+ data: omit(FIELDS_TO_IGNORE, entry),
562
+ relatedDocumentId: documentId,
563
+ locale: entry.locale,
564
+ status,
565
+ ...schemas
566
+ });
567
+ }
540
568
  });
541
569
  });
542
570
  return result;
@@ -1176,6 +1204,11 @@ const { createPolicy } = policy;
1176
1204
  const hasPermissions = createPolicy({
1177
1205
  name: "plugin::content-manager.hasPermissions",
1178
1206
  validator: validateHasPermissionsInput,
1207
+ /**
1208
+ * NOTE: Action aliases are currently not checked at this level (policy).
1209
+ * This is currently the intended behavior to avoid changing the behavior of API related permissions.
1210
+ * If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
1211
+ */
1179
1212
  handler(ctx, config = {}) {
1180
1213
  const { actions = [], hasAtLeastOne = false } = config;
1181
1214
  const { userAbility } = ctx.state;
@@ -1728,7 +1761,7 @@ const collectionTypes = {
1728
1761
  permissionChecker2,
1729
1762
  model,
1730
1763
  // @ts-expect-error TODO: fix
1731
- { id, locale, publishedAt: null },
1764
+ { documentId: id, locale, publishedAt: null },
1732
1765
  { availableLocales: true, availableStatus: false }
1733
1766
  );
1734
1767
  ctx.body = { data: {}, meta };
@@ -1854,11 +1887,28 @@ const collectionTypes = {
1854
1887
  const publishedDocument = await strapi.db.transaction(async () => {
1855
1888
  const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1856
1889
  const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1857
- const document = id ? await updateDocument(ctx, { populate }) : await createDocument(ctx, { populate });
1890
+ let document;
1891
+ const { locale } = await getDocumentLocaleAndStatus(body, model);
1892
+ const isCreate = isNil$1(id);
1893
+ if (isCreate) {
1894
+ if (permissionChecker2.cannot.create()) {
1895
+ throw new errors.ForbiddenError();
1896
+ }
1897
+ document = await createDocument(ctx, { populate });
1898
+ }
1899
+ const isUpdate = !isCreate;
1900
+ if (isUpdate) {
1901
+ document = await documentManager2.findOne(id, model, { populate, locale });
1902
+ if (!document) {
1903
+ throw new errors.NotFoundError("Document not found");
1904
+ }
1905
+ if (permissionChecker2.can.update(document)) {
1906
+ await updateDocument(ctx);
1907
+ }
1908
+ }
1858
1909
  if (permissionChecker2.cannot.publish(document)) {
1859
1910
  throw new errors.ForbiddenError();
1860
1911
  }
1861
- const { locale } = await getDocumentLocaleAndStatus(body, model);
1862
1912
  const publishResult = await documentManager2.publish(document.documentId, model, {
1863
1913
  locale
1864
1914
  // TODO: Allow setting creator fields on publish
@@ -1914,7 +1964,9 @@ const collectionTypes = {
1914
1964
  if (permissionChecker2.cannot.unpublish()) {
1915
1965
  return ctx.forbidden();
1916
1966
  }
1917
- const { locale } = await getDocumentLocaleAndStatus(body, model);
1967
+ const { locale } = await getDocumentLocaleAndStatus(body, model, {
1968
+ allowMultipleLocales: true
1969
+ });
1918
1970
  const entityPromises = documentIds.map(
1919
1971
  (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1920
1972
  );
@@ -2265,20 +2317,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
2265
2317
  userAbility,
2266
2318
  model: model.uid
2267
2319
  });
2268
- if (!isListable(model, mainField)) {
2320
+ const isMainFieldListable = isListable(model, mainField);
2321
+ const canReadMainField = permissionChecker2.can.read(null, mainField);
2322
+ if (!isMainFieldListable || !canReadMainField) {
2269
2323
  return "id";
2270
2324
  }
2271
- if (permissionChecker2.cannot.read(null, mainField)) {
2272
- if (model.uid === "plugin::users-permissions.role") {
2273
- const userPermissionChecker = getService$1("permission-checker").create({
2274
- userAbility,
2275
- model: "plugin::users-permissions.user"
2276
- });
2277
- if (userPermissionChecker.can.read()) {
2278
- return "name";
2279
- }
2280
- }
2281
- return "id";
2325
+ if (model.uid === "plugin::users-permissions.role") {
2326
+ return "name";
2282
2327
  }
2283
2328
  return mainField;
2284
2329
  };
@@ -2478,8 +2523,9 @@ const relations = {
2478
2523
  } else {
2479
2524
  where.id = id;
2480
2525
  }
2481
- if (status) {
2482
- where[`${alias}.published_at`] = getPublishedAtClause(status, targetUid);
2526
+ const publishedAt = getPublishedAtClause(status, targetUid);
2527
+ if (!isEmpty(publishedAt)) {
2528
+ where[`${alias}.published_at`] = publishedAt;
2483
2529
  }
2484
2530
  if (filterByLocale) {
2485
2531
  where[`${alias}.locale`] = locale;
@@ -2536,9 +2582,7 @@ const relations = {
2536
2582
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2537
2583
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2538
2584
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2539
- ordering: "desc",
2540
- page: ctx.request.query.page,
2541
- pageSize: ctx.request.query.pageSize
2585
+ ordering: "desc"
2542
2586
  });
2543
2587
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2544
2588
  ctx.body = {
@@ -2625,7 +2669,7 @@ const singleTypes = {
2625
2669
  permissionChecker2,
2626
2670
  model,
2627
2671
  // @ts-expect-error - fix types
2628
- { id: document.documentId, locale, publishedAt: null },
2672
+ { documentId: document.documentId, locale, publishedAt: null },
2629
2673
  { availableLocales: true, availableStatus: false }
2630
2674
  );
2631
2675
  ctx.body = { data: {}, meta };
@@ -3444,12 +3488,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3444
3488
  ability: userAbility,
3445
3489
  model
3446
3490
  });
3447
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3491
+ const { actionProvider } = strapi2.service("admin::permission");
3492
+ const toSubject = (entity) => {
3493
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3494
+ };
3448
3495
  const can = (action, entity, field) => {
3449
- return userAbility.can(action, toSubject(entity), field);
3496
+ const subject = toSubject(entity);
3497
+ const aliases = actionProvider.unstable_aliases(action, model);
3498
+ return (
3499
+ // Test the original action to see if it passes
3500
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3501
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3502
+ );
3450
3503
  };
3451
3504
  const cannot = (action, entity, field) => {
3452
- return userAbility.cannot(action, toSubject(entity), field);
3505
+ const subject = toSubject(entity);
3506
+ const aliases = actionProvider.unstable_aliases(action, model);
3507
+ return (
3508
+ // Test both the original action
3509
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3510
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3511
+ );
3453
3512
  };
3454
3513
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3455
3514
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -4107,7 +4166,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4107
4166
  */
4108
4167
  async formatDocumentWithMetadata(uid2, document, opts = {}) {
4109
4168
  if (!document) {
4110
- return document;
4169
+ return {
4170
+ data: document,
4171
+ meta: {
4172
+ availableLocales: [],
4173
+ availableStatus: []
4174
+ }
4175
+ };
4111
4176
  }
4112
4177
  const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
4113
4178
  if (!hasDraftAndPublish) {