@steedos/objectql 2.1.54 → 2.1.58
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/lib/dynamic-load/preload_data.d.ts +3 -0
- package/lib/dynamic-load/preload_data.js +158 -1
- package/lib/dynamic-load/preload_data.js.map +1 -1
- package/lib/dynamic-load/restrictionRules.d.ts +1 -0
- package/lib/dynamic-load/restrictionRules.js +42 -0
- package/lib/dynamic-load/restrictionRules.js.map +1 -0
- package/lib/dynamic-load/shareRules.d.ts +1 -0
- package/lib/dynamic-load/shareRules.js +42 -0
- package/lib/dynamic-load/shareRules.js.map +1 -0
- package/lib/dynamic-load/trigger.d.ts +1 -3
- package/lib/dynamic-load/trigger.js +24 -14
- package/lib/dynamic-load/trigger.js.map +1 -1
- package/lib/formula/core.js +22 -5
- package/lib/formula/core.js.map +1 -1
- package/lib/formula/index.d.ts +2 -0
- package/lib/formula/index.js +28 -1
- package/lib/formula/index.js.map +1 -1
- package/lib/formula/simple_params.d.ts +2 -0
- package/lib/formula/simple_params.js +91 -0
- package/lib/formula/simple_params.js.map +1 -0
- package/lib/formula/type.d.ts +3 -2
- package/lib/formula/type.js.map +1 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/metadata-register/_base.d.ts +3 -1
- package/lib/metadata-register/_base.js +16 -5
- package/lib/metadata-register/_base.js.map +1 -1
- package/lib/metadata-register/permissionFields.d.ts +7 -0
- package/lib/metadata-register/permissionFields.js +18 -0
- package/lib/metadata-register/permissionFields.js.map +1 -0
- package/lib/metadata-register/restrictionRules.d.ts +7 -0
- package/lib/metadata-register/restrictionRules.js +18 -0
- package/lib/metadata-register/restrictionRules.js.map +1 -0
- package/lib/metadata-register/shareRules.d.ts +7 -0
- package/lib/metadata-register/shareRules.js +18 -0
- package/lib/metadata-register/shareRules.js.map +1 -0
- package/lib/ts-types/triggerActionParams.d.ts +1 -0
- package/lib/types/field_permission.d.ts +4 -0
- package/lib/types/field_permission.js +50 -0
- package/lib/types/field_permission.js.map +1 -0
- package/lib/types/object.d.ts +1 -0
- package/lib/types/object.js +333 -163
- package/lib/types/object.js.map +1 -1
- package/lib/types/object_dynamic_load.js +13 -4
- package/lib/types/object_dynamic_load.js.map +1 -1
- package/lib/types/object_permission.d.ts +1 -0
- package/lib/types/object_permission.js +31 -0
- package/lib/types/object_permission.js.map +1 -1
- package/lib/types/restrictionRule.d.ts +13 -0
- package/lib/types/restrictionRule.js +75 -0
- package/lib/types/restrictionRule.js.map +1 -0
- package/lib/types/shareRule.d.ts +13 -0
- package/lib/types/shareRule.js +75 -0
- package/lib/types/shareRule.js.map +1 -0
- package/lib/types/trigger.d.ts +1 -0
- package/lib/types/trigger.js.map +1 -1
- package/lib/util/field.js +4 -4
- package/lib/util/field.js.map +1 -1
- package/lib/util/function_expression.d.ts +2 -0
- package/lib/util/function_expression.js +66 -0
- package/lib/util/function_expression.js.map +1 -0
- package/lib/util/index.d.ts +1 -0
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/transform.js +1 -1
- package/lib/util/transform.js.map +1 -1
- package/package.json +8 -8
- package/src/dynamic-load/preload_data.ts +44 -0
- package/src/dynamic-load/restrictionRules.ts +19 -0
- package/src/dynamic-load/shareRules.ts +19 -0
- package/src/dynamic-load/trigger.ts +22 -15
- package/src/formula/core.ts +19 -2
- package/src/formula/index.ts +21 -1
- package/src/formula/simple_params.ts +92 -0
- package/src/formula/type.ts +4 -3
- package/src/index.ts +4 -1
- package/src/metadata-register/_base.ts +14 -3
- package/src/metadata-register/permissionFields.ts +13 -0
- package/src/metadata-register/restrictionRules.ts +12 -0
- package/src/metadata-register/shareRules.ts +13 -0
- package/src/ts-types/triggerActionParams.ts +1 -0
- package/src/types/field_permission.ts +26 -0
- package/src/types/object.ts +207 -28
- package/src/types/object_dynamic_load.ts +4 -1
- package/src/types/object_permission.ts +32 -0
- package/src/types/restrictionRule.ts +57 -0
- package/src/types/shareRule.ts +57 -0
- package/src/types/trigger.ts +1 -0
- package/src/util/field.ts +4 -4
- package/src/util/function_expression.ts +63 -0
- package/src/util/index.ts +1 -0
- package/src/util/transform.ts +1 -1
|
@@ -35,8 +35,8 @@ export const addObjectListenerConfig = (json: SteedosListenerConfig) => {
|
|
|
35
35
|
throw new Error('missing attribute listenTo')
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
if (!_.isString(json.listenTo) && !_.isFunction(json.listenTo)) {
|
|
39
|
-
throw new Error('listenTo must be a function or string')
|
|
38
|
+
if (!_.isString(json.listenTo) && !_.isFunction(json.listenTo) && !_.isArray(json.listenTo) && !_.isRegExp(json.listenTo)) {
|
|
39
|
+
throw new Error('listenTo must be a function or string or array or regExp')
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
let object_name = '';
|
|
@@ -46,22 +46,29 @@ export const addObjectListenerConfig = (json: SteedosListenerConfig) => {
|
|
|
46
46
|
} else if (_.isFunction(json.listenTo)) {
|
|
47
47
|
object_name = json.listenTo()
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
if(object_name){
|
|
50
|
+
let object = getObjectConfig(object_name);
|
|
51
|
+
if (object) {
|
|
52
|
+
if(!object.listeners){
|
|
53
|
+
object.listeners = {}
|
|
54
|
+
}
|
|
55
|
+
delete json.listenTo
|
|
56
|
+
const license = clone(json);
|
|
57
|
+
license.name = json._id || getMD5(JSONStringify(json));
|
|
58
|
+
object.listeners[license.name] = license
|
|
59
|
+
if(object.datasource === 'meteor'){
|
|
60
|
+
util.extend(object, {triggers: transformListenersToTriggers(object, license)})
|
|
61
|
+
}
|
|
54
62
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
addLazyLoadListeners(object_name, Object.assign({}, json, {listenTo: object_name}));
|
|
64
|
+
return Object.assign({}, json, {listenTo: object_name});
|
|
65
|
+
}else{
|
|
66
|
+
if(_.isRegExp(json.listenTo)){
|
|
67
|
+
return Object.assign({}, json, {listenTo: json.listenTo.toString()});
|
|
68
|
+
}else{
|
|
69
|
+
return json;
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
|
-
addLazyLoadListeners(object_name, Object.assign({}, json, {listenTo: object_name}));
|
|
64
|
-
return Object.assign({}, json, {listenTo: object_name});
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
export const loadObjectTriggers = function (filePath: string){
|
package/src/formula/core.ts
CHANGED
|
@@ -11,6 +11,7 @@ import _ = require('lodash')
|
|
|
11
11
|
// import _eval = require('eval')
|
|
12
12
|
import { extract, parse } from '@steedos/formula';
|
|
13
13
|
import { getFieldSubstitution, FormulonDataType } from './params'
|
|
14
|
+
import { getSimpleParamSubstitution } from './simple_params'
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* 根据公式内容,取出其中{}中的变量
|
|
@@ -63,7 +64,7 @@ export const computeFormulaParams = async (doc: JsonMap, vars: Array<SteedosForm
|
|
|
63
64
|
let params: Array<SteedosFormulaParamTypeConfig> = [];
|
|
64
65
|
const spaceId = doc.space;
|
|
65
66
|
if (vars && vars.length) {
|
|
66
|
-
for (let { key, paths, is_user_var: isUserVar } of vars) {
|
|
67
|
+
for (let { key, paths, is_user_var: isUserVar, is_simple_var: isSimpleVar } of vars) {
|
|
67
68
|
key = key.trim();
|
|
68
69
|
// 如果变量key以$user开头,则解析为userSession,此时paths为空
|
|
69
70
|
let tempValue: any;
|
|
@@ -83,6 +84,16 @@ export const computeFormulaParams = async (doc: JsonMap, vars: Array<SteedosForm
|
|
|
83
84
|
// tempFormulaParams[FormulaUserKey] = currentUserId;
|
|
84
85
|
// tempValue = evalFieldFormula(tepmFormula, tempFormulaParams);
|
|
85
86
|
}
|
|
87
|
+
if(isSimpleVar){
|
|
88
|
+
// 普通变量,取参数值时直接取值,而不用走变量上的paths属性。
|
|
89
|
+
// 注意未传入objectName时,公式中的user var的isSimpleVar为false,还是走下面的paths取值逻辑。
|
|
90
|
+
tempValue = <any>doc[key];
|
|
91
|
+
params.push({
|
|
92
|
+
key: key,
|
|
93
|
+
value: tempValue
|
|
94
|
+
});
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
86
97
|
tempValue = _.reduce(paths, (reslut, next, index) => {
|
|
87
98
|
if (index === 0) {
|
|
88
99
|
if (isUserVar) {
|
|
@@ -176,7 +187,13 @@ export const runFormula = function (formula: string, params: Array<SteedosFormul
|
|
|
176
187
|
// formulaParams[key] = value;
|
|
177
188
|
// 把{}括起来的变量替换为计算得到的变量值
|
|
178
189
|
// formula = formula.replace(`{${key}}`, `__params["${key}"]`);
|
|
179
|
-
|
|
190
|
+
if(path){
|
|
191
|
+
formulaParams[key] = getFieldSubstitution(path.reference_from, path.field_name, value, blankValue);
|
|
192
|
+
}
|
|
193
|
+
else{
|
|
194
|
+
// 变量中没有path属性说明是普通变量
|
|
195
|
+
formulaParams[key] = getSimpleParamSubstitution(value, blankValue);
|
|
196
|
+
}
|
|
180
197
|
});
|
|
181
198
|
|
|
182
199
|
// console.log("===runFormula===formula====", formula);
|
package/src/formula/index.ts
CHANGED
|
@@ -58,4 +58,24 @@ async function _computeFormula(formula: string, objectName:string, data: any, cu
|
|
|
58
58
|
return runFormula(formula, params, options, {objectName});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
export const computeFormula = _computeFormula
|
|
61
|
+
export const computeFormula = _computeFormula
|
|
62
|
+
|
|
63
|
+
async function _computeSimpleFormula(formula: string, data: any, currentUserId?: string, spaceId?: string, options?: SteedosFormulaOptions) {
|
|
64
|
+
// objectConfig参数值设置为null传入computeFormulaVarsAndQuotes表示计算不带objectConfig参数的普通公式变量
|
|
65
|
+
const varsAndQuotes = await computeFormulaVarsAndQuotes(formula, null);
|
|
66
|
+
const vars = varsAndQuotes.vars;
|
|
67
|
+
if (!currentUserId) {
|
|
68
|
+
const required = isCurrentUserIdRequiredForFormulaVars(vars);
|
|
69
|
+
if(required){
|
|
70
|
+
throw new Error(`The param 'currentUserId' is required for formula ${formula.replace("$", "\\$")}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if(spaceId){
|
|
74
|
+
data.space = spaceId;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let params = await computeFormulaParams(data, vars, currentUserId);
|
|
78
|
+
return runFormula(formula, params, options);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const computeSimpleFormula = _computeSimpleFormula
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { SteedosFormulaBlankValue } from './type';
|
|
2
|
+
import { FormulonDataType } from './params';
|
|
3
|
+
|
|
4
|
+
const VALUE_TYPES_NOT_SUPPORTED = ["function"];
|
|
5
|
+
|
|
6
|
+
function getSubstitutionDataType(value: any){
|
|
7
|
+
const valueType = typeof value;
|
|
8
|
+
let dateType: FormulonDataType;
|
|
9
|
+
if(VALUE_TYPES_NOT_SUPPORTED.indexOf(dateType) > -1){
|
|
10
|
+
throw new Error(`runFormula:Catch an error the param type "${valueType}" is not supported while eval formula with the params value: "${value}"`);
|
|
11
|
+
}
|
|
12
|
+
switch (valueType) {
|
|
13
|
+
case 'string':
|
|
14
|
+
dateType = FormulonDataType.Text;
|
|
15
|
+
break;
|
|
16
|
+
case 'number':
|
|
17
|
+
dateType = FormulonDataType.Number;
|
|
18
|
+
break;
|
|
19
|
+
case 'boolean':
|
|
20
|
+
dateType = FormulonDataType.Checkbox;
|
|
21
|
+
break;
|
|
22
|
+
case 'object':
|
|
23
|
+
if(value === null){
|
|
24
|
+
dateType = FormulonDataType.Null;
|
|
25
|
+
}
|
|
26
|
+
else if (value instanceof Date){
|
|
27
|
+
dateType = FormulonDataType.Datetime;
|
|
28
|
+
}
|
|
29
|
+
else{
|
|
30
|
+
throw new Error(`runFormula:Catch an error the param type "${valueType}" is not supported while eval formula with the params value: "${value}"`);
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
case 'undefined':
|
|
34
|
+
dateType = FormulonDataType.Null;
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
return dateType;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getSubstitutionOptions(dataType: string, value: any){
|
|
43
|
+
switch (dataType) {
|
|
44
|
+
case FormulonDataType.Number:
|
|
45
|
+
let scale = 0;
|
|
46
|
+
let str = value.toString();
|
|
47
|
+
let dotStr = str.toString().split(".")[1];
|
|
48
|
+
let dotCount = dotStr && dotStr.length;
|
|
49
|
+
if(dotCount > 0){
|
|
50
|
+
scale = dotCount;
|
|
51
|
+
}
|
|
52
|
+
return { scale };
|
|
53
|
+
case FormulonDataType.Text:
|
|
54
|
+
return {length: Number.MAX_VALUE};
|
|
55
|
+
default:
|
|
56
|
+
return ;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getSubstitutionValue(dataType: string, value: any, blankValue: SteedosFormulaBlankValue){
|
|
61
|
+
switch (dataType) {
|
|
62
|
+
case FormulonDataType.Text:
|
|
63
|
+
if(value === null || value === undefined){
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case FormulonDataType.Number:
|
|
68
|
+
if(value === null || value === undefined){
|
|
69
|
+
if(blankValue === SteedosFormulaBlankValue.blanks){
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
else{
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function getSimpleParamSubstitution(value: any, blankValue: SteedosFormulaBlankValue){
|
|
84
|
+
let fieldSubstitution: any = {
|
|
85
|
+
type: 'literal',
|
|
86
|
+
value: value
|
|
87
|
+
}
|
|
88
|
+
fieldSubstitution.dataType = getSubstitutionDataType(value);
|
|
89
|
+
fieldSubstitution.options = getSubstitutionOptions(fieldSubstitution.dataType, value);
|
|
90
|
+
fieldSubstitution.value = getSubstitutionValue(fieldSubstitution.dataType, value, blankValue);
|
|
91
|
+
return fieldSubstitution;
|
|
92
|
+
}
|
package/src/formula/type.ts
CHANGED
|
@@ -44,7 +44,7 @@ export type SteedosFormulaVarPathTypeConfig = {
|
|
|
44
44
|
*/
|
|
45
45
|
export type SteedosFormulaParamTypeConfig = {
|
|
46
46
|
key: string,
|
|
47
|
-
path
|
|
47
|
+
path?: any,
|
|
48
48
|
value: any
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -62,8 +62,9 @@ export type SteedosFormulaParamTypeConfig = {
|
|
|
62
62
|
*/
|
|
63
63
|
export type SteedosFormulaVarTypeConfig = {
|
|
64
64
|
key: string,
|
|
65
|
-
paths
|
|
66
|
-
is_user_var?: boolean
|
|
65
|
+
paths?: Array<SteedosFormulaVarPathTypeConfig>,
|
|
66
|
+
is_user_var?: boolean,
|
|
67
|
+
is_simple_var?: boolean //当不传入objectApiName时变量上设置该属性表示一个普通的变量,此时paths为空
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
export type SteedosFieldFormulaTypeConfig = {
|
package/src/index.ts
CHANGED
|
@@ -10,4 +10,7 @@ export * from "./dynamic-load"
|
|
|
10
10
|
export * from './metadata-register/query'
|
|
11
11
|
export * from './metadata-register/chart'
|
|
12
12
|
export * from './metadata-register/page'
|
|
13
|
-
export * from './metadata-register/tab'
|
|
13
|
+
export * from './metadata-register/tab'
|
|
14
|
+
export * from './metadata-register/shareRules'
|
|
15
|
+
export * from './metadata-register/restrictionRules'
|
|
16
|
+
export * from './metadata-register/permissionFields'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { JsonMap } from "@salesforce/ts-types"
|
|
2
|
+
import * as _ from 'lodash';
|
|
1
3
|
const clone = require('clone');
|
|
2
4
|
export class RegisterBase{
|
|
3
5
|
serviceName;
|
|
@@ -5,9 +7,14 @@ export class RegisterBase{
|
|
|
5
7
|
this.serviceName = serviceName;
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
getApiName(metadata) {
|
|
11
|
+
return metadata._id || metadata.name;
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
async register(broker, packageServiceName, config){
|
|
9
15
|
const metadata = clone(config);
|
|
10
|
-
const res = await broker.call(`${this.serviceName}.add`, {apiName:
|
|
16
|
+
const res = await broker.call(`${this.serviceName}.add`, { apiName: this.getApiName(metadata), data: metadata }, {
|
|
17
|
+
meta: {
|
|
11
18
|
metadataServiceName: packageServiceName,
|
|
12
19
|
caller: {
|
|
13
20
|
nodeID: broker.nodeID,
|
|
@@ -19,8 +26,12 @@ export class RegisterBase{
|
|
|
19
26
|
return res;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
async remove(broker,
|
|
23
|
-
|
|
29
|
+
async remove(broker, metadataApiNameOrConfig: string | JsonMap) {
|
|
30
|
+
let metadataApiName = metadataApiNameOrConfig;
|
|
31
|
+
if (_.isObject(metadataApiName)) {
|
|
32
|
+
metadataApiName = this.getApiName(metadataApiNameOrConfig);
|
|
33
|
+
}
|
|
34
|
+
const res = await broker.call(`${this.serviceName}.delete`, { fullName: metadataApiName, metadataApiName: metadataApiName });
|
|
24
35
|
return res;
|
|
25
36
|
}
|
|
26
37
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RegisterBase } from "./_base";
|
|
2
|
+
const SERVICE_NAME = 'permission_fields';
|
|
3
|
+
class RegisterPermissionFields extends RegisterBase {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(SERVICE_NAME);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
getApiName(config) {
|
|
9
|
+
return `${config.name}`
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const registerPermissionFields = new RegisterPermissionFields();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RegisterBase } from "./_base";
|
|
2
|
+
const SERVICE_NAME = 'restriction_rules';
|
|
3
|
+
class RegisterRestrictionRules extends RegisterBase {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(SERVICE_NAME);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
getApiName(config) {
|
|
9
|
+
return `${config.object_name}.${config.name}`
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export const registerRestrictionRules = new RegisterRestrictionRules();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RegisterBase } from "./_base";
|
|
2
|
+
const SERVICE_NAME = 'share_rules';
|
|
3
|
+
class RegisterShareRules extends RegisterBase {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(SERVICE_NAME);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
getApiName(config) {
|
|
9
|
+
return `${config.object_name}.${config.name}`
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const registerShareRules = new RegisterShareRules();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { registerPermissionFields } from '../metadata-register/permissionFields';
|
|
2
|
+
import { getSteedosSchema } from '../types'
|
|
3
|
+
import * as _ from 'lodash'
|
|
4
|
+
|
|
5
|
+
export class FieldPermission {
|
|
6
|
+
|
|
7
|
+
static async getObjectFieldsPermission(objectApiName, permissionSetApiName) {
|
|
8
|
+
const schema = getSteedosSchema();
|
|
9
|
+
return await registerPermissionFields.find(schema.broker, {
|
|
10
|
+
pattern: `${permissionSetApiName}.${objectApiName}.*`
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static async getObjectFieldsPermissionGroupRole(objectApiName) {
|
|
15
|
+
const permissions = await this.getObjectFieldsPermission(objectApiName, '*');
|
|
16
|
+
const result = {};
|
|
17
|
+
_.each(permissions, (permission) => {
|
|
18
|
+
const { permission_set_id, field, editable, readable } = permission.metadata;
|
|
19
|
+
if (!result[permission_set_id]) {
|
|
20
|
+
result[permission_set_id] = [];
|
|
21
|
+
}
|
|
22
|
+
result[permission_set_id].push({ field: field, read: readable, edit: editable })
|
|
23
|
+
})
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
}
|