@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
@@ -138,40 +138,65 @@ const FIELDS_TO_IGNORE = [
138
138
  "strapi_stage",
139
139
  "strapi_assignee"
140
140
  ];
141
- const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
142
- const sanitizedContentTypeSchemaAttributes = fp.omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
143
- const reduceDifferenceToAttributesObject = (diffKeys, source) => {
144
- return diffKeys.reduce((previousAttributesObject, diffKey) => {
145
- previousAttributesObject[diffKey] = source[diffKey];
146
- return previousAttributesObject;
147
- }, {});
148
- };
149
- const versionSchemaKeys = Object.keys(versionSchemaAttributes);
150
- const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
151
- const uniqueToContentType = fp.difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
152
- const added = reduceDifferenceToAttributesObject(
153
- uniqueToContentType,
154
- sanitizedContentTypeSchemaAttributes
155
- );
156
- const uniqueToVersion = fp.difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
157
- const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
158
- return { added, removed };
159
- };
160
141
  const DEFAULT_RETENTION_DAYS = 90;
161
- const createHistoryService = ({ strapi: strapi2 }) => {
162
- const state = {
163
- deleteExpiredJob: null,
164
- isInitialized: false
142
+ const createServiceUtils = ({ strapi: strapi2 }) => {
143
+ const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
144
+ const sanitizedContentTypeSchemaAttributes = fp.omit(
145
+ FIELDS_TO_IGNORE,
146
+ contentTypeSchemaAttributes
147
+ );
148
+ const reduceDifferenceToAttributesObject = (diffKeys, source) => {
149
+ return diffKeys.reduce(
150
+ (previousAttributesObject, diffKey) => {
151
+ previousAttributesObject[diffKey] = source[diffKey];
152
+ return previousAttributesObject;
153
+ },
154
+ {}
155
+ );
156
+ };
157
+ const versionSchemaKeys = Object.keys(versionSchemaAttributes);
158
+ const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
159
+ const uniqueToContentType = fp.difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
160
+ const added = reduceDifferenceToAttributesObject(
161
+ uniqueToContentType,
162
+ sanitizedContentTypeSchemaAttributes
163
+ );
164
+ const uniqueToVersion = fp.difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
165
+ const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
166
+ return { added, removed };
165
167
  };
166
- const query = strapi2.db.query(HISTORY_VERSION_UID);
167
- const getRetentionDays = (strapi22) => {
168
- const featureConfig = strapi22.ee.features.get("cms-content-history");
169
- const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
170
- const userRetentionDays = strapi22.config.get("admin.history.retentionDays");
171
- if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
172
- return userRetentionDays;
168
+ const getRelationRestoreValue = async (versionRelationData, attribute) => {
169
+ if (Array.isArray(versionRelationData)) {
170
+ if (versionRelationData.length === 0)
171
+ return versionRelationData;
172
+ const existingAndMissingRelations = await Promise.all(
173
+ versionRelationData.map((relation) => {
174
+ return strapi2.documents(attribute.target).findOne({
175
+ documentId: relation.documentId,
176
+ locale: relation.locale || void 0
177
+ });
178
+ })
179
+ );
180
+ return existingAndMissingRelations.filter(
181
+ (relation) => relation !== null
182
+ );
173
183
  }
174
- return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
184
+ return strapi2.documents(attribute.target).findOne({
185
+ documentId: versionRelationData.documentId,
186
+ locale: versionRelationData.locale || void 0
187
+ });
188
+ };
189
+ const getMediaRestoreValue = async (versionRelationData, attribute) => {
190
+ if (attribute.multiple) {
191
+ const existingAndMissingMedias = await Promise.all(
192
+ // @ts-expect-error Fix the type definitions so this isn't any
193
+ versionRelationData.map((media) => {
194
+ return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
195
+ })
196
+ );
197
+ return existingAndMissingMedias.filter((media) => media != null);
198
+ }
199
+ return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
175
200
  };
176
201
  const localesService = strapi2.plugin("i18n")?.service("locales");
177
202
  const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
@@ -187,6 +212,15 @@ const createHistoryService = ({ strapi: strapi2 }) => {
187
212
  {}
188
213
  );
189
214
  };
215
+ const getRetentionDays = () => {
216
+ const featureConfig = strapi2.ee.features.get("cms-content-history");
217
+ const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
218
+ const userRetentionDays = strapi2.config.get("admin.history.retentionDays");
219
+ if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
220
+ return userRetentionDays;
221
+ }
222
+ return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
223
+ };
190
224
  const getVersionStatus = async (contentTypeUid, document) => {
191
225
  const documentMetadataService = strapi2.plugin("content-manager").service("document-metadata");
192
226
  const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
@@ -228,80 +262,68 @@ const createHistoryService = ({ strapi: strapi2 }) => {
228
262
  return acc;
229
263
  }, {});
230
264
  };
