New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fig-tree-evaluator

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fig-tree-evaluator - npm Package Compare versions

Comparing version 2.3.3 to 2.4.0

143

build/evaluate.js

@@ -54,6 +54,6 @@ "use strict";

var evaluatorFunction = function (input, config) { return __awaiter(void 0, void 0, void 0, function () {
var options, operators, operatorAliases, expression, _a, fallback, returnErrorAsString, operator, _b, _c, requiredProperties, propertyAliases, evaluate, parseChildren, _d, _e, validationError, _f, _g, _h, result, err_1, _j, outputType, evaluatedOutputType, _k, err_2, _l;
var _m, _o;
return __generator(this, function (_p) {
switch (_p.label) {
var options, operators, operatorAliases, expression, _a, fallback, returnErrorAsString, _b, fragment, parameters, fragmentReplacement, _c, operator, _d, _e, requiredProperties, propertyAliases, evaluate, parseChildren, _f, _g, validationError, _h, _j, _k, result, err_1, _l, outputType, evaluatedOutputType, _m, err_2, _o;
var _p, _q, _r;
return __generator(this, function (_s) {
switch (_s.label) {
case 0:

@@ -65,88 +65,103 @@ options = config.options, operators = config.operators, operatorAliases = config.operatorAliases;

case 1:
expression = _p.sent();
_p.label = 2;
expression = _s.sent();
_s.label = 2;
case 2:
if (!(options.evaluateFullObject && !(0, helpers_1.isOperatorNode)(expression))) return [3, 4];
if (!(options.evaluateFullObject && !(0, helpers_1.isOperatorNode)(expression) && !(0, helpers_1.isFragmentNode)(expression))) return [3, 4];
_a = helpers_1.replaceAliasNodeValues;
return [4, (0, helpers_1.evaluateObject)(expression, config)];
case 3: return [2, _a.apply(void 0, [_p.sent(), config])];
case 3: return [2, _a.apply(void 0, [_s.sent(), config])];
case 4:
if (!(0, helpers_1.isOperatorNode)(expression))
if (!(0, helpers_1.isOperatorNode)(expression) && !(0, helpers_1.isFragmentNode)(expression))
return [2, (0, helpers_1.replaceAliasNodeValues)(expression, config)];
fallback = expression.fallback;
returnErrorAsString = (_m = options === null || options === void 0 ? void 0 : options.returnErrorAsString) !== null && _m !== void 0 ? _m : false;
_p.label = 5;
returnErrorAsString = (_p = options === null || options === void 0 ? void 0 : options.returnErrorAsString) !== null && _p !== void 0 ? _p : false;
if (!(0, helpers_1.isFragmentNode)(expression)) return [3, 8];
return [4, (0, _operatorUtils_1.evaluateArray)([expression.fragment, expression.parameters], config)];
case 5:
_p.trys.push([5, 26, , 28]);
operator = (0, helpers_1.getOperatorName)(expression.operator, operatorAliases);
if (!!operator) return [3, 7];
_b = helpers_1.fallbackOrError;
_b = (_s.sent()), fragment = _b[0], parameters = _b[1];
fragmentReplacement = (_q = options === null || options === void 0 ? void 0 : options.fragments) === null || _q === void 0 ? void 0 : _q[fragment];
if (!!fragmentReplacement) return [3, 7];
_c = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 6: return [2, _b.apply(void 0, [_p.sent(), "Invalid operator: ".concat(expression.operator), returnErrorAsString])];
case 6: return [2, _c.apply(void 0, [_s.sent(), "Fragment not defined: ".concat(fragment), returnErrorAsString])];
case 7:
_c = operators[operator], requiredProperties = _c.requiredProperties, propertyAliases = _c.propertyAliases, evaluate = _c.evaluate, parseChildren = _c.parseChildren;
expression = (0, helpers_1.mapPropertyAliases)(propertyAliases, expression);
_d = config;
_e = [__assign({}, config.resolvedAliasNodes)];
return [4, (0, helpers_1.evaluateNodeAliases)(expression, config)];
if (!(0, helpers_1.isOperatorNode)(fragmentReplacement))
return [2, fragmentReplacement];
expression = __assign(__assign(__assign({}, expression), fragmentReplacement), parameters);
delete expression.fragment;
delete expression.parameters;
_s.label = 8;
case 8:
_d.resolvedAliasNodes = __assign.apply(void 0, _e.concat([(_p.sent())]));
validationError = (0, helpers_1.checkRequiredNodes)(requiredProperties, expression);
if (!validationError) return [3, 10];
_f = helpers_1.fallbackOrError;
_s.trys.push([8, 29, , 31]);
operator = (0, helpers_1.getOperatorName)(expression.operator, operatorAliases);
if (!!operator) return [3, 10];
_d = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 9: return [2, _f.apply(void 0, [_p.sent(), "Operator: ".concat(operator, "\n- ").concat(validationError), returnErrorAsString])];
case 9: return [2, _d.apply(void 0, [_s.sent(), "Invalid operator: ".concat(expression.operator), returnErrorAsString])];
case 10:
if (!('children' in expression)) return [3, 16];
if (!!Array.isArray(expression.children)) return [3, 12];
_g = expression;
return [4, (0, exports.evaluatorFunction)(expression.children, config)];
_e = operators[operator], requiredProperties = _e.requiredProperties, propertyAliases = _e.propertyAliases, evaluate = _e.evaluate, parseChildren = _e.parseChildren;
expression = (0, helpers_1.mapPropertyAliases)(propertyAliases, expression);
_f = config;
_g = [__assign({}, config.resolvedAliasNodes)];
return [4, (0, helpers_1.evaluateNodeAliases)(expression, config)];
case 11:
_g.children = _p.sent();
_p.label = 12;
case 12:
if (!!Array.isArray(expression.children)) return [3, 14];
_f.resolvedAliasNodes = __assign.apply(void 0, _g.concat([(_s.sent())]));
validationError = (0, helpers_1.checkRequiredNodes)(requiredProperties, expression);
if (!validationError) return [3, 13];
_h = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 13: return [2, _h.apply(void 0, [_p.sent(), "Operator: ".concat(operator, "\n- Property \"children\" is not of type: array"), returnErrorAsString])];
case 14: return [4, parseChildren(expression, config)];
case 12: return [2, _h.apply(void 0, [_s.sent(), "Operator: ".concat(operator, "\n- ").concat(validationError), returnErrorAsString])];
case 13:
if (!('children' in expression)) return [3, 19];
if (!!Array.isArray(expression.children)) return [3, 15];
_j = expression;
return [4, (0, exports.evaluatorFunction)(expression.children, config)];
case 14:
_j.children = _s.sent();
_s.label = 15;
case 15:
expression = _p.sent();
_p.label = 16;
case 16:
result = void 0;
_p.label = 17;
case 17:
_p.trys.push([17, 19, , 21]);
return [4, evaluate(expression, config)];
if (!!Array.isArray(expression.children)) return [3, 17];
_k = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 16: return [2, _k.apply(void 0, [_s.sent(), "Operator: ".concat(operator, "\n- Property \"children\" is not of type: array"), returnErrorAsString])];
case 17: return [4, parseChildren(expression, config)];
case 18:
result = _p.sent();
return [3, 21];
expression = _s.sent();
_s.label = 19;
case 19:
err_1 = _p.sent();
_j = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
result = void 0;
_s.label = 20;
case 20:
result = _j.apply(void 0, [_p.sent(), "Operator: ".concat(operator, "\n").concat((0, helpers_1.errorMessage)(err_1)), returnErrorAsString]);
return [3, 21];
_s.trys.push([20, 22, , 24]);
return [4, evaluate(expression, config)];
case 21:
outputType = (_o = expression === null || expression === void 0 ? void 0 : expression.outputType) !== null && _o !== void 0 ? _o : expression === null || expression === void 0 ? void 0 : expression.type;
result = _s.sent();
return [3, 24];
case 22:
err_1 = _s.sent();
_l = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 23:
result = _l.apply(void 0, [_s.sent(), "Operator: ".concat(operator, "\n").concat((0, helpers_1.errorMessage)(err_1)), returnErrorAsString]);
return [3, 24];
case 24:
outputType = (_r = expression === null || expression === void 0 ? void 0 : expression.outputType) !== null && _r !== void 0 ? _r : expression === null || expression === void 0 ? void 0 : expression.type;
if (!outputType)
return [2, result];
return [4, (0, exports.evaluatorFunction)(outputType, config)];
case 22:
evaluatedOutputType = (_p.sent());
if (!!(evaluatedOutputType in helpers_1.convertOutputMethods)) return [3, 24];
_k = helpers_1.fallbackOrError;
case 25:
evaluatedOutputType = (_s.sent());
if (!!(evaluatedOutputType in helpers_1.convertOutputMethods)) return [3, 27];
_m = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 23: return [2, _k.apply(void 0, [_p.sent(), "Operator: ".concat(operator, "\n- Invalid output type: ").concat(evaluatedOutputType), returnErrorAsString])];
case 24: return [2, helpers_1.convertOutputMethods[evaluatedOutputType](result)];
case 25: return [3, 28];
case 26:
err_2 = _p.sent();
_l = helpers_1.fallbackOrError;
case 26: return [2, _m.apply(void 0, [_s.sent(), "Operator: ".concat(operator, "\n- Invalid output type: ").concat(evaluatedOutputType), returnErrorAsString])];
case 27: return [2, helpers_1.convertOutputMethods[evaluatedOutputType](result)];
case 28: return [3, 31];
case 29:
err_2 = _s.sent();
_o = helpers_1.fallbackOrError;
return [4, (0, exports.evaluatorFunction)(fallback, config)];
case 27: return [2, _l.apply(void 0, [_p.sent(), (0, helpers_1.errorMessage)(err_2),
case 30: return [2, _o.apply(void 0, [_s.sent(), (0, helpers_1.errorMessage)(err_2),
returnErrorAsString])];
case 28: return [2];
case 31: return [2];
}

@@ -153,0 +168,0 @@ });

import { OutputType, EvaluatorNode, CombinedOperatorNode, Operator, EvaluatorOutput, FigTreeOptions, OperatorNodeUnion, FigTreeConfig } from './types';
export declare const parseIfJson: (input: EvaluatorNode) => any;
export declare const isOperatorNode: (input: EvaluatorNode) => boolean;
export declare const isFragmentNode: (input: EvaluatorNode) => boolean;
export declare const getOperatorName: (operator: string, operatorAliases: {

@@ -5,0 +6,0 @@ [key: string]: "AND" | "OR" | "EQUAL" | "NOT_EQUAL" | "PLUS" | "SUBTRACT" | "MULTIPLY" | "DIVIDE" | "GREATER_THAN" | "LESS_THAN" | "CONDITIONAL" | "REGEX" | "OBJECT_PROPERTIES" | "STRING_SUBSTITUTION" | "SPLIT" | "COUNT" | "GET" | "POST" | "PG_SQL" | "GRAPHQL" | "BUILD_OBJECT" | "MATCH" | "CUSTOM_FUNCTIONS" | "PASSTHRU";

@@ -50,3 +50,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluateObject = exports.errorMessage = exports.convertOutputMethods = exports.mergeOptions = exports.checkRequiredNodes = exports.replaceAliasNodeValues = exports.evaluateNodeAliases = exports.mapPropertyAliases = exports.fallbackOrError = exports.truncateString = exports.getOperatorName = exports.isOperatorNode = exports.parseIfJson = void 0;
exports.evaluateObject = exports.errorMessage = exports.convertOutputMethods = exports.mergeOptions = exports.checkRequiredNodes = exports.replaceAliasNodeValues = exports.evaluateNodeAliases = exports.mapPropertyAliases = exports.fallbackOrError = exports.truncateString = exports.getOperatorName = exports.isFragmentNode = exports.isOperatorNode = exports.parseIfJson = void 0;
var change_case_1 = require("change-case");

@@ -71,2 +71,6 @@ var evaluate_1 = require("./evaluate");

exports.isOperatorNode = isOperatorNode;
var isFragmentNode = function (input) {
return input instanceof Object && 'fragment' in input;
};
exports.isFragmentNode = isFragmentNode;
var standardiseOperatorName = function (name) {

@@ -151,2 +155,4 @@ var camelCaseName = (0, change_case_1.camelCase)(name);

combinedOptions.functions = __assign(__assign({}, origOptions.functions), newOptions.functions);
if (origOptions.fragments || newOptions.fragments)
combinedOptions.fragments = __assign(__assign({}, origOptions.fragments), newOptions.fragments);
if (origOptions.headers || newOptions.headers)

@@ -153,0 +159,0 @@ combinedOptions.headers = __assign(__assign({}, origOptions.headers), newOptions.headers);

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

@@ -130,3 +119,3 @@ if (k2 === undefined) k2 = k;

FigTreeEvaluator.prototype.updateOptions = function (options) {
this.options = __assign(__assign({}, this.options), standardiseOptionNames(options));
this.options = (0, helpers_1.mergeOptions)(this.options, standardiseOptionNames(options));
};

@@ -133,0 +122,0 @@ return FigTreeEvaluator;

@@ -15,2 +15,5 @@ import FigTreeCache from './cache';

};
fragments?: {
[key: string]: EvaluatorNode;
};
pgConnection?: PGConnection;

@@ -51,6 +54,13 @@ graphQLConnection?: GraphQLConnection;

}
export interface FragmentNode {
fragment: string;
parameters?: {
[key: string]: EvaluatorNode;
};
[key: string]: EvaluatorNode;
}
export type CombinedOperatorNode = BaseOperatorNode & BasicExtendedNode & SubtractionNode & DivisionNode & ComparatorNode & ConditionalNode & RegexNode & StringSubNode & SplitNode & ObjPropNode & APINode & PGNode & GraphQLNode & BuildObjectNode & MatchNode & FunctionNode & PassThruNode;
export type OperatorNodeUnion = BasicExtendedNode | SubtractionNode | DivisionNode | ComparatorNode | ConditionalNode | RegexNode | StringSubNode | SplitNode | ObjPropNode | PGNode | GraphQLNode | APINode | BuildObjectNode | MatchNode | FunctionNode | PassThruNode;
export type EvaluatorOutput = string | boolean | number | GenericObject | null | undefined | any[];
export type EvaluatorNode = CombinedOperatorNode | EvaluatorOutput;
export type EvaluatorNode = CombinedOperatorNode | FragmentNode | EvaluatorOutput;
export type OperatorObject = {

@@ -57,0 +67,0 @@ requiredProperties: readonly string[];

{
"name": "fig-tree-evaluator",
"version": "2.3.3",
"version": "2.4.0",
"description": "Module to evaluate JSON-structured expression trees",

@@ -40,3 +40,3 @@ "main": "build/index.js",

"dequal": "^2.0.3",
"object-property-extractor": "^1.0.3"
"object-property-extractor": "^1.0.6"
},

@@ -43,0 +43,0 @@ "bugs": {

@@ -52,2 +52,3 @@ # fig-tree-evaluator

- [Alias Nodes](#alias-nodes)
- [Fragments](#fragments)
- [Caching (Memoization)](#caching-memoization)

@@ -144,2 +145,3 @@ - [More examples](#more-examples)

- `functions` -- a single object containing any *custom functions* available for use by the [customFunctions](#custom_functions) operator.
- `fragments` -- commonly-used expressions (with optional parameters) that can be re-used in any other expression. See [Fragments](#fragments)
- `pgConnection` -- if you wish to make calls to a Postgres database using the [`pgSQL` operator](#pg_sql), pass a [node-postres](https://node-postgres.com/) connection object here.

@@ -1393,2 +1395,64 @@ - `graphQLConnection` -- a GraphQL connection object, if using the [`graphQL` operator](#graphql). See operator details below.

## Fragments
You may find that the expressions you are building for your configuration files often use very similar sub-expressions (but perhaps with only some input values that differ). For example, your expressions might be regularly looking up a "countries" database and fetching the capital city, such as:
```js
{
operator: 'GET',
url: {
operator: 'stringSubstitution',
string: 'https://restcountries.com/v3.1/name/%1',
replacements: ['New Zealand'],
},
returnProperty: '[0].capital',
outputType: 'string',
}
// => "Wellington"
```
In this case, you can pre-define the main part of the expression as part of an expression "**fragment**" in the evaluator [options](#available-options).
The idea is that you can "hard-code" some common expressions into your app, so that external configuration expressions can be simpler when using these common elements.
The syntax is similar to [Alias Nodes](#alias-nodes), in that any string values prefixed with `$` will be treated as "parameters" that will be replaced during evaluation. In the above example, you would define the fragment when instantiating the evaluator like so:
```js
const exp = new FigTreeEvaluator({
fragments: {
getCapital: {
operator: 'GET',
url: {
operator: 'stringSubstitution',
string: 'https://restcountries.com/v3.1/name/%1',
replacements: [ "$country" ],
},
returnProperty: '[0].capital',
outputType: 'string',
},
},
})
```
Then any subsequent expressions can use this fragment by specifying a special "Fragment Node", which contains the `fragment` and (optionally) `parameters` fields:
```js
{
fragment: "getCapital",
parameters: {
$country: { operator: "getData", property: "path.to.country.name" }
}
}
```
Like the `branches` field in the ["Match" operator](#match), the properties of the `parameters` field can be specified at the root level as well -- it just depends on whichever is most appropriate for your use case. So the following is equivalent to the previous fragment node:
```js
{
fragment: "getCapital",
$country: { operator: "getData", property: "path.to.country.name" }
}
```
See `22_fragments.test.ts` for more complex examples.
Unlike Alias Nodes, which are evaluated *once* and then the result re-used whenever the alias is referenced, Fragments are evaluated every time, as the input parameters may differ.
## Caching (Memoization)

@@ -1442,2 +1506,5 @@

*Trivial upgrades (e.g. documentation only) not included*
- **v2.4.0**: Implement [Fragments](#fragments) (#74)
- **v2.3.2**: Bug fix: alias nodes not working with `evaluateFullObject` (#72)

@@ -1467,4 +1534,3 @@ - **v2.3.0**: Implement [caching/memoization](#caching-memoization) (#68)

## Credit
Icon: Tree by ka reemov from <a href="https://thenounproject.com/icon/tree-2665898/" target="_blank" title="Tree Icon">Noun Project</a>
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc