@strapi/content-manager 5.33.3 → 5.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/LeftMenu.js +13 -8
- package/dist/admin/components/LeftMenu.js.map +1 -1
- package/dist/admin/components/LeftMenu.mjs +13 -8
- package/dist/admin/components/LeftMenu.mjs.map +1 -1
- package/dist/admin/history/components/VersionHeader.js +1 -0
- package/dist/admin/history/components/VersionHeader.js.map +1 -1
- package/dist/admin/history/components/VersionHeader.mjs +1 -0
- package/dist/admin/history/components/VersionHeader.mjs.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.js +71 -71
- package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.mjs +73 -73
- package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +29 -21
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +30 -22
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.js +23 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.mjs +23 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Heading.js +30 -6
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Heading.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Heading.mjs +30 -6
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Heading.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js +14 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs +14 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js +157 -7
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs +154 -5
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js +28 -20
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs +25 -17
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +6 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +7 -4
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +12 -12
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs +13 -13
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/types.js +4 -8
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/types.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/types.mjs +4 -7
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/types.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +2 -12
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +2 -12
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +48 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +49 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +47 -13
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +49 -15
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +10 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +10 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js +5 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.mjs +5 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.js +19 -7
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.mjs +19 -7
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/Header.js +91 -44
- package/dist/admin/pages/EditView/components/Header.js.map +1 -1
- package/dist/admin/pages/EditView/components/Header.mjs +92 -45
- package/dist/admin/pages/EditView/components/Header.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.js +6 -2
- package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.mjs +6 -2
- package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
- package/dist/admin/pages/EditView/utils/data.js +22 -0
- package/dist/admin/pages/EditView/utils/data.js.map +1 -1
- package/dist/admin/pages/EditView/utils/data.mjs +22 -1
- package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +6 -4
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +6 -4
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/types.d.ts +2 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +2 -1
- package/dist/admin/src/pages/EditView/utils/data.d.ts +6 -1
- package/dist/admin/translations/de.json.js +165 -32
- package/dist/admin/translations/de.json.js.map +1 -1
- package/dist/admin/translations/de.json.mjs +165 -32
- package/dist/admin/translations/de.json.mjs.map +1 -1
- package/dist/admin/translations/zh-Hans.json.js +0 -44
- package/dist/admin/translations/zh-Hans.json.js.map +1 -1
- package/dist/admin/translations/zh-Hans.json.mjs +0 -44
- package/dist/admin/translations/zh-Hans.json.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +16 -13
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +16 -13
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/relations.js +5 -2
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +5 -2
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/controllers/utils/document-status.js +28 -0
- package/dist/server/controllers/utils/document-status.js.map +1 -0
- package/dist/server/controllers/utils/document-status.mjs +26 -0
- package/dist/server/controllers/utils/document-status.mjs.map +1 -0
- package/dist/server/services/components.js +68 -20
- package/dist/server/services/components.js.map +1 -1
- package/dist/server/services/components.mjs +69 -21
- package/dist/server/services/components.mjs.map +1 -1
- package/dist/server/services/permission-checker.js +23 -0
- package/dist/server/services/permission-checker.js.map +1 -1
- package/dist/server/services/permission-checker.mjs +23 -0
- package/dist/server/services/permission-checker.mjs.map +1 -1
- package/dist/server/services/utils/store.js +51 -4
- package/dist/server/services/utils/store.js.map +1 -1
- package/dist/server/services/utils/store.mjs +51 -4
- package/dist/server/services/utils/store.mjs.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/utils/document-status.d.ts +10 -0
- package/dist/server/src/controllers/utils/document-status.d.ts.map +1 -0
- package/dist/server/src/index.d.ts +1 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/components.d.ts +6 -0
- package/dist/server/src/services/components.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +1 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts +1 -0
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/store.d.ts +5 -1
- package/dist/server/src/services/utils/store.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withImages.js +0 -17
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withImages.js.map +0 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withImages.mjs +0 -15
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withImages.mjs.map +0 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withLinks.js +0 -75
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withLinks.js.map +0 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withLinks.mjs +0 -73
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withLinks.mjs.map +0 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js +0 -88
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.js.map +0 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs +0 -84
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/utils/links.mjs.map +0 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/plugins/withImages.d.ts +0 -11
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/plugins/withLinks.d.ts +0 -9
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/links.d.ts +0 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNil, mapValues
|
|
1
|
+
import { isNil, mapValues } from 'lodash/fp';
|
|
2
2
|
import { getService } from '../utils/index.mjs';
|
|
3
3
|
import storeUtils from './utils/store.mjs';
|
|
4
4
|
import createConfigurationService from './configuration.mjs';
|
|
@@ -35,30 +35,78 @@ var components = (({ strapi: strapi1 })=>({
|
|
|
35
35
|
await configurationService.setConfiguration(component.uid, newConfiguration);
|
|
36
36
|
return this.findConfiguration(component);
|
|
37
37
|
},
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Batch load component configurations.
|
|
40
|
+
*
|
|
41
|
+
* Collects all component UIDs upfront, then loads configurations in a single
|
|
42
|
+
* batch query instead of sequential queries per component.
|
|
43
|
+
*/ async findComponentsConfigurations (model) {
|
|
44
|
+
// Cache on request state so the same request can reuse configs
|
|
45
|
+
const requestState = strapi1.requestContext?.get?.()?.state;
|
|
46
|
+
const requestCache = requestState?.__componentsConfigurationsCache;
|
|
47
|
+
const componentUids = new Set();
|
|
48
|
+
const collectComponentUids = (schema)=>{
|
|
49
|
+
for (const key of Object.keys(schema.attributes)){
|
|
50
|
+
const attribute = schema.attributes[key];
|
|
51
|
+
if (attribute.type === 'component') {
|
|
52
|
+
const uid = attribute.component;
|
|
53
|
+
if (!componentUids.has(uid)) {
|
|
54
|
+
componentUids.add(uid);
|
|
55
|
+
const nestedComponent = this.findComponent(uid);
|
|
56
|
+
if (nestedComponent) {
|
|
57
|
+
collectComponentUids(nestedComponent);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (attribute.type === 'dynamiczone') {
|
|
62
|
+
for (const uid of attribute.components){
|
|
63
|
+
if (!componentUids.has(uid)) {
|
|
64
|
+
componentUids.add(uid);
|
|
65
|
+
const nestedComponent = this.findComponent(uid);
|
|
66
|
+
if (nestedComponent) {
|
|
67
|
+
collectComponentUids(nestedComponent);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
44
72
|
}
|
|
45
|
-
const componentConfiguration = await this.findConfiguration(component);
|
|
46
|
-
const componentsConfigurations = await this.findComponentsConfigurations(component);
|
|
47
|
-
Object.assign(componentsMap, {
|
|
48
|
-
[uid]: componentConfiguration,
|
|
49
|
-
...componentsConfigurations
|
|
50
|
-
});
|
|
51
73
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
collectComponentUids(model);
|
|
75
|
+
if (componentUids.size === 0) {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
// Key format must match configuration.ts uidToStoreKey: `${prefix}::${uid}`
|
|
79
|
+
const uidsArray = Array.from(componentUids);
|
|
80
|
+
const prefixedKeys = uidsArray.map((uid)=>`components::${uid}`);
|
|
81
|
+
const cacheKey = prefixedKeys.slice().sort().join('|');
|
|
82
|
+
if (requestCache?.has(cacheKey)) {
|
|
83
|
+
return requestCache.get(cacheKey);
|
|
84
|
+
}
|
|
85
|
+
const configs = await storeUtils.getModelConfigurations(prefixedKeys);
|
|
86
|
+
const componentsMap = {};
|
|
87
|
+
for (const uid of uidsArray){
|
|
88
|
+
const component = this.findComponent(uid);
|
|
89
|
+
const configKey = `components::${uid}`;
|
|
90
|
+
// Fallback must include proper layouts structure for frontend compatibility
|
|
91
|
+
const configuration = configs[configKey] || {
|
|
92
|
+
settings: {},
|
|
93
|
+
metadatas: {},
|
|
94
|
+
layouts: {
|
|
95
|
+
list: [],
|
|
96
|
+
edit: []
|
|
60
97
|
}
|
|
98
|
+
};
|
|
99
|
+
componentsMap[uid] = {
|
|
100
|
+
uid: component.uid,
|
|
101
|
+
category: component.category,
|
|
102
|
+
...configuration
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (requestState) {
|
|
106
|
+
if (!requestState.__componentsConfigurationsCache) {
|
|
107
|
+
requestState.__componentsConfigurationsCache = new Map();
|
|
61
108
|
}
|
|
109
|
+
requestState.__componentsConfigurationsCache.set(cacheKey, componentsMap);
|
|
62
110
|
}
|
|
63
111
|
return componentsMap;
|
|
64
112
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.mjs","sources":["../../../server/src/services/components.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"components.mjs","sources":["../../../server/src/services/components.ts"],"sourcesContent":["import { isNil, mapValues } from 'lodash/fp';\n\nimport type { UID, Struct, Core } from '@strapi/types';\nimport type { Configuration } from '../../../shared/contracts/content-types';\nimport type { ConfigurationUpdate } from './configuration';\n\nimport { getService } from '../utils';\nimport storeUtils from './utils/store';\nimport createConfigurationService from './configuration';\n\nconst STORE_KEY_PREFIX = 'components';\n\nconst configurationService = createConfigurationService({\n storeUtils,\n isComponent: true,\n prefix: STORE_KEY_PREFIX,\n getModels() {\n const { toContentManagerModel } = getService('data-mapper');\n\n return mapValues(toContentManagerModel, strapi.components);\n },\n});\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n findAllComponents() {\n const { toContentManagerModel } = getService('data-mapper');\n\n return Object.values(strapi.components).map(toContentManagerModel);\n },\n\n findComponent(uid: UID.Component) {\n const { toContentManagerModel } = getService('data-mapper');\n\n const component = strapi.components[uid];\n\n return isNil(component) ? component : toContentManagerModel(component);\n },\n\n async findConfiguration(component: Struct.ComponentSchema) {\n const configuration: Configuration = await configurationService.getConfiguration(component.uid);\n\n return {\n uid: component.uid,\n category: component.category,\n ...configuration,\n };\n },\n\n async updateConfiguration(\n component: Struct.ComponentSchema,\n newConfiguration: ConfigurationUpdate\n ) {\n await configurationService.setConfiguration(component.uid, newConfiguration);\n\n return this.findConfiguration(component);\n },\n\n /**\n * Batch load component configurations.\n *\n * Collects all component UIDs upfront, then loads configurations in a single\n * batch query instead of sequential queries per component.\n */\n async findComponentsConfigurations(model: Struct.ComponentSchema) {\n // Cache on request state so the same request can reuse configs\n const requestState = strapi.requestContext?.get?.()?.state as\n | { __componentsConfigurationsCache?: Map<string, Record<string, Configuration>> }\n | undefined;\n const requestCache = requestState?.__componentsConfigurationsCache;\n\n const componentUids = new Set<UID.Component>();\n\n const collectComponentUids = (schema: Struct.ComponentSchema) => {\n for (const key of Object.keys(schema.attributes)) {\n const attribute = schema.attributes[key];\n\n if (attribute.type === 'component') {\n const uid = attribute.component;\n if (!componentUids.has(uid)) {\n componentUids.add(uid);\n const nestedComponent = this.findComponent(uid);\n if (nestedComponent) {\n collectComponentUids(nestedComponent);\n }\n }\n }\n\n if (attribute.type === 'dynamiczone') {\n for (const uid of attribute.components) {\n if (!componentUids.has(uid)) {\n componentUids.add(uid);\n const nestedComponent = this.findComponent(uid);\n if (nestedComponent) {\n collectComponentUids(nestedComponent);\n }\n }\n }\n }\n }\n };\n\n collectComponentUids(model);\n\n if (componentUids.size === 0) {\n return {};\n }\n\n // Key format must match configuration.ts uidToStoreKey: `${prefix}::${uid}`\n const uidsArray = Array.from(componentUids);\n const prefixedKeys = uidsArray.map((uid) => `components::${uid}`);\n const cacheKey = prefixedKeys.slice().sort().join('|');\n if (requestCache?.has(cacheKey)) {\n return requestCache.get(cacheKey)! as Record<\n string,\n Configuration & { category: string; isComponent: boolean }\n >;\n }\n\n const configs = await storeUtils.getModelConfigurations(prefixedKeys);\n\n const componentsMap: Record<\n string,\n Configuration & { category: string; isComponent: boolean }\n > = {};\n\n for (const uid of uidsArray) {\n const component = this.findComponent(uid);\n const configKey = `components::${uid}`;\n // Fallback must include proper layouts structure for frontend compatibility\n const configuration = configs[configKey] || {\n settings: {},\n metadatas: {},\n layouts: { list: [], edit: [] },\n };\n\n componentsMap[uid] = {\n uid: component.uid,\n category: component.category,\n ...configuration,\n };\n }\n\n if (requestState) {\n if (!requestState.__componentsConfigurationsCache) {\n requestState.__componentsConfigurationsCache = new Map();\n }\n requestState.__componentsConfigurationsCache.set(cacheKey, componentsMap);\n }\n\n return componentsMap;\n },\n\n syncConfigurations() {\n return configurationService.syncConfigurations();\n },\n});\n"],"names":["STORE_KEY_PREFIX","configurationService","createConfigurationService","storeUtils","isComponent","prefix","getModels","toContentManagerModel","getService","mapValues","strapi","components","findAllComponents","Object","values","map","findComponent","uid","component","isNil","findConfiguration","configuration","getConfiguration","category","updateConfiguration","newConfiguration","setConfiguration","findComponentsConfigurations","model","requestState","requestContext","get","state","requestCache","__componentsConfigurationsCache","componentUids","Set","collectComponentUids","schema","key","keys","attributes","attribute","type","has","add","nestedComponent","size","uidsArray","Array","from","prefixedKeys","cacheKey","slice","sort","join","configs","getModelConfigurations","componentsMap","configKey","settings","metadatas","layouts","list","edit","Map","set","syncConfigurations"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var strapiUtils = require('@strapi/utils');
|
|
4
|
+
var fp = require('lodash/fp');
|
|
4
5
|
|
|
5
6
|
const ACTIONS = {
|
|
6
7
|
read: 'plugin::content-manager.explorer.read',
|
|
@@ -44,6 +45,25 @@ const createPermissionChecker = (strapi)=>({ userAbility, model })=>{
|
|
|
44
45
|
action
|
|
45
46
|
});
|
|
46
47
|
};
|
|
48
|
+
const getRulesForAction = (action)=>{
|
|
49
|
+
if (typeof userAbility.rulesFor !== 'function') {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
|
53
|
+
const actions = [
|
|
54
|
+
action,
|
|
55
|
+
...aliases
|
|
56
|
+
];
|
|
57
|
+
return actions.flatMap((actionName)=>userAbility.rulesFor(actionName, model));
|
|
58
|
+
};
|
|
59
|
+
// Tell callers if we need the full entity to check access
|
|
60
|
+
const requiresEntity = (action)=>{
|
|
61
|
+
if (typeof userAbility.rulesFor !== 'function') {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
const rules = getRulesForAction(action);
|
|
65
|
+
return rules.some((rule)=>rule.conditions && !fp.isEmpty(rule.conditions));
|
|
66
|
+
};
|
|
47
67
|
const sanitizeQuery = (query, { action = ACTIONS.read } = {})=>{
|
|
48
68
|
return permissionsManager.sanitizeQuery(query, {
|
|
49
69
|
subject: model,
|
|
@@ -87,11 +107,14 @@ const createPermissionChecker = (strapi)=>({ userAbility, model })=>{
|
|
|
87
107
|
can[action] = (...args)=>can(ACTIONS[action], ...args);
|
|
88
108
|
// @ts-expect-error TODO
|
|
89
109
|
cannot[action] = (...args)=>cannot(ACTIONS[action], ...args);
|
|
110
|
+
// @ts-expect-error TODO
|
|
111
|
+
requiresEntity[action] = ()=>requiresEntity(ACTIONS[action]);
|
|
90
112
|
});
|
|
91
113
|
return {
|
|
92
114
|
// Permission utils
|
|
93
115
|
can,
|
|
94
116
|
cannot,
|
|
117
|
+
requiresEntity,
|
|
95
118
|
// Sanitizers
|
|
96
119
|
sanitizeOutput,
|
|
97
120
|
sanitizeQuery,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-checker.js","sources":["../../../server/src/services/permission-checker.ts"],"sourcesContent":["import { async } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nconst ACTIONS = {\n read: 'plugin::content-manager.explorer.read',\n create: 'plugin::content-manager.explorer.create',\n update: 'plugin::content-manager.explorer.update',\n delete: 'plugin::content-manager.explorer.delete',\n publish: 'plugin::content-manager.explorer.publish',\n unpublish: 'plugin::content-manager.explorer.publish',\n discard: 'plugin::content-manager.explorer.update',\n} as const;\n\ntype Entity = Modules.EntityService.Result<UID.ContentType>;\ntype Query = {\n page?: string;\n pageSize?: string;\n sort?: string;\n};\n\nconst createPermissionChecker =\n (strapi: Core.Strapi) =>\n ({ userAbility, model }: { userAbility: any; model: string }) => {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n model,\n });\n\n const { actionProvider } = strapi.service('admin::permission');\n\n const toSubject = (entity?: Entity) => {\n return entity ? permissionsManager.toSubject(entity, model) : model;\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const can = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test the original action to see if it passes\n userAbility.can(action, subject, field) ||\n // Else try every known alias if at least one of them succeed, then the user \"can\"\n aliases.some((alias) => userAbility.can(alias, subject, field))\n );\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const cannot = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test both the original action\n userAbility.cannot(action, subject, field) &&\n // and every known alias, if all of them fail (cannot), then the user truly \"cannot\"\n aliases.every((alias) => userAbility.cannot(alias, subject, field))\n );\n };\n\n const sanitizeOutput = (data: Entity, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });\n };\n\n const sanitizeQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeQuery(query, { subject: model, action });\n };\n\n const sanitizeInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.sanitizeInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const validateQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.validateQuery(query, { subject: model, action });\n };\n\n const validateInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.validateInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const sanitizeCreateInput = (data: any) => sanitizeInput(ACTIONS.create, data);\n const sanitizeUpdateInput = (entity: Entity) => (data: any) =>\n sanitizeInput(ACTIONS.update, data, entity);\n\n const buildPermissionQuery = (query: Query, action: { action?: string } = {}) => {\n return permissionsManager.addPermissionsQueryTo(query, action);\n };\n\n const sanitizedQuery = (query: Query, action: { action?: string } = {}) => {\n return async.pipe(\n (q: Query) => sanitizeQuery(q, action),\n (q: Query) => buildPermissionQuery(q, action)\n )(query);\n };\n\n // Sanitized queries shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n sanitizedQuery[action] = (query: Query) => sanitizedQuery(query, ACTIONS[action]);\n });\n\n // Permission utils shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n can[action] = (...args: any) => can(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n cannot[action] = (...args: any) => cannot(ACTIONS[action], ...args);\n });\n\n return {\n // Permission utils\n can, // check if you have the permission\n cannot, // check if you don't have the permission\n // Sanitizers\n sanitizeOutput,\n sanitizeQuery,\n sanitizeCreateInput,\n sanitizeUpdateInput,\n // Validators\n validateQuery,\n validateInput,\n // Queries Builder\n sanitizedQuery,\n };\n };\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n create: createPermissionChecker(strapi),\n});\n"],"names":["ACTIONS","read","create","update","delete","publish","unpublish","discard","createPermissionChecker","strapi","userAbility","model","permissionsManager","service","createPermissionsManager","ability","actionProvider","toSubject","entity","can","action","field","subject","aliases","unstable_aliases","some","alias","cannot","every","sanitizeOutput","data","sanitizeQuery","query","sanitizeInput","validateQuery","validateInput","sanitizeCreateInput","sanitizeUpdateInput","buildPermissionQuery","addPermissionsQueryTo","sanitizedQuery","async","pipe","q","Object","keys","forEach","args"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permission-checker.js","sources":["../../../server/src/services/permission-checker.ts"],"sourcesContent":["import { async } from '@strapi/utils';\nimport { isEmpty } from 'lodash/fp';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nconst ACTIONS = {\n read: 'plugin::content-manager.explorer.read',\n create: 'plugin::content-manager.explorer.create',\n update: 'plugin::content-manager.explorer.update',\n delete: 'plugin::content-manager.explorer.delete',\n publish: 'plugin::content-manager.explorer.publish',\n unpublish: 'plugin::content-manager.explorer.publish',\n discard: 'plugin::content-manager.explorer.update',\n} as const;\n\ntype Entity = Modules.EntityService.Result<UID.ContentType>;\ntype Query = {\n page?: string;\n pageSize?: string;\n sort?: string;\n};\n\nconst createPermissionChecker =\n (strapi: Core.Strapi) =>\n ({ userAbility, model }: { userAbility: any; model: string }) => {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n model,\n });\n\n const { actionProvider } = strapi.service('admin::permission');\n\n const toSubject = (entity?: Entity) => {\n return entity ? permissionsManager.toSubject(entity, model) : model;\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const can = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test the original action to see if it passes\n userAbility.can(action, subject, field) ||\n // Else try every known alias if at least one of them succeed, then the user \"can\"\n aliases.some((alias) => userAbility.can(alias, subject, field))\n );\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const cannot = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test both the original action\n userAbility.cannot(action, subject, field) &&\n // and every known alias, if all of them fail (cannot), then the user truly \"cannot\"\n aliases.every((alias) => userAbility.cannot(alias, subject, field))\n );\n };\n\n const sanitizeOutput = (data: Entity, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });\n };\n\n const getRulesForAction = (action: string) => {\n if (typeof userAbility.rulesFor !== 'function') {\n return [];\n }\n\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n const actions = [action, ...aliases];\n\n return actions.flatMap((actionName) => userAbility.rulesFor(actionName, model));\n };\n\n // Tell callers if we need the full entity to check access\n const requiresEntity = (action: string) => {\n if (typeof userAbility.rulesFor !== 'function') {\n return true;\n }\n\n const rules = getRulesForAction(action);\n\n return rules.some((rule: any) => rule.conditions && !isEmpty(rule.conditions));\n };\n\n const sanitizeQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeQuery(query, { subject: model, action });\n };\n\n const sanitizeInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.sanitizeInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const validateQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.validateQuery(query, { subject: model, action });\n };\n\n const validateInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.validateInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const sanitizeCreateInput = (data: any) => sanitizeInput(ACTIONS.create, data);\n const sanitizeUpdateInput = (entity: Entity) => (data: any) =>\n sanitizeInput(ACTIONS.update, data, entity);\n\n const buildPermissionQuery = (query: Query, action: { action?: string } = {}) => {\n return permissionsManager.addPermissionsQueryTo(query, action);\n };\n\n const sanitizedQuery = (query: Query, action: { action?: string } = {}) => {\n return async.pipe(\n (q: Query) => sanitizeQuery(q, action),\n (q: Query) => buildPermissionQuery(q, action)\n )(query);\n };\n\n // Sanitized queries shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n sanitizedQuery[action] = (query: Query) => sanitizedQuery(query, ACTIONS[action]);\n });\n\n // Permission utils shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n can[action] = (...args: any) => can(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n cannot[action] = (...args: any) => cannot(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n requiresEntity[action] = () => requiresEntity(ACTIONS[action]);\n });\n\n return {\n // Permission utils\n can, // check if you have the permission\n cannot, // check if you don't have the permission\n requiresEntity, // check if entity data is needed for permission evaluation\n // Sanitizers\n sanitizeOutput,\n sanitizeQuery,\n sanitizeCreateInput,\n sanitizeUpdateInput,\n // Validators\n validateQuery,\n validateInput,\n // Queries Builder\n sanitizedQuery,\n };\n };\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n create: createPermissionChecker(strapi),\n});\n"],"names":["ACTIONS","read","create","update","delete","publish","unpublish","discard","createPermissionChecker","strapi","userAbility","model","permissionsManager","service","createPermissionsManager","ability","actionProvider","toSubject","entity","can","action","field","subject","aliases","unstable_aliases","some","alias","cannot","every","sanitizeOutput","data","getRulesForAction","rulesFor","actions","flatMap","actionName","requiresEntity","rules","rule","conditions","isEmpty","sanitizeQuery","query","sanitizeInput","validateQuery","validateInput","sanitizeCreateInput","sanitizeUpdateInput","buildPermissionQuery","addPermissionsQueryTo","sanitizedQuery","async","pipe","q","Object","keys","forEach","args"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { async } from '@strapi/utils';
|
|
2
|
+
import { isEmpty } from 'lodash/fp';
|
|
2
3
|
|
|
3
4
|
const ACTIONS = {
|
|
4
5
|
read: 'plugin::content-manager.explorer.read',
|
|
@@ -42,6 +43,25 @@ const createPermissionChecker = (strapi)=>({ userAbility, model })=>{
|
|
|
42
43
|
action
|
|
43
44
|
});
|
|
44
45
|
};
|
|
46
|
+
const getRulesForAction = (action)=>{
|
|
47
|
+
if (typeof userAbility.rulesFor !== 'function') {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
|
51
|
+
const actions = [
|
|
52
|
+
action,
|
|
53
|
+
...aliases
|
|
54
|
+
];
|
|
55
|
+
return actions.flatMap((actionName)=>userAbility.rulesFor(actionName, model));
|
|
56
|
+
};
|
|
57
|
+
// Tell callers if we need the full entity to check access
|
|
58
|
+
const requiresEntity = (action)=>{
|
|
59
|
+
if (typeof userAbility.rulesFor !== 'function') {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
const rules = getRulesForAction(action);
|
|
63
|
+
return rules.some((rule)=>rule.conditions && !isEmpty(rule.conditions));
|
|
64
|
+
};
|
|
45
65
|
const sanitizeQuery = (query, { action = ACTIONS.read } = {})=>{
|
|
46
66
|
return permissionsManager.sanitizeQuery(query, {
|
|
47
67
|
subject: model,
|
|
@@ -85,11 +105,14 @@ const createPermissionChecker = (strapi)=>({ userAbility, model })=>{
|
|
|
85
105
|
can[action] = (...args)=>can(ACTIONS[action], ...args);
|
|
86
106
|
// @ts-expect-error TODO
|
|
87
107
|
cannot[action] = (...args)=>cannot(ACTIONS[action], ...args);
|
|
108
|
+
// @ts-expect-error TODO
|
|
109
|
+
requiresEntity[action] = ()=>requiresEntity(ACTIONS[action]);
|
|
88
110
|
});
|
|
89
111
|
return {
|
|
90
112
|
// Permission utils
|
|
91
113
|
can,
|
|
92
114
|
cannot,
|
|
115
|
+
requiresEntity,
|
|
93
116
|
// Sanitizers
|
|
94
117
|
sanitizeOutput,
|
|
95
118
|
sanitizeQuery,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-checker.mjs","sources":["../../../server/src/services/permission-checker.ts"],"sourcesContent":["import { async } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nconst ACTIONS = {\n read: 'plugin::content-manager.explorer.read',\n create: 'plugin::content-manager.explorer.create',\n update: 'plugin::content-manager.explorer.update',\n delete: 'plugin::content-manager.explorer.delete',\n publish: 'plugin::content-manager.explorer.publish',\n unpublish: 'plugin::content-manager.explorer.publish',\n discard: 'plugin::content-manager.explorer.update',\n} as const;\n\ntype Entity = Modules.EntityService.Result<UID.ContentType>;\ntype Query = {\n page?: string;\n pageSize?: string;\n sort?: string;\n};\n\nconst createPermissionChecker =\n (strapi: Core.Strapi) =>\n ({ userAbility, model }: { userAbility: any; model: string }) => {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n model,\n });\n\n const { actionProvider } = strapi.service('admin::permission');\n\n const toSubject = (entity?: Entity) => {\n return entity ? permissionsManager.toSubject(entity, model) : model;\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const can = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test the original action to see if it passes\n userAbility.can(action, subject, field) ||\n // Else try every known alias if at least one of them succeed, then the user \"can\"\n aliases.some((alias) => userAbility.can(alias, subject, field))\n );\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const cannot = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test both the original action\n userAbility.cannot(action, subject, field) &&\n // and every known alias, if all of them fail (cannot), then the user truly \"cannot\"\n aliases.every((alias) => userAbility.cannot(alias, subject, field))\n );\n };\n\n const sanitizeOutput = (data: Entity, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });\n };\n\n const sanitizeQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeQuery(query, { subject: model, action });\n };\n\n const sanitizeInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.sanitizeInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const validateQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.validateQuery(query, { subject: model, action });\n };\n\n const validateInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.validateInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const sanitizeCreateInput = (data: any) => sanitizeInput(ACTIONS.create, data);\n const sanitizeUpdateInput = (entity: Entity) => (data: any) =>\n sanitizeInput(ACTIONS.update, data, entity);\n\n const buildPermissionQuery = (query: Query, action: { action?: string } = {}) => {\n return permissionsManager.addPermissionsQueryTo(query, action);\n };\n\n const sanitizedQuery = (query: Query, action: { action?: string } = {}) => {\n return async.pipe(\n (q: Query) => sanitizeQuery(q, action),\n (q: Query) => buildPermissionQuery(q, action)\n )(query);\n };\n\n // Sanitized queries shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n sanitizedQuery[action] = (query: Query) => sanitizedQuery(query, ACTIONS[action]);\n });\n\n // Permission utils shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n can[action] = (...args: any) => can(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n cannot[action] = (...args: any) => cannot(ACTIONS[action], ...args);\n });\n\n return {\n // Permission utils\n can, // check if you have the permission\n cannot, // check if you don't have the permission\n // Sanitizers\n sanitizeOutput,\n sanitizeQuery,\n sanitizeCreateInput,\n sanitizeUpdateInput,\n // Validators\n validateQuery,\n validateInput,\n // Queries Builder\n sanitizedQuery,\n };\n };\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n create: createPermissionChecker(strapi),\n});\n"],"names":["ACTIONS","read","create","update","delete","publish","unpublish","discard","createPermissionChecker","strapi","userAbility","model","permissionsManager","service","createPermissionsManager","ability","actionProvider","toSubject","entity","can","action","field","subject","aliases","unstable_aliases","some","alias","cannot","every","sanitizeOutput","data","sanitizeQuery","query","sanitizeInput","validateQuery","validateInput","sanitizeCreateInput","sanitizeUpdateInput","buildPermissionQuery","addPermissionsQueryTo","sanitizedQuery","async","pipe","q","Object","keys","forEach","args"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permission-checker.mjs","sources":["../../../server/src/services/permission-checker.ts"],"sourcesContent":["import { async } from '@strapi/utils';\nimport { isEmpty } from 'lodash/fp';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nconst ACTIONS = {\n read: 'plugin::content-manager.explorer.read',\n create: 'plugin::content-manager.explorer.create',\n update: 'plugin::content-manager.explorer.update',\n delete: 'plugin::content-manager.explorer.delete',\n publish: 'plugin::content-manager.explorer.publish',\n unpublish: 'plugin::content-manager.explorer.publish',\n discard: 'plugin::content-manager.explorer.update',\n} as const;\n\ntype Entity = Modules.EntityService.Result<UID.ContentType>;\ntype Query = {\n page?: string;\n pageSize?: string;\n sort?: string;\n};\n\nconst createPermissionChecker =\n (strapi: Core.Strapi) =>\n ({ userAbility, model }: { userAbility: any; model: string }) => {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n model,\n });\n\n const { actionProvider } = strapi.service('admin::permission');\n\n const toSubject = (entity?: Entity) => {\n return entity ? permissionsManager.toSubject(entity, model) : model;\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const can = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test the original action to see if it passes\n userAbility.can(action, subject, field) ||\n // Else try every known alias if at least one of them succeed, then the user \"can\"\n aliases.some((alias) => userAbility.can(alias, subject, field))\n );\n };\n\n // @ts-expect-error preserve the parameter order\n // eslint-disable-next-line @typescript-eslint/default-param-last\n const cannot = (action: string, entity?: Entity, field: string) => {\n const subject = toSubject(entity);\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n\n return (\n // Test both the original action\n userAbility.cannot(action, subject, field) &&\n // and every known alias, if all of them fail (cannot), then the user truly \"cannot\"\n aliases.every((alias) => userAbility.cannot(alias, subject, field))\n );\n };\n\n const sanitizeOutput = (data: Entity, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });\n };\n\n const getRulesForAction = (action: string) => {\n if (typeof userAbility.rulesFor !== 'function') {\n return [];\n }\n\n const aliases = actionProvider.unstable_aliases(action, model) as string[];\n const actions = [action, ...aliases];\n\n return actions.flatMap((actionName) => userAbility.rulesFor(actionName, model));\n };\n\n // Tell callers if we need the full entity to check access\n const requiresEntity = (action: string) => {\n if (typeof userAbility.rulesFor !== 'function') {\n return true;\n }\n\n const rules = getRulesForAction(action);\n\n return rules.some((rule: any) => rule.conditions && !isEmpty(rule.conditions));\n };\n\n const sanitizeQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.sanitizeQuery(query, { subject: model, action });\n };\n\n const sanitizeInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.sanitizeInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const validateQuery = (query: Query, { action = ACTIONS.read }: { action?: string } = {}) => {\n return permissionsManager.validateQuery(query, { subject: model, action });\n };\n\n const validateInput = (action: string, data: any, entity?: Entity) => {\n return permissionsManager.validateInput(data, {\n subject: entity ? toSubject(entity) : model,\n action,\n });\n };\n\n const sanitizeCreateInput = (data: any) => sanitizeInput(ACTIONS.create, data);\n const sanitizeUpdateInput = (entity: Entity) => (data: any) =>\n sanitizeInput(ACTIONS.update, data, entity);\n\n const buildPermissionQuery = (query: Query, action: { action?: string } = {}) => {\n return permissionsManager.addPermissionsQueryTo(query, action);\n };\n\n const sanitizedQuery = (query: Query, action: { action?: string } = {}) => {\n return async.pipe(\n (q: Query) => sanitizeQuery(q, action),\n (q: Query) => buildPermissionQuery(q, action)\n )(query);\n };\n\n // Sanitized queries shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n sanitizedQuery[action] = (query: Query) => sanitizedQuery(query, ACTIONS[action]);\n });\n\n // Permission utils shortcuts\n Object.keys(ACTIONS).forEach((action) => {\n // @ts-expect-error TODO\n can[action] = (...args: any) => can(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n cannot[action] = (...args: any) => cannot(ACTIONS[action], ...args);\n // @ts-expect-error TODO\n requiresEntity[action] = () => requiresEntity(ACTIONS[action]);\n });\n\n return {\n // Permission utils\n can, // check if you have the permission\n cannot, // check if you don't have the permission\n requiresEntity, // check if entity data is needed for permission evaluation\n // Sanitizers\n sanitizeOutput,\n sanitizeQuery,\n sanitizeCreateInput,\n sanitizeUpdateInput,\n // Validators\n validateQuery,\n validateInput,\n // Queries Builder\n sanitizedQuery,\n };\n };\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n create: createPermissionChecker(strapi),\n});\n"],"names":["ACTIONS","read","create","update","delete","publish","unpublish","discard","createPermissionChecker","strapi","userAbility","model","permissionsManager","service","createPermissionsManager","ability","actionProvider","toSubject","entity","can","action","field","subject","aliases","unstable_aliases","some","alias","cannot","every","sanitizeOutput","data","getRulesForAction","rulesFor","actions","flatMap","actionName","requiresEntity","rules","rule","conditions","isEmpty","sanitizeQuery","query","sanitizeInput","validateQuery","validateInput","sanitizeCreateInput","sanitizeUpdateInput","buildPermissionQuery","addPermissionsQueryTo","sanitizedQuery","async","pipe","q","Object","keys","forEach","args"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ var _ = require('lodash');
|
|
|
5
5
|
const keys = {
|
|
6
6
|
CONFIGURATION: 'configuration'
|
|
7
7
|
};
|
|
8
|
+
const STORE_KEY_PREFIX = 'plugin_content_manager_';
|
|
8
9
|
const getStore = ()=>strapi.store({
|
|
9
10
|
type: 'plugin',
|
|
10
11
|
name: 'content_manager'
|
|
@@ -12,7 +13,10 @@ const getStore = ()=>strapi.store({
|
|
|
12
13
|
/** Model configuration */ const EMPTY_CONFIG = {
|
|
13
14
|
settings: {},
|
|
14
15
|
metadatas: {},
|
|
15
|
-
layouts: {
|
|
16
|
+
layouts: {
|
|
17
|
+
list: [],
|
|
18
|
+
edit: []
|
|
19
|
+
}
|
|
16
20
|
};
|
|
17
21
|
const configurationKey = (key)=>`${keys.CONFIGURATION}_${key}`;
|
|
18
22
|
const getModelConfiguration = async (key)=>{
|
|
@@ -21,6 +25,41 @@ const getModelConfiguration = async (key)=>{
|
|
|
21
25
|
});
|
|
22
26
|
return _.merge({}, EMPTY_CONFIG, config);
|
|
23
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Batch load multiple model configurations in a single query.
|
|
30
|
+
*
|
|
31
|
+
* @param keys - Array of configuration keys (e.g., ['components::sections.hero', ...])
|
|
32
|
+
* @returns Map of key -> configuration object
|
|
33
|
+
*/ const getModelConfigurations = async (keys)=>{
|
|
34
|
+
if (keys.length === 0) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
const configKeys = keys.map((k)=>`${STORE_KEY_PREFIX}${configurationKey(k)}`);
|
|
38
|
+
const results = await strapi.db.query('strapi::core-store').findMany({
|
|
39
|
+
where: {
|
|
40
|
+
key: {
|
|
41
|
+
$in: configKeys
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const configMap = {};
|
|
46
|
+
for (const result of results){
|
|
47
|
+
const originalKey = result.key.replace(`${STORE_KEY_PREFIX}configuration_`, '');
|
|
48
|
+
try {
|
|
49
|
+
const value = typeof result.value === 'string' ? JSON.parse(result.value) : result.value;
|
|
50
|
+
configMap[originalKey] = _.merge({}, EMPTY_CONFIG, value);
|
|
51
|
+
} catch {
|
|
52
|
+
strapi.log.warn(`Malformed JSON in core-store key "${result.key}", using default config`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Default missing keys to empty config
|
|
56
|
+
for (const key of keys){
|
|
57
|
+
if (!configMap[key]) {
|
|
58
|
+
configMap[key] = _.merge({}, EMPTY_CONFIG);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return configMap;
|
|
62
|
+
};
|
|
24
63
|
const setModelConfiguration = async (key, value)=>{
|
|
25
64
|
const storedConfig = await getStore().get({
|
|
26
65
|
key: configurationKey(key)
|
|
@@ -43,7 +82,7 @@ const setModelConfiguration = async (key, value)=>{
|
|
|
43
82
|
const deleteKey = (key)=>{
|
|
44
83
|
return strapi.db.query('strapi::core-store').delete({
|
|
45
84
|
where: {
|
|
46
|
-
key:
|
|
85
|
+
key: `${STORE_KEY_PREFIX}configuration_${key}`
|
|
47
86
|
}
|
|
48
87
|
});
|
|
49
88
|
};
|
|
@@ -55,13 +94,21 @@ const findByKey = async (key)=>{
|
|
|
55
94
|
}
|
|
56
95
|
}
|
|
57
96
|
});
|
|
58
|
-
return results.map(({ value })=>
|
|
97
|
+
return results.map(({ key, value })=>{
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(value);
|
|
100
|
+
} catch {
|
|
101
|
+
strapi.log.warn(`Malformed JSON in core-store key "${key}", skipping entry`);
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}).filter((v)=>v !== null);
|
|
59
105
|
};
|
|
60
|
-
const getAllConfigurations = ()=>findByKey(
|
|
106
|
+
const getAllConfigurations = ()=>findByKey(`${STORE_KEY_PREFIX}configuration`);
|
|
61
107
|
var storeUtils = {
|
|
62
108
|
getAllConfigurations,
|
|
63
109
|
findByKey,
|
|
64
110
|
getModelConfiguration,
|
|
111
|
+
getModelConfigurations,
|
|
65
112
|
setModelConfiguration,
|
|
66
113
|
deleteKey,
|
|
67
114
|
keys
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sources":["../../../../server/src/services/utils/store.ts"],"sourcesContent":["import _ from 'lodash';\n\nconst keys = {\n CONFIGURATION: 'configuration',\n};\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'content_manager' });\n\n/** Model configuration */\nconst EMPTY_CONFIG = {\n settings: {},\n metadatas: {},\n layouts: {},\n};\n\nconst configurationKey = (key: any) => `${keys.CONFIGURATION}_${key}`;\n\nconst getModelConfiguration = async (key: any) => {\n const config = await getStore().get({ key: configurationKey(key) });\n return _.merge({}, EMPTY_CONFIG, config);\n};\n\nconst setModelConfiguration = async (key: string, value: any) => {\n const storedConfig = (await getStore().get({ key: configurationKey(key) })) || {};\n const currentConfig = { ...storedConfig };\n\n Object.keys(value).forEach((key) => {\n if (value[key] !== null && value[key] !== undefined) {\n _.set(currentConfig, key, value[key]);\n }\n });\n\n if (!_.isEqual(currentConfig, storedConfig)) {\n return getStore().set({\n key: configurationKey(key),\n value: currentConfig,\n });\n }\n};\n\nconst deleteKey = (key: any) => {\n return strapi.db\n .query('strapi::core-store')\n .delete({ where: { key:
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../../../server/src/services/utils/store.ts"],"sourcesContent":["import _ from 'lodash';\n\nconst keys = {\n CONFIGURATION: 'configuration',\n};\n\nconst STORE_KEY_PREFIX = 'plugin_content_manager_';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'content_manager' });\n\n/** Model configuration */\nconst EMPTY_CONFIG = {\n settings: {},\n metadatas: {},\n layouts: { list: [], edit: [] },\n};\n\nconst configurationKey = (key: any) => `${keys.CONFIGURATION}_${key}`;\n\nconst getModelConfiguration = async (key: any) => {\n const config = await getStore().get({ key: configurationKey(key) });\n return _.merge({}, EMPTY_CONFIG, config);\n};\n\n/**\n * Batch load multiple model configurations in a single query.\n *\n * @param keys - Array of configuration keys (e.g., ['components::sections.hero', ...])\n * @returns Map of key -> configuration object\n */\nconst getModelConfigurations = async (keys: string[]) => {\n if (keys.length === 0) {\n return {};\n }\n\n const configKeys = keys.map((k) => `${STORE_KEY_PREFIX}${configurationKey(k)}`);\n const results = await strapi.db.query('strapi::core-store').findMany({\n where: {\n key: { $in: configKeys },\n },\n });\n\n const configMap: Record<string, any> = {};\n for (const result of results) {\n const originalKey = result.key.replace(`${STORE_KEY_PREFIX}configuration_`, '');\n try {\n const value = typeof result.value === 'string' ? JSON.parse(result.value) : result.value;\n configMap[originalKey] = _.merge({}, EMPTY_CONFIG, value);\n } catch {\n strapi.log.warn(`Malformed JSON in core-store key \"${result.key}\", using default config`);\n }\n }\n\n // Default missing keys to empty config\n for (const key of keys) {\n if (!configMap[key]) {\n configMap[key] = _.merge({}, EMPTY_CONFIG);\n }\n }\n\n return configMap;\n};\n\nconst setModelConfiguration = async (key: string, value: any) => {\n const storedConfig = (await getStore().get({ key: configurationKey(key) })) || {};\n const currentConfig = { ...storedConfig };\n\n Object.keys(value).forEach((key) => {\n if (value[key] !== null && value[key] !== undefined) {\n _.set(currentConfig, key, value[key]);\n }\n });\n\n if (!_.isEqual(currentConfig, storedConfig)) {\n return getStore().set({\n key: configurationKey(key),\n value: currentConfig,\n });\n }\n};\n\nconst deleteKey = (key: any) => {\n return strapi.db\n .query('strapi::core-store')\n .delete({ where: { key: `${STORE_KEY_PREFIX}configuration_${key}` } });\n};\n\nconst findByKey = async (key: any) => {\n const results = await strapi.db.query('strapi::core-store').findMany({\n where: {\n key: {\n $startsWith: key,\n },\n },\n });\n\n return results\n .map(({ key, value }) => {\n try {\n return JSON.parse(value);\n } catch {\n strapi.log.warn(`Malformed JSON in core-store key \"${key}\", skipping entry`);\n return null;\n }\n })\n .filter((v) => v !== null);\n};\n\nconst getAllConfigurations = () => findByKey(`${STORE_KEY_PREFIX}configuration`);\n\nexport default {\n getAllConfigurations,\n findByKey,\n getModelConfiguration,\n getModelConfigurations,\n setModelConfiguration,\n deleteKey,\n keys,\n};\n"],"names":["keys","CONFIGURATION","STORE_KEY_PREFIX","getStore","strapi","store","type","name","EMPTY_CONFIG","settings","metadatas","layouts","list","edit","configurationKey","key","getModelConfiguration","config","get","_","merge","getModelConfigurations","length","configKeys","map","k","results","db","query","findMany","where","$in","configMap","result","originalKey","replace","value","JSON","parse","log","warn","setModelConfiguration","storedConfig","currentConfig","Object","forEach","undefined","set","isEqual","deleteKey","delete","findByKey","$startsWith","filter","v","getAllConfigurations"],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import _ from 'lodash';
|
|
|
3
3
|
const keys = {
|
|
4
4
|
CONFIGURATION: 'configuration'
|
|
5
5
|
};
|
|
6
|
+
const STORE_KEY_PREFIX = 'plugin_content_manager_';
|
|
6
7
|
const getStore = ()=>strapi.store({
|
|
7
8
|
type: 'plugin',
|
|
8
9
|
name: 'content_manager'
|
|
@@ -10,7 +11,10 @@ const getStore = ()=>strapi.store({
|
|
|
10
11
|
/** Model configuration */ const EMPTY_CONFIG = {
|
|
11
12
|
settings: {},
|
|
12
13
|
metadatas: {},
|
|
13
|
-
layouts: {
|
|
14
|
+
layouts: {
|
|
15
|
+
list: [],
|
|
16
|
+
edit: []
|
|
17
|
+
}
|
|
14
18
|
};
|
|
15
19
|
const configurationKey = (key)=>`${keys.CONFIGURATION}_${key}`;
|
|
16
20
|
const getModelConfiguration = async (key)=>{
|
|
@@ -19,6 +23,41 @@ const getModelConfiguration = async (key)=>{
|
|
|
19
23
|
});
|
|
20
24
|
return _.merge({}, EMPTY_CONFIG, config);
|
|
21
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Batch load multiple model configurations in a single query.
|
|
28
|
+
*
|
|
29
|
+
* @param keys - Array of configuration keys (e.g., ['components::sections.hero', ...])
|
|
30
|
+
* @returns Map of key -> configuration object
|
|
31
|
+
*/ const getModelConfigurations = async (keys)=>{
|
|
32
|
+
if (keys.length === 0) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
const configKeys = keys.map((k)=>`${STORE_KEY_PREFIX}${configurationKey(k)}`);
|
|
36
|
+
const results = await strapi.db.query('strapi::core-store').findMany({
|
|
37
|
+
where: {
|
|
38
|
+
key: {
|
|
39
|
+
$in: configKeys
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const configMap = {};
|
|
44
|
+
for (const result of results){
|
|
45
|
+
const originalKey = result.key.replace(`${STORE_KEY_PREFIX}configuration_`, '');
|
|
46
|
+
try {
|
|
47
|
+
const value = typeof result.value === 'string' ? JSON.parse(result.value) : result.value;
|
|
48
|
+
configMap[originalKey] = _.merge({}, EMPTY_CONFIG, value);
|
|
49
|
+
} catch {
|
|
50
|
+
strapi.log.warn(`Malformed JSON in core-store key "${result.key}", using default config`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Default missing keys to empty config
|
|
54
|
+
for (const key of keys){
|
|
55
|
+
if (!configMap[key]) {
|
|
56
|
+
configMap[key] = _.merge({}, EMPTY_CONFIG);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return configMap;
|
|
60
|
+
};
|
|
22
61
|
const setModelConfiguration = async (key, value)=>{
|
|
23
62
|
const storedConfig = await getStore().get({
|
|
24
63
|
key: configurationKey(key)
|
|
@@ -41,7 +80,7 @@ const setModelConfiguration = async (key, value)=>{
|
|
|
41
80
|
const deleteKey = (key)=>{
|
|
42
81
|
return strapi.db.query('strapi::core-store').delete({
|
|
43
82
|
where: {
|
|
44
|
-
key:
|
|
83
|
+
key: `${STORE_KEY_PREFIX}configuration_${key}`
|
|
45
84
|
}
|
|
46
85
|
});
|
|
47
86
|
};
|
|
@@ -53,13 +92,21 @@ const findByKey = async (key)=>{
|
|
|
53
92
|
}
|
|
54
93
|
}
|
|
55
94
|
});
|
|
56
|
-
return results.map(({ value })=>
|
|
95
|
+
return results.map(({ key, value })=>{
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse(value);
|
|
98
|
+
} catch {
|
|
99
|
+
strapi.log.warn(`Malformed JSON in core-store key "${key}", skipping entry`);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}).filter((v)=>v !== null);
|
|
57
103
|
};
|
|
58
|
-
const getAllConfigurations = ()=>findByKey(
|
|
104
|
+
const getAllConfigurations = ()=>findByKey(`${STORE_KEY_PREFIX}configuration`);
|
|
59
105
|
var storeUtils = {
|
|
60
106
|
getAllConfigurations,
|
|
61
107
|
findByKey,
|
|
62
108
|
getModelConfiguration,
|
|
109
|
+
getModelConfigurations,
|
|
63
110
|
setModelConfiguration,
|
|
64
111
|
deleteKey,
|
|
65
112
|
keys
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.mjs","sources":["../../../../server/src/services/utils/store.ts"],"sourcesContent":["import _ from 'lodash';\n\nconst keys = {\n CONFIGURATION: 'configuration',\n};\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'content_manager' });\n\n/** Model configuration */\nconst EMPTY_CONFIG = {\n settings: {},\n metadatas: {},\n layouts: {},\n};\n\nconst configurationKey = (key: any) => `${keys.CONFIGURATION}_${key}`;\n\nconst getModelConfiguration = async (key: any) => {\n const config = await getStore().get({ key: configurationKey(key) });\n return _.merge({}, EMPTY_CONFIG, config);\n};\n\nconst setModelConfiguration = async (key: string, value: any) => {\n const storedConfig = (await getStore().get({ key: configurationKey(key) })) || {};\n const currentConfig = { ...storedConfig };\n\n Object.keys(value).forEach((key) => {\n if (value[key] !== null && value[key] !== undefined) {\n _.set(currentConfig, key, value[key]);\n }\n });\n\n if (!_.isEqual(currentConfig, storedConfig)) {\n return getStore().set({\n key: configurationKey(key),\n value: currentConfig,\n });\n }\n};\n\nconst deleteKey = (key: any) => {\n return strapi.db\n .query('strapi::core-store')\n .delete({ where: { key:
|
|
1
|
+
{"version":3,"file":"store.mjs","sources":["../../../../server/src/services/utils/store.ts"],"sourcesContent":["import _ from 'lodash';\n\nconst keys = {\n CONFIGURATION: 'configuration',\n};\n\nconst STORE_KEY_PREFIX = 'plugin_content_manager_';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'content_manager' });\n\n/** Model configuration */\nconst EMPTY_CONFIG = {\n settings: {},\n metadatas: {},\n layouts: { list: [], edit: [] },\n};\n\nconst configurationKey = (key: any) => `${keys.CONFIGURATION}_${key}`;\n\nconst getModelConfiguration = async (key: any) => {\n const config = await getStore().get({ key: configurationKey(key) });\n return _.merge({}, EMPTY_CONFIG, config);\n};\n\n/**\n * Batch load multiple model configurations in a single query.\n *\n * @param keys - Array of configuration keys (e.g., ['components::sections.hero', ...])\n * @returns Map of key -> configuration object\n */\nconst getModelConfigurations = async (keys: string[]) => {\n if (keys.length === 0) {\n return {};\n }\n\n const configKeys = keys.map((k) => `${STORE_KEY_PREFIX}${configurationKey(k)}`);\n const results = await strapi.db.query('strapi::core-store').findMany({\n where: {\n key: { $in: configKeys },\n },\n });\n\n const configMap: Record<string, any> = {};\n for (const result of results) {\n const originalKey = result.key.replace(`${STORE_KEY_PREFIX}configuration_`, '');\n try {\n const value = typeof result.value === 'string' ? JSON.parse(result.value) : result.value;\n configMap[originalKey] = _.merge({}, EMPTY_CONFIG, value);\n } catch {\n strapi.log.warn(`Malformed JSON in core-store key \"${result.key}\", using default config`);\n }\n }\n\n // Default missing keys to empty config\n for (const key of keys) {\n if (!configMap[key]) {\n configMap[key] = _.merge({}, EMPTY_CONFIG);\n }\n }\n\n return configMap;\n};\n\nconst setModelConfiguration = async (key: string, value: any) => {\n const storedConfig = (await getStore().get({ key: configurationKey(key) })) || {};\n const currentConfig = { ...storedConfig };\n\n Object.keys(value).forEach((key) => {\n if (value[key] !== null && value[key] !== undefined) {\n _.set(currentConfig, key, value[key]);\n }\n });\n\n if (!_.isEqual(currentConfig, storedConfig)) {\n return getStore().set({\n key: configurationKey(key),\n value: currentConfig,\n });\n }\n};\n\nconst deleteKey = (key: any) => {\n return strapi.db\n .query('strapi::core-store')\n .delete({ where: { key: `${STORE_KEY_PREFIX}configuration_${key}` } });\n};\n\nconst findByKey = async (key: any) => {\n const results = await strapi.db.query('strapi::core-store').findMany({\n where: {\n key: {\n $startsWith: key,\n },\n },\n });\n\n return results\n .map(({ key, value }) => {\n try {\n return JSON.parse(value);\n } catch {\n strapi.log.warn(`Malformed JSON in core-store key \"${key}\", skipping entry`);\n return null;\n }\n })\n .filter((v) => v !== null);\n};\n\nconst getAllConfigurations = () => findByKey(`${STORE_KEY_PREFIX}configuration`);\n\nexport default {\n getAllConfigurations,\n findByKey,\n getModelConfiguration,\n getModelConfigurations,\n setModelConfiguration,\n deleteKey,\n keys,\n};\n"],"names":["keys","CONFIGURATION","STORE_KEY_PREFIX","getStore","strapi","store","type","name","EMPTY_CONFIG","settings","metadatas","layouts","list","edit","configurationKey","key","getModelConfiguration","config","get","_","merge","getModelConfigurations","length","configKeys","map","k","results","db","query","findMany","where","$in","configMap","result","originalKey","replace","value","JSON","parse","log","warn","setModelConfiguration","storedConfig","currentConfig","Object","forEach","undefined","set","isEqual","deleteKey","delete","findByKey","$startsWith","filter","v","getAllConfigurations"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/collection-types.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"collection-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/collection-types.ts"],"names":[],"mappings":";cA2HkB,GAAG;iBAuDA,GAAG;gBAyDJ,GAAG;gBA0BH,GAAG;eAYJ,GAAG;mBA4CC,GAAG;gBAmBN,GAAG;IAoCrB;;;OAGG;iBACgB,GAAG;qBA6FC,GAAG;uBA6CD,GAAG;mBAyCP,GAAG;iBAyDL,GAAG;oBAwCA,GAAG;6BA6CM,GAAG;wCAqCQ,GAAG;;AApmB/C,wBAqoBE"}
|