@strapi/content-manager 5.0.0-beta.6 → 5.0.0-beta.7

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 (118) hide show
  1. package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
  2. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
  3. package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
  4. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
  5. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-DMq0wvcL.js} +3 -3
  6. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-DMq0wvcL.js.map} +1 -1
  7. package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-uTMkLI60.mjs} +3 -3
  8. package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-uTMkLI60.mjs.map} +1 -1
  9. package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-B2HhCh-b.mjs} +3 -3
  10. package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-B2HhCh-b.mjs.map} +1 -1
  11. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-BFpQwwbc.js} +3 -3
  12. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-BFpQwwbc.js.map} +1 -1
  13. package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-BVIrgjyG.mjs} +4 -4
  14. package/dist/_chunks/EditViewPage-BVIrgjyG.mjs.map +1 -0
  15. package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-CXXue16T.js} +5 -7
  16. package/dist/_chunks/EditViewPage-CXXue16T.js.map +1 -0
  17. package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-0_2h1vuK.mjs} +303 -294
  18. package/dist/_chunks/Field-0_2h1vuK.mjs.map +1 -0
  19. package/dist/_chunks/{Field-Caef4JjM.js → Field-ZgzKlgxR.js} +363 -355
  20. package/dist/_chunks/Field-ZgzKlgxR.js.map +1 -0
  21. package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-B7TUnQDd.mjs} +14 -14
  22. package/dist/_chunks/Form-B7TUnQDd.mjs.map +1 -0
  23. package/dist/_chunks/{Form-BzuAjtRq.js → Form-DgTc2qkx.js} +14 -15
  24. package/dist/_chunks/Form-DgTc2qkx.js.map +1 -0
  25. package/dist/_chunks/{History-C17LiyRg.js → History-DtHjQuqM.js} +28 -40
  26. package/dist/_chunks/History-DtHjQuqM.js.map +1 -0
  27. package/dist/_chunks/{History-D6sbCJvo.mjs → History-Dug_4HIA.mjs} +28 -39
  28. package/dist/_chunks/History-Dug_4HIA.mjs.map +1 -0
  29. package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-BuSdTjfa.js} +17 -19
  30. package/dist/_chunks/ListConfigurationPage-BuSdTjfa.js.map +1 -0
  31. package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-CmEeNg6T.mjs} +14 -14
  32. package/dist/_chunks/ListConfigurationPage-CmEeNg6T.mjs.map +1 -0
  33. package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-CExWwa4S.js} +24 -37
  34. package/dist/_chunks/ListViewPage-CExWwa4S.js.map +1 -0
  35. package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-Dsoa3wEA.mjs} +21 -33
  36. package/dist/_chunks/ListViewPage-Dsoa3wEA.mjs.map +1 -0
  37. package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-DCUL8gVi.js} +5 -5
  38. package/dist/_chunks/NoContentTypePage-DCUL8gVi.js.map +1 -0
  39. package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-Dh38hBXB.mjs} +7 -7
  40. package/dist/_chunks/NoContentTypePage-Dh38hBXB.mjs.map +1 -0
  41. package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-BK-XCpIy.js} +4 -5
  42. package/dist/_chunks/NoPermissionsPage-BK-XCpIy.js.map +1 -0
  43. package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-Dt2O40ey.mjs} +5 -6
  44. package/dist/_chunks/NoPermissionsPage-Dt2O40ey.mjs.map +1 -0
  45. package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-CNypkp-g.js} +66 -59
  46. package/dist/_chunks/Relations-CNypkp-g.js.map +1 -0
  47. package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-DZyjWZHl.mjs} +62 -54
  48. package/dist/_chunks/Relations-DZyjWZHl.mjs.map +1 -0
  49. package/dist/_chunks/{index-DNVx8ssZ.mjs → index-B3c-4it4.mjs} +54 -41
  50. package/dist/_chunks/index-B3c-4it4.mjs.map +1 -0
  51. package/dist/_chunks/{index-X_2tafck.js → index-DFK7LwDW.js} +59 -47
  52. package/dist/_chunks/index-DFK7LwDW.js.map +1 -0
  53. package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-B5cm7cZj.mjs} +10 -10
  54. package/dist/_chunks/layout-B5cm7cZj.mjs.map +1 -0
  55. package/dist/_chunks/{layout-dBc7wN7L.js → layout-DLih5-_W.js} +11 -13
  56. package/dist/_chunks/layout-DLih5-_W.js.map +1 -0
  57. package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-BZkrMa2z.mjs} +2 -2
  58. package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-BZkrMa2z.mjs.map} +1 -1
  59. package/dist/_chunks/{relations-4pHtBrHJ.js → relations-CTvkuINQ.js} +2 -2
  60. package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-CTvkuINQ.js.map} +1 -1
  61. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
  62. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
  63. package/dist/admin/index.js +1 -1
  64. package/dist/admin/index.mjs +1 -1
  65. package/dist/admin/src/hooks/useDocumentLayout.d.ts +1 -1
  66. package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
  67. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  68. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +8 -3
  69. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
  70. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +48 -54
  71. package/dist/admin/src/utils/api.d.ts +6 -7
  72. package/dist/server/index.js +333 -327
  73. package/dist/server/index.js.map +1 -1
  74. package/dist/server/index.mjs +340 -334
  75. package/dist/server/index.mjs.map +1 -1
  76. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  77. package/dist/server/src/controllers/validation/index.d.ts +1 -1
  78. package/dist/server/src/history/services/history.d.ts +2 -4
  79. package/dist/server/src/history/services/history.d.ts.map +1 -1
  80. package/dist/server/src/history/services/index.d.ts +6 -2
  81. package/dist/server/src/history/services/index.d.ts.map +1 -1
  82. package/dist/server/src/history/services/lifecycles.d.ts +9 -0
  83. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
  84. package/dist/server/src/history/services/utils.d.ts +41 -9
  85. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  86. package/dist/server/src/history/utils.d.ts +6 -2
  87. package/dist/server/src/history/utils.d.ts.map +1 -1
  88. package/dist/server/src/index.d.ts +11 -11
  89. package/dist/server/src/services/document-manager.d.ts +12 -11
  90. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  91. package/dist/server/src/services/index.d.ts +11 -11
  92. package/dist/shared/contracts/collection-types.d.ts +3 -1
  93. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  94. package/package.json +10 -11
  95. package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
  96. package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
  97. package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
  98. package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
  99. package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
  100. package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
  101. package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
  102. package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
  103. package/dist/_chunks/History-C17LiyRg.js.map +0 -1
  104. package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
  105. package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
  106. package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
  107. package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
  108. package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
  109. package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
  110. package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
  111. package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
  112. package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
  113. package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
  114. package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
  115. package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
  116. package/dist/_chunks/index-X_2tafck.js.map +0 -1
  117. package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
  118. package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, sanitize } from "@strapi/utils";
