@strapi/content-manager 0.0.0-experimental.edc24aaa3bb5a90fa5fd4fee208167dd4e2e38d4 → 0.0.0-experimental.f2351bcfa3965c60f063a492da51faa2c636eee8

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 (112) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-BlAzljQ6.js} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-BlAzljQ6.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-Ccwb19Qj.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-Ccwb19Qj.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-BPoOzhCM.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-BPoOzhCM.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs → EditConfigurationPage-C19b_9RL.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-C19b_9RL.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-D9xH8HYD.js} +19 -8
  10. package/dist/_chunks/EditViewPage-D9xH8HYD.js.map +1 -0
  11. package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-nmrHNiJ9.mjs} +19 -8
  12. package/dist/_chunks/EditViewPage-nmrHNiJ9.mjs.map +1 -0
  13. package/dist/_chunks/{Field-Cs7duwWd.mjs → Field--kmlJuSb.mjs} +118 -90
  14. package/dist/_chunks/Field--kmlJuSb.mjs.map +1 -0
  15. package/dist/_chunks/{Field-Bfph5SOd.js → Field-BB_pHo6D.js} +120 -92
  16. package/dist/_chunks/Field-BB_pHo6D.js.map +1 -0
  17. package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-CUtOiC4S.mjs} +35 -16
  18. package/dist/_chunks/Form-CUtOiC4S.mjs.map +1 -0
  19. package/dist/_chunks/{Form-CPYqIWDG.js → Form-iwbkoaAF.js} +35 -16
  20. package/dist/_chunks/Form-iwbkoaAF.js.map +1 -0
  21. package/dist/_chunks/{History-wrnHqf09.mjs → History-BKR3KyU3.mjs} +4 -4
  22. package/dist/_chunks/{History-wrnHqf09.mjs.map → History-BKR3KyU3.mjs.map} +1 -1
  23. package/dist/_chunks/{History-DNQkXANT.js → History-guuZF4lR.js} +4 -4
  24. package/dist/_chunks/{History-DNQkXANT.js.map → History-guuZF4lR.js.map} +1 -1
  25. package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-B_O3hiLT.mjs} +14 -4
  26. package/dist/_chunks/ListConfigurationPage-B_O3hiLT.mjs.map +1 -0
  27. package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-Cu26t5sE.js} +14 -4
  28. package/dist/_chunks/ListConfigurationPage-Cu26t5sE.js.map +1 -0
  29. package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-B4sTBfu6.mjs} +46 -37
  30. package/dist/_chunks/ListViewPage-B4sTBfu6.mjs.map +1 -0
  31. package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-DWqqGno8.js} +48 -39
  32. package/dist/_chunks/ListViewPage-DWqqGno8.js.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-Daktt4t9.mjs} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-Daktt4t9.mjs.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-TTkwA8uk.js} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-TTkwA8uk.js.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-CBUXY2Pt.mjs} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-CBUXY2Pt.mjs.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-D8_k39Q0.js} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-D8_k39Q0.js.map} +1 -1
  41. package/dist/_chunks/{Relations-CtELXYIK.js → Relations-DjvmZ_XQ.js} +4 -4
  42. package/dist/_chunks/{Relations-CtELXYIK.js.map → Relations-DjvmZ_XQ.js.map} +1 -1
  43. package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-HKmXF7eO.mjs} +4 -4
  44. package/dist/_chunks/{Relations-BZr8tL0R.mjs.map → Relations-HKmXF7eO.mjs.map} +1 -1
  45. package/dist/_chunks/{en-uOUIxfcQ.js → en-BVzUkPxZ.js} +6 -5
  46. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BVzUkPxZ.js.map} +1 -1
  47. package/dist/_chunks/{en-BrCTWlZv.mjs → en-CPTj6CjC.mjs} +6 -5
  48. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-CPTj6CjC.mjs.map} +1 -1
  49. package/dist/_chunks/{index-c_5DdJi-.mjs → index-CB1AN26E.mjs} +223 -125
  50. package/dist/_chunks/index-CB1AN26E.mjs.map +1 -0
  51. package/dist/_chunks/{index-OerGjbAN.js → index-jDJgW_Lf.js} +204 -106
  52. package/dist/_chunks/index-jDJgW_Lf.js.map +1 -0
  53. package/dist/_chunks/{layout-oPBiO7RY.mjs → layout-BCzDsMgN.mjs} +22 -9
  54. package/dist/_chunks/layout-BCzDsMgN.mjs.map +1 -0
  55. package/dist/_chunks/{layout-Ci7qHlFb.js → layout-D6A3K-ut.js} +21 -8
  56. package/dist/_chunks/layout-D6A3K-ut.js.map +1 -0
  57. package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-B5Jnw32V.mjs} +2 -2
  58. package/dist/_chunks/{relations-BIdWFjdq.mjs.map → relations-B5Jnw32V.mjs.map} +1 -1
  59. package/dist/_chunks/{relations-COBpStiF.js → relations-C10QoukP.js} +2 -2
  60. package/dist/_chunks/{relations-COBpStiF.js.map → relations-C10QoukP.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 +1 -1
  66. package/dist/admin/index.mjs +4 -4
  67. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  68. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  69. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  70. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  71. package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
  72. package/dist/admin/src/services/api.d.ts +1 -1
  73. package/dist/admin/src/services/components.d.ts +2 -2
  74. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  75. package/dist/admin/src/services/documents.d.ts +19 -17
  76. package/dist/admin/src/services/init.d.ts +1 -1
  77. package/dist/admin/src/services/relations.d.ts +2 -2
  78. package/dist/admin/src/services/uid.d.ts +3 -3
  79. package/dist/admin/src/utils/validation.d.ts +4 -1
  80. package/dist/server/index.js +143 -79
  81. package/dist/server/index.js.map +1 -1
  82. package/dist/server/index.mjs +144 -80
  83. package/dist/server/index.mjs.map +1 -1
  84. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  85. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  86. package/dist/server/src/history/services/history.d.ts.map +1 -1
  87. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  88. package/dist/server/src/history/services/utils.d.ts +2 -1
  89. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  90. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  91. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  92. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  93. package/dist/shared/contracts/collection-types.d.ts +3 -1
  94. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  95. package/package.json +9 -9
  96. package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +0 -1
  97. package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
  98. package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
  99. package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
  100. package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
  101. package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
  102. package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
  103. package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
  104. package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
  105. package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
  106. package/dist/_chunks/index-OerGjbAN.js.map +0 -1
  107. package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
  108. package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
  109. package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
  110. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  111. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  112. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
@@ -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
  };