231
- return {
232
- async bootstrap() {
233
- if (state.isInitialized) {
234
- return;
235
- }
236
- strapi2.documents.use(async (context, next) => {
237
- if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
238
- return next();
265
+ const buildMediaResponse = async (values) => {
266
+ return values.slice(0, 25).reduce(
267
+ async (currentRelationDataPromise, entry) => {
268
+ const currentRelationData = await currentRelationDataPromise;
269
+ if (!entry) {
270
+ return currentRelationData;
239
271
  }
240
- if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
241
- return next();
272
+ const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
273
+ if (relatedEntry) {
274
+ currentRelationData.results.push(relatedEntry);
275
+ } else {
276
+ currentRelationData.meta.missingCount += 1;
242
277
  }
243
- const contentTypeUid = context.contentType.uid;
244
- if (!contentTypeUid.startsWith("api::")) {
245
- return next();
278
+ return currentRelationData;
279
+ },
280
+ Promise.resolve({
281
+ results: [],
282
+ meta: { missingCount: 0 }
283
+ })
284
+ );
285
+ };
286
+ const buildRelationReponse = async (values, attributeSchema) => {
287
+ return values.slice(0, 25).reduce(
288
+ async (currentRelationDataPromise, entry) => {
289
+ const currentRelationData = await currentRelationDataPromise;
290
+ if (!entry) {
291
+ return currentRelationData;
246
292
  }
247
- const result = await next();
248
- const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
249
- const defaultLocale = await getDefaultLocale();
250
- const locale = documentContext.locale || defaultLocale;
251
- const document = await strapi2.documents(contentTypeUid).findOne({
252
- documentId: documentContext.documentId,
253
- locale,
254
- populate: getDeepPopulate2(contentTypeUid)
255
- });
256
- const status = await getVersionStatus(contentTypeUid, document);
257
- const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
258
- const componentsSchemas = Object.keys(
259
- attributesSchema
260
- ).reduce((currentComponentSchemas, key) => {
261
- const fieldSchema = attributesSchema[key];
262
- if (fieldSchema.type === "component") {
263
- const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
264
- return {
265
- ...currentComponentSchemas,
266
- [fieldSchema.component]: componentSchema
267
- };
268
- }
269
- return currentComponentSchemas;
270
- }, {});
271
- await strapi2.db.transaction(async ({ onCommit }) => {
272
- onCommit(() => {
273
- this.createVersion({
274
- contentType: contentTypeUid,
275
- data: fp.omit(FIELDS_TO_IGNORE, document),
276
- schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
277
- componentsSchemas,
278
- relatedDocumentId: documentContext.documentId,
279
- locale,
280
- status
281
- });
293
+ const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
294
+ if (relatedEntry) {
295
+ currentRelationData.results.push({
296
+ ...relatedEntry,
297
+ status: await getVersionStatus(attributeSchema.target, relatedEntry)
282
298
  });
283
- });
284
- return result;
285
- });
286
- const retentionDays = getRetentionDays(strapi2);
287
- state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
288
- const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
289
- const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
290
- query.deleteMany({
291
- where: {
292
- created_at: {
293
- $lt: expirationDate.toISOString()
294
- }
295
- }
296
- });
297
- });
298
- state.isInitialized = true;
299
- },
300
- async destroy() {
301
- if (state.deleteExpiredJob) {
302
- state.deleteExpiredJob.cancel();
303
- }
304
- },
299
+ } else {
300
+ currentRelationData.meta.missingCount += 1;
301
+ }
302
+ return currentRelationData;
303
+ },
304
+ Promise.resolve({
305
+ results: [],
306
+ meta: { missingCount: 0 }
307
+ })
308
+ );
309
+ };
310
+ return {
311
+ getSchemaAttributesDiff,
312
+ getRelationRestoreValue,
313
+ getMediaRestoreValue,
314
+ getDefaultLocale,
315
+ getLocaleDictionary,
316
+ getRetentionDays,
317
+ getVersionStatus,
318
+ getDeepPopulate: getDeepPopulate2,
319
+ buildMediaResponse,
320
+ buildRelationReponse
321
+ };
322
+ };
323
+ const createHistoryService = ({ strapi: strapi2 }) => {
324
+ const query = strapi2.db.query(HISTORY_VERSION_UID);
325
+ const serviceUtils = createServiceUtils({ strapi: strapi2 });
326
+ return {
305
327
  async createVersion(historyVersionData) {
306
328
  await query.create({
307
329
  data: {
@@ -312,7 +334,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
312
334
  });
313
335
  },
314
336
  async findVersionsPage(params) {
315
- const locale = params.query.locale || await getDefaultLocale();
337
+ const locale = params.query.locale || await serviceUtils.getDefaultLocale();
316
338
  const [{ results, pagination }, localeDictionary] = await Promise.all([
317
339
  query.findPage({
318
340
  ...params.query,
@@ -326,78 +348,34 @@ const createHistoryService = ({ strapi: strapi2 }) => {
326
348
  populate: ["createdBy"],
327
349
  orderBy: [{ createdAt: "desc" }]
328
350
  }),
329
- getLocaleDictionary()
351
+ serviceUtils.getLocaleDictionary()
330
352
  ]);
331
- const buildRelationReponse = async (values, attributeSchema) => {
332
- return values.slice(0, 25).reduce(
333
- async (currentRelationDataPromise, entry) => {
334
- const currentRelationData = await currentRelationDataPromise;
335
- if (!entry) {
336
- return currentRelationData;
337
- }
338
- const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
339
- const permissionChecker2 = getService$1("permission-checker").create({
340
- userAbility: params.state.userAbility,
341
- model: attributeSchema.target
342
- });
343
- const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
344
- if (sanitizedEntry) {
345
- currentRelationData.results.push({
346
- ...sanitizedEntry,
347
- status: await getVersionStatus(attributeSchema.target, sanitizedEntry)
348
- });
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
- const buildMediaResponse = async (values) => {
361
- return values.slice(0, 25).reduce(
362
- async (currentRelationDataPromise, entry) => {
363
- const currentRelationData = await currentRelationDataPromise;
364
- if (!entry) {
365
- return currentRelationData;
366
- }
367
- const permissionChecker2 = getService$1("permission-checker").create({
368
- userAbility: params.state.userAbility,
369
- model: "plugin::upload.file"
370
- });
371
- const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
372
- const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
373
- if (sanitizedEntry) {
374
- currentRelationData.results.push(sanitizedEntry);
375
- } else {
376
- currentRelationData.meta.missingCount += 1;
377
- }
378
- return currentRelationData;
379
- },
380
- Promise.resolve({
381
- results: [],
382
- meta: { missingCount: 0 }
383
- })
384
- );
385
- };
386
353
  const populateEntryRelations = async (entry) => {
387
354
  const entryWithRelations = await Object.entries(entry.schema).reduce(
388
355
  async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
389
356
  const attributeValue = entry.data[attributeKey];
390
357
  const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
391
358
  if (attributeSchema.type === "media") {
359
+ const permissionChecker2 = getService$1("permission-checker").create({
360
+ userAbility: params.state.userAbility,
361
+ model: "plugin::upload.file"
362
+ });
363
+ const response = await serviceUtils.buildMediaResponse(attributeValues);
364
+ const sanitizedResults = await Promise.all(
365
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
366
+ );
392
367
  return {
393
368
  ...await currentDataWithRelations,
394
- [attributeKey]: await buildMediaResponse(attributeValues)
369
+ [attributeKey]: {
370
+ results: sanitizedResults,
371
+ meta: response.meta
372
+ }
395
373
  };
396
374
  }
397
375
  if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
398
376
  if (attributeSchema.target === "admin::user") {
399
377
  const adminUsers = await Promise.all(
400
- attributeValues.map(async (userToPopulate) => {
378
+ attributeValues.map((userToPopulate) => {
401
379
  if (userToPopulate == null) {
402
380
  return null;
403
381
  }
@@ -414,9 +392,23 @@ const createHistoryService = ({ strapi: strapi2 }) => {
414
392
  [attributeKey]: adminUsers
415
393
  };
416
394
  }
395
+ const permissionChecker2 = getService$1("permission-checker").create({
396
+ userAbility: params.state.userAbility,
397
+ model: attributeSchema.target
398
+ });
399
+ const response = await serviceUtils.buildRelationReponse(
400
+ attributeValues,
401
+ attributeSchema
402
+ );
403
+ const sanitizedResults = await Promise.all(
404
+ response.results.map((media) => permissionChecker2.sanitizeOutput(media))
405
+ );
417
406
  return {
418
407
  ...await currentDataWithRelations,
419
- [attributeKey]: await buildRelationReponse(attributeValues, attributeSchema)
408
+ [attributeKey]: {
409
+ results: sanitizedResults,
410
+ meta: response.meta
411
+ }
420
412
  };
421
413
  }
422
414
  return currentDataWithRelations;
@@ -431,7 +423,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
431
423
  ...result,
432
424
  data: await populateEntryRelations(result),
433
425
  meta: {
434
- unknownAttributes: getSchemaAttributesDiff(
426
+ unknownAttributes: serviceUtils.getSchemaAttributesDiff(
435
427
  result.schema,
436
428
  strapi2.getModel(params.query.contentType).attributes
437
429
  )
@@ -448,7 +440,10 @@ const createHistoryService = ({ strapi: strapi2 }) => {
448
440
  async restoreVersion(versionId) {
449
441
  const version = await query.findOne({ where: { id: versionId } });
450
442
  const contentTypeSchemaAttributes = strapi2.getModel(version.contentType).attributes;
451
- const schemaDiff = getSchemaAttributesDiff(version.schema, contentTypeSchemaAttributes);
443
+ const schemaDiff = serviceUtils.getSchemaAttributesDiff(
444
+ version.schema,
445
+ contentTypeSchemaAttributes
446
+ );
452
447
  const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(
453
448
  (currentData, addedKey) => {
454
449
  currentData[addedKey] = null;
@@ -461,61 +456,26 @@ const createHistoryService = ({ strapi: strapi2 }) => {
461
456
  FIELDS_TO_IGNORE,
462
457
  contentTypeSchemaAttributes
463
458
  );
464
- const dataWithoutMissingRelations = await Object.entries(sanitizedSchemaAttributes).reduce(
465
- async (previousRelationAttributesPromise, [name, attribute]) => {
466
- const previousRelationAttributes = await previousRelationAttributesPromise;
467
- const relationData = version.data[name];
468
- if (relationData === null) {
459
+ const reducer = strapiUtils.async.reduce(Object.entries(sanitizedSchemaAttributes));
460
+ const dataWithoutMissingRelations = await reducer(
461
+ async (previousRelationAttributes, [name, attribute]) => {
462
+ const versionRelationData = version.data[name];
463
+ if (!versionRelationData) {
469
464
  return previousRelationAttributes;
470
465
  }
471
466
  if (attribute.type === "relation" && // TODO: handle polymorphic relations
472
467
  attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
473
- if (Array.isArray(relationData)) {
474
- if (relationData.length === 0)
475
- return previousRelationAttributes;
476
- const existingAndMissingRelations = await Promise.all(
477
- relationData.map((relation) => {
478
- return strapi2.documents(attribute.target).findOne({
479
- documentId: relation.documentId,
480
- locale: relation.locale || void 0
481
- });
482
- })
483
- );
484
- const existingRelations = existingAndMissingRelations.filter(
485
- (relation) => relation !== null
486
- );
487
- previousRelationAttributes[name] = existingRelations;
488
- } else {
489
- const existingRelation = await strapi2.documents(attribute.target).findOne({
490
- documentId: relationData.documentId,
491
- locale: relationData.locale || void 0
492
- });
493
- if (!existingRelation) {
494
- previousRelationAttributes[name] = null;
495
- }
496
- }
468
+ const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
469
+ previousRelationAttributes[name] = data2;
497
470
  }
498
471
  if (attribute.type === "media") {
499
- if (attribute.multiple) {
500
- const existingAndMissingMedias = await Promise.all(
501
- // @ts-expect-error Fix the type definitions so this isn't any
502
- relationData.map((media) => {
503
- return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
504
- })
505
- );
506
- const existingMedias = existingAndMissingMedias.filter((media) => media != null);
507
- previousRelationAttributes[name] = existingMedias;
508
- } else {
509
- const existingMedia = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: version.data[name].id } });
510
- if (!existingMedia) {
511
- previousRelationAttributes[name] = null;
512
- }
513
- }
472
+ const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
473
+ previousRelationAttributes[name] = data2;
514
474
  }
515
475
  return previousRelationAttributes;
516
476
  },
517
477
  // Clone to avoid mutating the original version data
518
- Promise.resolve(structuredClone(dataWithoutAddedAttributes))
478
+ structuredClone(dataWithoutAddedAttributes)
519
479
  );
520
480
  const data = fp.omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
521
481
  const restoredDocument = await strapi2.documents(version.contentType).update({
@@ -530,8 +490,93 @@ const createHistoryService = ({ strapi: strapi2 }) => {
530
490
  }
531
491
  };
532
492
  };
493
+ const createLifecyclesService = ({ strapi: strapi2 }) => {
494
+ const state = {
495
+ deleteExpiredJob: null,
496
+ isInitialized: false
497
+ };
498
+ const query = strapi2.db.query(HISTORY_VERSION_UID);
499
+ const historyService = getService(strapi2, "history");
500
+ const serviceUtils = createServiceUtils({ strapi: strapi2 });
501
+ return {
502
+ async bootstrap() {
503
+ if (state.isInitialized) {
504
+ return;
505
+ }
506
+ strapi2.documents.use(async (context, next) => {
507
+ if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
508
+ return next();
509
+ }
510
+ if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
511
+ return next();
512
+ }
513
+ const contentTypeUid = context.contentType.uid;
514
+ if (!contentTypeUid.startsWith("api::")) {
515
+ return next();
516
+ }
517
+ const result = await next();
518
+ const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
519
+ const defaultLocale = await serviceUtils.getDefaultLocale();
520
+ const locale = documentContext.locale || defaultLocale;
521
+ const document = await strapi2.documents(contentTypeUid).findOne({
522
+ documentId: documentContext.documentId,
523
+ locale,
524
+ populate: serviceUtils.getDeepPopulate(contentTypeUid)
525
+ });
526
+ const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
527
+ const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
528
+ const componentsSchemas = Object.keys(
529
+ attributesSchema
530
+ ).reduce((currentComponentSchemas, key) => {
531
+ const fieldSchema = attributesSchema[key];
532
+ if (fieldSchema.type === "component") {
533
+ const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
534
+ return {
535
+ ...currentComponentSchemas,
536
+ [fieldSchema.component]: componentSchema
537
+ };
538
+ }
539
+ return currentComponentSchemas;
540
+ }, {});
541
+ await strapi2.db.transaction(async ({ onCommit }) => {
542
+ onCommit(() => {
543
+ historyService.createVersion({
544
+ contentType: contentTypeUid,
545
+ data: fp.omit(FIELDS_TO_IGNORE, document),
546
+ schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
547
+ componentsSchemas,
548
+ relatedDocumentId: documentContext.documentId,
549
+ locale,
550
+ status
551
+ });
552
+ });
553
+ });
554
+ return result;
555
+ });
556
+ const retentionDays = serviceUtils.getRetentionDays();
557
+ state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
558
+ const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
559
+ const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
560
+ query.deleteMany({
561
+ where: {
562
+ created_at: {
563
+ $lt: expirationDate.toISOString()
564
+ }
565
+ }
566
+ });
567
+ });
568
+ state.isInitialized = true;
569
+ },
570
+ async destroy() {
571
+ if (state.deleteExpiredJob) {
572
+ state.deleteExpiredJob.cancel();
573
+ }
574
+ }
575
+ };
576
+ };
533
577
  const services$1 = {
534
- history: createHistoryService
578
+ history: createHistoryService,
579
+ lifecycles: createLifecyclesService
535
580
  };
536
581
  const info = { pluginName: "content-manager", type: "admin" };
537
582
  const historyVersionRouter = {
@@ -611,10 +656,10 @@ const getFeature = () => {
611
656
  strapi2.get("models").add(historyVersion);
612
657
  },
613
658
  bootstrap({ strapi: strapi2 }) {
614
- getService(strapi2, "history").bootstrap();
659
+ getService(strapi2, "lifecycles").bootstrap();
615
660
  },
616
661
  destroy({ strapi: strapi2 }) {
617
- getService(strapi2, "history").destroy();
662
+ getService(strapi2, "lifecycles").destroy();
618
663
  },
619
664
  controllers: controllers$1,
620
665
  services: services$1,
@@ -1433,7 +1478,7 @@ const { PaginationError, ValidationError } = strapiUtils.errors;
1433
1478
  const TYPES = ["singleType", "collectionType"];
1434
1479
  const kindSchema = strapiUtils.yup.string().oneOf(TYPES).nullable();
1435
1480
  const bulkActionInputSchema = strapiUtils.yup.object({
1436
- ids: strapiUtils.yup.array().of(strapiUtils.yup.strapiID()).min(1).required()
1481
+ documentIds: strapiUtils.yup.array().of(strapiUtils.yup.strapiID()).min(1).required()
1437
1482
  }).required();
1438
1483
  const generateUIDInputSchema = strapiUtils.yup.object({
1439
1484
  contentTypeUID: strapiUtils.yup.string().required(),
@@ -1809,17 +1854,18 @@ const collectionTypes = {
1809
1854
  const { userAbility } = ctx.state;
1810
1855
  const { model } = ctx.params;
1811
1856
  const { body } = ctx.request;
1812
- const { ids } = body;
1857
+ const { documentIds } = body;
1813
1858
  await validateBulkActionInput(body);
1814
1859
  const documentManager2 = getService$1("document-manager");
1815
1860
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1816
1861
  if (permissionChecker2.cannot.publish()) {
1817
1862
  return ctx.forbidden();
1818
1863
  }
1819
- const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1820
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
1821
- const entityPromises = ids.map((id) => documentManager2.findOne(id, model, { populate }));
1822
- const entities = await Promise.all(entityPromises);
1864
+ const { locale } = getDocumentLocaleAndStatus(body);
1865
+ const entityPromises = documentIds.map(
1866
+ (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: false })
1867
+ );
1868
+ const entities = (await Promise.all(entityPromises)).flat();
1823
1869
  for (const entity of entities) {
1824
1870
  if (!entity) {
1825
1871
  return ctx.notFound();
@@ -1828,24 +1874,26 @@ const collectionTypes = {
1828
1874
  return ctx.forbidden();
1829
1875
  }
1830
1876
  }
1831
- const { count } = await documentManager2.publishMany(entities, model);
1877
+ const entitiesIds = entities.map((document) => document.documentId);
1878
+ const { count } = await documentManager2.publishMany(entitiesIds, model, { locale });
1832
1879
  ctx.body = { count };
1833
1880
  },
1834
1881
  async bulkUnpublish(ctx) {
1835
1882
  const { userAbility } = ctx.state;
1836
1883
  const { model } = ctx.params;
1837
1884
  const { body } = ctx.request;
1838
- const { ids } = body;
1885
+ const { documentIds } = body;
1839
1886
  await validateBulkActionInput(body);
1840
1887
  const documentManager2 = getService$1("document-manager");
1841
1888
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1842
1889
  if (permissionChecker2.cannot.unpublish()) {
1843
1890
  return ctx.forbidden();
1844
1891
  }
1845
- const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
1846
- const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1847
- const entityPromises = ids.map((id) => documentManager2.findOne(id, model, { populate }));
1848
- const entities = await Promise.all(entityPromises);
1892
+ const { locale } = getDocumentLocaleAndStatus(body);
1893
+ const entityPromises = documentIds.map(
1894
+ (documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
1895
+ );
1896
+ const entities = (await Promise.all(entityPromises)).flat();
1849
1897
  for (const entity of entities) {
1850
1898
  if (!entity) {
1851
1899
  return ctx.notFound();
@@ -1854,7 +1902,8 @@ const collectionTypes = {
1854
1902
  return ctx.forbidden();
1855
1903
  }
1856
1904
  }
1857
- const { count } = await documentManager2.unpublishMany(entities, model);
1905
+ const entitiesIds = entities.map((document) => document.documentId);
1906
+ const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
1858
1907
  ctx.body = { count };
1859
1908
  },
1860
1909
  async unpublish(ctx) {
@@ -1934,7 +1983,7 @@ const collectionTypes = {
1934
1983
  const { userAbility } = ctx.state;
1935
1984
  const { model } = ctx.params;
1936
1985
  const { query, body } = ctx.request;
1937
- const { ids } = body;
1986
+ const { documentIds } = body;
1938
1987
  await validateBulkActionInput(body);
1939
1988
  const documentManager2 = getService$1("document-manager");
1940
1989
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
@@ -1942,14 +1991,22 @@ const collectionTypes = {
1942
1991
  return ctx.forbidden();
1943
1992
  }
1944
1993
  const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
1945
- const idsWhereClause = { id: { $in: ids } };
1946
- const params = {
1947
- ...permissionQuery,
1948
- filters: {
1949
- $and: [idsWhereClause].concat(permissionQuery.filters || [])
1994
+ const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
1995
+ const { locale } = getDocumentLocaleAndStatus(body);
1996
+ const documentLocales = await documentManager2.findLocales(documentIds, model, {
1997
+ populate,
1998
+ locale
1999
+ });
2000
+ if (documentLocales.length === 0) {
2001
+ return ctx.notFound();
2002
+ }
2003
+ for (const document of documentLocales) {
2004
+ if (permissionChecker2.cannot.delete(document)) {
2005
+ return ctx.forbidden();
1950
2006
  }
1951
- };
1952
- const { count } = await documentManager2.deleteMany(params, model);
2007
+ }
2008
+ const localeDocumentsIds = documentLocales.map((document) => document.documentId);
2009
+ const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
1953
2010
  ctx.body = { count };
1954
2011
  },
1955
2012
  async countDraftRelations(ctx) {
@@ -1977,27 +2034,26 @@ const collectionTypes = {
1977
2034
  },
1978
2035
  async countManyEntriesDraftRelations(ctx) {
1979
2036
  const { userAbility } = ctx.state;
1980
- const ids = ctx.request.query.ids;
1981
- const locale = ctx.request.query.locale;
2037
+ const { documentIds, locale } = ctx.request.query;
1982
2038
  const { model } = ctx.params;
1983
2039
  const documentManager2 = getService$1("document-manager");
1984
2040
  const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
1985
2041
  if (permissionChecker2.cannot.read()) {
1986
2042
  return ctx.forbidden();
1987
2043
  }
1988
- const entities = await documentManager2.findMany(
2044
+ const documents = await documentManager2.findMany(
1989
2045
  {
1990
2046
  filters: {
1991
- id: ids
2047
+ documentId: { $in: documentIds }
1992
2048
  },
1993
2049
  locale
1994
2050
  },
1995
2051
  model
1996
2052
  );
1997
- if (!entities) {
2053
+ if (!documents) {
1998
2054
  return ctx.notFound();
1999
2055
  }
2000
- const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
2056
+ const number = await documentManager2.countManyEntriesDraftRelations(documentIds, model, locale);
2001
2057
  return {
2002
2058
  data: number
2003
2059
  };
@@ -3997,26 +4053,9 @@ const sumDraftCounts = (entity, uid2) => {
3997
4053
  }, 0);
3998
4054
  };
3999
4055
  const { ApplicationError } = strapiUtils.errors;
4000
- const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
4001
4056
  const { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
4002
4057
  const omitPublishedAtField = fp.omit(PUBLISHED_AT_ATTRIBUTE);
4003
4058
  const omitIdField = fp.omit("id");
4004
- const emitEvent = async (uid2, event, document) => {
4005
- const modelDef = strapi.getModel(uid2);
4006
- const sanitizedDocument = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput(
4007
- {
4008
- schema: modelDef,
4009
- getModel(uid22) {
4010
- return strapi.getModel(uid22);
4011
- }
4012
- },
4013
- document
4014
- );
4015
- strapi.eventHub.emit(event, {
4016
- model: modelDef.modelName,
4017
- entry: sanitizedDocument
4018
- });
4019
- };
4020
4059
  const documentManager = ({ strapi: strapi2 }) => {
4021
4060
  return {
4022
4061
  async findOne(id, uid2, opts = {}) {
@@ -4035,6 +4074,9 @@ const documentManager = ({ strapi: strapi2 }) => {
4035
4074
  } else if (opts.locale && opts.locale !== "*") {
4036
4075
  where.locale = opts.locale;
4037
4076
  }
4077
+ if (typeof opts.isPublished === "boolean") {
4078
+ where.publishedAt = { $notNull: opts.isPublished };
4079
+ }
4038
4080
  return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
4039
4081
  },
4040
4082
  async findMany(opts, uid2) {
@@ -4042,20 +4084,16 @@ const documentManager = ({ strapi: strapi2 }) => {
4042
4084
  return strapi2.documents(uid2).findMany(params);
4043
4085
  },
4044
4086
  async findPage(opts, uid2) {
4045
- const page = Number(opts?.page) || 1;
4046
- const pageSize = Number(opts?.pageSize) || 10;
4087
+ const params = strapiUtils.pagination.withDefaultPagination(opts || {}, {
4088
+ maxLimit: 1e3
4089
+ });
4047
4090
  const [documents, total = 0] = await Promise.all([
4048
- strapi2.documents(uid2).findMany(opts),
4049
- strapi2.documents(uid2).count(opts)
4091
+ strapi2.documents(uid2).findMany(params),
4092
+ strapi2.documents(uid2).count(params)
4050
4093
  ]);
4051
4094
  return {
4052
4095
  results: documents,
4053
- pagination: {
4054
- page,
4055
- pageSize,
4056
- pageCount: Math.ceil(total / pageSize),
4057
- total
4058
- }
4096
+ pagination: strapiUtils.pagination.transformPagedPaginationInfo(params, total)
4059
4097
  };
4060
4098
  },
4061
4099
  async create(uid2, opts = {}) {
@@ -4101,70 +4139,38 @@ const documentManager = ({ strapi: strapi2 }) => {
4101
4139
  return {};
4102
4140
  },
4103
4141
  // FIXME: handle relations
4104
- async deleteMany(opts, uid2) {
4105
- const docs = await strapi2.documents(uid2).findMany(opts);
4106
- for (const doc of docs) {
4107
- await strapi2.documents(uid2).delete({ documentId: doc.documentId });
4108
- }
4109
- return { count: docs.length };
4142
+ async deleteMany(documentIds, uid2, opts) {
4143
+ const deletedEntries = await strapi2.db.transaction(async () => {
4144
+ return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
4145
+ });
4146
+ return { count: deletedEntries.length };
4110
4147
  },
4111
4148
  async publish(id, uid2, opts = {}) {
4112
4149
  const populate = await buildDeepPopulate(uid2);
4113
4150
  const params = { ...opts, populate };
4114
4151
  return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries.at(0));
4115
4152
  },
4116
- async publishMany(entities, uid2) {
4117
- if (!entities.length) {
4118
- return null;
4119
- }
4120
- await Promise.all(
4121
- entities.map((document) => {
4122
- return strapi2.entityValidator.validateEntityCreation(
4123
- strapi2.getModel(uid2),
4124
- document,
4125
- void 0,
4126
- // @ts-expect-error - FIXME: entity here is unnecessary
4127
- document
4128
- );
4129
- })
4130
- );
4131
- const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
4132
- const filters = { id: { $in: entitiesToPublish } };
4133
- const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
4134
- const populate = await buildDeepPopulate(uid2);
4135
- const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
4136
- where: filters,
4137
- data
4138
- });
4139
- const publishedEntities = await strapi2.db.query(uid2).findMany({
4140
- where: filters,
4141
- populate
4153
+ async publishMany(documentIds, uid2, opts = {}) {
4154
+ const publishedEntries = await strapi2.db.transaction(async () => {
4155
+ return Promise.all(
4156
+ documentIds.map(
4157
+ (id) => strapi2.documents(uid2).publish({ ...opts, documentId: id }).then((result) => result?.entries)
4158
+ )
4159
+ );
4142
4160
  });
4143
- await Promise.all(
4144
- publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
4145
- );
4146
- return publishedEntitiesCount;
4161
+ const publishedEntitiesCount = publishedEntries.flat().filter(Boolean).length;
4162
+ return { count: publishedEntitiesCount };
4147
4163
  },
4148
- async unpublishMany(documents, uid2) {
4149
- if (!documents.length) {
4150
- return null;
4151
- }
4152
- const entitiesToUnpublish = documents.filter((doc) => doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
4153
- const filters = { id: { $in: entitiesToUnpublish } };
4154
- const data = { [PUBLISHED_AT_ATTRIBUTE]: null };
4155
- const populate = await buildDeepPopulate(uid2);
4156
- const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
4157
- where: filters,
4158
- data
4159
- });
4160
- const unpublishedEntities = await strapi2.db.query(uid2).findMany({
4161
- where: filters,
4162
- populate
4164
+ async unpublishMany(documentIds, uid2, opts = {}) {
4165
+ const unpublishedEntries = await strapi2.db.transaction(async () => {
4166
+ return Promise.all(
4167
+ documentIds.map(
4168
+ (id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
4169
+ )
4170
+ );
4163
4171
  });
4164
- await Promise.all(
4165
- unpublishedEntities.map((doc) => emitEvent(uid2, ENTRY_UNPUBLISH, doc))
4166
- );
4167
- return unpublishedEntitiesCount;
4172
+ const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
4173
+ return { count: unpublishedEntitiesCount };
4168
4174
  },
4169
4175
  async unpublish(id, uid2, opts = {}) {
4170
4176
  const populate = await buildDeepPopulate(uid2);
@@ -4189,19 +4195,19 @@ const documentManager = ({ strapi: strapi2 }) => {
4189
4195
  }
4190
4196
  return sumDraftCounts(document, uid2);
4191
4197
  },
4192
- async countManyEntriesDraftRelations(ids, uid2, locale) {
4198
+ async countManyEntriesDraftRelations(documentIds, uid2, locale) {
4193
4199
  const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
4194
4200
  if (!hasRelations) {
4195
4201
  return 0;
4196
4202
  }
4197
- const entities = await strapi2.db.query(uid2).findMany({
4203
+ const documents = await strapi2.documents(uid2).findMany({
4198
4204
  populate,
4199
- where: {
4200
- id: { $in: ids },
4201
- ...locale ? { locale } : {}
4202
- }
4205
+ filters: {
4206
+ documentId: documentIds
4207
+ },
4208
+ locale
4203
4209
  });
4204
- const totalNumberDraftRelations = entities.reduce(
4210
+ const totalNumberDraftRelations = documents.reduce(
4205
4211
  (count, entity) => sumDraftCounts(entity, uid2) + count,
4206
4212
  0
4207
4213
  );