1
+ import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, pagination } from "@strapi/utils";
2
2
  import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy, castArray } from "lodash/fp";
3
3
  import "@strapi/types";
4
4
  import * as yup from "yup";
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
54
54
  return ctx.forbidden();
55
55
  }
56
56
  const query = await permissionChecker2.sanitizeQuery(ctx.query);
57
- const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
57
+ const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
58
58
  query: {
59
59
  ...query,
60
60
  ...getValidPagination({ page: query.page, pageSize: query.pageSize })
@@ -73,7 +73,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
73
73
  );
74
74
  return {
75
75
  data: sanitizedResults,
76
- meta: { pagination }
76
+ meta: { pagination: pagination2 }
77
77
  };
78
78
  },
79
79
  async restoreVersion(ctx) {
@@ -112,40 +112,65 @@ const FIELDS_TO_IGNORE = [
112
112
  "strapi_stage",
113
113
  "strapi_assignee"
114
114
  ];
115
- const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
116
- const sanitizedContentTypeSchemaAttributes = omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
117
- const reduceDifferenceToAttributesObject = (diffKeys, source) => {
118
- return diffKeys.reduce((previousAttributesObject, diffKey) => {
119
- previousAttributesObject[diffKey] = source[diffKey];
120
- return previousAttributesObject;
121
- }, {});
122
- };
123
- const versionSchemaKeys = Object.keys(versionSchemaAttributes);
124
- const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
125
- const uniqueToContentType = difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
126
- const added = reduceDifferenceToAttributesObject(
127
- uniqueToContentType,
128
- sanitizedContentTypeSchemaAttributes
129
- );
130
- const uniqueToVersion = difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
131
- const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
132
- return { added, removed };
133
- };
134
115
  const DEFAULT_RETENTION_DAYS = 90;
135
- const createHistoryService = ({ strapi: strapi2 }) => {
136
- const state = {
137
- deleteExpiredJob: null,
138
- isInitialized: false
116
+ const createServiceUtils = ({ strapi: strapi2 }) => {
117
+ const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
118
+ const sanitizedContentTypeSchemaAttributes = omit(
119
+ FIELDS_TO_IGNORE,
120
+ contentTypeSchemaAttributes
121
+ );
122
+ const reduceDifferenceToAttributesObject = (diffKeys, source) => {
123
+ return diffKeys.reduce(
124
+ (previousAttributesObject, diffKey) => {
125
+ previousAttributesObject[diffKey] = source[diffKey];
126
+ return previousAttributesObject;
127
+ },
128
+ {}
129
+ );
130
+ };
131
+ const versionSchemaKeys = Object.keys(versionSchemaAttributes);
132
+ const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
133
+ const uniqueToContentType = difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
134
+ const added = reduceDifferenceToAttributesObject(
135
+ uniqueToContentType,
136
+ sanitizedContentTypeSchemaAttributes
137
+ );
138
+ const uniqueToVersion = difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
139
+ const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
140
+ return { added, removed };
139
141
  };
140
- const query = strapi2.db.query(HISTORY_VERSION_UID);
141
- const getRetentionDays = (strapi22) => {
142
- const featureConfig = strapi22.ee.features.get("cms-content-history");
143
- const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
144
- const userRetentionDays = strapi22.config.get("admin.history.retentionDays");
145
- if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
146
- return userRetentionDays;
142
+ const getRelationRestoreValue = async (versionRelationData, attribute) => {
143
+ if (Array.isArray(versionRelationData)) {
144
+ if (versionRelationData.length === 0)
145
+ return versionRelationData;
146
+ const existingAndMissingRelations = await Promise.all(
147
+ versionRelationData.map((relation) => {
148
+ return strapi2.documents(attribute.target).findOne({
149
+ documentId: relation.documentId,
150
+ locale: relation.locale || void 0
151
+ });
152
+ })
153
+ );
154
+ return existingAndMissingRelations.filter(
155
+ (relation) => relation !== null
156
+ );
147
157
  }
148
- return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
158
+ return strapi2.documents(attribute.target).findOne({
159
+ documentId: versionRelationData.documentId,
160
+ locale: versionRelationData.locale || void 0
161
+ });
162
+ };
163
+ const getMediaRestoreValue = async (versionRelationData, attribute) => {
164
+ if (attribute.multiple) {
165
+ const existingAndMissingMedias = await Promise.all(
166
+ // @ts-expect-error Fix the type definitions so this isn't any
167
+ versionRelationData.map((media) => {
168
+ return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
169
+ })
170
+ );
171
+ return existingAndMissingMedias.filter((media) => media != null);
172
+ }
173
+ return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
149
174
  };
150
175
  const localesService = strapi2.plugin("i18n")?.service("locales");
151
176
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
@@ -161,6 +186,15 @@ const createHistoryService = ({ strapi: strapi2 }) => {
161
186
  {}
162
187
  );
163
188
  };
189
+ const getRetentionDays = () => {
190
+ const featureConfig = strapi2.ee.features.get("cms-content-history");
191
+ const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
192
+ const userRetentionDays = strapi2.config.get("admin.history.retentionDays");
193
+ if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
194
+ return userRetentionDays;
195
+ }
196
+ return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
197
+ };
164
198
  const getVersionStatus = async (contentTypeUid, document) => {
165
199
  const documentMetadataService = strapi2.plugin("content-manager").service("document-metadata");
166
200
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
@@ -202,80 +236,68 @@ const createHistoryService = ({ strapi: strapi2 }) => {
202
236
  return acc;
203
237
  }, {});
204
238
  };
