@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.edc24aaa3bb5a90fa5fd4fee208167dd4e2e38d4
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/LICENSE +18 -3
- 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-DjWJdz6Y.js → ComponentConfigurationPage-5ukroXAh.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-5ukroXAh.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-BAgyHiMm.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-BAgyHiMm.mjs.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-DacbqQ_f.mjs → EditConfigurationPage-DmoXawIh.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-DmoXawIh.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-Xp7lun0f.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-Xp7lun0f.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-BLsjc5F-.mjs} +47 -47
- package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-C-ukDOB7.js} +46 -48
- package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-Bfph5SOd.js} +953 -782
- package/dist/_chunks/Field-Bfph5SOd.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-Cs7duwWd.mjs} +901 -729
- package/dist/_chunks/Field-Cs7duwWd.mjs.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-CPYqIWDG.js} +39 -38
- package/dist/_chunks/Form-CPYqIWDG.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-Dg_GS5TQ.mjs} +39 -37
- package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-DNQkXANT.js} +149 -56
- package/dist/_chunks/History-DNQkXANT.js.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-wrnHqf09.mjs} +148 -54
- package/dist/_chunks/History-wrnHqf09.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-CUQxfpjT.js} +58 -59
- package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-DScmJVkW.mjs} +54 -54
- package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-BsLiH2-2.js} +92 -108
- package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-C4IvrMgY.mjs} +87 -103
- package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BZ-PnGAf.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BZ-PnGAf.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Djg8nPlj.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-Djg8nPlj.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-DSP7R-hv.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-DSP7R-hv.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-_lUqjGW3.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-_lUqjGW3.js.map} +1 -1
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-BZr8tL0R.mjs} +66 -56
- package/dist/_chunks/Relations-BZr8tL0R.mjs.map +1 -0
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-CtELXYIK.js} +70 -61
- package/dist/_chunks/Relations-CtELXYIK.js.map +1 -0
- package/dist/_chunks/{en-MBPul9Su.mjs → en-BrCTWlZv.mjs} +11 -4
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-uOUIxfcQ.js} +11 -4
- package/dist/_chunks/{en-C-V1_90f.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-C6AH2hEl.js → index-OerGjbAN.js} +1588 -837
- package/dist/_chunks/index-OerGjbAN.js.map +1 -0
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-c_5DdJi-.mjs} +1610 -858
- package/dist/_chunks/index-c_5DdJi-.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-Ci7qHlFb.js} +30 -27
- package/dist/_chunks/layout-Ci7qHlFb.js.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-oPBiO7RY.mjs} +29 -24
- package/dist/_chunks/layout-oPBiO7RY.mjs.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-BIdWFjdq.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-BIdWFjdq.mjs.map} +1 -1
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-COBpStiF.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-COBpStiF.js.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/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -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/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- 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 +30 -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 +59 -52
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- 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 +309 -218
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +317 -226
- 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/uid.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 +11 -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.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/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-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.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/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.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1,
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set,
|
1
|
+
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
+
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, isNil as isNil$1, getOr, propEq, merge, groupBy, castArray } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -73,7 +73,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
73
73
|
);
|
74
74
|
return {
|
75
75
|
data: sanitizedResults,
|
76
|
-
meta: { pagination }
|
76
|
+
meta: { pagination: pagination2 }
|
77
77
|
};
|
78
78
|
},
|
79
79
|
async restoreVersion(ctx) {
|
@@ -206,6 +206,10 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
206
206
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
207
|
switch (attribute.type) {
|
208
208
|
case "relation": {
|
209
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
210
|
+
if (isMorphRelation) {
|
211
|
+
break;
|
212
|
+
}
|
209
213
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
214
|
if (isVisible2) {
|
211
215
|
acc[attributeName] = { fields: ["documentId", "locale", "publishedAt"] };
|
@@ -309,7 +313,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
309
313
|
},
|
310
314
|
async findVersionsPage(params) {
|
311
315
|
const locale = params.query.locale || await serviceUtils.getDefaultLocale();
|
312
|
-
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
316
|
+
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
317
|
query.findPage({
|
314
318
|
...params.query,
|
315
319
|
where: {
|
@@ -408,7 +412,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
408
412
|
);
|
409
413
|
return {
|
410
414
|
results: formattedResults,
|
411
|
-
pagination
|
415
|
+
pagination: pagination2
|
412
416
|
};
|
413
417
|
},
|
414
418
|
async restoreVersion(versionId) {
|
@@ -469,8 +473,6 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
469
473
|
deleteExpiredJob: null,
|
470
474
|
isInitialized: false
|
471
475
|
};
|
472
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
473
|
-
const historyService = getService(strapi2, "history");
|
474
476
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
475
477
|
return {
|
476
478
|
async bootstrap() {
|
@@ -481,7 +483,10 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
481
483
|
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
484
|
return next();
|
483
485
|
}
|
484
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
486
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
487
|
+
return next();
|
488
|
+
}
|
489
|
+
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
485
490
|
return next();
|
486
491
|
}
|
487
492
|
const contentTypeUid = context.contentType.uid;
|
@@ -489,9 +494,18 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
489
494
|
return next();
|
490
495
|
}
|
491
496
|
const result = await next();
|
492
|
-
const documentContext =
|
497
|
+
const documentContext = {
|
498
|
+
documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
|
499
|
+
locale: context.params?.locale
|
500
|
+
};
|
493
501
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
494
502
|
const locale = documentContext.locale || defaultLocale;
|
503
|
+
if (Array.isArray(locale)) {
|
504
|
+
strapi2.log.warn(
|
505
|
+
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
506
|
+
);
|
507
|
+
return next();
|
508
|
+
}
|
495
509
|
const document = await strapi2.documents(contentTypeUid).findOne({
|
496
510
|
documentId: documentContext.documentId,
|
497
511
|
locale,
|
@@ -514,7 +528,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
514
528
|
}, {});
|
515
529
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
516
530
|
onCommit(() => {
|
517
|
-
|
531
|
+
getService(strapi2, "history").createVersion({
|
518
532
|
contentType: contentTypeUid,
|
519
533
|
data: omit(FIELDS_TO_IGNORE, document),
|
520
534
|
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
@@ -527,11 +541,10 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
527
541
|
});
|
528
542
|
return result;
|
529
543
|
});
|
530
|
-
const retentionDays = serviceUtils.getRetentionDays();
|
531
544
|
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
532
|
-
const retentionDaysInMilliseconds =
|
545
|
+
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
533
546
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
534
|
-
query.deleteMany({
|
547
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
535
548
|
where: {
|
536
549
|
created_at: {
|
537
550
|
$lt: expirationDate.toISOString()
|
@@ -1452,7 +1465,7 @@ const { PaginationError, ValidationError } = errors;
|
|
1452
1465
|
const TYPES = ["singleType", "collectionType"];
|
1453
1466
|
const kindSchema = yup$1.string().oneOf(TYPES).nullable();
|
1454
1467
|
const bulkActionInputSchema = yup$1.object({
|
1455
|
-
|
1468
|
+
documentIds: yup$1.array().of(yup$1.strapiID()).min(1).required()
|
1456
1469
|
}).required();
|
1457
1470
|
const generateUIDInputSchema = yup$1.object({
|
1458
1471
|
contentTypeUID: yup$1.string().required(),
|
@@ -1551,15 +1564,49 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1551
1564
|
}
|
1552
1565
|
}, body);
|
1553
1566
|
};
|
1554
|
-
const
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1567
|
+
const singleLocaleSchema = yup$1.string().nullable();
|
1568
|
+
const multipleLocaleSchema = yup$1.lazy(
|
1569
|
+
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1570
|
+
);
|
1571
|
+
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1572
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1573
|
+
const { allowMultipleLocales } = opts;
|
1574
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1575
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1576
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1577
|
+
const schema = yup$1.object().shape({
|
1578
|
+
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1579
|
+
status: statusSchema
|
1580
|
+
});
|
1581
|
+
try {
|
1582
|
+
await validateYupSchema(schema, { strict: true, abortEarly: false })(request);
|
1583
|
+
return { locale, status, ...rest };
|
1584
|
+
} catch (error) {
|
1585
|
+
throw new errors.ValidationError(`Validation error: ${error.message}`);
|
1561
1586
|
}
|
1562
|
-
|
1587
|
+
};
|
1588
|
+
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1589
|
+
const documentMetadata2 = getService$1("document-metadata");
|
1590
|
+
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1591
|
+
let {
|
1592
|
+
meta: { availableLocales, availableStatus }
|
1593
|
+
} = serviceOutput;
|
1594
|
+
const metadataSanitizer = permissionChecker2.sanitizeOutput;
|
1595
|
+
availableLocales = await async.map(
|
1596
|
+
availableLocales,
|
1597
|
+
async (localeDocument) => metadataSanitizer(localeDocument)
|
1598
|
+
);
|
1599
|
+
availableStatus = await async.map(
|
1600
|
+
availableStatus,
|
1601
|
+
async (statusDocument) => metadataSanitizer(statusDocument)
|
1602
|
+
);
|
1603
|
+
return {
|
1604
|
+
...serviceOutput,
|
1605
|
+
meta: {
|
1606
|
+
availableLocales,
|
1607
|
+
availableStatus
|
1608
|
+
}
|
1609
|
+
};
|
1563
1610
|
};
|
1564
1611
|
const createDocument = async (ctx, opts) => {
|
1565
1612
|
const { userAbility, user } = ctx.state;
|
@@ -1574,7 +1621,7 @@ const createDocument = async (ctx, opts) => {
|
|
1574
1621
|
const setCreator = setCreatorFields({ user });
|
1575
1622
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1576
1623
|
const sanitizedBody = await sanitizeFn(body);
|
1577
|
-
const { locale, status
|
1624
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1578
1625
|
return documentManager2.create(model, {
|
1579
1626
|
data: sanitizedBody,
|
1580
1627
|
locale,
|
@@ -1593,7 +1640,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1593
1640
|
}
|
1594
1641
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1595
1642
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1596
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1643
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1597
1644
|
const [documentVersion, documentExists] = await Promise.all([
|
1598
1645
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1599
1646
|
documentManager2.exists(model, id)
|
@@ -1631,8 +1678,8 @@ const collectionTypes = {
|
|
1631
1678
|
}
|
1632
1679
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1633
1680
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1634
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1635
|
-
const { results: documents, pagination } = await documentManager2.findPage(
|
1681
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1682
|
+
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1636
1683
|
{ ...permissionQuery, populate, locale, status },
|
1637
1684
|
model
|
1638
1685
|
);
|
@@ -1653,21 +1700,20 @@ const collectionTypes = {
|
|
1653
1700
|
);
|
1654
1701
|
ctx.body = {
|
1655
1702
|
results,
|
1656
|
-
pagination
|
1703
|
+
pagination: pagination2
|
1657
1704
|
};
|
1658
1705
|
},
|
1659
1706
|
async findOne(ctx) {
|
1660
1707
|
const { userAbility } = ctx.state;
|
1661
1708
|
const { model, id } = ctx.params;
|
1662
1709
|
const documentManager2 = getService$1("document-manager");
|
1663
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1664
1710
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1665
1711
|
if (permissionChecker2.cannot.read()) {
|
1666
1712
|
return ctx.forbidden();
|
1667
1713
|
}
|
1668
1714
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1669
1715
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1670
|
-
const { locale, status
|
1716
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1671
1717
|
const version = await documentManager2.findOne(id, model, {
|
1672
1718
|
populate,
|
1673
1719
|
locale,
|
@@ -1678,8 +1724,10 @@ const collectionTypes = {
|
|
1678
1724
|
if (!exists) {
|
1679
1725
|
return ctx.notFound();
|
1680
1726
|
}
|
1681
|
-
const { meta } = await
|
1727
|
+
const { meta } = await formatDocumentWithMetadata(
|
1728
|
+
permissionChecker2,
|
1682
1729
|
model,
|
1730
|
+
// @ts-expect-error TODO: fix
|
1683
1731
|
{ id, locale, publishedAt: null },
|
1684
1732
|
{ availableLocales: true, availableStatus: false }
|
1685
1733
|
);
|
@@ -1690,12 +1738,11 @@ const collectionTypes = {
|
|
1690
1738
|
return ctx.forbidden();
|
1691
1739
|
}
|
1692
1740
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1693
|
-
ctx.body = await
|
1741
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1694
1742
|
},
|
1695
1743
|
async create(ctx) {
|
1696
1744
|
const { userAbility } = ctx.state;
|
1697
1745
|
const { model } = ctx.params;
|
1698
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1699
1746
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1700
1747
|
const [totalEntries, document] = await Promise.all([
|
1701
1748
|
strapi.db.query(model).count(),
|
@@ -1703,7 +1750,7 @@ const collectionTypes = {
|
|
1703
1750
|
]);
|
1704
1751
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1705
1752
|
ctx.status = 201;
|
1706
|
-
ctx.body = await
|
1753
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1707
1754
|
// Empty metadata as it's not relevant for a new document
|
1708
1755
|
availableLocales: false,
|
1709
1756
|
availableStatus: false
|
@@ -1717,25 +1764,23 @@ const collectionTypes = {
|
|
1717
1764
|
async update(ctx) {
|
1718
1765
|
const { userAbility } = ctx.state;
|
1719
1766
|
const { model } = ctx.params;
|
1720
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1721
1767
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1722
1768
|
const updatedVersion = await updateDocument(ctx);
|
1723
1769
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1724
|
-
ctx.body = await
|
1770
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1725
1771
|
},
|
1726
1772
|
async clone(ctx) {
|
1727
1773
|
const { userAbility, user } = ctx.state;
|
1728
1774
|
const { model, sourceId: id } = ctx.params;
|
1729
1775
|
const { body } = ctx.request;
|
1730
1776
|
const documentManager2 = getService$1("document-manager");
|
1731
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1732
1777
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1733
1778
|
if (permissionChecker2.cannot.create()) {
|
1734
1779
|
return ctx.forbidden();
|
1735
1780
|
}
|
1736
1781
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1737
1782
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1738
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1783
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1739
1784
|
const document = await documentManager2.findOne(id, model, {
|
1740
1785
|
populate,
|
1741
1786
|
locale,
|
@@ -1751,7 +1796,7 @@ const collectionTypes = {
|
|
1751
1796
|
const sanitizedBody = await sanitizeFn(body);
|
1752
1797
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1753
1798
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1754
|
-
ctx.body = await
|
1799
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1755
1800
|
// Empty metadata as it's not relevant for a new document
|
1756
1801
|
availableLocales: false,
|
1757
1802
|
availableStatus: false
|
@@ -1780,7 +1825,7 @@ const collectionTypes = {
|
|
1780
1825
|
}
|
1781
1826
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1782
1827
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1783
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
1828
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1784
1829
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1785
1830
|
if (documentLocales.length === 0) {
|
1786
1831
|
return ctx.notFound();
|
@@ -1802,7 +1847,6 @@ const collectionTypes = {
|
|
1802
1847
|
const { id, model } = ctx.params;
|
1803
1848
|
const { body } = ctx.request;
|
1804
1849
|
const documentManager2 = getService$1("document-manager");
|
1805
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1806
1850
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1807
1851
|
if (permissionChecker2.cannot.publish()) {
|
1808
1852
|
return ctx.forbidden();
|
@@ -1814,21 +1858,25 @@ const collectionTypes = {
|
|
1814
1858
|
if (permissionChecker2.cannot.publish(document)) {
|
1815
1859
|
throw new errors.ForbiddenError();
|
1816
1860
|
}
|
1817
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1818
|
-
|
1861
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1862
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1819
1863
|
locale
|
1820
1864
|
// TODO: Allow setting creator fields on publish
|
1821
1865
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1822
1866
|
});
|
1867
|
+
if (!publishResult || publishResult.length === 0) {
|
1868
|
+
throw new errors.NotFoundError("Document not found or already published.");
|
1869
|
+
}
|
1870
|
+
return publishResult[0];
|
1823
1871
|
});
|
1824
1872
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1825
|
-
ctx.body = await
|
1873
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1826
1874
|
},
|
1827
1875
|
async bulkPublish(ctx) {
|
1828
1876
|
const { userAbility } = ctx.state;
|
1829
1877
|
const { model } = ctx.params;
|
1830
1878
|
const { body } = ctx.request;
|
1831
|
-
const {
|
1879
|
+
const { documentIds } = body;
|
1832
1880
|
await validateBulkActionInput(body);
|
1833
1881
|
const documentManager2 = getService$1("document-manager");
|
1834
1882
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1837,8 +1885,13 @@ const collectionTypes = {
|
|
1837
1885
|
}
|
1838
1886
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1839
1887
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1840
|
-
const
|
1841
|
-
|
1888
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1889
|
+
allowMultipleLocales: true
|
1890
|
+
});
|
1891
|
+
const entityPromises = documentIds.map(
|
1892
|
+
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1893
|
+
);
|
1894
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1842
1895
|
for (const entity of entities) {
|
1843
1896
|
if (!entity) {
|
1844
1897
|
return ctx.notFound();
|
@@ -1847,24 +1900,25 @@ const collectionTypes = {
|
|
1847
1900
|
return ctx.forbidden();
|
1848
1901
|
}
|
1849
1902
|
}
|
1850
|
-
const
|
1903
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1851
1904
|
ctx.body = { count };
|
1852
1905
|
},
|
1853
1906
|
async bulkUnpublish(ctx) {
|
1854
1907
|
const { userAbility } = ctx.state;
|
1855
1908
|
const { model } = ctx.params;
|
1856
1909
|
const { body } = ctx.request;
|
1857
|
-
const {
|
1910
|
+
const { documentIds } = body;
|
1858
1911
|
await validateBulkActionInput(body);
|
1859
1912
|
const documentManager2 = getService$1("document-manager");
|
1860
1913
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1861
1914
|
if (permissionChecker2.cannot.unpublish()) {
|
1862
1915
|
return ctx.forbidden();
|
1863
1916
|
}
|
1864
|
-
const
|
1865
|
-
const
|
1866
|
-
|
1867
|
-
|
1917
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1918
|
+
const entityPromises = documentIds.map(
|
1919
|
+
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1920
|
+
);
|
1921
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1868
1922
|
for (const entity of entities) {
|
1869
1923
|
if (!entity) {
|
1870
1924
|
return ctx.notFound();
|
@@ -1873,7 +1927,8 @@ const collectionTypes = {
|
|
1873
1927
|
return ctx.forbidden();
|
1874
1928
|
}
|
1875
1929
|
}
|
1876
|
-
const
|
1930
|
+
const entitiesIds = entities.map((document) => document.documentId);
|
1931
|
+
const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
|
1877
1932
|
ctx.body = { count };
|
1878
1933
|
},
|
1879
1934
|
async unpublish(ctx) {
|
@@ -1883,7 +1938,6 @@ const collectionTypes = {
|
|
1883
1938
|
body: { discardDraft, ...body }
|
1884
1939
|
} = ctx.request;
|
1885
1940
|
const documentManager2 = getService$1("document-manager");
|
1886
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1887
1941
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1888
1942
|
if (permissionChecker2.cannot.unpublish()) {
|
1889
1943
|
return ctx.forbidden();
|
@@ -1893,7 +1947,7 @@ const collectionTypes = {
|
|
1893
1947
|
}
|
1894
1948
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1895
1949
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1896
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1950
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1897
1951
|
const document = await documentManager2.findOne(id, model, {
|
1898
1952
|
populate,
|
1899
1953
|
locale,
|
@@ -1915,7 +1969,7 @@ const collectionTypes = {
|
|
1915
1969
|
ctx.body = await async.pipe(
|
1916
1970
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1917
1971
|
permissionChecker2.sanitizeOutput,
|
1918
|
-
(document2) =>
|
1972
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1919
1973
|
)(document);
|
1920
1974
|
});
|
1921
1975
|
},
|
@@ -1924,14 +1978,13 @@ const collectionTypes = {
|
|
1924
1978
|
const { id, model } = ctx.params;
|
1925
1979
|
const { body } = ctx.request;
|
1926
1980
|
const documentManager2 = getService$1("document-manager");
|
1927
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1928
1981
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1929
1982
|
if (permissionChecker2.cannot.discard()) {
|
1930
1983
|
return ctx.forbidden();
|
1931
1984
|
}
|
1932
1985
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1933
1986
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1934
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1987
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1935
1988
|
const document = await documentManager2.findOne(id, model, {
|
1936
1989
|
populate,
|
1937
1990
|
locale,
|
@@ -1946,14 +1999,14 @@ const collectionTypes = {
|
|
1946
1999
|
ctx.body = await async.pipe(
|
1947
2000
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1948
2001
|
permissionChecker2.sanitizeOutput,
|
1949
|
-
(document2) =>
|
2002
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1950
2003
|
)(document);
|
1951
2004
|
},
|
1952
2005
|
async bulkDelete(ctx) {
|
1953
2006
|
const { userAbility } = ctx.state;
|
1954
2007
|
const { model } = ctx.params;
|
1955
2008
|
const { query, body } = ctx.request;
|
1956
|
-
const {
|
2009
|
+
const { documentIds } = body;
|
1957
2010
|
await validateBulkActionInput(body);
|
1958
2011
|
const documentManager2 = getService$1("document-manager");
|
1959
2012
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1961,14 +2014,22 @@ const collectionTypes = {
|
|
1961
2014
|
return ctx.forbidden();
|
1962
2015
|
}
|
1963
2016
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1964
|
-
const
|
1965
|
-
const
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
2017
|
+
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2018
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2019
|
+
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2020
|
+
populate,
|
2021
|
+
locale
|
2022
|
+
});
|
2023
|
+
if (documentLocales.length === 0) {
|
2024
|
+
return ctx.notFound();
|
2025
|
+
}
|
2026
|
+
for (const document of documentLocales) {
|
2027
|
+
if (permissionChecker2.cannot.delete(document)) {
|
2028
|
+
return ctx.forbidden();
|
1969
2029
|
}
|
1970
|
-
}
|
1971
|
-
const
|
2030
|
+
}
|
2031
|
+
const localeDocumentsIds = documentLocales.map((document) => document.documentId);
|
2032
|
+
const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
|
1972
2033
|
ctx.body = { count };
|
1973
2034
|
},
|
1974
2035
|
async countDraftRelations(ctx) {
|
@@ -1981,7 +2042,7 @@ const collectionTypes = {
|
|
1981
2042
|
}
|
1982
2043
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1983
2044
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1984
|
-
const { locale, status
|
2045
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1985
2046
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
1986
2047
|
if (!entity) {
|
1987
2048
|
return ctx.notFound();
|
@@ -1996,7 +2057,7 @@ const collectionTypes = {
|
|
1996
2057
|
},
|
1997
2058
|
async countManyEntriesDraftRelations(ctx) {
|
1998
2059
|
const { userAbility } = ctx.state;
|
1999
|
-
const ids = ctx.request.query.
|
2060
|
+
const ids = ctx.request.query.documentIds;
|
2000
2061
|
const locale = ctx.request.query.locale;
|
2001
2062
|
const { model } = ctx.params;
|
2002
2063
|
const documentManager2 = getService$1("document-manager");
|
@@ -2004,16 +2065,16 @@ const collectionTypes = {
|
|
2004
2065
|
if (permissionChecker2.cannot.read()) {
|
2005
2066
|
return ctx.forbidden();
|
2006
2067
|
}
|
2007
|
-
const
|
2068
|
+
const documents = await documentManager2.findMany(
|
2008
2069
|
{
|
2009
2070
|
filters: {
|
2010
|
-
|
2071
|
+
documentId: ids
|
2011
2072
|
},
|
2012
2073
|
locale
|
2013
2074
|
},
|
2014
2075
|
model
|
2015
2076
|
);
|
2016
|
-
if (!
|
2077
|
+
if (!documents) {
|
2017
2078
|
return ctx.notFound();
|
2018
2079
|
}
|
2019
2080
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2509,7 +2570,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2509
2570
|
throw new errors.ForbiddenError();
|
2510
2571
|
}
|
2511
2572
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2512
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2573
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2513
2574
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2514
2575
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2515
2576
|
// Find the first document to check if it exists
|
@@ -2546,12 +2607,11 @@ const singleTypes = {
|
|
2546
2607
|
const { model } = ctx.params;
|
2547
2608
|
const { query = {} } = ctx.request;
|
2548
2609
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2549
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2550
2610
|
if (permissionChecker2.cannot.read()) {
|
2551
2611
|
return ctx.forbidden();
|
2552
2612
|
}
|
2553
2613
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2554
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2614
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2555
2615
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2556
2616
|
if (!version) {
|
2557
2617
|
if (permissionChecker2.cannot.create()) {
|
@@ -2561,8 +2621,10 @@ const singleTypes = {
|
|
2561
2621
|
if (!document) {
|
2562
2622
|
return ctx.notFound();
|
2563
2623
|
}
|
2564
|
-
const { meta } = await
|
2624
|
+
const { meta } = await formatDocumentWithMetadata(
|
2625
|
+
permissionChecker2,
|
2565
2626
|
model,
|
2627
|
+
// @ts-expect-error - fix types
|
2566
2628
|
{ id: document.documentId, locale, publishedAt: null },
|
2567
2629
|
{ availableLocales: true, availableStatus: false }
|
2568
2630
|
);
|
@@ -2573,16 +2635,15 @@ const singleTypes = {
|
|
2573
2635
|
return ctx.forbidden();
|
2574
2636
|
}
|
2575
2637
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2576
|
-
ctx.body = await
|
2638
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2577
2639
|
},
|
2578
2640
|
async createOrUpdate(ctx) {
|
2579
2641
|
const { userAbility } = ctx.state;
|
2580
2642
|
const { model } = ctx.params;
|
2581
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2582
2643
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2583
2644
|
const document = await createOrUpdateDocument(ctx);
|
2584
2645
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2585
|
-
ctx.body = await
|
2646
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2586
2647
|
},
|
2587
2648
|
async delete(ctx) {
|
2588
2649
|
const { userAbility } = ctx.state;
|
@@ -2595,7 +2656,7 @@ const singleTypes = {
|
|
2595
2656
|
}
|
2596
2657
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2597
2658
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2598
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2659
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2599
2660
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2600
2661
|
populate,
|
2601
2662
|
locale
|
@@ -2618,7 +2679,6 @@ const singleTypes = {
|
|
2618
2679
|
const { model } = ctx.params;
|
2619
2680
|
const { query = {} } = ctx.request;
|
2620
2681
|
const documentManager2 = getService$1("document-manager");
|
2621
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2622
2682
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2623
2683
|
if (permissionChecker2.cannot.publish()) {
|
2624
2684
|
return ctx.forbidden();
|
@@ -2633,11 +2693,12 @@ const singleTypes = {
|
|
2633
2693
|
if (permissionChecker2.cannot.publish(document)) {
|
2634
2694
|
throw new errors.ForbiddenError();
|
2635
2695
|
}
|
2636
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2637
|
-
|
2696
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2697
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2698
|
+
return publishResult.at(0);
|
2638
2699
|
});
|
2639
2700
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2640
|
-
ctx.body = await
|
2701
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2641
2702
|
},
|
2642
2703
|
async unpublish(ctx) {
|
2643
2704
|
const { userAbility } = ctx.state;
|
@@ -2647,7 +2708,6 @@ const singleTypes = {
|
|
2647
2708
|
query = {}
|
2648
2709
|
} = ctx.request;
|
2649
2710
|
const documentManager2 = getService$1("document-manager");
|
2650
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2651
2711
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2652
2712
|
if (permissionChecker2.cannot.unpublish()) {
|
2653
2713
|
return ctx.forbidden();
|
@@ -2656,7 +2716,7 @@ const singleTypes = {
|
|
2656
2716
|
return ctx.forbidden();
|
2657
2717
|
}
|
2658
2718
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2659
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2719
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2660
2720
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2661
2721
|
if (!document) {
|
2662
2722
|
return ctx.notFound();
|
@@ -2674,7 +2734,7 @@ const singleTypes = {
|
|
2674
2734
|
ctx.body = await async.pipe(
|
2675
2735
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2676
2736
|
permissionChecker2.sanitizeOutput,
|
2677
|
-
(document2) =>
|
2737
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2678
2738
|
)(document);
|
2679
2739
|
});
|
2680
2740
|
},
|
@@ -2683,13 +2743,12 @@ const singleTypes = {
|
|
2683
2743
|
const { model } = ctx.params;
|
2684
2744
|
const { body, query = {} } = ctx.request;
|
2685
2745
|
const documentManager2 = getService$1("document-manager");
|
2686
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2687
2746
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2688
2747
|
if (permissionChecker2.cannot.discard()) {
|
2689
2748
|
return ctx.forbidden();
|
2690
2749
|
}
|
2691
2750
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2692
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2751
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2693
2752
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2694
2753
|
if (!document) {
|
2695
2754
|
return ctx.notFound();
|
@@ -2700,7 +2759,7 @@ const singleTypes = {
|
|
2700
2759
|
ctx.body = await async.pipe(
|
2701
2760
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2702
2761
|
permissionChecker2.sanitizeOutput,
|
2703
|
-
(document2) =>
|
2762
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2704
2763
|
)(document);
|
2705
2764
|
},
|
2706
2765
|
async countDraftRelations(ctx) {
|
@@ -2709,7 +2768,7 @@ const singleTypes = {
|
|
2709
2768
|
const { query } = ctx.request;
|
2710
2769
|
const documentManager2 = getService$1("document-manager");
|
2711
2770
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2712
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2771
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2713
2772
|
if (permissionChecker2.cannot.read()) {
|
2714
2773
|
return ctx.forbidden();
|
2715
2774
|
}
|
@@ -2730,7 +2789,7 @@ const uid$1 = {
|
|
2730
2789
|
async generateUID(ctx) {
|
2731
2790
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2732
2791
|
const { query = {} } = ctx.request;
|
2733
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2792
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2734
2793
|
await validateUIDField(contentTypeUID, field);
|
2735
2794
|
const uidService = getService$1("uid");
|
2736
2795
|
ctx.body = {
|
@@ -2742,7 +2801,7 @@ const uid$1 = {
|
|
2742
2801
|
ctx.request.body
|
2743
2802
|
);
|
2744
2803
|
const { query = {} } = ctx.request;
|
2745
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2804
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2746
2805
|
await validateUIDField(contentTypeUID, field);
|
2747
2806
|
const uidService = getService$1("uid");
|
2748
2807
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3533,7 +3592,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3533
3592
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3534
3593
|
}
|
3535
3594
|
});
|
3536
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils.contentTypes;
|
3595
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils.contentTypes;
|
3537
3596
|
const { isAnyToMany } = strapiUtils.relations;
|
3538
3597
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils.contentTypes.constants;
|
3539
3598
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3624,6 +3683,42 @@ const getDeepPopulate = (uid2, {
|
|
3624
3683
|
{}
|
3625
3684
|
);
|
3626
3685
|
};
|
3686
|
+
const getValidatableFieldsPopulate = (uid2, {
|
3687
|
+
initialPopulate = {},
|
3688
|
+
countMany = false,
|
3689
|
+
countOne = false,
|
3690
|
+
maxLevel = Infinity
|
3691
|
+
} = {}, level = 1) => {
|
3692
|
+
if (level > maxLevel) {
|
3693
|
+
return {};
|
3694
|
+
}
|
3695
|
+
const model = strapi.getModel(uid2);
|
3696
|
+
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
3697
|
+
if (!getDoesAttributeRequireValidation(attribute)) {
|
3698
|
+
return populateAcc;
|
3699
|
+
}
|
3700
|
+
if (isScalarAttribute(attribute)) {
|
3701
|
+
return merge(populateAcc, {
|
3702
|
+
[attributeName]: true
|
3703
|
+
});
|
3704
|
+
}
|
3705
|
+
return merge(
|
3706
|
+
populateAcc,
|
3707
|
+
getPopulateFor(
|
3708
|
+
attributeName,
|
3709
|
+
model,
|
3710
|
+
{
|
3711
|
+
// @ts-expect-error - improve types
|
3712
|
+
initialPopulate: initialPopulate?.[attributeName],
|
3713
|
+
countMany,
|
3714
|
+
countOne,
|
3715
|
+
maxLevel
|
3716
|
+
},
|
3717
|
+
level
|
3718
|
+
)
|
3719
|
+
);
|
3720
|
+
}, {});
|
3721
|
+
};
|
3627
3722
|
const getDeepPopulateDraftCount = (uid2) => {
|
3628
3723
|
const model = strapi.getModel(uid2);
|
3629
3724
|
let hasRelations = false;
|
@@ -3631,6 +3726,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3631
3726
|
const attribute = model.attributes[attributeName];
|
3632
3727
|
switch (attribute.type) {
|
3633
3728
|
case "relation": {
|
3729
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3730
|
+
if (isMorphRelation) {
|
3731
|
+
break;
|
3732
|
+
}
|
3634
3733
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3635
3734
|
populateAcc[attributeName] = {
|
3636
3735
|
count: true,
|
@@ -3645,22 +3744,24 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3645
3744
|
attribute.component
|
3646
3745
|
);
|
3647
3746
|
if (childHasRelations) {
|
3648
|
-
populateAcc[attributeName] = {
|
3747
|
+
populateAcc[attributeName] = {
|
3748
|
+
populate: populate2
|
3749
|
+
};
|
3649
3750
|
hasRelations = true;
|
3650
3751
|
}
|
3651
3752
|
break;
|
3652
3753
|
}
|
3653
3754
|
case "dynamiczone": {
|
3654
|
-
const
|
3655
|
-
const { populate:
|
3656
|
-
if (
|
3755
|
+
const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {
|
3756
|
+
const { populate: componentPopulate, hasRelations: componentHasRelations } = getDeepPopulateDraftCount(componentUID);
|
3757
|
+
if (componentHasRelations) {
|
3657
3758
|
hasRelations = true;
|
3658
|
-
return
|
3759
|
+
return { ...acc, [componentUID]: { populate: componentPopulate } };
|
3659
3760
|
}
|
3660
3761
|
return acc;
|
3661
3762
|
}, {});
|
3662
|
-
if (!isEmpty(
|
3663
|
-
populateAcc[attributeName] = {
|
3763
|
+
if (!isEmpty(dzPopulateFragment)) {
|
3764
|
+
populateAcc[attributeName] = { on: dzPopulateFragment };
|
3664
3765
|
}
|
3665
3766
|
break;
|
3666
3767
|
}
|
@@ -3852,41 +3953,70 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3852
3953
|
"updatedBy",
|
3853
3954
|
"status"
|
3854
3955
|
];
|
3855
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
3956
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
3957
|
+
"id",
|
3958
|
+
"locale",
|
3959
|
+
"updatedAt",
|
3960
|
+
"createdAt",
|
3961
|
+
"status",
|
3962
|
+
"publishedAt",
|
3963
|
+
"documentId"
|
3964
|
+
];
|
3856
3965
|
const CONTENT_MANAGER_STATUS = {
|
3857
3966
|
PUBLISHED: "published",
|
3858
3967
|
DRAFT: "draft",
|
3859
3968
|
MODIFIED: "modified"
|
3860
3969
|
};
|
3861
|
-
const
|
3862
|
-
if (!
|
3970
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
3971
|
+
if (!version || !version.updatedAt) {
|
3863
3972
|
return false;
|
3864
3973
|
}
|
3865
|
-
const
|
3866
|
-
const
|
3867
|
-
|
3868
|
-
return difference2 <= threshold;
|
3974
|
+
const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;
|
3975
|
+
const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;
|
3976
|
+
return versionUpdatedAt > otherUpdatedAt;
|
3869
3977
|
};
|
3870
3978
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3871
3979
|
/**
|
3872
3980
|
* Returns available locales of a document for the current status
|
3873
3981
|
*/
|
3874
|
-
getAvailableLocales(uid2, version, allVersions) {
|
3982
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3875
3983
|
const versionsByLocale = groupBy("locale", allVersions);
|
3876
3984
|
delete versionsByLocale[version.locale];
|
3877
|
-
|
3878
|
-
|
3879
|
-
|
3985
|
+
const model = strapi2.getModel(uid2);
|
3986
|
+
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3987
|
+
const traversalFunction = async (localeVersion) => traverseEntity(
|
3988
|
+
({ key }, { remove }) => {
|
3989
|
+
if (keysToKeep.includes(key)) {
|
3990
|
+
return;
|
3991
|
+
}
|
3992
|
+
remove(key);
|
3993
|
+
},
|
3994
|
+
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
3995
|
+
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
3996
|
+
localeVersion
|
3997
|
+
);
|
3998
|
+
const mappingResult = await async.map(
|
3999
|
+
Object.values(versionsByLocale),
|
4000
|
+
async (localeVersions) => {
|
4001
|
+
const mappedLocaleVersions = await async.map(
|
4002
|
+
localeVersions,
|
4003
|
+
traversalFunction
|
4004
|
+
);
|
4005
|
+
if (!contentTypes$1.hasDraftAndPublish(model)) {
|
4006
|
+
return mappedLocaleVersions[0];
|
4007
|
+
}
|
4008
|
+
const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
|
4009
|
+
const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
|
4010
|
+
if (!draftVersion) {
|
4011
|
+
return;
|
4012
|
+
}
|
4013
|
+
return {
|
4014
|
+
...draftVersion,
|
4015
|
+
status: this.getStatus(draftVersion, otherVersions)
|
4016
|
+
};
|
3880
4017
|
}
|
3881
|
-
|
3882
|
-
|
3883
|
-
if (!draftVersion)
|
3884
|
-
return;
|
3885
|
-
return {
|
3886
|
-
...pick(AVAILABLE_LOCALES_FIELDS, draftVersion),
|
3887
|
-
status: this.getStatus(draftVersion, otherVersions)
|
3888
|
-
};
|
3889
|
-
}).filter(Boolean);
|
4018
|
+
);
|
4019
|
+
return mappingResult.filter(Boolean);
|
3890
4020
|
},
|
3891
4021
|
/**
|
3892
4022
|
* Returns available status of a document for the current locale
|
@@ -3924,26 +4054,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3924
4054
|
});
|
3925
4055
|
},
|
3926
4056
|
getStatus(version, otherDocumentStatuses) {
|
3927
|
-
|
3928
|
-
|
3929
|
-
|
4057
|
+
let draftVersion;
|
4058
|
+
let publishedVersion;
|
4059
|
+
if (version.publishedAt) {
|
4060
|
+
publishedVersion = version;
|
4061
|
+
} else {
|
4062
|
+
draftVersion = version;
|
3930
4063
|
}
|
3931
|
-
|
3932
|
-
|
3933
|
-
|
3934
|
-
|
3935
|
-
|
4064
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4065
|
+
if (otherVersion?.publishedAt) {
|
4066
|
+
publishedVersion = otherVersion;
|
4067
|
+
} else if (otherVersion) {
|
4068
|
+
draftVersion = otherVersion;
|
3936
4069
|
}
|
3937
|
-
if (
|
4070
|
+
if (!draftVersion)
|
3938
4071
|
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
3939
|
-
|
3940
|
-
|
4072
|
+
if (!publishedVersion)
|
4073
|
+
return CONTENT_MANAGER_STATUS.DRAFT;
|
4074
|
+
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4075
|
+
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
3941
4076
|
},
|
4077
|
+
// TODO is it necessary to return metadata on every page of the CM
|
4078
|
+
// We could refactor this so the locales are only loaded when they're
|
4079
|
+
// needed. e.g. in the bulk locale action modal.
|
3942
4080
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4081
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3943
4082
|
const versions = await strapi2.db.query(uid2).findMany({
|
3944
4083
|
where: { documentId: version.documentId },
|
3945
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3946
4084
|
populate: {
|
4085
|
+
// Populate only fields that require validation for bulk locale actions
|
4086
|
+
...populate,
|
4087
|
+
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
3947
4088
|
createdBy: {
|
3948
4089
|
select: ["id", "firstname", "lastname", "email"]
|
3949
4090
|
},
|
@@ -3952,7 +4093,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3952
4093
|
}
|
3953
4094
|
}
|
3954
4095
|
});
|
3955
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4096
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3956
4097
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3957
4098
|
return {
|
3958
4099
|
availableLocales: availableLocalesResult,
|
@@ -3965,8 +4106,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3965
4106
|
* - Available status of the document for the current locale
|
3966
4107
|
*/
|
3967
4108
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3968
|
-
if (!document)
|
4109
|
+
if (!document) {
|
3969
4110
|
return document;
|
4111
|
+
}
|
3970
4112
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
3971
4113
|
if (!hasDraftAndPublish) {
|
3972
4114
|
opts.availableStatus = false;
|
@@ -4016,26 +4158,9 @@ const sumDraftCounts = (entity, uid2) => {
|
|
4016
4158
|
}, 0);
|
4017
4159
|
};
|
4018
4160
|
const { ApplicationError } = errors;
|
4019
|
-
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
|
4020
4161
|
const { PUBLISHED_AT_ATTRIBUTE } = contentTypes$1.constants;
|
4021
4162
|
const omitPublishedAtField = omit(PUBLISHED_AT_ATTRIBUTE);
|
4022
4163
|
const omitIdField = omit("id");
|
4023
|
-
const emitEvent = async (uid2, event, document) => {
|
4024
|
-
const modelDef = strapi.getModel(uid2);
|
4025
|
-
const sanitizedDocument = await sanitize.sanitizers.defaultSanitizeOutput(
|
4026
|
-
{
|
4027
|
-
schema: modelDef,
|
4028
|
-
getModel(uid22) {
|
4029
|
-
return strapi.getModel(uid22);
|
4030
|
-
}
|
4031
|
-
},
|
4032
|
-
document
|
4033
|
-
);
|
4034
|
-
strapi.eventHub.emit(event, {
|
4035
|
-
model: modelDef.modelName,
|
4036
|
-
entry: sanitizedDocument
|
4037
|
-
});
|
4038
|
-
};
|
4039
4164
|
const documentManager = ({ strapi: strapi2 }) => {
|
4040
4165
|
return {
|
4041
4166
|
async findOne(id, uid2, opts = {}) {
|
@@ -4054,6 +4179,9 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4054
4179
|
} else if (opts.locale && opts.locale !== "*") {
|
4055
4180
|
where.locale = opts.locale;
|
4056
4181
|
}
|
4182
|
+
if (typeof opts.isPublished === "boolean") {
|
4183
|
+
where.publishedAt = { $notNull: opts.isPublished };
|
4184
|
+
}
|
4057
4185
|
return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
|
4058
4186
|
},
|
4059
4187
|
async findMany(opts, uid2) {
|
@@ -4061,20 +4189,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4061
4189
|
return strapi2.documents(uid2).findMany(params);
|
4062
4190
|
},
|
4063
4191
|
async findPage(opts, uid2) {
|
4064
|
-
const
|
4065
|
-
|
4192
|
+
const params = pagination.withDefaultPagination(opts || {}, {
|
4193
|
+
maxLimit: 1e3
|
4194
|
+
});
|
4066
4195
|
const [documents, total = 0] = await Promise.all([
|
4067
|
-
strapi2.documents(uid2).findMany(
|
4068
|
-
strapi2.documents(uid2).count(
|
4196
|
+
strapi2.documents(uid2).findMany(params),
|
4197
|
+
strapi2.documents(uid2).count(params)
|
4069
4198
|
]);
|
4070
4199
|
return {
|
4071
4200
|
results: documents,
|
4072
|
-
pagination:
|
4073
|
-
page,
|
4074
|
-
pageSize,
|
4075
|
-
pageCount: Math.ceil(total / pageSize),
|
4076
|
-
total
|
4077
|
-
}
|
4201
|
+
pagination: pagination.transformPagedPaginationInfo(params, total)
|
4078
4202
|
};
|
4079
4203
|
},
|
4080
4204
|
async create(uid2, opts = {}) {
|
@@ -4091,10 +4215,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4091
4215
|
async clone(id, body, uid2) {
|
4092
4216
|
const populate = await buildDeepPopulate(uid2);
|
4093
4217
|
const params = {
|
4094
|
-
data:
|
4095
|
-
...omitIdField(body),
|
4096
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4097
|
-
},
|
4218
|
+
data: omitIdField(body),
|
4098
4219
|
populate
|
4099
4220
|
};
|
4100
4221
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4120,70 +4241,36 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4120
4241
|
return {};
|
4121
4242
|
},
|
4122
4243
|
// FIXME: handle relations
|
4123
|
-
async deleteMany(
|
4124
|
-
const
|
4125
|
-
|
4126
|
-
|
4127
|
-
}
|
4128
|
-
return { count: docs.length };
|
4244
|
+
async deleteMany(documentIds, uid2, opts = {}) {
|
4245
|
+
const deletedEntries = await strapi2.db.transaction(async () => {
|
4246
|
+
return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
|
4247
|
+
});
|
4248
|
+
return { count: deletedEntries.length };
|
4129
4249
|
},
|
4130
4250
|
async publish(id, uid2, opts = {}) {
|
4131
4251
|
const populate = await buildDeepPopulate(uid2);
|
4132
4252
|
const params = { ...opts, populate };
|
4133
|
-
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries
|
4253
|
+
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries);
|
4134
4254
|
},
|
4135
|
-
async publishMany(
|
4136
|
-
|
4137
|
-
|
4138
|
-
|
4139
|
-
|
4140
|
-
|
4141
|
-
|
4142
|
-
strapi2.getModel(uid2),
|
4143
|
-
document,
|
4144
|
-
void 0,
|
4145
|
-
// @ts-expect-error - FIXME: entity here is unnecessary
|
4146
|
-
document
|
4147
|
-
);
|
4148
|
-
})
|
4149
|
-
);
|
4150
|
-
const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
|
4151
|
-
const filters = { id: { $in: entitiesToPublish } };
|
4152
|
-
const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
|
4153
|
-
const populate = await buildDeepPopulate(uid2);
|
4154
|
-
const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4155
|
-
where: filters,
|
4156
|
-
data
|
4157
|
-
});
|
4158
|
-
const publishedEntities = await strapi2.db.query(uid2).findMany({
|
4159
|
-
where: filters,
|
4160
|
-
populate
|
4255
|
+
async publishMany(uid2, documentIds, locale) {
|
4256
|
+
return strapi2.db.transaction(async () => {
|
4257
|
+
const results = await Promise.all(
|
4258
|
+
documentIds.map((documentId) => this.publish(documentId, uid2, { locale }))
|
4259
|
+
);
|
4260
|
+
const publishedEntitiesCount = results.flat().filter(Boolean).length;
|
4261
|
+
return publishedEntitiesCount;
|
4161
4262
|
});
|
4162
|
-
await Promise.all(
|
4163
|
-
publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
|
4164
|
-
);
|
4165
|
-
return publishedEntitiesCount;
|
4166
4263
|
},
|
4167
|
-
async unpublishMany(
|
4168
|
-
|
4169
|
-
return
|
4170
|
-
|
4171
|
-
|
4172
|
-
|
4173
|
-
|
4174
|
-
const populate = await buildDeepPopulate(uid2);
|
4175
|
-
const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4176
|
-
where: filters,
|
4177
|
-
data
|
4178
|
-
});
|
4179
|
-
const unpublishedEntities = await strapi2.db.query(uid2).findMany({
|
4180
|
-
where: filters,
|
4181
|
-
populate
|
4264
|
+
async unpublishMany(documentIds, uid2, opts = {}) {
|
4265
|
+
const unpublishedEntries = await strapi2.db.transaction(async () => {
|
4266
|
+
return Promise.all(
|
4267
|
+
documentIds.map(
|
4268
|
+
(id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
|
4269
|
+
)
|
4270
|
+
);
|
4182
4271
|
});
|
4183
|
-
|
4184
|
-
|
4185
|
-
);
|
4186
|
-
return unpublishedEntitiesCount;
|
4272
|
+
const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
|
4273
|
+
return { count: unpublishedEntitiesCount };
|
4187
4274
|
},
|
4188
4275
|
async unpublish(id, uid2, opts = {}) {
|
4189
4276
|
const populate = await buildDeepPopulate(uid2);
|
@@ -4208,16 +4295,20 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4208
4295
|
}
|
4209
4296
|
return sumDraftCounts(document, uid2);
|
4210
4297
|
},
|
4211
|
-
async countManyEntriesDraftRelations(
|
4298
|
+
async countManyEntriesDraftRelations(documentIds, uid2, locale) {
|
4212
4299
|
const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
|
4213
4300
|
if (!hasRelations) {
|
4214
4301
|
return 0;
|
4215
4302
|
}
|
4303
|
+
let localeFilter = {};
|
4304
|
+
if (locale) {
|
4305
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4306
|
+
}
|
4216
4307
|
const entities = await strapi2.db.query(uid2).findMany({
|
4217
4308
|
populate,
|
4218
4309
|
where: {
|
4219
|
-
|
4220
|
-
...
|
4310
|
+
documentId: { $in: documentIds },
|
4311
|
+
...localeFilter
|
4221
4312
|
}
|
4222
4313
|
});
|
4223
4314
|
const totalNumberDraftRelations = entities.reduce(
|