@strapi/content-manager 0.0.0-experimental.3c73a4c6f6073abdf1608121a200c3d4d87b1aa8 → 0.0.0-experimental.438960f273755509510c3610187d9deb520ba2a0
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-BZIaEffq.js → ComponentConfigurationPage-3feZ0gyp.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BZIaEffq.js.map → ComponentConfigurationPage-3feZ0gyp.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-Cxz51Sve.mjs → ComponentConfigurationPage-DkUdgHD9.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-Cxz51Sve.mjs.map → ComponentConfigurationPage-DkUdgHD9.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CM62NN0L.js → EditConfigurationPage-B0KA-x9U.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CM62NN0L.js.map → EditConfigurationPage-B0KA-x9U.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CZLbgfIp.mjs → EditConfigurationPage-Ox5wFgpq.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CZLbgfIp.mjs.map → EditConfigurationPage-Ox5wFgpq.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CU7724gt.js → EditViewPage-OMv9CogC.js} +68 -47
- package/dist/_chunks/EditViewPage-OMv9CogC.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CzuJgWWp.mjs → EditViewPage-foKE8Al3.mjs} +69 -48
- package/dist/_chunks/EditViewPage-foKE8Al3.mjs.map +1 -0
- package/dist/_chunks/{Field-QtUSh5mU.mjs → Field-CLqZcnnc.mjs} +579 -227
- package/dist/_chunks/Field-CLqZcnnc.mjs.map +1 -0
- package/dist/_chunks/{Field-Dh1yZyqy.js → Field-u09MCk3G.js} +581 -229
- package/dist/_chunks/Field-u09MCk3G.js.map +1 -0
- package/dist/_chunks/{Form-BOR8NOe1.js → Form-B9c_Ti0q.js} +52 -34
- package/dist/_chunks/Form-B9c_Ti0q.js.map +1 -0
- package/dist/_chunks/{Form-COLpvlnv.mjs → Form-CU4hRyJf.mjs} +54 -36
- package/dist/_chunks/Form-CU4hRyJf.mjs.map +1 -0
- package/dist/_chunks/{History-Bu53Yfw-.mjs → History-BFyFzpSS.mjs} +159 -42
- package/dist/_chunks/History-BFyFzpSS.mjs.map +1 -0
- package/dist/_chunks/{History-CW2akQ6h.js → History-OlickLyX.js} +158 -41
- package/dist/_chunks/History-OlickLyX.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-TqrmwjPN.mjs → ListConfigurationPage-Bu5Z_39o.mjs} +58 -48
- package/dist/_chunks/ListConfigurationPage-Bu5Z_39o.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-jzdhEk_u.js → ListConfigurationPage-D0AAi_cW.js} +57 -46
- package/dist/_chunks/ListConfigurationPage-D0AAi_cW.js.map +1 -0
- package/dist/_chunks/{ListViewPage-B3bMOrMv.js → ListViewPage--lV5p8Qi.js} +105 -104
- package/dist/_chunks/ListViewPage--lV5p8Qi.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BO_mOXIl.mjs → ListViewPage-BAHxSPux.mjs} +103 -102
- package/dist/_chunks/ListViewPage-BAHxSPux.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DqB0QV0k.mjs → NoContentTypePage-C6SMXW77.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DqB0QV0k.mjs.map → NoContentTypePage-C6SMXW77.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-D77xsNHj.js → NoContentTypePage-Dxl9oZqL.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-D77xsNHj.js.map → NoContentTypePage-Dxl9oZqL.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-C6qTGogm.js → NoPermissionsPage-BY1-rMng.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-C6qTGogm.js.map → NoPermissionsPage-BY1-rMng.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DTXi042N.mjs → NoPermissionsPage-o9BXzQeI.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DTXi042N.mjs.map → NoPermissionsPage-o9BXzQeI.mjs.map} +1 -1
- package/dist/_chunks/{Relations-CJ4qdkRo.mjs → Relations-BAK95JHc.mjs} +33 -24
- package/dist/_chunks/Relations-BAK95JHc.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6fb2POW.js → Relations-CHfwGkBG.js} +33 -24
- package/dist/_chunks/Relations-CHfwGkBG.js.map +1 -0
- package/dist/_chunks/{en-DZXjRiWA.js → en-Bm0D0IWz.js} +19 -15
- package/dist/_chunks/{en-DZXjRiWA.js.map → en-Bm0D0IWz.js.map} +1 -1
- package/dist/_chunks/{en-9GwRW_ku.mjs → en-DKV44jRb.mjs} +19 -15
- package/dist/_chunks/{en-9GwRW_ku.mjs.map → en-DKV44jRb.mjs.map} +1 -1
- package/dist/_chunks/{index-Dahjdw4h.mjs → index-CxlpxzA5.mjs} +1034 -869
- package/dist/_chunks/index-CxlpxzA5.mjs.map +1 -0
- package/dist/_chunks/{index-DcUu-_72.js → index-_Mlmsefd.js} +1024 -859
- package/dist/_chunks/index-_Mlmsefd.js.map +1 -0
- package/dist/_chunks/{layout-omucV6TV.mjs → layout-Cr0H40au.mjs} +27 -14
- package/dist/_chunks/layout-Cr0H40au.mjs.map +1 -0
- package/dist/_chunks/{layout-jcY4dyUG.js → layout-vcHVgSr1.js} +25 -12
- package/dist/_chunks/layout-vcHVgSr1.js.map +1 -0
- package/dist/_chunks/{relations-CN0-aw6p.mjs → relations-Dq60voyX.mjs} +2 -2
- package/dist/_chunks/{relations-CN0-aw6p.mjs.map → relations-Dq60voyX.mjs.map} +1 -1
- package/dist/_chunks/{relations-DGzD7ORa.js → relations-hXUB80SH.js} +2 -2
- package/dist/_chunks/{relations-DGzD7ORa.js.map → relations-hXUB80SH.js.map} +1 -1
- 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/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
- 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 +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/preview/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -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 +223 -122
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +224 -123
- 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/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.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 +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- 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/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.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/package.json +13 -13
- package/dist/_chunks/EditViewPage-CU7724gt.js.map +0 -1
- package/dist/_chunks/EditViewPage-CzuJgWWp.mjs.map +0 -1
- package/dist/_chunks/Field-Dh1yZyqy.js.map +0 -1
- package/dist/_chunks/Field-QtUSh5mU.mjs.map +0 -1
- package/dist/_chunks/Form-BOR8NOe1.js.map +0 -1
- package/dist/_chunks/Form-COLpvlnv.mjs.map +0 -1
- package/dist/_chunks/History-Bu53Yfw-.mjs.map +0 -1
- package/dist/_chunks/History-CW2akQ6h.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-TqrmwjPN.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-jzdhEk_u.js.map +0 -1
- package/dist/_chunks/ListViewPage-B3bMOrMv.js.map +0 -1
- package/dist/_chunks/ListViewPage-BO_mOXIl.mjs.map +0 -1
- package/dist/_chunks/Relations-B6fb2POW.js.map +0 -1
- package/dist/_chunks/Relations-CJ4qdkRo.mjs.map +0 -1
- package/dist/_chunks/index-Dahjdw4h.mjs.map +0 -1
- package/dist/_chunks/index-DcUu-_72.js.map +0 -1
- package/dist/_chunks/layout-jcY4dyUG.js.map +0 -1
- package/dist/_chunks/layout-omucV6TV.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.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,20 +202,25 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const getDeepPopulate2 = (uid2) => {
|
205
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
206
|
const model = strapi2.getModel(uid2);
|
205
207
|
const attributes = Object.entries(model.attributes);
|
208
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
209
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
210
|
switch (attribute.type) {
|
208
211
|
case "relation": {
|
212
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
213
|
+
if (isMorphRelation) {
|
214
|
+
break;
|
215
|
+
}
|
209
216
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
217
|
if (isVisible2) {
|
211
|
-
acc[attributeName] = {
|
218
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
212
219
|
}
|
213
220
|
break;
|
214
221
|
}
|
215
222
|
case "media": {
|
216
|
-
acc[attributeName] = {
|
223
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
217
224
|
break;
|
218
225
|
}
|
219
226
|
case "component": {
|
@@ -286,6 +293,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
286
293
|
getRelationRestoreValue,
|
287
294
|
getMediaRestoreValue,
|
288
295
|
getDefaultLocale,
|
296
|
+
isLocalizedContentType,
|
289
297
|
getLocaleDictionary,
|
290
298
|
getRetentionDays,
|
291
299
|
getVersionStatus,
|
@@ -308,7 +316,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
308
316
|
});
|
309
317
|
},
|
310
318
|
async findVersionsPage(params) {
|
311
|
-
const
|
319
|
+
const model = strapi2.getModel(params.query.contentType);
|
320
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
321
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
322
|
+
let locale = null;
|
323
|
+
if (isLocalizedContentType) {
|
324
|
+
locale = params.query.locale || defaultLocale;
|
325
|
+
}
|
312
326
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
327
|
query.findPage({
|
314
328
|
...params.query,
|
@@ -353,7 +367,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
353
367
|
if (userToPopulate == null) {
|
354
368
|
return null;
|
355
369
|
}
|
356
|
-
return strapi2.query("admin::user").findOne({
|
370
|
+
return strapi2.query("admin::user").findOne({
|
371
|
+
where: {
|
372
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
373
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
374
|
+
}
|
375
|
+
});
|
357
376
|
})
|
358
377
|
);
|
359
378
|
return {
|
@@ -464,13 +483,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
464
483
|
}
|
465
484
|
};
|
466
485
|
};
|
486
|
+
const shouldCreateHistoryVersion = (context) => {
|
487
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
488
|
+
return false;
|
489
|
+
}
|
490
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
491
|
+
return false;
|
492
|
+
}
|
493
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
494
|
+
return false;
|
495
|
+
}
|
496
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
497
|
+
return false;
|
498
|
+
}
|
499
|
+
return true;
|
500
|
+
};
|
501
|
+
const getSchemas = (uid2) => {
|
502
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
503
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
504
|
+
(currentComponentSchemas, key) => {
|
505
|
+
const fieldSchema = attributesSchema[key];
|
506
|
+
if (fieldSchema.type === "component") {
|
507
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
508
|
+
return {
|
509
|
+
...currentComponentSchemas,
|
510
|
+
[fieldSchema.component]: componentSchema
|
511
|
+
};
|
512
|
+
}
|
513
|
+
return currentComponentSchemas;
|
514
|
+
},
|
515
|
+
{}
|
516
|
+
);
|
517
|
+
return {
|
518
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
519
|
+
componentsSchemas
|
520
|
+
};
|
521
|
+
};
|
467
522
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
523
|
const state = {
|
469
524
|
deleteExpiredJob: null,
|
470
525
|
isInitialized: false
|
471
526
|
};
|
472
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
473
|
-
const historyService = getService(strapi2, "history");
|
474
527
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
475
528
|
return {
|
476
529
|
async bootstrap() {
|
@@ -478,60 +531,45 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
478
531
|
return;
|
479
532
|
}
|
480
533
|
strapi2.documents.use(async (context, next) => {
|
481
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
|
-
return next();
|
483
|
-
}
|
484
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
485
|
-
return next();
|
486
|
-
}
|
487
|
-
const contentTypeUid = context.contentType.uid;
|
488
|
-
if (!contentTypeUid.startsWith("api::")) {
|
489
|
-
return next();
|
490
|
-
}
|
491
534
|
const result = await next();
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
535
|
+
if (!shouldCreateHistoryVersion(context)) {
|
536
|
+
return result;
|
537
|
+
}
|
538
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
496
539
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
497
|
-
const
|
498
|
-
if (
|
499
|
-
|
500
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
501
|
-
);
|
502
|
-
return next();
|
540
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
541
|
+
if (!locales.length) {
|
542
|
+
return result;
|
503
543
|
}
|
504
|
-
const
|
505
|
-
|
506
|
-
|
507
|
-
|
544
|
+
const uid2 = context.contentType.uid;
|
545
|
+
const schemas = getSchemas(uid2);
|
546
|
+
const model = strapi2.getModel(uid2);
|
547
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
548
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
549
|
+
where: {
|
550
|
+
documentId,
|
551
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
552
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
553
|
+
},
|
554
|
+
populate: serviceUtils.getDeepPopulate(
|
555
|
+
uid2,
|
556
|
+
true
|
557
|
+
/* use database syntax */
|
558
|
+
)
|
508
559
|
});
|
509
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
510
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
511
|
-
const componentsSchemas = Object.keys(
|
512
|
-
attributesSchema
|
513
|
-
).reduce((currentComponentSchemas, key) => {
|
514
|
-
const fieldSchema = attributesSchema[key];
|
515
|
-
if (fieldSchema.type === "component") {
|
516
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
517
|
-
return {
|
518
|
-
...currentComponentSchemas,
|
519
|
-
[fieldSchema.component]: componentSchema
|
520
|
-
};
|
521
|
-
}
|
522
|
-
return currentComponentSchemas;
|
523
|
-
}, {});
|
524
560
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
525
|
-
onCommit(() => {
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
561
|
+
onCommit(async () => {
|
562
|
+
for (const entry of localeEntries) {
|
563
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
564
|
+
await getService(strapi2, "history").createVersion({
|
565
|
+
contentType: uid2,
|
566
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
567
|
+
relatedDocumentId: documentId,
|
568
|
+
locale: entry.locale,
|
569
|
+
status,
|
570
|
+
...schemas
|
571
|
+
});
|
572
|
+
}
|
535
573
|
});
|
536
574
|
});
|
537
575
|
return result;
|
@@ -539,7 +577,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
539
577
|
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
540
578
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
541
579
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
542
|
-
query.deleteMany({
|
580
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
543
581
|
where: {
|
544
582
|
created_at: {
|
545
583
|
$lt: expirationDate.toISOString()
|
@@ -631,7 +669,7 @@ const historyVersion = {
|
|
631
669
|
}
|
632
670
|
}
|
633
671
|
};
|
634
|
-
const getFeature = () => {
|
672
|
+
const getFeature$1 = () => {
|
635
673
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
636
674
|
return {
|
637
675
|
register({ strapi: strapi2 }) {
|
@@ -654,7 +692,7 @@ const getFeature = () => {
|
|
654
692
|
}
|
655
693
|
};
|
656
694
|
};
|
657
|
-
const history = getFeature();
|
695
|
+
const history = getFeature$1();
|
658
696
|
const register = async ({ strapi: strapi2 }) => {
|
659
697
|
await history.register?.({ strapi: strapi2 });
|
660
698
|
};
|
@@ -662,6 +700,18 @@ const ALLOWED_WEBHOOK_EVENTS = {
|
|
662
700
|
ENTRY_PUBLISH: "entry.publish",
|
663
701
|
ENTRY_UNPUBLISH: "entry.unpublish"
|
664
702
|
};
|
703
|
+
const FEATURE_ID = "preview";
|
704
|
+
const getFeature = () => {
|
705
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
706
|
+
return {};
|
707
|
+
}
|
708
|
+
return {
|
709
|
+
bootstrap() {
|
710
|
+
console.log("Bootstrapping preview server");
|
711
|
+
}
|
712
|
+
};
|
713
|
+
};
|
714
|
+
const preview = getFeature();
|
665
715
|
const bootstrap = async () => {
|
666
716
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
667
717
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
@@ -671,6 +721,7 @@ const bootstrap = async () => {
|
|
671
721
|
await getService$1("content-types").syncConfigurations();
|
672
722
|
await getService$1("permission").registerPermissions();
|
673
723
|
await history.bootstrap?.({ strapi });
|
724
|
+
await preview.bootstrap?.({ strapi });
|
674
725
|
};
|
675
726
|
const destroy = async ({ strapi: strapi2 }) => {
|
676
727
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1171,6 +1222,11 @@ const { createPolicy } = policy;
|
|
1171
1222
|
const hasPermissions = createPolicy({
|
1172
1223
|
name: "plugin::content-manager.hasPermissions",
|
1173
1224
|
validator: validateHasPermissionsInput,
|
1225
|
+
/**
|
1226
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1227
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1228
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1229
|
+
*/
|
1174
1230
|
handler(ctx, config = {}) {
|
1175
1231
|
const { actions = [], hasAtLeastOne = false } = config;
|
1176
1232
|
const { userAbility } = ctx.state;
|
@@ -1564,9 +1620,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1564
1620
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1565
1621
|
);
|
1566
1622
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1567
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1623
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1568
1624
|
const { allowMultipleLocales } = opts;
|
1569
|
-
const { locale, status, ...rest } = request || {};
|
1625
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1626
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1627
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1570
1628
|
const schema = yup$1.object().shape({
|
1571
1629
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1572
1630
|
status: statusSchema
|
@@ -1614,7 +1672,7 @@ const createDocument = async (ctx, opts) => {
|
|
1614
1672
|
const setCreator = setCreatorFields({ user });
|
1615
1673
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1616
1674
|
const sanitizedBody = await sanitizeFn(body);
|
1617
|
-
const { locale, status
|
1675
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1618
1676
|
return documentManager2.create(model, {
|
1619
1677
|
data: sanitizedBody,
|
1620
1678
|
locale,
|
@@ -1633,7 +1691,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1633
1691
|
}
|
1634
1692
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1635
1693
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1636
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1694
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1637
1695
|
const [documentVersion, documentExists] = await Promise.all([
|
1638
1696
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1639
1697
|
documentManager2.exists(model, id)
|
@@ -1649,7 +1707,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1649
1707
|
throw new errors.ForbiddenError();
|
1650
1708
|
}
|
1651
1709
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1652
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1710
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1653
1711
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1654
1712
|
const sanitizedBody = await sanitizeFn(body);
|
1655
1713
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1671,7 +1729,7 @@ const collectionTypes = {
|
|
1671
1729
|
}
|
1672
1730
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1673
1731
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1674
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1732
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1675
1733
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1676
1734
|
{ ...permissionQuery, populate, locale, status },
|
1677
1735
|
model
|
@@ -1706,7 +1764,7 @@ const collectionTypes = {
|
|
1706
1764
|
}
|
1707
1765
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1708
1766
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1709
|
-
const { locale, status
|
1767
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1710
1768
|
const version = await documentManager2.findOne(id, model, {
|
1711
1769
|
populate,
|
1712
1770
|
locale,
|
@@ -1721,7 +1779,7 @@ const collectionTypes = {
|
|
1721
1779
|
permissionChecker2,
|
1722
1780
|
model,
|
1723
1781
|
// @ts-expect-error TODO: fix
|
1724
|
-
{ id, locale, publishedAt: null },
|
1782
|
+
{ documentId: id, locale, publishedAt: null },
|
1725
1783
|
{ availableLocales: true, availableStatus: false }
|
1726
1784
|
);
|
1727
1785
|
ctx.body = { data: {}, meta };
|
@@ -1773,7 +1831,7 @@ const collectionTypes = {
|
|
1773
1831
|
}
|
1774
1832
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1775
1833
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1776
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1834
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1777
1835
|
const document = await documentManager2.findOne(id, model, {
|
1778
1836
|
populate,
|
1779
1837
|
locale,
|
@@ -1818,7 +1876,7 @@ const collectionTypes = {
|
|
1818
1876
|
}
|
1819
1877
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1820
1878
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1821
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1879
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1822
1880
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1823
1881
|
if (documentLocales.length === 0) {
|
1824
1882
|
return ctx.notFound();
|
@@ -1847,11 +1905,34 @@ const collectionTypes = {
|
|
1847
1905
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1848
1906
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1849
1907
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1850
|
-
|
1908
|
+
let document;
|
1909
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1910
|
+
const isCreate = isNil$1(id);
|
1911
|
+
if (isCreate) {
|
1912
|
+
if (permissionChecker2.cannot.create()) {
|
1913
|
+
throw new errors.ForbiddenError();
|
1914
|
+
}
|
1915
|
+
document = await createDocument(ctx, { populate });
|
1916
|
+
}
|
1917
|
+
const isUpdate = !isCreate;
|
1918
|
+
if (isUpdate) {
|
1919
|
+
const documentExists = documentManager2.exists(model, id);
|
1920
|
+
if (!documentExists) {
|
1921
|
+
throw new errors.NotFoundError("Document not found");
|
1922
|
+
}
|
1923
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
1924
|
+
if (!document) {
|
1925
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
1926
|
+
throw new errors.ForbiddenError();
|
1927
|
+
}
|
1928
|
+
document = await updateDocument(ctx);
|
1929
|
+
} else if (permissionChecker2.can.update(document)) {
|
1930
|
+
await updateDocument(ctx);
|
1931
|
+
}
|
1932
|
+
}
|
1851
1933
|
if (permissionChecker2.cannot.publish(document)) {
|
1852
1934
|
throw new errors.ForbiddenError();
|
1853
1935
|
}
|
1854
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1855
1936
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1856
1937
|
locale
|
1857
1938
|
// TODO: Allow setting creator fields on publish
|
@@ -1878,7 +1959,9 @@ const collectionTypes = {
|
|
1878
1959
|
}
|
1879
1960
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1880
1961
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1881
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
1962
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1963
|
+
allowMultipleLocales: true
|
1964
|
+
});
|
1882
1965
|
const entityPromises = documentIds.map(
|
1883
1966
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1884
1967
|
);
|
@@ -1905,7 +1988,9 @@ const collectionTypes = {
|
|
1905
1988
|
if (permissionChecker2.cannot.unpublish()) {
|
1906
1989
|
return ctx.forbidden();
|
1907
1990
|
}
|
1908
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
1991
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1992
|
+
allowMultipleLocales: true
|
1993
|
+
});
|
1909
1994
|
const entityPromises = documentIds.map(
|
1910
1995
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1911
1996
|
);
|
@@ -1938,7 +2023,7 @@ const collectionTypes = {
|
|
1938
2023
|
}
|
1939
2024
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1940
2025
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1941
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2026
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1942
2027
|
const document = await documentManager2.findOne(id, model, {
|
1943
2028
|
populate,
|
1944
2029
|
locale,
|
@@ -1975,7 +2060,7 @@ const collectionTypes = {
|
|
1975
2060
|
}
|
1976
2061
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1977
2062
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1978
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2063
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1979
2064
|
const document = await documentManager2.findOne(id, model, {
|
1980
2065
|
populate,
|
1981
2066
|
locale,
|
@@ -2006,7 +2091,7 @@ const collectionTypes = {
|
|
2006
2091
|
}
|
2007
2092
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2008
2093
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2009
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2094
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2010
2095
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2011
2096
|
populate,
|
2012
2097
|
locale
|
@@ -2033,7 +2118,7 @@ const collectionTypes = {
|
|
2033
2118
|
}
|
2034
2119
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2035
2120
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2036
|
-
const { locale, status
|
2121
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2037
2122
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2038
2123
|
if (!entity) {
|
2039
2124
|
return ctx.notFound();
|
@@ -2056,7 +2141,7 @@ const collectionTypes = {
|
|
2056
2141
|
if (permissionChecker2.cannot.read()) {
|
2057
2142
|
return ctx.forbidden();
|
2058
2143
|
}
|
2059
|
-
const
|
2144
|
+
const documents = await documentManager2.findMany(
|
2060
2145
|
{
|
2061
2146
|
filters: {
|
2062
2147
|
documentId: ids
|
@@ -2065,7 +2150,7 @@ const collectionTypes = {
|
|
2065
2150
|
},
|
2066
2151
|
model
|
2067
2152
|
);
|
2068
|
-
if (!
|
2153
|
+
if (!documents) {
|
2069
2154
|
return ctx.notFound();
|
2070
2155
|
}
|
2071
2156
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2256,20 +2341,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
|
|
2256
2341
|
userAbility,
|
2257
2342
|
model: model.uid
|
2258
2343
|
});
|
2259
|
-
|
2344
|
+
const isMainFieldListable = isListable(model, mainField);
|
2345
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2346
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2260
2347
|
return "id";
|
2261
2348
|
}
|
2262
|
-
if (
|
2263
|
-
|
2264
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2265
|
-
userAbility,
|
2266
|
-
model: "plugin::users-permissions.user"
|
2267
|
-
});
|
2268
|
-
if (userPermissionChecker.can.read()) {
|
2269
|
-
return "name";
|
2270
|
-
}
|
2271
|
-
}
|
2272
|
-
return "id";
|
2349
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2350
|
+
return "name";
|
2273
2351
|
}
|
2274
2352
|
return mainField;
|
2275
2353
|
};
|
@@ -2302,11 +2380,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2302
2380
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2303
2381
|
const isSourceLocalized = isLocalized(sourceModel);
|
2304
2382
|
const isTargetLocalized = isLocalized(targetModel);
|
2305
|
-
let validatedLocale = locale;
|
2306
|
-
if (!targetModel || !isTargetLocalized)
|
2307
|
-
validatedLocale = void 0;
|
2308
2383
|
return {
|
2309
|
-
locale
|
2384
|
+
locale,
|
2310
2385
|
isSourceLocalized,
|
2311
2386
|
isTargetLocalized
|
2312
2387
|
};
|
@@ -2409,7 +2484,7 @@ const relations = {
|
|
2409
2484
|
attribute,
|
2410
2485
|
fieldsToSelect,
|
2411
2486
|
mainField,
|
2412
|
-
source: { schema: sourceSchema },
|
2487
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2413
2488
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2414
2489
|
sourceSchema,
|
2415
2490
|
targetSchema,
|
@@ -2431,7 +2506,8 @@ const relations = {
|
|
2431
2506
|
fieldsToSelect,
|
2432
2507
|
mainField,
|
2433
2508
|
source: {
|
2434
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2509
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2510
|
+
isLocalized: isSourceLocalized
|
2435
2511
|
},
|
2436
2512
|
target: {
|
2437
2513
|
schema: { uid: targetUid },
|
@@ -2469,12 +2545,16 @@ const relations = {
|
|
2469
2545
|
} else {
|
2470
2546
|
where.id = id;
|
2471
2547
|
}
|
2472
|
-
|
2473
|
-
|
2548
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2549
|
+
if (!isEmpty(publishedAt)) {
|
2550
|
+
where[`${alias}.published_at`] = publishedAt;
|
2474
2551
|
}
|
2475
|
-
if (
|
2552
|
+
if (isTargetLocalized && locale) {
|
2476
2553
|
where[`${alias}.locale`] = locale;
|
2477
2554
|
}
|
2555
|
+
if (isSourceLocalized && locale) {
|
2556
|
+
where.locale = locale;
|
2557
|
+
}
|
2478
2558
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2479
2559
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2480
2560
|
}
|
@@ -2492,7 +2572,8 @@ const relations = {
|
|
2492
2572
|
id: { $notIn: uniq(idsToOmit) }
|
2493
2573
|
});
|
2494
2574
|
}
|
2495
|
-
const
|
2575
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2576
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2496
2577
|
ctx.body = {
|
2497
2578
|
...res,
|
2498
2579
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2527,9 +2608,7 @@ const relations = {
|
|
2527
2608
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2528
2609
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2529
2610
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2530
|
-
ordering: "desc"
|
2531
|
-
page: ctx.request.query.page,
|
2532
|
-
pageSize: ctx.request.query.pageSize
|
2611
|
+
ordering: "desc"
|
2533
2612
|
});
|
2534
2613
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2535
2614
|
ctx.body = {
|
@@ -2561,7 +2640,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2561
2640
|
throw new errors.ForbiddenError();
|
2562
2641
|
}
|
2563
2642
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2564
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2643
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2565
2644
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2566
2645
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2567
2646
|
// Find the first document to check if it exists
|
@@ -2602,7 +2681,7 @@ const singleTypes = {
|
|
2602
2681
|
return ctx.forbidden();
|
2603
2682
|
}
|
2604
2683
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2605
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2684
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2606
2685
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2607
2686
|
if (!version) {
|
2608
2687
|
if (permissionChecker2.cannot.create()) {
|
@@ -2616,7 +2695,7 @@ const singleTypes = {
|
|
2616
2695
|
permissionChecker2,
|
2617
2696
|
model,
|
2618
2697
|
// @ts-expect-error - fix types
|
2619
|
-
{
|
2698
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2620
2699
|
{ availableLocales: true, availableStatus: false }
|
2621
2700
|
);
|
2622
2701
|
ctx.body = { data: {}, meta };
|
@@ -2647,7 +2726,7 @@ const singleTypes = {
|
|
2647
2726
|
}
|
2648
2727
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2649
2728
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2650
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2729
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2651
2730
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2652
2731
|
populate,
|
2653
2732
|
locale
|
@@ -2684,7 +2763,7 @@ const singleTypes = {
|
|
2684
2763
|
if (permissionChecker2.cannot.publish(document)) {
|
2685
2764
|
throw new errors.ForbiddenError();
|
2686
2765
|
}
|
2687
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2766
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2688
2767
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2689
2768
|
return publishResult.at(0);
|
2690
2769
|
});
|
@@ -2707,7 +2786,7 @@ const singleTypes = {
|
|
2707
2786
|
return ctx.forbidden();
|
2708
2787
|
}
|
2709
2788
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2710
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2789
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2711
2790
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2712
2791
|
if (!document) {
|
2713
2792
|
return ctx.notFound();
|
@@ -2739,7 +2818,7 @@ const singleTypes = {
|
|
2739
2818
|
return ctx.forbidden();
|
2740
2819
|
}
|
2741
2820
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2742
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2821
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2743
2822
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2744
2823
|
if (!document) {
|
2745
2824
|
return ctx.notFound();
|
@@ -2759,7 +2838,7 @@ const singleTypes = {
|
|
2759
2838
|
const { query } = ctx.request;
|
2760
2839
|
const documentManager2 = getService$1("document-manager");
|
2761
2840
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2762
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2841
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2763
2842
|
if (permissionChecker2.cannot.read()) {
|
2764
2843
|
return ctx.forbidden();
|
2765
2844
|
}
|
@@ -2780,7 +2859,7 @@ const uid$1 = {
|
|
2780
2859
|
async generateUID(ctx) {
|
2781
2860
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2782
2861
|
const { query = {} } = ctx.request;
|
2783
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2862
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2784
2863
|
await validateUIDField(contentTypeUID, field);
|
2785
2864
|
const uidService = getService$1("uid");
|
2786
2865
|
ctx.body = {
|
@@ -2792,7 +2871,7 @@ const uid$1 = {
|
|
2792
2871
|
ctx.request.body
|
2793
2872
|
);
|
2794
2873
|
const { query = {} } = ctx.request;
|
2795
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2874
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2796
2875
|
await validateUIDField(contentTypeUID, field);
|
2797
2876
|
const uidService = getService$1("uid");
|
2798
2877
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3435,12 +3514,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3435
3514
|
ability: userAbility,
|
3436
3515
|
model
|
3437
3516
|
});
|
3438
|
-
const
|
3517
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3518
|
+
const toSubject = (entity) => {
|
3519
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3520
|
+
};
|
3439
3521
|
const can = (action, entity, field) => {
|
3440
|
-
|
3522
|
+
const subject = toSubject(entity);
|
3523
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3524
|
+
return (
|
3525
|
+
// Test the original action to see if it passes
|
3526
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3527
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3528
|
+
);
|
3441
3529
|
};
|
3442
3530
|
const cannot = (action, entity, field) => {
|
3443
|
-
|
3531
|
+
const subject = toSubject(entity);
|
3532
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3533
|
+
return (
|
3534
|
+
// Test both the original action
|
3535
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3536
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3537
|
+
);
|
3444
3538
|
};
|
3445
3539
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3446
3540
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3717,6 +3811,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3717
3811
|
const attribute = model.attributes[attributeName];
|
3718
3812
|
switch (attribute.type) {
|
3719
3813
|
case "relation": {
|
3814
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3815
|
+
if (isMorphRelation) {
|
3816
|
+
break;
|
3817
|
+
}
|
3720
3818
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3721
3819
|
populateAcc[attributeName] = {
|
3722
3820
|
count: true,
|
@@ -4094,7 +4192,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4094
4192
|
*/
|
4095
4193
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4096
4194
|
if (!document) {
|
4097
|
-
return
|
4195
|
+
return {
|
4196
|
+
data: document,
|
4197
|
+
meta: {
|
4198
|
+
availableLocales: [],
|
4199
|
+
availableStatus: []
|
4200
|
+
}
|
4201
|
+
};
|
4098
4202
|
}
|
4099
4203
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4100
4204
|
if (!hasDraftAndPublish) {
|
@@ -4202,10 +4306,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4202
4306
|
async clone(id, body, uid2) {
|
4203
4307
|
const populate = await buildDeepPopulate(uid2);
|
4204
4308
|
const params = {
|
4205
|
-
data:
|
4206
|
-
...omitIdField(body),
|
4207
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4208
|
-
},
|
4309
|
+
data: omitIdField(body),
|
4209
4310
|
populate
|
4210
4311
|
};
|
4211
4312
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|