fig-tree-evaluator 2.6.0 → 2.8.0
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/README.md +196 -12
- package/build/FigTreeEvaluator.d.ts +18 -0
- package/build/FigTreeEvaluator.js +26 -3
- package/build/evaluate.js +18 -10
- package/build/helpers.d.ts +29 -4
- package/build/helpers.js +16 -4
- package/build/operators/AND/data.d.ts +5 -0
- package/build/operators/AND/data.js +23 -0
- package/build/operators/AND/index.d.ts +1 -0
- package/build/operators/AND/index.js +5 -0
- package/build/operators/{logicalAnd.d.ts → AND/operator.d.ts} +2 -3
- package/build/operators/AND/operator.js +54 -0
- package/build/operators/BUILD_OBJECT/data.d.ts +5 -0
- package/build/operators/BUILD_OBJECT/data.js +23 -0
- package/build/operators/BUILD_OBJECT/index.d.ts +1 -0
- package/build/operators/BUILD_OBJECT/index.js +17 -0
- package/build/operators/{buildObject.d.ts → BUILD_OBJECT/operator.d.ts} +2 -3
- package/build/operators/{buildObject.js → BUILD_OBJECT/operator.js} +29 -12
- package/build/operators/CONDITIONAL/data.d.ts +5 -0
- package/build/operators/CONDITIONAL/data.js +37 -0
- package/build/operators/CONDITIONAL/index.d.ts +1 -0
- package/build/operators/CONDITIONAL/index.js +17 -0
- package/build/operators/{conditional.d.ts → CONDITIONAL/operator.d.ts} +2 -3
- package/build/operators/{conditional.js → CONDITIONAL/operator.js} +28 -7
- package/build/operators/COUNT/data.d.ts +5 -0
- package/build/operators/COUNT/data.js +23 -0
- package/build/operators/COUNT/index.d.ts +1 -0
- package/build/operators/COUNT/index.js +17 -0
- package/build/operators/COUNT/operator.d.ts +2 -0
- package/build/operators/COUNT/operator.js +50 -0
- package/build/operators/CUSTOM_FUNCTIONS/data.d.ts +5 -0
- package/build/operators/CUSTOM_FUNCTIONS/data.js +37 -0
- package/build/operators/CUSTOM_FUNCTIONS/index.d.ts +1 -0
- package/build/operators/CUSTOM_FUNCTIONS/index.js +17 -0
- package/build/operators/{customFunctions.d.ts → CUSTOM_FUNCTIONS/operator.d.ts} +2 -3
- package/build/operators/{customFunctions.js → CUSTOM_FUNCTIONS/operator.js} +29 -22
- package/build/operators/DIVIDE/data.d.ts +5 -0
- package/build/operators/DIVIDE/data.js +44 -0
- package/build/operators/DIVIDE/index.d.ts +1 -0
- package/build/operators/DIVIDE/index.js +17 -0
- package/build/operators/{divide.d.ts → DIVIDE/operator.d.ts} +2 -2
- package/build/operators/DIVIDE/operator.js +62 -0
- package/build/operators/EQUAL/data.d.ts +5 -0
- package/build/operators/EQUAL/data.js +30 -0
- package/build/operators/EQUAL/index.d.ts +1 -0
- package/build/operators/EQUAL/index.js +17 -0
- package/build/operators/EQUAL/operator.d.ts +2 -0
- package/build/operators/{equal.js → EQUAL/operator.js} +31 -10
- package/build/operators/GET/data.d.ts +5 -0
- package/build/operators/GET/data.js +51 -0
- package/build/operators/GET/index.d.ts +1 -0
- package/build/operators/GET/index.js +5 -0
- package/build/operators/{getRequest.d.ts → GET/operator.d.ts} +2 -3
- package/build/operators/{getRequest.js → GET/operator.js} +51 -13
- package/build/operators/GRAPHQL/data.d.ts +5 -0
- package/build/operators/GRAPHQL/data.js +58 -0
- package/build/operators/GRAPHQL/index.d.ts +1 -0
- package/build/operators/GRAPHQL/index.js +17 -0
- package/build/operators/{graphQL.d.ts → GRAPHQL/operator.d.ts} +2 -3
- package/build/operators/{graphQL.js → GRAPHQL/operator.js} +29 -8
- package/build/operators/GREATER_THAN/data.d.ts +5 -0
- package/build/operators/GREATER_THAN/data.js +30 -0
- package/build/operators/GREATER_THAN/index.d.ts +1 -0
- package/build/operators/GREATER_THAN/index.js +17 -0
- package/build/operators/{greaterThan.d.ts → GREATER_THAN/operator.d.ts} +2 -2
- package/build/operators/GREATER_THAN/operator.js +55 -0
- package/build/operators/LESS_THAN/data.d.ts +5 -0
- package/build/operators/LESS_THAN/data.js +30 -0
- package/build/operators/LESS_THAN/index.d.ts +1 -0
- package/build/operators/LESS_THAN/index.js +17 -0
- package/build/operators/{lessThan.d.ts → LESS_THAN/operator.d.ts} +1 -1
- package/build/operators/LESS_THAN/operator.js +55 -0
- package/build/operators/MATCH/data.d.ts +5 -0
- package/build/operators/MATCH/data.js +30 -0
- package/build/operators/MATCH/index.d.ts +1 -0
- package/build/operators/MATCH/index.js +17 -0
- package/build/operators/{match.d.ts → MATCH/operator.d.ts} +2 -3
- package/build/operators/{match.js → MATCH/operator.js} +31 -18
- package/build/operators/MULTIPLY/data.d.ts +5 -0
- package/build/operators/MULTIPLY/data.js +23 -0
- package/build/operators/MULTIPLY/index.d.ts +1 -0
- package/build/operators/MULTIPLY/index.js +17 -0
- package/build/operators/{multiply.d.ts → MULTIPLY/operator.d.ts} +1 -1
- package/build/operators/MULTIPLY/operator.js +50 -0
- package/build/operators/NOT_EQUAL/data.d.ts +5 -0
- package/build/operators/NOT_EQUAL/data.js +30 -0
- package/build/operators/NOT_EQUAL/index.d.ts +1 -0
- package/build/operators/NOT_EQUAL/index.js +17 -0
- package/build/operators/{notEqual.d.ts → NOT_EQUAL/operator.d.ts} +1 -1
- package/build/operators/{notEqual.js → NOT_EQUAL/operator.js} +31 -10
- package/build/operators/OBJECT_PROPERTIES/data.d.ts +5 -0
- package/build/operators/OBJECT_PROPERTIES/data.js +38 -0
- package/build/operators/OBJECT_PROPERTIES/index.d.ts +1 -0
- package/build/operators/OBJECT_PROPERTIES/index.js +17 -0
- package/build/operators/{objectProperties.d.ts → OBJECT_PROPERTIES/operator.d.ts} +2 -3
- package/build/operators/{objectProperties.js → OBJECT_PROPERTIES/operator.js} +33 -24
- package/build/operators/OR/data.d.ts +5 -0
- package/build/operators/OR/data.js +23 -0
- package/build/operators/OR/index.d.ts +1 -0
- package/build/operators/OR/index.js +17 -0
- package/build/operators/OR/operator.d.ts +2 -0
- package/build/operators/OR/operator.js +50 -0
- package/build/operators/PASSTHRU/data.d.ts +5 -0
- package/build/operators/PASSTHRU/data.js +23 -0
- package/build/operators/PASSTHRU/index.d.ts +1 -0
- package/build/operators/PASSTHRU/index.js +17 -0
- package/build/operators/{passThru.d.ts → PASSTHRU/operator.d.ts} +3 -4
- package/build/operators/PASSTHRU/operator.js +52 -0
- package/build/operators/PG_SQL/data.d.ts +5 -0
- package/build/operators/PG_SQL/data.js +37 -0
- package/build/operators/PG_SQL/index.d.ts +1 -0
- package/build/operators/PG_SQL/index.js +17 -0
- package/build/operators/{pgSQL.d.ts → PG_SQL/operator.d.ts} +2 -2
- package/build/operators/{pgSQL.js → PG_SQL/operator.js} +29 -8
- package/build/operators/PLUS/data.d.ts +5 -0
- package/build/operators/PLUS/data.js +30 -0
- package/build/operators/PLUS/index.d.ts +1 -0
- package/build/operators/PLUS/index.js +17 -0
- package/build/operators/{plus.d.ts → PLUS/operator.d.ts} +3 -4
- package/build/operators/{plus.js → PLUS/operator.js} +34 -10
- package/build/operators/POST/data.d.ts +5 -0
- package/build/operators/POST/data.js +51 -0
- package/build/operators/POST/index.d.ts +1 -0
- package/build/operators/POST/index.js +17 -0
- package/build/operators/POST/operator.d.ts +2 -0
- package/build/operators/{postRequest.js → POST/operator.js} +31 -10
- package/build/operators/REGEX/data.d.ts +5 -0
- package/build/operators/REGEX/data.js +30 -0
- package/build/operators/REGEX/index.d.ts +1 -0
- package/build/operators/REGEX/index.js +17 -0
- package/build/operators/{regex.d.ts → REGEX/operator.d.ts} +2 -3
- package/build/operators/{regex.js → REGEX/operator.js} +30 -16
- package/build/operators/SPLIT/data.d.ts +5 -0
- package/build/operators/SPLIT/data.js +44 -0
- package/build/operators/SPLIT/index.d.ts +1 -0
- package/build/operators/SPLIT/index.js +17 -0
- package/build/operators/{split.d.ts → SPLIT/operator.d.ts} +2 -3
- package/build/operators/{split.js → SPLIT/operator.js} +34 -15
- package/build/operators/STRING_SUBSTITUTION/data.d.ts +5 -0
- package/build/operators/STRING_SUBSTITUTION/data.js +30 -0
- package/build/operators/STRING_SUBSTITUTION/index.d.ts +1 -0
- package/build/operators/STRING_SUBSTITUTION/index.js +17 -0
- package/build/operators/{stringSubstitution.d.ts → STRING_SUBSTITUTION/operator.d.ts} +2 -3
- package/build/operators/{stringSubstitution.js → STRING_SUBSTITUTION/operator.js} +29 -9
- package/build/operators/SUBTRACT/data.d.ts +5 -0
- package/build/operators/SUBTRACT/data.js +37 -0
- package/build/operators/SUBTRACT/index.d.ts +1 -0
- package/build/operators/SUBTRACT/index.js +17 -0
- package/build/operators/{subtract.d.ts → SUBTRACT/operator.d.ts} +2 -2
- package/build/operators/SUBTRACT/operator.js +53 -0
- package/build/operators/_operatorAliases.json +1 -0
- package/build/operators/_operatorUtils.d.ts +9 -1
- package/build/operators/_operatorUtils.js +19 -1
- package/build/operators/index.d.ts +24 -24
- package/build/operators/index.js +24 -27
- package/build/shorthandSyntax.d.ts +2 -0
- package/build/shorthandSyntax.js +55 -0
- package/build/typeCheck.d.ts +1 -1
- package/build/typeCheck.js +1 -0
- package/build/types.d.ts +35 -15
- package/package.json +1 -1
- package/build/operators/count.d.ts +0 -2
- package/build/operators/count.js +0 -29
- package/build/operators/divide.js +0 -41
- package/build/operators/equal.d.ts +0 -2
- package/build/operators/greaterThan.js +0 -35
- package/build/operators/lessThan.js +0 -35
- package/build/operators/logicalAnd.js +0 -33
- package/build/operators/logicalOr.d.ts +0 -2
- package/build/operators/logicalOr.js +0 -29
- package/build/operators/multiply.js +0 -29
- package/build/operators/passThru.js +0 -30
- package/build/operators/postRequest.d.ts +0 -2
- package/build/operators/subtract.js +0 -32
package/README.md
CHANGED
|
@@ -50,7 +50,9 @@ A range of built-in operators are available, from simple logic, arithmetic and s
|
|
|
50
50
|
- [CUSTOM\_FUNCTIONS](#custom_functions)
|
|
51
51
|
- [Alias Nodes](#alias-nodes)
|
|
52
52
|
- [Fragments](#fragments)
|
|
53
|
+
- [Shorthand syntax](#shorthand-syntax)
|
|
53
54
|
- [Caching (Memoization)](#caching-memoization)
|
|
55
|
+
- [Metadata](#metadata)
|
|
54
56
|
- [More examples](#more-examples)
|
|
55
57
|
- [Development environment](#development-environment)
|
|
56
58
|
- [Tests](#tests)
|
|
@@ -123,16 +125,16 @@ or\
|
|
|
123
125
|
import FigTreeEvaluator from 'fig-tree-evaluator'
|
|
124
126
|
|
|
125
127
|
// New evaluator instance
|
|
126
|
-
const
|
|
128
|
+
const fig = new FigTreeEvaluator([ options ]) // See available options below
|
|
127
129
|
|
|
128
130
|
// Evaluate expressions
|
|
129
|
-
|
|
131
|
+
fig.evaluate(expression, [options]) // Options over-ride initial options for this evaluation
|
|
130
132
|
.then((result) => { // "evaluate" is async method
|
|
131
133
|
// Do something with result
|
|
132
134
|
})
|
|
133
135
|
|
|
134
136
|
// Or within async function:
|
|
135
|
-
const result = await
|
|
137
|
+
const result = await fig.evaluate(expression, [options])
|
|
136
138
|
```
|
|
137
139
|
|
|
138
140
|
FigTreeEvaluator is written in **Typescript**, and the following types are available to import from the package:
|
|
@@ -157,16 +159,18 @@ The `options` parameter is an object with the following available properties (al
|
|
|
157
159
|
- `skipRuntimeTypeCheck` -- we perform comprehensive type checking at runtime to ensure that each operator only performs its operation on valid inputs. If type checking fails, we throw an error detailing the explicit problem. However, if `skipRuntimeTypeCheck` is set to `true`, then all inputs are passed to the operator regardless, and any errors will come from whatever standard javascript errors might be encountered (e.g. trying to pass a primitive value when an array is expected => `.map is not a function`)
|
|
158
160
|
- `nullEqualsUndefined` -- this only affects the [`equal`/`notEqual` operators](#equal) (see there for more detail).
|
|
159
161
|
- `evaluateFullObject` -- by default, FigTree expects the root of an input expression to be an [Operator Node](#operator-nodes), and if not, will return the input unmodified. However, you may have cases where the evaluation expressions are deep within a larger structure (such as a JSON schema, for example). In this case, you can set `evaluateFullObject` to `true` and the evaluator will find *any* operator nodes within the structure and evaluate them within the object tree.
|
|
162
|
+
- `excludeOperators` -- an array of operator names (or [aliases](#operator--property-aliases)) to prohibit from being used in expressions. You may wish to restrict (for example) database access via FigTree configurations, in which case these exclusions can be defined when instantiating the FigTree instance (or updated on the fly).
|
|
160
163
|
- `useCache` -- caches the results from certain operators to avoid repeated network requests with the same input values. By default, this is set to `true`, and it can be overridden for specific nodes. See [Memoization/Caching section](#caching-memoization) for more detail
|
|
161
164
|
- `maxCacheSize` -- the maximum number of results that will be held in the aforementioned cache (default: `50`)
|
|
165
|
+
- `noShorthand` -- there is a [shorthand syntax](#shorthand-syntax) available for writing expressions. Internally, this is pre-processed into the standard expression form before evaluation. If you have no use for this and you'd rather all expressions were written with full verbosity, set `noShorthand: true` to save a small amount in performance by skipping internal pre-processing.
|
|
162
166
|
|
|
163
167
|
As mentioned above, `options` can be provided as part of the constructor as part of each separate evaluation. You can also change the options permanently for a given evaluator instance with:
|
|
164
168
|
|
|
165
|
-
`
|
|
169
|
+
`fig.updateOptions(options)`
|
|
166
170
|
|
|
167
171
|
You can also retrieve the current options state at any time with:
|
|
168
172
|
|
|
169
|
-
`
|
|
173
|
+
`fig.getOptions()`
|
|
170
174
|
|
|
171
175
|
It's also possible to run one-off evaluations by importing the evaluation method directly rather than using the constructor:
|
|
172
176
|
|
|
@@ -700,11 +704,11 @@ const user = {
|
|
|
700
704
|
],
|
|
701
705
|
}
|
|
702
706
|
|
|
703
|
-
const
|
|
707
|
+
const fig = new FigTreeEvaluator()
|
|
704
708
|
|
|
705
709
|
const expression = getExpressionFromConfig()
|
|
706
710
|
|
|
707
|
-
|
|
711
|
+
fig.evaluate(expression, { data: { user } })
|
|
708
712
|
```
|
|
709
713
|
|
|
710
714
|
Here is the result of various values of `expression:`
|
|
@@ -731,7 +735,7 @@ Here is the result of various values of `expression:`
|
|
|
731
735
|
Notice the last example pulls multiple values out of an array of objects, in this case the "name". This is essentially a shorthand for:
|
|
732
736
|
|
|
733
737
|
```js
|
|
734
|
-
|
|
738
|
+
fig.evaluate(
|
|
735
739
|
{ operator: 'getProperty', path: 'user.enemies' },
|
|
736
740
|
{ data: { user } }
|
|
737
741
|
).map((e) => e.name)
|
|
@@ -911,7 +915,7 @@ e.g.
|
|
|
911
915
|
`children` array: `[urlObject, parameterKeys, ...values, returnProperty]`
|
|
912
916
|
|
|
913
917
|
- `urlObject`: either a url string, or an object structured as `{url: <string>, headers: <object>}` (if additional headers are required)
|
|
914
|
-
- `parameterKeys`: an array of strings representing the keys of any query parameters
|
|
918
|
+
- `parameterKeys`: an array of strings representing the keys of any query parameters (or just a single string if only one)
|
|
915
919
|
- `...values`: one value for each key specified in `parameterKeys`
|
|
916
920
|
- `returnProperty` (optional): as above
|
|
917
921
|
|
|
@@ -1062,7 +1066,7 @@ const pgConnect = new Client(pgConfig) // pgConfig = database details, see node-
|
|
|
1062
1066
|
|
|
1063
1067
|
pgConnect.connect()
|
|
1064
1068
|
|
|
1065
|
-
const
|
|
1069
|
+
const fig = new FigTreeEvaluator({ pgConnection: pgConnect })
|
|
1066
1070
|
```
|
|
1067
1071
|
|
|
1068
1072
|
The following examples query a default installation of the [Northwind](https://github.com/pthom/northwind_psql) demo database.
|
|
@@ -1279,7 +1283,7 @@ Custom functions are stored in the evaluator `options`, in the `functions` prope
|
|
|
1279
1283
|
|
|
1280
1284
|
For examples, consider the following fig-tree instance:
|
|
1281
1285
|
```js
|
|
1282
|
-
const
|
|
1286
|
+
const fig = new FigTreeEvaluator({
|
|
1283
1287
|
functions: {
|
|
1284
1288
|
double: (x) => x * 2,
|
|
1285
1289
|
getCurrentYear: () => new Date().toLocaleString('en', { year: 'numeric' }),
|
|
@@ -1420,7 +1424,7 @@ The idea is that you can "hard-code" some common expressions into your app, so t
|
|
|
1420
1424
|
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:
|
|
1421
1425
|
|
|
1422
1426
|
```js
|
|
1423
|
-
const
|
|
1427
|
+
const fig = new FigTreeEvaluator({
|
|
1424
1428
|
fragments: {
|
|
1425
1429
|
getCapital: {
|
|
1426
1430
|
operator: 'GET',
|
|
@@ -1431,6 +1435,11 @@ const exp = new FigTreeEvaluator({
|
|
|
1431
1435
|
},
|
|
1432
1436
|
returnProperty: '[0].capital',
|
|
1433
1437
|
outputType: 'string',
|
|
1438
|
+
metadata: {
|
|
1439
|
+
// Not required, but useful for external consumers -- see Metadata below
|
|
1440
|
+
description: "Fetches the capital city of a country",
|
|
1441
|
+
parameters: { $country: { type: 'string', required: true } },
|
|
1442
|
+
}
|
|
1434
1443
|
},
|
|
1435
1444
|
},
|
|
1436
1445
|
})
|
|
@@ -1458,6 +1467,63 @@ See `22_fragments.test.ts` for more complex examples.
|
|
|
1458
1467
|
|
|
1459
1468
|
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.
|
|
1460
1469
|
|
|
1470
|
+
## Shorthand syntax
|
|
1471
|
+
|
|
1472
|
+
It's possible to express FigTree expressions in a more compact syntax, as follows:
|
|
1473
|
+
|
|
1474
|
+
- Fragment and Operator nodes can be represented by putting the name of the fragment or operator as a property name (prefixed by `$`), then putting the parameters in an object as the property value. For example:
|
|
1475
|
+
```js
|
|
1476
|
+
{
|
|
1477
|
+
operator: 'regex',
|
|
1478
|
+
string: "home@myplace.com",
|
|
1479
|
+
pattern: '^[A-Za-z0-9.]+@[A-Za-z0-9]+\\.[A-Za-z0-9.]+$'
|
|
1480
|
+
}
|
|
1481
|
+
```
|
|
1482
|
+
can be written as:
|
|
1483
|
+
```js
|
|
1484
|
+
{
|
|
1485
|
+
$regex:
|
|
1486
|
+
{
|
|
1487
|
+
string: 'home@myplace.com',
|
|
1488
|
+
pattern: '^[A-Za-z0-9.]+@[A-Za-z0-9]+\\.[A-Za-z0-9.]+$'
|
|
1489
|
+
},
|
|
1490
|
+
}
|
|
1491
|
+
```
|
|
1492
|
+
|
|
1493
|
+
- For operator nodes (not fragments, as they always require named parameters), parameters can be represented positionally (equivalent to the `children` property in normal operator nodes) in an array. The above example could also be expressed as:
|
|
1494
|
+
```js
|
|
1495
|
+
{
|
|
1496
|
+
$regex: [ 'home@myplace.com', '^[A-Za-z0-9.]+@[A-Za-z0-9]+\\.[A-Za-z0-9.]+$' ]
|
|
1497
|
+
}
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
- Operator nodes with a single parameter can just be placed directly as the single property value. For example:
|
|
1501
|
+
```js
|
|
1502
|
+
{
|
|
1503
|
+
operator: "getData",
|
|
1504
|
+
property: "user.firstName"
|
|
1505
|
+
}
|
|
1506
|
+
```
|
|
1507
|
+
can become, simply:
|
|
1508
|
+
```js
|
|
1509
|
+
{ $getData: "user.firstName" }
|
|
1510
|
+
```
|
|
1511
|
+
|
|
1512
|
+
- Operator nodes can even be represented as strings, written to resemble functions. The above example can be reduced further to just:
|
|
1513
|
+
```js
|
|
1514
|
+
"$getData(user.firstName)"
|
|
1515
|
+
```
|
|
1516
|
+
Multiple parameters are interpreted positionally, as above. These string-functions *can* be nested, although it is generally recommended to limit them to "leaf" nodes for readability.
|
|
1517
|
+
|
|
1518
|
+
Fragments can also be represented in this "string-function" syntax, but only if they have no parameters, for example:
|
|
1519
|
+
```js
|
|
1520
|
+
"$myFragment()"
|
|
1521
|
+
```
|
|
1522
|
+
would be replaced with the fragment `myFragment`.
|
|
1523
|
+
|
|
1524
|
+
For more examples, see `23_shorthand.test.ts`, or have a play with the [demo app](https://carlosnz.github.io/fig-tree-evaluator/) app.
|
|
1525
|
+
|
|
1526
|
+
|
|
1461
1527
|
## Caching (Memoization)
|
|
1462
1528
|
|
|
1463
1529
|
FigTree Evaluator has basic [memoization](https://en.wikipedia.org/wiki/Memoization) functionality for certain nodes to speed up re-evaluation when the input parameters haven't changed. There is a single cache store per FigTree instance which persists for the lifetime of the instance. By default, it remembers the last 50 results, but this can be modified using the `maxCacheSize` option.
|
|
@@ -1476,6 +1542,120 @@ This is different to the memoization provided by [Alias Nodes](#alias-nodes):
|
|
|
1476
1542
|
|
|
1477
1543
|
Caching is enabled by default for most of the above operators, but this can be overridden by setting `useCache: false` in [options](#available-options), either globally or per expression. If you're querying a database or API that is likely to have a different result for the same request (i.e. data has changed), then you probably want to turn the cache off.
|
|
1478
1544
|
|
|
1545
|
+
## Metadata
|
|
1546
|
+
|
|
1547
|
+
Evaluator expression can be configured by hand, with [aliases](#alias-nodes), [fragments](#fragments) and [shorthand](#shorthand-syntax) available to make the job easier.
|
|
1548
|
+
|
|
1549
|
+
However, you may wish to build an external UI for building FigTree expression. To this end, the FigTree instance provides three methods that could be useful for populating your configuration UI:
|
|
1550
|
+
|
|
1551
|
+
#### New FigTree instance
|
|
1552
|
+
|
|
1553
|
+
Containing fragments and [custom functions](#custom_functions).
|
|
1554
|
+
|
|
1555
|
+
```js
|
|
1556
|
+
const fig = new FigTreeEvaluator({
|
|
1557
|
+
fragments: {
|
|
1558
|
+
getCapital: {
|
|
1559
|
+
operator: 'GET',
|
|
1560
|
+
url: {
|
|
1561
|
+
operator: 'stringSubstitution',
|
|
1562
|
+
string: 'https://restcountries.com/v3.1/name/%1',
|
|
1563
|
+
replacements: [ "$country" ],
|
|
1564
|
+
},
|
|
1565
|
+
returnProperty: '[0].capital',
|
|
1566
|
+
outputType: 'string',
|
|
1567
|
+
// Metadata used by getFragments() (below)
|
|
1568
|
+
metadata: {
|
|
1569
|
+
description: "Fetches the capital city of a country",
|
|
1570
|
+
parameters: { $country: { type: 'string', required: true } },
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
... // More fragments
|
|
1574
|
+
},
|
|
1575
|
+
functions: {
|
|
1576
|
+
doubleArray: (...args) => args.map((e) => e + e),
|
|
1577
|
+
getDate: (dateString) => new Date(dateString),
|
|
1578
|
+
... // More functions
|
|
1579
|
+
}
|
|
1580
|
+
... // More options
|
|
1581
|
+
})
|
|
1582
|
+
```
|
|
1583
|
+
|
|
1584
|
+
#### Retrieve Operator info
|
|
1585
|
+
|
|
1586
|
+
```js
|
|
1587
|
+
fig.getOperators()
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1590
|
+
This will return an array of operators with detailed info about their [aliases](#operator--property-aliases), and parameter requirements:
|
|
1591
|
+
|
|
1592
|
+
```js
|
|
1593
|
+
[
|
|
1594
|
+
...
|
|
1595
|
+
{
|
|
1596
|
+
operator: 'PLUS',
|
|
1597
|
+
description: 'Add, concatenate or merge multiple values',
|
|
1598
|
+
aliases: ['+', 'plus', 'add', 'concat', 'join', 'merge'],
|
|
1599
|
+
parameters: [
|
|
1600
|
+
{
|
|
1601
|
+
name: 'values',
|
|
1602
|
+
description: 'Array of values to check to add together',
|
|
1603
|
+
aliases: [],
|
|
1604
|
+
required: true,
|
|
1605
|
+
type: 'array',
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
name: 'type',
|
|
1609
|
+
description: 'Data type to coerce input values to before addition',
|
|
1610
|
+
aliases: [],
|
|
1611
|
+
required: false,
|
|
1612
|
+
type: 'string',
|
|
1613
|
+
},
|
|
1614
|
+
],
|
|
1615
|
+
},
|
|
1616
|
+
... // More operators
|
|
1617
|
+
]
|
|
1618
|
+
```
|
|
1619
|
+
|
|
1620
|
+
#### Retrieve Fragment info
|
|
1621
|
+
|
|
1622
|
+
Because Fragments are defined within the FigTree instance, optional metadata can be provided to make working with these fragments easier in a configuration UI:
|
|
1623
|
+
|
|
1624
|
+
```js
|
|
1625
|
+
fig.getOperators()
|
|
1626
|
+
```
|
|
1627
|
+
|
|
1628
|
+
This will return something like:
|
|
1629
|
+
|
|
1630
|
+
```js
|
|
1631
|
+
[
|
|
1632
|
+
{
|
|
1633
|
+
name: 'getCapital',
|
|
1634
|
+
description: 'Fetches the capital city of a country',
|
|
1635
|
+
parameters: { $country: { type: 'string', required: true } },
|
|
1636
|
+
},
|
|
1637
|
+
{ name: 'simpleFragment' }, // No metadata provided
|
|
1638
|
+
... // More fragments
|
|
1639
|
+
]
|
|
1640
|
+
```
|
|
1641
|
+
|
|
1642
|
+
#### Retrieve customFunction info
|
|
1643
|
+
|
|
1644
|
+
Similarly, we can fetch basic info about custom functions in the current FigTree instance, although with more limited detail:
|
|
1645
|
+
```js
|
|
1646
|
+
fig.getCustomFunctions()
|
|
1647
|
+
```
|
|
1648
|
+
|
|
1649
|
+
Returns:
|
|
1650
|
+
|
|
1651
|
+
```js
|
|
1652
|
+
[
|
|
1653
|
+
{ name: 'doubleArray', numRequiredArgs: 0 },
|
|
1654
|
+
{ name: 'getDate', numRequiredArgs: 1 },
|
|
1655
|
+
... // More functions
|
|
1656
|
+
]
|
|
1657
|
+
```
|
|
1658
|
+
|
|
1479
1659
|
## More examples
|
|
1480
1660
|
|
|
1481
1661
|
More examples, included large, complex expressions can be found within the test suites in the [repository](https://github.com/CarlosNZ/fig-tree-evaluator).
|
|
@@ -1510,6 +1690,10 @@ Please open an issue: https://github.com/CarlosNZ/fig-tree-evaluator/issues
|
|
|
1510
1690
|
|
|
1511
1691
|
*Trivial upgrades (e.g. documentation, small re-factors, types, etc.) not included*
|
|
1512
1692
|
|
|
1693
|
+
- **v2.8.0**:
|
|
1694
|
+
- [Shorthand syntax](#shorthand-syntax) (#80)
|
|
1695
|
+
- Methods to retrieve [metadata](#metadata) about operators, fragments and functions (#82)
|
|
1696
|
+
- **v2.7.0**: Add `excludeOperators` option to allow certain operators to be prohibited (e.g. database lookups) (#54)
|
|
1513
1697
|
- **v2.6.0**: Resolve alias nodes that are not part of an Operator node when `evaluateFullObject` is enabled (#78)
|
|
1514
1698
|
- **v2.5.0**:
|
|
1515
1699
|
- Bug fixes for edge cases (mainly related to backwards compatibility)
|
|
@@ -9,6 +9,24 @@ declare class FigTreeEvaluator {
|
|
|
9
9
|
evaluate(expression: EvaluatorNode, options?: FigTreeOptions): Promise<import("./types").EvaluatorOutput>;
|
|
10
10
|
getOptions(): FigTreeOptions;
|
|
11
11
|
updateOptions(options: FigTreeOptions): void;
|
|
12
|
+
getOperators(): {
|
|
13
|
+
description: string;
|
|
14
|
+
aliases: string[];
|
|
15
|
+
parameters: import("./types").Parameter[];
|
|
16
|
+
operator: string;
|
|
17
|
+
}[];
|
|
18
|
+
getFragments(): {
|
|
19
|
+
description?: string | undefined;
|
|
20
|
+
parameters?: Record<string, {
|
|
21
|
+
type: string | string[];
|
|
22
|
+
required: boolean;
|
|
23
|
+
}> | undefined;
|
|
24
|
+
name: string;
|
|
25
|
+
}[];
|
|
26
|
+
getCustomFunctions(): {
|
|
27
|
+
name: string;
|
|
28
|
+
numRequiredArgs: number;
|
|
29
|
+
}[];
|
|
12
30
|
getVersion: () => any;
|
|
13
31
|
}
|
|
14
32
|
export default FigTreeEvaluator;
|
|
@@ -43,8 +43,10 @@ const operators = __importStar(require("./operators"));
|
|
|
43
43
|
const helpers_1 = require("./helpers");
|
|
44
44
|
const cache_1 = __importDefault(require("./cache"));
|
|
45
45
|
const pkg = require('../package.json');
|
|
46
|
+
const operatorAliases = _operatorAliases_json_1.default;
|
|
46
47
|
class FigTreeEvaluator {
|
|
47
48
|
constructor(options = {}) {
|
|
49
|
+
var _a, _b;
|
|
48
50
|
this.typeChecker = (...args) => {
|
|
49
51
|
const result = (0, typeCheck_1.typeCheck)(...args);
|
|
50
52
|
if (result === true)
|
|
@@ -53,8 +55,8 @@ class FigTreeEvaluator {
|
|
|
53
55
|
};
|
|
54
56
|
this.getVersion = () => pkg.version;
|
|
55
57
|
this.options = standardiseOptionNames(options);
|
|
56
|
-
this.operators = operators;
|
|
57
|
-
this.operatorAliases =
|
|
58
|
+
this.operators = (0, helpers_1.filterOperators)(operators, (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.excludeOperators) !== null && _b !== void 0 ? _b : [], operatorAliases);
|
|
59
|
+
this.operatorAliases = operatorAliases;
|
|
58
60
|
this.cache = new cache_1.default(options.maxCacheSize);
|
|
59
61
|
}
|
|
60
62
|
evaluate(expression, options = {}) {
|
|
@@ -64,7 +66,9 @@ class FigTreeEvaluator {
|
|
|
64
66
|
this.cache.setMax(currentOptions.maxCacheSize);
|
|
65
67
|
return yield (0, evaluate_1.evaluatorFunction)(expression, {
|
|
66
68
|
options: currentOptions,
|
|
67
|
-
operators:
|
|
69
|
+
operators: options.excludeOperators
|
|
70
|
+
? (0, helpers_1.filterOperators)(operators, options.excludeOperators, operatorAliases)
|
|
71
|
+
: this.operators,
|
|
68
72
|
operatorAliases: this.operatorAliases,
|
|
69
73
|
typeChecker: currentOptions.skipRuntimeTypeCheck ? () => { } : this.typeChecker,
|
|
70
74
|
resolvedAliasNodes: {},
|
|
@@ -77,6 +81,25 @@ class FigTreeEvaluator {
|
|
|
77
81
|
}
|
|
78
82
|
updateOptions(options) {
|
|
79
83
|
this.options = (0, helpers_1.mergeOptions)(this.options, standardiseOptionNames(options));
|
|
84
|
+
if (this.options.excludeOperators)
|
|
85
|
+
this.operators = (0, helpers_1.filterOperators)(operators, this.options.excludeOperators, operatorAliases);
|
|
86
|
+
}
|
|
87
|
+
getOperators() {
|
|
88
|
+
const validOperators = this.options.excludeOperators
|
|
89
|
+
? (0, helpers_1.filterOperators)(operators, this.options.excludeOperators, operatorAliases)
|
|
90
|
+
: this.operators;
|
|
91
|
+
return Object.entries(validOperators).map(([key, value]) => (Object.assign({ operator: key }, value.operatorData)));
|
|
92
|
+
}
|
|
93
|
+
getFragments() {
|
|
94
|
+
var _a;
|
|
95
|
+
return Object.entries((_a = this.options.fragments) !== null && _a !== void 0 ? _a : {}).map(([key, value]) => (Object.assign({ name: key }, value === null || value === void 0 ? void 0 : value.metadata)));
|
|
96
|
+
}
|
|
97
|
+
getCustomFunctions() {
|
|
98
|
+
var _a;
|
|
99
|
+
return Object.entries((_a = this.options.functions) !== null && _a !== void 0 ? _a : {}).map(([name, value]) => ({
|
|
100
|
+
name,
|
|
101
|
+
numRequiredArgs: value.length,
|
|
102
|
+
}));
|
|
80
103
|
}
|
|
81
104
|
}
|
|
82
105
|
exports.default = FigTreeEvaluator;
|
package/build/evaluate.js
CHANGED
|
@@ -11,11 +11,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.evaluatorFunction = void 0;
|
|
13
13
|
const _operatorUtils_1 = require("./operators/_operatorUtils");
|
|
14
|
+
const shorthandSyntax_1 = require("./shorthandSyntax");
|
|
14
15
|
const helpers_1 = require("./helpers");
|
|
15
16
|
const evaluatorFunction = (input, config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
-
var _a, _b, _c;
|
|
17
|
+
var _a, _b, _c, _d;
|
|
17
18
|
const { options, operators, operatorAliases } = config;
|
|
18
19
|
let expression = (options === null || options === void 0 ? void 0 : options.allowJSONStringInput) ? (0, helpers_1.parseIfJson)(input) : input;
|
|
20
|
+
expression = (0, shorthandSyntax_1.preProcessShorthand)(expression, (_a = config.options) === null || _a === void 0 ? void 0 : _a.fragments, !options.noShorthand);
|
|
19
21
|
if (Array.isArray(expression)) {
|
|
20
22
|
expression = yield (0, _operatorUtils_1.evaluateArray)(expression, config);
|
|
21
23
|
}
|
|
@@ -29,14 +31,14 @@ const evaluatorFunction = (input, config) => __awaiter(void 0, void 0, void 0, f
|
|
|
29
31
|
return (0, helpers_1.replaceAliasNodeValues)(expression, config);
|
|
30
32
|
}
|
|
31
33
|
const { fallback } = expression;
|
|
32
|
-
const returnErrorAsString = (
|
|
34
|
+
const returnErrorAsString = (_b = options === null || options === void 0 ? void 0 : options.returnErrorAsString) !== null && _b !== void 0 ? _b : false;
|
|
33
35
|
if (isFragment) {
|
|
34
36
|
const [fragment, parameters] = (yield (0, _operatorUtils_1.evaluateArray)([expression.fragment, expression.parameters], config));
|
|
35
|
-
const fragmentReplacement = (
|
|
37
|
+
const fragmentReplacement = (0, shorthandSyntax_1.preProcessShorthand)((_c = options === null || options === void 0 ? void 0 : options.fragments) === null || _c === void 0 ? void 0 : _c[fragment], options.fragments, !options.noShorthand);
|
|
36
38
|
if (fragmentReplacement === undefined)
|
|
37
39
|
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback, config), `Fragment not defined: ${fragment}`, returnErrorAsString);
|
|
38
40
|
if (!(0, helpers_1.isOperatorNode)(fragmentReplacement))
|
|
39
|
-
return fragmentReplacement;
|
|
41
|
+
return (0, helpers_1.replaceAliasNodeValues)(fragmentReplacement, config);
|
|
40
42
|
expression = Object.assign(Object.assign(Object.assign({}, expression), fragmentReplacement), parameters);
|
|
41
43
|
delete expression.fragment;
|
|
42
44
|
delete expression.parameters;
|
|
@@ -45,27 +47,33 @@ const evaluatorFunction = (input, config) => __awaiter(void 0, void 0, void 0, f
|
|
|
45
47
|
const operator = (0, helpers_1.getOperatorName)(expression.operator, operatorAliases);
|
|
46
48
|
if (!operator)
|
|
47
49
|
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback, config), `Invalid operator: ${expression.operator}`, returnErrorAsString);
|
|
50
|
+
if (!config.operators[operator])
|
|
51
|
+
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback, config), `Excluded operator: ${expression.operator}`, returnErrorAsString);
|
|
48
52
|
const { requiredProperties, propertyAliases, evaluate, parseChildren } = operators[operator];
|
|
49
53
|
expression = (0, helpers_1.mapPropertyAliases)(propertyAliases, expression);
|
|
50
|
-
|
|
54
|
+
const newAliasNodes = yield (0, helpers_1.evaluateNodeAliases)(expression, config);
|
|
55
|
+
if (!isFragment)
|
|
56
|
+
Object.entries(newAliasNodes).forEach(([alias, result]) => (config.resolvedAliasNodes[alias] = result));
|
|
57
|
+
const childConfig = isFragment
|
|
58
|
+
? Object.assign(Object.assign({}, config), { resolvedAliasNodes: Object.assign(Object.assign({}, config.resolvedAliasNodes), newAliasNodes) }) : config;
|
|
51
59
|
const validationError = (0, helpers_1.checkRequiredNodes)(requiredProperties, expression);
|
|
52
60
|
if (validationError)
|
|
53
|
-
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback,
|
|
61
|
+
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback, childConfig), `Operator: ${operator}\n- ${validationError}`, returnErrorAsString);
|
|
54
62
|
if ('children' in expression) {
|
|
55
63
|
if (!Array.isArray(expression.children))
|
|
56
|
-
expression.children = yield (0, exports.evaluatorFunction)(expression.children,
|
|
64
|
+
expression.children = yield (0, exports.evaluatorFunction)(expression.children, childConfig);
|
|
57
65
|
if (!Array.isArray(expression.children))
|
|
58
66
|
return (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(fallback, config), `Operator: ${operator}\n- Property "children" is not of type: array`, returnErrorAsString);
|
|
59
|
-
expression = yield parseChildren(expression,
|
|
67
|
+
expression = yield parseChildren(expression, childConfig);
|
|
60
68
|
}
|
|
61
69
|
let result;
|
|
62
70
|
try {
|
|
63
|
-
result = yield evaluate(expression,
|
|
71
|
+
result = yield evaluate(expression, childConfig);
|
|
64
72
|
}
|
|
65
73
|
catch (err) {
|
|
66
74
|
result = (0, helpers_1.fallbackOrError)(yield (0, exports.evaluatorFunction)(expression.fallback, config), `Operator: ${operator}\n${(0, helpers_1.errorMessage)(err)}`, returnErrorAsString);
|
|
67
75
|
}
|
|
68
|
-
const outputType = (
|
|
76
|
+
const outputType = (_d = expression === null || expression === void 0 ? void 0 : expression.outputType) !== null && _d !== void 0 ? _d : expression === null || expression === void 0 ? void 0 : expression.type;
|
|
69
77
|
if (!outputType)
|
|
70
78
|
return result;
|
|
71
79
|
const evaluatedOutputType = (yield (0, exports.evaluatorFunction)(outputType, config));
|
package/build/helpers.d.ts
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
|
-
import { OutputType, EvaluatorNode, CombinedOperatorNode,
|
|
1
|
+
import { OutputType, EvaluatorNode, CombinedOperatorNode, EvaluatorOutput, FigTreeOptions, OperatorNodeUnion, FigTreeConfig, OperatorReference, OperatorAliases } from './types';
|
|
2
2
|
export declare const parseIfJson: (input: EvaluatorNode) => any;
|
|
3
3
|
export declare const isOperatorNode: (input: EvaluatorNode) => boolean;
|
|
4
4
|
export declare const isFragmentNode: (input: EvaluatorNode) => boolean;
|
|
5
|
-
export declare const getOperatorName: (operator: string, operatorAliases:
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export declare const getOperatorName: (operator: string, operatorAliases: OperatorAliases) => "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";
|
|
6
|
+
export declare const filterOperators: (operators: OperatorReference, exclusions: string[], operatorAliases: OperatorAliases) => {
|
|
7
|
+
AND: import("./types").OperatorObject;
|
|
8
|
+
OR: import("./types").OperatorObject;
|
|
9
|
+
EQUAL: import("./types").OperatorObject;
|
|
10
|
+
NOT_EQUAL: import("./types").OperatorObject;
|
|
11
|
+
PLUS: import("./types").OperatorObject;
|
|
12
|
+
SUBTRACT: import("./types").OperatorObject;
|
|
13
|
+
MULTIPLY: import("./types").OperatorObject;
|
|
14
|
+
DIVIDE: import("./types").OperatorObject;
|
|
15
|
+
GREATER_THAN: import("./types").OperatorObject;
|
|
16
|
+
LESS_THAN: import("./types").OperatorObject;
|
|
17
|
+
CONDITIONAL: import("./types").OperatorObject;
|
|
18
|
+
REGEX: import("./types").OperatorObject;
|
|
19
|
+
OBJECT_PROPERTIES: import("./types").OperatorObject;
|
|
20
|
+
STRING_SUBSTITUTION: import("./types").OperatorObject;
|
|
21
|
+
SPLIT: import("./types").OperatorObject;
|
|
22
|
+
COUNT: import("./types").OperatorObject;
|
|
23
|
+
GET: import("./types").OperatorObject;
|
|
24
|
+
POST: import("./types").OperatorObject;
|
|
25
|
+
PG_SQL: import("./types").OperatorObject;
|
|
26
|
+
GRAPHQL: import("./types").OperatorObject;
|
|
27
|
+
BUILD_OBJECT: import("./types").OperatorObject;
|
|
28
|
+
MATCH: import("./types").OperatorObject;
|
|
29
|
+
CUSTOM_FUNCTIONS: import("./types").OperatorObject;
|
|
30
|
+
PASSTHRU: import("./types").OperatorObject;
|
|
31
|
+
};
|
|
8
32
|
export declare const truncateString: (string: string, length?: number) => string;
|
|
9
33
|
export declare const fallbackOrError: (fallback: any, errorMessage: string, returnErrorAsString?: boolean) => any;
|
|
10
34
|
export declare const mapPropertyAliases: (propertyAliases: {
|
|
11
35
|
[key: string]: string;
|
|
12
36
|
}, expression: CombinedOperatorNode) => CombinedOperatorNode;
|
|
37
|
+
export declare const isAliasString: (value: string) => boolean;
|
|
13
38
|
export declare const evaluateNodeAliases: (expression: OperatorNodeUnion, config: FigTreeConfig) => Promise<{
|
|
14
39
|
[x: string]: EvaluatorOutput;
|
|
15
40
|
}>;
|
package/build/helpers.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.evaluateObject = exports.isObject = 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;
|
|
12
|
+
exports.evaluateObject = exports.isObject = exports.errorMessage = exports.convertOutputMethods = exports.mergeOptions = exports.checkRequiredNodes = exports.replaceAliasNodeValues = exports.evaluateNodeAliases = exports.isAliasString = exports.mapPropertyAliases = exports.fallbackOrError = exports.truncateString = exports.filterOperators = exports.getOperatorName = exports.isFragmentNode = exports.isOperatorNode = exports.parseIfJson = void 0;
|
|
13
13
|
const change_case_1 = require("change-case");
|
|
14
14
|
const evaluate_1 = require("./evaluate");
|
|
15
15
|
const _operatorUtils_1 = require("./operators/_operatorUtils");
|
|
@@ -35,6 +35,17 @@ const standardiseOperatorName = (name) => {
|
|
|
35
35
|
};
|
|
36
36
|
const getOperatorName = (operator, operatorAliases) => operatorAliases[standardiseOperatorName(operator)];
|
|
37
37
|
exports.getOperatorName = getOperatorName;
|
|
38
|
+
const filterOperators = (operators, exclusions, operatorAliases) => {
|
|
39
|
+
const filteredOperators = Object.assign({}, operators);
|
|
40
|
+
exclusions.forEach((exclusion) => {
|
|
41
|
+
const operator = operatorAliases[standardiseOperatorName(exclusion)];
|
|
42
|
+
if (!operator)
|
|
43
|
+
console.warn(`Invalid operator exclusion: ${exclusion}`);
|
|
44
|
+
delete filteredOperators[operatorAliases[standardiseOperatorName(exclusion)]];
|
|
45
|
+
});
|
|
46
|
+
return filteredOperators;
|
|
47
|
+
};
|
|
48
|
+
exports.filterOperators = filterOperators;
|
|
38
49
|
const truncateString = (string, length = 200) => string.length < length ? string : `${string.slice(0, length - 2).trim()}...`;
|
|
39
50
|
exports.truncateString = truncateString;
|
|
40
51
|
const fallbackOrError = (fallback, errorMessage, returnErrorAsString = false) => {
|
|
@@ -54,8 +65,9 @@ const mapObjectKeys = (inputObj, mapFunction) => {
|
|
|
54
65
|
return Object.fromEntries(mappedKeys);
|
|
55
66
|
};
|
|
56
67
|
const isAliasString = (value) => /^\$.+/.test(value);
|
|
68
|
+
exports.isAliasString = isAliasString;
|
|
57
69
|
const evaluateNodeAliases = (expression, config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
-
const aliasKeys = Object.keys(expression).filter(isAliasString);
|
|
70
|
+
const aliasKeys = Object.keys(expression).filter(exports.isAliasString);
|
|
59
71
|
if (aliasKeys.length === 0)
|
|
60
72
|
return {};
|
|
61
73
|
const evaluations = [];
|
|
@@ -65,7 +77,7 @@ const evaluateNodeAliases = (expression, config) => __awaiter(void 0, void 0, vo
|
|
|
65
77
|
exports.evaluateNodeAliases = evaluateNodeAliases;
|
|
66
78
|
const replaceAliasNodeValues = (value, { resolvedAliasNodes }) => {
|
|
67
79
|
var _a;
|
|
68
|
-
if (typeof value !== 'string' || !isAliasString(value))
|
|
80
|
+
if (typeof value !== 'string' || !(0, exports.isAliasString)(value))
|
|
69
81
|
return value;
|
|
70
82
|
return (_a = resolvedAliasNodes === null || resolvedAliasNodes === void 0 ? void 0 : resolvedAliasNodes[value]) !== null && _a !== void 0 ? _a : value;
|
|
71
83
|
};
|
|
@@ -118,7 +130,7 @@ const evaluateObject = (input, config) => __awaiter(void 0, void 0, void 0, func
|
|
|
118
130
|
const newObjectEntries = [];
|
|
119
131
|
const newAliases = [];
|
|
120
132
|
Object.entries(input).forEach(([key, value]) => {
|
|
121
|
-
if (isAliasString(key)) {
|
|
133
|
+
if ((0, exports.isAliasString)(key)) {
|
|
122
134
|
newAliases.push(key, (0, evaluate_1.evaluatorFunction)(value, config));
|
|
123
135
|
delete input[key];
|
|
124
136
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.propertyAliases = exports.requiredProperties = void 0;
|
|
4
|
+
const _operatorUtils_1 = require("../_operatorUtils");
|
|
5
|
+
const description = 'Logical AND';
|
|
6
|
+
const aliases = ['and', '&', '&&'];
|
|
7
|
+
const parameters = [
|
|
8
|
+
{
|
|
9
|
+
name: 'values',
|
|
10
|
+
description: 'Returns true if all values are true',
|
|
11
|
+
aliases: [],
|
|
12
|
+
required: true,
|
|
13
|
+
type: 'array',
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
exports.requiredProperties = (0, _operatorUtils_1.getRequiredProperties)(parameters);
|
|
17
|
+
exports.propertyAliases = (0, _operatorUtils_1.getPropertyAliases)(parameters);
|
|
18
|
+
const operatorData = {
|
|
19
|
+
description,
|
|
20
|
+
aliases,
|
|
21
|
+
parameters,
|
|
22
|
+
};
|
|
23
|
+
exports.default = operatorData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AND, type BasicExtendedNode } from './operator';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { EvaluatorNode, BaseOperatorNode, CombinedOperatorNode, OperatorObject } from '
|
|
2
|
-
|
|
1
|
+
import { EvaluatorNode, BaseOperatorNode, CombinedOperatorNode, OperatorObject } from '../../types';
|
|
2
|
+
import { requiredProperties } from './data';
|
|
3
3
|
export type BasicExtendedNode = {
|
|
4
4
|
[key in typeof requiredProperties[number]]: EvaluatorNode[];
|
|
5
5
|
} & BaseOperatorNode;
|
|
6
6
|
export declare const parseChildren: (expression: CombinedOperatorNode) => BasicExtendedNode;
|
|
7
7
|
export declare const AND: OperatorObject;
|
|
8
|
-
export {};
|