@strapi/content-manager 5.0.0-beta.7 → 5.0.0-beta.9
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/{ComponentConfigurationPage-uTMkLI60.mjs → ComponentConfigurationPage-BMajAl1u.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-uTMkLI60.mjs.map → ComponentConfigurationPage-BMajAl1u.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DMq0wvcL.js → ComponentConfigurationPage-y_7iLdmB.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DMq0wvcL.js.map → ComponentConfigurationPage-y_7iLdmB.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-BFpQwwbc.js → EditConfigurationPage-CPVB8Uqc.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BFpQwwbc.js.map → EditConfigurationPage-CPVB8Uqc.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-B2HhCh-b.mjs → EditConfigurationPage-CcOoD26O.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-B2HhCh-b.mjs.map → EditConfigurationPage-CcOoD26O.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CXXue16T.js → EditViewPage-CTTDHKkQ.js} +5 -5
- package/dist/_chunks/{EditViewPage-CXXue16T.js.map → EditViewPage-CTTDHKkQ.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BVIrgjyG.mjs → EditViewPage-DWb0DE7R.mjs} +5 -5
- package/dist/_chunks/{EditViewPage-BVIrgjyG.mjs.map → EditViewPage-DWb0DE7R.mjs.map} +1 -1
- package/dist/_chunks/{Field-ZgzKlgxR.js → Field-C5Z1Ivdv.js} +240 -357
- package/dist/_chunks/Field-C5Z1Ivdv.js.map +1 -0
- package/dist/_chunks/{Field-0_2h1vuK.mjs → Field-DnStdvQw.mjs} +240 -357
- package/dist/_chunks/Field-DnStdvQw.mjs.map +1 -0
- package/dist/_chunks/{Form-DgTc2qkx.js → Form-B81OtW-k.js} +9 -6
- package/dist/_chunks/Form-B81OtW-k.js.map +1 -0
- package/dist/_chunks/{Form-B7TUnQDd.mjs → Form-DqGgE55Q.mjs} +9 -6
- package/dist/_chunks/Form-DqGgE55Q.mjs.map +1 -0
- package/dist/_chunks/{History-DtHjQuqM.js → History-4NbOq2dX.js} +97 -15
- package/dist/_chunks/History-4NbOq2dX.js.map +1 -0
- package/dist/_chunks/{History-Dug_4HIA.mjs → History-DS6-HCYX.mjs} +97 -15
- package/dist/_chunks/History-DS6-HCYX.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-BuSdTjfa.js → ListConfigurationPage-CpfstlYY.js} +2 -2
- package/dist/_chunks/{ListConfigurationPage-BuSdTjfa.js.map → ListConfigurationPage-CpfstlYY.js.map} +1 -1
- package/dist/_chunks/{ListConfigurationPage-CmEeNg6T.mjs → ListConfigurationPage-DQJJltko.mjs} +2 -2
- package/dist/_chunks/{ListConfigurationPage-CmEeNg6T.mjs.map → ListConfigurationPage-DQJJltko.mjs.map} +1 -1
- package/dist/_chunks/{ListViewPage-CExWwa4S.js → ListViewPage-CA3I75m5.js} +23 -18
- package/dist/_chunks/ListViewPage-CA3I75m5.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Dsoa3wEA.mjs → ListViewPage-nQrOQuVo.mjs} +21 -17
- package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Dh38hBXB.mjs → NoContentTypePage-DbnHE22g.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Dh38hBXB.mjs.map → NoContentTypePage-DbnHE22g.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DCUL8gVi.js → NoContentTypePage-Dldu-_Mx.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DCUL8gVi.js.map → NoContentTypePage-Dldu-_Mx.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BK-XCpIy.js → NoPermissionsPage-CO2MK200.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BK-XCpIy.js.map → NoPermissionsPage-CO2MK200.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dt2O40ey.mjs → NoPermissionsPage-fOIkQM0v.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dt2O40ey.mjs.map → NoPermissionsPage-fOIkQM0v.mjs.map} +1 -1
- package/dist/_chunks/{Relations-DZyjWZHl.mjs → Relations-BDRl99Ux.mjs} +8 -6
- package/dist/_chunks/{Relations-DZyjWZHl.mjs.map → Relations-BDRl99Ux.mjs.map} +1 -1
- package/dist/_chunks/{Relations-CNypkp-g.js → Relations-DG2jnOcr.js} +8 -6
- package/dist/_chunks/{Relations-CNypkp-g.js.map → Relations-DG2jnOcr.js.map} +1 -1
- package/dist/_chunks/{en-MBPul9Su.mjs → en-Ux26r5pl.mjs} +7 -1
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-Ux26r5pl.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-fbKQxLGn.js} +7 -1
- package/dist/_chunks/{en-C-V1_90f.js.map → en-fbKQxLGn.js.map} +1 -1
- package/dist/_chunks/{index-DFK7LwDW.js → index-BZoNZMXL.js} +1528 -779
- package/dist/_chunks/index-BZoNZMXL.js.map +1 -0
- package/dist/_chunks/{index-B3c-4it4.mjs → index-Drt2DN7v.mjs} +1552 -803
- package/dist/_chunks/index-Drt2DN7v.mjs.map +1 -0
- package/dist/_chunks/{layout-B5cm7cZj.mjs → layout-BzAbmoO6.mjs} +20 -15
- package/dist/_chunks/layout-BzAbmoO6.mjs.map +1 -0
- package/dist/_chunks/{layout-DLih5-_W.js → layout-DEYBqgF1.js} +20 -15
- package/dist/_chunks/layout-DEYBqgF1.js.map +1 -0
- package/dist/_chunks/{relations-CTvkuINQ.js → relations-D0eZ4VWw.js} +2 -2
- package/dist/_chunks/{relations-CTvkuINQ.js.map → relations-D0eZ4VWw.js.map} +1 -1
- package/dist/_chunks/{relations-BZkrMa2z.mjs → relations-D26zVRdi.mjs} +2 -2
- package/dist/_chunks/{relations-BZkrMa2z.mjs.map → relations-D26zVRdi.mjs.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 +8 -7
- 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/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 +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 +2 -15
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- 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 +56 -35
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- 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 -17
- package/dist/admin/src/utils/validation.d.ts +1 -6
- package/dist/server/index.js +247 -127
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +249 -129
- 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/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 +12 -33
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +6 -6
- 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 +12 -33
- 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 +11 -5
- 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 +11 -11
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/Field-0_2h1vuK.mjs.map +0 -1
- package/dist/_chunks/Field-ZgzKlgxR.js.map +0 -1
- package/dist/_chunks/Form-B7TUnQDd.mjs.map +0 -1
- package/dist/_chunks/Form-DgTc2qkx.js.map +0 -1
- package/dist/_chunks/History-DtHjQuqM.js.map +0 -1
- package/dist/_chunks/History-Dug_4HIA.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-CExWwa4S.js.map +0 -1
- package/dist/_chunks/ListViewPage-Dsoa3wEA.mjs.map +0 -1
- package/dist/_chunks/index-B3c-4it4.mjs.map +0 -1
- package/dist/_chunks/index-DFK7LwDW.js.map +0 -1
- package/dist/_chunks/layout-B5cm7cZj.mjs.map +0 -1
- package/dist/_chunks/layout-DLih5-_W.js.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/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, pagination } from "@strapi/utils";
|
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";
|
@@ -481,7 +481,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
481
481
|
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
482
|
return next();
|
483
483
|
}
|
484
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
484
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
485
485
|
return next();
|
486
486
|
}
|
487
487
|
const contentTypeUid = context.contentType.uid;
|
@@ -489,9 +489,18 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
489
489
|
return next();
|
490
490
|
}
|
491
491
|
const result = await next();
|
492
|
-
const documentContext =
|
492
|
+
const documentContext = {
|
493
|
+
documentId: context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId,
|
494
|
+
locale: context.params?.locale
|
495
|
+
};
|
493
496
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
494
497
|
const locale = documentContext.locale || defaultLocale;
|
498
|
+
if (Array.isArray(locale)) {
|
499
|
+
strapi2.log.warn(
|
500
|
+
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
501
|
+
);
|
502
|
+
return next();
|
503
|
+
}
|
495
504
|
const document = await strapi2.documents(contentTypeUid).findOne({
|
496
505
|
documentId: documentContext.documentId,
|
497
506
|
locale,
|
@@ -527,9 +536,8 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
527
536
|
});
|
528
537
|
return result;
|
529
538
|
});
|
530
|
-
const retentionDays = serviceUtils.getRetentionDays();
|
531
539
|
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
532
|
-
const retentionDaysInMilliseconds =
|
540
|
+
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
533
541
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
534
542
|
query.deleteMany({
|
535
543
|
where: {
|
@@ -1551,15 +1559,47 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1551
1559
|
}
|
1552
1560
|
}, body);
|
1553
1561
|
};
|
1554
|
-
const
|
1562
|
+
const singleLocaleSchema = yup$1.string().nullable();
|
1563
|
+
const multipleLocaleSchema = yup$1.lazy(
|
1564
|
+
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1565
|
+
);
|
1566
|
+
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1567
|
+
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1568
|
+
const { allowMultipleLocales } = opts;
|
1555
1569
|
const { locale, status, ...rest } = request || {};
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1570
|
+
const schema = yup$1.object().shape({
|
1571
|
+
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1572
|
+
status: statusSchema
|
1573
|
+
});
|
1574
|
+
try {
|
1575
|
+
await validateYupSchema(schema, { strict: true, abortEarly: false })(request);
|
1576
|
+
return { locale, status, ...rest };
|
1577
|
+
} catch (error) {
|
1578
|
+
throw new errors.ValidationError(`Validation error: ${error.message}`);
|
1561
1579
|
}
|
1562
|
-
|
1580
|
+
};
|
1581
|
+
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1582
|
+
const documentMetadata2 = getService$1("document-metadata");
|
1583
|
+
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1584
|
+
let {
|
1585
|
+
meta: { availableLocales, availableStatus }
|
1586
|
+
} = serviceOutput;
|
1587
|
+
const metadataSanitizer = permissionChecker2.sanitizeOutput;
|
1588
|
+
availableLocales = await async.map(
|
1589
|
+
availableLocales,
|
1590
|
+
async (localeDocument) => metadataSanitizer(localeDocument)
|
1591
|
+
);
|
1592
|
+
availableStatus = await async.map(
|
1593
|
+
availableStatus,
|
1594
|
+
async (statusDocument) => metadataSanitizer(statusDocument)
|
1595
|
+
);
|
1596
|
+
return {
|
1597
|
+
...serviceOutput,
|
1598
|
+
meta: {
|
1599
|
+
availableLocales,
|
1600
|
+
availableStatus
|
1601
|
+
}
|
1602
|
+
};
|
1563
1603
|
};
|
1564
1604
|
const createDocument = async (ctx, opts) => {
|
1565
1605
|
const { userAbility, user } = ctx.state;
|
@@ -1574,7 +1614,7 @@ const createDocument = async (ctx, opts) => {
|
|
1574
1614
|
const setCreator = setCreatorFields({ user });
|
1575
1615
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1576
1616
|
const sanitizedBody = await sanitizeFn(body);
|
1577
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(body);
|
1617
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(body);
|
1578
1618
|
return documentManager2.create(model, {
|
1579
1619
|
data: sanitizedBody,
|
1580
1620
|
locale,
|
@@ -1593,7 +1633,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1593
1633
|
}
|
1594
1634
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1595
1635
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1596
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1636
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1597
1637
|
const [documentVersion, documentExists] = await Promise.all([
|
1598
1638
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1599
1639
|
documentManager2.exists(model, id)
|
@@ -1631,7 +1671,7 @@ const collectionTypes = {
|
|
1631
1671
|
}
|
1632
1672
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1633
1673
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1634
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1674
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1635
1675
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1636
1676
|
{ ...permissionQuery, populate, locale, status },
|
1637
1677
|
model
|
@@ -1660,14 +1700,13 @@ const collectionTypes = {
|
|
1660
1700
|
const { userAbility } = ctx.state;
|
1661
1701
|
const { model, id } = ctx.params;
|
1662
1702
|
const documentManager2 = getService$1("document-manager");
|
1663
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1664
1703
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1665
1704
|
if (permissionChecker2.cannot.read()) {
|
1666
1705
|
return ctx.forbidden();
|
1667
1706
|
}
|
1668
1707
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1669
1708
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1670
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
1709
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
1671
1710
|
const version = await documentManager2.findOne(id, model, {
|
1672
1711
|
populate,
|
1673
1712
|
locale,
|
@@ -1678,8 +1717,10 @@ const collectionTypes = {
|
|
1678
1717
|
if (!exists) {
|
1679
1718
|
return ctx.notFound();
|
1680
1719
|
}
|
1681
|
-
const { meta } = await
|
1720
|
+
const { meta } = await formatDocumentWithMetadata(
|
1721
|
+
permissionChecker2,
|
1682
1722
|
model,
|
1723
|
+
// @ts-expect-error TODO: fix
|
1683
1724
|
{ id, locale, publishedAt: null },
|
1684
1725
|
{ availableLocales: true, availableStatus: false }
|
1685
1726
|
);
|
@@ -1690,12 +1731,11 @@ const collectionTypes = {
|
|
1690
1731
|
return ctx.forbidden();
|
1691
1732
|
}
|
1692
1733
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1693
|
-
ctx.body = await
|
1734
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1694
1735
|
},
|
1695
1736
|
async create(ctx) {
|
1696
1737
|
const { userAbility } = ctx.state;
|
1697
1738
|
const { model } = ctx.params;
|
1698
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1699
1739
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1700
1740
|
const [totalEntries, document] = await Promise.all([
|
1701
1741
|
strapi.db.query(model).count(),
|
@@ -1703,7 +1743,7 @@ const collectionTypes = {
|
|
1703
1743
|
]);
|
1704
1744
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1705
1745
|
ctx.status = 201;
|
1706
|
-
ctx.body = await
|
1746
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1707
1747
|
// Empty metadata as it's not relevant for a new document
|
1708
1748
|
availableLocales: false,
|
1709
1749
|
availableStatus: false
|
@@ -1717,25 +1757,23 @@ const collectionTypes = {
|
|
1717
1757
|
async update(ctx) {
|
1718
1758
|
const { userAbility } = ctx.state;
|
1719
1759
|
const { model } = ctx.params;
|
1720
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1721
1760
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1722
1761
|
const updatedVersion = await updateDocument(ctx);
|
1723
1762
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1724
|
-
ctx.body = await
|
1763
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1725
1764
|
},
|
1726
1765
|
async clone(ctx) {
|
1727
1766
|
const { userAbility, user } = ctx.state;
|
1728
1767
|
const { model, sourceId: id } = ctx.params;
|
1729
1768
|
const { body } = ctx.request;
|
1730
1769
|
const documentManager2 = getService$1("document-manager");
|
1731
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1732
1770
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1733
1771
|
if (permissionChecker2.cannot.create()) {
|
1734
1772
|
return ctx.forbidden();
|
1735
1773
|
}
|
1736
1774
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1737
1775
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1738
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1776
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1739
1777
|
const document = await documentManager2.findOne(id, model, {
|
1740
1778
|
populate,
|
1741
1779
|
locale,
|
@@ -1751,7 +1789,7 @@ const collectionTypes = {
|
|
1751
1789
|
const sanitizedBody = await sanitizeFn(body);
|
1752
1790
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1753
1791
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1754
|
-
ctx.body = await
|
1792
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1755
1793
|
// Empty metadata as it's not relevant for a new document
|
1756
1794
|
availableLocales: false,
|
1757
1795
|
availableStatus: false
|
@@ -1780,7 +1818,7 @@ const collectionTypes = {
|
|
1780
1818
|
}
|
1781
1819
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1782
1820
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1783
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
1821
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1784
1822
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1785
1823
|
if (documentLocales.length === 0) {
|
1786
1824
|
return ctx.notFound();
|
@@ -1802,7 +1840,6 @@ const collectionTypes = {
|
|
1802
1840
|
const { id, model } = ctx.params;
|
1803
1841
|
const { body } = ctx.request;
|
1804
1842
|
const documentManager2 = getService$1("document-manager");
|
1805
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1806
1843
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1807
1844
|
if (permissionChecker2.cannot.publish()) {
|
1808
1845
|
return ctx.forbidden();
|
@@ -1814,15 +1851,19 @@ const collectionTypes = {
|
|
1814
1851
|
if (permissionChecker2.cannot.publish(document)) {
|
1815
1852
|
throw new errors.ForbiddenError();
|
1816
1853
|
}
|
1817
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1818
|
-
|
1854
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1855
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1819
1856
|
locale
|
1820
1857
|
// TODO: Allow setting creator fields on publish
|
1821
1858
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1822
1859
|
});
|
1860
|
+
if (!publishResult || publishResult.length === 0) {
|
1861
|
+
throw new errors.NotFoundError("Document not found or already published.");
|
1862
|
+
}
|
1863
|
+
return publishResult[0];
|
1823
1864
|
});
|
1824
1865
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1825
|
-
ctx.body = await
|
1866
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1826
1867
|
},
|
1827
1868
|
async bulkPublish(ctx) {
|
1828
1869
|
const { userAbility } = ctx.state;
|
@@ -1835,9 +1876,11 @@ const collectionTypes = {
|
|
1835
1876
|
if (permissionChecker2.cannot.publish()) {
|
1836
1877
|
return ctx.forbidden();
|
1837
1878
|
}
|
1838
|
-
const
|
1879
|
+
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1880
|
+
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1881
|
+
const { locale } = await getDocumentLocaleAndStatus(body, { allowMultipleLocales: true });
|
1839
1882
|
const entityPromises = documentIds.map(
|
1840
|
-
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: false })
|
1883
|
+
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1841
1884
|
);
|
1842
1885
|
const entities = (await Promise.all(entityPromises)).flat();
|
1843
1886
|
for (const entity of entities) {
|
@@ -1848,8 +1891,7 @@ const collectionTypes = {
|
|
1848
1891
|
return ctx.forbidden();
|
1849
1892
|
}
|
1850
1893
|
}
|
1851
|
-
const
|
1852
|
-
const { count } = await documentManager2.publishMany(entitiesIds, model, { locale });
|
1894
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1853
1895
|
ctx.body = { count };
|
1854
1896
|
},
|
1855
1897
|
async bulkUnpublish(ctx) {
|
@@ -1863,7 +1905,7 @@ const collectionTypes = {
|
|
1863
1905
|
if (permissionChecker2.cannot.unpublish()) {
|
1864
1906
|
return ctx.forbidden();
|
1865
1907
|
}
|
1866
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1908
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1867
1909
|
const entityPromises = documentIds.map(
|
1868
1910
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1869
1911
|
);
|
@@ -1887,7 +1929,6 @@ const collectionTypes = {
|
|
1887
1929
|
body: { discardDraft, ...body }
|
1888
1930
|
} = ctx.request;
|
1889
1931
|
const documentManager2 = getService$1("document-manager");
|
1890
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1891
1932
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1892
1933
|
if (permissionChecker2.cannot.unpublish()) {
|
1893
1934
|
return ctx.forbidden();
|
@@ -1897,7 +1938,7 @@ const collectionTypes = {
|
|
1897
1938
|
}
|
1898
1939
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1899
1940
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1900
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1941
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1901
1942
|
const document = await documentManager2.findOne(id, model, {
|
1902
1943
|
populate,
|
1903
1944
|
locale,
|
@@ -1919,7 +1960,7 @@ const collectionTypes = {
|
|
1919
1960
|
ctx.body = await async.pipe(
|
1920
1961
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1921
1962
|
permissionChecker2.sanitizeOutput,
|
1922
|
-
(document2) =>
|
1963
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1923
1964
|
)(document);
|
1924
1965
|
});
|
1925
1966
|
},
|
@@ -1928,14 +1969,13 @@ const collectionTypes = {
|
|
1928
1969
|
const { id, model } = ctx.params;
|
1929
1970
|
const { body } = ctx.request;
|
1930
1971
|
const documentManager2 = getService$1("document-manager");
|
1931
|
-
const documentMetadata2 = getService$1("document-metadata");
|
1932
1972
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1933
1973
|
if (permissionChecker2.cannot.discard()) {
|
1934
1974
|
return ctx.forbidden();
|
1935
1975
|
}
|
1936
1976
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1937
1977
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1938
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1978
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1939
1979
|
const document = await documentManager2.findOne(id, model, {
|
1940
1980
|
populate,
|
1941
1981
|
locale,
|
@@ -1950,7 +1990,7 @@ const collectionTypes = {
|
|
1950
1990
|
ctx.body = await async.pipe(
|
1951
1991
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1952
1992
|
permissionChecker2.sanitizeOutput,
|
1953
|
-
(document2) =>
|
1993
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1954
1994
|
)(document);
|
1955
1995
|
},
|
1956
1996
|
async bulkDelete(ctx) {
|
@@ -1966,7 +2006,7 @@ const collectionTypes = {
|
|
1966
2006
|
}
|
1967
2007
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1968
2008
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1969
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2009
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
1970
2010
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
1971
2011
|
populate,
|
1972
2012
|
locale
|
@@ -1993,7 +2033,7 @@ const collectionTypes = {
|
|
1993
2033
|
}
|
1994
2034
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1995
2035
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1996
|
-
const { locale, status = "draft" } = getDocumentLocaleAndStatus(ctx.query);
|
2036
|
+
const { locale, status = "draft" } = await getDocumentLocaleAndStatus(ctx.query);
|
1997
2037
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
1998
2038
|
if (!entity) {
|
1999
2039
|
return ctx.notFound();
|
@@ -2008,26 +2048,27 @@ const collectionTypes = {
|
|
2008
2048
|
},
|
2009
2049
|
async countManyEntriesDraftRelations(ctx) {
|
2010
2050
|
const { userAbility } = ctx.state;
|
2011
|
-
const
|
2051
|
+
const ids = ctx.request.query.documentIds;
|
2052
|
+
const locale = ctx.request.query.locale;
|
2012
2053
|
const { model } = ctx.params;
|
2013
2054
|
const documentManager2 = getService$1("document-manager");
|
2014
2055
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2015
2056
|
if (permissionChecker2.cannot.read()) {
|
2016
2057
|
return ctx.forbidden();
|
2017
2058
|
}
|
2018
|
-
const
|
2059
|
+
const entities = await documentManager2.findMany(
|
2019
2060
|
{
|
2020
2061
|
filters: {
|
2021
|
-
documentId:
|
2062
|
+
documentId: ids
|
2022
2063
|
},
|
2023
2064
|
locale
|
2024
2065
|
},
|
2025
2066
|
model
|
2026
2067
|
);
|
2027
|
-
if (!
|
2068
|
+
if (!entities) {
|
2028
2069
|
return ctx.notFound();
|
2029
2070
|
}
|
2030
|
-
const number = await documentManager2.countManyEntriesDraftRelations(
|
2071
|
+
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
2031
2072
|
return {
|
2032
2073
|
data: number
|
2033
2074
|
};
|
@@ -2520,7 +2561,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2520
2561
|
throw new errors.ForbiddenError();
|
2521
2562
|
}
|
2522
2563
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2523
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2564
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2524
2565
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2525
2566
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2526
2567
|
// Find the first document to check if it exists
|
@@ -2557,12 +2598,11 @@ const singleTypes = {
|
|
2557
2598
|
const { model } = ctx.params;
|
2558
2599
|
const { query = {} } = ctx.request;
|
2559
2600
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2560
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2561
2601
|
if (permissionChecker2.cannot.read()) {
|
2562
2602
|
return ctx.forbidden();
|
2563
2603
|
}
|
2564
2604
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2565
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2605
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2566
2606
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2567
2607
|
if (!version) {
|
2568
2608
|
if (permissionChecker2.cannot.create()) {
|
@@ -2572,8 +2612,10 @@ const singleTypes = {
|
|
2572
2612
|
if (!document) {
|
2573
2613
|
return ctx.notFound();
|
2574
2614
|
}
|
2575
|
-
const { meta } = await
|
2615
|
+
const { meta } = await formatDocumentWithMetadata(
|
2616
|
+
permissionChecker2,
|
2576
2617
|
model,
|
2618
|
+
// @ts-expect-error - fix types
|
2577
2619
|
{ id: document.documentId, locale, publishedAt: null },
|
2578
2620
|
{ availableLocales: true, availableStatus: false }
|
2579
2621
|
);
|
@@ -2584,16 +2626,15 @@ const singleTypes = {
|
|
2584
2626
|
return ctx.forbidden();
|
2585
2627
|
}
|
2586
2628
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2587
|
-
ctx.body = await
|
2629
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2588
2630
|
},
|
2589
2631
|
async createOrUpdate(ctx) {
|
2590
2632
|
const { userAbility } = ctx.state;
|
2591
2633
|
const { model } = ctx.params;
|
2592
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2593
2634
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2594
2635
|
const document = await createOrUpdateDocument(ctx);
|
2595
2636
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2596
|
-
ctx.body = await
|
2637
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2597
2638
|
},
|
2598
2639
|
async delete(ctx) {
|
2599
2640
|
const { userAbility } = ctx.state;
|
@@ -2606,7 +2647,7 @@ const singleTypes = {
|
|
2606
2647
|
}
|
2607
2648
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2608
2649
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2609
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2650
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2610
2651
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2611
2652
|
populate,
|
2612
2653
|
locale
|
@@ -2629,7 +2670,6 @@ const singleTypes = {
|
|
2629
2670
|
const { model } = ctx.params;
|
2630
2671
|
const { query = {} } = ctx.request;
|
2631
2672
|
const documentManager2 = getService$1("document-manager");
|
2632
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2633
2673
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2634
2674
|
if (permissionChecker2.cannot.publish()) {
|
2635
2675
|
return ctx.forbidden();
|
@@ -2644,11 +2684,12 @@ const singleTypes = {
|
|
2644
2684
|
if (permissionChecker2.cannot.publish(document)) {
|
2645
2685
|
throw new errors.ForbiddenError();
|
2646
2686
|
}
|
2647
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2648
|
-
|
2687
|
+
const { locale } = await getDocumentLocaleAndStatus(document);
|
2688
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2689
|
+
return publishResult.at(0);
|
2649
2690
|
});
|
2650
2691
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2651
|
-
ctx.body = await
|
2692
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2652
2693
|
},
|
2653
2694
|
async unpublish(ctx) {
|
2654
2695
|
const { userAbility } = ctx.state;
|
@@ -2658,7 +2699,6 @@ const singleTypes = {
|
|
2658
2699
|
query = {}
|
2659
2700
|
} = ctx.request;
|
2660
2701
|
const documentManager2 = getService$1("document-manager");
|
2661
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2662
2702
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2663
2703
|
if (permissionChecker2.cannot.unpublish()) {
|
2664
2704
|
return ctx.forbidden();
|
@@ -2667,7 +2707,7 @@ const singleTypes = {
|
|
2667
2707
|
return ctx.forbidden();
|
2668
2708
|
}
|
2669
2709
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2670
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2710
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2671
2711
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2672
2712
|
if (!document) {
|
2673
2713
|
return ctx.notFound();
|
@@ -2685,7 +2725,7 @@ const singleTypes = {
|
|
2685
2725
|
ctx.body = await async.pipe(
|
2686
2726
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2687
2727
|
permissionChecker2.sanitizeOutput,
|
2688
|
-
(document2) =>
|
2728
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2689
2729
|
)(document);
|
2690
2730
|
});
|
2691
2731
|
},
|
@@ -2694,13 +2734,12 @@ const singleTypes = {
|
|
2694
2734
|
const { model } = ctx.params;
|
2695
2735
|
const { body, query = {} } = ctx.request;
|
2696
2736
|
const documentManager2 = getService$1("document-manager");
|
2697
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2698
2737
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2699
2738
|
if (permissionChecker2.cannot.discard()) {
|
2700
2739
|
return ctx.forbidden();
|
2701
2740
|
}
|
2702
2741
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2703
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2742
|
+
const { locale } = await getDocumentLocaleAndStatus(body);
|
2704
2743
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2705
2744
|
if (!document) {
|
2706
2745
|
return ctx.notFound();
|
@@ -2711,7 +2750,7 @@ const singleTypes = {
|
|
2711
2750
|
ctx.body = await async.pipe(
|
2712
2751
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2713
2752
|
permissionChecker2.sanitizeOutput,
|
2714
|
-
(document2) =>
|
2753
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2715
2754
|
)(document);
|
2716
2755
|
},
|
2717
2756
|
async countDraftRelations(ctx) {
|
@@ -2720,7 +2759,7 @@ const singleTypes = {
|
|
2720
2759
|
const { query } = ctx.request;
|
2721
2760
|
const documentManager2 = getService$1("document-manager");
|
2722
2761
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2723
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2762
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2724
2763
|
if (permissionChecker2.cannot.read()) {
|
2725
2764
|
return ctx.forbidden();
|
2726
2765
|
}
|
@@ -2741,7 +2780,7 @@ const uid$1 = {
|
|
2741
2780
|
async generateUID(ctx) {
|
2742
2781
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2743
2782
|
const { query = {} } = ctx.request;
|
2744
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2783
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2745
2784
|
await validateUIDField(contentTypeUID, field);
|
2746
2785
|
const uidService = getService$1("uid");
|
2747
2786
|
ctx.body = {
|
@@ -2753,7 +2792,7 @@ const uid$1 = {
|
|
2753
2792
|
ctx.request.body
|
2754
2793
|
);
|
2755
2794
|
const { query = {} } = ctx.request;
|
2756
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2795
|
+
const { locale } = await getDocumentLocaleAndStatus(query);
|
2757
2796
|
await validateUIDField(contentTypeUID, field);
|
2758
2797
|
const uidService = getService$1("uid");
|
2759
2798
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3544,7 +3583,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3544
3583
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3545
3584
|
}
|
3546
3585
|
});
|
3547
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils.contentTypes;
|
3586
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils.contentTypes;
|
3548
3587
|
const { isAnyToMany } = strapiUtils.relations;
|
3549
3588
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils.contentTypes.constants;
|
3550
3589
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3635,6 +3674,42 @@ const getDeepPopulate = (uid2, {
|
|
3635
3674
|
{}
|
3636
3675
|
);
|
3637
3676
|
};
|
3677
|
+
const getValidatableFieldsPopulate = (uid2, {
|
3678
|
+
initialPopulate = {},
|
3679
|
+
countMany = false,
|
3680
|
+
countOne = false,
|
3681
|
+
maxLevel = Infinity
|
3682
|
+
} = {}, level = 1) => {
|
3683
|
+
if (level > maxLevel) {
|
3684
|
+
return {};
|
3685
|
+
}
|
3686
|
+
const model = strapi.getModel(uid2);
|
3687
|
+
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
3688
|
+
if (!getDoesAttributeRequireValidation(attribute)) {
|
3689
|
+
return populateAcc;
|
3690
|
+
}
|
3691
|
+
if (isScalarAttribute(attribute)) {
|
3692
|
+
return merge(populateAcc, {
|
3693
|
+
[attributeName]: true
|
3694
|
+
});
|
3695
|
+
}
|
3696
|
+
return merge(
|
3697
|
+
populateAcc,
|
3698
|
+
getPopulateFor(
|
3699
|
+
attributeName,
|
3700
|
+
model,
|
3701
|
+
{
|
3702
|
+
// @ts-expect-error - improve types
|
3703
|
+
initialPopulate: initialPopulate?.[attributeName],
|
3704
|
+
countMany,
|
3705
|
+
countOne,
|
3706
|
+
maxLevel
|
3707
|
+
},
|
3708
|
+
level
|
3709
|
+
)
|
3710
|
+
);
|
3711
|
+
}, {});
|
3712
|
+
};
|
3638
3713
|
const getDeepPopulateDraftCount = (uid2) => {
|
3639
3714
|
const model = strapi.getModel(uid2);
|
3640
3715
|
let hasRelations = false;
|
@@ -3656,22 +3731,24 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3656
3731
|
attribute.component
|
3657
3732
|
);
|
3658
3733
|
if (childHasRelations) {
|
3659
|
-
populateAcc[attributeName] = {
|
3734
|
+
populateAcc[attributeName] = {
|
3735
|
+
populate: populate2
|
3736
|
+
};
|
3660
3737
|
hasRelations = true;
|
3661
3738
|
}
|
3662
3739
|
break;
|
3663
3740
|
}
|
3664
3741
|
case "dynamiczone": {
|
3665
|
-
const
|
3666
|
-
const { populate:
|
3667
|
-
if (
|
3742
|
+
const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {
|
3743
|
+
const { populate: componentPopulate, hasRelations: componentHasRelations } = getDeepPopulateDraftCount(componentUID);
|
3744
|
+
if (componentHasRelations) {
|
3668
3745
|
hasRelations = true;
|
3669
|
-
return
|
3746
|
+
return { ...acc, [componentUID]: { populate: componentPopulate } };
|
3670
3747
|
}
|
3671
3748
|
return acc;
|
3672
3749
|
}, {});
|
3673
|
-
if (!isEmpty(
|
3674
|
-
populateAcc[attributeName] = {
|
3750
|
+
if (!isEmpty(dzPopulateFragment)) {
|
3751
|
+
populateAcc[attributeName] = { on: dzPopulateFragment };
|
3675
3752
|
}
|
3676
3753
|
break;
|
3677
3754
|
}
|
@@ -3863,41 +3940,70 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3863
3940
|
"updatedBy",
|
3864
3941
|
"status"
|
3865
3942
|
];
|
3866
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
3943
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
3944
|
+
"id",
|
3945
|
+
"locale",
|
3946
|
+
"updatedAt",
|
3947
|
+
"createdAt",
|
3948
|
+
"status",
|
3949
|
+
"publishedAt",
|
3950
|
+
"documentId"
|
3951
|
+
];
|
3867
3952
|
const CONTENT_MANAGER_STATUS = {
|
3868
3953
|
PUBLISHED: "published",
|
3869
3954
|
DRAFT: "draft",
|
3870
3955
|
MODIFIED: "modified"
|
3871
3956
|
};
|
3872
|
-
const
|
3873
|
-
if (!
|
3957
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
3958
|
+
if (!version || !version.updatedAt) {
|
3874
3959
|
return false;
|
3875
3960
|
}
|
3876
|
-
const
|
3877
|
-
const
|
3878
|
-
|
3879
|
-
return difference2 <= threshold;
|
3961
|
+
const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;
|
3962
|
+
const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;
|
3963
|
+
return versionUpdatedAt > otherUpdatedAt;
|
3880
3964
|
};
|
3881
3965
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3882
3966
|
/**
|
3883
3967
|
* Returns available locales of a document for the current status
|
3884
3968
|
*/
|
3885
|
-
getAvailableLocales(uid2, version, allVersions) {
|
3969
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3886
3970
|
const versionsByLocale = groupBy("locale", allVersions);
|
3887
3971
|
delete versionsByLocale[version.locale];
|
3888
|
-
|
3889
|
-
|
3890
|
-
|
3972
|
+
const model = strapi2.getModel(uid2);
|
3973
|
+
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3974
|
+
const traversalFunction = async (localeVersion) => traverseEntity(
|
3975
|
+
({ key }, { remove }) => {
|
3976
|
+
if (keysToKeep.includes(key)) {
|
3977
|
+
return;
|
3978
|
+
}
|
3979
|
+
remove(key);
|
3980
|
+
},
|
3981
|
+
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
3982
|
+
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
3983
|
+
localeVersion
|
3984
|
+
);
|
3985
|
+
const mappingResult = await async.map(
|
3986
|
+
Object.values(versionsByLocale),
|
3987
|
+
async (localeVersions) => {
|
3988
|
+
const mappedLocaleVersions = await async.map(
|
3989
|
+
localeVersions,
|
3990
|
+
traversalFunction
|
3991
|
+
);
|
3992
|
+
if (!contentTypes$1.hasDraftAndPublish(model)) {
|
3993
|
+
return mappedLocaleVersions[0];
|
3994
|
+
}
|
3995
|
+
const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
|
3996
|
+
const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
|
3997
|
+
if (!draftVersion) {
|
3998
|
+
return;
|
3999
|
+
}
|
4000
|
+
return {
|
4001
|
+
...draftVersion,
|
4002
|
+
status: this.getStatus(draftVersion, otherVersions)
|
4003
|
+
};
|
3891
4004
|
}
|
3892
|
-
|
3893
|
-
|
3894
|
-
if (!draftVersion)
|
3895
|
-
return;
|
3896
|
-
return {
|
3897
|
-
...pick(AVAILABLE_LOCALES_FIELDS, draftVersion),
|
3898
|
-
status: this.getStatus(draftVersion, otherVersions)
|
3899
|
-
};
|
3900
|
-
}).filter(Boolean);
|
4005
|
+
);
|
4006
|
+
return mappingResult.filter(Boolean);
|
3901
4007
|
},
|
3902
4008
|
/**
|
3903
4009
|
* Returns available status of a document for the current locale
|
@@ -3935,26 +4041,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3935
4041
|
});
|
3936
4042
|
},
|
3937
4043
|
getStatus(version, otherDocumentStatuses) {
|
3938
|
-
|
3939
|
-
|
3940
|
-
|
4044
|
+
let draftVersion;
|
4045
|
+
let publishedVersion;
|
4046
|
+
if (version.publishedAt) {
|
4047
|
+
publishedVersion = version;
|
4048
|
+
} else {
|
4049
|
+
draftVersion = version;
|
3941
4050
|
}
|
3942
|
-
|
3943
|
-
|
3944
|
-
|
3945
|
-
|
3946
|
-
|
4051
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4052
|
+
if (otherVersion?.publishedAt) {
|
4053
|
+
publishedVersion = otherVersion;
|
4054
|
+
} else if (otherVersion) {
|
4055
|
+
draftVersion = otherVersion;
|
3947
4056
|
}
|
3948
|
-
if (
|
4057
|
+
if (!draftVersion)
|
3949
4058
|
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
3950
|
-
|
3951
|
-
|
4059
|
+
if (!publishedVersion)
|
4060
|
+
return CONTENT_MANAGER_STATUS.DRAFT;
|
4061
|
+
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4062
|
+
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
3952
4063
|
},
|
4064
|
+
// TODO is it necessary to return metadata on every page of the CM
|
4065
|
+
// We could refactor this so the locales are only loaded when they're
|
4066
|
+
// needed. e.g. in the bulk locale action modal.
|
3953
4067
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4068
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3954
4069
|
const versions = await strapi2.db.query(uid2).findMany({
|
3955
4070
|
where: { documentId: version.documentId },
|
3956
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3957
4071
|
populate: {
|
4072
|
+
// Populate only fields that require validation for bulk locale actions
|
4073
|
+
...populate,
|
4074
|
+
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
3958
4075
|
createdBy: {
|
3959
4076
|
select: ["id", "firstname", "lastname", "email"]
|
3960
4077
|
},
|
@@ -3963,7 +4080,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3963
4080
|
}
|
3964
4081
|
}
|
3965
4082
|
});
|
3966
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4083
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3967
4084
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3968
4085
|
return {
|
3969
4086
|
availableLocales: availableLocalesResult,
|
@@ -3976,8 +4093,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3976
4093
|
* - Available status of the document for the current locale
|
3977
4094
|
*/
|
3978
4095
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3979
|
-
if (!document)
|
4096
|
+
if (!document) {
|
3980
4097
|
return document;
|
4098
|
+
}
|
3981
4099
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
3982
4100
|
if (!hasDraftAndPublish) {
|
3983
4101
|
opts.availableStatus = false;
|
@@ -4113,7 +4231,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4113
4231
|
return {};
|
4114
4232
|
},
|
4115
4233
|
// FIXME: handle relations
|
4116
|
-
async deleteMany(documentIds, uid2, opts) {
|
4234
|
+
async deleteMany(documentIds, uid2, opts = {}) {
|
4117
4235
|
const deletedEntries = await strapi2.db.transaction(async () => {
|
4118
4236
|
return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
|
4119
4237
|
});
|
@@ -4122,18 +4240,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4122
4240
|
async publish(id, uid2, opts = {}) {
|
4123
4241
|
const populate = await buildDeepPopulate(uid2);
|
4124
4242
|
const params = { ...opts, populate };
|
4125
|
-
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries
|
4243
|
+
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries);
|
4126
4244
|
},
|
4127
|
-
async publishMany(
|
4128
|
-
|
4129
|
-
|
4130
|
-
documentIds.map(
|
4131
|
-
(id) => strapi2.documents(uid2).publish({ ...opts, documentId: id }).then((result) => result?.entries)
|
4132
|
-
)
|
4245
|
+
async publishMany(uid2, documentIds, locale) {
|
4246
|
+
return strapi2.db.transaction(async () => {
|
4247
|
+
const results = await Promise.all(
|
4248
|
+
documentIds.map((documentId) => this.publish(documentId, uid2, { locale }))
|
4133
4249
|
);
|
4250
|
+
const publishedEntitiesCount = results.flat().filter(Boolean).length;
|
4251
|
+
return publishedEntitiesCount;
|
4134
4252
|
});
|
4135
|
-
const publishedEntitiesCount = publishedEntries.flat().filter(Boolean).length;
|
4136
|
-
return { count: publishedEntitiesCount };
|
4137
4253
|
},
|
4138
4254
|
async unpublishMany(documentIds, uid2, opts = {}) {
|
4139
4255
|
const unpublishedEntries = await strapi2.db.transaction(async () => {
|
@@ -4174,14 +4290,18 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4174
4290
|
if (!hasRelations) {
|
4175
4291
|
return 0;
|
4176
4292
|
}
|
4177
|
-
|
4293
|
+
let localeFilter = {};
|
4294
|
+
if (locale) {
|
4295
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4296
|
+
}
|
4297
|
+
const entities = await strapi2.db.query(uid2).findMany({
|
4178
4298
|
populate,
|
4179
|
-
|
4180
|
-
documentId: documentIds
|
4181
|
-
|
4182
|
-
|
4299
|
+
where: {
|
4300
|
+
documentId: { $in: documentIds },
|
4301
|
+
...localeFilter
|
4302
|
+
}
|
4183
4303
|
});
|
4184
|
-
const totalNumberDraftRelations =
|
4304
|
+
const totalNumberDraftRelations = entities.reduce(
|
4185
4305
|
(count, entity) => sumDraftCounts(entity, uid2) + count,
|
4186
4306
|
0
|
4187
4307
|
);
|