@@ -2536,9 +2581,7 @@ const relations = {
2536
2581
  addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
2537
2582
  const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
2538
2583
  ...strapi.get("query-params").transform(targetUid, permissionQuery),
2539
- ordering: "desc",
2540
- page: ctx.request.query.page,
2541
- pageSize: ctx.request.query.pageSize
2584
+ ordering: "desc"
2542
2585
  });
2543
2586
  const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
2544
2587
  ctx.body = {
@@ -3444,12 +3487,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
3444
3487
  ability: userAbility,
3445
3488
  model
3446
3489
  });
3447
- const toSubject = (entity) => entity ? permissionsManager.toSubject(entity, model) : model;
3490
+ const { actionProvider } = strapi2.service("admin::permission");
3491
+ const toSubject = (entity) => {
3492
+ return entity ? permissionsManager.toSubject(entity, model) : model;
3493
+ };
3448
3494
  const can = (action, entity, field) => {
3449
- return userAbility.can(action, toSubject(entity), field);
3495
+ const subject = toSubject(entity);
3496
+ const aliases = actionProvider.unstable_aliases(action, model);
3497
+ return (
3498
+ // Test the original action to see if it passes
3499
+ userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
3500
+ aliases.some((alias) => userAbility.can(alias, subject, field))
3501
+ );
3450
3502
  };
3451
3503
  const cannot = (action, entity, field) => {
3452
- return userAbility.cannot(action, toSubject(entity), field);
3504
+ const subject = toSubject(entity);
3505
+ const aliases = actionProvider.unstable_aliases(action, model);
3506
+ return (
3507
+ // Test both the original action
3508
+ userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
3509
+ aliases.every((alias) => userAbility.cannot(alias, subject, field))
3510
+ );
3453
3511
  };
3454
3512
  const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
3455
3513
  return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
@@ -4107,7 +4165,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
4107
4165
  */
4108
4166
  async formatDocumentWithMetadata(uid2, document, opts = {}) {
4109
4167
  if (!document) {
4110
- return document;
4168
+ return {
4169
+ data: document,
4170
+ meta: {
4171
+ availableLocales: [],
4172
+ availableStatus: []
4173
+ }
4174
+ };
4111
4175
  }
4112
4176
  const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
4113
4177
  if (!hasDraftAndPublish) {