@magda/typescript-common 2.0.0-alpha.0 → 2.0.0-alpha.1
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/OpaCompileResponseParser.d.ts +115 -4
- package/dist/OpaCompileResponseParser.js +233 -19
- package/dist/OpaCompileResponseParser.js.map +1 -1
- package/dist/SQLUtils.js +1 -1
- package/dist/SQLUtils.js.map +1 -1
- package/dist/authorization-api/authMiddleware.d.ts +7 -6
- package/dist/authorization-api/authMiddleware.js +54 -45
- package/dist/authorization-api/authMiddleware.js.map +1 -1
- package/dist/authorization-api/model.d.ts +1 -1
- package/dist/generated/registry/api.d.ts +11 -0
- package/dist/generated/registry/api.js +57 -0
- package/dist/generated/registry/api.js.map +1 -1
- package/dist/getStorageUrl.d.ts +34 -0
- package/dist/getStorageUrl.js +138 -0
- package/dist/getStorageUrl.js.map +1 -0
- package/dist/handleServerError.d.ts +2 -0
- package/dist/handleServerError.js +17 -0
- package/dist/handleServerError.js.map +1 -0
- package/dist/opa/AspectQuery.js +3 -0
- package/dist/opa/AspectQuery.js.map +1 -1
- package/dist/opa/AuthDecision.js +1 -1
- package/dist/opa/AuthDecision.js.map +1 -1
- package/dist/opa/AuthDecisionQueryClient.js +8 -5
- package/dist/opa/AuthDecisionQueryClient.js.map +1 -1
- package/dist/registry/RegistryClient.d.ts +1 -0
- package/dist/registry/RegistryClient.js +14 -0
- package/dist/registry/RegistryClient.js.map +1 -1
- package/dist/test/getStorageUrl.spec.d.ts +1 -0
- package/dist/test/getStorageUrl.spec.js +95 -0
- package/dist/test/getStorageUrl.spec.js.map +1 -0
- package/dist/test/sampleAuthDecisions/datasetPermissionWithOrgUnitConstraint.json +2 -2
- package/dist/test/sampleAuthDecisions/extraLargeResponse.json +2519 -0
- package/dist/test/sampleOpaResponses/datasetPermissionWithOrgUnitConstraint.json +2 -2
- package/dist/test/sampleOpaResponses/extraLargeResponse.json +104869 -0
- package/dist/test/testOpaCompileResponseParser.spec.js +19 -2
- package/dist/test/testOpaCompileResponseParser.spec.js.map +1 -1
- package/package.json +6 -4
|
@@ -53,6 +53,17 @@ export declare class RegoRule {
|
|
|
53
53
|
* @memberof RegoRule
|
|
54
54
|
*/
|
|
55
55
|
value: RegoValue;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the rule contains any expressions that has any resolvable references.
|
|
58
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
59
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
60
|
+
* i.e. evaluate() method should return immediately.
|
|
61
|
+
* This will speed up evaluation process.
|
|
62
|
+
*
|
|
63
|
+
* @type {boolean}
|
|
64
|
+
* @memberof RegoRule
|
|
65
|
+
*/
|
|
66
|
+
hasNoResolvableRef: boolean;
|
|
56
67
|
/**
|
|
57
68
|
* All Rego expressions in this rule's rule body. @see RegoExp
|
|
58
69
|
*
|
|
@@ -86,6 +97,24 @@ export declare class RegoRule {
|
|
|
86
97
|
*/
|
|
87
98
|
private parser;
|
|
88
99
|
constructor(options: RegoRuleOptions);
|
|
100
|
+
/**
|
|
101
|
+
* OPA PE result might contain duplicate expressions.
|
|
102
|
+
* https://github.com/open-policy-agent/opa/issues/4516
|
|
103
|
+
* This method will remove those duplication by simply string comparison.
|
|
104
|
+
*
|
|
105
|
+
* @return {*}
|
|
106
|
+
* @memberof RegoRule
|
|
107
|
+
*/
|
|
108
|
+
removeDuplicateExpressions(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Test whether the rule is an "impossible" rule.
|
|
111
|
+
* If so, the rule should be simply discarded.
|
|
112
|
+
* See: https://github.com/open-policy-agent/opa/issues/4516
|
|
113
|
+
*
|
|
114
|
+
* @return {*} {boolean}
|
|
115
|
+
* @memberof RegoRule
|
|
116
|
+
*/
|
|
117
|
+
isImpossible(): boolean;
|
|
89
118
|
clone(options?: Partial<RegoRuleOptions>): RegoRule;
|
|
90
119
|
/**
|
|
91
120
|
* Re-evaluate this rule
|
|
@@ -117,12 +146,26 @@ export declare class RegoRule {
|
|
|
117
146
|
fullName: string;
|
|
118
147
|
name: string;
|
|
119
148
|
expressions: ({
|
|
149
|
+
negated: boolean;
|
|
150
|
+
terms: {
|
|
151
|
+
type: string;
|
|
152
|
+
value: RegoTermValue;
|
|
153
|
+
}[];
|
|
154
|
+
index?: undefined;
|
|
155
|
+
} | {
|
|
120
156
|
negated: boolean;
|
|
121
157
|
index: number;
|
|
122
158
|
terms: {
|
|
123
159
|
type: string;
|
|
124
160
|
value: RegoTermValue;
|
|
125
161
|
}[];
|
|
162
|
+
} | {
|
|
163
|
+
terms: {
|
|
164
|
+
type: string;
|
|
165
|
+
value: RegoTermValue;
|
|
166
|
+
}[];
|
|
167
|
+
negated?: undefined;
|
|
168
|
+
index?: undefined;
|
|
126
169
|
} | {
|
|
127
170
|
index: number;
|
|
128
171
|
terms: {
|
|
@@ -193,6 +236,17 @@ export declare class RegoTerm {
|
|
|
193
236
|
type: string;
|
|
194
237
|
value: RegoTermValue;
|
|
195
238
|
private parser;
|
|
239
|
+
/**
|
|
240
|
+
* Whether the expression contains any resolvable references.
|
|
241
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
242
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
243
|
+
* i.e. evaluate() method should return immediately.
|
|
244
|
+
* This will speed up evaluation process.
|
|
245
|
+
*
|
|
246
|
+
* @type {boolean}
|
|
247
|
+
* @memberof RegoTerm
|
|
248
|
+
*/
|
|
249
|
+
hasNoResolvableRef: boolean;
|
|
196
250
|
constructor(type: string, value: RegoTermValue, parser: OpaCompileResponseParser);
|
|
197
251
|
clone(): RegoTerm;
|
|
198
252
|
/**
|
|
@@ -201,7 +255,7 @@ export declare class RegoTerm {
|
|
|
201
255
|
* @returns
|
|
202
256
|
* @memberof RegoTerm
|
|
203
257
|
*/
|
|
204
|
-
asString():
|
|
258
|
+
asString(): string;
|
|
205
259
|
/**
|
|
206
260
|
* If it's a reference term. A operator is an Reference term as well
|
|
207
261
|
*
|
|
@@ -317,6 +371,17 @@ export declare class RegoExp {
|
|
|
317
371
|
* @memberof RegoExp
|
|
318
372
|
*/
|
|
319
373
|
terms: RegoTerm[];
|
|
374
|
+
/**
|
|
375
|
+
* Whether the expression contains any resolvable references.
|
|
376
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
377
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
378
|
+
* i.e. evaluate() method should return immediately.
|
|
379
|
+
* This will speed up evaluation process.
|
|
380
|
+
*
|
|
381
|
+
* @type {boolean}
|
|
382
|
+
* @memberof RegoExp
|
|
383
|
+
*/
|
|
384
|
+
hasNoResolvableRef: boolean;
|
|
320
385
|
/**
|
|
321
386
|
* Whether this expression is a negative expression
|
|
322
387
|
* i.e. it's final evaluation result should be `false` if result is `true`
|
|
@@ -355,7 +420,15 @@ export declare class RegoExp {
|
|
|
355
420
|
* @returns
|
|
356
421
|
* @memberof RegoExp
|
|
357
422
|
*/
|
|
358
|
-
termsAsString():
|
|
423
|
+
termsAsString(): string;
|
|
424
|
+
/**
|
|
425
|
+
* Print concise format expression string presentation.
|
|
426
|
+
* Can be used for debugging
|
|
427
|
+
*
|
|
428
|
+
* @return {*}
|
|
429
|
+
* @memberof RegoExp
|
|
430
|
+
*/
|
|
431
|
+
asString(): string;
|
|
359
432
|
/**
|
|
360
433
|
* Output human readable string
|
|
361
434
|
*
|
|
@@ -404,13 +477,27 @@ export declare class RegoExp {
|
|
|
404
477
|
* @memberof RegoExp
|
|
405
478
|
*/
|
|
406
479
|
evaluate(): this;
|
|
407
|
-
toData(index?: number): {
|
|
480
|
+
toData(index?: number, ignoreIndex?: boolean, ignoreNegated?: boolean): {
|
|
481
|
+
negated: boolean;
|
|
482
|
+
terms: {
|
|
483
|
+
type: string;
|
|
484
|
+
value: RegoTermValue;
|
|
485
|
+
}[];
|
|
486
|
+
index?: undefined;
|
|
487
|
+
} | {
|
|
408
488
|
negated: boolean;
|
|
409
489
|
index: number;
|
|
410
490
|
terms: {
|
|
411
491
|
type: string;
|
|
412
492
|
value: RegoTermValue;
|
|
413
493
|
}[];
|
|
494
|
+
} | {
|
|
495
|
+
terms: {
|
|
496
|
+
type: string;
|
|
497
|
+
value: RegoTermValue;
|
|
498
|
+
}[];
|
|
499
|
+
negated?: undefined;
|
|
500
|
+
index?: undefined;
|
|
414
501
|
} | {
|
|
415
502
|
index: number;
|
|
416
503
|
terms: {
|
|
@@ -419,7 +506,7 @@ export declare class RegoExp {
|
|
|
419
506
|
}[];
|
|
420
507
|
negated?: undefined;
|
|
421
508
|
};
|
|
422
|
-
toJSON(index?: number): string;
|
|
509
|
+
toJSON(index?: number, ignoreIndex?: boolean, ignoreNegated?: boolean): string;
|
|
423
510
|
toConciseData(): {
|
|
424
511
|
negated: boolean;
|
|
425
512
|
operator: string;
|
|
@@ -440,6 +527,17 @@ export declare class RegoExp {
|
|
|
440
527
|
*/
|
|
441
528
|
export declare class RegoRef {
|
|
442
529
|
parts: RegoRefPart[];
|
|
530
|
+
/**
|
|
531
|
+
* Whether the expression contains any resolvable references.
|
|
532
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
533
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
534
|
+
* i.e. evaluate() method should return immediately.
|
|
535
|
+
* This will speed up evaluation process.
|
|
536
|
+
*
|
|
537
|
+
* @type {boolean}
|
|
538
|
+
* @memberof RegoRef
|
|
539
|
+
*/
|
|
540
|
+
hasNoResolvableRef: boolean;
|
|
443
541
|
constructor(parts: RegoRefPart[]);
|
|
444
542
|
clone(): RegoRef;
|
|
445
543
|
toData(): {
|
|
@@ -475,6 +573,17 @@ export declare class RegoRuleSet {
|
|
|
475
573
|
value?: any;
|
|
476
574
|
isCompleteEvaluated: boolean;
|
|
477
575
|
parser: OpaCompileResponseParser;
|
|
576
|
+
/**
|
|
577
|
+
* Whether the ruleSet contains any rules that has any resolvable references.
|
|
578
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
579
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
580
|
+
* i.e. evaluate() method should return immediately.
|
|
581
|
+
* This will speed up evaluation process.
|
|
582
|
+
*
|
|
583
|
+
* @type {boolean}
|
|
584
|
+
* @memberof RegoRuleSet
|
|
585
|
+
*/
|
|
586
|
+
hasNoResolvableRef: boolean;
|
|
478
587
|
constructor(parser: OpaCompileResponseParser, rules: RegoRule[], fullName?: string, name?: string);
|
|
479
588
|
evaluate(): RegoRuleSet;
|
|
480
589
|
isResolvable(): boolean;
|
|
@@ -546,6 +655,7 @@ export default class OpaCompileResponseParser {
|
|
|
546
655
|
* @memberof OpaCompileResponseParser
|
|
547
656
|
*/
|
|
548
657
|
readonly pseudoQueryRuleName: string;
|
|
658
|
+
private ruleDuplicationCheckCache;
|
|
549
659
|
private setQueryRuleResult;
|
|
550
660
|
/**
|
|
551
661
|
* Parse OPA result Response
|
|
@@ -555,6 +665,7 @@ export default class OpaCompileResponseParser {
|
|
|
555
665
|
* @memberof OpaCompileResponseParser
|
|
556
666
|
*/
|
|
557
667
|
parse(json: any): RegoRule[];
|
|
668
|
+
addRule(rule: RegoRule): void;
|
|
558
669
|
isRefResolvable(fullName: string): boolean;
|
|
559
670
|
getRefValue(fullName: string): any;
|
|
560
671
|
private resolveAllRuleSets;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
@@ -19,6 +30,18 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
|
19
30
|
*/
|
|
20
31
|
class RegoRule {
|
|
21
32
|
constructor(options) {
|
|
33
|
+
var _a;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the rule contains any expressions that has any resolvable references.
|
|
36
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
37
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
38
|
+
* i.e. evaluate() method should return immediately.
|
|
39
|
+
* This will speed up evaluation process.
|
|
40
|
+
*
|
|
41
|
+
* @type {boolean}
|
|
42
|
+
* @memberof RegoRule
|
|
43
|
+
*/
|
|
44
|
+
this.hasNoResolvableRef = false;
|
|
22
45
|
this.isCompleteEvaluated = false;
|
|
23
46
|
this.name = lodash_1.default.isString(options.name) ? options.name : "";
|
|
24
47
|
this.fullName = lodash_1.default.isString(options.fullName) ? options.fullName : "";
|
|
@@ -42,8 +65,69 @@ class RegoRule {
|
|
|
42
65
|
if (!(this.parser instanceof OpaCompileResponseParser)) {
|
|
43
66
|
throw new Error("Require parser parameter to create a RegoRule");
|
|
44
67
|
}
|
|
68
|
+
this.removeDuplicateExpressions();
|
|
69
|
+
if (((_a = this.expressions) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
70
|
+
this.expressions.findIndex((exp) => !exp.hasNoResolvableRef) === -1) {
|
|
71
|
+
this.hasNoResolvableRef = true;
|
|
72
|
+
}
|
|
45
73
|
this.evaluate();
|
|
46
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* OPA PE result might contain duplicate expressions.
|
|
77
|
+
* https://github.com/open-policy-agent/opa/issues/4516
|
|
78
|
+
* This method will remove those duplication by simply string comparison.
|
|
79
|
+
*
|
|
80
|
+
* @return {*}
|
|
81
|
+
* @memberof RegoRule
|
|
82
|
+
*/
|
|
83
|
+
removeDuplicateExpressions() {
|
|
84
|
+
var _a;
|
|
85
|
+
if (!((_a = this === null || this === void 0 ? void 0 : this.expressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const expSet = new Set();
|
|
89
|
+
this.expressions = this.expressions.filter((exp) => {
|
|
90
|
+
const orgSetLength = expSet.size;
|
|
91
|
+
// exp.toJSON() is faster than exp.toConciseJSON()
|
|
92
|
+
expSet.add(exp.toJSON(0, true));
|
|
93
|
+
return expSet.size > orgSetLength;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Test whether the rule is an "impossible" rule.
|
|
98
|
+
* If so, the rule should be simply discarded.
|
|
99
|
+
* See: https://github.com/open-policy-agent/opa/issues/4516
|
|
100
|
+
*
|
|
101
|
+
* @return {*} {boolean}
|
|
102
|
+
* @memberof RegoRule
|
|
103
|
+
*/
|
|
104
|
+
isImpossible() {
|
|
105
|
+
var _a;
|
|
106
|
+
if (!((_a = this === null || this === void 0 ? void 0 : this.expressions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const nonNegatedExpSet = new Set();
|
|
110
|
+
const negatedExps = this.expressions.filter((exp) => {
|
|
111
|
+
if (exp.isNegated) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// add non negated exp content to set
|
|
116
|
+
// exp.toJSON() is faster than exp.toConciseJSON()
|
|
117
|
+
nonNegatedExpSet.add(exp.toJSON(0, true));
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
if (!negatedExps.length) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
for (const exp of negatedExps) {
|
|
125
|
+
if (nonNegatedExpSet.has(exp.toJSON(0, true, true))) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
47
131
|
clone(options = {}) {
|
|
48
132
|
const regoRule = new RegoRule(Object.assign({ name: this.name, fullName: this.fullName, isDefault: this.isDefault, value: this.value, isCompleteEvaluated: this.isCompleteEvaluated, expressions: this.expressions.map((e) => e.clone()), parser: this.parser }, options));
|
|
49
133
|
regoRule.isMatched = this.isMatched;
|
|
@@ -58,6 +142,9 @@ class RegoRule {
|
|
|
58
142
|
*/
|
|
59
143
|
evaluate() {
|
|
60
144
|
var _a;
|
|
145
|
+
if (this.hasNoResolvableRef) {
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
61
148
|
if (this.isCompleteEvaluated) {
|
|
62
149
|
return this;
|
|
63
150
|
}
|
|
@@ -223,9 +310,23 @@ exports.RegoOperators = {
|
|
|
223
310
|
*/
|
|
224
311
|
class RegoTerm {
|
|
225
312
|
constructor(type, value, parser) {
|
|
313
|
+
/**
|
|
314
|
+
* Whether the expression contains any resolvable references.
|
|
315
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
316
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
317
|
+
* i.e. evaluate() method should return immediately.
|
|
318
|
+
* This will speed up evaluation process.
|
|
319
|
+
*
|
|
320
|
+
* @type {boolean}
|
|
321
|
+
* @memberof RegoTerm
|
|
322
|
+
*/
|
|
323
|
+
this.hasNoResolvableRef = false;
|
|
226
324
|
this.type = type;
|
|
227
325
|
this.value = value;
|
|
228
326
|
this.parser = parser;
|
|
327
|
+
if (this.value instanceof RegoRef && this.value.hasNoResolvableRef) {
|
|
328
|
+
this.hasNoResolvableRef = true;
|
|
329
|
+
}
|
|
229
330
|
}
|
|
230
331
|
clone() {
|
|
231
332
|
return new RegoTerm(this.type, this.value, this.parser);
|
|
@@ -240,7 +341,7 @@ class RegoTerm {
|
|
|
240
341
|
if (this.value instanceof RegoRef)
|
|
241
342
|
return this.value.fullRefString();
|
|
242
343
|
else
|
|
243
|
-
return this.value;
|
|
344
|
+
return JSON.stringify(this.value);
|
|
244
345
|
}
|
|
245
346
|
/**
|
|
246
347
|
* If it's a reference term. A operator is an Reference term as well
|
|
@@ -376,6 +477,9 @@ class RegoTerm {
|
|
|
376
477
|
* @memberof RegoTerm
|
|
377
478
|
*/
|
|
378
479
|
getValue() {
|
|
480
|
+
if (this.hasNoResolvableRef) {
|
|
481
|
+
return undefined;
|
|
482
|
+
}
|
|
379
483
|
if (!this.isRef()) {
|
|
380
484
|
return this.value;
|
|
381
485
|
}
|
|
@@ -399,6 +503,9 @@ class RegoTerm {
|
|
|
399
503
|
* @memberof RegoTerm
|
|
400
504
|
*/
|
|
401
505
|
isValueResolvable() {
|
|
506
|
+
if (this.hasNoResolvableRef) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
402
509
|
if (!this.isRef()) {
|
|
403
510
|
return true;
|
|
404
511
|
}
|
|
@@ -461,6 +568,18 @@ exports.RegoTerm = RegoTerm;
|
|
|
461
568
|
*/
|
|
462
569
|
class RegoExp {
|
|
463
570
|
constructor(terms, isNegated = false, isCompleteEvaluated = false, value = null, parser) {
|
|
571
|
+
var _a;
|
|
572
|
+
/**
|
|
573
|
+
* Whether the expression contains any resolvable references.
|
|
574
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
575
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
576
|
+
* i.e. evaluate() method should return immediately.
|
|
577
|
+
* This will speed up evaluation process.
|
|
578
|
+
*
|
|
579
|
+
* @type {boolean}
|
|
580
|
+
* @memberof RegoExp
|
|
581
|
+
*/
|
|
582
|
+
this.hasNoResolvableRef = false;
|
|
464
583
|
/**
|
|
465
584
|
* If it's complete evaluated
|
|
466
585
|
*
|
|
@@ -480,6 +599,10 @@ class RegoExp {
|
|
|
480
599
|
this.isCompleteEvaluated = isCompleteEvaluated;
|
|
481
600
|
this.value = value;
|
|
482
601
|
this.parser = parser;
|
|
602
|
+
if (((_a = this === null || this === void 0 ? void 0 : this.terms) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
603
|
+
this.terms.findIndex((item) => !item.hasNoResolvableRef) === -1) {
|
|
604
|
+
this.hasNoResolvableRef = true;
|
|
605
|
+
}
|
|
483
606
|
}
|
|
484
607
|
clone() {
|
|
485
608
|
const regoExp = new RegoExp(this.terms.map((t) => t.clone()), this.isNegated, this.isCompleteEvaluated, this.value, this.parser);
|
|
@@ -492,7 +615,22 @@ class RegoExp {
|
|
|
492
615
|
* @memberof RegoExp
|
|
493
616
|
*/
|
|
494
617
|
termsAsString() {
|
|
495
|
-
return this.terms.map((t) => t.asString());
|
|
618
|
+
return this.terms.map((t) => t.asString()).join(" ");
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Print concise format expression string presentation.
|
|
622
|
+
* Can be used for debugging
|
|
623
|
+
*
|
|
624
|
+
* @return {*}
|
|
625
|
+
* @memberof RegoExp
|
|
626
|
+
*/
|
|
627
|
+
asString() {
|
|
628
|
+
if (this.isNegated) {
|
|
629
|
+
return "NOT " + this.termsAsString();
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
return this.termsAsString();
|
|
633
|
+
}
|
|
496
634
|
}
|
|
497
635
|
/**
|
|
498
636
|
* Output human readable string
|
|
@@ -631,6 +769,9 @@ class RegoExp {
|
|
|
631
769
|
* @memberof RegoExp
|
|
632
770
|
*/
|
|
633
771
|
evaluate() {
|
|
772
|
+
if (this.hasNoResolvableRef) {
|
|
773
|
+
return this;
|
|
774
|
+
}
|
|
634
775
|
if (this.isCompleteEvaluated) {
|
|
635
776
|
return this;
|
|
636
777
|
}
|
|
@@ -696,24 +837,39 @@ class RegoExp {
|
|
|
696
837
|
throw new Error(`Invalid ${this.terms.length} terms rego expression: ${this.termsAsString()}`);
|
|
697
838
|
}
|
|
698
839
|
}
|
|
699
|
-
toData(index = 0) {
|
|
840
|
+
toData(index = 0, ignoreIndex = false, ignoreNegated = false) {
|
|
700
841
|
const terms = this.terms.map((term) => term.toData());
|
|
701
|
-
if (this.isNegated) {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
842
|
+
if (this.isNegated && !ignoreNegated) {
|
|
843
|
+
if (ignoreIndex) {
|
|
844
|
+
return {
|
|
845
|
+
negated: true,
|
|
846
|
+
terms
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
return {
|
|
851
|
+
negated: true,
|
|
852
|
+
index,
|
|
853
|
+
terms
|
|
854
|
+
};
|
|
855
|
+
}
|
|
707
856
|
}
|
|
708
857
|
else {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
858
|
+
if (ignoreIndex) {
|
|
859
|
+
return {
|
|
860
|
+
terms
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
return {
|
|
865
|
+
index,
|
|
866
|
+
terms
|
|
867
|
+
};
|
|
868
|
+
}
|
|
713
869
|
}
|
|
714
870
|
}
|
|
715
|
-
toJSON(index = 0) {
|
|
716
|
-
return JSON.stringify(this.toData(index));
|
|
871
|
+
toJSON(index = 0, ignoreIndex = false, ignoreNegated = false) {
|
|
872
|
+
return JSON.stringify(this.toData(index, ignoreIndex, ignoreNegated));
|
|
717
873
|
}
|
|
718
874
|
toConciseData() {
|
|
719
875
|
let data;
|
|
@@ -768,7 +924,25 @@ exports.RegoExp = RegoExp;
|
|
|
768
924
|
*/
|
|
769
925
|
class RegoRef {
|
|
770
926
|
constructor(parts) {
|
|
927
|
+
var _a;
|
|
928
|
+
/**
|
|
929
|
+
* Whether the expression contains any resolvable references.
|
|
930
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
931
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
932
|
+
* i.e. evaluate() method should return immediately.
|
|
933
|
+
* This will speed up evaluation process.
|
|
934
|
+
*
|
|
935
|
+
* @type {boolean}
|
|
936
|
+
* @memberof RegoRef
|
|
937
|
+
*/
|
|
938
|
+
this.hasNoResolvableRef = false;
|
|
771
939
|
this.parts = parts;
|
|
940
|
+
if (
|
|
941
|
+
// `input.` ref should be considered not resolvable in partial evaluate context.
|
|
942
|
+
(this.parts.length && ((_a = this.parts[0]) === null || _a === void 0 ? void 0 : _a.value) === "input") ||
|
|
943
|
+
this.isOperator()) {
|
|
944
|
+
this.hasNoResolvableRef = true;
|
|
945
|
+
}
|
|
772
946
|
}
|
|
773
947
|
clone() {
|
|
774
948
|
return new RegoRef(this.parts.map((p) => (Object.assign({}, p))));
|
|
@@ -893,6 +1067,17 @@ class RegoRuleSet {
|
|
|
893
1067
|
this.rules = [];
|
|
894
1068
|
this.defaultRule = null;
|
|
895
1069
|
this.isCompleteEvaluated = false;
|
|
1070
|
+
/**
|
|
1071
|
+
* Whether the ruleSet contains any rules that has any resolvable references.
|
|
1072
|
+
* reference start with `input.` should be considered as non-resolvable in context of partial evaluation.
|
|
1073
|
+
* When this field is set to `true`, we should not attempt to evaluate this expression.
|
|
1074
|
+
* i.e. evaluate() method should return immediately.
|
|
1075
|
+
* This will speed up evaluation process.
|
|
1076
|
+
*
|
|
1077
|
+
* @type {boolean}
|
|
1078
|
+
* @memberof RegoRuleSet
|
|
1079
|
+
*/
|
|
1080
|
+
this.hasNoResolvableRef = false;
|
|
896
1081
|
this.parser = parser;
|
|
897
1082
|
if (rules === null || rules === void 0 ? void 0 : rules.length) {
|
|
898
1083
|
const defaultRuleIdx = rules.findIndex((r) => r.isDefault);
|
|
@@ -913,10 +1098,17 @@ class RegoRuleSet {
|
|
|
913
1098
|
else if ((_b = rules === null || rules === void 0 ? void 0 : rules[0]) === null || _b === void 0 ? void 0 : _b.name) {
|
|
914
1099
|
this.name = rules[0].name;
|
|
915
1100
|
}
|
|
1101
|
+
if (this.rules.length &&
|
|
1102
|
+
this.rules.findIndex((r) => !r.hasNoResolvableRef) === -1) {
|
|
1103
|
+
this.hasNoResolvableRef = true;
|
|
1104
|
+
}
|
|
916
1105
|
this.evaluate();
|
|
917
1106
|
}
|
|
918
1107
|
evaluate() {
|
|
919
1108
|
var _a;
|
|
1109
|
+
if (this.hasNoResolvableRef) {
|
|
1110
|
+
return this;
|
|
1111
|
+
}
|
|
920
1112
|
if (this.isCompleteEvaluated) {
|
|
921
1113
|
return this;
|
|
922
1114
|
}
|
|
@@ -1113,6 +1305,7 @@ class OpaCompileResponseParser {
|
|
|
1113
1305
|
* @memberof OpaCompileResponseParser
|
|
1114
1306
|
*/
|
|
1115
1307
|
this.pseudoQueryRuleName = RegoRule.randomRuleName("default_rule_");
|
|
1308
|
+
this.ruleDuplicationCheckCache = {};
|
|
1116
1309
|
}
|
|
1117
1310
|
setQueryRuleResult(val) {
|
|
1118
1311
|
this.completeRuleResults[this.pseudoQueryRuleName] = {
|
|
@@ -1173,8 +1366,9 @@ class OpaCompileResponseParser {
|
|
|
1173
1366
|
value: true,
|
|
1174
1367
|
parser: this
|
|
1175
1368
|
});
|
|
1176
|
-
this.originalRules.push(rule);
|
|
1177
|
-
this.rules.push(rule);
|
|
1369
|
+
// this.originalRules.push(rule);
|
|
1370
|
+
// this.rules.push(rule);
|
|
1371
|
+
this.addRule(rule);
|
|
1178
1372
|
});
|
|
1179
1373
|
}
|
|
1180
1374
|
const packages = this.data.support;
|
|
@@ -1188,15 +1382,35 @@ class OpaCompileResponseParser {
|
|
|
1188
1382
|
const rules = p.rules;
|
|
1189
1383
|
rules.forEach((r) => {
|
|
1190
1384
|
const regoRule = RegoRule.parseFromData(r, packageName, this);
|
|
1191
|
-
this.originalRules.push(regoRule);
|
|
1192
|
-
this.rules.push(regoRule);
|
|
1385
|
+
//this.originalRules.push(regoRule);
|
|
1386
|
+
//this.rules.push(regoRule);
|
|
1387
|
+
this.addRule(regoRule);
|
|
1193
1388
|
});
|
|
1194
1389
|
});
|
|
1195
1390
|
}
|
|
1391
|
+
this.ruleDuplicationCheckCache = {};
|
|
1196
1392
|
lodash_1.default.uniq(this.rules.map((r) => r.fullName)).forEach((fullName) => (this.ruleSets[fullName] = new RegoRuleSet(this, this.rules.filter((r) => r.fullName === fullName), fullName)));
|
|
1197
1393
|
this.resolveAllRuleSets();
|
|
1198
1394
|
return this.rules;
|
|
1199
1395
|
}
|
|
1396
|
+
addRule(rule) {
|
|
1397
|
+
this.originalRules.push(rule);
|
|
1398
|
+
if (rule.isImpossible()) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
if (!this.ruleDuplicationCheckCache[rule.fullName]) {
|
|
1402
|
+
this.ruleDuplicationCheckCache[rule.fullName] = new Set();
|
|
1403
|
+
}
|
|
1404
|
+
const setData = this.ruleDuplicationCheckCache[rule.fullName];
|
|
1405
|
+
const _a = rule.toData(), { name, fullName } = _a, ruleData = __rest(_a, ["name", "fullName"]);
|
|
1406
|
+
const jsonData = JSON.stringify(ruleData);
|
|
1407
|
+
const size = setData.size;
|
|
1408
|
+
setData.add(jsonData);
|
|
1409
|
+
if (size === setData.size) {
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
this.rules.push(rule);
|
|
1413
|
+
}
|
|
1200
1414
|
isRefResolvable(fullName) {
|
|
1201
1415
|
if (this.completeRuleResults[fullName]) {
|
|
1202
1416
|
return true;
|