n8n-workflow 2.45.0 → 2.46.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/dist/cjs/build.tsbuildinfo +1 -1
- package/dist/cjs/errors/abstract/execution-base.error.d.ts.map +1 -1
- package/dist/cjs/errors/abstract/execution-base.error.js +0 -7
- package/dist/cjs/errors/abstract/execution-base.error.js.map +1 -1
- package/dist/cjs/errors/execution-cancelled.error.d.ts +4 -1
- package/dist/cjs/errors/execution-cancelled.error.d.ts.map +1 -1
- package/dist/cjs/errors/execution-cancelled.error.js +8 -1
- package/dist/cjs/errors/execution-cancelled.error.js.map +1 -1
- package/dist/cjs/errors/index.d.ts +1 -1
- package/dist/cjs/errors/index.d.ts.map +1 -1
- package/dist/cjs/errors/index.js +2 -1
- package/dist/cjs/errors/index.js.map +1 -1
- package/dist/cjs/errors/workflow-activation.error.d.ts.map +1 -1
- package/dist/cjs/errors/workflow-activation.error.js +15 -2
- package/dist/cjs/errors/workflow-activation.error.js.map +1 -1
- package/dist/cjs/execution-cancellation.d.ts +4 -0
- package/dist/cjs/execution-cancellation.d.ts.map +1 -0
- package/dist/cjs/execution-cancellation.js +22 -0
- package/dist/cjs/execution-cancellation.js.map +1 -0
- package/dist/cjs/expression.d.ts +17 -0
- package/dist/cjs/expression.d.ts.map +1 -1
- package/dist/cjs/expression.js +64 -5
- package/dist/cjs/expression.js.map +1 -1
- package/dist/cjs/expressions/native-evaluation/compiler.d.ts +14 -0
- package/dist/cjs/expressions/native-evaluation/compiler.d.ts.map +1 -0
- package/dist/cjs/expressions/native-evaluation/compiler.js +68 -0
- package/dist/cjs/expressions/native-evaluation/compiler.js.map +1 -0
- package/dist/cjs/expressions/native-evaluation/index.d.ts.map +1 -1
- package/dist/cjs/expressions/native-evaluation/index.js +38 -66
- package/dist/cjs/expressions/native-evaluation/index.js.map +1 -1
- package/dist/cjs/expressions/native-evaluation/skeleton.d.ts +4 -0
- package/dist/cjs/expressions/native-evaluation/skeleton.d.ts.map +1 -0
- package/dist/cjs/expressions/native-evaluation/skeleton.js +89 -0
- package/dist/cjs/expressions/native-evaluation/skeleton.js.map +1 -0
- package/dist/cjs/expressions/native-evaluation/verify.d.ts +30 -0
- package/dist/cjs/expressions/native-evaluation/verify.d.ts.map +1 -0
- package/dist/cjs/expressions/native-evaluation/verify.js +193 -0
- package/dist/cjs/expressions/native-evaluation/verify.js.map +1 -0
- package/dist/cjs/extensions/array-extensions.d.ts.map +1 -1
- package/dist/cjs/extensions/array-extensions.js +26 -12
- package/dist/cjs/extensions/array-extensions.js.map +1 -1
- package/dist/cjs/extensions/expression-extension.d.ts.map +1 -1
- package/dist/cjs/extensions/expression-extension.js +15 -0
- package/dist/cjs/extensions/expression-extension.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces.d.ts +27 -2
- package/dist/cjs/interfaces.d.ts.map +1 -1
- package/dist/cjs/interfaces.js.map +1 -1
- package/dist/cjs/mcp-helpers.d.ts +19 -3
- package/dist/cjs/mcp-helpers.d.ts.map +1 -1
- package/dist/cjs/mcp-helpers.js +12 -1
- package/dist/cjs/mcp-helpers.js.map +1 -1
- package/dist/cjs/metadata-utils.d.ts.map +1 -1
- package/dist/cjs/metadata-utils.js +5 -2
- package/dist/cjs/metadata-utils.js.map +1 -1
- package/dist/cjs/n8n-oauth2-auth.d.ts.map +1 -1
- package/dist/cjs/n8n-oauth2-auth.js +9 -1
- package/dist/cjs/n8n-oauth2-auth.js.map +1 -1
- package/dist/cjs/node-helpers.d.ts +8 -0
- package/dist/cjs/node-helpers.d.ts.map +1 -1
- package/dist/cjs/node-helpers.js +22 -0
- package/dist/cjs/node-helpers.js.map +1 -1
- package/dist/cjs/schemas.d.ts.map +1 -1
- package/dist/cjs/schemas.js +3 -0
- package/dist/cjs/schemas.js.map +1 -1
- package/dist/cjs/telemetry-helpers.d.ts.map +1 -1
- package/dist/cjs/telemetry-helpers.js +5 -1
- package/dist/cjs/telemetry-helpers.js.map +1 -1
- package/dist/cjs/workflow-checksum.d.ts +0 -3
- package/dist/cjs/workflow-checksum.d.ts.map +1 -1
- package/dist/cjs/workflow-checksum.js +2 -24
- package/dist/cjs/workflow-checksum.js.map +1 -1
- package/dist/esm/errors/abstract/execution-base.error.d.ts.map +1 -1
- package/dist/esm/errors/abstract/execution-base.error.js +0 -7
- package/dist/esm/errors/abstract/execution-base.error.js.map +1 -1
- package/dist/esm/errors/execution-cancelled.error.d.ts +4 -1
- package/dist/esm/errors/execution-cancelled.error.d.ts.map +1 -1
- package/dist/esm/errors/execution-cancelled.error.js +6 -0
- package/dist/esm/errors/execution-cancelled.error.js.map +1 -1
- package/dist/esm/errors/index.d.ts +1 -1
- package/dist/esm/errors/index.d.ts.map +1 -1
- package/dist/esm/errors/index.js +1 -1
- package/dist/esm/errors/index.js.map +1 -1
- package/dist/esm/errors/workflow-activation.error.d.ts.map +1 -1
- package/dist/esm/errors/workflow-activation.error.js +15 -2
- package/dist/esm/errors/workflow-activation.error.js.map +1 -1
- package/dist/esm/execution-cancellation.d.ts +4 -0
- package/dist/esm/execution-cancellation.d.ts.map +1 -0
- package/dist/esm/execution-cancellation.js +18 -0
- package/dist/esm/execution-cancellation.js.map +1 -0
- package/dist/esm/expression.d.ts +17 -0
- package/dist/esm/expression.d.ts.map +1 -1
- package/dist/esm/expression.js +64 -5
- package/dist/esm/expression.js.map +1 -1
- package/dist/esm/expressions/native-evaluation/compiler.d.ts +14 -0
- package/dist/esm/expressions/native-evaluation/compiler.d.ts.map +1 -0
- package/dist/esm/expressions/native-evaluation/compiler.js +65 -0
- package/dist/esm/expressions/native-evaluation/compiler.js.map +1 -0
- package/dist/esm/expressions/native-evaluation/index.d.ts.map +1 -1
- package/dist/esm/expressions/native-evaluation/index.js +36 -64
- package/dist/esm/expressions/native-evaluation/index.js.map +1 -1
- package/dist/esm/expressions/native-evaluation/skeleton.d.ts +4 -0
- package/dist/esm/expressions/native-evaluation/skeleton.d.ts.map +1 -0
- package/dist/esm/expressions/native-evaluation/skeleton.js +85 -0
- package/dist/esm/expressions/native-evaluation/skeleton.js.map +1 -0
- package/dist/esm/expressions/native-evaluation/verify.d.ts +30 -0
- package/dist/esm/expressions/native-evaluation/verify.d.ts.map +1 -0
- package/dist/esm/expressions/native-evaluation/verify.js +151 -0
- package/dist/esm/expressions/native-evaluation/verify.js.map +1 -0
- package/dist/esm/extensions/array-extensions.d.ts.map +1 -1
- package/dist/esm/extensions/array-extensions.js +26 -12
- package/dist/esm/extensions/array-extensions.js.map +1 -1
- package/dist/esm/extensions/expression-extension.d.ts.map +1 -1
- package/dist/esm/extensions/expression-extension.js +15 -0
- package/dist/esm/extensions/expression-extension.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interfaces.d.ts +27 -2
- package/dist/esm/interfaces.d.ts.map +1 -1
- package/dist/esm/interfaces.js.map +1 -1
- package/dist/esm/mcp-helpers.d.ts +19 -3
- package/dist/esm/mcp-helpers.d.ts.map +1 -1
- package/dist/esm/mcp-helpers.js +10 -1
- package/dist/esm/mcp-helpers.js.map +1 -1
- package/dist/esm/metadata-utils.d.ts.map +1 -1
- package/dist/esm/metadata-utils.js +5 -2
- package/dist/esm/metadata-utils.js.map +1 -1
- package/dist/esm/n8n-oauth2-auth.d.ts.map +1 -1
- package/dist/esm/n8n-oauth2-auth.js +9 -1
- package/dist/esm/n8n-oauth2-auth.js.map +1 -1
- package/dist/esm/node-helpers.d.ts +8 -0
- package/dist/esm/node-helpers.d.ts.map +1 -1
- package/dist/esm/node-helpers.js +20 -0
- package/dist/esm/node-helpers.js.map +1 -1
- package/dist/esm/schemas.d.ts.map +1 -1
- package/dist/esm/schemas.js +3 -0
- package/dist/esm/schemas.js.map +1 -1
- package/dist/esm/telemetry-helpers.d.ts.map +1 -1
- package/dist/esm/telemetry-helpers.js +5 -1
- package/dist/esm/telemetry-helpers.js.map +1 -1
- package/dist/esm/typecheck.tsbuildinfo +1 -1
- package/dist/esm/workflow-checksum.d.ts +0 -3
- package/dist/esm/workflow-checksum.d.ts.map +1 -1
- package/dist/esm/workflow-checksum.js +2 -21
- package/dist/esm/workflow-checksum.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/compiler.ts"],"names":[],"mappings":";;;AAAA,gDAAsD;AAEtD,oDAAgD;AAGhD,qCAA4D;AAW5D,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,MAAM,KAAK,GAAG,IAAI,oBAAQ,CAAoC,IAAI,CAAC,CAAC;AACpE,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAE5C,yEAAyE;AACzE,yEAAyE;AACzE,UAAU;AACV,SAAS,YAAY,CAAC,KAAiB;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;IACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,SAAS,CAAC,IAAI,KAAK,qBAAqB;QAAE,OAAO,IAAI,CAAC;IAE1D,IAAI,CAAC;QACJ,OAAO,IAAA,oBAAW,EAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,OAAO,CAAC,UAAkB;IAClC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACJ,MAAM,GAAG,IAAA,gCAAmB,EAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,oEAAoE;QACpE,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,SAAS;QACV,CAAC;QAED,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAA,4BAAmB,EAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,uEAAuE;IACvE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;IAE/F,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AACjC,CAAC;AAED,qBAA4B,UAAkB;IAC7C,IAAI,UAAU,CAAC,MAAM,GAAG,4BAA4B;QAAE,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjF,IAAI,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAErC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAC/B,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI/D,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,QAAQ,EACR,YAAY,GACZ,MAAM,WAAW,CAAC;AAsCnB,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,sBAAsB,GAC1B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,CAYxD"}
|
|
@@ -3,11 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TIME_METHODS = exports.MAX_WORK = exports.MAX_STEPS = exports.MAX_RESULT_LENGTH = exports.ITERATOR_METHODS = exports.CALLABLE_METHODS = void 0;
|
|
4
4
|
exports.isNativelyEvaluable = isNativelyEvaluable;
|
|
5
5
|
exports.evaluateNatively = evaluateNatively;
|
|
6
|
-
const
|
|
7
|
-
const lru_cache_1 = require("@n8n/utils/lru-cache");
|
|
6
|
+
const compiler_1 = require("./compiler");
|
|
8
7
|
const evaluator_1 = require("./evaluator");
|
|
9
8
|
const grammar_1 = require("./grammar");
|
|
10
|
-
const parser_1 = require("./parser");
|
|
11
9
|
const { getPrototypeOf, keys } = Object;
|
|
12
10
|
var grammar_2 = require("./grammar");
|
|
13
11
|
Object.defineProperty(exports, "CALLABLE_METHODS", { enumerable: true, get: function () { return grammar_2.CALLABLE_METHODS; } });
|
|
@@ -16,70 +14,44 @@ Object.defineProperty(exports, "MAX_RESULT_LENGTH", { enumerable: true, get: fun
|
|
|
16
14
|
Object.defineProperty(exports, "MAX_STEPS", { enumerable: true, get: function () { return grammar_2.MAX_STEPS; } });
|
|
17
15
|
Object.defineProperty(exports, "MAX_WORK", { enumerable: true, get: function () { return grammar_2.MAX_WORK; } });
|
|
18
16
|
Object.defineProperty(exports, "TIME_METHODS", { enumerable: true, get: function () { return grammar_2.TIME_METHODS; } });
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (chunk.type === 'text') {
|
|
55
|
-
chunks.push(chunk);
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
const node = compileChunk(chunk);
|
|
59
|
-
if (node === null)
|
|
60
|
-
return null;
|
|
61
|
-
chunks.push({ type: 'code', node });
|
|
62
|
-
nodes.push(node);
|
|
63
|
-
}
|
|
64
|
-
if ((0, parser_1.usesPolyfilledChain)(nodes))
|
|
65
|
-
return null;
|
|
66
|
-
// Mirrors the branch condition in ExpressionBuilder.getExpressionCode.
|
|
67
|
-
const isWholeValue = chunks.length === 2 && chunks[0].type === 'text' && chunks[0].text === '';
|
|
68
|
-
return { chunks, isWholeValue };
|
|
69
|
-
}
|
|
70
|
-
function getCompiled(expression) {
|
|
71
|
-
if (expression.length > MAX_CACHED_EXPRESSION_LENGTH)
|
|
72
|
-
return compile(expression);
|
|
73
|
-
let compiled = cache.get(expression);
|
|
74
|
-
if (compiled === undefined) {
|
|
75
|
-
compiled = compile(expression);
|
|
76
|
-
cache.set(expression, compiled);
|
|
77
|
-
}
|
|
78
|
-
return compiled;
|
|
79
|
-
}
|
|
17
|
+
// Fast native evaluation: an in-process interpreter for a closed subset of
|
|
18
|
+
// the expression grammar.
|
|
19
|
+
//
|
|
20
|
+
// The subset is data path access on the data roots (`$json`, `$parameter`,
|
|
21
|
+
// `$vars`, `$binary`, `$itemIndex`, `$runIndex`) and on node references
|
|
22
|
+
// (`$('Name').item`, `$('Name').first()`, `$input.item`, `$node['Name'].json`),
|
|
23
|
+
// primitive reads off the time roots (`$now.toMillis()`, `$today.year`),
|
|
24
|
+
// literals (array literals of literals included), a fixed set of operators,
|
|
25
|
+
// calls to a closed allowlist of native string/number/array methods, and the
|
|
26
|
+
// five array iterators (some/every/find/filter/map) with a one-parameter
|
|
27
|
+
// arrow callback whose body is in the same subset. Such expressions cannot
|
|
28
|
+
// reach prototypes or touch anything outside the data proxy, and the only
|
|
29
|
+
// loop is a native iterator over a size-capped array under a step budget, so
|
|
30
|
+
// they are interpreted here without the sandbox AST hooks, the
|
|
31
|
+
// global-context setup, or an engine (isolate) evaluation. Anything that
|
|
32
|
+
// does not fit the subset is declined and takes the regular pipeline.
|
|
33
|
+
//
|
|
34
|
+
// Structure follows "parse, don't validate": the esprima AST is not checked
|
|
35
|
+
// in place, it is re-parsed into the closed {@link SimpleNode} grammar below.
|
|
36
|
+
// Construction either yields a node of that grammar or null; the interpreter
|
|
37
|
+
// only ever sees objects this module built, so it cannot read a field the
|
|
38
|
+
// parser did not put there, and unsupported constructs are unrepresentable
|
|
39
|
+
// rather than rejected. Expression text is never executed as code.
|
|
40
|
+
//
|
|
41
|
+
// Data is the other input. Node output is normalised to JSON at the node
|
|
42
|
+
// boundary (verified for Set and Code output on a running instance), so
|
|
43
|
+
// `$json` holds plain objects, arrays and primitives. The runtime guards
|
|
44
|
+
// below therefore target what JSON content can do (sizes) and where the host
|
|
45
|
+
// would diverge from the isolates (live references, coercion, aliasing), not
|
|
46
|
+
// hooks that cannot arrive. Non-JSON values in workflow data are engine bugs.
|
|
47
|
+
//
|
|
48
|
+
// Layout: grammar.ts holds the closed grammar and the allowlists, parser.ts
|
|
49
|
+
// turns esprima output into it, compiler.ts splits, compiles and caches whole
|
|
50
|
+
// expressions, evaluator.ts interprets them, and this file runs them.
|
|
51
|
+
// skeleton.ts and verify.ts serve verify mode only.
|
|
80
52
|
/** Does the expression (leading `=` stripped) fit the native subset? */
|
|
81
53
|
function isNativelyEvaluable(expression) {
|
|
82
|
-
return getCompiled(expression) !== null;
|
|
54
|
+
return (0, compiler_1.getCompiled)(expression) !== null;
|
|
83
55
|
}
|
|
84
56
|
/**
|
|
85
57
|
* Evaluate an expression (with the leading `=` already stripped) in-process.
|
|
@@ -88,7 +60,7 @@ function isNativelyEvaluable(expression) {
|
|
|
88
60
|
* the regular pipeline.
|
|
89
61
|
*/
|
|
90
62
|
function evaluateNatively(expression, data) {
|
|
91
|
-
const compiled = getCompiled(expression);
|
|
63
|
+
const compiled = (0, compiler_1.getCompiled)(expression);
|
|
92
64
|
if (compiled === null)
|
|
93
65
|
return { handled: false };
|
|
94
66
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/index.ts"],"names":[],"mappings":";;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAO5C,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAkCnD;AAkBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAM/D"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skeletonOf = skeletonOf;
|
|
4
|
+
exports.readsClockOrParameter = readsClockOrParameter;
|
|
5
|
+
// The expression's shape without its user data, for verify-mode reports.
|
|
6
|
+
// The grammar is closed, so every method, root and operator here comes from
|
|
7
|
+
// an allowlist; only literals, field names and node names are user text, and
|
|
8
|
+
// those are masked. This masking is the user-data boundary for what verify
|
|
9
|
+
// mode sends to Sentry, so extend it rather than redacting the raw text.
|
|
10
|
+
function skeletonOf(node) {
|
|
11
|
+
switch (node.kind) {
|
|
12
|
+
case 'literal':
|
|
13
|
+
if (typeof node.value === 'string')
|
|
14
|
+
return '<str>';
|
|
15
|
+
if (typeof node.value === 'number')
|
|
16
|
+
return '<num>';
|
|
17
|
+
return String(node.value);
|
|
18
|
+
case 'root':
|
|
19
|
+
case 'timeRoot':
|
|
20
|
+
return node.name;
|
|
21
|
+
case 'nodeRef':
|
|
22
|
+
if (node.ref === 'input')
|
|
23
|
+
return '$input';
|
|
24
|
+
return node.ref === 'node' ? '$(<str>)' : '$node[<str>]';
|
|
25
|
+
case 'undefined':
|
|
26
|
+
return 'undefined';
|
|
27
|
+
case 'param':
|
|
28
|
+
return 'x';
|
|
29
|
+
case 'member':
|
|
30
|
+
return `${skeletonOf(node.object)}${access(node.optional)}${memberKey(node)}`;
|
|
31
|
+
case 'chain':
|
|
32
|
+
return skeletonOf(node.expression);
|
|
33
|
+
case 'unary':
|
|
34
|
+
return `${node.op}${skeletonOf(node.argument)}`;
|
|
35
|
+
case 'binary':
|
|
36
|
+
case 'logical':
|
|
37
|
+
return `(${skeletonOf(node.left)} ${node.op} ${skeletonOf(node.right)})`;
|
|
38
|
+
case 'conditional':
|
|
39
|
+
return `(${skeletonOf(node.test)} ? ${skeletonOf(node.consequent)} : ${skeletonOf(node.alternate)})`;
|
|
40
|
+
case 'call':
|
|
41
|
+
return `${skeletonOf(node.receiver)}${access(node.optional)}${node.method}(${node.args.map(skeletonOf).join(', ')})`;
|
|
42
|
+
case 'array':
|
|
43
|
+
return `[${node.elements.map(skeletonOf).join(', ')}]`;
|
|
44
|
+
case 'iterate':
|
|
45
|
+
return `${skeletonOf(node.receiver)}${access(node.optional)}${node.method}(x => ${skeletonOf(node.body)})`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const access = (optional) => (optional ? '?.' : '.');
|
|
49
|
+
// n8n's own item keys. `length` tells a string or array read apart.
|
|
50
|
+
const KNOWN_KEYS = new Set(['json', 'binary', 'length']);
|
|
51
|
+
// Keys off node references and time roots come from allowlists; any other
|
|
52
|
+
// key is a field name from workflow data.
|
|
53
|
+
function memberKey(node) {
|
|
54
|
+
if (typeof node.key === 'number')
|
|
55
|
+
return '<num>';
|
|
56
|
+
if (node.object.kind === 'nodeRef' || node.object.kind === 'timeRoot')
|
|
57
|
+
return node.key;
|
|
58
|
+
return KNOWN_KEYS.has(node.key) ? node.key : '<id>';
|
|
59
|
+
}
|
|
60
|
+
// The engine reads its own clock, and a `$parameter` read evaluates that
|
|
61
|
+
// parameter again, which can read the clock too. Two evaluations of such an
|
|
62
|
+
// expression can differ without a bug.
|
|
63
|
+
function readsClockOrParameter(node) {
|
|
64
|
+
return (node.kind === 'timeRoot' ||
|
|
65
|
+
(node.kind === 'root' && node.name === '$parameter') ||
|
|
66
|
+
childrenOf(node).some(readsClockOrParameter));
|
|
67
|
+
}
|
|
68
|
+
function childrenOf(node) {
|
|
69
|
+
switch (node.kind) {
|
|
70
|
+
case 'member':
|
|
71
|
+
return [node.object];
|
|
72
|
+
case 'chain':
|
|
73
|
+
return [node.expression];
|
|
74
|
+
case 'unary':
|
|
75
|
+
return [node.argument];
|
|
76
|
+
case 'binary':
|
|
77
|
+
case 'logical':
|
|
78
|
+
return [node.left, node.right];
|
|
79
|
+
case 'conditional':
|
|
80
|
+
return [node.test, node.consequent, node.alternate];
|
|
81
|
+
case 'call':
|
|
82
|
+
return [node.receiver, ...node.args];
|
|
83
|
+
case 'iterate':
|
|
84
|
+
return [node.receiver, node.body];
|
|
85
|
+
default:
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/skeleton.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ExpressionEvaluationOutcome } from '../../expression';
|
|
2
|
+
import type { IWorkflowDataProxyData } from '../../interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Whether verify mode can compare the expression: it fits the native subset
|
|
5
|
+
* and reads neither `$now`, `$today` nor `$parameter`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function canVerifyNatively(expression: string): boolean;
|
|
8
|
+
/** The shape of an expression with its user data masked. Null outside the native subset. */
|
|
9
|
+
export declare function nativeSkeleton(expression: string): string | null;
|
|
10
|
+
/** Holds no workflow data. */
|
|
11
|
+
export type NativeVerifyMismatch = {
|
|
12
|
+
engine: 'legacy' | 'vm' | 'quickjs';
|
|
13
|
+
skeleton: string;
|
|
14
|
+
nativeResultType: string;
|
|
15
|
+
engineResultType: string;
|
|
16
|
+
workflowId?: string;
|
|
17
|
+
};
|
|
18
|
+
/** Compares a sample of native results with the engine's and reports each new difference. */
|
|
19
|
+
export declare class NativeVerifier {
|
|
20
|
+
private readonly sample;
|
|
21
|
+
private readonly report;
|
|
22
|
+
private readonly canReport;
|
|
23
|
+
private readonly reportedShapes;
|
|
24
|
+
constructor(sample: number, report: (mismatch: NativeVerifyMismatch) => void, canReport?: () => boolean);
|
|
25
|
+
/** Draws whether this evaluation is part of the sample. False while reports cannot be sent. */
|
|
26
|
+
isSampled(): boolean;
|
|
27
|
+
/** Reports `native` when it differs from `engine`. Never throws. */
|
|
28
|
+
compare(expression: string, engineName: NativeVerifyMismatch['engine'], native: ExpressionEvaluationOutcome, engine: ExpressionEvaluationOutcome, data: IWorkflowDataProxyData): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/verify.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAa/D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAahE;AAED,8BAA8B;AAC9B,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,6FAA6F;AAC7F,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IAEpD,YACkB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,EAChD,SAAS,GAAE,MAAM,OAAoB,EACnD;IAEJ,+FAA+F;IAC/F,SAAS,IAAI,OAAO,CAEnB;IAED,oEAAoE;IACpE,OAAO,CACN,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAC1C,MAAM,EAAE,2BAA2B,EACnC,MAAM,EAAE,2BAA2B,EACnC,IAAI,EAAE,sBAAsB,GAC1B,IAAI,CA2BN;CACD"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.NativeVerifier = void 0;
|
|
40
|
+
exports.canVerifyNatively = canVerifyNatively;
|
|
41
|
+
exports.nativeSkeleton = nativeSkeleton;
|
|
42
|
+
const isEqualWith_1 = __importDefault(require("lodash/isEqualWith"));
|
|
43
|
+
const compiler_1 = require("./compiler");
|
|
44
|
+
const skeleton_1 = require("./skeleton");
|
|
45
|
+
const LoggerProxy = __importStar(require("../../logger-proxy"));
|
|
46
|
+
const utils_1 = require("../../utils");
|
|
47
|
+
// Each mismatch shape is reported once per process, up to this many, so a
|
|
48
|
+
// common mismatch cannot spend the Sentry quota.
|
|
49
|
+
const MAX_REPORTED_SHAPES = 1000;
|
|
50
|
+
// The comparison runs outside the engine timeout.
|
|
51
|
+
const MAX_COMPARED_PAIRS = 10_000;
|
|
52
|
+
class ComparisonTooLargeError extends Error {
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Whether verify mode can compare the expression: it fits the native subset
|
|
56
|
+
* and reads neither `$now`, `$today` nor `$parameter`.
|
|
57
|
+
*/
|
|
58
|
+
function canVerifyNatively(expression) {
|
|
59
|
+
const compiled = (0, compiler_1.getCompiled)(expression);
|
|
60
|
+
return (compiled !== null &&
|
|
61
|
+
!compiled.chunks.some((chunk) => chunk.type === 'code' && (0, skeleton_1.readsClockOrParameter)(chunk.node)));
|
|
62
|
+
}
|
|
63
|
+
/** The shape of an expression with its user data masked. Null outside the native subset. */
|
|
64
|
+
function nativeSkeleton(expression) {
|
|
65
|
+
const compiled = (0, compiler_1.getCompiled)(expression);
|
|
66
|
+
if (compiled === null)
|
|
67
|
+
return null;
|
|
68
|
+
return compiled.chunks
|
|
69
|
+
.map((chunk) => chunk.type === 'text'
|
|
70
|
+
? chunk.text === ''
|
|
71
|
+
? ''
|
|
72
|
+
: '<text>'
|
|
73
|
+
: `{{ ${(0, skeleton_1.skeletonOf)(chunk.node)} }}`)
|
|
74
|
+
.join('');
|
|
75
|
+
}
|
|
76
|
+
/** Compares a sample of native results with the engine's and reports each new difference. */
|
|
77
|
+
class NativeVerifier {
|
|
78
|
+
sample;
|
|
79
|
+
report;
|
|
80
|
+
canReport;
|
|
81
|
+
reportedShapes = new Set();
|
|
82
|
+
constructor(sample, report, canReport = () => true) {
|
|
83
|
+
this.sample = sample;
|
|
84
|
+
this.report = report;
|
|
85
|
+
this.canReport = canReport;
|
|
86
|
+
}
|
|
87
|
+
/** Draws whether this evaluation is part of the sample. False while reports cannot be sent. */
|
|
88
|
+
isSampled() {
|
|
89
|
+
return this.sample > 0 && this.canReport() && Math.random() < this.sample;
|
|
90
|
+
}
|
|
91
|
+
/** Reports `native` when it differs from `engine`. Never throws. */
|
|
92
|
+
compare(expression, engineName, native, engine, data) {
|
|
93
|
+
try {
|
|
94
|
+
if (compareResults(native, engine) === 'different' && !hitEngineLimit(engine)) {
|
|
95
|
+
const skeleton = nativeSkeleton(expression);
|
|
96
|
+
if (skeleton === null)
|
|
97
|
+
return;
|
|
98
|
+
const shape = {
|
|
99
|
+
skeleton,
|
|
100
|
+
engine: engineName,
|
|
101
|
+
nativeResultType: resultType(native),
|
|
102
|
+
engineResultType: resultType(engine),
|
|
103
|
+
};
|
|
104
|
+
const key = JSON.stringify(shape);
|
|
105
|
+
if (this.reportedShapes.has(key))
|
|
106
|
+
return;
|
|
107
|
+
if (this.reportedShapes.size >= MAX_REPORTED_SHAPES)
|
|
108
|
+
return;
|
|
109
|
+
this.reportedShapes.add(key);
|
|
110
|
+
if (this.reportedShapes.size === MAX_REPORTED_SHAPES) {
|
|
111
|
+
LoggerProxy.warn('Native evaluation verify mode reached its report limit and stops reporting new differences');
|
|
112
|
+
}
|
|
113
|
+
this.report({ ...shape, workflowId: workflowIdOf(data) });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Reporting must never change what the caller gets.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.NativeVerifier = NativeVerifier;
|
|
122
|
+
function compareResults(a, b) {
|
|
123
|
+
if (a.ok && b.ok)
|
|
124
|
+
return compareValues(a.value, b.value);
|
|
125
|
+
if (a.ok || b.ok)
|
|
126
|
+
return 'different';
|
|
127
|
+
const sameError = a.error instanceof Error &&
|
|
128
|
+
b.error instanceof Error &&
|
|
129
|
+
a.error.constructor === b.error.constructor &&
|
|
130
|
+
a.error.message === b.error.message;
|
|
131
|
+
return sameError ? 'same' : 'different';
|
|
132
|
+
}
|
|
133
|
+
// TODO(native-evaluation verify, CET-447): share the bounded comparison with the QuickJS shadow.
|
|
134
|
+
function compareValues(a, b, maxComparedPairs = MAX_COMPARED_PAIRS) {
|
|
135
|
+
let remaining = maxComparedPairs;
|
|
136
|
+
const compare = (x, y) => {
|
|
137
|
+
remaining--;
|
|
138
|
+
if (remaining < 0) {
|
|
139
|
+
throw new ComparisonTooLargeError();
|
|
140
|
+
}
|
|
141
|
+
// QuickJS drops object keys that hold undefined from its results.
|
|
142
|
+
if ((0, utils_1.isObject)(x) && (0, utils_1.isObject)(y)) {
|
|
143
|
+
return sameDefinedEntries(x, y, compare);
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
};
|
|
147
|
+
try {
|
|
148
|
+
return (0, isEqualWith_1.default)(a, b, compare) ? 'same' : 'different';
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
if (error instanceof ComparisonTooLargeError) {
|
|
152
|
+
return 'too_large';
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function sameDefinedEntries(a, b, compare) {
|
|
158
|
+
const definedKeys = (value) => Object.keys(value).filter((key) => value[key] !== undefined);
|
|
159
|
+
const aKeys = definedKeys(a);
|
|
160
|
+
return (aKeys.length === definedKeys(b).length &&
|
|
161
|
+
aKeys.every((key) => Object.hasOwn(b, key) && (0, isEqualWith_1.default)(a[key], b[key], compare)));
|
|
162
|
+
}
|
|
163
|
+
function hitEngineLimit(result) {
|
|
164
|
+
return !result.ok && (result.errorClass === 'timeout' || result.errorClass === 'memory_limit');
|
|
165
|
+
}
|
|
166
|
+
function resultType(result) {
|
|
167
|
+
if (!result.ok) {
|
|
168
|
+
return `error:${result.errorClass}`;
|
|
169
|
+
}
|
|
170
|
+
const { value } = result;
|
|
171
|
+
if (value === null)
|
|
172
|
+
return 'null';
|
|
173
|
+
if (Array.isArray(value))
|
|
174
|
+
return 'array';
|
|
175
|
+
if (typeof value === 'object')
|
|
176
|
+
return prototypeName(value);
|
|
177
|
+
return typeof value;
|
|
178
|
+
}
|
|
179
|
+
function prototypeName(value) {
|
|
180
|
+
const prototype = Object.getPrototypeOf(value);
|
|
181
|
+
const constructor = typeof prototype === 'object' && prototype !== null ? prototype.constructor : undefined;
|
|
182
|
+
return typeof constructor === 'function' ? constructor.name : 'object';
|
|
183
|
+
}
|
|
184
|
+
function workflowIdOf(data) {
|
|
185
|
+
try {
|
|
186
|
+
const id = data.$workflow?.id;
|
|
187
|
+
return typeof id === 'string' ? id : undefined;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../../src/expressions/native-evaluation/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-extensions.d.ts","sourceRoot":"","sources":["../../../src/extensions/array-extensions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"array-extensions.d.ts","sourceRoot":"","sources":["../../../src/extensions/array-extensions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AA+I5D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,UASvC;yBATe,OAAO;;;;;;;;;;;;;AAkOvB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAE5C;yBAFe,YAAY;;;;;;;;;;;;AAI5B,wBAAgB,KAAK,cAEpB;AAED,wBAAgB,OAAO,cAEtB;AAED,wBAAgB,SAAS,cAExB;AAED,wBAAgB,UAAU,cAEzB;AAgYD,eAAO,MAAM,eAAe,EAAE,YAgC7B,CAAC"}
|
|
@@ -113,27 +113,41 @@ function sum(value) {
|
|
|
113
113
|
}
|
|
114
114
|
function min(value) {
|
|
115
115
|
ensureNumberArray(value, { fnName: 'min' });
|
|
116
|
-
|
|
116
|
+
// Math.min(...value) passes every element as an argument and throws
|
|
117
|
+
// "Maximum call stack size exceeded" for arrays of ~125k numbers or more.
|
|
118
|
+
// A plain loop (not reduce) visits holes in sparse arrays as undefined.
|
|
119
|
+
let result = Infinity;
|
|
120
|
+
for (const v of value) {
|
|
117
121
|
if (typeof v === 'string') {
|
|
118
|
-
|
|
122
|
+
result = Math.min(result, parseFloat(v));
|
|
119
123
|
}
|
|
120
|
-
if (typeof v !== 'number') {
|
|
121
|
-
|
|
124
|
+
else if (typeof v !== 'number') {
|
|
125
|
+
result = NaN;
|
|
122
126
|
}
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
else {
|
|
128
|
+
result = Math.min(result, v);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
125
132
|
}
|
|
126
133
|
function max(value) {
|
|
127
134
|
ensureNumberArray(value, { fnName: 'max' });
|
|
128
|
-
|
|
135
|
+
// Math.max(...value) passes every element as an argument and throws
|
|
136
|
+
// "Maximum call stack size exceeded" for arrays of ~125k numbers or more.
|
|
137
|
+
// A plain loop (not reduce) visits holes in sparse arrays as undefined.
|
|
138
|
+
let result = -Infinity;
|
|
139
|
+
for (const v of value) {
|
|
129
140
|
if (typeof v === 'string') {
|
|
130
|
-
|
|
141
|
+
result = Math.max(result, parseFloat(v));
|
|
131
142
|
}
|
|
132
|
-
if (typeof v !== 'number') {
|
|
133
|
-
|
|
143
|
+
else if (typeof v !== 'number') {
|
|
144
|
+
result = NaN;
|
|
134
145
|
}
|
|
135
|
-
|
|
136
|
-
|
|
146
|
+
else {
|
|
147
|
+
result = Math.max(result, v);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
137
151
|
}
|
|
138
152
|
function average(value) {
|
|
139
153
|
ensureNumberArray(value, { fnName: 'average' });
|