UNPKG

opa-compile-response-parser

Version:
705 lines (704 loc) 20.7 kB
export declare type RegoValue = string | boolean | number | Array<any> | Record<string, any>; export interface RegoRuleOptions { name: string; fullName: string; isDefault: boolean; value: RegoValue; expressions: RegoExp[]; isCompleteEvaluated?: boolean; parser: OpaCompileResponseParser; } /** * @class RegoRule * @export * * RegoRule represents [Rule](https://www.openpolicyagent.org/docs/latest/how-do-i-write-policies/#rules) concept in Rego language. * - A simple rule is made up of Rule head, Rule value & Rule body * - The Rule value defines the final result of the rule if the rule is matched (i.e. all expressions in rule body are true) * - If you didn't sepcify the rule value, it will be assume as boolean value `true` * - The rule body is made up of one of more rego expressions (see @class RegoExp) and each of the expression is made up of terms (see @class RegoTerm) * - The rule is considered as matched if all expressions in rule body are `true` * You can opt to define a `default` rule. A default rule has no rule body and will only considered as matched if all other rules are not matched. */ export declare class RegoRule { /** * the local name of the rule. i.e. doesn't include full package path * e.g. `allow` * * @type {string} * @memberof RegoRule */ name: string; /** * Full name of the rule. Includes fulle package path * e.g. `data.object.content.allowRead` * * @type {string} * @memberof RegoRule */ fullName: string; /** * Whether a rule is a default Rule * Its value only be used if any other residual rules are not matched (or no other residual rules) * * @type {boolean} * @memberof RegoRule */ isDefault: boolean; /** * Rule value. Rule value is this value if all expression in rule body are true * It can be any type. e.g. can be object or array etc. But a simple policy normally outputs a boolean true or false * * @type {RegoValue} * @memberof RegoRule */ value: RegoValue; /** * Whether the rule contains any expressions that has any resolvable references. * reference start with `input.` should be considered as non-resolvable in context of partial evaluation. * When this field is set to `true`, we should not attempt to evaluate this expression. * i.e. evaluate() method should return immediately. * This will speed up evaluation process. * * @type {boolean} * @memberof RegoRule */ hasNoResolvableRef: boolean; /** * All Rego expressions in this rule's rule body. @see RegoExp * * @type {RegoExp[]} * @memberof RegoRule */ expressions: RegoExp[]; /** * If the rule is matched or not * Default to undefined * Its value is only set when `isCompleteEvaluated` is true * * @type {boolean} * @memberof RegoRule */ isMatched?: boolean; /** * If the rule is fully evaluate * Default to false * * @type {boolean} * @memberof RegoRule */ isCompleteEvaluated: boolean; /** * Reference to OpaParser * * @private * @type {OpaCompileResponseParser} * @memberof RegoRule */ private parser; constructor(options: RegoRuleOptions); /** * OPA PE result might contain duplicate expressions. * https://github.com/open-policy-agent/opa/issues/4516 * This method will remove those duplication by simply string comparison. * * @return {*} * @memberof RegoRule */ removeDuplicateExpressions(): void; /** * Test whether the rule is an "impossible" rule. * If so, the rule should be simply discarded. * See: https://github.com/open-policy-agent/opa/issues/4516 * * @return {*} {boolean} * @memberof RegoRule */ isImpossible(): boolean; clone(options?: Partial<RegoRuleOptions>): RegoRule; /** * Re-evaluate this rule * If fully evaluated, this.isCompleteEvaluated will be set to true * * @returns * @memberof RegoRule */ evaluate(): this; /** * Whether or not the rule is resolvable (i.e. we can tell whether it's matched or not) now. * * @return {*} {boolean} * @memberof RegoRule */ isResolvable(): boolean; /** * Generate Human Readable string of this rule * If it's fully evaluated, the output will be true or false (or actual rule value) * Otherwise, will generate expressions concate with `AND` * * @returns {string} * @memberof RegoRule */ toHumanReadableString(): string; toData(): { default: boolean; value: RegoValue; fullName: string; name: string; expressions: ({ negated: boolean; terms: { type: string; value: RegoTermValue; }[]; index?: undefined; } | { negated: boolean; index: number; terms: { type: string; value: RegoTermValue; }[]; } | { terms: { type: string; value: RegoTermValue; }[]; negated?: undefined; index?: undefined; } | { index: number; terms: { type: string; value: RegoTermValue; }[]; negated?: undefined; })[]; }; toJson(): string; toConciseData(): { default: boolean; value: RegoValue; fullName: string; name: string; expressions: { negated: boolean; operator: string; operands: { isRef: boolean; value: RegoTermValue; }[]; }[]; }; toConciseJSON(): string; /** * Create RegoRule from Opa response data * * @static * @param {*} r * @param {string} packageName * @param {OpaCompileResponseParser} parser * @returns {RegoRule} * @memberof RegoRule */ static parseFromData(r: any, packageName: string, parser: OpaCompileResponseParser): RegoRule; static createExpressionsFromRuleBodyData(data: any, parser: OpaCompileResponseParser): RegoExp[]; static randomRuleName(prefix: string): string; static createFromValue(val: RegoValue, parser: OpaCompileResponseParser): RegoRule; } export interface RegoRefPart { type: string; value: string; } export declare const RegoOperators: { readonly eq: "="; readonly equal: "="; readonly neq: "!="; readonly lt: "<"; readonly gt: ">"; readonly lte: "<="; readonly gte: ">="; }; export declare type RegoOperatorAstString = keyof typeof RegoOperators; export declare type RegoOperatorString = typeof RegoOperators[RegoOperatorAstString]; export declare type RegoTermValue = RegoRef | RegoValue; /** * RegoTerm represent the basic elements that creates an expressions. * e.g. An expression `a > 4` is made up of 3 terms * - Reference Term: `a` * - Operator Term `>` * - Value Term: `4` * * @export * @class RegoTerm */ export declare class RegoTerm { type: string; value: RegoTermValue; private parser; /** * Whether the expression contains any resolvable references. * reference start with `input.` should be considered as non-resolvable in context of partial evaluation. * When this field is set to `true`, we should not attempt to evaluate this expression. * i.e. evaluate() method should return immediately. * This will speed up evaluation process. * * @type {boolean} * @memberof RegoTerm */ hasNoResolvableRef: boolean; constructor(type: string, value: RegoTermValue, parser: OpaCompileResponseParser); clone(): RegoTerm; /** * If it's a reference term, return its full string representation * * @returns * @memberof RegoTerm */ asString(): string; /** * If it's a reference term. A operator is an Reference term as well * * @returns {boolean} * @memberof RegoTerm */ isRef(): boolean; /** * Return RegoRef instance if this term is a RegoRef. * * @returns {RegoRef} * @memberof RegoTerm */ getRef(): RegoRef; /** * If the term is a reference and it contains any collection lookup * e.g. * - objectA.propB.collectionC[_] * - objectA.propB.collectionC[_].ABC[_].name * - objectA.propB.collectionC[_].id * * @returns {boolean} * @memberof RegoTerm */ hasCollectionLookup(): boolean; /** * The term is not only a Reference but a reference contains simple collection lookup * i.e. only contains one collection lookup and the whole ref ends with the only collection lookup * e.g. objectA.propB.collectionC[_] * Note: objectA.propB.collectionC[_].name is not a simple collection lookup as it resolve to single value (`name` property) * rather than a collection * * @returns {boolean} * @memberof RegoTerm */ isSimpleCollectionLookup(): boolean; /** * * * @returns {boolean} * @memberof RegoTerm */ isResolveAsCollectionValue(): boolean; /** * If it's a reference term, return its full string representation * Otherwise, throw exception * * @param {string[]} [removalPrefixs=[]] * @returns {string} * @memberof RegoTerm */ fullRefString(removalPrefixs?: string[]): string; /** * If it's a reference term, return its string representation (not include ending [_]) * Otherwise, throw exception * * @param {string[]} [removalPrefixs=[]] * @returns {string} * @memberof RegoTerm */ refString(removalPrefixs?: string[]): string; /** * Return term as operator string e.g. `=`, `>=` etc. * * @returns {string} * @memberof RegoTerm */ asOperator(): RegoOperatorString; /** * If it's a operator term * * @returns {boolean} * @memberof RegoTerm */ isOperator(): boolean; /** * Tried to determine the value of the term * * @returns {RegoValue} * @memberof RegoTerm */ getValue(): RegoValue; /** * Whether or not the RegoTerm is resolvable * * @return {*} {boolean} * @memberof RegoTerm */ isValueResolvable(): boolean; toData(): { type: string; value: RegoTermValue; }; toJson(): string; toConciseData(): { isRef: boolean; value: RegoTermValue; }; toConciseJSON(): string; static parseFromData(data: any, parser: OpaCompileResponseParser): RegoTerm; } /** * Represents Rego expression * * @export * @class RegoExp */ export declare class RegoExp { /** * All RegoTerms belongs to this expression * * @type {RegoTerm[]} * @memberof RegoExp */ terms: RegoTerm[]; /** * Whether the expression contains any resolvable references. * reference start with `input.` should be considered as non-resolvable in context of partial evaluation. * When this field is set to `true`, we should not attempt to evaluate this expression. * i.e. evaluate() method should return immediately. * This will speed up evaluation process. * * @type {boolean} * @memberof RegoExp */ hasNoResolvableRef: boolean; /** * Whether this expression is a negative expression * i.e. it's final evaluation result should be `false` if result is `true` * * @type {boolean} * @memberof RegoExp */ isNegated: boolean; /** * If it's complete evaluated * * @type {boolean} * @memberof RegoExp */ isCompleteEvaluated: boolean; /** * The value of the expression * * @type {RegoValue} * @memberof RegoExp */ value: RegoValue; /** * Ref to Opa Parser * * @private * @type {OpaCompileResponseParser} * @memberof RegoExp */ private parser; constructor(terms: RegoTerm[], isNegated: boolean, isCompleteEvaluated: boolean, value: RegoValue, parser: OpaCompileResponseParser); clone(): RegoExp; /** * For debug usage, print terms as easy to ready short string * * @returns * @memberof RegoExp */ termsAsString(): string; /** * Print concise format expression string presentation. * Can be used for debugging * * @return {*} * @memberof RegoExp */ asString(): string; /** * Output human readable string * * @returns {string} * @memberof RegoExp */ toHumanReadableString(): string; /** * Try to determins its value * * @returns * @memberof RegoExp */ getValue(): RegoValue; /** * Whether or not a expression should be considered as "matched". * If all expressions of a rule are "matched", the rule will be considered as "matched". * Thus, the rule has a value. * * Please note: if an expression's value is `0`, empty string "", null etc, the expression is considered as "matched". * We only consider an expression as "Not Matched" when the expression has value `false` or is undefined. * * @return {boolean} * @memberof RegoExp */ isMatched(): boolean; /** * Whether or not the expression is resolvable now. * * @return {boolean} * @memberof RegoExp */ isResolvable(): boolean; /** * Convert operator term to string and put rest operands into an array. * And then return a [Operator, Operands] structure * * @returns {[string, RegoTerm[]]} * @memberof RegoExp */ toOperatorOperandsArray(): [RegoOperatorString, RegoTerm[]]; /** * Try to evaluate the expression * * @returns * @memberof RegoExp */ evaluate(): this; toData(index?: number, ignoreIndex?: boolean, ignoreNegated?: boolean): { negated: boolean; terms: { type: string; value: RegoTermValue; }[]; index?: undefined; } | { negated: boolean; index: number; terms: { type: string; value: RegoTermValue; }[]; } | { terms: { type: string; value: RegoTermValue; }[]; negated?: undefined; index?: undefined; } | { index: number; terms: { type: string; value: RegoTermValue; }[]; negated?: undefined; }; toJSON(index?: number, ignoreIndex?: boolean, ignoreNegated?: boolean): string; toConciseData(): { negated: boolean; operator: string; operands: { isRef: boolean; value: RegoTermValue; }[]; }; toConciseJSON(): string; static parseFromData(expData: any, parser: OpaCompileResponseParser): RegoExp; } /** * Represents a special Rego Term type: reference term * You shouldn't use this class directly * * @export * @class RegoRef */ export declare class RegoRef { parts: RegoRefPart[]; /** * Whether the expression contains any resolvable references. * reference start with `input.` should be considered as non-resolvable in context of partial evaluation. * When this field is set to `true`, we should not attempt to evaluate this expression. * i.e. evaluate() method should return immediately. * This will speed up evaluation process. * * @type {boolean} * @memberof RegoRef */ hasNoResolvableRef: boolean; constructor(parts: RegoRefPart[]); clone(): RegoRef; toData(): { type: string; value: RegoRefPart[]; }; toJson(): string; static parseFromData(data: any): RegoRef; static convertToFullRefString(parts: RegoRefPart[]): string; removeAllPrefixs(str: string, removalPrefixs?: string[]): string; fullRefString(removalPrefixs?: string[]): string; refString(removalPrefixs?: string[]): string; asCollectionRefs(removalPrefixs?: string[]): string[]; isOperator(): boolean; hasCollectionLookup(): boolean; isSimpleCollectionLookup(): boolean; isResolveAsCollectionValue(): boolean; asOperator(): RegoOperatorString | null; } export interface CompleteRuleResult { fullName: string; name: string; value: RegoValue; isCompleteEvaluated: boolean; residualRules?: RegoRule[]; } export declare function value2String(value: RegoValue): string; export declare class RegoRuleSet { fullName: string; name: string; rules: RegoRule[]; defaultRule: RegoRule | null; value?: any; isCompleteEvaluated: boolean; parser: OpaCompileResponseParser; /** * Whether the ruleSet contains any rules that has any resolvable references. * reference start with `input.` should be considered as non-resolvable in context of partial evaluation. * When this field is set to `true`, we should not attempt to evaluate this expression. * i.e. evaluate() method should return immediately. * This will speed up evaluation process. * * @type {boolean} * @memberof RegoRuleSet */ hasNoResolvableRef: boolean; constructor(parser: OpaCompileResponseParser, rules: RegoRule[], fullName?: string, name?: string); evaluate(): RegoRuleSet; isResolvable(): boolean; getResidualRules(): RegoRule[]; } /** * OPA result Parser * * @export * @class OpaCompileResponseParser */ export default class OpaCompileResponseParser { /** * If a warning is produced during the parsing * * @type {boolean} * @memberof OpaCompileResponseParser */ hasWarns: boolean; /** * Any warnings produced during the parsing * * @type {string[]} * @memberof OpaCompileResponseParser */ warns: string[]; private data; /** * Inital Rules parsed from result * Only for debug purpose * * @type {RegoRule[]} * @memberof OpaCompileResponseParser */ originalRules: RegoRule[]; /** * Parsed, compressed & evaluated rules * * @type {RegoRule[]} * @memberof OpaCompileResponseParser */ rules: RegoRule[]; /** * Parsed, compressed & evaluated rule sets * * @type {RegoRuleSet[]} * @memberof OpaCompileResponseParser */ ruleSets: { [fullName: string]: RegoRuleSet; }; queries: RegoExp[]; /** * A cache of all resolved rule result * * @type {{ * [fullName: string]: CompleteRuleResult; * }} * @memberof OpaCompileResponseParser */ completeRuleResults: { [fullName: string]: CompleteRuleResult; }; /** * The pseudo query rule name * The parser will assign a random pseudo rule name to the query expressions you submit. * * @type {string} * @memberof OpaCompileResponseParser */ readonly pseudoQueryRuleName: string; private ruleDuplicationCheckCache; private setQueryRuleResult; /** * Parse OPA result Response * * @param {*} json * @returns {RegoRule[]} * @memberof OpaCompileResponseParser */ parse(json: any): RegoRule[]; addRule(rule: RegoRule): void; isRefResolvable(fullName: string): boolean; getRefValue(fullName: string): any; private resolveAllRuleSets; /** * Call to evaluate a rule * * @param {string} fullName * @returns {CompleteRuleResult} * @memberof OpaCompileResponseParser */ evaluateRule(fullName: string): CompleteRuleResult | null; /** * Shortcut to evalute query result directly * * @returns {CompleteRuleResult} * @memberof OpaCompileResponseParser */ evaluate(): CompleteRuleResult; /** * evaluate a rule and returned as human readable string * * @param {string} fullName * @returns {string} * @memberof OpaCompileResponseParser */ evaluateRuleAsHumanReadableString(fullName: string): string; /** * Shortcut to evalute query result directly and returned as human readable string * * @returns {string} * @memberof OpaCompileResponseParser */ evaluateAsHumanReadableString(): string; reportWarns(msg: string): void; } export declare function unknown2Ref(unknown: string): string;