@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.f75e3c6d67cc47c64ab37479efdbb7b43be50b78
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-BPvzFjM7.mjs → ComponentConfigurationPage-CuWgXugY.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-CuWgXugY.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-by0e_kNd.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.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-Dmv83RlS.js → EditConfigurationPage-CqBeCPGH.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-CqBeCPGH.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-DbI4KMyz.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-DbI4KMyz.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-ChgloMyO.js} +7 -9
- package/dist/_chunks/EditViewPage-ChgloMyO.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-dFPBya9U.mjs} +6 -6
- package/dist/_chunks/EditViewPage-dFPBya9U.mjs.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-C1nUKcdS.mjs} +500 -608
- package/dist/_chunks/Field-C1nUKcdS.mjs.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-dLk-vgLL.js} +552 -661
- package/dist/_chunks/Field-dLk-vgLL.js.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-CbXtmHC_.js} +18 -16
- package/dist/_chunks/Form-CbXtmHC_.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-DOlpi7Js.mjs} +16 -13
- package/dist/_chunks/Form-DOlpi7Js.mjs.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-BFNUAiGc.mjs} +29 -40
- package/dist/_chunks/History-BFNUAiGc.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-BjDfohBr.js} +30 -42
- package/dist/_chunks/History-BjDfohBr.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-DDi0KqFm.mjs} +9 -9
- package/dist/_chunks/ListConfigurationPage-DDi0KqFm.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-IQBgWTaa.js} +14 -16
- package/dist/_chunks/ListConfigurationPage-IQBgWTaa.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-BPjljUsH.mjs} +21 -41
- package/dist/_chunks/ListViewPage-BPjljUsH.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-CZYGqlvF.js} +28 -48
- package/dist/_chunks/ListViewPage-CZYGqlvF.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BOAI6VZ1.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BOAI6VZ1.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-DaWw67K-.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-DaWw67K-.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-CZrJH00p.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-CZrJH00p.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-cYEtLc_e.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-cYEtLc_e.js.map} +1 -1
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-DTowyge2.mjs} +66 -56
- package/dist/_chunks/Relations-DTowyge2.mjs.map +1 -0
- package/dist/_chunks/{Relations-CgWtgnPe.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-CwRRo1V9.mjs → index-BaGHmIir.mjs} +507 -202
- package/dist/_chunks/index-BaGHmIir.mjs.map +1 -0
- package/dist/_chunks/{index-C6AH2hEl.js → index-CCJeB7Rw.js} +502 -198
- package/dist/_chunks/index-CCJeB7Rw.js.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-BinjszSQ.mjs} +10 -10
- package/dist/_chunks/layout-BinjszSQ.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-ni_L9kT1.js} +12 -14
- package/dist/_chunks/layout-ni_L9kT1.js.map +1 -0
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-CeJAJc5I.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-CeJAJc5I.js.map} +1 -1
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-c91ji5eR.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.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 +273 -196
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +281 -204
- 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.map +1 -1
- package/dist/server/src/history/services/lifecycles.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/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
@@ -518,6 +518,12 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
518
518
|
const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
|
519
519
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
520
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
|
+
}
|
521
527
|
const document = await strapi2.documents(contentTypeUid).findOne({
|
522
528
|
documentId: documentContext.documentId,
|
523
529
|
locale,
|
@@ -1478,7 +1484,7 @@ const { PaginationError, ValidationError } = strapiUtils.errors;
|
|
1478
1484
|
const TYPES = ["singleType", "collectionType"];
|
1479
1485
|
const kindSchema = strapiUtils.yup.string().oneOf(TYPES).nullable();
|
1480
1486
|
const bulkActionInputSchema = strapiUtils.yup.object({
|
1481
|
-
|
1487
|
+
documentIds: strapiUtils.yup.array().of(strapiUtils.yup.strapiID()).min(1).required()
|
1482
1488
|
}).required();
|
1483
1489
|
const generateUIDInputSchema = strapiUtils.yup.object({
|
1484
1490
|
contentTypeUID: strapiUtils.yup.string().required(),
|
@@ -1577,15 +1583,47 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1577
1583
|
}
|
1578
1584
|
}, body);
|
1579
1585
|
};
|
1580
|
-
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;
|
1581
1593
|
const { locale, status, ...rest } = request || {};
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
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}`);
|
1587
1603
|
}
|
1588
|
-
|
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
|
+
};
|
1589
1627
|
};
|
1590
1628
|
const createDocument = async (ctx, opts) => {
|
1591
1629
|
const { userAbility, user } = ctx.state;
|
@@ -1600,7 +1638,7 @@ const createDocument = async (ctx, opts) => {
|
|
1600
1638
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1601
1639
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1602
1640
|
const sanitizedBody = await sanitizeFn(body);
|
1603
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(body);
|
1641
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(body);
|
1604
1642
|
return documentManager2.create(model, {
|
1605
1643
|
data: sanitizedBody,
|
1606
1644
|
locale,
|
@@ -1619,7 +1657,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1619
1657
|
}
|
1620
1658
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1621
1659
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1622
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1660
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1623
1661
|
const [documentVersion, documentExists] = await Promise.all([
|
1624
1662
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1625
1663
|
documentManager2.exists(model, id)
|
@@ -1657,7 +1695,7 @@ const collectionTypes = {
|
|
1657
1695
|
}
|
1658
1696
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1659
1697
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1660
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1698
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1661
1699
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1662
1700
|
{ ...permissionQuery, populate, locale, status },
|
1663
1701
|
model
|
@@ -1686,14 +1724,13 @@ const collectionTypes = {
|
|
1686
1724
|
const { userAbility } = ctx.state;
|
1687
1725
|
const { model, id } = ctx.params;
|
1688
1726
|
const documentManager2 = getService$1("document-manager");
|
1689
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1690
1727
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1691
1728
|
if (permissionChecker2.cannot.read()) {
|
1692
1729
|
return ctx.forbidden();
|
1693
1730
|
}
|
1694
1731
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1695
1732
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1696
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
1733
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
1697
1734
|
const version = await documentManager2.findOne(id, model, {
|
1698
1735
|
populate,
|
1699
1736
|
locale,
|
@@ -1704,8 +1741,10 @@ const collectionTypes = {
|
|
1704
1741
|
if (!exists) {
|
1705
1742
|
return ctx.notFound();
|
1706
1743
|
}
|
1707
|
-
const { meta } = await
|
1744
|
+
const { meta } = await formatDocumentWithMetadata(
|
1745
|
+
permissionChecker2,
|
1708
1746
|
model,
|
1747
|
+
// @ts-expect-error TODO: fix
|
1709
1748
|
{ id, locale, publishedAt: null },
|
1710
1749
|
{ availableLocales: true, availableStatus: false }
|
1711
1750
|
);
|
@@ -1716,12 +1755,11 @@ const collectionTypes = {
|
|
1716
1755
|
return ctx.forbidden();
|
1717
1756
|
}
|
1718
1757
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1719
|
-
ctx.body = await
|
1758
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1720
1759
|
},
|
1721
1760
|
async create(ctx) {
|
1722
1761
|
const { userAbility } = ctx.state;
|
1723
1762
|
const { model } = ctx.params;
|
1724
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1725
1763
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1726
1764
|
const [totalEntries, document] = await Promise.all([
|
1727
1765
|
strapi.db.query(model).count(),
|
@@ -1729,7 +1767,7 @@ const collectionTypes = {
|
|
1729
1767
|
]);
|
1730
1768
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1731
1769
|
ctx.status = 201;
|
1732
|
-
ctx.body = await
|
1770
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1733
1771
|
// Empty metadata as it's not relevant for a new document
|
1734
1772
|
availableLocales: false,
|
1735
1773
|
availableStatus: false
|
@@ -1743,25 +1781,23 @@ const collectionTypes = {
|
|
1743
1781
|
async update(ctx) {
|
1744
1782
|
const { userAbility } = ctx.state;
|
1745
1783
|
const { model } = ctx.params;
|
1746
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1747
1784
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1748
1785
|
const updatedVersion = await updateDocument(ctx);
|
1749
1786
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1750
|
-
ctx.body = await
|
1787
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1751
1788
|
},
|
1752
1789
|
async clone(ctx) {
|
1753
1790
|
const { userAbility, user } = ctx.state;
|
1754
1791
|
const { model, sourceId: id } = ctx.params;
|
1755
1792
|
const { body } = ctx.request;
|
1756
1793
|
const documentManager2 = getService$1("document-manager");
|
1757
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1758
1794
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1759
1795
|
if (permissionChecker2.cannot.create()) {
|
1760
1796
|
return ctx.forbidden();
|
1761
1797
|
}
|
1762
1798
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1763
1799
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1764
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1800
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1765
1801
|
const document = await documentManager2.findOne(id, model, {
|
1766
1802
|
populate,
|
1767
1803
|
locale,
|
@@ -1777,7 +1813,7 @@ const collectionTypes = {
|
|
1777
1813
|
const sanitizedBody = await sanitizeFn(body);
|
1778
1814
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1779
1815
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1780
|
-
ctx.body = await
|
1816
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1781
1817
|
// Empty metadata as it's not relevant for a new document
|
1782
1818
|
availableLocales: false,
|
1783
1819
|
availableStatus: false
|
@@ -1806,7 +1842,7 @@ const collectionTypes = {
|
|
1806
1842
|
}
|
1807
1843
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1808
1844
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1809
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
1845
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1810
1846
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1811
1847
|
if (documentLocales.length === 0) {
|
1812
1848
|
return ctx.notFound();
|
@@ -1828,7 +1864,6 @@ const collectionTypes = {
|
|
1828
1864
|
const { id, model } = ctx.params;
|
1829
1865
|
const { body } = ctx.request;
|
1830
1866
|
const documentManager2 = getService$1("document-manager");
|
1831
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1832
1867
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1833
1868
|
if (permissionChecker2.cannot.publish()) {
|
1834
1869
|
return ctx.forbidden();
|
@@ -1840,21 +1875,25 @@ const collectionTypes = {
|
|
1840
1875
|
if (permissionChecker2.cannot.publish(document)) {
|
1841
1876
|
throw new strapiUtils.errors.ForbiddenError();
|
1842
1877
|
}
|
1843
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1844
|
-
|
1878
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1879
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1845
1880
|
locale
|
1846
1881
|
// TODO: Allow setting creator fields on publish
|
1847
1882
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1848
1883
|
});
|
1884
|
+
if (!publishResult || publishResult.length === 0) {
|
1885
|
+
throw new strapiUtils.errors.NotFoundError("Document not found or already published.");
|
1886
|
+
}
|
1887
|
+
return publishResult[0];
|
1849
1888
|
});
|
1850
1889
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1851
|
-
ctx.body = await
|
1890
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1852
1891
|
},
|
1853
1892
|
async bulkPublish(ctx) {
|
1854
1893
|
const { userAbility } = ctx.state;
|
1855
1894
|
const { model } = ctx.params;
|
1856
1895
|
const { body } = ctx.request;
|
1857
|
-
const {
|
1896
|
+
const { documentIds } = body;
|
1858
1897
|
await validateBulkActionInput(body);
|
1859
1898
|
const documentManager2 = getService$1("document-manager");
|
1860
1899
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1863,8 +1902,11 @@ const collectionTypes = {
|
|
1863
1902
|
}
|
1864
1903
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1865
1904
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1866
|
-
const
|
1867
|
-
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();
|
1868
1910
|
for (const entity of entities) {
|
1869
1911
|
if (!entity) {
|
1870
1912
|
return ctx.notFound();
|
@@ -1873,24 +1915,25 @@ const collectionTypes = {
|
|
1873
1915
|
return ctx.forbidden();
|
1874
1916
|
}
|
1875
1917
|
}
|
1876
|
-
const
|
1918
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1877
1919
|
ctx.body = { count };
|
1878
1920
|
},
|
1879
1921
|
async bulkUnpublish(ctx) {
|
1880
1922
|
const { userAbility } = ctx.state;
|
1881
1923
|
const { model } = ctx.params;
|
1882
1924
|
const { body } = ctx.request;
|
1883
|
-
const {
|
1925
|
+
const { documentIds } = body;
|
1884
1926
|
await validateBulkActionInput(body);
|
1885
1927
|
const documentManager2 = getService$1("document-manager");
|
1886
1928
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1887
1929
|
if (permissionChecker2.cannot.unpublish()) {
|
1888
1930
|
return ctx.forbidden();
|
1889
1931
|
}
|
1890
|
-
const
|
1891
|
-
const
|
1892
|
-
|
1893
|
-
|
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();
|
1894
1937
|
for (const entity of entities) {
|
1895
1938
|
if (!entity) {
|
1896
1939
|
return ctx.notFound();
|
@@ -1899,7 +1942,8 @@ const collectionTypes = {
|
|
1899
1942
|
return ctx.forbidden();
|
1900
1943
|
}
|
1901
1944
|
}
|
1902
|
-
const
|
1945
|
+
const entitiesIds = entities.map((document) => document.documentId);
|
1946
|
+
const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
|
1903
1947
|
ctx.body = { count };
|
1904
1948
|
},
|
1905
1949
|
async unpublish(ctx) {
|
@@ -1909,7 +1953,6 @@ const collectionTypes = {
|
|
1909
1953
|
body: { discardDraft, ...body }
|
1910
1954
|
} = ctx.request;
|
1911
1955
|
const documentManager2 = getService$1("document-manager");
|
1912
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1913
1956
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1914
1957
|
if (permissionChecker2.cannot.unpublish()) {
|
1915
1958
|
return ctx.forbidden();
|
@@ -1919,7 +1962,7 @@ const collectionTypes = {
|
|
1919
1962
|
}
|
1920
1963
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1921
1964
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1922
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1965
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1923
1966
|
const document = await documentManager2.findOne(id, model, {
|
1924
1967
|
populate,
|
1925
1968
|
locale,
|
@@ -1941,7 +1984,7 @@ const collectionTypes = {
|
|
1941
1984
|
ctx.body = await strapiUtils.async.pipe(
|
1942
1985
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1943
1986
|
permissionChecker2.sanitizeOutput,
|
1944
|
-
(document2) =>
|
1987
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1945
1988
|
)(document);
|
1946
1989
|
});
|
1947
1990
|
},
|
@@ -1950,14 +1993,13 @@ const collectionTypes = {
|
|
1950
1993
|
const { id, model } = ctx.params;
|
1951
1994
|
const { body } = ctx.request;
|
1952
1995
|
const documentManager2 = getService$1("document-manager");
|
1953
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1954
1996
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1955
1997
|
if (permissionChecker2.cannot.discard()) {
|
1956
1998
|
return ctx.forbidden();
|
1957
1999
|
}
|
1958
2000
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1959
2001
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1960
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2002
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1961
2003
|
const document = await documentManager2.findOne(id, model, {
|
1962
2004
|
populate,
|
1963
2005
|
locale,
|
@@ -1972,14 +2014,14 @@ const collectionTypes = {
|
|
1972
2014
|
ctx.body = await strapiUtils.async.pipe(
|
1973
2015
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1974
2016
|
permissionChecker2.sanitizeOutput,
|
1975
|
-
(document2) =>
|
2017
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1976
2018
|
)(document);
|
1977
2019
|
},
|
1978
2020
|
async bulkDelete(ctx) {
|
1979
2021
|
const { userAbility } = ctx.state;
|
1980
2022
|
const { model } = ctx.params;
|
1981
2023
|
const { query, body } = ctx.request;
|
1982
|
-
const {
|
2024
|
+
const { documentIds } = body;
|
1983
2025
|
await validateBulkActionInput(body);
|
1984
2026
|
const documentManager2 = getService$1("document-manager");
|
1985
2027
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
@@ -1987,14 +2029,22 @@ const collectionTypes = {
|
|
1987
2029
|
return ctx.forbidden();
|
1988
2030
|
}
|
1989
2031
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1990
|
-
const
|
1991
|
-
const
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
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();
|
1995
2044
|
}
|
1996
|
-
}
|
1997
|
-
const
|
2045
|
+
}
|
2046
|
+
const localeDocumentsIds = documentLocales.map((document) => document.documentId);
|
2047
|
+
const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
|
1998
2048
|
ctx.body = { count };
|
1999
2049
|
},
|
2000
2050
|
async countDraftRelations(ctx) {
|
@@ -2007,7 +2057,7 @@ const collectionTypes = {
|
|
2007
2057
|
}
|
2008
2058
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2009
2059
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2010
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
2060
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
2011
2061
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2012
2062
|
if (!entity) {
|
2013
2063
|
return ctx.notFound();
|
@@ -2022,7 +2072,7 @@ const collectionTypes = {
|
|
2022
2072
|
},
|
2023
2073
|
async countManyEntriesDraftRelations(ctx) {
|
2024
2074
|
const { userAbility } = ctx.state;
|
2025
|
-
const ids = ctx.request.query.
|
2075
|
+
const ids = ctx.request.query.documentIds;
|
2026
2076
|
const locale = ctx.request.query.locale;
|
2027
2077
|
const { model } = ctx.params;
|
2028
2078
|
const documentManager2 = getService$1("document-manager");
|
@@ -2033,7 +2083,7 @@ const collectionTypes = {
|
|
2033
2083
|
const entities = await documentManager2.findMany(
|
2034
2084
|
{
|
2035
2085
|
filters: {
|
2036
|
-
|
2086
|
+
documentId: ids
|
2037
2087
|
},
|
2038
2088
|
locale
|
2039
2089
|
},
|
@@ -2535,7 +2585,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2535
2585
|
throw new strapiUtils.errors.ForbiddenError();
|
2536
2586
|
}
|
2537
2587
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2538
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2588
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2539
2589
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2540
2590
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2541
2591
|
// Find the first document to check if it exists
|
@@ -2572,12 +2622,11 @@ const singleTypes = {
|
|
2572
2622
|
const { model } = ctx.params;
|
2573
2623
|
const { query = {} } = ctx.request;
|
2574
2624
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2575
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2576
2625
|
if (permissionChecker2.cannot.read()) {
|
2577
2626
|
return ctx.forbidden();
|
2578
2627
|
}
|
2579
2628
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2580
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2629
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2581
2630
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2582
2631
|
if (!version) {
|
2583
2632
|
if (permissionChecker2.cannot.create()) {
|
@@ -2587,8 +2636,10 @@ const singleTypes = {
|
|
2587
2636
|
if (!document) {
|
2588
2637
|
return ctx.notFound();
|
2589
2638
|
}
|
2590
|
-
const { meta } = await
|
2639
|
+
const { meta } = await formatDocumentWithMetadata(
|
2640
|
+
permissionChecker2,
|
2591
2641
|
model,
|
2642
|
+
// @ts-expect-error - fix types
|
2592
2643
|
{ id: document.documentId, locale, publishedAt: null },
|
2593
2644
|
{ availableLocales: true, availableStatus: false }
|
2594
2645
|
);
|
@@ -2599,16 +2650,15 @@ const singleTypes = {
|
|
2599
2650
|
return ctx.forbidden();
|
2600
2651
|
}
|
2601
2652
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2602
|
-
ctx.body = await
|
2653
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2603
2654
|
},
|
2604
2655
|
async createOrUpdate(ctx) {
|
2605
2656
|
const { userAbility } = ctx.state;
|
2606
2657
|
const { model } = ctx.params;
|
2607
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2608
2658
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2609
2659
|
const document = await createOrUpdateDocument(ctx);
|
2610
2660
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2611
|
-
ctx.body = await
|
2661
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2612
2662
|
},
|
2613
2663
|
async delete(ctx) {
|
2614
2664
|
const { userAbility } = ctx.state;
|
@@ -2621,7 +2671,7 @@ const singleTypes = {
|
|
2621
2671
|
}
|
2622
2672
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2623
2673
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2624
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2674
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2625
2675
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2626
2676
|
populate,
|
2627
2677
|
locale
|
@@ -2644,7 +2694,6 @@ const singleTypes = {
|
|
2644
2694
|
const { model } = ctx.params;
|
2645
2695
|
const { query = {} } = ctx.request;
|
2646
2696
|
const documentManager2 = getService$1("document-manager");
|
2647
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2648
2697
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2649
2698
|
if (permissionChecker2.cannot.publish()) {
|
2650
2699
|
return ctx.forbidden();
|
@@ -2659,11 +2708,12 @@ const singleTypes = {
|
|
2659
2708
|
if (permissionChecker2.cannot.publish(document)) {
|
2660
2709
|
throw new strapiUtils.errors.ForbiddenError();
|
2661
2710
|
}
|
2662
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2663
|
-
|
2711
|
+
const { locale } = await getDocumentLocaleAndStatus(document);
|
2712
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2713
|
+
return publishResult.at(0);
|
2664
2714
|
});
|
2665
2715
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2666
|
-
ctx.body = await
|
2716
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2667
2717
|
},
|
2668
2718
|
async unpublish(ctx) {
|
2669
2719
|
const { userAbility } = ctx.state;
|
@@ -2673,7 +2723,6 @@ const singleTypes = {
|
|
2673
2723
|
query = {}
|
2674
2724
|
} = ctx.request;
|
2675
2725
|
const documentManager2 = getService$1("document-manager");
|
2676
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2677
2726
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2678
2727
|
if (permissionChecker2.cannot.unpublish()) {
|
2679
2728
|
return ctx.forbidden();
|
@@ -2682,7 +2731,7 @@ const singleTypes = {
|
|
2682
2731
|
return ctx.forbidden();
|
2683
2732
|
}
|
2684
2733
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2685
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2734
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2686
2735
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2687
2736
|
if (!document) {
|
2688
2737
|
return ctx.notFound();
|
@@ -2700,7 +2749,7 @@ const singleTypes = {
|
|
2700
2749
|
ctx.body = await strapiUtils.async.pipe(
|
2701
2750
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2702
2751
|
permissionChecker2.sanitizeOutput,
|
2703
|
-
(document2) =>
|
2752
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2704
2753
|
)(document);
|
2705
2754
|
});
|
2706
2755
|
},
|
@@ -2709,13 +2758,12 @@ const singleTypes = {
|
|
2709
2758
|
const { model } = ctx.params;
|
2710
2759
|
const { body, query = {} } = ctx.request;
|
2711
2760
|
const documentManager2 = getService$1("document-manager");
|
2712
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2713
2761
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2714
2762
|
if (permissionChecker2.cannot.discard()) {
|
2715
2763
|
return ctx.forbidden();
|
2716
2764
|
}
|
2717
2765
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2718
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2766
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2719
2767
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2720
2768
|
if (!document) {
|
2721
2769
|
return ctx.notFound();
|
@@ -2726,7 +2774,7 @@ const singleTypes = {
|
|
2726
2774
|
ctx.body = await strapiUtils.async.pipe(
|
2727
2775
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2728
2776
|
permissionChecker2.sanitizeOutput,
|
2729
|
-
(document2) =>
|
2777
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2730
2778
|
)(document);
|
2731
2779
|
},
|
2732
2780
|
async countDraftRelations(ctx) {
|
@@ -2735,7 +2783,7 @@ const singleTypes = {
|
|
2735
2783
|
const { query } = ctx.request;
|
2736
2784
|
const documentManager2 = getService$1("document-manager");
|
2737
2785
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2738
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2786
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2739
2787
|
if (permissionChecker2.cannot.read()) {
|
2740
2788
|
return ctx.forbidden();
|
2741
2789
|
}
|
@@ -2756,7 +2804,7 @@ const uid$1 = {
|
|
2756
2804
|
async generateUID(ctx) {
|
2757
2805
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2758
2806
|
const { query = {} } = ctx.request;
|
2759
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2807
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2760
2808
|
await validateUIDField(contentTypeUID, field);
|
2761
2809
|
const uidService = getService$1("uid");
|
2762
2810
|
ctx.body = {
|
@@ -2768,7 +2816,7 @@ const uid$1 = {
|
|
2768
2816
|
ctx.request.body
|
2769
2817
|
);
|
2770
2818
|
const { query = {} } = ctx.request;
|
2771
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2819
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2772
2820
|
await validateUIDField(contentTypeUID, field);
|
2773
2821
|
const uidService = getService$1("uid");
|
2774
2822
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3559,7 +3607,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3559
3607
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3560
3608
|
}
|
3561
3609
|
});
|
3562
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils__default.default.contentTypes;
|
3610
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils__default.default.contentTypes;
|
3563
3611
|
const { isAnyToMany } = strapiUtils__default.default.relations;
|
3564
3612
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils__default.default.contentTypes.constants;
|
3565
3613
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3650,6 +3698,42 @@ const getDeepPopulate = (uid2, {
|
|
3650
3698
|
{}
|
3651
3699
|
);
|
3652
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
|
+
};
|
3653
3737
|
const getDeepPopulateDraftCount = (uid2) => {
|
3654
3738
|
const model = strapi.getModel(uid2);
|
3655
3739
|
let hasRelations = false;
|
@@ -3878,41 +3962,70 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3878
3962
|
"updatedBy",
|
3879
3963
|
"status"
|
3880
3964
|
];
|
3881
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
3965
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
3966
|
+
"id",
|
3967
|
+
"locale",
|
3968
|
+
"updatedAt",
|
3969
|
+
"createdAt",
|
3970
|
+
"status",
|
3971
|
+
"publishedAt",
|
3972
|
+
"documentId"
|
3973
|
+
];
|
3882
3974
|
const CONTENT_MANAGER_STATUS = {
|
3883
3975
|
PUBLISHED: "published",
|
3884
3976
|
DRAFT: "draft",
|
3885
3977
|
MODIFIED: "modified"
|
3886
3978
|
};
|
3887
|
-
const
|
3888
|
-
if (!
|
3979
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
3980
|
+
if (!version || !version.updatedAt) {
|
3889
3981
|
return false;
|
3890
3982
|
}
|
3891
|
-
const
|
3892
|
-
const
|
3893
|
-
|
3894
|
-
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;
|
3895
3986
|
};
|
3896
3987
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3897
3988
|
/**
|
3898
3989
|
* Returns available locales of a document for the current status
|
3899
3990
|
*/
|
3900
|
-
getAvailableLocales(uid2, version, allVersions) {
|
3991
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3901
3992
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
3902
3993
|
delete versionsByLocale[version.locale];
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
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
|
+
};
|
3906
4026
|
}
|
3907
|
-
|
3908
|
-
|
3909
|
-
if (!draftVersion)
|
3910
|
-
return;
|
3911
|
-
return {
|
3912
|
-
...fp.pick(AVAILABLE_LOCALES_FIELDS, draftVersion),
|
3913
|
-
status: this.getStatus(draftVersion, otherVersions)
|
3914
|
-
};
|
3915
|
-
}).filter(Boolean);
|
4027
|
+
);
|
4028
|
+
return mappingResult.filter(Boolean);
|
3916
4029
|
},
|
3917
4030
|
/**
|
3918
4031
|
* Returns available status of a document for the current locale
|
@@ -3950,26 +4063,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3950
4063
|
});
|
3951
4064
|
},
|
3952
4065
|
getStatus(version, otherDocumentStatuses) {
|
3953
|
-
|
3954
|
-
|
3955
|
-
|
4066
|
+
let draftVersion;
|
4067
|
+
let publishedVersion;
|
4068
|
+
if (version.publishedAt) {
|
4069
|
+
publishedVersion = version;
|
4070
|
+
} else {
|
4071
|
+
draftVersion = version;
|
3956
4072
|
}
|
3957
|
-
|
3958
|
-
|
3959
|
-
|
3960
|
-
|
3961
|
-
|
4073
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4074
|
+
if (otherVersion?.publishedAt) {
|
4075
|
+
publishedVersion = otherVersion;
|
4076
|
+
} else if (otherVersion) {
|
4077
|
+
draftVersion = otherVersion;
|
3962
4078
|
}
|
3963
|
-
if (
|
4079
|
+
if (!draftVersion)
|
3964
4080
|
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
3965
|
-
|
3966
|
-
|
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;
|
3967
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.
|
3968
4089
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4090
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3969
4091
|
const versions = await strapi2.db.query(uid2).findMany({
|
3970
4092
|
where: { documentId: version.documentId },
|
3971
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3972
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
|
3973
4097
|
createdBy: {
|
3974
4098
|
select: ["id", "firstname", "lastname", "email"]
|
3975
4099
|
},
|
@@ -3978,7 +4102,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3978
4102
|
}
|
3979
4103
|
}
|
3980
4104
|
});
|
3981
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4105
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3982
4106
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3983
4107
|
return {
|
3984
4108
|
availableLocales: availableLocalesResult,
|
@@ -3991,8 +4115,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3991
4115
|
* - Available status of the document for the current locale
|
3992
4116
|
*/
|
3993
4117
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3994
|
-
if (!document)
|
4118
|
+
if (!document) {
|
3995
4119
|
return document;
|
4120
|
+
}
|
3996
4121
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
3997
4122
|
if (!hasDraftAndPublish) {
|
3998
4123
|
opts.availableStatus = false;
|
@@ -4042,26 +4167,9 @@ const sumDraftCounts = (entity, uid2) => {
|
|
4042
4167
|
}, 0);
|
4043
4168
|
};
|
4044
4169
|
const { ApplicationError } = strapiUtils.errors;
|
4045
|
-
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
|
4046
4170
|
const { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
|
4047
4171
|
const omitPublishedAtField = fp.omit(PUBLISHED_AT_ATTRIBUTE);
|
4048
4172
|
const omitIdField = fp.omit("id");
|
4049
|
-
const emitEvent = async (uid2, event, document) => {
|
4050
|
-
const modelDef = strapi.getModel(uid2);
|
4051
|
-
const sanitizedDocument = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput(
|
4052
|
-
{
|
4053
|
-
schema: modelDef,
|
4054
|
-
getModel(uid22) {
|
4055
|
-
return strapi.getModel(uid22);
|
4056
|
-
}
|
4057
|
-
},
|
4058
|
-
document
|
4059
|
-
);
|
4060
|
-
strapi.eventHub.emit(event, {
|
4061
|
-
model: modelDef.modelName,
|
4062
|
-
entry: sanitizedDocument
|
4063
|
-
});
|
4064
|
-
};
|
4065
4173
|
const documentManager = ({ strapi: strapi2 }) => {
|
4066
4174
|
return {
|
4067
4175
|
async findOne(id, uid2, opts = {}) {
|
@@ -4080,6 +4188,9 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4080
4188
|
} else if (opts.locale && opts.locale !== "*") {
|
4081
4189
|
where.locale = opts.locale;
|
4082
4190
|
}
|
4191
|
+
if (typeof opts.isPublished === "boolean") {
|
4192
|
+
where.publishedAt = { $notNull: opts.isPublished };
|
4193
|
+
}
|
4083
4194
|
return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
|
4084
4195
|
},
|
4085
4196
|
async findMany(opts, uid2) {
|
@@ -4087,20 +4198,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4087
4198
|
return strapi2.documents(uid2).findMany(params);
|
4088
4199
|
},
|
4089
4200
|
async findPage(opts, uid2) {
|
4090
|
-
const
|
4091
|
-
|
4201
|
+
const params = strapiUtils.pagination.withDefaultPagination(opts || {}, {
|
4202
|
+
maxLimit: 1e3
|
4203
|
+
});
|
4092
4204
|
const [documents, total = 0] = await Promise.all([
|
4093
|
-
strapi2.documents(uid2).findMany(
|
4094
|
-
strapi2.documents(uid2).count(
|
4205
|
+
strapi2.documents(uid2).findMany(params),
|
4206
|
+
strapi2.documents(uid2).count(params)
|
4095
4207
|
]);
|
4096
4208
|
return {
|
4097
4209
|
results: documents,
|
4098
|
-
pagination:
|
4099
|
-
page,
|
4100
|
-
pageSize,
|
4101
|
-
pageCount: Math.ceil(total / pageSize),
|
4102
|
-
total
|
4103
|
-
}
|
4210
|
+
pagination: strapiUtils.pagination.transformPagedPaginationInfo(params, total)
|
4104
4211
|
};
|
4105
4212
|
},
|
4106
4213
|
async create(uid2, opts = {}) {
|
@@ -4146,70 +4253,36 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4146
4253
|
return {};
|
4147
4254
|
},
|
4148
4255
|
// FIXME: handle relations
|
4149
|
-
async deleteMany(
|
4150
|
-
const
|
4151
|
-
|
4152
|
-
|
4153
|
-
}
|
4154
|
-
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 };
|
4155
4261
|
},
|
4156
4262
|
async publish(id, uid2, opts = {}) {
|
4157
4263
|
const populate = await buildDeepPopulate(uid2);
|
4158
4264
|
const params = { ...opts, populate };
|
4159
|
-
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);
|
4160
4266
|
},
|
4161
|
-
async publishMany(
|
4162
|
-
|
4163
|
-
|
4164
|
-
|
4165
|
-
|
4166
|
-
|
4167
|
-
|
4168
|
-
strapi2.getModel(uid2),
|
4169
|
-
document,
|
4170
|
-
void 0,
|
4171
|
-
// @ts-expect-error - FIXME: entity here is unnecessary
|
4172
|
-
document
|
4173
|
-
);
|
4174
|
-
})
|
4175
|
-
);
|
4176
|
-
const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
|
4177
|
-
const filters = { id: { $in: entitiesToPublish } };
|
4178
|
-
const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
|
4179
|
-
const populate = await buildDeepPopulate(uid2);
|
4180
|
-
const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4181
|
-
where: filters,
|
4182
|
-
data
|
4183
|
-
});
|
4184
|
-
const publishedEntities = await strapi2.db.query(uid2).findMany({
|
4185
|
-
where: filters,
|
4186
|
-
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;
|
4187
4274
|
});
|
4188
|
-
await Promise.all(
|
4189
|
-
publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
|
4190
|
-
);
|
4191
|
-
return publishedEntitiesCount;
|
4192
4275
|
},
|
4193
|
-
async unpublishMany(
|
4194
|
-
|
4195
|
-
return
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
const populate = await buildDeepPopulate(uid2);
|
4201
|
-
const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4202
|
-
where: filters,
|
4203
|
-
data
|
4204
|
-
});
|
4205
|
-
const unpublishedEntities = await strapi2.db.query(uid2).findMany({
|
4206
|
-
where: filters,
|
4207
|
-
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
|
+
);
|
4208
4283
|
});
|
4209
|
-
|
4210
|
-
|
4211
|
-
);
|
4212
|
-
return unpublishedEntitiesCount;
|
4284
|
+
const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
|
4285
|
+
return { count: unpublishedEntitiesCount };
|
4213
4286
|
},
|
4214
4287
|
async unpublish(id, uid2, opts = {}) {
|
4215
4288
|
const populate = await buildDeepPopulate(uid2);
|
@@ -4234,16 +4307,20 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4234
4307
|
}
|
4235
4308
|
return sumDraftCounts(document, uid2);
|
4236
4309
|
},
|
4237
|
-
async countManyEntriesDraftRelations(
|
4310
|
+
async countManyEntriesDraftRelations(documentIds, uid2, locale) {
|
4238
4311
|
const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
|
4239
4312
|
if (!hasRelations) {
|
4240
4313
|
return 0;
|
4241
4314
|
}
|
4315
|
+
let localeFilter = {};
|
4316
|
+
if (locale) {
|
4317
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4318
|
+
}
|
4242
4319
|
const entities = await strapi2.db.query(uid2).findMany({
|
4243
4320
|
populate,
|
4244
4321
|
where: {
|
4245
|
-
|
4246
|
-
...
|
4322
|
+
documentId: { $in: documentIds },
|
4323
|
+
...localeFilter
|
4247
4324
|
}
|
4248
4325
|
});
|
4249
4326
|
const totalNumberDraftRelations = entities.reduce(
|