205
- return {
206
- async bootstrap() {
207
- if (state.isInitialized) {
208
- return;
209
- }
210
- strapi2.documents.use(async (context, next) => {
211
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
212
- return next();
239
+ const buildMediaResponse = async (values) => {
240
+ return values.slice(0, 25).reduce(
241
+ async (currentRelationDataPromise, entry) => {
242
+ const currentRelationData = await currentRelationDataPromise;
243
+ if (!entry) {
244
+ return currentRelationData;
213
245
  }
214
- if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
215
- return next();
246
+ const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
247
+ if (relatedEntry) {
248
+ currentRelationData.results.push(relatedEntry);
249
+ } else {
250
+ currentRelationData.meta.missingCount += 1;
216
251
  }
217
- const contentTypeUid = context.contentType.uid;
218
- if (!contentTypeUid.startsWith("api::")) {
219
- return next();
252
+ return currentRelationData;
253
+ },
254
+ Promise.resolve({
255
+ results: [],
256
+ meta: { missingCount: 0 }
257
+ })
258
+ );
259
+ };
260
+ const buildRelationReponse = async (values, attributeSchema) => {
261
+ return values.slice(0, 25).reduce(
262
+ async (currentRelationDataPromise, entry) => {
263
+ const currentRelationData = await currentRelationDataPromise;
264
+ if (!entry) {
265
+ return currentRelationData;
220
266
  }
221
- const result = await next();
222
- const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
223
- const defaultLocale = await getDefaultLocale();
224
- const locale = documentContext.locale || defaultLocale;
225
- const document = await strapi2.documents(contentTypeUid).findOne({
226
- documentId: documentContext.documentId,
227
- locale,
228
- populate: getDeepPopulate2(contentTypeUid)
229
- });
230
- const status = await getVersionStatus(contentTypeUid, document);
231
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
232
- const componentsSchemas = Object.keys(
233
- attributesSchema
234
- ).reduce((currentComponentSchemas, key) => {
235
- const fieldSchema = attributesSchema[key];
236
- if (fieldSchema.type === "component") {
237
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
238
- return {
239
- ...currentComponentSchemas,
240
- [fieldSchema.component]: componentSchema
241
- };
242
- }
243
- return currentComponentSchemas;
244
- }, {});
245
- await strapi2.db.transaction(async ({ onCommit }) => {
246
- onCommit(() => {
247
- this.createVersion({
248
- contentType: contentTypeUid,
249
- data: omit(FIELDS_TO_IGNORE, document),
250
- schema: omit(FIELDS_TO_IGNORE, attributesSchema),
251
- componentsSchemas,
252
- relatedDocumentId: documentContext.documentId,
253
- locale,
254
- status
255
- });
267
+ const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
268
+ if (relatedEntry) {
269
+ currentRelationData.results.push({
270
+ ...relatedEntry,
271
+ status: await getVersionStatus(attributeSchema.target, relatedEntry)
256
272
  });
257
- });
258
- return result;
259
- });
260
- const retentionDays = getRetentionDays(strapi2);
261
- state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
262
- const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
263
- const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
264
- query.deleteMany({
265
- where: {
266
- created_at: {
267
- $lt: expirationDate.toISOString()
268
- }
269
- }
270
- });
271
- });
272
- state.isInitialized = true;
273
- },
274
- async destroy() {
275
- if (state.deleteExpiredJob) {
276
- state.deleteExpiredJob.cancel();
277
- }
278
- },
273
+ } else {
274
+ currentRelationData.meta.missingCount += 1;
275
+ }
276
+ return currentRelationData;
277
+ },
278
+ Promise.resolve({
279
+ results: [],
280
+ meta: { missingCount: 0 }
281
+ })
282
+ );
283
+ };
284
+ return {
285
+ getSchemaAttributesDiff,
286
+ getRelationRestoreValue,
287
+ getMediaRestoreValue,
288
+ getDefaultLocale,
289
+ getLocaleDictionary,
290
+ getRetentionDays,
291
+ getVersionStatus,
292
+ getDeepPopulate: getDeepPopulate2,
293
+ buildMediaResponse,
294
+ buildRelationReponse
295
+ };
296
+ };
297
+ const createHistoryService = ({ strapi: strapi2 }) => {
298
+ const query = strapi2.db.query(HISTORY_VERSION_UID);
299
+ const serviceUtils = createServiceUtils({ strapi: strapi2 });
300
+ return {
279
301
  async createVersion(historyVersionData) {
280
302
  await query.create({
281
303
  data: {
@@ -286,8 +308,8 @@ const createHistoryService = ({ strapi: strapi2 }) => {
286
308
  });
287
309
  },
288
310
  async findVersionsPage(params) {
289
- const locale = params.query.locale || await getDefaultLocale();
290
- const [{ results, pagination }, localeDictionary] = await Promise.all([
311
+ const locale = params.query.locale || await serviceUtils.getDefaultLocale();
312
+ const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
291
313
  query.findPage({
292
314
  ...params.query,
293
315
  where: {
@@ -300,78 +322,34 @@ const createHistoryService = ({ strapi: strapi2 }) => {
300
322
  populate: ["createdBy"],
301
323
  orderBy: [{ createdAt: "desc" }]
302
324
  }),
303
- getLocaleDictionary()
325
+ serviceUtils.getLocaleDictionary()
304
326
  ]);
305
- const buildRelationReponse = async (values, attributeSchema) => {
306
- return values.slice(0, 25).reduce(
307
- async (currentRelationDataPromise, entry) => {
308
- const currentRelationData = await currentRelationDataPromise;
309
- if (!entry) {
310
- return currentRelationData;
311
- }
312
- const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
313
- const permissionChecker2 = getService$1("permission-checker").create({
314
- userAbility: params.state.userAbility,
315
- model: attributeSchema.target
316
- });
317
- const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
318
- if (sanitizedEntry) {
319
- currentRelationData.results.push({
320
- ...sanitizedEntry,
321
- status: await getVersionStatus(attributeSchema.target, sanitizedEntry)
322
- });
323
- } else {
324
- currentRelationData.meta.missingCount += 1;
325
- }
326
- return currentRelationData;
327
- },
328
- Promise.resolve({
329
- results: [],
330
- meta: { missingCount: 0 }
331
- })
332
- );
333
- };
334
- const buildMediaResponse = async (values) => {
335
- return values.slice(0, 25).reduce(
336
- async (currentRelationDataPromise, entry) => {
337
- const currentRelationData = await currentRelationDataPromise;
338
- if (!entry) {
339
- return currentRelationData;
340
- }
341
- const permissionChecker2 = getService$1("permission-checker").create({
342
- userAbility: params.state.userAbility,
343
- model: "plugin::upload.file"
344
- });
345
- const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
346
- const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
347
- if (sanitizedEntry) {
348
- currentRelationData.results.push(sanitizedEntry);
349
- } else {
350
- currentRelationData.meta.missingCount += 1;
351
- }
352
- return currentRelationData;
353
- },
354
- Promise.resolve({
355
- results: [],
356
- meta: { missingCount: 0 }
357
- })
358
- );
359
- };
360
327
  const populateEntryRelations = async (entry) => {
361
328
  const entryWithRelations = await Object.entries(entry.schema).reduce(
362
329
  async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
363
330
  const attributeValue = entry.data[attributeKey];
364
331
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
365
332
  if (attributeSchema.type === "media") {
333
+ const permissionChecker2 = getService$1("permission-checker").create({
334
+ userAbility: params.state.userAbility,
335
+ model: "plugin::upload.file"
336
+ });
337
+ const response = await serviceUtils.buildMediaResponse(attributeValues);
338
+ const sanitizedResults = await Promise.all(
339
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
340
+ );
366
341
  return {
367
342
  ...await currentDataWithRelations,
368
- [attributeKey]: await buildMediaResponse(attributeValues)
343
+ [attributeKey]: {
344
+ results: sanitizedResults,
345
+ meta: response.meta
346
+ }
369
347
  };
370
348
  }
371
349
  if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
372
350
  if (attributeSchema.target === "admin::user") {
373
351
  const adminUsers = await Promise.all(
374
- attributeValues.map(async (userToPopulate) => {
352
+ attributeValues.map((userToPopulate) => {
375
353
  if (userToPopulate == null) {
376
354
  return null;
377
355
  }
@@ -388,9 +366,23 @@ const createHistoryService = ({ strapi: strapi2 }) => {
388
366
  [attributeKey]: adminUsers
389
367
  };
390
368
  }
369
+ const permissionChecker2 = getService$1("permission-checker").create({
370
+ userAbility: params.state.userAbility,
371
+ model: attributeSchema.target
372
+ });
373
+ const response = await serviceUtils.buildRelationReponse(
374
+ attributeValues,
375
+ attributeSchema
376
+ );
377
+ const sanitizedResults = await Promise.all(
378
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
379
+ );
391
380
  return {
392
381
  ...await currentDataWithRelations,
393
- [attributeKey]: await buildRelationReponse(attributeValues, attributeSchema)
382
+ [attributeKey]: {
383
+ results: sanitizedResults,
384
+ meta: response.meta
385
+ }
394
386
  };
395
387
  }
396
388
  return currentDataWithRelations;
@@ -405,7 +397,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
405
397
  ...result,
406
398
  data: await populateEntryRelations(result),
407
399
  meta: {
408
- unknownAttributes: getSchemaAttributesDiff(
400
+ unknownAttributes: serviceUtils.getSchemaAttributesDiff(
409
401
  result.schema,
410
402
  strapi2.getModel(params.query.contentType).attributes
411
403
  )
@@ -416,13 +408,16 @@ const createHistoryService = ({ strapi: strapi2 }) => {
416
408
  );
417
409
  return {
418
410
  results: formattedResults,
419
- pagination
411
+ pagination: pagination2
420
412
  };
421
413
  },
422
414
  async restoreVersion(versionId) {
423
415
  const version = await query.findOne({ where: { id: versionId } });
424
416
  const contentTypeSchemaAttributes = strapi2.getModel(version.contentType).attributes;
425
- const schemaDiff = getSchemaAttributesDiff(version.schema, contentTypeSchemaAttributes);
417
+ const schemaDiff = serviceUtils.getSchemaAttributesDiff(
418
+ version.schema,
419
+ contentTypeSchemaAttributes
420
+ );
426
421
  const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(
427
422
  (currentData, addedKey) => {
428
423
  currentData[addedKey] = null;
@@ -435,61 +430,26 @@ const createHistoryService = ({ strapi: strapi2 }) => {
435
430
  FIELDS_TO_IGNORE,
436
431
  contentTypeSchemaAttributes
437
432
  );
438
- const dataWithoutMissingRelations = await Object.entries(sanitizedSchemaAttributes).reduce(
439
- async (previousRelationAttributesPromise, [name, attribute]) => {
440
- const previousRelationAttributes = await previousRelationAttributesPromise;
441
- const relationData = version.data[name];
442
- if (relationData === null) {
433
+ const reducer = async.reduce(Object.entries(sanitizedSchemaAttributes));
434
+ const dataWithoutMissingRelations = await reducer(
435
+ async (previousRelationAttributes, [name, attribute]) => {
436
+ const versionRelationData = version.data[name];
437
+ if (!versionRelationData) {
443
438
  return previousRelationAttributes;
444
439
  }
445
440
  if (attribute.type === "relation" && // TODO: handle polymorphic relations
446
441
  attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
447
- if (Array.isArray(relationData)) {
448
- if (relationData.length === 0)
449
- return previousRelationAttributes;
450
- const existingAndMissingRelations = await Promise.all(
451
- relationData.map((relation) => {
452
- return strapi2.documents(attribute.target).findOne({
453
- documentId: relation.documentId,
454
- locale: relation.locale || void 0
455
- });
456
- })
457
- );
458
- const existingRelations = existingAndMissingRelations.filter(
459
- (relation) => relation !== null
460
- );
461
- previousRelationAttributes[name] = existingRelations;
462
- } else {
463
- const existingRelation = await strapi2.documents(attribute.target).findOne({
464
- documentId: relationData.documentId,
465
- locale: relationData.locale || void 0
466
- });
467
- if (!existingRelation) {
468
- previousRelationAttributes[name] = null;
469
- }
470
- }
442
+ const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
443
+ previousRelationAttributes[name] = data2;
471
444
  }
472
445
  if (attribute.type === "media") {
473
- if (attribute.multiple) {
474
- const existingAndMissingMedias = await Promise.all(
475
- // @ts-expect-error Fix the type definitions so this isn't any
476
- relationData.map((media) => {
477
- return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
478
- })
479
- );
480
- const existingMedias = existingAndMissingMedias.filter((media) => media != null);
481
- previousRelationAttributes[name] = existingMedias;
482
- } else {
483
- const existingMedia = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: version.data[name].id } });
484
- if (!existingMedia) {
485
- previousRelationAttributes[name] = null;
486
- }
487
- }
446
+ const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
447
+ previousRelationAttributes[name] = data2;
488
448
  }
489
449
  return previousRelationAttributes;
490
450
  },
491
451
  // Clone to avoid mutating the original version data
492
- Promise.resolve(structuredClone(dataWithoutAddedAttributes))
452
+ structuredClone(dataWithoutAddedAttributes)
493
453
  );
494
454
  const data = omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
495
455
  const restoredDocument = await strapi2.documents(version.contentType).update({
@@ -504,8 +464,93 @@ const createHistoryService = ({ strapi: strapi2 }) => {
504
464
  }
505
465
  };
506
466
  };
467
+ const createLifecyclesService = ({ strapi: strapi2 }) => {
468
+ const state = {
469
+ deleteExpiredJob: null,
470
+ isInitialized: false
471
+ };
472
+ const query = strapi2.db.query(HISTORY_VERSION_UID);
473
+ const historyService = getService(strapi2, "history");
474
+ const serviceUtils = createServiceUtils({ strapi: strapi2 });
475
+ return {
476
+ async bootstrap() {
477
+ if (state.isInitialized) {
478
+ return;
479
+ }
480
+ strapi2.documents.use(async (context, next) => {
481
+ if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
482
+ return next();
483
+ }
484
+ if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
485
+ return next();
486
+ }
487
+ const contentTypeUid = context.contentType.uid;
488
+ if (!contentTypeUid.startsWith("api::")) {
489
+ return next();
490
+ }
491
+ const result = await next();
492
+ const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
493
+ const defaultLocale = await serviceUtils.getDefaultLocale();
494
+ const locale = documentContext.locale || defaultLocale;
495
+ const document = await strapi2.documents(contentTypeUid).findOne({
496
+ documentId: documentContext.documentId,
497
+ locale,
498
+ populate: serviceUtils.getDeepPopulate(contentTypeUid)
499
+ });
500
+ const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
501
+ const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
502
+ const componentsSchemas = Object.keys(
503
+ attributesSchema
504
+ ).reduce((currentComponentSchemas, key) => {
505
+ const fieldSchema = attributesSchema[key];
506
+ if (fieldSchema.type === "component") {
507
+ const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
508
+ return {
509
+ ...currentComponentSchemas,
510
+ [fieldSchema.component]: componentSchema
511
+ };
512
+ }
513
+ return currentComponentSchemas;
514
+ }, {});
515
+ await strapi2.db.transaction(async ({ onCommit }) => {
516
+ onCommit(() => {
517
+ historyService.createVersion({
518
+ contentType: contentTypeUid,
519
+ data: omit(FIELDS_TO_IGNORE, document),
520
+ schema: omit(FIELDS_TO_IGNORE, attributesSchema),
521
+ componentsSchemas,
522
+ relatedDocumentId: documentContext.documentId,
523
+ locale,
524
+ status
525
+ });
526
+ });
527
+ });
528
+ return result;
529
+ });
530
+ const retentionDays = serviceUtils.getRetentionDays();
531
+ state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
532
+ const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
533
+ const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
534
+ query.deleteMany({
535
+ where: {
536
+ created_at: {
537
+ $lt: expirationDate.toISOString()
538
+ }
539
+ }
540
+ });
541
+ });
542
+ state.isInitialized = true;
543
+ },
544
+ async destroy() {
545
+ if (state.deleteExpiredJob) {
546
+ state.deleteExpiredJob.cancel();
547
+ }
548
+ }
549
+ };
550
+ };
507
551
  const services$1 = {
508
- history: createHistoryService
552
+ history: createHistoryService,
553
+ lifecycles: createLifecyclesService
509
554
  };
510
555
  const info = { pluginName: "content-manager", type: "admin" };
511
556
  const historyVersionRouter = {
@@ -585,10 +630,10 @@ const getFeature = () => {
585
630
  strapi2.get("models").add(historyVersion);
586
631
  },
587
632
  bootstrap({ strapi: strapi2 }) {
588
- getService(strapi2, "history").bootstrap();
633
+ getService(strapi2, "lifecycles").bootstrap();
589
634
  },
590
635
  destroy({ strapi: strapi2 }) {
591
- getService(strapi2, "history").destroy();
636
+ getService(strapi2, "lifecycles").destroy();
592
637
  },
593
638
  controllers: controllers$1,
594
639
  services: services$1,
@@ -1407,7 +1452,7 @@ const { PaginationError, ValidationError } = errors;
1407
1452
  const TYPES = ["singleType", "collectionType"];
1408
1453
  const kindSchema = yup$1.string().oneOf(TYPES).nullable();
1409
1454
  const bulkActionInputSchema = yup$1.object({
1410
- ids: yup$1.array().of(yup$1.strapiID()).min(1).required()
1455
+ documentIds: yup$1.array().of(yup$1.strapiID()).min(1).required()
1411
1456
  }).required();
1412
1457
  const generateUIDInputSchema = yup$1.object({
1413
1458
  contentTypeUID: yup$1.string().required(),
@@ -1587,7 +1632,7 @@ const collectionTypes = {
1587
1632
  const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
1588
1633
  const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
1589
1634
  const { locale, status } = getDocumentLocaleAndStatus(query);
1590
- const { results: documents, pagination } = await documentManager2.findPage(
1635
+ const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
1591
1636
  { ...permissionQuery, populate, locale, status },
1592
1637
  model
1593
1638
  );
@@ -1608,7 +1653,7 @@ const collectionTypes = {
1608
1653
  );
1609
1654
  ctx.body = {
1610
1655
  results,
1611
- pagination
1656
+ pagination: pagination2
1612
1657
  };
1613
1658
  },
1614
1659
  async findOne(ctx) {
@@ -1783,17 +1828,18 @@ const collectionTypes = {
1783
1828
  const { userAbility } = ctx.state;
1784
1829
  const { model } = ctx.params;
1785
1830
  const { body } = ctx.request;
1786
- const { ids } = body;
1831
+ const { documentIds } = body;
1787
1832
  await validateBulkActionInput(body);
1788
1833
  const documentManager2 = getService$1("document-manager");
1789
1834
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1790
1835
  if (permissionChecker2.cannot.publish()) {
1791
1836
  return ctx.forbidden();
1792
1837
  }
1793
- const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1794
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1795
- const entityPromises = ids.map((id) => documentManager2.findOne(id, model, { populate }));
1796
- const entities = await Promise.all(entityPromises);
1838
+ const { locale } = getDocumentLocaleAndStatus(body);
1839
+ const entityPromises = documentIds.map(
1840
+ (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: false })
1841
+ );
1842
+ const entities = (await Promise.all(entityPromises)).flat();
1797
1843
  for (const entity of entities) {
1798
1844
  if (!entity) {
1799
1845
  return ctx.notFound();
@@ -1802,24 +1848,26 @@ const collectionTypes = {
1802
1848
  return ctx.forbidden();
1803
1849
  }
1804
1850
  }
1805
- const { count } = await documentManager2.publishMany(entities, model);
1851
+ const entitiesIds = entities.map((document) => document.documentId);
1852
+ const { count } = await documentManager2.publishMany(entitiesIds, model, { locale });
1806
1853
  ctx.body = { count };
1807
1854
  },
1808
1855
  async bulkUnpublish(ctx) {
1809
1856
  const { userAbility } = ctx.state;
1810
1857
  const { model } = ctx.params;
1811
1858
  const { body } = ctx.request;
1812
- const { ids } = body;
1859
+ const { documentIds } = body;
1813
1860
  await validateBulkActionInput(body);
1814
1861
  const documentManager2 = getService$1("document-manager");
1815
1862
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1816
1863
  if (permissionChecker2.cannot.unpublish()) {
1817
1864
  return ctx.forbidden();
1818
1865
  }
1819
- const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1820
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1821
- const entityPromises = ids.map((id) => documentManager2.findOne(id, model, { populate }));
1822
- const entities = await Promise.all(entityPromises);
1866
+ const { locale } = getDocumentLocaleAndStatus(body);
1867
+ const entityPromises = documentIds.map(
1868
+ (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1869
+ );
1870
+ const entities = (await Promise.all(entityPromises)).flat();
1823
1871
  for (const entity of entities) {
1824
1872
  if (!entity) {
1825
1873
  return ctx.notFound();
@@ -1828,7 +1876,8 @@ const collectionTypes = {
1828
1876
  return ctx.forbidden();
1829
1877
  }
1830
1878
  }
1831
- const { count } = await documentManager2.unpublishMany(entities, model);
1879
+ const entitiesIds = entities.map((document) => document.documentId);
1880
+ const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
1832
1881
  ctx.body = { count };
1833
1882
  },
1834
1883
  async unpublish(ctx) {
@@ -1908,7 +1957,7 @@ const collectionTypes = {
1908
1957
  const { userAbility } = ctx.state;
1909
1958
  const { model } = ctx.params;
1910
1959
  const { query, body } = ctx.request;
1911
- const { ids } = body;
1960
+ const { documentIds } = body;
1912
1961
  await validateBulkActionInput(body);
1913
1962
  const documentManager2 = getService$1("document-manager");
1914
1963
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
@@ -1916,14 +1965,22 @@ const collectionTypes = {
1916
1965
  return ctx.forbidden();
1917
1966
  }
1918
1967
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
1919
- const idsWhereClause = { id: { $in: ids } };
1920
- const params = {
1921
- ...permissionQuery,
1922
- filters: {
1923
- $and: [idsWhereClause].concat(permissionQuery.filters || [])
1968
+ const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1969
+ const { locale } = getDocumentLocaleAndStatus(body);
1970
+ const documentLocales = await documentManager2.findLocales(documentIds, model, {
1971
+ populate,
1972
+ locale
1973
+ });
1974
+ if (documentLocales.length === 0) {
1975
+ return ctx.notFound();
1976
+ }
1977
+ for (const document of documentLocales) {
1978
+ if (permissionChecker2.cannot.delete(document)) {
1979
+ return ctx.forbidden();
1924
1980
  }
1925
- };
1926
- const { count } = await documentManager2.deleteMany(params, model);
1981
+ }
1982
+ const localeDocumentsIds = documentLocales.map((document) => document.documentId);
1983
+ const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
1927
1984
  ctx.body = { count };
1928
1985
  },
1929
1986
  async countDraftRelations(ctx) {
@@ -1951,27 +2008,26 @@ const collectionTypes = {
1951
2008
  },
1952
2009
  async countManyEntriesDraftRelations(ctx) {
1953
2010
  const { userAbility } = ctx.state;
1954
- const ids = ctx.request.query.ids;
1955
- const locale = ctx.request.query.locale;
2011
+ const { documentIds, locale } = ctx.request.query;
1956
2012
  const { model } = ctx.params;
1957
2013
  const documentManager2 = getService$1("document-manager");
1958
2014
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1959
2015
  if (permissionChecker2.cannot.read()) {
1960
2016
  return ctx.forbidden();
1961
2017
  }
1962
- const entities = await documentManager2.findMany(
2018
+ const documents = await documentManager2.findMany(
1963
2019
  {
1964
2020
  filters: {
1965
- id: ids
2021
+ documentId: { $in: documentIds }
1966
2022
  },
1967
2023
  locale
1968
2024
  },
1969
2025
  model
1970
2026
  );
1971
- if (!entities) {
2027
+ if (!documents) {
1972
2028
  return ctx.notFound();
1973
2029
  }
1974
- const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
2030
+ const number = await documentManager2.countManyEntriesDraftRelations(documentIds, model, locale);
1975
2031
  return {
1976
2032
  data: number
1977
2033
  };
@@ -3971,26 +4027,9 @@ const sumDraftCounts = (entity, uid2) => {
3971
4027
  }, 0);
3972
4028
  };
3973
4029
  const { ApplicationError } = errors;
3974
- const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
3975
4030
  const { PUBLISHED_AT_ATTRIBUTE } = contentTypes$1.constants;
3976
4031
  const omitPublishedAtField = omit(PUBLISHED_AT_ATTRIBUTE);
3977
4032
  const omitIdField = omit("id");
3978
- const emitEvent = async (uid2, event, document) => {
3979
- const modelDef = strapi.getModel(uid2);
3980
- const sanitizedDocument = await sanitize.sanitizers.defaultSanitizeOutput(
3981
- {
3982
- schema: modelDef,
3983
- getModel(uid22) {
3984
- return strapi.getModel(uid22);
3985
- }
3986
- },
3987
- document
3988
- );
3989
- strapi.eventHub.emit(event, {
3990
- model: modelDef.modelName,
3991
- entry: sanitizedDocument
3992
- });
3993
- };
3994
4033
  const documentManager = ({ strapi: strapi2 }) => {
3995
4034
  return {
3996
4035
  async findOne(id, uid2, opts = {}) {
@@ -4009,6 +4048,9 @@ const documentManager = ({ strapi: strapi2 }) => {
4009
4048
  } else if (opts.locale && opts.locale !== "*") {
4010
4049
  where.locale = opts.locale;
4011
4050
  }
4051
+ if (typeof opts.isPublished === "boolean") {
4052
+ where.publishedAt = { $notNull: opts.isPublished };
4053
+ }
4012
4054
  return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
4013
4055
  },
4014
4056
  async findMany(opts, uid2) {
@@ -4016,20 +4058,16 @@ const documentManager = ({ strapi: strapi2 }) => {
4016
4058
  return strapi2.documents(uid2).findMany(params);
4017
4059
  },
4018
4060
  async findPage(opts, uid2) {
4019
- const page = Number(opts?.page) || 1;
4020
- const pageSize = Number(opts?.pageSize) || 10;
4061
+ const params = pagination.withDefaultPagination(opts || {}, {
4062
+ maxLimit: 1e3
4063
+ });
4021
4064
  const [documents, total = 0] = await Promise.all([
4022
- strapi2.documents(uid2).findMany(opts),
4023
- strapi2.documents(uid2).count(opts)
4065
+ strapi2.documents(uid2).findMany(params),
4066
+ strapi2.documents(uid2).count(params)
4024
4067
  ]);
4025
4068
  return {
4026
4069
  results: documents,
4027
- pagination: {
4028
- page,
4029
- pageSize,
4030
- pageCount: Math.ceil(total / pageSize),
4031
- total
4032
- }
4070
+ pagination: pagination.transformPagedPaginationInfo(params, total)
4033
4071
  };
4034
4072
  },
4035
4073
  async create(uid2, opts = {}) {
@@ -4075,70 +4113,38 @@ const documentManager = ({ strapi: strapi2 }) => {
4075
4113
  return {};
4076
4114
  },
4077
4115
  // FIXME: handle relations
4078
- async deleteMany(opts, uid2) {
4079
- const docs = await strapi2.documents(uid2).findMany(opts);
4080
- for (const doc of docs) {
4081
- await strapi2.documents(uid2).delete({ documentId: doc.documentId });
4082
- }
4083
- return { count: docs.length };
4116
+ async deleteMany(documentIds, uid2, opts) {
4117
+ const deletedEntries = await strapi2.db.transaction(async () => {
4118
+ return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
4119
+ });
4120
+ return { count: deletedEntries.length };
4084
4121
  },
4085
4122
  async publish(id, uid2, opts = {}) {
4086
4123
  const populate = await buildDeepPopulate(uid2);
4087
4124
  const params = { ...opts, populate };
4088
4125
  return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries.at(0));
4089
4126
  },
4090
- async publishMany(entities, uid2) {
4091
- if (!entities.length) {
4092
- return null;
4093
- }
4094
- await Promise.all(
4095
- entities.map((document) => {
4096
- return strapi2.entityValidator.validateEntityCreation(
4097
- strapi2.getModel(uid2),
4098
- document,
4099
- void 0,
4100
- // @ts-expect-error - FIXME: entity here is unnecessary
4101
- document
4102
- );
4103
- })
4104
- );
4105
- const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
4106
- const filters = { id: { $in: entitiesToPublish } };
4107
- const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
4108
- const populate = await buildDeepPopulate(uid2);
4109
- const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
4110
- where: filters,
4111
- data
4112
- });
4113
- const publishedEntities = await strapi2.db.query(uid2).findMany({
4114
- where: filters,
4115
- populate
4127
+ async publishMany(documentIds, uid2, opts = {}) {
4128
+ const publishedEntries = await strapi2.db.transaction(async () => {
4129
+ return Promise.all(
4130
+ documentIds.map(
4131
+ (id) => strapi2.documents(uid2).publish({ ...opts, documentId: id }).then((result) => result?.entries)
4132
+ )
4133
+ );
4116
4134
  });
4117
- await Promise.all(
4118
- publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
4119
- );
4120
- return publishedEntitiesCount;
4135
+ const publishedEntitiesCount = publishedEntries.flat().filter(Boolean).length;
4136
+ return { count: publishedEntitiesCount };
4121
4137
  },
4122
- async unpublishMany(documents, uid2) {
4123
- if (!documents.length) {
4124
- return null;
4125
- }
4126
- const entitiesToUnpublish = documents.filter((doc) => doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
4127
- const filters = { id: { $in: entitiesToUnpublish } };
4128
- const data = { [PUBLISHED_AT_ATTRIBUTE]: null };
4129
- const populate = await buildDeepPopulate(uid2);
4130
- const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
4131
- where: filters,
4132
- data
4133
- });
4134
- const unpublishedEntities = await strapi2.db.query(uid2).findMany({
4135
- where: filters,
4136
- populate
4138
+ async unpublishMany(documentIds, uid2, opts = {}) {
4139
+ const unpublishedEntries = await strapi2.db.transaction(async () => {
4140
+ return Promise.all(
4141
+ documentIds.map(
4142
+ (id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
4143
+ )
4144
+ );
4137
4145
  });
4138
- await Promise.all(
4139
- unpublishedEntities.map((doc) => emitEvent(uid2, ENTRY_UNPUBLISH, doc))
4140
- );
4141
- return unpublishedEntitiesCount;
4146
+ const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
4147
+ return { count: unpublishedEntitiesCount };
4142
4148
  },
4143
4149
  async unpublish(id, uid2, opts = {}) {
4144
4150
  const populate = await buildDeepPopulate(uid2);
@@ -4163,19 +4169,19 @@ const documentManager = ({ strapi: strapi2 }) => {
4163
4169
  }
4164
4170
  return sumDraftCounts(document, uid2);
4165
4171
  },
4166
- async countManyEntriesDraftRelations(ids, uid2, locale) {
4172
+ async countManyEntriesDraftRelations(documentIds, uid2, locale) {
4167
4173
  const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
4168
4174
  if (!hasRelations) {
4169
4175
  return 0;
4170
4176
  }
4171
- const entities = await strapi2.db.query(uid2).findMany({
4177
+ const documents = await strapi2.documents(uid2).findMany({
4172
4178
  populate,
4173
- where: {
4174
- id: { $in: ids },
4175
- ...locale ? { locale } : {}
4176
- }
4179
+ filters: {
4180
+ documentId: documentIds
4181
+ },
4182
+ locale
4177
4183
  });
4178
- const totalNumberDraftRelations = entities.reduce(
4184
+ const totalNumberDraftRelations = documents.reduce(
4179
4185
  (count, entity) => sumDraftCounts(entity, uid2) + count,
4180
4186
  0
4181
4187
  );