@contember/engine-content-api 2.0.0-rc.1 → 2.0.0-rc.2
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/development/src/acl/PermissionFactory.cjs +80 -39
- package/dist/development/src/acl/PermissionFactory.cjs.map +1 -1
- package/dist/development/src/acl/PermissionFactory.js +80 -39
- package/dist/development/src/acl/PermissionFactory.js.map +1 -1
- package/dist/production/src/acl/PermissionFactory.cjs +80 -39
- package/dist/production/src/acl/PermissionFactory.cjs.map +1 -1
- package/dist/production/src/acl/PermissionFactory.js +80 -39
- package/dist/production/src/acl/PermissionFactory.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/acl/PermissionFactory.d.ts +3 -0
- package/dist/types/acl/PermissionFactory.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/acl/PermissionFactory.ts +111 -42
- package/tests/cases/unit/permissionMerger.test.ts +180 -0
|
@@ -61,7 +61,7 @@ class PermissionFactory {
|
|
|
61
61
|
const predicateReferences = Object.entries(fieldPermissions).filter(([key]) => key !== entity.primary).map(([key, value]) => value).filter((value) => value !== false).filter((value, index, array) => array.indexOf(value) === index);
|
|
62
62
|
let idPermissions = fieldPermissions[entity.primary] || false;
|
|
63
63
|
for (let predicateReference of predicateReferences) {
|
|
64
|
-
const
|
|
64
|
+
const { predicateDefinition, predicate } = this.mergePredicates(
|
|
65
65
|
entityPredicates,
|
|
66
66
|
idPermissions,
|
|
67
67
|
entityPredicates,
|
|
@@ -100,36 +100,24 @@ class PermissionFactory {
|
|
|
100
100
|
operations.customPrimary = true;
|
|
101
101
|
}
|
|
102
102
|
const noRoot = [];
|
|
103
|
-
|
|
103
|
+
for (let operation of [
|
|
104
104
|
"create",
|
|
105
105
|
"read",
|
|
106
106
|
"update"
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const rightNoRoot = right.operations.noRoot?.includes(operation) || false;
|
|
111
|
-
if (leftNoRoot && rightNoRoot) {
|
|
107
|
+
]) {
|
|
108
|
+
const { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot2 } = this.mergeOperationPermissions(left, right, operation);
|
|
109
|
+
if (opNoRoot2) {
|
|
112
110
|
noRoot.push(operation);
|
|
113
111
|
}
|
|
114
|
-
|
|
115
|
-
const rightFieldPermissions = rightNoRoot && !leftNoRoot ? {} : right.operations[operation] || {};
|
|
116
|
-
const [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(
|
|
117
|
-
left.predicates,
|
|
118
|
-
leftFieldPermissions,
|
|
119
|
-
right.predicates,
|
|
120
|
-
rightFieldPermissions
|
|
121
|
-
);
|
|
122
|
-
predicates = { ...predicates, ...operationPredicates };
|
|
112
|
+
predicates = { ...predicates, ...opPredicates };
|
|
123
113
|
if (Object.keys(fieldPermissions).length > 0) {
|
|
124
114
|
operations[operation] = fieldPermissions;
|
|
125
115
|
}
|
|
126
116
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
right.operations.delete || false
|
|
132
|
-
);
|
|
117
|
+
const { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right);
|
|
118
|
+
if (opNoRoot) {
|
|
119
|
+
noRoot.push("delete");
|
|
120
|
+
}
|
|
133
121
|
if (predicate === true) {
|
|
134
122
|
operations.delete = true;
|
|
135
123
|
} else if (predicateDefinition !== void 0 && typeof predicate === "string") {
|
|
@@ -144,47 +132,94 @@ class PermissionFactory {
|
|
|
144
132
|
operations
|
|
145
133
|
};
|
|
146
134
|
}
|
|
147
|
-
|
|
148
|
-
const
|
|
135
|
+
mergeOperationPermissions(left, right, operation) {
|
|
136
|
+
const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation);
|
|
137
|
+
return {
|
|
138
|
+
noRoot,
|
|
139
|
+
...this.mergeFieldPermissions(
|
|
140
|
+
left.predicates,
|
|
141
|
+
leftPermissions,
|
|
142
|
+
right.predicates,
|
|
143
|
+
rightPermissions
|
|
144
|
+
)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
mergeDeletePermissions(left, right) {
|
|
148
|
+
const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, "delete");
|
|
149
|
+
return {
|
|
150
|
+
noRoot,
|
|
151
|
+
...this.mergePredicates(
|
|
152
|
+
left.predicates,
|
|
153
|
+
leftPermissions,
|
|
154
|
+
right.predicates,
|
|
155
|
+
rightPermissions
|
|
156
|
+
)
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
resolveNoRoot(left, right, operation) {
|
|
160
|
+
const leftRootForbidden = left.operations.noRoot?.includes(operation) || false;
|
|
161
|
+
const rightRootForbidden = right.operations.noRoot?.includes(operation) || false;
|
|
162
|
+
const leftPermissions = left.operations[operation];
|
|
163
|
+
const rightPermissions = right.operations[operation];
|
|
164
|
+
const rootForbidden = leftRootForbidden && rightRootForbidden || leftRootForbidden && !rightPermissions || rightRootForbidden && !leftPermissions;
|
|
165
|
+
const resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? void 0 : leftPermissions;
|
|
166
|
+
const resolvedRightPermissions = !rootForbidden && rightRootForbidden ? void 0 : rightPermissions;
|
|
167
|
+
return {
|
|
168
|
+
noRoot: rootForbidden,
|
|
169
|
+
leftPermissions: resolvedLeftPermissions,
|
|
170
|
+
rightPermissions: resolvedRightPermissions
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
mergeFieldPermissions(leftPredicates, leftFieldPermissions = {}, rightPredicates, rightFieldPermissions = {}) {
|
|
174
|
+
const permissions = {};
|
|
149
175
|
const predicates = {};
|
|
150
176
|
for (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {
|
|
151
|
-
const
|
|
177
|
+
const { predicateDefinition, predicate } = this.mergePredicates(
|
|
152
178
|
leftPredicates,
|
|
153
179
|
leftFieldPermissions[field] || false,
|
|
154
180
|
rightPredicates,
|
|
155
181
|
rightFieldPermissions[field] || false
|
|
156
182
|
);
|
|
157
183
|
if (predicate === true) {
|
|
158
|
-
|
|
184
|
+
permissions[field] = true;
|
|
159
185
|
} else if (predicateDefinition !== void 0 && typeof predicate === "string") {
|
|
160
|
-
|
|
186
|
+
permissions[field] = predicate;
|
|
161
187
|
predicates[predicate] = predicateDefinition;
|
|
162
188
|
}
|
|
163
189
|
}
|
|
164
|
-
return
|
|
190
|
+
return { predicates, permissions };
|
|
165
191
|
}
|
|
166
|
-
mergePredicates(leftPredicates, leftReference, rightPredicates, rightReference) {
|
|
192
|
+
mergePredicates(leftPredicates, leftReference = false, rightPredicates, rightReference = false) {
|
|
167
193
|
if (leftReference === true || rightReference === true) {
|
|
168
|
-
return
|
|
194
|
+
return {
|
|
195
|
+
predicate: true,
|
|
196
|
+
predicateDefinition: void 0
|
|
197
|
+
};
|
|
169
198
|
}
|
|
170
199
|
if (leftReference !== false && rightReference !== false) {
|
|
171
200
|
const leftPredicate = leftPredicates[leftReference];
|
|
172
201
|
const rightPredicate = rightPredicates[rightReference];
|
|
173
202
|
if (leftPredicate === rightPredicate) {
|
|
174
|
-
return
|
|
203
|
+
return {
|
|
204
|
+
predicate: leftReference,
|
|
205
|
+
predicateDefinition: leftPredicate
|
|
206
|
+
};
|
|
175
207
|
}
|
|
176
208
|
let predicateName = "__merge__" + leftReference + "__" + rightReference;
|
|
177
209
|
while (leftPredicates[predicateName]) {
|
|
178
210
|
predicateName += "_";
|
|
179
211
|
}
|
|
180
|
-
return
|
|
181
|
-
|
|
212
|
+
return {
|
|
213
|
+
predicate: predicateName,
|
|
214
|
+
predicateDefinition: {
|
|
182
215
|
or: [leftPredicate, rightPredicate]
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
];
|
|
216
|
+
}
|
|
217
|
+
};
|
|
186
218
|
} else if (leftReference !== false) {
|
|
187
|
-
return
|
|
219
|
+
return {
|
|
220
|
+
predicate: leftReference,
|
|
221
|
+
predicateDefinition: leftPredicates[leftReference]
|
|
222
|
+
};
|
|
188
223
|
} else if (rightReference !== false) {
|
|
189
224
|
let predicateName = rightReference;
|
|
190
225
|
if (rightPredicates !== leftPredicates) {
|
|
@@ -192,9 +227,15 @@ class PermissionFactory {
|
|
|
192
227
|
predicateName += "_";
|
|
193
228
|
}
|
|
194
229
|
}
|
|
195
|
-
return
|
|
230
|
+
return {
|
|
231
|
+
predicate: predicateName,
|
|
232
|
+
predicateDefinition: rightPredicates[rightReference]
|
|
233
|
+
};
|
|
196
234
|
} else {
|
|
197
|
-
return
|
|
235
|
+
return {
|
|
236
|
+
predicate: false,
|
|
237
|
+
predicateDefinition: void 0
|
|
238
|
+
};
|
|
198
239
|
}
|
|
199
240
|
}
|
|
200
241
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionFactory.cjs","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tconst operationNames: (keyof Pick<Acl.EntityOperations, 'create' | 'read' | 'update'>)[] = [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t]\n\n\t\tfor (let operation of operationNames) {\n\t\t\tconst leftNoRoot = left.operations.noRoot?.includes(operation) || false\n\t\t\tconst rightNoRoot = right.operations.noRoot?.includes(operation) || false\n\t\t\tif (leftNoRoot && rightNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tconst leftFieldPermissions: Acl.FieldPermissions = leftNoRoot && !rightNoRoot ? {} : (left.operations[operation] || {})\n\t\t\tconst rightFieldPermissions: Acl.FieldPermissions = rightNoRoot && !leftNoRoot ? {} : (right.operations[operation] || {})\n\t\t\tconst [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftFieldPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightFieldPermissions,\n\t\t\t)\n\t\t\tpredicates = { ...predicates, ...operationPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\tleft.predicates,\n\t\t\tleft.operations.delete || false,\n\t\t\tright.predicates,\n\t\t\tright.operations.delete || false,\n\t\t)\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions,\n\t): [Acl.PredicateMap, Acl.FieldPermissions] {\n\t\tconst fields: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tfields[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tfields[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn [predicates, fields]\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate,\n\t): [Acl.PredicateDefinition, Acl.PredicateReference] | [undefined, boolean] {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn [undefined, true]\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn [leftPredicate, leftReference]\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t\tpredicateName,\n\t\t\t]\n\t\t} else if (leftReference !== false) {\n\t\t\treturn [leftPredicates[leftReference], leftReference]\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [rightPredicates[rightReference], predicateName]\n\t\t} else {\n\t\t\treturn [undefined, false]\n\t\t}\n\t}\n}\n"],"names":["mapObject","PredicateDefinitionProcessor","getEntity","prefixVariable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PermissionFactory.cjs","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tfor (let operation of [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t] as const) {\n\n\t\t\tconst { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot } = this.mergeOperationPermissions(left, right, operation)\n\n\t\t\tif (opNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tpredicates = { ...predicates, ...opPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right)\n\t\tif (opNoRoot) {\n\t\t\tnoRoot.push('delete')\n\t\t}\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\n\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\n\tprivate mergeOperationPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: 'create' | 'read' | 'update'): {\n\t\tnoRoot: boolean\n\t\tpredicates: Acl.PredicateMap\n\t\tpermissions: Acl.FieldPermissions\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation)\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate mergeDeletePermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): {\n\t\tnoRoot: boolean\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, 'delete')\n\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergePredicates(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate resolveNoRoot<const Op extends`${Acl.Operation}`>(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: Op): {\n\t\tnoRoot: boolean\n\t\tleftPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t\trightPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t} {\n\t\tconst leftRootForbidden = left.operations.noRoot?.includes(operation) || false\n\t\tconst rightRootForbidden = right.operations.noRoot?.includes(operation) || false\n\t\tconst leftPermissions = left.operations[operation]\n\t\tconst rightPermissions = right.operations[operation]\n\n\t\tconst rootForbidden = (leftRootForbidden && rightRootForbidden)\n\t\t\t|| (leftRootForbidden && !rightPermissions)\n\t\t\t|| (rightRootForbidden && !leftPermissions)\n\n\t\tconst resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? undefined : leftPermissions\n\t\tconst resolvedRightPermissions = !rootForbidden && rightRootForbidden ? undefined : rightPermissions\n\n\t\treturn {\n\t\t\tnoRoot: rootForbidden,\n\t\t\tleftPermissions: resolvedLeftPermissions,\n\t\t\trightPermissions: resolvedRightPermissions,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t): {predicates: Acl.PredicateMap; permissions: Acl.FieldPermissions} {\n\t\tconst permissions: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tpermissions[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tpermissions[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn { predicates, permissions }\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate | undefined = false,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate | undefined = false,\n\t): {\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn {\n\t\t\t\tpredicate: true,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn {\n\t\t\t\t\tpredicate: leftReference,\n\t\t\t\t\tpredicateDefinition: leftPredicate,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: {\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t}\n\t\t} else if (leftReference !== false) {\n\t\t\treturn {\n\t\t\t\tpredicate: leftReference,\n\t\t\t\tpredicateDefinition: leftPredicates[leftReference],\n\t\t\t}\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: rightPredicates[rightReference],\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tpredicate: false,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["mapObject","PredicateDefinitionProcessor","getEntity","prefixVariable","opNoRoot"],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ class PermissionFactory {
|
|
|
59
59
|
const predicateReferences = Object.entries(fieldPermissions).filter(([key]) => key !== entity.primary).map(([key, value]) => value).filter((value) => value !== false).filter((value, index, array) => array.indexOf(value) === index);
|
|
60
60
|
let idPermissions = fieldPermissions[entity.primary] || false;
|
|
61
61
|
for (let predicateReference of predicateReferences) {
|
|
62
|
-
const
|
|
62
|
+
const { predicateDefinition, predicate } = this.mergePredicates(
|
|
63
63
|
entityPredicates,
|
|
64
64
|
idPermissions,
|
|
65
65
|
entityPredicates,
|
|
@@ -98,36 +98,24 @@ class PermissionFactory {
|
|
|
98
98
|
operations.customPrimary = true;
|
|
99
99
|
}
|
|
100
100
|
const noRoot = [];
|
|
101
|
-
|
|
101
|
+
for (let operation of [
|
|
102
102
|
"create",
|
|
103
103
|
"read",
|
|
104
104
|
"update"
|
|
105
|
-
]
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const rightNoRoot = right.operations.noRoot?.includes(operation) || false;
|
|
109
|
-
if (leftNoRoot && rightNoRoot) {
|
|
105
|
+
]) {
|
|
106
|
+
const { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot2 } = this.mergeOperationPermissions(left, right, operation);
|
|
107
|
+
if (opNoRoot2) {
|
|
110
108
|
noRoot.push(operation);
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
const rightFieldPermissions = rightNoRoot && !leftNoRoot ? {} : right.operations[operation] || {};
|
|
114
|
-
const [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(
|
|
115
|
-
left.predicates,
|
|
116
|
-
leftFieldPermissions,
|
|
117
|
-
right.predicates,
|
|
118
|
-
rightFieldPermissions
|
|
119
|
-
);
|
|
120
|
-
predicates = { ...predicates, ...operationPredicates };
|
|
110
|
+
predicates = { ...predicates, ...opPredicates };
|
|
121
111
|
if (Object.keys(fieldPermissions).length > 0) {
|
|
122
112
|
operations[operation] = fieldPermissions;
|
|
123
113
|
}
|
|
124
114
|
}
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
right.operations.delete || false
|
|
130
|
-
);
|
|
115
|
+
const { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right);
|
|
116
|
+
if (opNoRoot) {
|
|
117
|
+
noRoot.push("delete");
|
|
118
|
+
}
|
|
131
119
|
if (predicate === true) {
|
|
132
120
|
operations.delete = true;
|
|
133
121
|
} else if (predicateDefinition !== void 0 && typeof predicate === "string") {
|
|
@@ -142,47 +130,94 @@ class PermissionFactory {
|
|
|
142
130
|
operations
|
|
143
131
|
};
|
|
144
132
|
}
|
|
145
|
-
|
|
146
|
-
const
|
|
133
|
+
mergeOperationPermissions(left, right, operation) {
|
|
134
|
+
const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation);
|
|
135
|
+
return {
|
|
136
|
+
noRoot,
|
|
137
|
+
...this.mergeFieldPermissions(
|
|
138
|
+
left.predicates,
|
|
139
|
+
leftPermissions,
|
|
140
|
+
right.predicates,
|
|
141
|
+
rightPermissions
|
|
142
|
+
)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
mergeDeletePermissions(left, right) {
|
|
146
|
+
const { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, "delete");
|
|
147
|
+
return {
|
|
148
|
+
noRoot,
|
|
149
|
+
...this.mergePredicates(
|
|
150
|
+
left.predicates,
|
|
151
|
+
leftPermissions,
|
|
152
|
+
right.predicates,
|
|
153
|
+
rightPermissions
|
|
154
|
+
)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
resolveNoRoot(left, right, operation) {
|
|
158
|
+
const leftRootForbidden = left.operations.noRoot?.includes(operation) || false;
|
|
159
|
+
const rightRootForbidden = right.operations.noRoot?.includes(operation) || false;
|
|
160
|
+
const leftPermissions = left.operations[operation];
|
|
161
|
+
const rightPermissions = right.operations[operation];
|
|
162
|
+
const rootForbidden = leftRootForbidden && rightRootForbidden || leftRootForbidden && !rightPermissions || rightRootForbidden && !leftPermissions;
|
|
163
|
+
const resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? void 0 : leftPermissions;
|
|
164
|
+
const resolvedRightPermissions = !rootForbidden && rightRootForbidden ? void 0 : rightPermissions;
|
|
165
|
+
return {
|
|
166
|
+
noRoot: rootForbidden,
|
|
167
|
+
leftPermissions: resolvedLeftPermissions,
|
|
168
|
+
rightPermissions: resolvedRightPermissions
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
mergeFieldPermissions(leftPredicates, leftFieldPermissions = {}, rightPredicates, rightFieldPermissions = {}) {
|
|
172
|
+
const permissions = {};
|
|
147
173
|
const predicates = {};
|
|
148
174
|
for (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {
|
|
149
|
-
const
|
|
175
|
+
const { predicateDefinition, predicate } = this.mergePredicates(
|
|
150
176
|
leftPredicates,
|
|
151
177
|
leftFieldPermissions[field] || false,
|
|
152
178
|
rightPredicates,
|
|
153
179
|
rightFieldPermissions[field] || false
|
|
154
180
|
);
|
|
155
181
|
if (predicate === true) {
|
|
156
|
-
|
|
182
|
+
permissions[field] = true;
|
|
157
183
|
} else if (predicateDefinition !== void 0 && typeof predicate === "string") {
|
|
158
|
-
|
|
184
|
+
permissions[field] = predicate;
|
|
159
185
|
predicates[predicate] = predicateDefinition;
|
|
160
186
|
}
|
|
161
187
|
}
|
|
162
|
-
return
|
|
188
|
+
return { predicates, permissions };
|
|
163
189
|
}
|
|
164
|
-
mergePredicates(leftPredicates, leftReference, rightPredicates, rightReference) {
|
|
190
|
+
mergePredicates(leftPredicates, leftReference = false, rightPredicates, rightReference = false) {
|
|
165
191
|
if (leftReference === true || rightReference === true) {
|
|
166
|
-
return
|
|
192
|
+
return {
|
|
193
|
+
predicate: true,
|
|
194
|
+
predicateDefinition: void 0
|
|
195
|
+
};
|
|
167
196
|
}
|
|
168
197
|
if (leftReference !== false && rightReference !== false) {
|
|
169
198
|
const leftPredicate = leftPredicates[leftReference];
|
|
170
199
|
const rightPredicate = rightPredicates[rightReference];
|
|
171
200
|
if (leftPredicate === rightPredicate) {
|
|
172
|
-
return
|
|
201
|
+
return {
|
|
202
|
+
predicate: leftReference,
|
|
203
|
+
predicateDefinition: leftPredicate
|
|
204
|
+
};
|
|
173
205
|
}
|
|
174
206
|
let predicateName = "__merge__" + leftReference + "__" + rightReference;
|
|
175
207
|
while (leftPredicates[predicateName]) {
|
|
176
208
|
predicateName += "_";
|
|
177
209
|
}
|
|
178
|
-
return
|
|
179
|
-
|
|
210
|
+
return {
|
|
211
|
+
predicate: predicateName,
|
|
212
|
+
predicateDefinition: {
|
|
180
213
|
or: [leftPredicate, rightPredicate]
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
];
|
|
214
|
+
}
|
|
215
|
+
};
|
|
184
216
|
} else if (leftReference !== false) {
|
|
185
|
-
return
|
|
217
|
+
return {
|
|
218
|
+
predicate: leftReference,
|
|
219
|
+
predicateDefinition: leftPredicates[leftReference]
|
|
220
|
+
};
|
|
186
221
|
} else if (rightReference !== false) {
|
|
187
222
|
let predicateName = rightReference;
|
|
188
223
|
if (rightPredicates !== leftPredicates) {
|
|
@@ -190,9 +225,15 @@ class PermissionFactory {
|
|
|
190
225
|
predicateName += "_";
|
|
191
226
|
}
|
|
192
227
|
}
|
|
193
|
-
return
|
|
228
|
+
return {
|
|
229
|
+
predicate: predicateName,
|
|
230
|
+
predicateDefinition: rightPredicates[rightReference]
|
|
231
|
+
};
|
|
194
232
|
} else {
|
|
195
|
-
return
|
|
233
|
+
return {
|
|
234
|
+
predicate: false,
|
|
235
|
+
predicateDefinition: void 0
|
|
236
|
+
};
|
|
196
237
|
}
|
|
197
238
|
}
|
|
198
239
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionFactory.js","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tconst operationNames: (keyof Pick<Acl.EntityOperations, 'create' | 'read' | 'update'>)[] = [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t]\n\n\t\tfor (let operation of operationNames) {\n\t\t\tconst leftNoRoot = left.operations.noRoot?.includes(operation) || false\n\t\t\tconst rightNoRoot = right.operations.noRoot?.includes(operation) || false\n\t\t\tif (leftNoRoot && rightNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tconst leftFieldPermissions: Acl.FieldPermissions = leftNoRoot && !rightNoRoot ? {} : (left.operations[operation] || {})\n\t\t\tconst rightFieldPermissions: Acl.FieldPermissions = rightNoRoot && !leftNoRoot ? {} : (right.operations[operation] || {})\n\t\t\tconst [operationPredicates, fieldPermissions] = this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftFieldPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightFieldPermissions,\n\t\t\t)\n\t\t\tpredicates = { ...predicates, ...operationPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\tleft.predicates,\n\t\t\tleft.operations.delete || false,\n\t\t\tright.predicates,\n\t\t\tright.operations.delete || false,\n\t\t)\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions,\n\t): [Acl.PredicateMap, Acl.FieldPermissions] {\n\t\tconst fields: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst [predicateDefinition, predicate] = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tfields[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tfields[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn [predicates, fields]\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate,\n\t): [Acl.PredicateDefinition, Acl.PredicateReference] | [undefined, boolean] {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn [undefined, true]\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn [leftPredicate, leftReference]\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t\tpredicateName,\n\t\t\t]\n\t\t} else if (leftReference !== false) {\n\t\t\treturn [leftPredicates[leftReference], leftReference]\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [rightPredicates[rightReference], predicateName]\n\t\t} else {\n\t\t\treturn [undefined, false]\n\t\t}\n\t}\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PermissionFactory.js","sources":["../../../../../packages/engine-content-api/src/acl/PermissionFactory.ts"],"sourcesContent":["import { Acl, Model, Schema, Writable } from '@contember/schema'\nimport { getEntity, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { mapObject } from '../utils'\nimport { prefixVariable } from './VariableUtils'\n\nexport interface Identity {\n\tprojectRoles: readonly string[]\n}\n\nexport class PermissionFactory {\n\tpublic create(schema: Schema, roles: readonly string[], prefix?: string): Acl.Permissions {\n\t\tlet result: Acl.Permissions = {}\n\t\tfor (let role of roles) {\n\t\t\tconst roleDefinition = schema.acl.roles[role] || { entities: {} }\n\t\t\tlet rolePermissions: Acl.Permissions = this.prefixPredicatesWithRole(schema.model, roleDefinition.entities, prefix || role)\n\t\t\tif (roleDefinition.inherits) {\n\t\t\t\tconst inheritedPermissions = this.create(schema, roleDefinition.inherits, prefix || role)\n\t\t\t\trolePermissions = this.mergePermissions(inheritedPermissions, rolePermissions)\n\t\t\t}\n\t\t\tresult = this.mergePermissions(result, rolePermissions)\n\t\t}\n\t\tresult = this.makePrimaryPredicatesUnionOfAllFields(schema.model, result)\n\n\t\treturn result\n\t}\n\n\tprivate prefixPredicatesWithRole(model: Model.Schema, permissions: Acl.Permissions, role: string): Acl.Permissions {\n\t\treturn mapObject(permissions, ({ operations, predicates }, entityName) => ({\n\t\t\toperations,\n\t\t\tpredicates: mapObject(predicates, predicate => {\n\t\t\t\tconst predicateDefinitionProcessor = new PredicateDefinitionProcessor(model)\n\t\t\t\treturn predicateDefinitionProcessor.process(getEntity(model, entityName), predicate, {\n\t\t\t\t\thandleColumn: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t\thandleRelation: ({ value }) => {\n\t\t\t\t\t\tif (typeof value === 'string') {\n\t\t\t\t\t\t\treturn prefixVariable(role, value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}),\n\t\t}))\n\t}\n\n\tprivate makePrimaryPredicatesUnionOfAllFields(model: Model.Schema, permissions: Acl.Permissions): Acl.Permissions {\n\t\treturn mapObject(permissions, (permission, entityName): Acl.EntityPermissions => {\n\t\t\tconst entity = getEntity(model, entityName)\n\t\t\tconst entityPredicates: Writable<Acl.PredicateMap> = { ...permission.predicates }\n\t\t\tconst entityOperations: Writable<Acl.EntityOperations> = { ...permission.operations }\n\n\t\t\tconst operationNames = ['read', 'create', 'update'] as const\n\t\t\tfor (let operation of operationNames) {\n\t\t\t\tif (!entityOperations[operation]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst fieldPermissions: Writable<Acl.FieldPermissions> = { ...entityOperations[operation] }\n\t\t\t\tentityOperations[operation] = fieldPermissions\n\n\t\t\t\tif (Object.values(fieldPermissions).some(it => it === true)) {\n\t\t\t\t\tfieldPermissions[entity.primary] = true\n\t\t\t\t}\n\t\t\t\tif (fieldPermissions[entity.primary] === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst predicateReferences: string[] = Object.entries(fieldPermissions)\n\t\t\t\t\t.filter(([key]) => key !== entity.primary)\n\t\t\t\t\t.map(([key, value]) => value)\n\t\t\t\t\t.filter(value => value !== false)\n\t\t\t\t\t.filter((value, index, array): value is string => array.indexOf(value) === index)\n\n\t\t\t\tlet idPermissions: Acl.Predicate = fieldPermissions[entity.primary] || false\n\n\t\t\t\tfor (let predicateReference of predicateReferences) {\n\t\t\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tidPermissions,\n\t\t\t\t\t\tentityPredicates,\n\t\t\t\t\t\tpredicateReference,\n\t\t\t\t\t)\n\t\t\t\t\tif (typeof predicate !== 'string' || predicateDefinition === undefined) {\n\t\t\t\t\t\tthrow new Error('should not happen')\n\t\t\t\t\t}\n\t\t\t\t\tidPermissions = predicate\n\t\t\t\t\tentityPredicates[predicate] = predicateDefinition\n\t\t\t\t}\n\t\t\t\tfieldPermissions[entity.primary] = idPermissions\n\t\t\t\tentityPredicates[idPermissions as Acl.PredicateReference] = entityPredicates[idPermissions as Acl.PredicateReference]\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toperations: entityOperations,\n\t\t\t\tpredicates: entityPredicates,\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate mergePermissions(left: Acl.Permissions, right: Acl.Permissions): Acl.Permissions {\n\t\tconst result = { ...left }\n\t\tfor (let entityName in right) {\n\t\t\tif (result[entityName] !== undefined) {\n\t\t\t\tresult[entityName] = this.mergeEntityPermissions(result[entityName], right[entityName])\n\t\t\t} else {\n\t\t\t\tresult[entityName] = right[entityName]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate mergeEntityPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): Acl.EntityPermissions {\n\t\tlet predicates: Writable<Acl.PredicateMap> = {}\n\t\tconst operations: Writable<Acl.EntityOperations> = {}\n\t\tif (left.operations.customPrimary || right.operations.customPrimary) {\n\t\t\toperations.customPrimary = true\n\t\t}\n\t\tconst noRoot: `${Acl.Operation}`[] = []\n\n\t\tfor (let operation of [\n\t\t\t'create',\n\t\t\t'read',\n\t\t\t'update',\n\t\t] as const) {\n\n\t\t\tconst { predicates: opPredicates, permissions: fieldPermissions, noRoot: opNoRoot } = this.mergeOperationPermissions(left, right, operation)\n\n\t\t\tif (opNoRoot) {\n\t\t\t\tnoRoot.push(operation)\n\t\t\t}\n\n\t\t\tpredicates = { ...predicates, ...opPredicates }\n\t\t\tif (Object.keys(fieldPermissions).length > 0) {\n\t\t\t\toperations[operation] = fieldPermissions\n\t\t\t}\n\t\t}\n\n\t\tconst { predicateDefinition, predicate, noRoot: opNoRoot } = this.mergeDeletePermissions(left, right)\n\t\tif (opNoRoot) {\n\t\t\tnoRoot.push('delete')\n\t\t}\n\t\tif (predicate === true) {\n\t\t\toperations.delete = true\n\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\toperations.delete = predicate\n\t\t}\n\n\n\t\tif (noRoot.length > 0) {\n\t\t\toperations.noRoot = noRoot\n\t\t}\n\n\t\treturn {\n\t\t\tpredicates: predicates,\n\t\t\toperations: operations,\n\t\t}\n\t}\n\n\n\tprivate mergeOperationPermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: 'create' | 'read' | 'update'): {\n\t\tnoRoot: boolean\n\t\tpredicates: Acl.PredicateMap\n\t\tpermissions: Acl.FieldPermissions\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, operation)\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergeFieldPermissions(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate mergeDeletePermissions(left: Acl.EntityPermissions, right: Acl.EntityPermissions): {\n\t\tnoRoot: boolean\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tconst { noRoot, leftPermissions, rightPermissions } = this.resolveNoRoot(left, right, 'delete')\n\n\t\treturn {\n\t\t\tnoRoot,\n\t\t\t...this.mergePredicates(\n\t\t\t\tleft.predicates,\n\t\t\t\tleftPermissions,\n\t\t\t\tright.predicates,\n\t\t\t\trightPermissions,\n\t\t\t),\n\t\t}\n\t}\n\n\tprivate resolveNoRoot<const Op extends`${Acl.Operation}`>(left: Acl.EntityPermissions, right: Acl.EntityPermissions, operation: Op): {\n\t\tnoRoot: boolean\n\t\tleftPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t\trightPermissions: Acl.EntityPermissions['operations'][Op] | undefined\n\t} {\n\t\tconst leftRootForbidden = left.operations.noRoot?.includes(operation) || false\n\t\tconst rightRootForbidden = right.operations.noRoot?.includes(operation) || false\n\t\tconst leftPermissions = left.operations[operation]\n\t\tconst rightPermissions = right.operations[operation]\n\n\t\tconst rootForbidden = (leftRootForbidden && rightRootForbidden)\n\t\t\t|| (leftRootForbidden && !rightPermissions)\n\t\t\t|| (rightRootForbidden && !leftPermissions)\n\n\t\tconst resolvedLeftPermissions = !rootForbidden && leftRootForbidden ? undefined : leftPermissions\n\t\tconst resolvedRightPermissions = !rootForbidden && rightRootForbidden ? undefined : rightPermissions\n\n\t\treturn {\n\t\t\tnoRoot: rootForbidden,\n\t\t\tleftPermissions: resolvedLeftPermissions,\n\t\t\trightPermissions: resolvedRightPermissions,\n\t\t}\n\t}\n\n\tprivate mergeFieldPermissions(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightFieldPermissions: Acl.FieldPermissions | undefined = {},\n\t): {predicates: Acl.PredicateMap; permissions: Acl.FieldPermissions} {\n\t\tconst permissions: Writable<Acl.FieldPermissions> = {}\n\t\tconst predicates: Writable<Acl.PredicateMap> = {}\n\n\t\tfor (let field in { ...leftFieldPermissions, ...rightFieldPermissions }) {\n\t\t\tconst { predicateDefinition, predicate } = this.mergePredicates(\n\t\t\t\tleftPredicates,\n\t\t\t\tleftFieldPermissions[field] || false,\n\t\t\t\trightPredicates,\n\t\t\t\trightFieldPermissions[field] || false,\n\t\t\t)\n\t\t\tif (predicate === true) {\n\t\t\t\tpermissions[field] = true\n\t\t\t} else if (predicateDefinition !== undefined && typeof predicate === 'string') {\n\t\t\t\tpermissions[field] = predicate\n\t\t\t\tpredicates[predicate] = predicateDefinition\n\t\t\t}\n\t\t}\n\n\t\treturn { predicates, permissions }\n\t}\n\n\tprivate mergePredicates(\n\t\tleftPredicates: Acl.PredicateMap,\n\t\tleftReference: Acl.Predicate | undefined = false,\n\t\trightPredicates: Acl.PredicateMap,\n\t\trightReference: Acl.Predicate | undefined = false,\n\t): {\n\t\tpredicate: Acl.PredicateReference | boolean\n\t\tpredicateDefinition: Acl.PredicateDefinition | undefined\n\t} {\n\t\tif (leftReference === true || rightReference === true) {\n\t\t\treturn {\n\t\t\t\tpredicate: true,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\n\t\tif (leftReference !== false && rightReference !== false) {\n\t\t\tconst leftPredicate: Acl.PredicateDefinition = leftPredicates[leftReference]\n\t\t\tconst rightPredicate: Acl.PredicateDefinition = rightPredicates[rightReference]\n\t\t\tif (leftPredicate === rightPredicate) {\n\t\t\t\treturn {\n\t\t\t\t\tpredicate: leftReference,\n\t\t\t\t\tpredicateDefinition: leftPredicate,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet predicateName = '__merge__' + leftReference + '__' + rightReference\n\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\tpredicateName += '_'\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: {\n\t\t\t\t\tor: [leftPredicate, rightPredicate],\n\t\t\t\t} as Acl.PredicateDefinition,\n\t\t\t}\n\t\t} else if (leftReference !== false) {\n\t\t\treturn {\n\t\t\t\tpredicate: leftReference,\n\t\t\t\tpredicateDefinition: leftPredicates[leftReference],\n\t\t\t}\n\t\t} else if (rightReference !== false) {\n\t\t\tlet predicateName = rightReference\n\t\t\tif (rightPredicates !== leftPredicates) {\n\t\t\t\twhile (leftPredicates[predicateName]) {\n\t\t\t\t\tpredicateName += '_'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpredicate: predicateName,\n\t\t\t\tpredicateDefinition: rightPredicates[rightReference],\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tpredicate: false,\n\t\t\t\tpredicateDefinition: undefined,\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["opNoRoot"],"mappings":"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"}
|