@strapi/content-manager 0.0.0-experimental.d954d57341a6623992a0d211daaec8e245c3517d → 0.0.0-experimental.dd1d47ef78ef6cfec4ed62576108500bd9f13740
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/{ComponentConfigurationPage-gdUj_t-O.mjs → ComponentConfigurationPage-BpM_Hc7r.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-gdUj_t-O.mjs.map → ComponentConfigurationPage-BpM_Hc7r.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-WRPUXGd6.js → ComponentConfigurationPage-CL9CAMaL.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-WRPUXGd6.js.map → ComponentConfigurationPage-CL9CAMaL.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js → EditConfigurationPage-ILWo0h1e.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js.map → EditConfigurationPage-ILWo0h1e.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs → EditConfigurationPage-_prbqpTM.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs.map → EditConfigurationPage-_prbqpTM.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DbcGfyqK.js → EditViewPage-BqZvBN4s.js} +30 -9
- package/dist/_chunks/EditViewPage-BqZvBN4s.js.map +1 -0
- package/dist/_chunks/{EditViewPage-0MiFkXa8.mjs → EditViewPage-DAtscabN.mjs} +30 -9
- package/dist/_chunks/EditViewPage-DAtscabN.mjs.map +1 -0
- package/dist/_chunks/{Field-BG1xu38N.js → Field-CcoQiiz1.js} +520 -156
- package/dist/_chunks/Field-CcoQiiz1.js.map +1 -0
- package/dist/_chunks/{Field-BDMSCcy5.mjs → Field-D-mgn1tH.mjs} +518 -154
- package/dist/_chunks/Field-D-mgn1tH.mjs.map +1 -0
- package/dist/_chunks/{Form-CPVWavB8.mjs → Form-BxyeWiXW.mjs} +40 -18
- package/dist/_chunks/Form-BxyeWiXW.mjs.map +1 -0
- package/dist/_chunks/{Form-9BnFyUjy.js → Form-CmLbZDfi.js} +40 -18
- package/dist/_chunks/Form-CmLbZDfi.js.map +1 -0
- package/dist/_chunks/{History-BVpd8LP3.mjs → History-BOhLaq_g.mjs} +78 -56
- package/dist/_chunks/History-BOhLaq_g.mjs.map +1 -0
- package/dist/_chunks/{History-BWWxLt2Z.js → History-uECUbCZB.js} +77 -55
- package/dist/_chunks/History-uECUbCZB.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DozVMKcR.mjs → ListConfigurationPage-D0vQez6F.mjs} +21 -9
- package/dist/_chunks/ListConfigurationPage-D0vQez6F.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-6swzjdAZ.js → ListConfigurationPage-D_bBSFNW.js} +21 -9
- package/dist/_chunks/ListConfigurationPage-D_bBSFNW.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BlzfjS2Q.js → ListViewPage-BkZ83b1A.js} +73 -44
- package/dist/_chunks/ListViewPage-BkZ83b1A.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Ds0ulgfG.mjs → ListViewPage-ns-bmy5C.mjs} +71 -42
- package/dist/_chunks/ListViewPage-ns-bmy5C.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs → NoContentTypePage-BA5ZKMDR.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs.map → NoContentTypePage-BA5ZKMDR.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js → NoContentTypePage-C1439s4s.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js.map → NoContentTypePage-C1439s4s.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs → NoPermissionsPage-B0GdMw1Q.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs.map → NoPermissionsPage-B0GdMw1Q.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js → NoPermissionsPage-CPGwsVfb.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js.map → NoPermissionsPage-CPGwsVfb.js.map} +1 -1
- package/dist/_chunks/{Relations-Dnag3fhV.mjs → Relations-BIGPMSW4.mjs} +73 -37
- package/dist/_chunks/Relations-BIGPMSW4.mjs.map +1 -0
- package/dist/_chunks/{Relations-CcgFTcWo.js → Relations-d-8Uef_-.js} +72 -36
- package/dist/_chunks/Relations-d-8Uef_-.js.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-Bdpa50w3.js} +22 -16
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-Bdpa50w3.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-CZw4xdPY.mjs} +22 -16
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-CZw4xdPY.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/{index-JNNNKUHs.mjs → index-3_WeHXYp.mjs} +1084 -663
- package/dist/_chunks/index-3_WeHXYp.mjs.map +1 -0
- package/dist/_chunks/{index-CWpLBSt0.js → index-BgaeYWIy.js} +1073 -651
- package/dist/_chunks/index-BgaeYWIy.js.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout--iHdZzRk.js → layout-ByFyQRDH.js} +25 -12
- package/dist/_chunks/layout-ByFyQRDH.js.map +1 -0
- package/dist/_chunks/{layout-DC503LnF.mjs → layout-CrTxOnCy.mjs} +27 -14
- package/dist/_chunks/layout-CrTxOnCy.mjs.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-CTje5t-a.mjs → relations-BlpLgngh.mjs} +3 -7
- package/dist/_chunks/relations-BlpLgngh.mjs.map +1 -0
- package/dist/_chunks/{relations-BbHizA5K.js → relations-C5RSW926.js} +3 -7
- package/dist/_chunks/relations-C5RSW926.js.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +3 -2
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +551 -266
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +552 -267
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +13 -13
- package/dist/_chunks/EditViewPage-0MiFkXa8.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DbcGfyqK.js.map +0 -1
- package/dist/_chunks/Field-BDMSCcy5.mjs.map +0 -1
- package/dist/_chunks/Field-BG1xu38N.js.map +0 -1
- package/dist/_chunks/Form-9BnFyUjy.js.map +0 -1
- package/dist/_chunks/Form-CPVWavB8.mjs.map +0 -1
- package/dist/_chunks/History-BVpd8LP3.mjs.map +0 -1
- package/dist/_chunks/History-BWWxLt2Z.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-6swzjdAZ.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DozVMKcR.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BlzfjS2Q.js.map +0 -1
- package/dist/_chunks/ListViewPage-Ds0ulgfG.mjs.map +0 -1
- package/dist/_chunks/Relations-CcgFTcWo.js.map +0 -1
- package/dist/_chunks/Relations-Dnag3fhV.mjs.map +0 -1
- package/dist/_chunks/index-CWpLBSt0.js.map +0 -1
- package/dist/_chunks/index-JNNNKUHs.mjs.map +0 -1
- package/dist/_chunks/layout--iHdZzRk.js.map +0 -1
- package/dist/_chunks/layout-DC503LnF.mjs.map +0 -1
- package/dist/_chunks/relations-BbHizA5K.js.map +0 -1
- package/dist/_chunks/relations-CTje5t-a.mjs.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.js
CHANGED
@@ -33,10 +33,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
33
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
34
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
35
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
36
|
+
const getService$2 = (name) => {
|
37
37
|
return strapi.plugin("content-manager").service(name);
|
38
38
|
};
|
39
|
-
function getService(strapi2, name) {
|
39
|
+
function getService$1(strapi2, name) {
|
40
40
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
41
|
}
|
42
42
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +72,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
72
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
73
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
74
|
}
|
75
|
-
const permissionChecker2 = getService$
|
75
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
76
|
userAbility: ctx.state.userAbility,
|
77
77
|
model: ctx.query.contentType
|
78
78
|
});
|
@@ -80,7 +80,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
80
|
return ctx.forbidden();
|
81
81
|
}
|
82
82
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
83
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
84
|
query: {
|
85
85
|
...query,
|
86
86
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +105,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
105
|
async restoreVersion(ctx) {
|
106
106
|
const request = ctx.request;
|
107
107
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
108
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
109
|
userAbility: ctx.state.userAbility,
|
110
110
|
model: request.body.contentType
|
111
111
|
});
|
112
112
|
if (permissionChecker2.cannot.update()) {
|
113
113
|
throw new strapiUtils.errors.ForbiddenError();
|
114
114
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
115
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
116
|
request.params.versionId
|
117
117
|
);
|
118
118
|
return {
|
@@ -121,7 +121,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
121
|
}
|
122
122
|
};
|
123
123
|
};
|
124
|
-
const controllers$
|
124
|
+
const controllers$2 = {
|
125
125
|
"history-version": createHistoryVersionController
|
126
126
|
/**
|
127
127
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -199,7 +199,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
199
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
200
|
};
|
201
201
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
202
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
203
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
204
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
205
|
const getLocaleDictionary = async () => {
|
204
206
|
if (!localesService)
|
205
207
|
return {};
|
@@ -226,31 +228,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
228
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
229
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
230
|
};
|
229
|
-
const
|
231
|
+
const getComponentFields = (componentUID) => {
|
232
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
233
|
+
(fieldsAcc, [key, attribute]) => {
|
234
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
235
|
+
fieldsAcc.push(key);
|
236
|
+
}
|
237
|
+
return fieldsAcc;
|
238
|
+
},
|
239
|
+
[]
|
240
|
+
);
|
241
|
+
};
|
242
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
243
|
const model = strapi2.getModel(uid2);
|
231
244
|
const attributes = Object.entries(model.attributes);
|
245
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
246
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
247
|
switch (attribute.type) {
|
234
248
|
case "relation": {
|
249
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
250
|
+
if (isMorphRelation) {
|
251
|
+
break;
|
252
|
+
}
|
235
253
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
236
254
|
if (isVisible2) {
|
237
|
-
acc[attributeName] = {
|
255
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
238
256
|
}
|
239
257
|
break;
|
240
258
|
}
|
241
259
|
case "media": {
|
242
|
-
acc[attributeName] = {
|
260
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
243
261
|
break;
|
244
262
|
}
|
245
263
|
case "component": {
|
246
264
|
const populate = getDeepPopulate2(attribute.component);
|
247
|
-
acc[attributeName] = {
|
265
|
+
acc[attributeName] = {
|
266
|
+
populate,
|
267
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
268
|
+
};
|
248
269
|
break;
|
249
270
|
}
|
250
271
|
case "dynamiczone": {
|
251
272
|
const populatedComponents = (attribute.components || []).reduce(
|
252
273
|
(acc2, componentUID) => {
|
253
|
-
acc2[componentUID] = {
|
274
|
+
acc2[componentUID] = {
|
275
|
+
populate: getDeepPopulate2(componentUID),
|
276
|
+
[fieldSelector]: getComponentFields(componentUID)
|
277
|
+
};
|
254
278
|
return acc2;
|
255
279
|
},
|
256
280
|
{}
|
@@ -312,6 +336,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
312
336
|
getRelationRestoreValue,
|
313
337
|
getMediaRestoreValue,
|
314
338
|
getDefaultLocale,
|
339
|
+
isLocalizedContentType,
|
315
340
|
getLocaleDictionary,
|
316
341
|
getRetentionDays,
|
317
342
|
getVersionStatus,
|
@@ -334,7 +359,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
359
|
});
|
335
360
|
},
|
336
361
|
async findVersionsPage(params) {
|
337
|
-
const
|
362
|
+
const model = strapi2.getModel(params.query.contentType);
|
363
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
364
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
365
|
+
let locale = null;
|
366
|
+
if (isLocalizedContentType) {
|
367
|
+
locale = params.query.locale || defaultLocale;
|
368
|
+
}
|
338
369
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
339
370
|
query.findPage({
|
340
371
|
...params.query,
|
@@ -356,7 +387,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
356
387
|
const attributeValue = entry.data[attributeKey];
|
357
388
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
358
389
|
if (attributeSchema.type === "media") {
|
359
|
-
const permissionChecker2 = getService$
|
390
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
360
391
|
userAbility: params.state.userAbility,
|
361
392
|
model: "plugin::upload.file"
|
362
393
|
});
|
@@ -379,7 +410,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
379
410
|
if (userToPopulate == null) {
|
380
411
|
return null;
|
381
412
|
}
|
382
|
-
return strapi2.query("admin::user").findOne({
|
413
|
+
return strapi2.query("admin::user").findOne({
|
414
|
+
where: {
|
415
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
416
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
417
|
+
}
|
418
|
+
});
|
383
419
|
})
|
384
420
|
);
|
385
421
|
return {
|
@@ -392,7 +428,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
392
428
|
[attributeKey]: adminUsers
|
393
429
|
};
|
394
430
|
}
|
395
|
-
const permissionChecker2 = getService$
|
431
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
396
432
|
userAbility: params.state.userAbility,
|
397
433
|
model: attributeSchema.target
|
398
434
|
});
|
@@ -490,13 +526,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
490
526
|
}
|
491
527
|
};
|
492
528
|
};
|
529
|
+
const shouldCreateHistoryVersion = (context) => {
|
530
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
540
|
+
return false;
|
541
|
+
}
|
542
|
+
return true;
|
543
|
+
};
|
544
|
+
const getSchemas = (uid2) => {
|
545
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
546
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
547
|
+
(currentComponentSchemas, key) => {
|
548
|
+
const fieldSchema = attributesSchema[key];
|
549
|
+
if (fieldSchema.type === "component") {
|
550
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
551
|
+
return {
|
552
|
+
...currentComponentSchemas,
|
553
|
+
[fieldSchema.component]: componentSchema
|
554
|
+
};
|
555
|
+
}
|
556
|
+
return currentComponentSchemas;
|
557
|
+
},
|
558
|
+
{}
|
559
|
+
);
|
560
|
+
return {
|
561
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
562
|
+
componentsSchemas
|
563
|
+
};
|
564
|
+
};
|
493
565
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
566
|
const state = {
|
495
567
|
deleteExpiredJob: null,
|
496
568
|
isInitialized: false
|
497
569
|
};
|
498
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
-
const historyService = getService(strapi2, "history");
|
500
570
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
571
|
return {
|
502
572
|
async bootstrap() {
|
@@ -504,76 +574,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
504
574
|
return;
|
505
575
|
}
|
506
576
|
strapi2.documents.use(async (context, next) => {
|
507
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
-
return next();
|
509
|
-
}
|
510
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
-
return next();
|
512
|
-
}
|
513
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
514
|
-
return next();
|
515
|
-
}
|
516
|
-
const contentTypeUid = context.contentType.uid;
|
517
|
-
if (!contentTypeUid.startsWith("api::")) {
|
518
|
-
return next();
|
519
|
-
}
|
520
577
|
const result = await next();
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
578
|
+
if (!shouldCreateHistoryVersion(context)) {
|
579
|
+
return result;
|
580
|
+
}
|
581
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
525
582
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
526
|
-
const
|
527
|
-
if (
|
528
|
-
|
529
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
530
|
-
);
|
531
|
-
return next();
|
583
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
584
|
+
if (!locales.length) {
|
585
|
+
return result;
|
532
586
|
}
|
533
|
-
const
|
534
|
-
|
535
|
-
|
536
|
-
|
587
|
+
const uid2 = context.contentType.uid;
|
588
|
+
const schemas = getSchemas(uid2);
|
589
|
+
const model = strapi2.getModel(uid2);
|
590
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
591
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
592
|
+
where: {
|
593
|
+
documentId,
|
594
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
595
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
596
|
+
},
|
597
|
+
populate: serviceUtils.getDeepPopulate(
|
598
|
+
uid2,
|
599
|
+
true
|
600
|
+
/* use database syntax */
|
601
|
+
)
|
537
602
|
});
|
538
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
539
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
540
|
-
const componentsSchemas = Object.keys(
|
541
|
-
attributesSchema
|
542
|
-
).reduce((currentComponentSchemas, key) => {
|
543
|
-
const fieldSchema = attributesSchema[key];
|
544
|
-
if (fieldSchema.type === "component") {
|
545
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
546
|
-
return {
|
547
|
-
...currentComponentSchemas,
|
548
|
-
[fieldSchema.component]: componentSchema
|
549
|
-
};
|
550
|
-
}
|
551
|
-
return currentComponentSchemas;
|
552
|
-
}, {});
|
553
603
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
554
|
-
onCommit(() => {
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
604
|
+
onCommit(async () => {
|
605
|
+
for (const entry of localeEntries) {
|
606
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
607
|
+
await getService$1(strapi2, "history").createVersion({
|
608
|
+
contentType: uid2,
|
609
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
610
|
+
relatedDocumentId: documentId,
|
611
|
+
locale: entry.locale,
|
612
|
+
status,
|
613
|
+
...schemas
|
614
|
+
});
|
615
|
+
}
|
564
616
|
});
|
565
617
|
});
|
566
618
|
return result;
|
567
619
|
});
|
568
|
-
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
620
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
569
621
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
570
622
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
571
|
-
query.deleteMany({
|
623
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
572
624
|
where: {
|
573
625
|
created_at: {
|
574
|
-
$lt: expirationDate
|
626
|
+
$lt: expirationDate
|
575
627
|
}
|
576
628
|
}
|
629
|
+
}).catch((error) => {
|
630
|
+
if (error instanceof Error) {
|
631
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
632
|
+
}
|
577
633
|
});
|
578
634
|
});
|
579
635
|
state.isInitialized = true;
|
@@ -585,17 +641,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
585
641
|
}
|
586
642
|
};
|
587
643
|
};
|
588
|
-
const services$
|
644
|
+
const services$2 = {
|
589
645
|
history: createHistoryService,
|
590
646
|
lifecycles: createLifecyclesService
|
591
647
|
};
|
592
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
648
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
593
649
|
const historyVersionRouter = {
|
594
650
|
type: "admin",
|
595
651
|
routes: [
|
596
652
|
{
|
597
653
|
method: "GET",
|
598
|
-
info,
|
654
|
+
info: info$1,
|
599
655
|
path: "/history-versions",
|
600
656
|
handler: "history-version.findMany",
|
601
657
|
config: {
|
@@ -604,7 +660,7 @@ const historyVersionRouter = {
|
|
604
660
|
},
|
605
661
|
{
|
606
662
|
method: "PUT",
|
607
|
-
info,
|
663
|
+
info: info$1,
|
608
664
|
path: "/history-versions/:versionId/restore",
|
609
665
|
handler: "history-version.restoreVersion",
|
610
666
|
config: {
|
@@ -613,7 +669,7 @@ const historyVersionRouter = {
|
|
613
669
|
}
|
614
670
|
]
|
615
671
|
};
|
616
|
-
const routes$
|
672
|
+
const routes$2 = {
|
617
673
|
"history-version": historyVersionRouter
|
618
674
|
};
|
619
675
|
const historyVersion = {
|
@@ -660,21 +716,21 @@ const historyVersion = {
|
|
660
716
|
}
|
661
717
|
}
|
662
718
|
};
|
663
|
-
const getFeature = () => {
|
719
|
+
const getFeature$1 = () => {
|
664
720
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
665
721
|
return {
|
666
722
|
register({ strapi: strapi2 }) {
|
667
723
|
strapi2.get("models").add(historyVersion);
|
668
724
|
},
|
669
725
|
bootstrap({ strapi: strapi2 }) {
|
670
|
-
getService(strapi2, "lifecycles").bootstrap();
|
726
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
671
727
|
},
|
672
728
|
destroy({ strapi: strapi2 }) {
|
673
|
-
getService(strapi2, "lifecycles").destroy();
|
729
|
+
getService$1(strapi2, "lifecycles").destroy();
|
674
730
|
},
|
675
|
-
controllers: controllers$
|
676
|
-
services: services$
|
677
|
-
routes: routes$
|
731
|
+
controllers: controllers$2,
|
732
|
+
services: services$2,
|
733
|
+
routes: routes$2
|
678
734
|
};
|
679
735
|
}
|
680
736
|
return {
|
@@ -683,7 +739,7 @@ const getFeature = () => {
|
|
683
739
|
}
|
684
740
|
};
|
685
741
|
};
|
686
|
-
const history = getFeature();
|
742
|
+
const history = getFeature$1();
|
687
743
|
const register = async ({ strapi: strapi2 }) => {
|
688
744
|
await history.register?.({ strapi: strapi2 });
|
689
745
|
};
|
@@ -691,15 +747,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
|
|
691
747
|
ENTRY_PUBLISH: "entry.publish",
|
692
748
|
ENTRY_UNPUBLISH: "entry.unpublish"
|
693
749
|
};
|
750
|
+
const FEATURE_ID = "preview";
|
751
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
752
|
+
const previewRouter = {
|
753
|
+
type: "admin",
|
754
|
+
routes: [
|
755
|
+
{
|
756
|
+
method: "GET",
|
757
|
+
info,
|
758
|
+
path: "/preview/url/:contentType",
|
759
|
+
handler: "preview.getPreviewUrl",
|
760
|
+
config: {
|
761
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
762
|
+
}
|
763
|
+
}
|
764
|
+
]
|
765
|
+
};
|
766
|
+
const routes$1 = {
|
767
|
+
preview: previewRouter
|
768
|
+
};
|
769
|
+
function getService(strapi2, name) {
|
770
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
771
|
+
}
|
772
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
773
|
+
// Will be undefined for single types
|
774
|
+
documentId: yup__namespace.string(),
|
775
|
+
locale: yup__namespace.string().nullable(),
|
776
|
+
status: yup__namespace.string()
|
777
|
+
}).required();
|
778
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
779
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
780
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
781
|
+
const model = strapi2.getModel(uid2);
|
782
|
+
if (!model || model.modelType !== "contentType") {
|
783
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
784
|
+
}
|
785
|
+
const isSingleType = model?.kind === "singleType";
|
786
|
+
if (!isSingleType && !params.documentId) {
|
787
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
788
|
+
}
|
789
|
+
if (isSingleType) {
|
790
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
791
|
+
if (!doc) {
|
792
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
793
|
+
}
|
794
|
+
newParams.documentId = doc?.documentId;
|
795
|
+
}
|
796
|
+
return newParams;
|
797
|
+
};
|
798
|
+
const createPreviewController = () => {
|
799
|
+
return {
|
800
|
+
/**
|
801
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
802
|
+
* in the Content Manager.
|
803
|
+
*/
|
804
|
+
async getPreviewUrl(ctx) {
|
805
|
+
const uid2 = ctx.params.contentType;
|
806
|
+
const query = ctx.request.query;
|
807
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
808
|
+
const previewService = getService(strapi, "preview");
|
809
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
810
|
+
if (!url) {
|
811
|
+
ctx.status = 204;
|
812
|
+
}
|
813
|
+
return {
|
814
|
+
data: { url }
|
815
|
+
};
|
816
|
+
}
|
817
|
+
};
|
818
|
+
};
|
819
|
+
const controllers$1 = {
|
820
|
+
preview: createPreviewController
|
821
|
+
/**
|
822
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
823
|
+
* passing a controller factory as the value, instead of a controller object directly
|
824
|
+
*/
|
825
|
+
};
|
826
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
827
|
+
const config = getService(strapi2, "preview-config");
|
828
|
+
return {
|
829
|
+
async getPreviewUrl(uid2, params) {
|
830
|
+
const handler = config.getPreviewHandler();
|
831
|
+
try {
|
832
|
+
return handler(uid2, params);
|
833
|
+
} catch (error) {
|
834
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
835
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
836
|
+
}
|
837
|
+
return;
|
838
|
+
}
|
839
|
+
};
|
840
|
+
};
|
841
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
842
|
+
return {
|
843
|
+
isEnabled() {
|
844
|
+
const config = strapi2.config.get("admin.preview");
|
845
|
+
if (!config) {
|
846
|
+
return false;
|
847
|
+
}
|
848
|
+
return config?.enabled ?? true;
|
849
|
+
},
|
850
|
+
/**
|
851
|
+
* Validate if the configuration is valid
|
852
|
+
*/
|
853
|
+
validate() {
|
854
|
+
if (!this.isEnabled()) {
|
855
|
+
return;
|
856
|
+
}
|
857
|
+
const handler = this.getPreviewHandler();
|
858
|
+
if (typeof handler !== "function") {
|
859
|
+
throw new strapiUtils.errors.ValidationError(
|
860
|
+
"Preview configuration is invalid. Handler must be a function"
|
861
|
+
);
|
862
|
+
}
|
863
|
+
},
|
864
|
+
/**
|
865
|
+
* Utility to get the preview handler from the configuration
|
866
|
+
*/
|
867
|
+
getPreviewHandler() {
|
868
|
+
const config = strapi2.config.get("admin.preview");
|
869
|
+
const emptyHandler = () => {
|
870
|
+
return void 0;
|
871
|
+
};
|
872
|
+
if (!this.isEnabled()) {
|
873
|
+
return emptyHandler;
|
874
|
+
}
|
875
|
+
return config?.config?.handler || emptyHandler;
|
876
|
+
}
|
877
|
+
};
|
878
|
+
};
|
879
|
+
const services$1 = {
|
880
|
+
preview: createPreviewService,
|
881
|
+
"preview-config": createPreviewConfigService
|
882
|
+
};
|
883
|
+
const getFeature = () => {
|
884
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
885
|
+
return {};
|
886
|
+
}
|
887
|
+
return {
|
888
|
+
bootstrap() {
|
889
|
+
console.log("Bootstrapping preview server");
|
890
|
+
const config = getService(strapi, "preview-config");
|
891
|
+
config.validate();
|
892
|
+
},
|
893
|
+
routes: routes$1,
|
894
|
+
controllers: controllers$1,
|
895
|
+
services: services$1
|
896
|
+
};
|
897
|
+
};
|
898
|
+
const preview = getFeature();
|
694
899
|
const bootstrap = async () => {
|
695
900
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
696
901
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
697
902
|
});
|
698
|
-
getService$
|
699
|
-
await getService$
|
700
|
-
await getService$
|
701
|
-
await getService$
|
903
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
904
|
+
await getService$2("components").syncConfigurations();
|
905
|
+
await getService$2("content-types").syncConfigurations();
|
906
|
+
await getService$2("permission").registerPermissions();
|
702
907
|
await history.bootstrap?.({ strapi });
|
908
|
+
await preview.bootstrap?.({ strapi });
|
703
909
|
};
|
704
910
|
const destroy = async ({ strapi: strapi2 }) => {
|
705
911
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1189,7 +1395,8 @@ const admin = {
|
|
1189
1395
|
};
|
1190
1396
|
const routes = {
|
1191
1397
|
admin,
|
1192
|
-
...history.routes ? history.routes : {}
|
1398
|
+
...history.routes ? history.routes : {},
|
1399
|
+
...preview.routes ? preview.routes : {}
|
1193
1400
|
};
|
1194
1401
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1195
1402
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1200,6 +1407,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1200
1407
|
const hasPermissions = createPolicy({
|
1201
1408
|
name: "plugin::content-manager.hasPermissions",
|
1202
1409
|
validator: validateHasPermissionsInput,
|
1410
|
+
/**
|
1411
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1412
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1413
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1414
|
+
*/
|
1203
1415
|
handler(ctx, config = {}) {
|
1204
1416
|
const { actions = [], hasAtLeastOne = false } = config;
|
1205
1417
|
const { userAbility } = ctx.state;
|
@@ -1441,7 +1653,7 @@ const createMetadasSchema = (schema) => {
|
|
1441
1653
|
if (!value) {
|
1442
1654
|
return strapiUtils.yup.string();
|
1443
1655
|
}
|
1444
|
-
const targetSchema = getService$
|
1656
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1445
1657
|
schema.attributes[key].targetModel
|
1446
1658
|
);
|
1447
1659
|
if (!targetSchema) {
|
@@ -1593,9 +1805,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1593
1805
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1594
1806
|
);
|
1595
1807
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1596
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1808
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1597
1809
|
const { allowMultipleLocales } = opts;
|
1598
|
-
const { locale, status, ...rest } = request || {};
|
1810
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1811
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1812
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1599
1813
|
const schema = strapiUtils.yup.object().shape({
|
1600
1814
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1601
1815
|
status: statusSchema
|
@@ -1608,7 +1822,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1608
1822
|
}
|
1609
1823
|
};
|
1610
1824
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1611
|
-
const documentMetadata2 = getService$
|
1825
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1612
1826
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1613
1827
|
let {
|
1614
1828
|
meta: { availableLocales, availableStatus }
|
@@ -1634,8 +1848,8 @@ const createDocument = async (ctx, opts) => {
|
|
1634
1848
|
const { userAbility, user } = ctx.state;
|
1635
1849
|
const { model } = ctx.params;
|
1636
1850
|
const { body } = ctx.request;
|
1637
|
-
const documentManager2 = getService$
|
1638
|
-
const permissionChecker2 = getService$
|
1851
|
+
const documentManager2 = getService$2("document-manager");
|
1852
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1639
1853
|
if (permissionChecker2.cannot.create()) {
|
1640
1854
|
throw new strapiUtils.errors.ForbiddenError();
|
1641
1855
|
}
|
@@ -1643,7 +1857,7 @@ const createDocument = async (ctx, opts) => {
|
|
1643
1857
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1644
1858
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1645
1859
|
const sanitizedBody = await sanitizeFn(body);
|
1646
|
-
const { locale, status
|
1860
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1647
1861
|
return documentManager2.create(model, {
|
1648
1862
|
data: sanitizedBody,
|
1649
1863
|
locale,
|
@@ -1655,14 +1869,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1655
1869
|
const { userAbility, user } = ctx.state;
|
1656
1870
|
const { id, model } = ctx.params;
|
1657
1871
|
const { body } = ctx.request;
|
1658
|
-
const documentManager2 = getService$
|
1659
|
-
const permissionChecker2 = getService$
|
1872
|
+
const documentManager2 = getService$2("document-manager");
|
1873
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1660
1874
|
if (permissionChecker2.cannot.update()) {
|
1661
1875
|
throw new strapiUtils.errors.ForbiddenError();
|
1662
1876
|
}
|
1663
1877
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1664
|
-
const populate = await getService$
|
1665
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1878
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1879
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1666
1880
|
const [documentVersion, documentExists] = await Promise.all([
|
1667
1881
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1668
1882
|
documentManager2.exists(model, id)
|
@@ -1678,7 +1892,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1678
1892
|
throw new strapiUtils.errors.ForbiddenError();
|
1679
1893
|
}
|
1680
1894
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1681
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1895
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1682
1896
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1683
1897
|
const sanitizedBody = await sanitizeFn(body);
|
1684
1898
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1692,15 +1906,15 @@ const collectionTypes = {
|
|
1692
1906
|
const { userAbility } = ctx.state;
|
1693
1907
|
const { model } = ctx.params;
|
1694
1908
|
const { query } = ctx.request;
|
1695
|
-
const documentMetadata2 = getService$
|
1696
|
-
const documentManager2 = getService$
|
1697
|
-
const permissionChecker2 = getService$
|
1909
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1910
|
+
const documentManager2 = getService$2("document-manager");
|
1911
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1698
1912
|
if (permissionChecker2.cannot.read()) {
|
1699
1913
|
return ctx.forbidden();
|
1700
1914
|
}
|
1701
1915
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1702
|
-
const populate = await getService$
|
1703
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1916
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1917
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1704
1918
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1705
1919
|
{ ...permissionQuery, populate, locale, status },
|
1706
1920
|
model
|
@@ -1728,14 +1942,14 @@ const collectionTypes = {
|
|
1728
1942
|
async findOne(ctx) {
|
1729
1943
|
const { userAbility } = ctx.state;
|
1730
1944
|
const { model, id } = ctx.params;
|
1731
|
-
const documentManager2 = getService$
|
1732
|
-
const permissionChecker2 = getService$
|
1945
|
+
const documentManager2 = getService$2("document-manager");
|
1946
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1733
1947
|
if (permissionChecker2.cannot.read()) {
|
1734
1948
|
return ctx.forbidden();
|
1735
1949
|
}
|
1736
1950
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1737
|
-
const populate = await getService$
|
1738
|
-
const { locale, status
|
1951
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1952
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1739
1953
|
const version = await documentManager2.findOne(id, model, {
|
1740
1954
|
populate,
|
1741
1955
|
locale,
|
@@ -1750,7 +1964,7 @@ const collectionTypes = {
|
|
1750
1964
|
permissionChecker2,
|
1751
1965
|
model,
|
1752
1966
|
// @ts-expect-error TODO: fix
|
1753
|
-
{ id, locale, publishedAt: null },
|
1967
|
+
{ documentId: id, locale, publishedAt: null },
|
1754
1968
|
{ availableLocales: true, availableStatus: false }
|
1755
1969
|
);
|
1756
1970
|
ctx.body = { data: {}, meta };
|
@@ -1765,7 +1979,7 @@ const collectionTypes = {
|
|
1765
1979
|
async create(ctx) {
|
1766
1980
|
const { userAbility } = ctx.state;
|
1767
1981
|
const { model } = ctx.params;
|
1768
|
-
const permissionChecker2 = getService$
|
1982
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1769
1983
|
const [totalEntries, document] = await Promise.all([
|
1770
1984
|
strapi.db.query(model).count(),
|
1771
1985
|
createDocument(ctx)
|
@@ -1786,7 +2000,7 @@ const collectionTypes = {
|
|
1786
2000
|
async update(ctx) {
|
1787
2001
|
const { userAbility } = ctx.state;
|
1788
2002
|
const { model } = ctx.params;
|
1789
|
-
const permissionChecker2 = getService$
|
2003
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1790
2004
|
const updatedVersion = await updateDocument(ctx);
|
1791
2005
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1792
2006
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1795,14 +2009,14 @@ const collectionTypes = {
|
|
1795
2009
|
const { userAbility, user } = ctx.state;
|
1796
2010
|
const { model, sourceId: id } = ctx.params;
|
1797
2011
|
const { body } = ctx.request;
|
1798
|
-
const documentManager2 = getService$
|
1799
|
-
const permissionChecker2 = getService$
|
2012
|
+
const documentManager2 = getService$2("document-manager");
|
2013
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1800
2014
|
if (permissionChecker2.cannot.create()) {
|
1801
2015
|
return ctx.forbidden();
|
1802
2016
|
}
|
1803
2017
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1804
|
-
const populate = await getService$
|
1805
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2018
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2019
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1806
2020
|
const document = await documentManager2.findOne(id, model, {
|
1807
2021
|
populate,
|
1808
2022
|
locale,
|
@@ -1840,14 +2054,14 @@ const collectionTypes = {
|
|
1840
2054
|
async delete(ctx) {
|
1841
2055
|
const { userAbility } = ctx.state;
|
1842
2056
|
const { id, model } = ctx.params;
|
1843
|
-
const documentManager2 = getService$
|
1844
|
-
const permissionChecker2 = getService$
|
2057
|
+
const documentManager2 = getService$2("document-manager");
|
2058
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1845
2059
|
if (permissionChecker2.cannot.delete()) {
|
1846
2060
|
return ctx.forbidden();
|
1847
2061
|
}
|
1848
2062
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1849
|
-
const populate = await getService$
|
1850
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2063
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2064
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1851
2065
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1852
2066
|
if (documentLocales.length === 0) {
|
1853
2067
|
return ctx.notFound();
|
@@ -1868,19 +2082,42 @@ const collectionTypes = {
|
|
1868
2082
|
const { userAbility } = ctx.state;
|
1869
2083
|
const { id, model } = ctx.params;
|
1870
2084
|
const { body } = ctx.request;
|
1871
|
-
const documentManager2 = getService$
|
1872
|
-
const permissionChecker2 = getService$
|
2085
|
+
const documentManager2 = getService$2("document-manager");
|
2086
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1873
2087
|
if (permissionChecker2.cannot.publish()) {
|
1874
2088
|
return ctx.forbidden();
|
1875
2089
|
}
|
1876
2090
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1877
2091
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1878
|
-
const populate = await getService$
|
1879
|
-
|
2092
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2093
|
+
let document;
|
2094
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2095
|
+
const isCreate = fp.isNil(id);
|
2096
|
+
if (isCreate) {
|
2097
|
+
if (permissionChecker2.cannot.create()) {
|
2098
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2099
|
+
}
|
2100
|
+
document = await createDocument(ctx, { populate });
|
2101
|
+
}
|
2102
|
+
const isUpdate = !isCreate;
|
2103
|
+
if (isUpdate) {
|
2104
|
+
const documentExists = documentManager2.exists(model, id);
|
2105
|
+
if (!documentExists) {
|
2106
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2107
|
+
}
|
2108
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2109
|
+
if (!document) {
|
2110
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2111
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2112
|
+
}
|
2113
|
+
document = await updateDocument(ctx);
|
2114
|
+
} else if (permissionChecker2.can.update(document)) {
|
2115
|
+
await updateDocument(ctx);
|
2116
|
+
}
|
2117
|
+
}
|
1880
2118
|
if (permissionChecker2.cannot.publish(document)) {
|
1881
2119
|
throw new strapiUtils.errors.ForbiddenError();
|
1882
2120
|
}
|
1883
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1884
2121
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1885
2122
|
locale
|
1886
2123
|
// TODO: Allow setting creator fields on publish
|
@@ -1900,14 +2137,16 @@ const collectionTypes = {
|
|
1900
2137
|
const { body } = ctx.request;
|
1901
2138
|
const { documentIds } = body;
|
1902
2139
|
await validateBulkActionInput(body);
|
1903
|
-
const documentManager2 = getService$
|
1904
|
-
const permissionChecker2 = getService$
|
2140
|
+
const documentManager2 = getService$2("document-manager");
|
2141
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1905
2142
|
if (permissionChecker2.cannot.publish()) {
|
1906
2143
|
return ctx.forbidden();
|
1907
2144
|
}
|
1908
2145
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1909
|
-
const populate = await getService$
|
1910
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2146
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2147
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2148
|
+
allowMultipleLocales: true
|
2149
|
+
});
|
1911
2150
|
const entityPromises = documentIds.map(
|
1912
2151
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1913
2152
|
);
|
@@ -1929,12 +2168,14 @@ const collectionTypes = {
|
|
1929
2168
|
const { body } = ctx.request;
|
1930
2169
|
const { documentIds } = body;
|
1931
2170
|
await validateBulkActionInput(body);
|
1932
|
-
const documentManager2 = getService$
|
1933
|
-
const permissionChecker2 = getService$
|
2171
|
+
const documentManager2 = getService$2("document-manager");
|
2172
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1934
2173
|
if (permissionChecker2.cannot.unpublish()) {
|
1935
2174
|
return ctx.forbidden();
|
1936
2175
|
}
|
1937
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2176
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2177
|
+
allowMultipleLocales: true
|
2178
|
+
});
|
1938
2179
|
const entityPromises = documentIds.map(
|
1939
2180
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1940
2181
|
);
|
@@ -1957,8 +2198,8 @@ const collectionTypes = {
|
|
1957
2198
|
const {
|
1958
2199
|
body: { discardDraft, ...body }
|
1959
2200
|
} = ctx.request;
|
1960
|
-
const documentManager2 = getService$
|
1961
|
-
const permissionChecker2 = getService$
|
2201
|
+
const documentManager2 = getService$2("document-manager");
|
2202
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1962
2203
|
if (permissionChecker2.cannot.unpublish()) {
|
1963
2204
|
return ctx.forbidden();
|
1964
2205
|
}
|
@@ -1966,8 +2207,8 @@ const collectionTypes = {
|
|
1966
2207
|
return ctx.forbidden();
|
1967
2208
|
}
|
1968
2209
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1969
|
-
const populate = await getService$
|
1970
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2210
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2211
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1971
2212
|
const document = await documentManager2.findOne(id, model, {
|
1972
2213
|
populate,
|
1973
2214
|
locale,
|
@@ -1997,14 +2238,14 @@ const collectionTypes = {
|
|
1997
2238
|
const { userAbility } = ctx.state;
|
1998
2239
|
const { id, model } = ctx.params;
|
1999
2240
|
const { body } = ctx.request;
|
2000
|
-
const documentManager2 = getService$
|
2001
|
-
const permissionChecker2 = getService$
|
2241
|
+
const documentManager2 = getService$2("document-manager");
|
2242
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2002
2243
|
if (permissionChecker2.cannot.discard()) {
|
2003
2244
|
return ctx.forbidden();
|
2004
2245
|
}
|
2005
2246
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2006
|
-
const populate = await getService$
|
2007
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2247
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2248
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2008
2249
|
const document = await documentManager2.findOne(id, model, {
|
2009
2250
|
populate,
|
2010
2251
|
locale,
|
@@ -2028,14 +2269,14 @@ const collectionTypes = {
|
|
2028
2269
|
const { query, body } = ctx.request;
|
2029
2270
|
const { documentIds } = body;
|
2030
2271
|
await validateBulkActionInput(body);
|
2031
|
-
const documentManager2 = getService$
|
2032
|
-
const permissionChecker2 = getService$
|
2272
|
+
const documentManager2 = getService$2("document-manager");
|
2273
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2033
2274
|
if (permissionChecker2.cannot.delete()) {
|
2034
2275
|
return ctx.forbidden();
|
2035
2276
|
}
|
2036
2277
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2037
|
-
const populate = await getService$
|
2038
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2278
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2279
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2039
2280
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2040
2281
|
populate,
|
2041
2282
|
locale
|
@@ -2055,14 +2296,14 @@ const collectionTypes = {
|
|
2055
2296
|
async countDraftRelations(ctx) {
|
2056
2297
|
const { userAbility } = ctx.state;
|
2057
2298
|
const { model, id } = ctx.params;
|
2058
|
-
const documentManager2 = getService$
|
2059
|
-
const permissionChecker2 = getService$
|
2299
|
+
const documentManager2 = getService$2("document-manager");
|
2300
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2060
2301
|
if (permissionChecker2.cannot.read()) {
|
2061
2302
|
return ctx.forbidden();
|
2062
2303
|
}
|
2063
2304
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2064
|
-
const populate = await getService$
|
2065
|
-
const { locale, status
|
2305
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2306
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2066
2307
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2067
2308
|
if (!entity) {
|
2068
2309
|
return ctx.notFound();
|
@@ -2080,12 +2321,12 @@ const collectionTypes = {
|
|
2080
2321
|
const ids = ctx.request.query.documentIds;
|
2081
2322
|
const locale = ctx.request.query.locale;
|
2082
2323
|
const { model } = ctx.params;
|
2083
|
-
const documentManager2 = getService$
|
2084
|
-
const permissionChecker2 = getService$
|
2324
|
+
const documentManager2 = getService$2("document-manager");
|
2325
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2085
2326
|
if (permissionChecker2.cannot.read()) {
|
2086
2327
|
return ctx.forbidden();
|
2087
2328
|
}
|
2088
|
-
const
|
2329
|
+
const documents = await documentManager2.findMany(
|
2089
2330
|
{
|
2090
2331
|
filters: {
|
2091
2332
|
documentId: ids
|
@@ -2094,7 +2335,7 @@ const collectionTypes = {
|
|
2094
2335
|
},
|
2095
2336
|
model
|
2096
2337
|
);
|
2097
|
-
if (!
|
2338
|
+
if (!documents) {
|
2098
2339
|
return ctx.notFound();
|
2099
2340
|
}
|
2100
2341
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2105,13 +2346,13 @@ const collectionTypes = {
|
|
2105
2346
|
};
|
2106
2347
|
const components$1 = {
|
2107
2348
|
findComponents(ctx) {
|
2108
|
-
const components2 = getService$
|
2109
|
-
const { toDto } = getService$
|
2349
|
+
const components2 = getService$2("components").findAllComponents();
|
2350
|
+
const { toDto } = getService$2("data-mapper");
|
2110
2351
|
ctx.body = { data: components2.map(toDto) };
|
2111
2352
|
},
|
2112
2353
|
async findComponentConfiguration(ctx) {
|
2113
2354
|
const { uid: uid2 } = ctx.params;
|
2114
|
-
const componentService = getService$
|
2355
|
+
const componentService = getService$2("components");
|
2115
2356
|
const component = componentService.findComponent(uid2);
|
2116
2357
|
if (!component) {
|
2117
2358
|
return ctx.notFound("component.notFound");
|
@@ -2128,7 +2369,7 @@ const components$1 = {
|
|
2128
2369
|
async updateComponentConfiguration(ctx) {
|
2129
2370
|
const { uid: uid2 } = ctx.params;
|
2130
2371
|
const { body } = ctx.request;
|
2131
|
-
const componentService = getService$
|
2372
|
+
const componentService = getService$2("components");
|
2132
2373
|
const component = componentService.findComponent(uid2);
|
2133
2374
|
if (!component) {
|
2134
2375
|
return ctx.notFound("component.notFound");
|
@@ -2162,12 +2403,12 @@ const contentTypes = {
|
|
2162
2403
|
} catch (error) {
|
2163
2404
|
return ctx.send({ error }, 400);
|
2164
2405
|
}
|
2165
|
-
const contentTypes2 = getService$
|
2166
|
-
const { toDto } = getService$
|
2406
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2407
|
+
const { toDto } = getService$2("data-mapper");
|
2167
2408
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2168
2409
|
},
|
2169
2410
|
async findContentTypesSettings(ctx) {
|
2170
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2411
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2171
2412
|
const contentTypes2 = await findAllContentTypes();
|
2172
2413
|
const configurations = await Promise.all(
|
2173
2414
|
contentTypes2.map(async (contentType) => {
|
@@ -2181,7 +2422,7 @@ const contentTypes = {
|
|
2181
2422
|
},
|
2182
2423
|
async findContentTypeConfiguration(ctx) {
|
2183
2424
|
const { uid: uid2 } = ctx.params;
|
2184
|
-
const contentTypeService = getService$
|
2425
|
+
const contentTypeService = getService$2("content-types");
|
2185
2426
|
const contentType = await contentTypeService.findContentType(uid2);
|
2186
2427
|
if (!contentType) {
|
2187
2428
|
return ctx.notFound("contentType.notFound");
|
@@ -2203,13 +2444,13 @@ const contentTypes = {
|
|
2203
2444
|
const { userAbility } = ctx.state;
|
2204
2445
|
const { uid: uid2 } = ctx.params;
|
2205
2446
|
const { body } = ctx.request;
|
2206
|
-
const contentTypeService = getService$
|
2207
|
-
const metricsService = getService$
|
2447
|
+
const contentTypeService = getService$2("content-types");
|
2448
|
+
const metricsService = getService$2("metrics");
|
2208
2449
|
const contentType = await contentTypeService.findContentType(uid2);
|
2209
2450
|
if (!contentType) {
|
2210
2451
|
return ctx.notFound("contentType.notFound");
|
2211
2452
|
}
|
2212
|
-
if (!getService$
|
2453
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2213
2454
|
return ctx.forbidden();
|
2214
2455
|
}
|
2215
2456
|
let input;
|
@@ -2242,10 +2483,10 @@ const contentTypes = {
|
|
2242
2483
|
};
|
2243
2484
|
const init = {
|
2244
2485
|
getInitData(ctx) {
|
2245
|
-
const { toDto } = getService$
|
2246
|
-
const { findAllComponents } = getService$
|
2247
|
-
const { getAllFieldSizes } = getService$
|
2248
|
-
const { findAllContentTypes } = getService$
|
2486
|
+
const { toDto } = getService$2("data-mapper");
|
2487
|
+
const { findAllComponents } = getService$2("components");
|
2488
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2489
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2249
2490
|
ctx.body = {
|
2250
2491
|
data: {
|
2251
2492
|
fieldSizes: getAllFieldSizes(),
|
@@ -2281,36 +2522,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2281
2522
|
params.filters.$and.push(filtersClause);
|
2282
2523
|
};
|
2283
2524
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2284
|
-
const permissionChecker2 = getService$
|
2525
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2285
2526
|
userAbility,
|
2286
2527
|
model: model.uid
|
2287
2528
|
});
|
2288
|
-
|
2529
|
+
const isMainFieldListable = isListable(model, mainField);
|
2530
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2531
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2289
2532
|
return "id";
|
2290
2533
|
}
|
2291
|
-
if (
|
2292
|
-
|
2293
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2294
|
-
userAbility,
|
2295
|
-
model: "plugin::users-permissions.user"
|
2296
|
-
});
|
2297
|
-
if (userPermissionChecker.can.read()) {
|
2298
|
-
return "name";
|
2299
|
-
}
|
2300
|
-
}
|
2301
|
-
return "id";
|
2534
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2535
|
+
return "name";
|
2302
2536
|
}
|
2303
2537
|
return mainField;
|
2304
2538
|
};
|
2305
|
-
const addStatusToRelations = async (
|
2306
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2539
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2540
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2307
2541
|
return relations2;
|
2308
2542
|
}
|
2309
|
-
const documentMetadata2 = getService$
|
2310
|
-
|
2543
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2544
|
+
if (!relations2.length) {
|
2545
|
+
return relations2;
|
2546
|
+
}
|
2547
|
+
const firstRelation = relations2[0];
|
2548
|
+
const filters = {
|
2549
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2550
|
+
// NOTE: find the "opposite" status
|
2551
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2552
|
+
};
|
2553
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2554
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2555
|
+
filters
|
2556
|
+
});
|
2311
2557
|
return relations2.map((relation) => {
|
2312
|
-
const availableStatuses =
|
2313
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2558
|
+
const availableStatuses = availableStatus.filter(
|
2559
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2314
2560
|
);
|
2315
2561
|
return {
|
2316
2562
|
...relation,
|
@@ -2331,11 +2577,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2331
2577
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2332
2578
|
const isSourceLocalized = isLocalized(sourceModel);
|
2333
2579
|
const isTargetLocalized = isLocalized(targetModel);
|
2334
|
-
let validatedLocale = locale;
|
2335
|
-
if (!targetModel || !isTargetLocalized)
|
2336
|
-
validatedLocale = void 0;
|
2337
2580
|
return {
|
2338
|
-
locale
|
2581
|
+
locale,
|
2339
2582
|
isSourceLocalized,
|
2340
2583
|
isTargetLocalized
|
2341
2584
|
};
|
@@ -2375,7 +2618,7 @@ const relations = {
|
|
2375
2618
|
ctx.request?.query?.locale
|
2376
2619
|
);
|
2377
2620
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2378
|
-
const permissionChecker2 = getService$
|
2621
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2379
2622
|
userAbility,
|
2380
2623
|
model
|
2381
2624
|
});
|
@@ -2400,7 +2643,7 @@ const relations = {
|
|
2400
2643
|
where.id = id;
|
2401
2644
|
}
|
2402
2645
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2403
|
-
const populate = await getService$
|
2646
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2404
2647
|
const currentEntity = await strapi.db.query(model).findOne({
|
2405
2648
|
where,
|
2406
2649
|
populate
|
@@ -2415,7 +2658,7 @@ const relations = {
|
|
2415
2658
|
}
|
2416
2659
|
entryId = currentEntity.id;
|
2417
2660
|
}
|
2418
|
-
const modelConfig = isComponent2 ? await getService$
|
2661
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2419
2662
|
const targetSchema = strapi.getModel(targetUid);
|
2420
2663
|
const mainField = fp.flow(
|
2421
2664
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2438,7 +2681,7 @@ const relations = {
|
|
2438
2681
|
attribute,
|
2439
2682
|
fieldsToSelect,
|
2440
2683
|
mainField,
|
2441
|
-
source: { schema: sourceSchema },
|
2684
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2442
2685
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2443
2686
|
sourceSchema,
|
2444
2687
|
targetSchema,
|
@@ -2460,7 +2703,8 @@ const relations = {
|
|
2460
2703
|
fieldsToSelect,
|
2461
2704
|
mainField,
|
2462
2705
|
source: {
|
2463
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2706
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2707
|
+
isLocalized: isSourceLocalized
|
2464
2708
|
},
|
2465
2709
|
target: {
|
2466
2710
|
schema: { uid: targetUid },
|
@@ -2468,7 +2712,7 @@ const relations = {
|
|
2468
2712
|
}
|
2469
2713
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2470
2714
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2471
|
-
const permissionChecker2 = getService$
|
2715
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2472
2716
|
userAbility: ctx.state.userAbility,
|
2473
2717
|
model: targetUid
|
2474
2718
|
});
|
@@ -2498,12 +2742,16 @@ const relations = {
|
|
2498
2742
|
} else {
|
2499
2743
|
where.id = id;
|
2500
2744
|
}
|
2501
|
-
|
2502
|
-
|
2745
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2746
|
+
if (!fp.isEmpty(publishedAt)) {
|
2747
|
+
where[`${alias}.published_at`] = publishedAt;
|
2503
2748
|
}
|
2504
|
-
if (
|
2749
|
+
if (isTargetLocalized && locale) {
|
2505
2750
|
where[`${alias}.locale`] = locale;
|
2506
2751
|
}
|
2752
|
+
if (isSourceLocalized && locale) {
|
2753
|
+
where.locale = locale;
|
2754
|
+
}
|
2507
2755
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2508
2756
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2509
2757
|
}
|
@@ -2521,7 +2769,8 @@ const relations = {
|
|
2521
2769
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2522
2770
|
});
|
2523
2771
|
}
|
2524
|
-
const
|
2772
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2773
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2525
2774
|
ctx.body = {
|
2526
2775
|
...res,
|
2527
2776
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2536,29 +2785,39 @@ const relations = {
|
|
2536
2785
|
attribute,
|
2537
2786
|
targetField,
|
2538
2787
|
fieldsToSelect,
|
2539
|
-
|
2540
|
-
|
2541
|
-
}
|
2542
|
-
target: {
|
2543
|
-
schema: { uid: targetUid }
|
2544
|
-
}
|
2788
|
+
status,
|
2789
|
+
source: { schema: sourceSchema },
|
2790
|
+
target: { schema: targetSchema }
|
2545
2791
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2546
|
-
const
|
2792
|
+
const { uid: sourceUid } = sourceSchema;
|
2793
|
+
const { uid: targetUid } = targetSchema;
|
2794
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2547
2795
|
const dbQuery = strapi.db.query(sourceUid);
|
2548
2796
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2797
|
+
const filters = {};
|
2798
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2799
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2800
|
+
if (status === "published") {
|
2801
|
+
filters.publishedAt = { $notNull: true };
|
2802
|
+
} else {
|
2803
|
+
filters.publishedAt = { $null: true };
|
2804
|
+
}
|
2805
|
+
}
|
2806
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2807
|
+
filters.publishedAt = { $null: true };
|
2808
|
+
}
|
2549
2809
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2550
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2810
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2551
2811
|
ordering: "desc",
|
2552
2812
|
page: ctx.request.query.page,
|
2553
|
-
pageSize: ctx.request.query.pageSize
|
2813
|
+
pageSize: ctx.request.query.pageSize,
|
2814
|
+
filters
|
2554
2815
|
});
|
2555
2816
|
const loadedIds = res.results.map((item) => item.id);
|
2556
2817
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2557
2818
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2558
2819
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2559
|
-
ordering: "desc"
|
2560
|
-
page: ctx.request.query.page,
|
2561
|
-
pageSize: ctx.request.query.pageSize
|
2820
|
+
ordering: "desc"
|
2562
2821
|
});
|
2563
2822
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2564
2823
|
ctx.body = {
|
@@ -2573,10 +2832,10 @@ const relations = {
|
|
2573
2832
|
}
|
2574
2833
|
};
|
2575
2834
|
const buildPopulateFromQuery = async (query, model) => {
|
2576
|
-
return getService$
|
2835
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2577
2836
|
};
|
2578
2837
|
const findDocument = async (query, uid2, opts = {}) => {
|
2579
|
-
const documentManager2 = getService$
|
2838
|
+
const documentManager2 = getService$2("document-manager");
|
2580
2839
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2581
2840
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2582
2841
|
};
|
@@ -2584,13 +2843,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2584
2843
|
const { user, userAbility } = ctx.state;
|
2585
2844
|
const { model } = ctx.params;
|
2586
2845
|
const { body, query } = ctx.request;
|
2587
|
-
const documentManager2 = getService$
|
2588
|
-
const permissionChecker2 = getService$
|
2846
|
+
const documentManager2 = getService$2("document-manager");
|
2847
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2589
2848
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2590
2849
|
throw new strapiUtils.errors.ForbiddenError();
|
2591
2850
|
}
|
2592
2851
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2593
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2852
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2594
2853
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2595
2854
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2596
2855
|
// Find the first document to check if it exists
|
@@ -2626,12 +2885,12 @@ const singleTypes = {
|
|
2626
2885
|
const { userAbility } = ctx.state;
|
2627
2886
|
const { model } = ctx.params;
|
2628
2887
|
const { query = {} } = ctx.request;
|
2629
|
-
const permissionChecker2 = getService$
|
2888
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2630
2889
|
if (permissionChecker2.cannot.read()) {
|
2631
2890
|
return ctx.forbidden();
|
2632
2891
|
}
|
2633
2892
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2634
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2893
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2635
2894
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2636
2895
|
if (!version) {
|
2637
2896
|
if (permissionChecker2.cannot.create()) {
|
@@ -2645,7 +2904,7 @@ const singleTypes = {
|
|
2645
2904
|
permissionChecker2,
|
2646
2905
|
model,
|
2647
2906
|
// @ts-expect-error - fix types
|
2648
|
-
{
|
2907
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2649
2908
|
{ availableLocales: true, availableStatus: false }
|
2650
2909
|
);
|
2651
2910
|
ctx.body = { data: {}, meta };
|
@@ -2660,7 +2919,7 @@ const singleTypes = {
|
|
2660
2919
|
async createOrUpdate(ctx) {
|
2661
2920
|
const { userAbility } = ctx.state;
|
2662
2921
|
const { model } = ctx.params;
|
2663
|
-
const permissionChecker2 = getService$
|
2922
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2664
2923
|
const document = await createOrUpdateDocument(ctx);
|
2665
2924
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2666
2925
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2669,14 +2928,14 @@ const singleTypes = {
|
|
2669
2928
|
const { userAbility } = ctx.state;
|
2670
2929
|
const { model } = ctx.params;
|
2671
2930
|
const { query = {} } = ctx.request;
|
2672
|
-
const documentManager2 = getService$
|
2673
|
-
const permissionChecker2 = getService$
|
2931
|
+
const documentManager2 = getService$2("document-manager");
|
2932
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2674
2933
|
if (permissionChecker2.cannot.delete()) {
|
2675
2934
|
return ctx.forbidden();
|
2676
2935
|
}
|
2677
2936
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2678
2937
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2679
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2938
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2680
2939
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2681
2940
|
populate,
|
2682
2941
|
locale
|
@@ -2698,8 +2957,8 @@ const singleTypes = {
|
|
2698
2957
|
const { userAbility } = ctx.state;
|
2699
2958
|
const { model } = ctx.params;
|
2700
2959
|
const { query = {} } = ctx.request;
|
2701
|
-
const documentManager2 = getService$
|
2702
|
-
const permissionChecker2 = getService$
|
2960
|
+
const documentManager2 = getService$2("document-manager");
|
2961
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2703
2962
|
if (permissionChecker2.cannot.publish()) {
|
2704
2963
|
return ctx.forbidden();
|
2705
2964
|
}
|
@@ -2713,7 +2972,7 @@ const singleTypes = {
|
|
2713
2972
|
if (permissionChecker2.cannot.publish(document)) {
|
2714
2973
|
throw new strapiUtils.errors.ForbiddenError();
|
2715
2974
|
}
|
2716
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2975
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2717
2976
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2718
2977
|
return publishResult.at(0);
|
2719
2978
|
});
|
@@ -2727,8 +2986,8 @@ const singleTypes = {
|
|
2727
2986
|
body: { discardDraft, ...body },
|
2728
2987
|
query = {}
|
2729
2988
|
} = ctx.request;
|
2730
|
-
const documentManager2 = getService$
|
2731
|
-
const permissionChecker2 = getService$
|
2989
|
+
const documentManager2 = getService$2("document-manager");
|
2990
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2732
2991
|
if (permissionChecker2.cannot.unpublish()) {
|
2733
2992
|
return ctx.forbidden();
|
2734
2993
|
}
|
@@ -2736,7 +2995,7 @@ const singleTypes = {
|
|
2736
2995
|
return ctx.forbidden();
|
2737
2996
|
}
|
2738
2997
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2739
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2998
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2740
2999
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2741
3000
|
if (!document) {
|
2742
3001
|
return ctx.notFound();
|
@@ -2762,13 +3021,13 @@ const singleTypes = {
|
|
2762
3021
|
const { userAbility } = ctx.state;
|
2763
3022
|
const { model } = ctx.params;
|
2764
3023
|
const { body, query = {} } = ctx.request;
|
2765
|
-
const documentManager2 = getService$
|
2766
|
-
const permissionChecker2 = getService$
|
3024
|
+
const documentManager2 = getService$2("document-manager");
|
3025
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2767
3026
|
if (permissionChecker2.cannot.discard()) {
|
2768
3027
|
return ctx.forbidden();
|
2769
3028
|
}
|
2770
3029
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2771
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3030
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2772
3031
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2773
3032
|
if (!document) {
|
2774
3033
|
return ctx.notFound();
|
@@ -2786,9 +3045,9 @@ const singleTypes = {
|
|
2786
3045
|
const { userAbility } = ctx.state;
|
2787
3046
|
const { model } = ctx.params;
|
2788
3047
|
const { query } = ctx.request;
|
2789
|
-
const documentManager2 = getService$
|
2790
|
-
const permissionChecker2 = getService$
|
2791
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3048
|
+
const documentManager2 = getService$2("document-manager");
|
3049
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3050
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2792
3051
|
if (permissionChecker2.cannot.read()) {
|
2793
3052
|
return ctx.forbidden();
|
2794
3053
|
}
|
@@ -2809,9 +3068,9 @@ const uid$1 = {
|
|
2809
3068
|
async generateUID(ctx) {
|
2810
3069
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2811
3070
|
const { query = {} } = ctx.request;
|
2812
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3071
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2813
3072
|
await validateUIDField(contentTypeUID, field);
|
2814
|
-
const uidService = getService$
|
3073
|
+
const uidService = getService$2("uid");
|
2815
3074
|
ctx.body = {
|
2816
3075
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2817
3076
|
};
|
@@ -2821,9 +3080,9 @@ const uid$1 = {
|
|
2821
3080
|
ctx.request.body
|
2822
3081
|
);
|
2823
3082
|
const { query = {} } = ctx.request;
|
2824
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3083
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2825
3084
|
await validateUIDField(contentTypeUID, field);
|
2826
|
-
const uidService = getService$
|
3085
|
+
const uidService = getService$2("uid");
|
2827
3086
|
const isAvailable = await uidService.checkUIDAvailability({
|
2828
3087
|
contentTypeUID,
|
2829
3088
|
field,
|
@@ -2844,7 +3103,8 @@ const controllers = {
|
|
2844
3103
|
relations,
|
2845
3104
|
"single-types": singleTypes,
|
2846
3105
|
uid: uid$1,
|
2847
|
-
...history.controllers ? history.controllers : {}
|
3106
|
+
...history.controllers ? history.controllers : {},
|
3107
|
+
...preview.controllers ? preview.controllers : {}
|
2848
3108
|
};
|
2849
3109
|
const keys = {
|
2850
3110
|
CONFIGURATION: "configuration"
|
@@ -2995,12 +3255,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2995
3255
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
2996
3256
|
}
|
2997
3257
|
const getTargetSchema = (targetModel) => {
|
2998
|
-
return getService$
|
3258
|
+
return getService$2("content-types").findContentType(targetModel);
|
2999
3259
|
};
|
3000
3260
|
const DEFAULT_LIST_LENGTH = 4;
|
3001
3261
|
const MAX_ROW_SIZE = 12;
|
3002
3262
|
const isAllowedFieldSize = (type, size) => {
|
3003
|
-
const { getFieldSize } = getService$
|
3263
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3004
3264
|
const fieldSize = getFieldSize(type);
|
3005
3265
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3006
3266
|
return false;
|
@@ -3008,7 +3268,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3008
3268
|
return size <= MAX_ROW_SIZE;
|
3009
3269
|
};
|
3010
3270
|
const getDefaultFieldSize = (attribute) => {
|
3011
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3271
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3012
3272
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3013
3273
|
};
|
3014
3274
|
async function createDefaultLayouts(schema) {
|
@@ -3043,7 +3303,7 @@ function syncLayouts(configuration, schema) {
|
|
3043
3303
|
for (const el of row) {
|
3044
3304
|
if (!hasEditableAttribute(schema, el.name))
|
3045
3305
|
continue;
|
3046
|
-
const { hasFieldSize } = getService$
|
3306
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3047
3307
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3048
3308
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3049
3309
|
elementsToReAppend.push(el.name);
|
@@ -3183,17 +3443,17 @@ const configurationService$1 = createConfigurationService({
|
|
3183
3443
|
isComponent: true,
|
3184
3444
|
prefix: STORE_KEY_PREFIX,
|
3185
3445
|
getModels() {
|
3186
|
-
const { toContentManagerModel } = getService$
|
3446
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3187
3447
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3188
3448
|
}
|
3189
3449
|
});
|
3190
3450
|
const components = ({ strapi: strapi2 }) => ({
|
3191
3451
|
findAllComponents() {
|
3192
|
-
const { toContentManagerModel } = getService$
|
3452
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3193
3453
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3194
3454
|
},
|
3195
3455
|
findComponent(uid2) {
|
3196
|
-
const { toContentManagerModel } = getService$
|
3456
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3197
3457
|
const component = strapi2.components[uid2];
|
3198
3458
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3199
3459
|
},
|
@@ -3244,17 +3504,17 @@ const configurationService = createConfigurationService({
|
|
3244
3504
|
storeUtils,
|
3245
3505
|
prefix: "content_types",
|
3246
3506
|
getModels() {
|
3247
|
-
const { toContentManagerModel } = getService$
|
3507
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3248
3508
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3249
3509
|
}
|
3250
3510
|
});
|
3251
3511
|
const service = ({ strapi: strapi2 }) => ({
|
3252
3512
|
findAllContentTypes() {
|
3253
|
-
const { toContentManagerModel } = getService$
|
3513
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3254
3514
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3255
3515
|
},
|
3256
3516
|
findContentType(uid2) {
|
3257
|
-
const { toContentManagerModel } = getService$
|
3517
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3258
3518
|
const contentType = strapi2.contentTypes[uid2];
|
3259
3519
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3260
3520
|
},
|
@@ -3283,7 +3543,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3283
3543
|
return this.findConfiguration(contentType);
|
3284
3544
|
},
|
3285
3545
|
findComponentsConfigurations(contentType) {
|
3286
|
-
return getService$
|
3546
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3287
3547
|
},
|
3288
3548
|
syncConfigurations() {
|
3289
3549
|
return configurationService.syncConfigurations();
|
@@ -3464,12 +3724,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3464
3724
|
ability: userAbility,
|
3465
3725
|
model
|
3466
3726
|
});
|
3467
|
-
const
|
3727
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3728
|
+
const toSubject = (entity) => {
|
3729
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3730
|
+
};
|
3468
3731
|
const can = (action, entity, field) => {
|
3469
|
-
|
3732
|
+
const subject = toSubject(entity);
|
3733
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3734
|
+
return (
|
3735
|
+
// Test the original action to see if it passes
|
3736
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3737
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3738
|
+
);
|
3470
3739
|
};
|
3471
3740
|
const cannot = (action, entity, field) => {
|
3472
|
-
|
3741
|
+
const subject = toSubject(entity);
|
3742
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3743
|
+
return (
|
3744
|
+
// Test both the original action
|
3745
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3746
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3747
|
+
);
|
3473
3748
|
};
|
3474
3749
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3475
3750
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3540,7 +3815,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3540
3815
|
return userAbility.can(action);
|
3541
3816
|
},
|
3542
3817
|
async registerPermissions() {
|
3543
|
-
const displayedContentTypes = getService$
|
3818
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3544
3819
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3545
3820
|
const actions = [
|
3546
3821
|
{
|
@@ -3746,6 +4021,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3746
4021
|
const attribute = model.attributes[attributeName];
|
3747
4022
|
switch (attribute.type) {
|
3748
4023
|
case "relation": {
|
4024
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4025
|
+
if (isMorphRelation) {
|
4026
|
+
break;
|
4027
|
+
}
|
3749
4028
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3750
4029
|
populateAcc[attributeName] = {
|
3751
4030
|
count: true,
|
@@ -3812,7 +4091,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3812
4091
|
return populateQuery;
|
3813
4092
|
};
|
3814
4093
|
const buildDeepPopulate = (uid2) => {
|
3815
|
-
return getService$
|
4094
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3816
4095
|
};
|
3817
4096
|
const populateBuilder = (uid2) => {
|
3818
4097
|
let getInitialPopulate = async () => {
|
@@ -3997,7 +4276,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3997
4276
|
*/
|
3998
4277
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3999
4278
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
4000
|
-
|
4279
|
+
if (version.locale) {
|
4280
|
+
delete versionsByLocale[version.locale];
|
4281
|
+
}
|
4001
4282
|
const model = strapi2.getModel(uid2);
|
4002
4283
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4003
4284
|
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
@@ -4123,7 +4404,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4123
4404
|
*/
|
4124
4405
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4125
4406
|
if (!document) {
|
4126
|
-
return
|
4407
|
+
return {
|
4408
|
+
data: document,
|
4409
|
+
meta: {
|
4410
|
+
availableLocales: [],
|
4411
|
+
availableStatus: []
|
4412
|
+
}
|
4413
|
+
};
|
4127
4414
|
}
|
4128
4415
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4129
4416
|
if (!hasDraftAndPublish) {
|
@@ -4231,10 +4518,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4231
4518
|
async clone(id, body, uid2) {
|
4232
4519
|
const populate = await buildDeepPopulate(uid2);
|
4233
4520
|
const params = {
|
4234
|
-
data:
|
4235
|
-
...omitIdField(body),
|
4236
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4237
|
-
},
|
4521
|
+
data: omitIdField(body),
|
4238
4522
|
populate
|
4239
4523
|
};
|
4240
4524
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4350,7 +4634,8 @@ const services = {
|
|
4350
4634
|
permission,
|
4351
4635
|
"populate-builder": populateBuilder$1,
|
4352
4636
|
uid,
|
4353
|
-
...history.services ? history.services : {}
|
4637
|
+
...history.services ? history.services : {},
|
4638
|
+
...preview.services ? preview.services : {}
|
4354
4639
|
};
|
4355
4640
|
const index = () => {
|
4356
4641
|
return {
|