@strapi/content-manager 5.0.0-beta.6 → 5.0.0-beta.8
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.
- package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-CuWgXugY.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-CuWgXugY.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-by0e_kNd.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-by0e_kNd.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-CqBeCPGH.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-CqBeCPGH.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-DbI4KMyz.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-DbI4KMyz.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-ChgloMyO.js} +7 -9
- package/dist/_chunks/EditViewPage-ChgloMyO.js.map +1 -0
- package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-dFPBya9U.mjs} +6 -6
- package/dist/_chunks/EditViewPage-dFPBya9U.mjs.map +1 -0
- package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-C1nUKcdS.mjs} +500 -608
- package/dist/_chunks/Field-C1nUKcdS.mjs.map +1 -0
- package/dist/_chunks/{Field-Caef4JjM.js → Field-dLk-vgLL.js} +552 -661
- package/dist/_chunks/Field-dLk-vgLL.js.map +1 -0
- package/dist/_chunks/{Form-BzuAjtRq.js → Form-CbXtmHC_.js} +21 -19
- package/dist/_chunks/Form-CbXtmHC_.js.map +1 -0
- package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-DOlpi7Js.mjs} +21 -18
- package/dist/_chunks/Form-DOlpi7Js.mjs.map +1 -0
- package/dist/_chunks/{History-D6sbCJvo.mjs → History-BFNUAiGc.mjs} +32 -43
- package/dist/_chunks/History-BFNUAiGc.mjs.map +1 -0
- package/dist/_chunks/{History-C17LiyRg.js → History-BjDfohBr.js} +32 -44
- package/dist/_chunks/History-BjDfohBr.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-DDi0KqFm.mjs} +14 -14
- package/dist/_chunks/ListConfigurationPage-DDi0KqFm.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-IQBgWTaa.js} +17 -19
- package/dist/_chunks/ListConfigurationPage-IQBgWTaa.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-BPjljUsH.mjs} +25 -45
- package/dist/_chunks/ListViewPage-BPjljUsH.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-CZYGqlvF.js} +31 -51
- package/dist/_chunks/ListViewPage-CZYGqlvF.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-BOAI6VZ1.js} +5 -5
- package/dist/_chunks/NoContentTypePage-BOAI6VZ1.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-DaWw67K-.mjs} +7 -7
- package/dist/_chunks/NoContentTypePage-DaWw67K-.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-CZrJH00p.mjs} +5 -6
- package/dist/_chunks/NoPermissionsPage-CZrJH00p.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-cYEtLc_e.js} +4 -5
- package/dist/_chunks/NoPermissionsPage-cYEtLc_e.js.map +1 -0
- package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-DTowyge2.mjs} +66 -56
- package/dist/_chunks/Relations-DTowyge2.mjs.map +1 -0
- package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-DU6B7irU.js} +70 -61
- package/dist/_chunks/Relations-DU6B7irU.js.map +1 -0
- package/dist/_chunks/{en-C-V1_90f.js → en-DTULi5-d.js} +3 -1
- package/dist/_chunks/{en-C-V1_90f.js.map → en-DTULi5-d.js.map} +1 -1
- package/dist/_chunks/{en-MBPul9Su.mjs → en-GCOTL6jR.mjs} +3 -1
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-GCOTL6jR.mjs.map} +1 -1
- package/dist/_chunks/{index-DNVx8ssZ.mjs → index-BaGHmIir.mjs} +507 -202
- package/dist/_chunks/index-BaGHmIir.mjs.map +1 -0
- package/dist/_chunks/{index-X_2tafck.js → index-CCJeB7Rw.js} +502 -198
- package/dist/_chunks/index-CCJeB7Rw.js.map +1 -0
- package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-BinjszSQ.mjs} +13 -13
- package/dist/_chunks/layout-BinjszSQ.mjs.map +1 -0
- package/dist/_chunks/{layout-dBc7wN7L.js → layout-ni_L9kT1.js} +14 -16
- package/dist/_chunks/layout-ni_L9kT1.js.map +1 -0
- package/dist/_chunks/{relations-4pHtBrHJ.js → relations-CeJAJc5I.js} +2 -2
- package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-CeJAJc5I.js.map} +1 -1
- package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-c91ji5eR.mjs} +2 -2
- package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-c91ji5eR.mjs.map} +1 -1
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +3 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +10 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +67 -52
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- package/dist/admin/src/services/api.d.ts +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +29 -17
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +1 -6
- package/dist/server/index.js +529 -407
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +537 -415
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +9 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts +2 -4
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/index.d.ts +6 -2
- package/dist/server/src/history/services/index.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts +9 -0
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
- package/dist/server/src/history/services/utils.d.ts +41 -9
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/history/utils.d.ts +6 -2
- package/dist/server/src/history/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +18 -39
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -29
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +18 -39
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +8 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +14 -6
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- package/package.json +13 -14
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
- package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
- package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
- package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
- package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
- package/dist/_chunks/History-C17LiyRg.js.map +0 -1
- package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
- package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
- package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
- package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
- package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
- package/dist/_chunks/index-X_2tafck.js.map +0 -1
- package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
- package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +0 -31
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
package/dist/server/index.js
CHANGED
@@ -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
|
162
|
-
const
|
163
|
-
|
164
|
-
|
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
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
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
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
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
|
-
|
241
|
-
|
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
|
-
|
244
|
-
|
245
|
-
|
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
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
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]:
|
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(
|
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]:
|
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(
|
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
|
465
|
-
|
466
|
-
|
467
|
-
const
|
468
|
-
if (
|
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
|
-
|
474
|
-
|
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
|
-
|
500
|
-
|
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
|
-
|
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,99 @@ 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
|
+
if (Array.isArray(locale)) {
|
522
|
+
strapi2.log.warn(
|
523
|
+
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
524
|
+
);
|
525
|
+
return next();
|
526
|
+
}
|
527
|
+
const document = await strapi2.documents(contentTypeUid).findOne({
|
528
|
+
documentId: documentContext.documentId,
|
529
|
+
locale,
|
530
|
+
populate: serviceUtils.getDeepPopulate(contentTypeUid)
|
531
|
+
});
|
532
|
+
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
533
|
+
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
534
|
+
const componentsSchemas = Object.keys(
|
535
|
+
attributesSchema
|
536
|
+
).reduce((currentComponentSchemas, key) => {
|
537
|
+
const fieldSchema = attributesSchema[key];
|
538
|
+
if (fieldSchema.type === "component") {
|
539
|
+
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
540
|
+
return {
|
541
|
+
...currentComponentSchemas,
|
542
|
+
[fieldSchema.component]: componentSchema
|
543
|
+
};
|
544
|
+
}
|
545
|
+
return currentComponentSchemas;
|
546
|
+
}, {});
|
547
|
+
await strapi2.db.transaction(async ({ onCommit }) => {
|
548
|
+
onCommit(() => {
|
549
|
+
historyService.createVersion({
|
550
|
+
contentType: contentTypeUid,
|
551
|
+
data: fp.omit(FIELDS_TO_IGNORE, document),
|
552
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
553
|
+
componentsSchemas,
|
554
|
+
relatedDocumentId: documentContext.documentId,
|
555
|
+
locale,
|
556
|
+
status
|
557
|
+
});
|
558
|
+
});
|
559
|
+
});
|
560
|
+
return result;
|
561
|
+
});
|
562
|
+
const retentionDays = serviceUtils.getRetentionDays();
|
563
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
564
|
+
const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
|
565
|
+
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
566
|
+
query.deleteMany({
|
567
|
+
where: {
|
568
|
+
created_at: {
|
569
|
+
$lt: expirationDate.toISOString()
|
570
|
+
}
|
571
|
+
}
|
572
|
+
});
|
573
|
+
});
|
574
|
+
state.isInitialized = true;
|
575
|
+
},
|
576
|
+
async destroy() {
|
577
|
+
if (state.deleteExpiredJob) {
|
578
|
+
state.deleteExpiredJob.cancel();
|
579
|
+
}
|
580
|
+
}
|
581
|
+
};
|
582
|
+
};
|
533
583
|
const services$1 = {
|
534
|
-
history: createHistoryService
|
584
|
+
history: createHistoryService,
|
585
|
+
lifecycles: createLifecyclesService
|
535
586
|
};
|
536
587
|
const info = { pluginName: "content-manager", type: "admin" };
|
537
588
|
const historyVersionRouter = {
|
@@ -611,10 +662,10 @@ const getFeature = () => {
|
|
611
662
|
strapi2.get("models").add(historyVersion);
|
612
663
|
},
|
613
664
|
bootstrap({ strapi: strapi2 }) {
|
614
|
-
getService(strapi2, "
|
665
|
+
getService(strapi2, "lifecycles").bootstrap();
|
615
666
|
},
|
616
667
|
destroy({ strapi: strapi2 }) {
|
617
|
-
getService(strapi2, "
|
668
|
+
getService(strapi2, "lifecycles").destroy();
|
618
669
|
},
|
619
670
|
controllers: controllers$1,
|
620
671
|
services: services$1,
|
@@ -1433,7 +1484,7 @@ const { PaginationError, ValidationError } = strapiUtils.errors;
|
|
1433
1484
|
const TYPES = ["singleType", "collectionType"];
|
1434
1485
|
const kindSchema = strapiUtils.yup.string().oneOf(TYPES).nullable();
|
1435
1486
|
const bulkActionInputSchema = strapiUtils.yup.object({
|
1436
|
-
|
1487
|
+
documentIds: strapiUtils.yup.array().of(strapiUtils.yup.strapiID()).min(1).required()
|
1437
1488
|
}).required();
|
1438
1489
|
const generateUIDInputSchema = strapiUtils.yup.object({
|
1439
1490
|
contentTypeUID: strapiUtils.yup.string().required(),
|
@@ -1532,15 +1583,47 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1532
1583
|
}
|
1533
1584
|
}, body);
|
1534
1585
|
};
|
1535
|
-
const
|
1586
|
+
const singleLocaleSchema = strapiUtils.yup.string().nullable();
|
1587
|
+
const multipleLocaleSchema = strapiUtils.yup.lazy(
|
1588
|
+
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1589
|
+
);
|
1590
|
+
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1591
|
+
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1592
|
+
const { allowMultipleLocales } = opts;
|
1536
1593
|
const { locale, status, ...rest } = request || {};
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1594
|
+
const schema = strapiUtils.yup.object().shape({
|
1595
|
+
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1596
|
+
status: statusSchema
|
1597
|
+
});
|
1598
|
+
try {
|
1599
|
+
await strapiUtils.validateYupSchema(schema, { strict: true, abortEarly: false })(request);
|
1600
|
+
return { locale, status, ...rest };
|
1601
|
+
} catch (error) {
|
1602
|
+
throw new strapiUtils.errors.ValidationError(`Validation error: ${error.message}`);
|
1542
1603
|
}
|
1543
|
-
|
1604
|
+
};
|
1605
|
+
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1606
|
+
const documentMetadata2 = getService$1("document-metadata");
|
1607
|
+
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1608
|
+
let {
|
1609
|
+
meta: { availableLocales, availableStatus }
|
1610
|
+
} = serviceOutput;
|
1611
|
+
const metadataSanitizer = permissionChecker2.sanitizeOutput;
|
1612
|
+
availableLocales = await strapiUtils.async.map(
|
1613
|
+
availableLocales,
|
1614
|
+
async (localeDocument) => metadataSanitizer(localeDocument)
|
1615
|
+
);
|
1616
|
+
availableStatus = await strapiUtils.async.map(
|
1617
|
+
availableStatus,
|
1618
|
+
async (statusDocument) => metadataSanitizer(statusDocument)
|
1619
|
+
);
|
1620
|
+
return {
|
1621
|
+
...serviceOutput,
|
1622
|
+
meta: {
|
1623
|
+
availableLocales,
|
1624
|
+
availableStatus
|
1625
|
+
}
|
1626
|
+
};
|
1544
1627
|
};
|
1545
1628
|
const createDocument = async (ctx, opts) => {
|
1546
1629
|
const { userAbility, user } = ctx.state;
|
@@ -1555,7 +1638,7 @@ const createDocument = async (ctx, opts) => {
|
|
1555
1638
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1556
1639
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1557
1640
|
const sanitizedBody = await sanitizeFn(body);
|
1558
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(body);
|
1641
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(body);
|
1559
1642
|
return documentManager2.create(model, {
|
1560
1643
|
data: sanitizedBody,
|
1561
1644
|
locale,
|
@@ -1574,7 +1657,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1574
1657
|
}
|
1575
1658
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1576
1659
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1577
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1660
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1578
1661
|
const [documentVersion, documentExists] = await Promise.all([
|
1579
1662
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1580
1663
|
documentManager2.exists(model, id)
|
@@ -1612,7 +1695,7 @@ const collectionTypes = {
|
|
1612
1695
|
}
|
1613
1696
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1614
1697
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1615
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1698
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1616
1699
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1617
1700
|
{ ...permissionQuery, populate, locale, status },
|
1618
1701
|
model
|
@@ -1641,14 +1724,13 @@ const collectionTypes = {
|
|
1641
1724
|
const { userAbility } = ctx.state;
|
1642
1725
|
const { model, id } = ctx.params;
|
1643
1726
|
const documentManager2 = getService$1("document-manager");
|
1644
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1645
1727
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1646
1728
|
if (permissionChecker2.cannot.read()) {
|
1647
1729
|
return ctx.forbidden();
|
1648
1730
|
}
|
1649
1731
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1650
1732
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1651
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
1733
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
1652
1734
|
const version = await documentManager2.findOne(id, model, {
|
1653
1735
|
populate,
|
1654
1736
|
locale,
|
@@ -1659,8 +1741,10 @@ const collectionTypes = {
|
|
1659
1741
|
if (!exists) {
|
1660
1742
|
return ctx.notFound();
|
1661
1743
|
}
|
1662
|
-
const { meta } = await
|
1744
|
+
const { meta } = await formatDocumentWithMetadata(
|
1745
|
+
permissionChecker2,
|
1663
1746
|
model,
|
1747
|
+
// @ts-expect-error TODO: fix
|
1664
1748
|
{ id, locale, publishedAt: null },
|
1665
1749
|
{ availableLocales: true, availableStatus: false }
|
1666
1750
|
);
|
@@ -1671,12 +1755,11 @@ const collectionTypes = {
|
|
1671
1755
|
return ctx.forbidden();
|
1672
1756
|
}
|
1673
1757
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1674
|
-
ctx.body = await
|
1758
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1675
1759
|
},
|
1676
1760
|
async create(ctx) {
|
1677
1761
|
const { userAbility } = ctx.state;
|
1678
1762
|
const { model } = ctx.params;
|
1679
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1680
1763
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1681
1764
|
const [totalEntries, document] = await Promise.all([
|
1682
1765
|
strapi.db.query(model).count(),
|
@@ -1684,7 +1767,7 @@ const collectionTypes = {
|
|
1684
1767
|
]);
|
1685
1768
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1686
1769
|
ctx.status = 201;
|
1687
|
-
ctx.body = await
|
1770
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1688
1771
|
// Empty metadata as it's not relevant for a new document
|
1689
1772
|
availableLocales: false,
|
1690
1773
|
availableStatus: false
|
@@ -1698,25 +1781,23 @@ const collectionTypes = {
|
|
1698
1781
|
async update(ctx) {
|
1699
1782
|
const { userAbility } = ctx.state;
|
1700
1783
|
const { model } = ctx.params;
|
1701
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1702
1784
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1703
1785
|
const updatedVersion = await updateDocument(ctx);
|
1704
1786
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1705
|
-
ctx.body = await
|
1787
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1706
1788
|
},
|
1707
1789
|
async clone(ctx) {
|
1708
1790
|
const { userAbility, user } = ctx.state;
|
1709
1791
|
const { model, sourceId: id } = ctx.params;
|
1710
1792
|
const { body } = ctx.request;
|
1711
1793
|
const documentManager2 = getService$1("document-manager");
|
1712
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1713
1794
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1714
1795
|
if (permissionChecker2.cannot.create()) {
|
1715
1796
|
return ctx.forbidden();
|
1716
1797
|
}
|
1717
1798
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1718
1799
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1719
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1800
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1720
1801
|
const document = await documentManager2.findOne(id, model, {
|
1721
1802
|
populate,
|
1722
1803
|
locale,
|
@@ -1732,7 +1813,7 @@ const collectionTypes = {
|
|
1732
1813
|
const sanitizedBody = await sanitizeFn(body);
|
1733
1814
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1734
1815
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1735
|
-
ctx.body = await
|
1816
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1736
1817
|
// Empty metadata as it's not relevant for a new document
|
1737
1818
|
availableLocales: false,
|
1738
1819
|
availableStatus: false
|
@@ -1761,7 +1842,7 @@ const collectionTypes = {
|
|
1761
1842
|
}
|
1762
1843
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1763
1844
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1764
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
1845
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1765
1846
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1766
1847
|
if (documentLocales.length === 0) {
|
1767
1848
|
return ctx.notFound();
|
@@ -1783,7 +1864,6 @@ const collectionTypes = {
|
|
1783
1864
|
const { id, model } = ctx.params;
|
1784
1865
|
const { body } = ctx.request;
|
1785
1866
|
const documentManager2 = getService$1("document-manager");
|
1786
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1787
1867
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1788
1868
|
if (permissionChecker2.cannot.publish()) {
|
1789
1869
|
return ctx.forbidden();
|
@@ -1795,21 +1875,25 @@ const collectionTypes = {
|
|
1795
1875
|
if (permissionChecker2.cannot.publish(document)) {
|
1796
1876
|
throw new strapiUtils.errors.ForbiddenError();
|
1797
1877
|
}
|
1798
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1799
|
-
|
1878
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1879
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1800
1880
|
locale
|
1801
1881
|
// TODO: Allow setting creator fields on publish
|
1802
1882
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1803
1883
|
});
|
1884
|
+
if (!publishResult || publishResult.length === 0) {
|
1885
|
+
throw new strapiUtils.errors.NotFoundError("Document not found or already published.");
|
1886
|
+
}
|
1887
|
+
return publishResult[0];
|
1804
1888
|
});
|
1805
1889
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1806
|
-
ctx.body = await
|
1890
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1807
1891
|
},
|
1808
1892
|
async bulkPublish(ctx) {
|
1809
1893
|
const { userAbility } = ctx.state;
|
1810
1894
|
const { model } = ctx.params;
|
1811
1895
|
const { body } = ctx.request;
|
1812
|
-
const {
|
1896
|
+
const { documentIds } = body;
|
1813
1897
|
await validateBulkActionInput(body);
|
1814
1898
|
const documentManager2 = getService$1("document-manager");
|
1815
1899
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1818,8 +1902,11 @@ const collectionTypes = {
|
|
1818
1902
|
}
|
1819
1903
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1820
1904
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1821
|
-
const
|
1822
|
-
const
|
1905
|
+
const { locale } = await getDocumentLocaleAndStatus(body, { allowMultipleLocales: true });
|
1906
|
+
const entityPromises = documentIds.map(
|
1907
|
+
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1908
|
+
);
|
1909
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1823
1910
|
for (const entity of entities) {
|
1824
1911
|
if (!entity) {
|
1825
1912
|
return ctx.notFound();
|
@@ -1828,24 +1915,25 @@ const collectionTypes = {
|
|
1828
1915
|
return ctx.forbidden();
|
1829
1916
|
}
|
1830
1917
|
}
|
1831
|
-
const
|
1918
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1832
1919
|
ctx.body = { count };
|
1833
1920
|
},
|
1834
1921
|
async bulkUnpublish(ctx) {
|
1835
1922
|
const { userAbility } = ctx.state;
|
1836
1923
|
const { model } = ctx.params;
|
1837
1924
|
const { body } = ctx.request;
|
1838
|
-
const {
|
1925
|
+
const { documentIds } = body;
|
1839
1926
|
await validateBulkActionInput(body);
|
1840
1927
|
const documentManager2 = getService$1("document-manager");
|
1841
1928
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1842
1929
|
if (permissionChecker2.cannot.unpublish()) {
|
1843
1930
|
return ctx.forbidden();
|
1844
1931
|
}
|
1845
|
-
const
|
1846
|
-
const
|
1847
|
-
|
1848
|
-
|
1932
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1933
|
+
const entityPromises = documentIds.map(
|
1934
|
+
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1935
|
+
);
|
1936
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1849
1937
|
for (const entity of entities) {
|
1850
1938
|
if (!entity) {
|
1851
1939
|
return ctx.notFound();
|
@@ -1854,7 +1942,8 @@ const collectionTypes = {
|
|
1854
1942
|
return ctx.forbidden();
|
1855
1943
|
}
|
1856
1944
|
}
|
1857
|
-
const
|
1945
|
+
const entitiesIds = entities.map((document) => document.documentId);
|
1946
|
+
const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
|
1858
1947
|
ctx.body = { count };
|
1859
1948
|
},
|
1860
1949
|
async unpublish(ctx) {
|
@@ -1864,7 +1953,6 @@ const collectionTypes = {
|
|
1864
1953
|
body: { discardDraft, ...body }
|
1865
1954
|
} = ctx.request;
|
1866
1955
|
const documentManager2 = getService$1("document-manager");
|
1867
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1868
1956
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1869
1957
|
if (permissionChecker2.cannot.unpublish()) {
|
1870
1958
|
return ctx.forbidden();
|
@@ -1874,7 +1962,7 @@ const collectionTypes = {
|
|
1874
1962
|
}
|
1875
1963
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1876
1964
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1877
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1965
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1878
1966
|
const document = await documentManager2.findOne(id, model, {
|
1879
1967
|
populate,
|
1880
1968
|
locale,
|
@@ -1896,7 +1984,7 @@ const collectionTypes = {
|
|
1896
1984
|
ctx.body = await strapiUtils.async.pipe(
|
1897
1985
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1898
1986
|
permissionChecker2.sanitizeOutput,
|
1899
|
-
(document2) =>
|
1987
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1900
1988
|
)(document);
|
1901
1989
|
});
|
1902
1990
|
},
|
@@ -1905,14 +1993,13 @@ const collectionTypes = {
|
|
1905
1993
|
const { id, model } = ctx.params;
|
1906
1994
|
const { body } = ctx.request;
|
1907
1995
|
const documentManager2 = getService$1("document-manager");
|
1908
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1909
1996
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1910
1997
|
if (permissionChecker2.cannot.discard()) {
|
1911
1998
|
return ctx.forbidden();
|
1912
1999
|
}
|
1913
2000
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1914
2001
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1915
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2002
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1916
2003
|
const document = await documentManager2.findOne(id, model, {
|
1917
2004
|
populate,
|
1918
2005
|
locale,
|
@@ -1927,14 +2014,14 @@ const collectionTypes = {
|
|
1927
2014
|
ctx.body = await strapiUtils.async.pipe(
|
1928
2015
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1929
2016
|
permissionChecker2.sanitizeOutput,
|
1930
|
-
(document2) =>
|
2017
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1931
2018
|
)(document);
|
1932
2019
|
},
|
1933
2020
|
async bulkDelete(ctx) {
|
1934
2021
|
const { userAbility } = ctx.state;
|
1935
2022
|
const { model } = ctx.params;
|
1936
2023
|
const { query, body } = ctx.request;
|
1937
|
-
const {
|
2024
|
+
const { documentIds } = body;
|
1938
2025
|
await validateBulkActionInput(body);
|
1939
2026
|
const documentManager2 = getService$1("document-manager");
|
1940
2027
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1942,14 +2029,22 @@ const collectionTypes = {
|
|
1942
2029
|
return ctx.forbidden();
|
1943
2030
|
}
|
1944
2031
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1945
|
-
const
|
1946
|
-
const
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
2032
|
+
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2033
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2034
|
+
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2035
|
+
populate,
|
2036
|
+
locale
|
2037
|
+
});
|
2038
|
+
if (documentLocales.length === 0) {
|
2039
|
+
return ctx.notFound();
|
2040
|
+
}
|
2041
|
+
for (const document of documentLocales) {
|
2042
|
+
if (permissionChecker2.cannot.delete(document)) {
|
2043
|
+
return ctx.forbidden();
|
1950
2044
|
}
|
1951
|
-
}
|
1952
|
-
const
|
2045
|
+
}
|
2046
|
+
const localeDocumentsIds = documentLocales.map((document) => document.documentId);
|
2047
|
+
const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
|
1953
2048
|
ctx.body = { count };
|
1954
2049
|
},
|
1955
2050
|
async countDraftRelations(ctx) {
|
@@ -1962,7 +2057,7 @@ const collectionTypes = {
|
|
1962
2057
|
}
|
1963
2058
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1964
2059
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1965
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
2060
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
1966
2061
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
1967
2062
|
if (!entity) {
|
1968
2063
|
return ctx.notFound();
|
@@ -1977,7 +2072,7 @@ const collectionTypes = {
|
|
1977
2072
|
},
|
1978
2073
|
async countManyEntriesDraftRelations(ctx) {
|
1979
2074
|
const { userAbility } = ctx.state;
|
1980
|
-
const ids = ctx.request.query.
|
2075
|
+
const ids = ctx.request.query.documentIds;
|
1981
2076
|
const locale = ctx.request.query.locale;
|
1982
2077
|
const { model } = ctx.params;
|
1983
2078
|
const documentManager2 = getService$1("document-manager");
|
@@ -1988,7 +2083,7 @@ const collectionTypes = {
|
|
1988
2083
|
const entities = await documentManager2.findMany(
|
1989
2084
|
{
|
1990
2085
|
filters: {
|
1991
|
-
|
2086
|
+
documentId: ids
|
1992
2087
|
},
|
1993
2088
|
locale
|
1994
2089
|
},
|
@@ -2490,7 +2585,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2490
2585
|
throw new strapiUtils.errors.ForbiddenError();
|
2491
2586
|
}
|
2492
2587
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2493
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2588
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2494
2589
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2495
2590
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2496
2591
|
// Find the first document to check if it exists
|
@@ -2527,12 +2622,11 @@ const singleTypes = {
|
|
2527
2622
|
const { model } = ctx.params;
|
2528
2623
|
const { query = {} } = ctx.request;
|
2529
2624
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2530
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2531
2625
|
if (permissionChecker2.cannot.read()) {
|
2532
2626
|
return ctx.forbidden();
|
2533
2627
|
}
|
2534
2628
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2535
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2629
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2536
2630
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2537
2631
|
if (!version) {
|
2538
2632
|
if (permissionChecker2.cannot.create()) {
|
@@ -2542,8 +2636,10 @@ const singleTypes = {
|
|
2542
2636
|
if (!document) {
|
2543
2637
|
return ctx.notFound();
|
2544
2638
|
}
|
2545
|
-
const { meta } = await
|
2639
|
+
const { meta } = await formatDocumentWithMetadata(
|
2640
|
+
permissionChecker2,
|
2546
2641
|
model,
|
2642
|
+
// @ts-expect-error - fix types
|
2547
2643
|
{ id: document.documentId, locale, publishedAt: null },
|
2548
2644
|
{ availableLocales: true, availableStatus: false }
|
2549
2645
|
);
|
@@ -2554,16 +2650,15 @@ const singleTypes = {
|
|
2554
2650
|
return ctx.forbidden();
|
2555
2651
|
}
|
2556
2652
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2557
|
-
ctx.body = await
|
2653
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2558
2654
|
},
|
2559
2655
|
async createOrUpdate(ctx) {
|
2560
2656
|
const { userAbility } = ctx.state;
|
2561
2657
|
const { model } = ctx.params;
|
2562
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2563
2658
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2564
2659
|
const document = await createOrUpdateDocument(ctx);
|
2565
2660
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2566
|
-
ctx.body = await
|
2661
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2567
2662
|
},
|
2568
2663
|
async delete(ctx) {
|
2569
2664
|
const { userAbility } = ctx.state;
|
@@ -2576,7 +2671,7 @@ const singleTypes = {
|
|
2576
2671
|
}
|
2577
2672
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2578
2673
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2579
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2674
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2580
2675
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2581
2676
|
populate,
|
2582
2677
|
locale
|
@@ -2599,7 +2694,6 @@ const singleTypes = {
|
|
2599
2694
|
const { model } = ctx.params;
|
2600
2695
|
const { query = {} } = ctx.request;
|
2601
2696
|
const documentManager2 = getService$1("document-manager");
|
2602
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2603
2697
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2604
2698
|
if (permissionChecker2.cannot.publish()) {
|
2605
2699
|
return ctx.forbidden();
|
@@ -2614,11 +2708,12 @@ const singleTypes = {
|
|
2614
2708
|
if (permissionChecker2.cannot.publish(document)) {
|
2615
2709
|
throw new strapiUtils.errors.ForbiddenError();
|
2616
2710
|
}
|
2617
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2618
|
-
|
2711
|
+
const { locale } = await getDocumentLocaleAndStatus(document);
|
2712
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2713
|
+
return publishResult.at(0);
|
2619
2714
|
});
|
2620
2715
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2621
|
-
ctx.body = await
|
2716
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2622
2717
|
},
|
2623
2718
|
async unpublish(ctx) {
|
2624
2719
|
const { userAbility } = ctx.state;
|
@@ -2628,7 +2723,6 @@ const singleTypes = {
|
|
2628
2723
|
query = {}
|
2629
2724
|
} = ctx.request;
|
2630
2725
|
const documentManager2 = getService$1("document-manager");
|
2631
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2632
2726
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2633
2727
|
if (permissionChecker2.cannot.unpublish()) {
|
2634
2728
|
return ctx.forbidden();
|
@@ -2637,7 +2731,7 @@ const singleTypes = {
|
|
2637
2731
|
return ctx.forbidden();
|
2638
2732
|
}
|
2639
2733
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2640
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2734
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2641
2735
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2642
2736
|
if (!document) {
|
2643
2737
|
return ctx.notFound();
|
@@ -2655,7 +2749,7 @@ const singleTypes = {
|
|
2655
2749
|
ctx.body = await strapiUtils.async.pipe(
|
2656
2750
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2657
2751
|
permissionChecker2.sanitizeOutput,
|
2658
|
-
(document2) =>
|
2752
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2659
2753
|
)(document);
|
2660
2754
|
});
|
2661
2755
|
},
|
@@ -2664,13 +2758,12 @@ const singleTypes = {
|
|
2664
2758
|
const { model } = ctx.params;
|
2665
2759
|
const { body, query = {} } = ctx.request;
|
2666
2760
|
const documentManager2 = getService$1("document-manager");
|
2667
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2668
2761
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2669
2762
|
if (permissionChecker2.cannot.discard()) {
|
2670
2763
|
return ctx.forbidden();
|
2671
2764
|
}
|
2672
2765
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2673
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2766
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2674
2767
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2675
2768
|
if (!document) {
|
2676
2769
|
return ctx.notFound();
|
@@ -2681,7 +2774,7 @@ const singleTypes = {
|
|
2681
2774
|
ctx.body = await strapiUtils.async.pipe(
|
2682
2775
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2683
2776
|
permissionChecker2.sanitizeOutput,
|
2684
|
-
(document2) =>
|
2777
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2685
2778
|
)(document);
|
2686
2779
|
},
|
2687
2780
|
async countDraftRelations(ctx) {
|
@@ -2690,7 +2783,7 @@ const singleTypes = {
|
|
2690
2783
|
const { query } = ctx.request;
|
2691
2784
|
const documentManager2 = getService$1("document-manager");
|
2692
2785
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2693
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2786
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2694
2787
|
if (permissionChecker2.cannot.read()) {
|
2695
2788
|
return ctx.forbidden();
|
2696
2789
|
}
|
@@ -2711,7 +2804,7 @@ const uid$1 = {
|
|
2711
2804
|
async generateUID(ctx) {
|
2712
2805
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2713
2806
|
const { query = {} } = ctx.request;
|
2714
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2807
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2715
2808
|
await validateUIDField(contentTypeUID, field);
|
2716
2809
|
const uidService = getService$1("uid");
|
2717
2810
|
ctx.body = {
|
@@ -2723,7 +2816,7 @@ const uid$1 = {
|
|
2723
2816
|
ctx.request.body
|
2724
2817
|
);
|
2725
2818
|
const { query = {} } = ctx.request;
|
2726
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2819
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2727
2820
|
await validateUIDField(contentTypeUID, field);
|
2728
2821
|
const uidService = getService$1("uid");
|
2729
2822
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3514,7 +3607,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3514
3607
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3515
3608
|
}
|
3516
3609
|
});
|
3517
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils__default.default.contentTypes;
|
3610
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils__default.default.contentTypes;
|
3518
3611
|
const { isAnyToMany } = strapiUtils__default.default.relations;
|
3519
3612
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils__default.default.contentTypes.constants;
|
3520
3613
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3605,6 +3698,42 @@ const getDeepPopulate = (uid2, {
|
|
3605
3698
|
{}
|
3606
3699
|
);
|
3607
3700
|
};
|
3701
|
+
const getValidatableFieldsPopulate = (uid2, {
|
3702
|
+
initialPopulate = {},
|
3703
|
+
countMany = false,
|
3704
|
+
countOne = false,
|
3705
|
+
maxLevel = Infinity
|
3706
|
+
} = {}, level = 1) => {
|
3707
|
+
if (level > maxLevel) {
|
3708
|
+
return {};
|
3709
|
+
}
|
3710
|
+
const model = strapi.getModel(uid2);
|
3711
|
+
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
3712
|
+
if (!getDoesAttributeRequireValidation(attribute)) {
|
3713
|
+
return populateAcc;
|
3714
|
+
}
|
3715
|
+
if (isScalarAttribute(attribute)) {
|
3716
|
+
return fp.merge(populateAcc, {
|
3717
|
+
[attributeName]: true
|
3718
|
+
});
|
3719
|
+
}
|
3720
|
+
return fp.merge(
|
3721
|
+
populateAcc,
|
3722
|
+
getPopulateFor(
|
3723
|
+
attributeName,
|
3724
|
+
model,
|
3725
|
+
{
|
3726
|
+
// @ts-expect-error - improve types
|
3727
|
+
initialPopulate: initialPopulate?.[attributeName],
|
3728
|
+
countMany,
|
3729
|
+
countOne,
|
3730
|
+
maxLevel
|
3731
|
+
},
|
3732
|
+
level
|
3733
|
+
)
|
3734
|
+
);
|
3735
|
+
}, {});
|
3736
|
+
};
|
3608
3737
|
const getDeepPopulateDraftCount = (uid2) => {
|
3609
3738
|
const model = strapi.getModel(uid2);
|
3610
3739
|
let hasRelations = false;
|
@@ -3833,41 +3962,70 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3833
3962
|
"updatedBy",
|
3834
3963
|
"status"
|
3835
3964
|
];
|
3836
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
3965
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
3966
|
+
"id",
|
3967
|
+
"locale",
|
3968
|
+
"updatedAt",
|
3969
|
+
"createdAt",
|
3970
|
+
"status",
|
3971
|
+
"publishedAt",
|
3972
|
+
"documentId"
|
3973
|
+
];
|
3837
3974
|
const CONTENT_MANAGER_STATUS = {
|
3838
3975
|
PUBLISHED: "published",
|
3839
3976
|
DRAFT: "draft",
|
3840
3977
|
MODIFIED: "modified"
|
3841
3978
|
};
|
3842
|
-
const
|
3843
|
-
if (!
|
3979
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
3980
|
+
if (!version || !version.updatedAt) {
|
3844
3981
|
return false;
|
3845
3982
|
}
|
3846
|
-
const
|
3847
|
-
const
|
3848
|
-
|
3849
|
-
return difference <= threshold;
|
3983
|
+
const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;
|
3984
|
+
const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;
|
3985
|
+
return versionUpdatedAt > otherUpdatedAt;
|
3850
3986
|
};
|
3851
3987
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3852
3988
|
/**
|
3853
3989
|
* Returns available locales of a document for the current status
|
3854
3990
|
*/
|
3855
|
-
getAvailableLocales(uid2, version, allVersions) {
|
3991
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3856
3992
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
3857
3993
|
delete versionsByLocale[version.locale];
|
3858
|
-
|
3859
|
-
|
3860
|
-
|
3994
|
+
const model = strapi2.getModel(uid2);
|
3995
|
+
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3996
|
+
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
3997
|
+
({ key }, { remove }) => {
|
3998
|
+
if (keysToKeep.includes(key)) {
|
3999
|
+
return;
|
4000
|
+
}
|
4001
|
+
remove(key);
|
4002
|
+
},
|
4003
|
+
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
4004
|
+
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
4005
|
+
localeVersion
|
4006
|
+
);
|
4007
|
+
const mappingResult = await strapiUtils.async.map(
|
4008
|
+
Object.values(versionsByLocale),
|
4009
|
+
async (localeVersions) => {
|
4010
|
+
const mappedLocaleVersions = await strapiUtils.async.map(
|
4011
|
+
localeVersions,
|
4012
|
+
traversalFunction
|
4013
|
+
);
|
4014
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(model)) {
|
4015
|
+
return mappedLocaleVersions[0];
|
4016
|
+
}
|
4017
|
+
const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
|
4018
|
+
const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
|
4019
|
+
if (!draftVersion) {
|
4020
|
+
return;
|
4021
|
+
}
|
4022
|
+
return {
|
4023
|
+
...draftVersion,
|
4024
|
+
status: this.getStatus(draftVersion, otherVersions)
|
4025
|
+
};
|
3861
4026
|
}
|
3862
|
-
|
3863
|
-
|
3864
|
-
if (!draftVersion)
|
3865
|
-
return;
|
3866
|
-
return {
|
3867
|
-
...fp.pick(AVAILABLE_LOCALES_FIELDS, draftVersion),
|
3868
|
-
status: this.getStatus(draftVersion, otherVersions)
|
3869
|
-
};
|
3870
|
-
}).filter(Boolean);
|
4027
|
+
);
|
4028
|
+
return mappingResult.filter(Boolean);
|
3871
4029
|
},
|
3872
4030
|
/**
|
3873
4031
|
* Returns available status of a document for the current locale
|
@@ -3905,26 +4063,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3905
4063
|
});
|
3906
4064
|
},
|
3907
4065
|
getStatus(version, otherDocumentStatuses) {
|
3908
|
-
|
3909
|
-
|
3910
|
-
|
4066
|
+
let draftVersion;
|
4067
|
+
let publishedVersion;
|
4068
|
+
if (version.publishedAt) {
|
4069
|
+
publishedVersion = version;
|
4070
|
+
} else {
|
4071
|
+
draftVersion = version;
|
3911
4072
|
}
|
3912
|
-
|
3913
|
-
|
3914
|
-
|
3915
|
-
|
3916
|
-
|
4073
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4074
|
+
if (otherVersion?.publishedAt) {
|
4075
|
+
publishedVersion = otherVersion;
|
4076
|
+
} else if (otherVersion) {
|
4077
|
+
draftVersion = otherVersion;
|
3917
4078
|
}
|
3918
|
-
if (
|
4079
|
+
if (!draftVersion)
|
3919
4080
|
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
3920
|
-
|
3921
|
-
|
4081
|
+
if (!publishedVersion)
|
4082
|
+
return CONTENT_MANAGER_STATUS.DRAFT;
|
4083
|
+
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4084
|
+
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
3922
4085
|
},
|
4086
|
+
// TODO is it necessary to return metadata on every page of the CM
|
4087
|
+
// We could refactor this so the locales are only loaded when they're
|
4088
|
+
// needed. e.g. in the bulk locale action modal.
|
3923
4089
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4090
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3924
4091
|
const versions = await strapi2.db.query(uid2).findMany({
|
3925
4092
|
where: { documentId: version.documentId },
|
3926
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3927
4093
|
populate: {
|
4094
|
+
// Populate only fields that require validation for bulk locale actions
|
4095
|
+
...populate,
|
4096
|
+
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
3928
4097
|
createdBy: {
|
3929
4098
|
select: ["id", "firstname", "lastname", "email"]
|
3930
4099
|
},
|
@@ -3933,7 +4102,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3933
4102
|
}
|
3934
4103
|
}
|
3935
4104
|
});
|
3936
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4105
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3937
4106
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3938
4107
|
return {
|
3939
4108
|
availableLocales: availableLocalesResult,
|
@@ -3946,8 +4115,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3946
4115
|
* - Available status of the document for the current locale
|
3947
4116
|
*/
|
3948
4117
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3949
|
-
if (!document)
|
4118
|
+
if (!document) {
|
3950
4119
|
return document;
|
4120
|
+
}
|
3951
4121
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
3952
4122
|
if (!hasDraftAndPublish) {
|
3953
4123
|
opts.availableStatus = false;
|
@@ -3997,26 +4167,9 @@ const sumDraftCounts = (entity, uid2) => {
|
|
3997
4167
|
}, 0);
|
3998
4168
|
};
|
3999
4169
|
const { ApplicationError } = strapiUtils.errors;
|
4000
|
-
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
|
4001
4170
|
const { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
|
4002
4171
|
const omitPublishedAtField = fp.omit(PUBLISHED_AT_ATTRIBUTE);
|
4003
4172
|
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
4173
|
const documentManager = ({ strapi: strapi2 }) => {
|
4021
4174
|
return {
|
4022
4175
|
async findOne(id, uid2, opts = {}) {
|
@@ -4035,6 +4188,9 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4035
4188
|
} else if (opts.locale && opts.locale !== "*") {
|
4036
4189
|
where.locale = opts.locale;
|
4037
4190
|
}
|
4191
|
+
if (typeof opts.isPublished === "boolean") {
|
4192
|
+
where.publishedAt = { $notNull: opts.isPublished };
|
4193
|
+
}
|
4038
4194
|
return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
|
4039
4195
|
},
|
4040
4196
|
async findMany(opts, uid2) {
|
@@ -4042,20 +4198,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4042
4198
|
return strapi2.documents(uid2).findMany(params);
|
4043
4199
|
},
|
4044
4200
|
async findPage(opts, uid2) {
|
4045
|
-
const
|
4046
|
-
|
4201
|
+
const params = strapiUtils.pagination.withDefaultPagination(opts || {}, {
|
4202
|
+
maxLimit: 1e3
|
4203
|
+
});
|
4047
4204
|
const [documents, total = 0] = await Promise.all([
|
4048
|
-
strapi2.documents(uid2).findMany(
|
4049
|
-
strapi2.documents(uid2).count(
|
4205
|
+
strapi2.documents(uid2).findMany(params),
|
4206
|
+
strapi2.documents(uid2).count(params)
|
4050
4207
|
]);
|
4051
4208
|
return {
|
4052
4209
|
results: documents,
|
4053
|
-
pagination:
|
4054
|
-
page,
|
4055
|
-
pageSize,
|
4056
|
-
pageCount: Math.ceil(total / pageSize),
|
4057
|
-
total
|
4058
|
-
}
|
4210
|
+
pagination: strapiUtils.pagination.transformPagedPaginationInfo(params, total)
|
4059
4211
|
};
|
4060
4212
|
},
|
4061
4213
|
async create(uid2, opts = {}) {
|
@@ -4101,70 +4253,36 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4101
4253
|
return {};
|
4102
4254
|
},
|
4103
4255
|
// FIXME: handle relations
|
4104
|
-
async deleteMany(
|
4105
|
-
const
|
4106
|
-
|
4107
|
-
|
4108
|
-
}
|
4109
|
-
return { count: docs.length };
|
4256
|
+
async deleteMany(documentIds, uid2, opts = {}) {
|
4257
|
+
const deletedEntries = await strapi2.db.transaction(async () => {
|
4258
|
+
return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
|
4259
|
+
});
|
4260
|
+
return { count: deletedEntries.length };
|
4110
4261
|
},
|
4111
4262
|
async publish(id, uid2, opts = {}) {
|
4112
4263
|
const populate = await buildDeepPopulate(uid2);
|
4113
4264
|
const params = { ...opts, populate };
|
4114
|
-
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries
|
4265
|
+
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries);
|
4115
4266
|
},
|
4116
|
-
async publishMany(
|
4117
|
-
|
4118
|
-
|
4119
|
-
|
4120
|
-
|
4121
|
-
|
4122
|
-
|
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
|
4267
|
+
async publishMany(uid2, documentIds, locale) {
|
4268
|
+
return strapi2.db.transaction(async () => {
|
4269
|
+
const results = await Promise.all(
|
4270
|
+
documentIds.map((documentId) => this.publish(documentId, uid2, { locale }))
|
4271
|
+
);
|
4272
|
+
const publishedEntitiesCount = results.flat().filter(Boolean).length;
|
4273
|
+
return publishedEntitiesCount;
|
4142
4274
|
});
|
4143
|
-
await Promise.all(
|
4144
|
-
publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
|
4145
|
-
);
|
4146
|
-
return publishedEntitiesCount;
|
4147
4275
|
},
|
4148
|
-
async unpublishMany(
|
4149
|
-
|
4150
|
-
return
|
4151
|
-
|
4152
|
-
|
4153
|
-
|
4154
|
-
|
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
|
4276
|
+
async unpublishMany(documentIds, uid2, opts = {}) {
|
4277
|
+
const unpublishedEntries = await strapi2.db.transaction(async () => {
|
4278
|
+
return Promise.all(
|
4279
|
+
documentIds.map(
|
4280
|
+
(id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
|
4281
|
+
)
|
4282
|
+
);
|
4163
4283
|
});
|
4164
|
-
|
4165
|
-
|
4166
|
-
);
|
4167
|
-
return unpublishedEntitiesCount;
|
4284
|
+
const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
|
4285
|
+
return { count: unpublishedEntitiesCount };
|
4168
4286
|
},
|
4169
4287
|
async unpublish(id, uid2, opts = {}) {
|
4170
4288
|
const populate = await buildDeepPopulate(uid2);
|
@@ -4189,16 +4307,20 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4189
4307
|
}
|
4190
4308
|
return sumDraftCounts(document, uid2);
|
4191
4309
|
},
|
4192
|
-
async countManyEntriesDraftRelations(
|
4310
|
+
async countManyEntriesDraftRelations(documentIds, uid2, locale) {
|
4193
4311
|
const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
|
4194
4312
|
if (!hasRelations) {
|
4195
4313
|
return 0;
|
4196
4314
|
}
|
4315
|
+
let localeFilter = {};
|
4316
|
+
if (locale) {
|
4317
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4318
|
+
}
|
4197
4319
|
const entities = await strapi2.db.query(uid2).findMany({
|
4198
4320
|
populate,
|
4199
4321
|
where: {
|
4200
|
-
|
4201
|
-
...
|
4322
|
+
documentId: { $in: documentIds },
|
4323
|
+
...localeFilter
|
4202
4324
|
}
|
4203
4325
|
});
|
4204
4326
|
const totalNumberDraftRelations = entities.reduce(
|