n8n-workflow 2.31.2 → 2.32.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/augment-object.js +136 -146
- package/dist/cjs/augment-object.js.map +1 -1
- package/dist/cjs/build.tsbuildinfo +1 -1
- package/dist/cjs/common/find-ai-root-node-names.js +36 -46
- package/dist/cjs/common/find-ai-root-node-names.js.map +1 -1
- package/dist/cjs/common/get-child-nodes.js +8 -18
- package/dist/cjs/common/get-child-nodes.js.map +1 -1
- package/dist/cjs/common/get-connected-nodes.js +84 -94
- package/dist/cjs/common/get-connected-nodes.js.map +1 -1
- package/dist/cjs/common/get-node-by-name.js +16 -26
- package/dist/cjs/common/get-node-by-name.js.map +1 -1
- package/dist/cjs/common/get-parent-nodes.js +14 -24
- package/dist/cjs/common/get-parent-nodes.js.map +1 -1
- package/dist/cjs/common/index.js +9 -19
- package/dist/cjs/common/index.js.map +1 -1
- package/dist/cjs/common/map-connections-by-destination.js +31 -41
- package/dist/cjs/common/map-connections-by-destination.js.map +1 -1
- package/dist/cjs/common/resolve-variables.d.ts +8 -0
- package/dist/cjs/common/resolve-variables.d.ts.map +1 -1
- package/dist/cjs/common/resolve-variables.js +46 -33
- package/dist/cjs/common/resolve-variables.js.map +1 -1
- package/dist/cjs/connections-diff.js +58 -68
- package/dist/cjs/connections-diff.js.map +1 -1
- package/dist/cjs/constants.d.ts +3 -3
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +157 -166
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/credential-domain-restrictions.js +153 -163
- package/dist/cjs/credential-domain-restrictions.js.map +1 -1
- package/dist/cjs/cron.d.ts.map +1 -1
- package/dist/cjs/cron.js +25 -35
- package/dist/cjs/cron.js.map +1 -1
- package/dist/cjs/data-table.types.js +10 -20
- package/dist/cjs/data-table.types.js.map +1 -1
- package/dist/cjs/dynamic-credentials-helpers.js +93 -103
- package/dist/cjs/dynamic-credentials-helpers.js.map +1 -1
- package/dist/cjs/errors/abstract/execution-base.error.d.ts.map +1 -1
- package/dist/cjs/errors/abstract/execution-base.error.js +41 -51
- package/dist/cjs/errors/abstract/execution-base.error.js.map +1 -1
- package/dist/cjs/errors/abstract/node.error.d.ts.map +1 -1
- package/dist/cjs/errors/abstract/node.error.js +142 -152
- package/dist/cjs/errors/abstract/node.error.js.map +1 -1
- package/dist/cjs/errors/base/base.error.d.ts.map +1 -1
- package/dist/cjs/errors/base/base.error.js +35 -45
- package/dist/cjs/errors/base/base.error.js.map +1 -1
- package/dist/cjs/errors/base/operational.error.d.ts.map +1 -1
- package/dist/cjs/errors/base/operational.error.js +17 -27
- package/dist/cjs/errors/base/operational.error.js.map +1 -1
- package/dist/cjs/errors/base/unexpected.error.d.ts.map +1 -1
- package/dist/cjs/errors/base/unexpected.error.js +17 -27
- package/dist/cjs/errors/base/unexpected.error.js.map +1 -1
- package/dist/cjs/errors/base/user.error.d.ts.map +1 -1
- package/dist/cjs/errors/base/user.error.js +17 -27
- package/dist/cjs/errors/base/user.error.js.map +1 -1
- package/dist/cjs/errors/cli-subworkflow-operation.error.js +7 -17
- package/dist/cjs/errors/cli-subworkflow-operation.error.js.map +1 -1
- package/dist/cjs/errors/db-connection-timeout-error.d.ts.map +1 -1
- package/dist/cjs/errors/db-connection-timeout-error.js +11 -21
- package/dist/cjs/errors/db-connection-timeout-error.js.map +1 -1
- package/dist/cjs/errors/execution-cancelled.error.d.ts.map +1 -1
- package/dist/cjs/errors/execution-cancelled.error.js +33 -43
- package/dist/cjs/errors/execution-cancelled.error.js.map +1 -1
- package/dist/cjs/errors/expression-class-extension.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression-class-extension.error.js +9 -19
- package/dist/cjs/errors/expression-class-extension.error.js.map +1 -1
- package/dist/cjs/errors/expression-computed-destructuring.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression-computed-destructuring.error.js +9 -19
- package/dist/cjs/errors/expression-computed-destructuring.error.js.map +1 -1
- package/dist/cjs/errors/expression-destructuring.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression-destructuring.error.js +9 -19
- package/dist/cjs/errors/expression-destructuring.error.js.map +1 -1
- package/dist/cjs/errors/expression-extension.error.js +7 -17
- package/dist/cjs/errors/expression-extension.error.js.map +1 -1
- package/dist/cjs/errors/expression-reserved-variable.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression-reserved-variable.error.js +9 -19
- package/dist/cjs/errors/expression-reserved-variable.error.js.map +1 -1
- package/dist/cjs/errors/expression-with-statement.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression-with-statement.error.js +9 -19
- package/dist/cjs/errors/expression-with-statement.error.js.map +1 -1
- package/dist/cjs/errors/expression.error.d.ts.map +1 -1
- package/dist/cjs/errors/expression.error.js +33 -43
- package/dist/cjs/errors/expression.error.js.map +1 -1
- package/dist/cjs/errors/index.js +62 -72
- package/dist/cjs/errors/index.js.map +1 -1
- package/dist/cjs/errors/node-api.error.d.ts.map +1 -1
- package/dist/cjs/errors/node-api.error.js +227 -237
- package/dist/cjs/errors/node-api.error.js.map +1 -1
- package/dist/cjs/errors/node-operation.error.d.ts.map +1 -1
- package/dist/cjs/errors/node-operation.error.js +43 -53
- package/dist/cjs/errors/node-operation.error.js.map +1 -1
- package/dist/cjs/errors/node-ssl.error.d.ts.map +1 -1
- package/dist/cjs/errors/node-ssl.error.js +9 -19
- package/dist/cjs/errors/node-ssl.error.js.map +1 -1
- package/dist/cjs/errors/subworkflow-operation.error.d.ts.map +1 -1
- package/dist/cjs/errors/subworkflow-operation.error.js +18 -28
- package/dist/cjs/errors/subworkflow-operation.error.js.map +1 -1
- package/dist/cjs/errors/trigger-close.error.d.ts.map +1 -1
- package/dist/cjs/errors/trigger-close.error.js +11 -21
- package/dist/cjs/errors/trigger-close.error.js.map +1 -1
- package/dist/cjs/errors/webhook-taken.error.d.ts.map +1 -1
- package/dist/cjs/errors/webhook-taken.error.js +9 -19
- package/dist/cjs/errors/webhook-taken.error.js.map +1 -1
- package/dist/cjs/errors/workflow-activation.error.d.ts.map +1 -1
- package/dist/cjs/errors/workflow-activation.error.js +54 -64
- package/dist/cjs/errors/workflow-activation.error.js.map +1 -1
- package/dist/cjs/errors/workflow-configuration.error.js +10 -20
- package/dist/cjs/errors/workflow-configuration.error.js.map +1 -1
- package/dist/cjs/errors/workflow-deactivation.error.js +7 -17
- package/dist/cjs/errors/workflow-deactivation.error.js.map +1 -1
- package/dist/cjs/errors/workflow-operation.error.d.ts.map +1 -1
- package/dist/cjs/errors/workflow-operation.error.js +20 -30
- package/dist/cjs/errors/workflow-operation.error.js.map +1 -1
- package/dist/cjs/evaluation-helpers.js +16 -26
- package/dist/cjs/evaluation-helpers.js.map +1 -1
- package/dist/cjs/execution-context-establishment-hooks.d.ts.map +1 -1
- package/dist/cjs/execution-context-establishment-hooks.js +43 -53
- package/dist/cjs/execution-context-establishment-hooks.js.map +1 -1
- package/dist/cjs/execution-context.d.ts +14 -14
- package/dist/cjs/execution-context.d.ts.map +1 -1
- package/dist/cjs/execution-context.js +203 -213
- package/dist/cjs/execution-context.js.map +1 -1
- package/dist/cjs/execution-status.d.ts +2 -2
- package/dist/cjs/execution-status.d.ts.map +1 -1
- package/dist/cjs/execution-status.js +27 -37
- package/dist/cjs/execution-status.js.map +1 -1
- package/dist/cjs/expression-evaluator-proxy.d.ts.map +1 -1
- package/dist/cjs/expression-evaluator-proxy.js +18 -28
- package/dist/cjs/expression-evaluator-proxy.js.map +1 -1
- package/dist/cjs/expression-sandboxing.d.ts.map +1 -1
- package/dist/cjs/expression-sandboxing.js +447 -457
- package/dist/cjs/expression-sandboxing.js.map +1 -1
- package/dist/cjs/expression.d.ts.map +1 -1
- package/dist/cjs/expression.js +535 -546
- package/dist/cjs/expression.js.map +1 -1
- package/dist/cjs/expressions/expression-helpers.d.ts.map +1 -1
- package/dist/cjs/expressions/expression-helpers.js +13 -23
- package/dist/cjs/expressions/expression-helpers.js.map +1 -1
- package/dist/cjs/extensions/array-extensions.js +591 -601
- package/dist/cjs/extensions/array-extensions.js.map +1 -1
- package/dist/cjs/extensions/boolean-extensions.d.ts +1 -1
- package/dist/cjs/extensions/boolean-extensions.js +38 -48
- package/dist/cjs/extensions/boolean-extensions.js.map +1 -1
- package/dist/cjs/extensions/date-extensions.js +507 -517
- package/dist/cjs/extensions/date-extensions.js.map +1 -1
- package/dist/cjs/extensions/expression-extension.d.ts.map +1 -1
- package/dist/cjs/extensions/expression-extension.js +455 -465
- package/dist/cjs/extensions/expression-extension.js.map +1 -1
- package/dist/cjs/extensions/expression-parser.d.ts.map +1 -1
- package/dist/cjs/extensions/expression-parser.js +82 -92
- package/dist/cjs/extensions/expression-parser.js.map +1 -1
- package/dist/cjs/extensions/extended-functions.d.ts +10 -18
- package/dist/cjs/extensions/extended-functions.d.ts.map +1 -1
- package/dist/cjs/extensions/extended-functions.js +80 -90
- package/dist/cjs/extensions/extended-functions.js.map +1 -1
- package/dist/cjs/extensions/extensions.js +2 -12
- package/dist/cjs/extensions/index.js +10 -20
- package/dist/cjs/extensions/index.js.map +1 -1
- package/dist/cjs/extensions/number-extensions.js +226 -236
- package/dist/cjs/extensions/number-extensions.js.map +1 -1
- package/dist/cjs/extensions/object-extensions.js +274 -284
- package/dist/cjs/extensions/object-extensions.js.map +1 -1
- package/dist/cjs/extensions/string-extensions.d.ts +1 -1
- package/dist/cjs/extensions/string-extensions.d.ts.map +1 -1
- package/dist/cjs/extensions/string-extensions.js +769 -779
- package/dist/cjs/extensions/string-extensions.js.map +1 -1
- package/dist/cjs/extensions/utils.d.ts.map +1 -1
- package/dist/cjs/extensions/utils.js +35 -45
- package/dist/cjs/extensions/utils.js.map +1 -1
- package/dist/cjs/from-ai-parse-utils.js +393 -403
- package/dist/cjs/from-ai-parse-utils.js.map +1 -1
- package/dist/cjs/global-state.js +12 -22
- package/dist/cjs/global-state.js.map +1 -1
- package/dist/cjs/graph/graph-utils.js +166 -176
- package/dist/cjs/graph/graph-utils.js.map +1 -1
- package/dist/cjs/highlighted-data.js +13 -23
- package/dist/cjs/highlighted-data.js.map +1 -1
- package/dist/cjs/index.js +105 -115
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces.d.ts +112 -22
- package/dist/cjs/interfaces.d.ts.map +1 -1
- package/dist/cjs/interfaces.js +62 -72
- package/dist/cjs/interfaces.js.map +1 -1
- package/dist/cjs/jmespath-query.js +26 -36
- package/dist/cjs/jmespath-query.js.map +1 -1
- package/dist/cjs/logger-proxy.d.ts.map +1 -1
- package/dist/cjs/logger-proxy.js +15 -25
- package/dist/cjs/logger-proxy.js.map +1 -1
- package/dist/cjs/mcp-helpers.js +10 -20
- package/dist/cjs/mcp-helpers.js.map +1 -1
- package/dist/cjs/message-event-bus.d.ts +184 -165
- package/dist/cjs/message-event-bus.d.ts.map +1 -1
- package/dist/cjs/message-event-bus.js +207 -217
- package/dist/cjs/message-event-bus.js.map +1 -1
- package/dist/cjs/metadata-utils.js +35 -45
- package/dist/cjs/metadata-utils.js.map +1 -1
- package/dist/cjs/native-methods/array.methods.js +527 -537
- package/dist/cjs/native-methods/array.methods.js.map +1 -1
- package/dist/cjs/native-methods/boolean.methods.js +18 -28
- package/dist/cjs/native-methods/boolean.methods.js.map +1 -1
- package/dist/cjs/native-methods/index.js +16 -26
- package/dist/cjs/native-methods/index.js.map +1 -1
- package/dist/cjs/native-methods/number.methods.js +79 -89
- package/dist/cjs/native-methods/number.methods.js.map +1 -1
- package/dist/cjs/native-methods/object.methods.js +7 -17
- package/dist/cjs/native-methods/object.methods.js.map +1 -1
- package/dist/cjs/native-methods/string.methods.js +474 -484
- package/dist/cjs/native-methods/string.methods.js.map +1 -1
- package/dist/cjs/node-grouping-validation.d.ts +6 -0
- package/dist/cjs/node-grouping-validation.d.ts.map +1 -1
- package/dist/cjs/node-grouping-validation.js +165 -144
- package/dist/cjs/node-grouping-validation.js.map +1 -1
- package/dist/cjs/node-helpers.d.ts.map +1 -1
- package/dist/cjs/node-helpers.js +1486 -1493
- package/dist/cjs/node-helpers.js.map +1 -1
- package/dist/cjs/node-parameters/filter-parameter.d.ts.map +1 -1
- package/dist/cjs/node-parameters/filter-parameter.js +315 -325
- package/dist/cjs/node-parameters/filter-parameter.js.map +1 -1
- package/dist/cjs/node-parameters/node-parameter-value-type-guard.js +105 -115
- package/dist/cjs/node-parameters/node-parameter-value-type-guard.js.map +1 -1
- package/dist/cjs/node-parameters/parameter-type-validation.js +120 -130
- package/dist/cjs/node-parameters/parameter-type-validation.js.map +1 -1
- package/dist/cjs/node-parameters/path-utils.js +21 -31
- package/dist/cjs/node-parameters/path-utils.js.map +1 -1
- package/dist/cjs/node-parameters/rename-node-utils.js +22 -32
- package/dist/cjs/node-parameters/rename-node-utils.js.map +1 -1
- package/dist/cjs/node-reference-parser-utils.js +472 -482
- package/dist/cjs/node-reference-parser-utils.js.map +1 -1
- package/dist/cjs/node-validation.js +59 -69
- package/dist/cjs/node-validation.js.map +1 -1
- package/dist/cjs/observable-object.js +56 -66
- package/dist/cjs/observable-object.js.map +1 -1
- package/dist/cjs/redaction-channels.js +36 -46
- package/dist/cjs/redaction-channels.js.map +1 -1
- package/dist/cjs/run-execution-data/run-execution-data.js +15 -25
- package/dist/cjs/run-execution-data/run-execution-data.js.map +1 -1
- package/dist/cjs/run-execution-data/run-execution-data.v0.js +2 -12
- package/dist/cjs/run-execution-data/run-execution-data.v1.js +26 -36
- package/dist/cjs/run-execution-data/run-execution-data.v1.js.map +1 -1
- package/dist/cjs/run-execution-data-factory.js +113 -123
- package/dist/cjs/run-execution-data-factory.js.map +1 -1
- package/dist/cjs/schemas.d.ts +13 -13
- package/dist/cjs/schemas.d.ts.map +1 -1
- package/dist/cjs/schemas.js +351 -360
- package/dist/cjs/schemas.js.map +1 -1
- package/dist/cjs/sub-workflow-output.js +10 -20
- package/dist/cjs/sub-workflow-output.js.map +1 -1
- package/dist/cjs/telemetry-helpers.d.ts.map +1 -1
- package/dist/cjs/telemetry-helpers.js +716 -726
- package/dist/cjs/telemetry-helpers.js.map +1 -1
- package/dist/cjs/tool-helpers.js +18 -28
- package/dist/cjs/tool-helpers.js.map +1 -1
- package/dist/cjs/trigger-identity.js +41 -51
- package/dist/cjs/trigger-identity.js.map +1 -1
- package/dist/cjs/trimmed-task-data.js +21 -31
- package/dist/cjs/trimmed-task-data.js.map +1 -1
- package/dist/cjs/type-guards.d.ts +3 -3
- package/dist/cjs/type-guards.d.ts.map +1 -1
- package/dist/cjs/type-guards.js +74 -84
- package/dist/cjs/type-guards.js.map +1 -1
- package/dist/cjs/type-validation.d.ts.map +1 -1
- package/dist/cjs/type-validation.js +383 -393
- package/dist/cjs/type-validation.js.map +1 -1
- package/dist/cjs/utils.d.ts +2 -2
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +430 -440
- package/dist/cjs/utils.js.map +1 -1
- package/dist/cjs/versioned-node-type.d.ts.map +1 -1
- package/dist/cjs/versioned-node-type.js +20 -30
- package/dist/cjs/versioned-node-type.js.map +1 -1
- package/dist/cjs/workflow-checksum.js +67 -77
- package/dist/cjs/workflow-checksum.js.map +1 -1
- package/dist/cjs/workflow-data-proxy-env-provider.js +58 -68
- package/dist/cjs/workflow-data-proxy-env-provider.js.map +1 -1
- package/dist/cjs/workflow-data-proxy-helpers.js +8 -18
- package/dist/cjs/workflow-data-proxy-helpers.js.map +1 -1
- package/dist/cjs/workflow-data-proxy.d.ts.map +1 -1
- package/dist/cjs/workflow-data-proxy.js +1162 -1172
- package/dist/cjs/workflow-data-proxy.js.map +1 -1
- package/dist/cjs/workflow-diff.d.ts +2 -1
- package/dist/cjs/workflow-diff.d.ts.map +1 -1
- package/dist/cjs/workflow-diff.js +292 -300
- package/dist/cjs/workflow-diff.js.map +1 -1
- package/dist/cjs/workflow-environments-helper.js +23 -33
- package/dist/cjs/workflow-environments-helper.js.map +1 -1
- package/dist/cjs/workflow-expression.d.ts.map +1 -1
- package/dist/cjs/workflow-expression.js +97 -107
- package/dist/cjs/workflow-expression.js.map +1 -1
- package/dist/cjs/workflow-structure-validation.d.ts.map +1 -1
- package/dist/cjs/workflow-structure-validation.js +140 -150
- package/dist/cjs/workflow-structure-validation.js.map +1 -1
- package/dist/cjs/workflow-validation.js +40 -50
- package/dist/cjs/workflow-validation.js.map +1 -1
- package/dist/cjs/workflow.d.ts.map +1 -1
- package/dist/cjs/workflow.js +612 -622
- package/dist/cjs/workflow.js.map +1 -1
- package/dist/esm/common/get-child-nodes.js.map +1 -1
- package/dist/esm/common/get-connected-nodes.js.map +1 -1
- package/dist/esm/common/get-parent-nodes.js.map +1 -1
- package/dist/esm/common/resolve-variables.d.ts +8 -0
- package/dist/esm/common/resolve-variables.d.ts.map +1 -1
- package/dist/esm/common/resolve-variables.js +22 -0
- package/dist/esm/common/resolve-variables.js.map +1 -1
- package/dist/esm/constants.d.ts +3 -3
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/cron.d.ts.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.map +1 -1
- package/dist/esm/errors/abstract/node.error.d.ts.map +1 -1
- package/dist/esm/errors/abstract/node.error.js.map +1 -1
- package/dist/esm/errors/base/base.error.d.ts.map +1 -1
- package/dist/esm/errors/base/base.error.js.map +1 -1
- package/dist/esm/errors/base/operational.error.d.ts.map +1 -1
- package/dist/esm/errors/base/operational.error.js.map +1 -1
- package/dist/esm/errors/base/unexpected.error.d.ts.map +1 -1
- package/dist/esm/errors/base/unexpected.error.js.map +1 -1
- package/dist/esm/errors/base/user.error.d.ts.map +1 -1
- package/dist/esm/errors/base/user.error.js.map +1 -1
- package/dist/esm/errors/db-connection-timeout-error.d.ts.map +1 -1
- package/dist/esm/errors/execution-cancelled.error.d.ts.map +1 -1
- package/dist/esm/errors/expression-class-extension.error.d.ts.map +1 -1
- package/dist/esm/errors/expression-computed-destructuring.error.d.ts.map +1 -1
- package/dist/esm/errors/expression-destructuring.error.d.ts.map +1 -1
- package/dist/esm/errors/expression-reserved-variable.error.d.ts.map +1 -1
- package/dist/esm/errors/expression-with-statement.error.d.ts.map +1 -1
- package/dist/esm/errors/expression.error.d.ts.map +1 -1
- package/dist/esm/errors/node-api.error.d.ts.map +1 -1
- package/dist/esm/errors/node-api.error.js.map +1 -1
- package/dist/esm/errors/node-operation.error.d.ts.map +1 -1
- package/dist/esm/errors/node-operation.error.js.map +1 -1
- package/dist/esm/errors/node-ssl.error.d.ts.map +1 -1
- package/dist/esm/errors/subworkflow-operation.error.d.ts.map +1 -1
- package/dist/esm/errors/trigger-close.error.d.ts.map +1 -1
- package/dist/esm/errors/trigger-close.error.js.map +1 -1
- package/dist/esm/errors/webhook-taken.error.d.ts.map +1 -1
- package/dist/esm/errors/workflow-activation.error.d.ts.map +1 -1
- package/dist/esm/errors/workflow-activation.error.js.map +1 -1
- package/dist/esm/errors/workflow-operation.error.d.ts.map +1 -1
- package/dist/esm/execution-context-establishment-hooks.d.ts.map +1 -1
- package/dist/esm/execution-context.d.ts +14 -14
- package/dist/esm/execution-context.d.ts.map +1 -1
- package/dist/esm/execution-status.d.ts +2 -2
- package/dist/esm/execution-status.d.ts.map +1 -1
- package/dist/esm/expression-evaluator-proxy.d.ts.map +1 -1
- package/dist/esm/expression-sandboxing.d.ts.map +1 -1
- package/dist/esm/expression-sandboxing.js.map +1 -1
- package/dist/esm/expression.d.ts.map +1 -1
- package/dist/esm/expression.js.map +1 -1
- package/dist/esm/expressions/expression-helpers.d.ts.map +1 -1
- package/dist/esm/extensions/boolean-extensions.d.ts +1 -1
- package/dist/esm/extensions/expression-extension.d.ts.map +1 -1
- package/dist/esm/extensions/expression-parser.d.ts.map +1 -1
- package/dist/esm/extensions/extended-functions.d.ts +10 -18
- package/dist/esm/extensions/extended-functions.d.ts.map +1 -1
- package/dist/esm/extensions/number-extensions.js.map +1 -1
- package/dist/esm/extensions/string-extensions.d.ts +1 -1
- package/dist/esm/extensions/string-extensions.d.ts.map +1 -1
- package/dist/esm/extensions/string-extensions.js.map +1 -1
- package/dist/esm/extensions/utils.d.ts.map +1 -1
- package/dist/esm/from-ai-parse-utils.js.map +1 -1
- package/dist/esm/interfaces.d.ts +112 -22
- package/dist/esm/interfaces.d.ts.map +1 -1
- package/dist/esm/interfaces.js.map +1 -1
- package/dist/esm/logger-proxy.d.ts.map +1 -1
- package/dist/esm/message-event-bus.d.ts +184 -165
- package/dist/esm/message-event-bus.d.ts.map +1 -1
- package/dist/esm/message-event-bus.js +2 -2
- package/dist/esm/message-event-bus.js.map +1 -1
- package/dist/esm/node-grouping-validation.d.ts +6 -0
- package/dist/esm/node-grouping-validation.d.ts.map +1 -1
- package/dist/esm/node-grouping-validation.js +34 -5
- package/dist/esm/node-grouping-validation.js.map +1 -1
- package/dist/esm/node-helpers.d.ts.map +1 -1
- package/dist/esm/node-helpers.js +3 -0
- package/dist/esm/node-helpers.js.map +1 -1
- package/dist/esm/node-parameters/filter-parameter.d.ts.map +1 -1
- package/dist/esm/node-parameters/filter-parameter.js.map +1 -1
- package/dist/esm/node-reference-parser-utils.js.map +1 -1
- package/dist/esm/run-execution-data-factory.js.map +1 -1
- package/dist/esm/schemas.d.ts +13 -13
- package/dist/esm/schemas.d.ts.map +1 -1
- package/dist/esm/schemas.js +1 -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.map +1 -1
- package/dist/esm/type-guards.d.ts +3 -3
- package/dist/esm/type-guards.d.ts.map +1 -1
- package/dist/esm/type-validation.d.ts.map +1 -1
- package/dist/esm/type-validation.js.map +1 -1
- package/dist/esm/typecheck.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +2 -2
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/versioned-node-type.d.ts.map +1 -1
- package/dist/esm/workflow-data-proxy.d.ts.map +1 -1
- package/dist/esm/workflow-data-proxy.js.map +1 -1
- package/dist/esm/workflow-diff.d.ts +2 -1
- package/dist/esm/workflow-diff.d.ts.map +1 -1
- package/dist/esm/workflow-diff.js +3 -1
- package/dist/esm/workflow-diff.js.map +1 -1
- package/dist/esm/workflow-expression.d.ts.map +1 -1
- package/dist/esm/workflow-expression.js.map +1 -1
- package/dist/esm/workflow-structure-validation.d.ts.map +1 -1
- package/dist/esm/workflow-structure-validation.js.map +1 -1
- package/dist/esm/workflow.d.ts.map +1 -1
- package/dist/esm/workflow.js.map +1 -1
- package/package.json +10 -9
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
3
4
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
@@ -34,1306 +35,1295 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
35
|
return result;
|
|
35
36
|
};
|
|
36
37
|
})();
|
|
37
|
-
(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.WorkflowDataProxy = void 0;
|
|
40
|
+
const jmespath = __importStar(require("jmespath"));
|
|
41
|
+
const luxon_1 = require("luxon");
|
|
42
|
+
const augment_object_1 = require("./augment-object");
|
|
43
|
+
const constants_1 = require("./constants");
|
|
44
|
+
const errors_1 = require("./errors");
|
|
45
|
+
const expression_error_1 = require("./errors/expression.error");
|
|
46
|
+
const expression_helpers_1 = require("./expressions/expression-helpers");
|
|
47
|
+
const global_state_1 = require("./global-state");
|
|
48
|
+
const interfaces_1 = require("./interfaces");
|
|
49
|
+
const NodeHelpers = __importStar(require("./node-helpers"));
|
|
50
|
+
const result_1 = require("@n8n/utils/result");
|
|
51
|
+
const type_guards_1 = require("./type-guards");
|
|
52
|
+
const utils_1 = require("./utils");
|
|
53
|
+
const workflow_data_proxy_env_provider_1 = require("./workflow-data-proxy-env-provider");
|
|
54
|
+
const workflow_data_proxy_helpers_1 = require("./workflow-data-proxy-helpers");
|
|
55
|
+
const isScriptingNode = (nodeName, workflow) => {
|
|
56
|
+
const node = workflow.getNode(nodeName);
|
|
57
|
+
return node && constants_1.SCRIPTING_NODE_TYPES.includes(node.type);
|
|
58
|
+
};
|
|
59
|
+
const PAIRED_ITEM_METHOD = {
|
|
60
|
+
PAIRED_ITEM: 'pairedItem',
|
|
61
|
+
ITEM_MATCHING: 'itemMatching',
|
|
62
|
+
ITEM: 'item',
|
|
63
|
+
$GET_PAIRED_ITEM: '$getPairedItem',
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Whether the runtime can compile expressions. The expression engine compiles
|
|
67
|
+
* expressions via `new Function`, which throws when the process is started with
|
|
68
|
+
* `--disallow-code-generation-from-strings` — as the secure-mode task runner is.
|
|
69
|
+
* This is a process-wide invariant, so we probe once and cache the result.
|
|
70
|
+
*/
|
|
71
|
+
let codeGenerationAllowed;
|
|
72
|
+
const isCodeGenerationAllowed = () => {
|
|
73
|
+
if (codeGenerationAllowed === undefined) {
|
|
74
|
+
try {
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
|
|
76
|
+
new Function('return 1');
|
|
77
|
+
codeGenerationAllowed = true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
codeGenerationAllowed = false;
|
|
81
|
+
}
|
|
41
82
|
}
|
|
42
|
-
|
|
43
|
-
|
|
83
|
+
return codeGenerationAllowed;
|
|
84
|
+
};
|
|
85
|
+
class WorkflowDataProxy {
|
|
86
|
+
workflow;
|
|
87
|
+
runIndex;
|
|
88
|
+
itemIndex;
|
|
89
|
+
activeNodeName;
|
|
90
|
+
siblingParameters;
|
|
91
|
+
mode;
|
|
92
|
+
additionalKeys;
|
|
93
|
+
executeData;
|
|
94
|
+
defaultReturnRunIndex;
|
|
95
|
+
selfData;
|
|
96
|
+
contextNodeName;
|
|
97
|
+
envProviderState;
|
|
98
|
+
runExecutionData;
|
|
99
|
+
connectionInputData;
|
|
100
|
+
timezone;
|
|
101
|
+
// TODO: Clean that up at some point and move all the options into an options object
|
|
102
|
+
constructor(workflow, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, siblingParameters, mode, additionalKeys, executeData, defaultReturnRunIndex = -1, selfData = {}, contextNodeName = activeNodeName, envProviderState) {
|
|
103
|
+
this.workflow = workflow;
|
|
104
|
+
this.runIndex = runIndex;
|
|
105
|
+
this.itemIndex = itemIndex;
|
|
106
|
+
this.activeNodeName = activeNodeName;
|
|
107
|
+
this.siblingParameters = siblingParameters;
|
|
108
|
+
this.mode = mode;
|
|
109
|
+
this.additionalKeys = additionalKeys;
|
|
110
|
+
this.executeData = executeData;
|
|
111
|
+
this.defaultReturnRunIndex = defaultReturnRunIndex;
|
|
112
|
+
this.selfData = selfData;
|
|
113
|
+
this.contextNodeName = contextNodeName;
|
|
114
|
+
this.envProviderState = envProviderState;
|
|
115
|
+
this.runExecutionData = isScriptingNode(this.contextNodeName, workflow)
|
|
116
|
+
? runExecutionData !== null
|
|
117
|
+
? (0, augment_object_1.augmentObject)(runExecutionData)
|
|
118
|
+
: null
|
|
119
|
+
: runExecutionData;
|
|
120
|
+
this.connectionInputData = isScriptingNode(this.contextNodeName, workflow)
|
|
121
|
+
? (0, augment_object_1.augmentArray)(connectionInputData)
|
|
122
|
+
: connectionInputData;
|
|
123
|
+
this.timezone = workflow.settings?.timezone ?? (0, global_state_1.getGlobalState)().defaultTimezone;
|
|
124
|
+
luxon_1.Settings.defaultZone = this.timezone;
|
|
44
125
|
}
|
|
45
|
-
})(function (require, exports) {
|
|
46
|
-
"use strict";
|
|
47
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.WorkflowDataProxy = void 0;
|
|
49
|
-
const jmespath = __importStar(require("jmespath"));
|
|
50
|
-
const luxon_1 = require("luxon");
|
|
51
|
-
const augment_object_1 = require("./augment-object");
|
|
52
|
-
const constants_1 = require("./constants");
|
|
53
|
-
const errors_1 = require("./errors");
|
|
54
|
-
const expression_error_1 = require("./errors/expression.error");
|
|
55
|
-
const expression_helpers_1 = require("./expressions/expression-helpers");
|
|
56
|
-
const global_state_1 = require("./global-state");
|
|
57
|
-
const interfaces_1 = require("./interfaces");
|
|
58
|
-
const NodeHelpers = __importStar(require("./node-helpers"));
|
|
59
|
-
const result_1 = require("@n8n/utils/result");
|
|
60
|
-
const type_guards_1 = require("./type-guards");
|
|
61
|
-
const utils_1 = require("./utils");
|
|
62
|
-
const workflow_data_proxy_env_provider_1 = require("./workflow-data-proxy-env-provider");
|
|
63
|
-
const workflow_data_proxy_helpers_1 = require("./workflow-data-proxy-helpers");
|
|
64
|
-
const isScriptingNode = (nodeName, workflow) => {
|
|
65
|
-
const node = workflow.getNode(nodeName);
|
|
66
|
-
return node && constants_1.SCRIPTING_NODE_TYPES.includes(node.type);
|
|
67
|
-
};
|
|
68
|
-
const PAIRED_ITEM_METHOD = {
|
|
69
|
-
PAIRED_ITEM: 'pairedItem',
|
|
70
|
-
ITEM_MATCHING: 'itemMatching',
|
|
71
|
-
ITEM: 'item',
|
|
72
|
-
$GET_PAIRED_ITEM: '$getPairedItem',
|
|
73
|
-
};
|
|
74
126
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
127
|
+
* Returns execution data, conditionally extracting only 'json' from the item based on workflow 'binaryMode' setting.
|
|
128
|
+
* When binary mode is 'combined', this method returns only the 'json' from the item unless 'fullItem' is true.
|
|
129
|
+
*
|
|
130
|
+
* @private
|
|
131
|
+
* @param {INodeExecutionData | INodeExecutionData[]} data - The execution data to process
|
|
132
|
+
* @param {boolean} fullItem - If true, always returns the complete item data
|
|
133
|
+
* @returns The full execution data or only the json property, depending on workflow 'binaryMode' setting
|
|
79
134
|
*/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
codeGenerationAllowed = false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return codeGenerationAllowed;
|
|
93
|
-
};
|
|
94
|
-
class WorkflowDataProxy {
|
|
95
|
-
workflow;
|
|
96
|
-
runIndex;
|
|
97
|
-
itemIndex;
|
|
98
|
-
activeNodeName;
|
|
99
|
-
siblingParameters;
|
|
100
|
-
mode;
|
|
101
|
-
additionalKeys;
|
|
102
|
-
executeData;
|
|
103
|
-
defaultReturnRunIndex;
|
|
104
|
-
selfData;
|
|
105
|
-
contextNodeName;
|
|
106
|
-
envProviderState;
|
|
107
|
-
runExecutionData;
|
|
108
|
-
connectionInputData;
|
|
109
|
-
timezone;
|
|
110
|
-
// TODO: Clean that up at some point and move all the options into an options object
|
|
111
|
-
constructor(workflow, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, siblingParameters, mode, additionalKeys, executeData, defaultReturnRunIndex = -1, selfData = {}, contextNodeName = activeNodeName, envProviderState) {
|
|
112
|
-
this.workflow = workflow;
|
|
113
|
-
this.runIndex = runIndex;
|
|
114
|
-
this.itemIndex = itemIndex;
|
|
115
|
-
this.activeNodeName = activeNodeName;
|
|
116
|
-
this.siblingParameters = siblingParameters;
|
|
117
|
-
this.mode = mode;
|
|
118
|
-
this.additionalKeys = additionalKeys;
|
|
119
|
-
this.executeData = executeData;
|
|
120
|
-
this.defaultReturnRunIndex = defaultReturnRunIndex;
|
|
121
|
-
this.selfData = selfData;
|
|
122
|
-
this.contextNodeName = contextNodeName;
|
|
123
|
-
this.envProviderState = envProviderState;
|
|
124
|
-
this.runExecutionData = isScriptingNode(this.contextNodeName, workflow)
|
|
125
|
-
? runExecutionData !== null
|
|
126
|
-
? (0, augment_object_1.augmentObject)(runExecutionData)
|
|
127
|
-
: null
|
|
128
|
-
: runExecutionData;
|
|
129
|
-
this.connectionInputData = isScriptingNode(this.contextNodeName, workflow)
|
|
130
|
-
? (0, augment_object_1.augmentArray)(connectionInputData)
|
|
131
|
-
: connectionInputData;
|
|
132
|
-
this.timezone = workflow.settings?.timezone ?? (0, global_state_1.getGlobalState)().defaultTimezone;
|
|
133
|
-
luxon_1.Settings.defaultZone = this.timezone;
|
|
135
|
+
returnExecutionData(data, fullItem = false) {
|
|
136
|
+
if (fullItem)
|
|
137
|
+
return data;
|
|
138
|
+
if (this.workflow.settings?.binaryMode !== constants_1.BINARY_MODE_COMBINED)
|
|
139
|
+
return data;
|
|
140
|
+
if (Array.isArray(data)) {
|
|
141
|
+
return data.map((i) => i.json);
|
|
134
142
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return data;
|
|
149
|
-
if (Array.isArray(data)) {
|
|
150
|
-
return data.map((i) => i.json);
|
|
151
|
-
}
|
|
152
|
-
return data.json;
|
|
143
|
+
return data.json;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns a proxy which allows to query context data of a given node
|
|
147
|
+
*
|
|
148
|
+
* @private
|
|
149
|
+
* @param {string} nodeName The name of the node to get the context from
|
|
150
|
+
*/
|
|
151
|
+
nodeContextGetter(nodeName) {
|
|
152
|
+
const that = this;
|
|
153
|
+
const node = this.workflow.nodes[nodeName];
|
|
154
|
+
if (!that.runExecutionData?.executionData && that.connectionInputData.length > 0) {
|
|
155
|
+
return {}; // incoming connection has pinned data, so stub context object
|
|
153
156
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
*/
|
|
160
|
-
nodeContextGetter(nodeName) {
|
|
161
|
-
const that = this;
|
|
162
|
-
const node = this.workflow.nodes[nodeName];
|
|
163
|
-
if (!that.runExecutionData?.executionData && that.connectionInputData.length > 0) {
|
|
164
|
-
return {}; // incoming connection has pinned data, so stub context object
|
|
165
|
-
}
|
|
166
|
-
if (!that.runExecutionData?.executionData && !that.runExecutionData?.resultData) {
|
|
167
|
-
throw new expression_error_1.ExpressionError("The workflow hasn't been executed yet, so you can't reference any context data", {
|
|
168
|
-
runIndex: that.runIndex,
|
|
169
|
-
itemIndex: that.itemIndex,
|
|
170
|
-
type: 'no_execution_data',
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
return new Proxy({}, {
|
|
174
|
-
has: () => true,
|
|
175
|
-
ownKeys(target) {
|
|
176
|
-
if (Reflect.ownKeys(target).length === 0) {
|
|
177
|
-
// Target object did not get set yet
|
|
178
|
-
Object.assign(target, NodeHelpers.getContext(that.runExecutionData, 'node', node));
|
|
179
|
-
}
|
|
180
|
-
return Reflect.ownKeys(target);
|
|
181
|
-
},
|
|
182
|
-
getOwnPropertyDescriptor() {
|
|
183
|
-
return {
|
|
184
|
-
enumerable: true,
|
|
185
|
-
configurable: true,
|
|
186
|
-
};
|
|
187
|
-
},
|
|
188
|
-
get(_, name) {
|
|
189
|
-
if (name === 'isProxy')
|
|
190
|
-
return true;
|
|
191
|
-
name = name.toString();
|
|
192
|
-
const contextData = NodeHelpers.getContext(that.runExecutionData, 'node', node);
|
|
193
|
-
return contextData[name];
|
|
194
|
-
},
|
|
157
|
+
if (!that.runExecutionData?.executionData && !that.runExecutionData?.resultData) {
|
|
158
|
+
throw new expression_error_1.ExpressionError("The workflow hasn't been executed yet, so you can't reference any context data", {
|
|
159
|
+
runIndex: that.runIndex,
|
|
160
|
+
itemIndex: that.itemIndex,
|
|
161
|
+
type: 'no_execution_data',
|
|
195
162
|
});
|
|
196
163
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
name = name.toString();
|
|
208
|
-
const value = that.selfData[name];
|
|
209
|
-
// A credential field saved in expression mode keeps n8n's leading "="
|
|
210
|
-
// marker in its stored value. Returning it verbatim leaks the marker
|
|
211
|
-
// (or an unevaluated `{{ }}` expression) into the consuming template —
|
|
212
|
-
// e.g. a `$self` reference embedded mid-URL in an OAuth2
|
|
213
|
-
// authUrl/accessTokenUrl. Resolve it here so callers receive the
|
|
214
|
-
// evaluated value.
|
|
215
|
-
if ((0, expression_helpers_1.isExpression)(value)) {
|
|
216
|
-
return that.workflow.expression.getParameterValue(value, that.runExecutionData, that.runIndex, that.itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
217
|
-
}
|
|
218
|
-
return value;
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
buildAgentToolInfo(node) {
|
|
223
|
-
const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
|
224
|
-
if (!nodeType) {
|
|
164
|
+
return new Proxy({}, {
|
|
165
|
+
has: () => true,
|
|
166
|
+
ownKeys(target) {
|
|
167
|
+
if (Reflect.ownKeys(target).length === 0) {
|
|
168
|
+
// Target object did not get set yet
|
|
169
|
+
Object.assign(target, NodeHelpers.getContext(that.runExecutionData, 'node', node));
|
|
170
|
+
}
|
|
171
|
+
return Reflect.ownKeys(target);
|
|
172
|
+
},
|
|
173
|
+
getOwnPropertyDescriptor() {
|
|
225
174
|
return {
|
|
226
|
-
|
|
227
|
-
|
|
175
|
+
enumerable: true,
|
|
176
|
+
configurable: true,
|
|
228
177
|
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
178
|
+
},
|
|
179
|
+
get(_, name) {
|
|
180
|
+
if (name === 'isProxy')
|
|
181
|
+
return true;
|
|
182
|
+
name = name.toString();
|
|
183
|
+
const contextData = NodeHelpers.getContext(that.runExecutionData, 'node', node);
|
|
184
|
+
return contextData[name];
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
selfGetter() {
|
|
189
|
+
const that = this;
|
|
190
|
+
return new Proxy({}, {
|
|
191
|
+
has: () => true,
|
|
192
|
+
ownKeys(target) {
|
|
193
|
+
return Reflect.ownKeys(target);
|
|
194
|
+
},
|
|
195
|
+
get(_, name) {
|
|
196
|
+
if (name === 'isProxy')
|
|
197
|
+
return true;
|
|
198
|
+
name = name.toString();
|
|
199
|
+
const value = that.selfData[name];
|
|
200
|
+
// A credential field saved in expression mode keeps n8n's leading "="
|
|
201
|
+
// marker in its stored value. Returning it verbatim leaks the marker
|
|
202
|
+
// (or an unevaluated `{{ }}` expression) into the consuming template —
|
|
203
|
+
// e.g. a `$self` reference embedded mid-URL in an OAuth2
|
|
204
|
+
// authUrl/accessTokenUrl. Resolve it here so callers receive the
|
|
205
|
+
// evaluated value.
|
|
206
|
+
if ((0, expression_helpers_1.isExpression)(value)) {
|
|
207
|
+
return that.workflow.expression.getParameterValue(value, that.runExecutionData, that.runIndex, that.itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
208
|
+
}
|
|
209
|
+
return value;
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
buildAgentToolInfo(node) {
|
|
214
|
+
const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
|
215
|
+
if (!nodeType) {
|
|
250
216
|
return {
|
|
251
217
|
name: node.name,
|
|
252
|
-
type,
|
|
253
|
-
resource,
|
|
254
|
-
operation,
|
|
255
|
-
hasCredentials,
|
|
256
|
-
hasValidCalendar,
|
|
257
|
-
aiDefinedFields,
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
agentInfo() {
|
|
261
|
-
const agentNode = this.workflow.getNode(this.activeNodeName);
|
|
262
|
-
if (!agentNode || agentNode.type !== constants_1.AGENT_LANGCHAIN_NODE_TYPE)
|
|
263
|
-
return undefined;
|
|
264
|
-
const connectedTools = this.workflow
|
|
265
|
-
.getParentNodes(this.activeNodeName, interfaces_1.NodeConnectionTypes.AiTool)
|
|
266
|
-
.map((nodeName) => this.workflow.getNode(nodeName))
|
|
267
|
-
.filter((node) => node);
|
|
268
|
-
const memoryConnectedToAgent = this.workflow.getParentNodes(this.activeNodeName, interfaces_1.NodeConnectionTypes.AiMemory).length > 0;
|
|
269
|
-
const allTools = this.workflow.queryNodes((nodeType) => {
|
|
270
|
-
return nodeType.description.name.toLowerCase().includes('tool');
|
|
271
|
-
});
|
|
272
|
-
const unconnectedTools = allTools
|
|
273
|
-
.filter((node) => this.workflow.getChildNodes(node.name, interfaces_1.NodeConnectionTypes.AiTool, 1).length === 0)
|
|
274
|
-
.filter((node) => !connectedTools.includes(node));
|
|
275
|
-
return {
|
|
276
|
-
memoryConnectedToAgent,
|
|
277
|
-
tools: [
|
|
278
|
-
...connectedTools.map((node) => ({ connected: true, ...this.buildAgentToolInfo(node) })),
|
|
279
|
-
...unconnectedTools.map((node) => ({ connected: false, ...this.buildAgentToolInfo(node) })),
|
|
280
|
-
],
|
|
218
|
+
type: node.type,
|
|
281
219
|
};
|
|
282
220
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
221
|
+
const type = nodeType.description.displayName;
|
|
222
|
+
const params = NodeHelpers.getNodeParameters(nodeType.description.properties, node.parameters, true, false, node, nodeType.description);
|
|
223
|
+
const resourceKey = params?.resource;
|
|
224
|
+
const operationKey = params?.operation;
|
|
225
|
+
const resource = nodeType.description.properties
|
|
226
|
+
.find((nodeProperties) => nodeProperties.name === 'resource')
|
|
227
|
+
?.options?.find((option) => 'value' in option && option.value === resourceKey)?.name ??
|
|
228
|
+
null;
|
|
229
|
+
const operation = nodeType.description.properties
|
|
230
|
+
.find((nodeProperty) => nodeProperty.name === 'operation' &&
|
|
231
|
+
nodeProperty.displayOptions?.show?.resource?.some((y) => y === resourceKey))
|
|
232
|
+
?.options?.find((y) => 'value' in y && y.value === operationKey)?.name ?? null;
|
|
233
|
+
const hasCredentials = !(0, utils_1.isObjectEmpty)(node.credentials ?? {});
|
|
234
|
+
const hasValidCalendar = nodeType.description.name.includes('googleCalendar')
|
|
235
|
+
? (0, type_guards_1.isResourceLocatorValue)(node.parameters.calendar) && node.parameters.calendar.value !== ''
|
|
236
|
+
: undefined;
|
|
237
|
+
const aiDefinedFields = Object.entries(node.parameters)
|
|
238
|
+
.map(([key, value]) => [key, (0, type_guards_1.isResourceLocatorValue)(value) ? value.value : value])
|
|
239
|
+
.filter(([_, value]) => value?.toString().toLowerCase().includes('$fromai'))
|
|
240
|
+
.map(([key]) => nodeType.description.properties.find((property) => property.name === key)?.displayName);
|
|
241
|
+
return {
|
|
242
|
+
name: node.name,
|
|
243
|
+
type,
|
|
244
|
+
resource,
|
|
245
|
+
operation,
|
|
246
|
+
hasCredentials,
|
|
247
|
+
hasValidCalendar,
|
|
248
|
+
aiDefinedFields,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
agentInfo() {
|
|
252
|
+
const agentNode = this.workflow.getNode(this.activeNodeName);
|
|
253
|
+
if (!agentNode || agentNode.type !== constants_1.AGENT_LANGCHAIN_NODE_TYPE)
|
|
254
|
+
return undefined;
|
|
255
|
+
const connectedTools = this.workflow
|
|
256
|
+
.getParentNodes(this.activeNodeName, interfaces_1.NodeConnectionTypes.AiTool)
|
|
257
|
+
.map((nodeName) => this.workflow.getNode(nodeName))
|
|
258
|
+
.filter((node) => node);
|
|
259
|
+
const memoryConnectedToAgent = this.workflow.getParentNodes(this.activeNodeName, interfaces_1.NodeConnectionTypes.AiMemory).length > 0;
|
|
260
|
+
const allTools = this.workflow.queryNodes((nodeType) => {
|
|
261
|
+
return nodeType.description.name.toLowerCase().includes('tool');
|
|
262
|
+
});
|
|
263
|
+
const unconnectedTools = allTools
|
|
264
|
+
.filter((node) => this.workflow.getChildNodes(node.name, interfaces_1.NodeConnectionTypes.AiTool, 1).length === 0)
|
|
265
|
+
.filter((node) => !connectedTools.includes(node));
|
|
266
|
+
return {
|
|
267
|
+
memoryConnectedToAgent,
|
|
268
|
+
tools: [
|
|
269
|
+
...connectedTools.map((node) => ({ connected: true, ...this.buildAgentToolInfo(node) })),
|
|
270
|
+
...unconnectedTools.map((node) => ({ connected: false, ...this.buildAgentToolInfo(node) })),
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Returns a proxy which allows to query parameter data of a given node
|
|
276
|
+
*
|
|
277
|
+
* @private
|
|
278
|
+
* @param {string} nodeName The name of the node to query data from
|
|
279
|
+
* @param {boolean} [resolveValue=true] If the expression value should get resolved
|
|
280
|
+
*/
|
|
281
|
+
nodeParameterGetter(nodeName, resolveValue = true) {
|
|
282
|
+
const that = this;
|
|
283
|
+
const node = this.workflow.nodes[nodeName];
|
|
284
|
+
// `node` is `undefined` only in expressions in credentials
|
|
285
|
+
return new Proxy(node?.parameters ?? {}, {
|
|
286
|
+
has: () => true,
|
|
287
|
+
ownKeys(target) {
|
|
288
|
+
return Reflect.ownKeys(target);
|
|
289
|
+
},
|
|
290
|
+
getOwnPropertyDescriptor() {
|
|
291
|
+
return {
|
|
292
|
+
enumerable: true,
|
|
293
|
+
configurable: true,
|
|
294
|
+
};
|
|
295
|
+
},
|
|
296
|
+
get(target, name) {
|
|
297
|
+
if (name === 'isProxy')
|
|
298
|
+
return true;
|
|
299
|
+
if (name === 'toJSON')
|
|
300
|
+
return () => (0, utils_1.deepCopy)(target);
|
|
301
|
+
name = name.toString();
|
|
302
|
+
let returnValue;
|
|
303
|
+
if (name[0] === '&') {
|
|
304
|
+
const key = name.slice(1);
|
|
305
|
+
if (!that.siblingParameters.hasOwnProperty(key)) {
|
|
306
|
+
throw new errors_1.UnexpectedError('Could not find sibling parameter on node', {
|
|
307
|
+
extra: { nodeName, parameter: key },
|
|
308
|
+
});
|
|
327
309
|
}
|
|
328
|
-
|
|
329
|
-
|
|
310
|
+
returnValue = that.siblingParameters[key];
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
if (!node.parameters.hasOwnProperty(name)) {
|
|
314
|
+
// Parameter does not exist on node
|
|
330
315
|
return undefined;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
316
|
+
}
|
|
317
|
+
returnValue = node.parameters[name];
|
|
318
|
+
}
|
|
319
|
+
// Avoid recursion
|
|
320
|
+
if (returnValue === `={{ $parameter.${name} }}`)
|
|
321
|
+
return undefined;
|
|
322
|
+
if ((0, type_guards_1.isResourceLocatorValue)(returnValue)) {
|
|
323
|
+
if (returnValue.__regex && typeof returnValue.value === 'string') {
|
|
324
|
+
const expr = new RegExp(returnValue.__regex);
|
|
325
|
+
const extracted = expr.exec(returnValue.value);
|
|
326
|
+
if (extracted && extracted.length >= 2) {
|
|
327
|
+
returnValue = extracted[1];
|
|
341
328
|
}
|
|
342
329
|
else {
|
|
343
|
-
|
|
330
|
+
return returnValue.value;
|
|
344
331
|
}
|
|
345
332
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
return that.workflow.expression.getParameterValue(returnValue, that.runExecutionData, that.runIndex, that.itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
333
|
+
else {
|
|
334
|
+
returnValue = returnValue.value;
|
|
349
335
|
}
|
|
350
|
-
return returnValue;
|
|
351
|
-
},
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
getNodeExecutionOrPinnedData({ nodeName, branchIndex, runIndex, shortSyntax = false, }) {
|
|
355
|
-
try {
|
|
356
|
-
return this.getNodeExecutionData(nodeName, shortSyntax, branchIndex, runIndex);
|
|
357
|
-
}
|
|
358
|
-
catch (e) {
|
|
359
|
-
const pinData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(this.workflow, nodeName, this.mode);
|
|
360
|
-
if (pinData) {
|
|
361
|
-
return pinData;
|
|
362
336
|
}
|
|
363
|
-
|
|
337
|
+
if (resolveValue && typeof returnValue === 'string' && returnValue.charAt(0) === '=') {
|
|
338
|
+
// The found value is an expression so resolve it
|
|
339
|
+
return that.workflow.expression.getParameterValue(returnValue, that.runExecutionData, that.runIndex, that.itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
340
|
+
}
|
|
341
|
+
return returnValue;
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
getNodeExecutionOrPinnedData({ nodeName, branchIndex, runIndex, shortSyntax = false, }) {
|
|
346
|
+
try {
|
|
347
|
+
return this.getNodeExecutionData(nodeName, shortSyntax, branchIndex, runIndex);
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
const pinData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(this.workflow, nodeName, this.mode);
|
|
351
|
+
if (pinData) {
|
|
352
|
+
return pinData;
|
|
364
353
|
}
|
|
354
|
+
throw e;
|
|
365
355
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Returns the node ExecutionData
|
|
359
|
+
*
|
|
360
|
+
* @private
|
|
361
|
+
* @param {string} nodeName The name of the node query data from
|
|
362
|
+
* @param {boolean} [shortSyntax=false] If short syntax got used
|
|
363
|
+
* @param {number} [outputIndex] The index of the output, if not given the first one gets used
|
|
364
|
+
* @param {number} [runIndex] The index of the run, if not given the current one does get used
|
|
365
|
+
*/
|
|
366
|
+
getNodeExecutionData(nodeName, shortSyntax = false, outputIndex, runIndex) {
|
|
367
|
+
const that = this;
|
|
368
|
+
let executionData;
|
|
369
|
+
if (!shortSyntax) {
|
|
370
|
+
// Long syntax got used to return data from node in path
|
|
371
|
+
if (that.runExecutionData === null) {
|
|
372
|
+
throw new expression_error_1.ExpressionError("The workflow hasn't been executed yet, so you can't reference any output data", {
|
|
373
|
+
runIndex: that.runIndex,
|
|
374
|
+
itemIndex: that.itemIndex,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
if (!that.workflow.getNode(nodeName)) {
|
|
378
|
+
throw new expression_error_1.ExpressionError("Referenced node doesn't exist", {
|
|
379
|
+
runIndex: that.runIndex,
|
|
380
|
+
itemIndex: that.itemIndex,
|
|
381
|
+
nodeCause: nodeName,
|
|
382
|
+
descriptionKey: 'nodeNotFound',
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (!that.runExecutionData.resultData.runData.hasOwnProperty(nodeName) &&
|
|
386
|
+
!(0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode)) {
|
|
387
|
+
throw new expression_error_1.ExpressionError(`Node '${nodeName}' hasn't been executed`, {
|
|
388
|
+
messageTemplate: 'An expression references this node, but the node is unexecuted. Consider re-wiring your nodes or checking for execution first, i.e. {{ $if( $("{{nodeName}}").isExecuted, <action_if_executed>, "") }}',
|
|
389
|
+
functionality: 'pairedItem',
|
|
390
|
+
descriptionKey: isScriptingNode(nodeName, that.workflow)
|
|
391
|
+
? 'pairedItemNoConnectionCodeNode'
|
|
392
|
+
: 'pairedItemNoConnection',
|
|
393
|
+
type: 'no_execution_data',
|
|
394
|
+
nodeCause: nodeName,
|
|
395
|
+
runIndex: that.runIndex,
|
|
396
|
+
itemIndex: that.itemIndex,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
runIndex = runIndex === undefined ? that.defaultReturnRunIndex : runIndex;
|
|
400
|
+
runIndex =
|
|
401
|
+
runIndex === -1 ? that.runExecutionData.resultData.runData[nodeName].length - 1 : runIndex;
|
|
402
|
+
if (that.runExecutionData.resultData.runData[nodeName].length <= runIndex) {
|
|
403
|
+
throw new expression_error_1.ExpressionError(`Run ${runIndex} of node "${nodeName}" not found`, {
|
|
404
|
+
runIndex: that.runIndex,
|
|
405
|
+
itemIndex: that.itemIndex,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
const taskData = that.runExecutionData.resultData.runData[nodeName][runIndex].data;
|
|
409
|
+
if (!taskData.main?.length || taskData.main[0] === null) {
|
|
410
|
+
// throw new ApplicationError('No data found for item-index', { extra: { itemIndex } });
|
|
411
|
+
throw new expression_error_1.ExpressionError('No data found from `main` input', {
|
|
412
|
+
runIndex: that.runIndex,
|
|
413
|
+
itemIndex: that.itemIndex,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
// Check from which output to read the data.
|
|
417
|
+
// Depends on how the nodes are connected.
|
|
418
|
+
// (example "IF" node. If node is connected to "true" or to "false" output)
|
|
419
|
+
if (outputIndex === undefined) {
|
|
420
|
+
const nodeConnection = that.workflow.getNodeConnectionIndexes(that.contextNodeName, nodeName, interfaces_1.NodeConnectionTypes.Main);
|
|
421
|
+
if (nodeConnection === undefined) {
|
|
422
|
+
throw new expression_error_1.ExpressionError(`connect "${that.contextNodeName}" to "${nodeName}"`, {
|
|
388
423
|
runIndex: that.runIndex,
|
|
389
424
|
itemIndex: that.itemIndex,
|
|
390
|
-
nodeCause: nodeName,
|
|
391
|
-
descriptionKey: 'nodeNotFound',
|
|
392
425
|
});
|
|
393
426
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
427
|
+
outputIndex = nodeConnection.sourceIndex;
|
|
428
|
+
}
|
|
429
|
+
if (outputIndex === undefined) {
|
|
430
|
+
outputIndex = 0;
|
|
431
|
+
}
|
|
432
|
+
if (taskData.main.length <= outputIndex) {
|
|
433
|
+
throw new expression_error_1.ExpressionError(`Node "${nodeName}" has no branch with index ${outputIndex}.`, {
|
|
434
|
+
runIndex: that.runIndex,
|
|
435
|
+
itemIndex: that.itemIndex,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
executionData = taskData.main[outputIndex];
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
// Short syntax got used to return data from active node
|
|
442
|
+
executionData = that.connectionInputData;
|
|
443
|
+
}
|
|
444
|
+
return executionData;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Returns a proxy which allows to query data of a given node
|
|
448
|
+
*
|
|
449
|
+
* @private
|
|
450
|
+
* @param {string} nodeName The name of the node query data from
|
|
451
|
+
* @param {boolean} [shortSyntax=false] If short syntax got used
|
|
452
|
+
* @param {boolean} [throwOnMissingExecutionData=true] If an error should get thrown if no execution data is available
|
|
453
|
+
*/
|
|
454
|
+
nodeDataGetter(nodeName, shortSyntax = false, throwOnMissingExecutionData = true) {
|
|
455
|
+
const that = this;
|
|
456
|
+
const node = this.workflow.nodes[nodeName];
|
|
457
|
+
return new Proxy({ binary: undefined, data: undefined, json: undefined }, {
|
|
458
|
+
has: () => true,
|
|
459
|
+
get(target, name, receiver) {
|
|
460
|
+
if (name === 'isProxy')
|
|
461
|
+
return true;
|
|
462
|
+
name = name.toString();
|
|
463
|
+
if (!node) {
|
|
464
|
+
throw new expression_error_1.ExpressionError('Referenced node does not exist', {
|
|
465
|
+
messageTemplate: 'Make sure to double-check the node name for typos',
|
|
398
466
|
functionality: 'pairedItem',
|
|
399
467
|
descriptionKey: isScriptingNode(nodeName, that.workflow)
|
|
400
468
|
? 'pairedItemNoConnectionCodeNode'
|
|
401
469
|
: 'pairedItemNoConnection',
|
|
402
|
-
type: '
|
|
470
|
+
type: 'paired_item_no_connection',
|
|
403
471
|
nodeCause: nodeName,
|
|
404
472
|
runIndex: that.runIndex,
|
|
405
473
|
itemIndex: that.itemIndex,
|
|
406
474
|
});
|
|
407
475
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
throw new expression_error_1.ExpressionError(`Run ${runIndex} of node "${nodeName}" not found`, {
|
|
413
|
-
runIndex: that.runIndex,
|
|
414
|
-
itemIndex: that.itemIndex,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
const taskData = that.runExecutionData.resultData.runData[nodeName][runIndex].data;
|
|
418
|
-
if (!taskData.main?.length || taskData.main[0] === null) {
|
|
419
|
-
// throw new ApplicationError('No data found for item-index', { extra: { itemIndex } });
|
|
420
|
-
throw new expression_error_1.ExpressionError('No data found from `main` input', {
|
|
421
|
-
runIndex: that.runIndex,
|
|
422
|
-
itemIndex: that.itemIndex,
|
|
476
|
+
if (['binary', 'data', 'json'].includes(name)) {
|
|
477
|
+
const executionData = that.getNodeExecutionOrPinnedData({
|
|
478
|
+
nodeName,
|
|
479
|
+
shortSyntax,
|
|
423
480
|
});
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
// Depends on how the nodes are connected.
|
|
427
|
-
// (example "IF" node. If node is connected to "true" or to "false" output)
|
|
428
|
-
if (outputIndex === undefined) {
|
|
429
|
-
const nodeConnection = that.workflow.getNodeConnectionIndexes(that.contextNodeName, nodeName, interfaces_1.NodeConnectionTypes.Main);
|
|
430
|
-
if (nodeConnection === undefined) {
|
|
431
|
-
throw new expression_error_1.ExpressionError(`connect "${that.contextNodeName}" to "${nodeName}"`, {
|
|
432
|
-
runIndex: that.runIndex,
|
|
433
|
-
itemIndex: that.itemIndex,
|
|
434
|
-
});
|
|
481
|
+
if (executionData.length === 0 && !throwOnMissingExecutionData) {
|
|
482
|
+
return undefined;
|
|
435
483
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
if (taskData.main.length <= outputIndex) {
|
|
442
|
-
throw new expression_error_1.ExpressionError(`Node "${nodeName}" has no branch with index ${outputIndex}.`, {
|
|
443
|
-
runIndex: that.runIndex,
|
|
444
|
-
itemIndex: that.itemIndex,
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
executionData = taskData.main[outputIndex];
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
// Short syntax got used to return data from active node
|
|
451
|
-
executionData = that.connectionInputData;
|
|
452
|
-
}
|
|
453
|
-
return executionData;
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Returns a proxy which allows to query data of a given node
|
|
457
|
-
*
|
|
458
|
-
* @private
|
|
459
|
-
* @param {string} nodeName The name of the node query data from
|
|
460
|
-
* @param {boolean} [shortSyntax=false] If short syntax got used
|
|
461
|
-
* @param {boolean} [throwOnMissingExecutionData=true] If an error should get thrown if no execution data is available
|
|
462
|
-
*/
|
|
463
|
-
nodeDataGetter(nodeName, shortSyntax = false, throwOnMissingExecutionData = true) {
|
|
464
|
-
const that = this;
|
|
465
|
-
const node = this.workflow.nodes[nodeName];
|
|
466
|
-
return new Proxy({ binary: undefined, data: undefined, json: undefined }, {
|
|
467
|
-
has: () => true,
|
|
468
|
-
get(target, name, receiver) {
|
|
469
|
-
if (name === 'isProxy')
|
|
470
|
-
return true;
|
|
471
|
-
name = name.toString();
|
|
472
|
-
if (!node) {
|
|
473
|
-
throw new expression_error_1.ExpressionError('Referenced node does not exist', {
|
|
474
|
-
messageTemplate: 'Make sure to double-check the node name for typos',
|
|
484
|
+
// Ultra-simple execution-based validation: if no execution data exists, throw error
|
|
485
|
+
if (executionData.length === 0) {
|
|
486
|
+
throw new expression_error_1.ExpressionError(`Node '${nodeName}' hasn't been executed`, {
|
|
487
|
+
messageTemplate: 'An expression references this node, but the node is unexecuted. Consider re-wiring your nodes or checking for execution first, i.e. {{ $if( $("{{nodeName}}").isExecuted, <action_if_executed>, "") }}',
|
|
475
488
|
functionality: 'pairedItem',
|
|
476
489
|
descriptionKey: isScriptingNode(nodeName, that.workflow)
|
|
477
490
|
? 'pairedItemNoConnectionCodeNode'
|
|
478
491
|
: 'pairedItemNoConnection',
|
|
479
|
-
type: '
|
|
492
|
+
type: 'no_execution_data',
|
|
480
493
|
nodeCause: nodeName,
|
|
481
494
|
runIndex: that.runIndex,
|
|
482
495
|
itemIndex: that.itemIndex,
|
|
483
496
|
});
|
|
484
497
|
}
|
|
485
|
-
if (
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
498
|
+
if (executionData.length <= that.itemIndex) {
|
|
499
|
+
throw new expression_error_1.ExpressionError(`"${nodeName}" node has ${executionData.length} item(s) but you're trying to access item ${that.itemIndex}`, {
|
|
500
|
+
messageTemplate: 'Adjust your expression to access an existing item index (0-{{maxIndex}})',
|
|
501
|
+
functionality: 'pairedItem',
|
|
502
|
+
descriptionKey: 'pairedItemInvalidIndex',
|
|
503
|
+
type: 'no_execution_data',
|
|
504
|
+
nodeCause: nodeName,
|
|
505
|
+
runIndex: that.runIndex,
|
|
506
|
+
itemIndex: that.itemIndex,
|
|
489
507
|
});
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
: 'pairedItemNoConnection',
|
|
501
|
-
type: 'no_execution_data',
|
|
502
|
-
nodeCause: nodeName,
|
|
503
|
-
runIndex: that.runIndex,
|
|
504
|
-
itemIndex: that.itemIndex,
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
if (executionData.length <= that.itemIndex) {
|
|
508
|
-
throw new expression_error_1.ExpressionError(`"${nodeName}" node has ${executionData.length} item(s) but you're trying to access item ${that.itemIndex}`, {
|
|
509
|
-
messageTemplate: 'Adjust your expression to access an existing item index (0-{{maxIndex}})',
|
|
510
|
-
functionality: 'pairedItem',
|
|
511
|
-
descriptionKey: 'pairedItemInvalidIndex',
|
|
512
|
-
type: 'no_execution_data',
|
|
513
|
-
nodeCause: nodeName,
|
|
514
|
-
runIndex: that.runIndex,
|
|
515
|
-
itemIndex: that.itemIndex,
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
if (['data', 'json'].includes(name)) {
|
|
519
|
-
// JSON-Data
|
|
520
|
-
return executionData[that.itemIndex].json;
|
|
508
|
+
}
|
|
509
|
+
if (['data', 'json'].includes(name)) {
|
|
510
|
+
// JSON-Data
|
|
511
|
+
return executionData[that.itemIndex].json;
|
|
512
|
+
}
|
|
513
|
+
if (name === 'binary') {
|
|
514
|
+
// Binary-Data
|
|
515
|
+
const returnData = {};
|
|
516
|
+
if (!executionData[that.itemIndex].binary) {
|
|
517
|
+
return returnData;
|
|
521
518
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
returnData[keyName] = {};
|
|
531
|
-
const binaryData = binaryKeyData[keyName];
|
|
532
|
-
for (const propertyName in binaryData) {
|
|
533
|
-
if (propertyName === 'data') {
|
|
534
|
-
// Skip the data property
|
|
535
|
-
continue;
|
|
536
|
-
}
|
|
537
|
-
returnData[keyName][propertyName] = binaryData[propertyName];
|
|
519
|
+
const binaryKeyData = executionData[that.itemIndex].binary;
|
|
520
|
+
for (const keyName of Object.keys(binaryKeyData)) {
|
|
521
|
+
returnData[keyName] = {};
|
|
522
|
+
const binaryData = binaryKeyData[keyName];
|
|
523
|
+
for (const propertyName in binaryData) {
|
|
524
|
+
if (propertyName === 'data') {
|
|
525
|
+
// Skip the data property
|
|
526
|
+
continue;
|
|
538
527
|
}
|
|
528
|
+
returnData[keyName][propertyName] = binaryData[propertyName];
|
|
539
529
|
}
|
|
540
|
-
return returnData;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
else if (name === 'context') {
|
|
544
|
-
return that.nodeContextGetter(nodeName);
|
|
545
|
-
}
|
|
546
|
-
else if (name === 'parameter') {
|
|
547
|
-
// Get node parameter data
|
|
548
|
-
return that.nodeParameterGetter(nodeName);
|
|
549
|
-
}
|
|
550
|
-
else if (name === 'runIndex') {
|
|
551
|
-
if (!that.runExecutionData?.resultData.runData[nodeName]) {
|
|
552
|
-
return -1;
|
|
553
530
|
}
|
|
554
|
-
return
|
|
555
|
-
}
|
|
556
|
-
return Reflect.get(target, name, receiver);
|
|
557
|
-
},
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
prevNodeGetter() {
|
|
561
|
-
const allowedValues = ['name', 'outputIndex', 'runIndex'];
|
|
562
|
-
const that = this;
|
|
563
|
-
return new Proxy({}, {
|
|
564
|
-
has: () => true,
|
|
565
|
-
ownKeys() {
|
|
566
|
-
return allowedValues;
|
|
567
|
-
},
|
|
568
|
-
getOwnPropertyDescriptor() {
|
|
569
|
-
return {
|
|
570
|
-
enumerable: true,
|
|
571
|
-
configurable: true,
|
|
572
|
-
};
|
|
573
|
-
},
|
|
574
|
-
get(target, name, receiver) {
|
|
575
|
-
if (name === 'isProxy')
|
|
576
|
-
return true;
|
|
577
|
-
if (!that.executeData?.source) {
|
|
578
|
-
// Means the previous node did not get executed yet
|
|
579
|
-
return undefined;
|
|
531
|
+
return returnData;
|
|
580
532
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
},
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Returns a proxy to query data from the workflow
|
|
597
|
-
*
|
|
598
|
-
* @private
|
|
599
|
-
*/
|
|
600
|
-
workflowGetter() {
|
|
601
|
-
const allowedValues = ['active', 'id', 'name'];
|
|
602
|
-
const that = this;
|
|
603
|
-
return new Proxy({}, {
|
|
604
|
-
has: () => true,
|
|
605
|
-
ownKeys() {
|
|
606
|
-
return allowedValues;
|
|
607
|
-
},
|
|
608
|
-
getOwnPropertyDescriptor() {
|
|
609
|
-
return {
|
|
610
|
-
enumerable: true,
|
|
611
|
-
configurable: true,
|
|
612
|
-
};
|
|
613
|
-
},
|
|
614
|
-
get(target, name, receiver) {
|
|
615
|
-
if (name === 'isProxy')
|
|
616
|
-
return true;
|
|
617
|
-
if (allowedValues.includes(name.toString())) {
|
|
618
|
-
const value = that.workflow[name];
|
|
619
|
-
if (value === undefined && name === 'id') {
|
|
620
|
-
throw new expression_error_1.ExpressionError('save workflow to view', {
|
|
621
|
-
description: 'Please save the workflow first to use $workflow',
|
|
622
|
-
runIndex: that.runIndex,
|
|
623
|
-
itemIndex: that.itemIndex,
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
return value;
|
|
533
|
+
}
|
|
534
|
+
else if (name === 'context') {
|
|
535
|
+
return that.nodeContextGetter(nodeName);
|
|
536
|
+
}
|
|
537
|
+
else if (name === 'parameter') {
|
|
538
|
+
// Get node parameter data
|
|
539
|
+
return that.nodeParameterGetter(nodeName);
|
|
540
|
+
}
|
|
541
|
+
else if (name === 'runIndex') {
|
|
542
|
+
if (!that.runExecutionData?.resultData.runData[nodeName]) {
|
|
543
|
+
return -1;
|
|
627
544
|
}
|
|
628
|
-
return
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
545
|
+
return that.runExecutionData.resultData.runData[nodeName].length - 1;
|
|
546
|
+
}
|
|
547
|
+
return Reflect.get(target, name, receiver);
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
prevNodeGetter() {
|
|
552
|
+
const allowedValues = ['name', 'outputIndex', 'runIndex'];
|
|
553
|
+
const that = this;
|
|
554
|
+
return new Proxy({}, {
|
|
555
|
+
has: () => true,
|
|
556
|
+
ownKeys() {
|
|
557
|
+
return allowedValues;
|
|
558
|
+
},
|
|
559
|
+
getOwnPropertyDescriptor() {
|
|
560
|
+
return {
|
|
561
|
+
enumerable: true,
|
|
562
|
+
configurable: true,
|
|
563
|
+
};
|
|
564
|
+
},
|
|
565
|
+
get(target, name, receiver) {
|
|
566
|
+
if (name === 'isProxy')
|
|
567
|
+
return true;
|
|
568
|
+
if (!that.executeData?.source) {
|
|
569
|
+
// Means the previous node did not get executed yet
|
|
570
|
+
return undefined;
|
|
571
|
+
}
|
|
572
|
+
const sourceData = that.executeData.source.main[0];
|
|
573
|
+
if (name === 'name') {
|
|
574
|
+
return sourceData.previousNode;
|
|
575
|
+
}
|
|
576
|
+
if (name === 'outputIndex') {
|
|
577
|
+
return sourceData.previousNodeOutput || 0;
|
|
578
|
+
}
|
|
579
|
+
if (name === 'runIndex') {
|
|
580
|
+
return sourceData.previousNodeRun || 0;
|
|
581
|
+
}
|
|
582
|
+
return Reflect.get(target, name, receiver);
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Returns a proxy to query data from the workflow
|
|
588
|
+
*
|
|
589
|
+
* @private
|
|
590
|
+
*/
|
|
591
|
+
workflowGetter() {
|
|
592
|
+
const allowedValues = ['active', 'id', 'name'];
|
|
593
|
+
const that = this;
|
|
594
|
+
return new Proxy({}, {
|
|
595
|
+
has: () => true,
|
|
596
|
+
ownKeys() {
|
|
597
|
+
return allowedValues;
|
|
598
|
+
},
|
|
599
|
+
getOwnPropertyDescriptor() {
|
|
600
|
+
return {
|
|
601
|
+
enumerable: true,
|
|
602
|
+
configurable: true,
|
|
603
|
+
};
|
|
604
|
+
},
|
|
605
|
+
get(target, name, receiver) {
|
|
606
|
+
if (name === 'isProxy')
|
|
607
|
+
return true;
|
|
608
|
+
if (allowedValues.includes(name.toString())) {
|
|
609
|
+
const value = that.workflow[name];
|
|
610
|
+
if (value === undefined && name === 'id') {
|
|
611
|
+
throw new expression_error_1.ExpressionError('save workflow to view', {
|
|
612
|
+
description: 'Please save the workflow first to use $workflow',
|
|
647
613
|
runIndex: that.runIndex,
|
|
648
614
|
itemIndex: that.itemIndex,
|
|
649
|
-
nodeCause: nodeName,
|
|
650
|
-
descriptionKey: 'nodeNotFound',
|
|
651
615
|
});
|
|
652
616
|
}
|
|
653
|
-
return
|
|
654
|
-
},
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Returns the data proxy object which allows to query data from current run
|
|
659
|
-
*
|
|
660
|
-
*/
|
|
661
|
-
getDataProxy(opts) {
|
|
662
|
-
const that = this;
|
|
663
|
-
// replacing proxies with the actual data.
|
|
664
|
-
const jmespathWrapper = (data, query) => {
|
|
665
|
-
if (typeof data !== 'object' || typeof query !== 'string') {
|
|
666
|
-
throw new expression_error_1.ExpressionError('expected two arguments (Object, string) for this function', {
|
|
667
|
-
runIndex: that.runIndex,
|
|
668
|
-
itemIndex: that.itemIndex,
|
|
669
|
-
});
|
|
617
|
+
return value;
|
|
670
618
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
619
|
+
return Reflect.get(target, name, receiver);
|
|
620
|
+
},
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Returns a proxy to query data of all nodes
|
|
625
|
+
*
|
|
626
|
+
* @private
|
|
627
|
+
*/
|
|
628
|
+
nodeGetter() {
|
|
629
|
+
const that = this;
|
|
630
|
+
return new Proxy({}, {
|
|
631
|
+
has: () => true,
|
|
632
|
+
get(_, name) {
|
|
633
|
+
if (name === 'isProxy')
|
|
634
|
+
return true;
|
|
635
|
+
const nodeName = name.toString();
|
|
636
|
+
if (that.workflow.getNode(nodeName) === null) {
|
|
637
|
+
throw new expression_error_1.ExpressionError("Referenced node doesn't exist", {
|
|
676
638
|
runIndex: that.runIndex,
|
|
677
639
|
itemIndex: that.itemIndex,
|
|
640
|
+
nodeCause: nodeName,
|
|
641
|
+
descriptionKey: 'nodeNotFound',
|
|
678
642
|
});
|
|
679
643
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
if (context?.nodeCause) {
|
|
696
|
-
const nodeName = context.nodeCause;
|
|
697
|
-
const pinData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode);
|
|
698
|
-
if (pinData) {
|
|
699
|
-
if (!context) {
|
|
700
|
-
context = {};
|
|
701
|
-
}
|
|
702
|
-
message = `Unpin '${nodeName}' to execute`;
|
|
703
|
-
context.messageTemplate = undefined;
|
|
704
|
-
context.descriptionKey = 'pairedItemPinned';
|
|
705
|
-
}
|
|
706
|
-
if (context.moreInfoLink && (pinData || isScriptingNode(nodeName, that.workflow))) {
|
|
707
|
-
const moreInfoLink = ' <a target="_blank" href="https://docs.n8n.io/data/data-mapping/data-item-linking/item-linking-errors/">More info</a>';
|
|
708
|
-
context.description += moreInfoLink;
|
|
709
|
-
if (context.descriptionTemplate)
|
|
710
|
-
context.descriptionTemplate += moreInfoLink;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
return new expression_error_1.ExpressionError(message, {
|
|
644
|
+
return that.nodeDataGetter(nodeName);
|
|
645
|
+
},
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Returns the data proxy object which allows to query data from current run
|
|
650
|
+
*
|
|
651
|
+
*/
|
|
652
|
+
getDataProxy(opts) {
|
|
653
|
+
const that = this;
|
|
654
|
+
// replacing proxies with the actual data.
|
|
655
|
+
const jmespathWrapper = (data, query) => {
|
|
656
|
+
if (typeof data !== 'object' || typeof query !== 'string') {
|
|
657
|
+
throw new expression_error_1.ExpressionError('expected two arguments (Object, string) for this function', {
|
|
714
658
|
runIndex: that.runIndex,
|
|
715
659
|
itemIndex: that.itemIndex,
|
|
716
|
-
...context,
|
|
717
660
|
});
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
return new expression_error_1.ExpressionError(message, {
|
|
661
|
+
}
|
|
662
|
+
// jmespath decodes escape sequences inside quoted identifiers, so
|
|
663
|
+
// the token check below must run against an unescaped query. Reject
|
|
664
|
+
// any backslash up front to keep the property-name match meaningful.
|
|
665
|
+
if (query.includes('\\') || (0, utils_1.containsUnsafeObjectPropertyToken)(query)) {
|
|
666
|
+
throw new expression_error_1.ExpressionError('Cannot access this property in a jmespath query due to security concerns', {
|
|
725
667
|
runIndex: that.runIndex,
|
|
726
668
|
itemIndex: that.itemIndex,
|
|
727
|
-
functionality: 'pairedItem',
|
|
728
|
-
descriptionKey: isScriptingNode(nodeCause, that.workflow)
|
|
729
|
-
? 'pairedItemNoInfoCodeNode'
|
|
730
|
-
: 'pairedItemNoInfo',
|
|
731
|
-
nodeCause,
|
|
732
|
-
causeDetailed: `Missing pairedItem data (node '${nodeCause}' probably didn't supply it)`,
|
|
733
|
-
type: 'paired_item_no_info',
|
|
734
|
-
});
|
|
735
|
-
};
|
|
736
|
-
const createNoConnectionError = (nodeCause) => {
|
|
737
|
-
return createExpressionError('Invalid expression', {
|
|
738
|
-
messageTemplate: 'No path back to referenced node',
|
|
739
|
-
functionality: 'pairedItem',
|
|
740
|
-
descriptionKey: isScriptingNode(nodeCause, that.workflow)
|
|
741
|
-
? 'pairedItemNoConnectionCodeNode'
|
|
742
|
-
: 'pairedItemNoConnection',
|
|
743
|
-
type: 'paired_item_no_connection',
|
|
744
|
-
moreInfoLink: true,
|
|
745
|
-
nodeCause,
|
|
746
|
-
});
|
|
747
|
-
};
|
|
748
|
-
function createBranchNotFoundError(node, item, cause) {
|
|
749
|
-
return createExpressionError('Branch not found', {
|
|
750
|
-
messageTemplate: 'Paired item references non-existent branch',
|
|
751
|
-
functionality: 'pairedItem',
|
|
752
|
-
nodeCause: cause,
|
|
753
|
-
functionOverrides: { message: 'Invalid branch reference' },
|
|
754
|
-
description: `Item ${item} in node ${node} references a branch that doesn't exist.`,
|
|
755
|
-
type: 'paired_item_invalid_info',
|
|
756
669
|
});
|
|
757
670
|
}
|
|
758
|
-
|
|
759
|
-
return
|
|
760
|
-
messageTemplate: 'Unable to find paired item source',
|
|
761
|
-
functionality: 'pairedItem',
|
|
762
|
-
nodeCause: cause,
|
|
763
|
-
functionOverrides: { message: 'Data not found' },
|
|
764
|
-
description: `Could not trace back to node '${destNode}'`,
|
|
765
|
-
type: 'paired_item_no_info',
|
|
766
|
-
moreInfoLink: true,
|
|
767
|
-
});
|
|
671
|
+
if (!Array.isArray(data) && typeof data === 'object') {
|
|
672
|
+
return jmespath.search({ ...data }, query);
|
|
768
673
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
674
|
+
return jmespath.search(data, query);
|
|
675
|
+
};
|
|
676
|
+
const createExpressionError = (message, context) => {
|
|
677
|
+
if (isScriptingNode(that.activeNodeName, that.workflow) && context?.functionOverrides) {
|
|
678
|
+
// If the node in which the error is thrown is a function node,
|
|
679
|
+
// display a different error message in case there is one defined
|
|
680
|
+
message = context.functionOverrides.message || message;
|
|
681
|
+
context.description = context.functionOverrides.description || context.description;
|
|
682
|
+
// The error will be in the code and not on an expression on a parameter
|
|
683
|
+
// so remove the messageTemplate as it would overwrite the message
|
|
684
|
+
context.messageTemplate = undefined;
|
|
780
685
|
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
686
|
+
if (context?.nodeCause) {
|
|
687
|
+
const nodeName = context.nodeCause;
|
|
688
|
+
const pinData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode);
|
|
689
|
+
if (pinData) {
|
|
690
|
+
if (!context) {
|
|
691
|
+
context = {};
|
|
692
|
+
}
|
|
693
|
+
message = `Unpin '${nodeName}' to execute`;
|
|
694
|
+
context.messageTemplate = undefined;
|
|
695
|
+
context.descriptionKey = 'pairedItemPinned';
|
|
696
|
+
}
|
|
697
|
+
if (context.moreInfoLink && (pinData || isScriptingNode(nodeName, that.workflow))) {
|
|
698
|
+
const moreInfoLink = ' <a target="_blank" href="https://docs.n8n.io/data/data-mapping/data-item-linking/item-linking-errors/">More info</a>';
|
|
699
|
+
context.description += moreInfoLink;
|
|
700
|
+
if (context.descriptionTemplate)
|
|
701
|
+
context.descriptionTemplate += moreInfoLink;
|
|
784
702
|
}
|
|
785
|
-
const finalSource = pairedItem.sourceOverwrite || sourceData;
|
|
786
|
-
return [pairedItem, finalSource];
|
|
787
703
|
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
}
|
|
704
|
+
return new expression_error_1.ExpressionError(message, {
|
|
705
|
+
runIndex: that.runIndex,
|
|
706
|
+
itemIndex: that.itemIndex,
|
|
707
|
+
...context,
|
|
708
|
+
});
|
|
709
|
+
};
|
|
710
|
+
const createMissingPairedItemError = (nodeCause, usedMethodName = PAIRED_ITEM_METHOD.PAIRED_ITEM) => {
|
|
711
|
+
const pinData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeCause, that.mode);
|
|
712
|
+
const message = pinData
|
|
713
|
+
? `Using the ${usedMethodName} method doesn't work with pinned data in this scenario. Please unpin '${nodeCause}' and try again.`
|
|
714
|
+
: `Paired item data for ${usedMethodName} from node '${nodeCause}' is unavailable. Ensure '${nodeCause}' is providing the required output.`;
|
|
715
|
+
return new expression_error_1.ExpressionError(message, {
|
|
716
|
+
runIndex: that.runIndex,
|
|
717
|
+
itemIndex: that.itemIndex,
|
|
718
|
+
functionality: 'pairedItem',
|
|
719
|
+
descriptionKey: isScriptingNode(nodeCause, that.workflow)
|
|
720
|
+
? 'pairedItemNoInfoCodeNode'
|
|
721
|
+
: 'pairedItemNoInfo',
|
|
722
|
+
nodeCause,
|
|
723
|
+
causeDetailed: `Missing pairedItem data (node '${nodeCause}' probably didn't supply it)`,
|
|
724
|
+
type: 'paired_item_no_info',
|
|
725
|
+
});
|
|
726
|
+
};
|
|
727
|
+
const createNoConnectionError = (nodeCause) => {
|
|
728
|
+
return createExpressionError('Invalid expression', {
|
|
729
|
+
messageTemplate: 'No path back to referenced node',
|
|
730
|
+
functionality: 'pairedItem',
|
|
731
|
+
descriptionKey: isScriptingNode(nodeCause, that.workflow)
|
|
732
|
+
? 'pairedItemNoConnectionCodeNode'
|
|
733
|
+
: 'pairedItemNoConnection',
|
|
734
|
+
type: 'paired_item_no_connection',
|
|
735
|
+
moreInfoLink: true,
|
|
736
|
+
nodeCause,
|
|
737
|
+
});
|
|
738
|
+
};
|
|
739
|
+
function createBranchNotFoundError(node, item, cause) {
|
|
740
|
+
return createExpressionError('Branch not found', {
|
|
741
|
+
messageTemplate: 'Paired item references non-existent branch',
|
|
742
|
+
functionality: 'pairedItem',
|
|
743
|
+
nodeCause: cause,
|
|
744
|
+
functionOverrides: { message: 'Invalid branch reference' },
|
|
745
|
+
description: `Item ${item} in node ${node} references a branch that doesn't exist.`,
|
|
746
|
+
type: 'paired_item_invalid_info',
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
function createPairedItemNotFound(destNode, cause) {
|
|
750
|
+
return createExpressionError('Paired item resolution failed', {
|
|
751
|
+
messageTemplate: 'Unable to find paired item source',
|
|
752
|
+
functionality: 'pairedItem',
|
|
753
|
+
nodeCause: cause,
|
|
754
|
+
functionOverrides: { message: 'Data not found' },
|
|
755
|
+
description: `Could not trace back to node '${destNode}'`,
|
|
756
|
+
type: 'paired_item_no_info',
|
|
757
|
+
moreInfoLink: true,
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
function createPairedItemMultipleItemsFound(destNode, itemIndex) {
|
|
761
|
+
return createExpressionError('Multiple matches found', {
|
|
762
|
+
messageTemplate: `Multiple matching items for item [${itemIndex}]`,
|
|
763
|
+
functionality: 'pairedItem',
|
|
764
|
+
functionOverrides: { message: 'Multiple matches' },
|
|
765
|
+
nodeCause: destNode,
|
|
766
|
+
descriptionKey: isScriptingNode(destNode, that.workflow)
|
|
767
|
+
? 'pairedItemMultipleMatchesCodeNode'
|
|
768
|
+
: 'pairedItemMultipleMatches',
|
|
769
|
+
type: 'paired_item_multiple_matches',
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
function normalizeInputs(pairedItem, sourceData) {
|
|
773
|
+
if (typeof pairedItem === 'number') {
|
|
774
|
+
pairedItem = { item: pairedItem };
|
|
798
775
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
776
|
+
const finalSource = pairedItem.sourceOverwrite || sourceData;
|
|
777
|
+
return [pairedItem, finalSource];
|
|
778
|
+
}
|
|
779
|
+
function pinDataToTask(pinData) {
|
|
780
|
+
if (!pinData)
|
|
781
|
+
return undefined;
|
|
782
|
+
return {
|
|
783
|
+
data: { main: [pinData] },
|
|
784
|
+
startTime: 0,
|
|
785
|
+
executionTime: 0,
|
|
786
|
+
executionIndex: 0,
|
|
787
|
+
source: [],
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
function getTaskData(source) {
|
|
791
|
+
return (that.runExecutionData?.resultData?.runData?.[source.previousNode]?.[source.previousNodeRun || 0] ??
|
|
792
|
+
pinDataToTask((0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, source.previousNode, that.mode)));
|
|
793
|
+
}
|
|
794
|
+
function getNodeOutput(taskData, source, nodeCause) {
|
|
795
|
+
const outputIndex = source.previousNodeOutput || 0;
|
|
796
|
+
const outputs = taskData?.data?.main?.[outputIndex];
|
|
797
|
+
if (!outputs) {
|
|
798
|
+
throw createExpressionError('Can’t get data for expression', {
|
|
799
|
+
messageTemplate: 'Missing output data',
|
|
800
|
+
functionOverrides: { message: 'Missing output' },
|
|
801
|
+
nodeCause,
|
|
802
|
+
description: `Expected output #${outputIndex} from node ${source.previousNode}`,
|
|
803
|
+
type: 'internal',
|
|
804
|
+
});
|
|
802
805
|
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
806
|
+
return outputs;
|
|
807
|
+
}
|
|
808
|
+
const normalizePairedItem = (paired) => {
|
|
809
|
+
if (paired === null || paired === undefined) {
|
|
810
|
+
return [];
|
|
811
|
+
}
|
|
812
|
+
const pairedItems = Array.isArray(paired) ? paired : [paired];
|
|
813
|
+
return pairedItems.map((p) => (typeof p === 'number' ? { item: p } : p));
|
|
814
|
+
};
|
|
815
|
+
const getPairedItem = (destinationNodeName, incomingSourceData, initialPairedItem, usedMethodName = PAIRED_ITEM_METHOD.$GET_PAIRED_ITEM, nodeBeforeLast) => {
|
|
816
|
+
// Normalize inputs
|
|
817
|
+
const [pairedItem, sourceData] = normalizeInputs(initialPairedItem, incomingSourceData);
|
|
818
|
+
if (!sourceData) {
|
|
819
|
+
throw createPairedItemNotFound(destinationNodeName, nodeBeforeLast);
|
|
820
|
+
}
|
|
821
|
+
const taskData = getTaskData(sourceData);
|
|
822
|
+
const outputData = getNodeOutput(taskData, sourceData, nodeBeforeLast);
|
|
823
|
+
const item = outputData[pairedItem.item];
|
|
824
|
+
const sourceArray = taskData?.source ?? [];
|
|
825
|
+
// Done: reached the destination node in the ancestry chain
|
|
826
|
+
if (sourceData.previousNode === destinationNodeName) {
|
|
827
|
+
if (pairedItem.item >= outputData.length) {
|
|
828
|
+
throw createMissingPairedItemError(sourceData.previousNode, usedMethodName);
|
|
814
829
|
}
|
|
815
|
-
return
|
|
830
|
+
return item;
|
|
816
831
|
}
|
|
817
|
-
|
|
818
|
-
|
|
832
|
+
// Normalize paired item to always be IPairedItemData[]
|
|
833
|
+
const nextPairedItems = normalizePairedItem(item.pairedItem);
|
|
834
|
+
if (nextPairedItems.length === 0) {
|
|
835
|
+
throw createMissingPairedItemError(sourceData.previousNode, usedMethodName);
|
|
836
|
+
}
|
|
837
|
+
// Recursively traverse ancestry to find the destination node + paired item
|
|
838
|
+
const results = nextPairedItems.flatMap((nextPairedItem) => {
|
|
839
|
+
const inputIndex = nextPairedItem.input ?? 0;
|
|
840
|
+
if (inputIndex >= sourceArray.length)
|
|
819
841
|
return [];
|
|
842
|
+
const nextSource = nextPairedItem.sourceOverwrite ?? sourceArray[inputIndex];
|
|
843
|
+
try {
|
|
844
|
+
return (0, result_1.createResultOk)(getPairedItem(destinationNodeName, nextSource, { ...nextPairedItem, input: inputIndex }, usedMethodName, sourceData.previousNode));
|
|
820
845
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
};
|
|
824
|
-
const getPairedItem = (destinationNodeName, incomingSourceData, initialPairedItem, usedMethodName = PAIRED_ITEM_METHOD.$GET_PAIRED_ITEM, nodeBeforeLast) => {
|
|
825
|
-
// Normalize inputs
|
|
826
|
-
const [pairedItem, sourceData] = normalizeInputs(initialPairedItem, incomingSourceData);
|
|
827
|
-
if (!sourceData) {
|
|
828
|
-
throw createPairedItemNotFound(destinationNodeName, nodeBeforeLast);
|
|
829
|
-
}
|
|
830
|
-
const taskData = getTaskData(sourceData);
|
|
831
|
-
const outputData = getNodeOutput(taskData, sourceData, nodeBeforeLast);
|
|
832
|
-
const item = outputData[pairedItem.item];
|
|
833
|
-
const sourceArray = taskData?.source ?? [];
|
|
834
|
-
// Done: reached the destination node in the ancestry chain
|
|
835
|
-
if (sourceData.previousNode === destinationNodeName) {
|
|
836
|
-
if (pairedItem.item >= outputData.length) {
|
|
837
|
-
throw createMissingPairedItemError(sourceData.previousNode, usedMethodName);
|
|
838
|
-
}
|
|
839
|
-
return item;
|
|
840
|
-
}
|
|
841
|
-
// Normalize paired item to always be IPairedItemData[]
|
|
842
|
-
const nextPairedItems = normalizePairedItem(item.pairedItem);
|
|
843
|
-
if (nextPairedItems.length === 0) {
|
|
844
|
-
throw createMissingPairedItemError(sourceData.previousNode, usedMethodName);
|
|
846
|
+
catch (error) {
|
|
847
|
+
return (0, result_1.createResultError)(error);
|
|
845
848
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
849
|
+
});
|
|
850
|
+
if (results.every((result) => !result.ok)) {
|
|
851
|
+
throw results[0].error;
|
|
852
|
+
}
|
|
853
|
+
const matchedItems = results.filter((result) => result.ok).map((result) => result.result);
|
|
854
|
+
if (matchedItems.length === 0) {
|
|
855
|
+
if (sourceArray.length === 0)
|
|
856
|
+
throw createNoConnectionError(destinationNodeName);
|
|
857
|
+
throw createBranchNotFoundError(sourceData.previousNode, pairedItem.item, nodeBeforeLast);
|
|
858
|
+
}
|
|
859
|
+
const [first, ...rest] = matchedItems;
|
|
860
|
+
if (rest.some((r) => r !== first)) {
|
|
861
|
+
throw createPairedItemMultipleItemsFound(destinationNodeName, pairedItem.item);
|
|
862
|
+
}
|
|
863
|
+
return first;
|
|
864
|
+
};
|
|
865
|
+
const handleFromAi = (name, _description, _type = 'string', defaultValue) => {
|
|
866
|
+
const { itemIndex, runIndex } = that;
|
|
867
|
+
if (!name || name === '') {
|
|
868
|
+
throw new expression_error_1.ExpressionError("Add a key, e.g. $fromAI('placeholder_name')", {
|
|
869
|
+
runIndex,
|
|
870
|
+
itemIndex,
|
|
858
871
|
});
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
872
|
+
}
|
|
873
|
+
const nameValidationRegex = /^[a-zA-Z0-9_-]{0,64}$/;
|
|
874
|
+
if (!nameValidationRegex.test(name)) {
|
|
875
|
+
throw new expression_error_1.ExpressionError('Invalid parameter key, must be between 1 and 64 characters long and only contain lowercase letters, uppercase letters, numbers, underscores, and hyphens', {
|
|
876
|
+
runIndex,
|
|
877
|
+
itemIndex,
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
const resultData = that.runExecutionData?.resultData?.runData?.[that.activeNodeName]?.[runIndex];
|
|
881
|
+
let inputData;
|
|
882
|
+
let placeholdersDataInputData;
|
|
883
|
+
if (!resultData) {
|
|
884
|
+
inputData = this.connectionInputData?.[runIndex];
|
|
885
|
+
placeholdersDataInputData = inputData?.json;
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
inputData =
|
|
889
|
+
that.runExecutionData?.resultData.runData[that.activeNodeName]?.[runIndex].inputOverride;
|
|
890
|
+
placeholdersDataInputData = inputData?.[interfaces_1.NodeConnectionTypes.AiTool]?.[0]?.[itemIndex].json;
|
|
891
|
+
}
|
|
892
|
+
if (!placeholdersDataInputData) {
|
|
893
|
+
throw new expression_error_1.ExpressionError('No execution data available', {
|
|
894
|
+
runIndex,
|
|
895
|
+
itemIndex,
|
|
896
|
+
type: 'no_execution_data',
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
return (
|
|
900
|
+
// TS does not know that the key exists, we need to address this in refactor
|
|
901
|
+
placeholdersDataInputData?.query?.[name] ??
|
|
902
|
+
placeholdersDataInputData?.[name] ??
|
|
903
|
+
defaultValue);
|
|
904
|
+
};
|
|
905
|
+
const handleTool = (throwOnError = true) => {
|
|
906
|
+
const fallbackValue = that.additionalKeys?.['$tool'];
|
|
907
|
+
try {
|
|
908
|
+
const toolName = handleFromAi('tool', '');
|
|
909
|
+
const toolParameters = handleFromAi('toolParameters', '');
|
|
910
|
+
return {
|
|
911
|
+
name: toolName ?? fallbackValue?.name,
|
|
912
|
+
parameters: toolParameters ?? fallbackValue?.parameters,
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
catch (error) {
|
|
916
|
+
const isNoExecutionDataError = error instanceof expression_error_1.ExpressionError && error.context.type === 'no_execution_data';
|
|
917
|
+
// always suppress no_execution_data error
|
|
918
|
+
// $tool can get accessed in some cases where no execution data is available, e.g. task runners
|
|
919
|
+
if (isNoExecutionDataError) {
|
|
920
|
+
return fallbackValue;
|
|
888
921
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
let placeholdersDataInputData;
|
|
892
|
-
if (!resultData) {
|
|
893
|
-
inputData = this.connectionInputData?.[runIndex];
|
|
894
|
-
placeholdersDataInputData = inputData?.json;
|
|
922
|
+
if (throwOnError) {
|
|
923
|
+
throw error;
|
|
895
924
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
925
|
+
return undefined;
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
const base = {
|
|
929
|
+
$: (nodeName, resolveFullItem) => {
|
|
930
|
+
if (!nodeName) {
|
|
931
|
+
nodeName = that.prevNodeGetter().name;
|
|
932
|
+
if (!nodeName) {
|
|
933
|
+
throw createExpressionError('When calling $(), please specify a node');
|
|
934
|
+
}
|
|
900
935
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
936
|
+
const referencedNode = that.workflow.getNode(nodeName);
|
|
937
|
+
if (referencedNode === null) {
|
|
938
|
+
throw createExpressionError("Referenced node doesn't exist", {
|
|
939
|
+
runIndex: that.runIndex,
|
|
940
|
+
itemIndex: that.itemIndex,
|
|
941
|
+
nodeCause: nodeName,
|
|
942
|
+
descriptionKey: 'nodeNotFound',
|
|
906
943
|
});
|
|
907
944
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
return {
|
|
920
|
-
name: toolName ?? fallbackValue?.name,
|
|
921
|
-
parameters: toolParameters ?? fallbackValue?.parameters,
|
|
922
|
-
};
|
|
923
|
-
}
|
|
924
|
-
catch (error) {
|
|
925
|
-
const isNoExecutionDataError = error instanceof expression_error_1.ExpressionError && error.context.type === 'no_execution_data';
|
|
926
|
-
// always suppress no_execution_data error
|
|
927
|
-
// $tool can get accessed in some cases where no execution data is available, e.g. task runners
|
|
928
|
-
if (isNoExecutionDataError) {
|
|
929
|
-
return fallbackValue;
|
|
930
|
-
}
|
|
931
|
-
if (throwOnError) {
|
|
932
|
-
throw error;
|
|
933
|
-
}
|
|
934
|
-
return undefined;
|
|
935
|
-
}
|
|
936
|
-
};
|
|
937
|
-
const base = {
|
|
938
|
-
$: (nodeName, resolveFullItem) => {
|
|
939
|
-
if (!nodeName) {
|
|
940
|
-
nodeName = that.prevNodeGetter().name;
|
|
941
|
-
if (!nodeName) {
|
|
942
|
-
throw createExpressionError('When calling $(), please specify a node');
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
const referencedNode = that.workflow.getNode(nodeName);
|
|
946
|
-
if (referencedNode === null) {
|
|
947
|
-
throw createExpressionError("Referenced node doesn't exist", {
|
|
945
|
+
const ensureNodeExecutionData = () => {
|
|
946
|
+
if (!that?.runExecutionData?.resultData?.runData.hasOwnProperty(nodeName) &&
|
|
947
|
+
!(0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode)) {
|
|
948
|
+
throw createExpressionError(`Node '${nodeName}' hasn't been executed`, {
|
|
949
|
+
messageTemplate: 'An expression references this node, but the node is unexecuted. Consider re-wiring your nodes or checking for execution first, i.e. {{ $if( $("{{nodeName}}").isExecuted, <action_if_executed>, "") }}',
|
|
950
|
+
functionality: 'pairedItem',
|
|
951
|
+
descriptionKey: isScriptingNode(nodeName, that.workflow)
|
|
952
|
+
? 'pairedItemNoConnectionCodeNode'
|
|
953
|
+
: 'pairedItemNoConnection',
|
|
954
|
+
type: 'no_execution_data',
|
|
955
|
+
nodeCause: nodeName,
|
|
948
956
|
runIndex: that.runIndex,
|
|
949
957
|
itemIndex: that.itemIndex,
|
|
950
|
-
nodeCause: nodeName,
|
|
951
|
-
descriptionKey: 'nodeNotFound',
|
|
952
958
|
});
|
|
953
959
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
960
|
+
};
|
|
961
|
+
return new Proxy({}, {
|
|
962
|
+
has: () => true,
|
|
963
|
+
ownKeys() {
|
|
964
|
+
return [
|
|
965
|
+
PAIRED_ITEM_METHOD.PAIRED_ITEM,
|
|
966
|
+
'isExecuted',
|
|
967
|
+
PAIRED_ITEM_METHOD.ITEM_MATCHING,
|
|
968
|
+
PAIRED_ITEM_METHOD.ITEM,
|
|
969
|
+
'first',
|
|
970
|
+
'last',
|
|
971
|
+
'all',
|
|
972
|
+
'context',
|
|
973
|
+
'params',
|
|
974
|
+
];
|
|
975
|
+
},
|
|
976
|
+
get(target, property, receiver) {
|
|
977
|
+
if (property === 'isProxy')
|
|
978
|
+
return true;
|
|
979
|
+
if (property === 'isExecuted') {
|
|
980
|
+
return (that?.runExecutionData?.resultData?.runData.hasOwnProperty(nodeName) ?? false);
|
|
968
981
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
'last',
|
|
980
|
-
'all',
|
|
981
|
-
'context',
|
|
982
|
-
'params',
|
|
983
|
-
];
|
|
984
|
-
},
|
|
985
|
-
get(target, property, receiver) {
|
|
986
|
-
if (property === 'isProxy')
|
|
987
|
-
return true;
|
|
988
|
-
if (property === 'isExecuted') {
|
|
989
|
-
return (that?.runExecutionData?.resultData?.runData.hasOwnProperty(nodeName) ?? false);
|
|
982
|
+
if (property === PAIRED_ITEM_METHOD.PAIRED_ITEM ||
|
|
983
|
+
property === PAIRED_ITEM_METHOD.ITEM_MATCHING ||
|
|
984
|
+
property === PAIRED_ITEM_METHOD.ITEM) {
|
|
985
|
+
// Before resolving the pairedItem make sure that the requested node comes in the
|
|
986
|
+
// graph before the current one
|
|
987
|
+
const activeNode = that.workflow.getNode(that.activeNodeName);
|
|
988
|
+
let contextNode = that.contextNodeName;
|
|
989
|
+
if (activeNode) {
|
|
990
|
+
const parentMainInputNode = that.workflow.getParentMainInputNode(activeNode);
|
|
991
|
+
contextNode = parentMainInputNode?.name ?? contextNode;
|
|
990
992
|
}
|
|
991
|
-
if
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
//
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
if (activeNode) {
|
|
999
|
-
const parentMainInputNode = that.workflow.getParentMainInputNode(activeNode);
|
|
1000
|
-
contextNode = parentMainInputNode?.name ?? contextNode;
|
|
1001
|
-
}
|
|
1002
|
-
// Check if the node has any children and check parents for them instead of the activeNodeName
|
|
1003
|
-
const children = that.workflow.getChildNodes(that.activeNodeName, 'ALL_NON_MAIN');
|
|
1004
|
-
if (children.length === 0) {
|
|
1005
|
-
// Node has no children, check parent of context node
|
|
1006
|
-
const parents = that.workflow.getParentNodes(contextNode);
|
|
1007
|
-
if (!parents.includes(nodeName)) {
|
|
1008
|
-
throw createNoConnectionError(nodeName);
|
|
1009
|
-
}
|
|
993
|
+
// Check if the node has any children and check parents for them instead of the activeNodeName
|
|
994
|
+
const children = that.workflow.getChildNodes(that.activeNodeName, 'ALL_NON_MAIN');
|
|
995
|
+
if (children.length === 0) {
|
|
996
|
+
// Node has no children, check parent of context node
|
|
997
|
+
const parents = that.workflow.getParentNodes(contextNode);
|
|
998
|
+
if (!parents.includes(nodeName)) {
|
|
999
|
+
throw createNoConnectionError(nodeName);
|
|
1010
1000
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
// Node has children, check parent of children
|
|
1004
|
+
const parents = children.flatMap((child) => that.workflow.getParentNodes(child, 'ALL'));
|
|
1005
|
+
if (!parents.includes(nodeName)) {
|
|
1006
|
+
throw createNoConnectionError(nodeName);
|
|
1017
1007
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
});
|
|
1025
|
-
}
|
|
1026
|
-
itemIndex = that.itemIndex;
|
|
1027
|
-
}
|
|
1028
|
-
if (!that.connectionInputData.length) {
|
|
1029
|
-
const pinnedData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode);
|
|
1030
|
-
if (pinnedData) {
|
|
1031
|
-
return that.returnExecutionData(pinnedData[itemIndex], resolveFullItem);
|
|
1032
|
-
}
|
|
1033
|
-
// The active node has not run yet (e.g. partial execution),
|
|
1034
|
-
// so paired item resolution cannot trace through the chain.
|
|
1035
|
-
// Fall back to reading directly from the referenced node's
|
|
1036
|
-
// run data, which is what first()/last()/all() do.
|
|
1037
|
-
const nodeRunData = that.getNodeExecutionOrPinnedData({
|
|
1038
|
-
nodeName,
|
|
1039
|
-
});
|
|
1040
|
-
if (nodeRunData.length) {
|
|
1041
|
-
// In the UI preview itemIndex is always 0, but guard against
|
|
1042
|
-
// out-of-bounds access in case that assumption ever changes.
|
|
1043
|
-
if (itemIndex >= nodeRunData.length) {
|
|
1044
|
-
throw createExpressionError(`"${nodeName}" node has ${nodeRunData.length} item(s) but expression references item ${itemIndex}`, { itemIndex });
|
|
1045
|
-
}
|
|
1046
|
-
return that.returnExecutionData(nodeRunData[itemIndex], resolveFullItem);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
const executionData = that.connectionInputData;
|
|
1050
|
-
const input = executionData?.[itemIndex];
|
|
1051
|
-
if (!input) {
|
|
1052
|
-
throw createExpressionError('Can’t get data for expression', {
|
|
1053
|
-
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
|
1054
|
-
functionality: 'pairedItem',
|
|
1055
|
-
functionOverrides: {
|
|
1056
|
-
description: `Some intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong>‘ have not executed yet.`,
|
|
1057
|
-
message: 'Can’t get data',
|
|
1058
|
-
},
|
|
1059
|
-
description: `Some intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong>‘ have not executed yet.`,
|
|
1060
|
-
causeDetailed: `pairedItem can\'t be found when intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong> have not executed yet.`,
|
|
1008
|
+
}
|
|
1009
|
+
ensureNodeExecutionData();
|
|
1010
|
+
const pairedItemMethod = (itemIndex) => {
|
|
1011
|
+
if (itemIndex === undefined) {
|
|
1012
|
+
if (property === PAIRED_ITEM_METHOD.ITEM_MATCHING) {
|
|
1013
|
+
throw createExpressionError('Missing item index for .itemMatching()', {
|
|
1061
1014
|
itemIndex,
|
|
1062
|
-
type: 'paired_item_intermediate_nodes',
|
|
1063
1015
|
});
|
|
1064
1016
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
const
|
|
1069
|
-
if (
|
|
1070
|
-
|
|
1017
|
+
itemIndex = that.itemIndex;
|
|
1018
|
+
}
|
|
1019
|
+
if (!that.connectionInputData.length) {
|
|
1020
|
+
const pinnedData = (0, workflow_data_proxy_helpers_1.getPinDataIfManualExecution)(that.workflow, nodeName, that.mode);
|
|
1021
|
+
if (pinnedData) {
|
|
1022
|
+
return that.returnExecutionData(pinnedData[itemIndex], resolveFullItem);
|
|
1071
1023
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1024
|
+
// The active node has not run yet (e.g. partial execution),
|
|
1025
|
+
// so paired item resolution cannot trace through the chain.
|
|
1026
|
+
// Fall back to reading directly from the referenced node's
|
|
1027
|
+
// run data, which is what first()/last()/all() do.
|
|
1028
|
+
const nodeRunData = that.getNodeExecutionOrPinnedData({
|
|
1029
|
+
nodeName,
|
|
1030
|
+
});
|
|
1031
|
+
if (nodeRunData.length) {
|
|
1032
|
+
// In the UI preview itemIndex is always 0, but guard against
|
|
1033
|
+
// out-of-bounds access in case that assumption ever changes.
|
|
1034
|
+
if (itemIndex >= nodeRunData.length) {
|
|
1035
|
+
throw createExpressionError(`"${nodeName}" node has ${nodeRunData.length} item(s) but expression references item ${itemIndex}`, { itemIndex });
|
|
1036
|
+
}
|
|
1037
|
+
return that.returnExecutionData(nodeRunData[itemIndex], resolveFullItem);
|
|
1083
1038
|
}
|
|
1084
|
-
const sourceData = that.executeData.source.main[pairedItem.input || 0] ??
|
|
1085
|
-
that.executeData.source.main[0];
|
|
1086
|
-
return that.returnExecutionData(getPairedItem(nodeName, sourceData, pairedItem, property), resolveFullItem);
|
|
1087
|
-
};
|
|
1088
|
-
if (property === PAIRED_ITEM_METHOD.ITEM) {
|
|
1089
|
-
return pairedItemMethod();
|
|
1090
1039
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
runIndex,
|
|
1040
|
+
const executionData = that.connectionInputData;
|
|
1041
|
+
const input = executionData?.[itemIndex];
|
|
1042
|
+
if (!input) {
|
|
1043
|
+
throw createExpressionError('Can’t get data for expression', {
|
|
1044
|
+
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
|
1045
|
+
functionality: 'pairedItem',
|
|
1046
|
+
functionOverrides: {
|
|
1047
|
+
description: `Some intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong>‘ have not executed yet.`,
|
|
1048
|
+
message: 'Can’t get data',
|
|
1049
|
+
},
|
|
1050
|
+
description: `Some intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong>‘ have not executed yet.`,
|
|
1051
|
+
causeDetailed: `pairedItem can\'t be found when intermediate nodes between ‘<strong>${nodeName}</strong>‘ and ‘<strong>${that.activeNodeName}</strong> have not executed yet.`,
|
|
1052
|
+
itemIndex,
|
|
1053
|
+
type: 'paired_item_intermediate_nodes',
|
|
1106
1054
|
});
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1055
|
+
}
|
|
1056
|
+
// As we operate on the incoming item we can be sure that pairedItem is not an
|
|
1057
|
+
// array. After all can it only come from exactly one previous node via a certain
|
|
1058
|
+
// input. For that reason do we not have to consider the array case.
|
|
1059
|
+
const pairedItem = input.pairedItem;
|
|
1060
|
+
if (pairedItem === undefined) {
|
|
1061
|
+
throw createMissingPairedItemError(that.activeNodeName, property);
|
|
1062
|
+
}
|
|
1063
|
+
if (!that.executeData?.source) {
|
|
1064
|
+
throw createExpressionError('Can’t get data for expression', {
|
|
1065
|
+
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
|
1066
|
+
functionality: 'pairedItem',
|
|
1067
|
+
functionOverrides: {
|
|
1068
|
+
message: 'Can’t get data',
|
|
1069
|
+
},
|
|
1070
|
+
description: 'Apologies, this is an internal error. See details for more information',
|
|
1071
|
+
causeDetailed: 'Missing sourceData (probably an internal error)',
|
|
1072
|
+
itemIndex,
|
|
1125
1073
|
});
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1134
|
-
if (property === 'all') {
|
|
1135
|
-
ensureNodeExecutionData();
|
|
1136
|
-
return (branchIndex, runIndex) => {
|
|
1137
|
-
branchIndex =
|
|
1138
|
-
branchIndex ??
|
|
1139
|
-
// default to the output the active node is connected to
|
|
1140
|
-
that.workflow.getNodeConnectionIndexes(that.activeNodeName, nodeName)
|
|
1141
|
-
?.sourceIndex ??
|
|
1142
|
-
0;
|
|
1143
|
-
return that.returnExecutionData(that.getNodeExecutionOrPinnedData({
|
|
1144
|
-
nodeName,
|
|
1145
|
-
branchIndex,
|
|
1146
|
-
runIndex,
|
|
1147
|
-
}), resolveFullItem);
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
if (property === 'context') {
|
|
1151
|
-
return that.nodeContextGetter(nodeName);
|
|
1152
|
-
}
|
|
1153
|
-
if (property === 'params') {
|
|
1154
|
-
return that.workflow.getNode(nodeName)?.parameters;
|
|
1074
|
+
}
|
|
1075
|
+
const sourceData = that.executeData.source.main[pairedItem.input || 0] ??
|
|
1076
|
+
that.executeData.source.main[0];
|
|
1077
|
+
return that.returnExecutionData(getPairedItem(nodeName, sourceData, pairedItem, property), resolveFullItem);
|
|
1078
|
+
};
|
|
1079
|
+
if (property === PAIRED_ITEM_METHOD.ITEM) {
|
|
1080
|
+
return pairedItemMethod();
|
|
1155
1081
|
}
|
|
1156
|
-
return
|
|
1157
|
-
},
|
|
1158
|
-
});
|
|
1159
|
-
},
|
|
1160
|
-
$input: new Proxy({}, {
|
|
1161
|
-
has: () => true,
|
|
1162
|
-
ownKeys() {
|
|
1163
|
-
return ['all', 'context', 'first', 'item', 'last', 'params'];
|
|
1164
|
-
},
|
|
1165
|
-
getOwnPropertyDescriptor() {
|
|
1166
|
-
return {
|
|
1167
|
-
enumerable: true,
|
|
1168
|
-
configurable: true,
|
|
1169
|
-
};
|
|
1170
|
-
},
|
|
1171
|
-
get(target, property, receiver) {
|
|
1172
|
-
if (property === 'isProxy')
|
|
1173
|
-
return true;
|
|
1174
|
-
if (that.connectionInputData.length === 0) {
|
|
1175
|
-
throw createExpressionError('No execution data available', {
|
|
1176
|
-
runIndex: that.runIndex,
|
|
1177
|
-
itemIndex: that.itemIndex,
|
|
1178
|
-
type: 'no_execution_data',
|
|
1179
|
-
});
|
|
1180
|
-
}
|
|
1181
|
-
if (property === 'item') {
|
|
1182
|
-
return that.returnExecutionData(that.connectionInputData[that.itemIndex]);
|
|
1082
|
+
return pairedItemMethod;
|
|
1183
1083
|
}
|
|
1184
1084
|
if (property === 'first') {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1085
|
+
ensureNodeExecutionData();
|
|
1086
|
+
return (branchIndex, runIndex) => {
|
|
1087
|
+
branchIndex =
|
|
1088
|
+
branchIndex ??
|
|
1089
|
+
// default to the output the active node is connected to
|
|
1090
|
+
that.workflow.getNodeConnectionIndexes(that.activeNodeName, nodeName)
|
|
1091
|
+
?.sourceIndex ??
|
|
1092
|
+
0;
|
|
1093
|
+
const executionData = that.getNodeExecutionOrPinnedData({
|
|
1094
|
+
nodeName,
|
|
1095
|
+
branchIndex,
|
|
1096
|
+
runIndex,
|
|
1097
|
+
});
|
|
1098
|
+
if (executionData[0])
|
|
1099
|
+
return that.returnExecutionData(executionData[0], resolveFullItem);
|
|
1193
1100
|
return undefined;
|
|
1194
1101
|
};
|
|
1195
1102
|
}
|
|
1196
1103
|
if (property === 'last') {
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1104
|
+
ensureNodeExecutionData();
|
|
1105
|
+
return (branchIndex, runIndex) => {
|
|
1106
|
+
branchIndex =
|
|
1107
|
+
branchIndex ??
|
|
1108
|
+
// default to the output the active node is connected to
|
|
1109
|
+
that.workflow.getNodeConnectionIndexes(that.activeNodeName, nodeName)
|
|
1110
|
+
?.sourceIndex ??
|
|
1111
|
+
0;
|
|
1112
|
+
const executionData = that.getNodeExecutionOrPinnedData({
|
|
1113
|
+
nodeName,
|
|
1114
|
+
branchIndex,
|
|
1115
|
+
runIndex,
|
|
1116
|
+
});
|
|
1117
|
+
if (!executionData.length)
|
|
1118
|
+
return undefined;
|
|
1119
|
+
if (executionData[executionData.length - 1]) {
|
|
1120
|
+
return that.returnExecutionData(executionData[executionData.length - 1], resolveFullItem);
|
|
1204
1121
|
}
|
|
1205
1122
|
return undefined;
|
|
1206
1123
|
};
|
|
1207
1124
|
}
|
|
1208
1125
|
if (property === 'all') {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1126
|
+
ensureNodeExecutionData();
|
|
1127
|
+
return (branchIndex, runIndex) => {
|
|
1128
|
+
branchIndex =
|
|
1129
|
+
branchIndex ??
|
|
1130
|
+
// default to the output the active node is connected to
|
|
1131
|
+
that.workflow.getNodeConnectionIndexes(that.activeNodeName, nodeName)
|
|
1132
|
+
?.sourceIndex ??
|
|
1133
|
+
0;
|
|
1134
|
+
return that.returnExecutionData(that.getNodeExecutionOrPinnedData({
|
|
1135
|
+
nodeName,
|
|
1136
|
+
branchIndex,
|
|
1137
|
+
runIndex,
|
|
1138
|
+
}), resolveFullItem);
|
|
1215
1139
|
};
|
|
1216
1140
|
}
|
|
1217
|
-
if (
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
|
1223
|
-
functionOverrides: {
|
|
1224
|
-
message: 'Can’t get data',
|
|
1225
|
-
},
|
|
1226
|
-
description: 'Apologies, this is an internal error. See details for more information',
|
|
1227
|
-
causeDetailed: 'Missing sourceData (probably an internal error)',
|
|
1228
|
-
runIndex: that.runIndex,
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
const sourceData = that.executeData.source.main[0];
|
|
1232
|
-
if (property === 'context') {
|
|
1233
|
-
return that.nodeContextGetter(sourceData.previousNode);
|
|
1234
|
-
}
|
|
1235
|
-
if (property === 'params') {
|
|
1236
|
-
return that.workflow.getNode(sourceData.previousNode)?.parameters;
|
|
1237
|
-
}
|
|
1141
|
+
if (property === 'context') {
|
|
1142
|
+
return that.nodeContextGetter(nodeName);
|
|
1143
|
+
}
|
|
1144
|
+
if (property === 'params') {
|
|
1145
|
+
return that.workflow.getNode(nodeName)?.parameters;
|
|
1238
1146
|
}
|
|
1239
1147
|
return Reflect.get(target, property, receiver);
|
|
1240
1148
|
},
|
|
1241
|
-
})
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
throw new expression_error_1.ExpressionError("$evaluateExpression can't be used in the Code node while task runners run in secure mode", {
|
|
1248
|
-
description: 'Secure-mode task runners disable evaluating strings as code, which expressions rely on. Evaluate the expression in a node field instead, for example an Edit Fields (Set) node before the Code node.',
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
itemIndex = itemIndex || that.itemIndex;
|
|
1252
|
-
return that.workflow.expression.getParameterValue(`=${expression}`, that.runExecutionData, that.runIndex, itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
1253
|
-
},
|
|
1254
|
-
// this is legacy syntax that is not documented
|
|
1255
|
-
$item: (itemIndex, runIndex) => {
|
|
1256
|
-
const defaultReturnRunIndex = runIndex === undefined ? -1 : runIndex;
|
|
1257
|
-
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData, that.siblingParameters, that.mode, that.additionalKeys, that.executeData, defaultReturnRunIndex, {}, that.contextNodeName);
|
|
1258
|
-
return dataProxy.getDataProxy();
|
|
1149
|
+
});
|
|
1150
|
+
},
|
|
1151
|
+
$input: new Proxy({}, {
|
|
1152
|
+
has: () => true,
|
|
1153
|
+
ownKeys() {
|
|
1154
|
+
return ['all', 'context', 'first', 'item', 'last', 'params'];
|
|
1259
1155
|
},
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
$items: (nodeName, outputIndex, runIndex) => {
|
|
1266
|
-
if (nodeName === undefined) {
|
|
1267
|
-
nodeName = that.prevNodeGetter().name;
|
|
1268
|
-
const node = this.workflow.nodes[nodeName];
|
|
1269
|
-
let result = that.connectionInputData;
|
|
1270
|
-
if (node.executeOnce === true) {
|
|
1271
|
-
result = result.slice(0, 1);
|
|
1272
|
-
}
|
|
1273
|
-
if (result.length) {
|
|
1274
|
-
return result;
|
|
1275
|
-
}
|
|
1276
|
-
return [];
|
|
1277
|
-
}
|
|
1278
|
-
outputIndex = outputIndex || 0;
|
|
1279
|
-
runIndex = runIndex === undefined ? -1 : runIndex;
|
|
1280
|
-
return that.getNodeExecutionData(nodeName, false, outputIndex, runIndex);
|
|
1156
|
+
getOwnPropertyDescriptor() {
|
|
1157
|
+
return {
|
|
1158
|
+
enumerable: true,
|
|
1159
|
+
configurable: true,
|
|
1160
|
+
};
|
|
1281
1161
|
},
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
$node: this.nodeGetter(),
|
|
1285
|
-
$self: this.selfGetter(),
|
|
1286
|
-
$parameter: this.nodeParameterGetter(this.activeNodeName),
|
|
1287
|
-
$rawParameter: this.nodeParameterGetter(this.activeNodeName, false),
|
|
1288
|
-
$prevNode: this.prevNodeGetter(),
|
|
1289
|
-
$runIndex: this.runIndex,
|
|
1290
|
-
$mode: this.mode,
|
|
1291
|
-
$workflow: this.workflowGetter(),
|
|
1292
|
-
$itemIndex: this.itemIndex,
|
|
1293
|
-
$now: luxon_1.DateTime.now(),
|
|
1294
|
-
$today: luxon_1.DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }),
|
|
1295
|
-
$jmesPath: jmespathWrapper,
|
|
1296
|
-
DateTime: luxon_1.DateTime,
|
|
1297
|
-
Interval: luxon_1.Interval,
|
|
1298
|
-
Duration: luxon_1.Duration,
|
|
1299
|
-
...that.additionalKeys,
|
|
1300
|
-
$getPairedItem: getPairedItem,
|
|
1301
|
-
// deprecated
|
|
1302
|
-
$jmespath: jmespathWrapper,
|
|
1303
|
-
$position: this.itemIndex,
|
|
1304
|
-
$thisItem: that.connectionInputData[that.itemIndex],
|
|
1305
|
-
$thisItemIndex: this.itemIndex,
|
|
1306
|
-
$thisRunIndex: this.runIndex,
|
|
1307
|
-
$nodeVersion: that.workflow.getNode(that.activeNodeName)?.typeVersion,
|
|
1308
|
-
$nodeId: that.workflow.getNode(that.activeNodeName)?.id,
|
|
1309
|
-
$agentInfo: this.agentInfo(),
|
|
1310
|
-
$webhookId: that.workflow.getNode(that.activeNodeName)?.webhookId,
|
|
1311
|
-
};
|
|
1312
|
-
const throwOnMissingExecutionData = opts?.throwOnMissingExecutionData ?? true;
|
|
1313
|
-
return new Proxy(base, {
|
|
1314
|
-
has: () => true,
|
|
1315
|
-
get(target, name, receiver) {
|
|
1316
|
-
if (name === 'isProxy')
|
|
1162
|
+
get(target, property, receiver) {
|
|
1163
|
+
if (property === 'isProxy')
|
|
1317
1164
|
return true;
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1165
|
+
if (that.connectionInputData.length === 0) {
|
|
1166
|
+
throw createExpressionError('No execution data available', {
|
|
1167
|
+
runIndex: that.runIndex,
|
|
1168
|
+
itemIndex: that.itemIndex,
|
|
1169
|
+
type: 'no_execution_data',
|
|
1170
|
+
});
|
|
1321
1171
|
}
|
|
1322
|
-
if (
|
|
1323
|
-
return that.
|
|
1172
|
+
if (property === 'item') {
|
|
1173
|
+
return that.returnExecutionData(that.connectionInputData[that.itemIndex]);
|
|
1324
1174
|
}
|
|
1325
|
-
if (
|
|
1326
|
-
return
|
|
1327
|
-
|
|
1175
|
+
if (property === 'first') {
|
|
1176
|
+
return (...args) => {
|
|
1177
|
+
if (args.length) {
|
|
1178
|
+
throw createExpressionError("$input.first() takes no arguments. To get items from a specific upstream node, use $('NodeName').first() (or $('NodeName').all() for every item).");
|
|
1179
|
+
}
|
|
1180
|
+
const result = that.connectionInputData;
|
|
1181
|
+
if (result[0]) {
|
|
1182
|
+
return that.returnExecutionData(result[0]);
|
|
1183
|
+
}
|
|
1184
|
+
return undefined;
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
if (property === 'last') {
|
|
1188
|
+
return (...args) => {
|
|
1189
|
+
if (args.length) {
|
|
1190
|
+
throw createExpressionError("$input.last() takes no arguments. To get items from a specific upstream node, use $('NodeName').last() (or $('NodeName').all() for every item).");
|
|
1191
|
+
}
|
|
1192
|
+
const result = that.connectionInputData;
|
|
1193
|
+
if (result.length && result[result.length - 1]) {
|
|
1194
|
+
return that.returnExecutionData(result[result.length - 1]);
|
|
1195
|
+
}
|
|
1196
|
+
return undefined;
|
|
1197
|
+
};
|
|
1328
1198
|
}
|
|
1329
|
-
if (
|
|
1330
|
-
return
|
|
1199
|
+
if (property === 'all') {
|
|
1200
|
+
return () => {
|
|
1201
|
+
const result = that.connectionInputData;
|
|
1202
|
+
if (result.length) {
|
|
1203
|
+
return that.returnExecutionData(result);
|
|
1204
|
+
}
|
|
1205
|
+
return [];
|
|
1206
|
+
};
|
|
1331
1207
|
}
|
|
1332
|
-
|
|
1208
|
+
if (['context', 'params'].includes(property)) {
|
|
1209
|
+
// For the following properties we need the source data so fail in case it is missing
|
|
1210
|
+
// for some reason (even though that should actually never happen)
|
|
1211
|
+
if (!that.executeData?.source) {
|
|
1212
|
+
throw createExpressionError('Can’t get data for expression', {
|
|
1213
|
+
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’ field',
|
|
1214
|
+
functionOverrides: {
|
|
1215
|
+
message: 'Can’t get data',
|
|
1216
|
+
},
|
|
1217
|
+
description: 'Apologies, this is an internal error. See details for more information',
|
|
1218
|
+
causeDetailed: 'Missing sourceData (probably an internal error)',
|
|
1219
|
+
runIndex: that.runIndex,
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
const sourceData = that.executeData.source.main[0];
|
|
1223
|
+
if (property === 'context') {
|
|
1224
|
+
return that.nodeContextGetter(sourceData.previousNode);
|
|
1225
|
+
}
|
|
1226
|
+
if (property === 'params') {
|
|
1227
|
+
return that.workflow.getNode(sourceData.previousNode)?.parameters;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
return Reflect.get(target, property, receiver);
|
|
1333
1231
|
},
|
|
1334
|
-
})
|
|
1335
|
-
|
|
1232
|
+
}),
|
|
1233
|
+
$binary: {}, // Placeholder
|
|
1234
|
+
$data: {}, // Placeholder
|
|
1235
|
+
$env: (0, workflow_data_proxy_env_provider_1.createEnvProvider)(that.runIndex, that.itemIndex, that.envProviderState ?? (0, workflow_data_proxy_env_provider_1.createEnvProviderState)()),
|
|
1236
|
+
$evaluateExpression: (expression, itemIndex) => {
|
|
1237
|
+
if (!isCodeGenerationAllowed()) {
|
|
1238
|
+
throw new expression_error_1.ExpressionError("$evaluateExpression can't be used in the Code node while task runners run in secure mode", {
|
|
1239
|
+
description: 'Secure-mode task runners disable evaluating strings as code, which expressions rely on. Evaluate the expression in a node field instead, for example an Edit Fields (Set) node before the Code node.',
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
itemIndex = itemIndex || that.itemIndex;
|
|
1243
|
+
return that.workflow.expression.getParameterValue(`=${expression}`, that.runExecutionData, that.runIndex, itemIndex, that.activeNodeName, that.connectionInputData, that.mode, that.additionalKeys, that.executeData, false, {}, that.contextNodeName);
|
|
1244
|
+
},
|
|
1245
|
+
// this is legacy syntax that is not documented
|
|
1246
|
+
$item: (itemIndex, runIndex) => {
|
|
1247
|
+
const defaultReturnRunIndex = runIndex === undefined ? -1 : runIndex;
|
|
1248
|
+
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData, that.siblingParameters, that.mode, that.additionalKeys, that.executeData, defaultReturnRunIndex, {}, that.contextNodeName);
|
|
1249
|
+
return dataProxy.getDataProxy();
|
|
1250
|
+
},
|
|
1251
|
+
$fromAI: handleFromAi,
|
|
1252
|
+
// Make sure mis-capitalized $fromAI is handled correctly even though we don't auto-complete it
|
|
1253
|
+
$fromai: handleFromAi,
|
|
1254
|
+
$fromAi: handleFromAi,
|
|
1255
|
+
// this is a legacy syntax that is not documented
|
|
1256
|
+
$items: (nodeName, outputIndex, runIndex) => {
|
|
1257
|
+
if (nodeName === undefined) {
|
|
1258
|
+
nodeName = that.prevNodeGetter().name;
|
|
1259
|
+
const node = this.workflow.nodes[nodeName];
|
|
1260
|
+
let result = that.connectionInputData;
|
|
1261
|
+
if (node.executeOnce === true) {
|
|
1262
|
+
result = result.slice(0, 1);
|
|
1263
|
+
}
|
|
1264
|
+
if (result.length) {
|
|
1265
|
+
return result;
|
|
1266
|
+
}
|
|
1267
|
+
return [];
|
|
1268
|
+
}
|
|
1269
|
+
outputIndex = outputIndex || 0;
|
|
1270
|
+
runIndex = runIndex === undefined ? -1 : runIndex;
|
|
1271
|
+
return that.getNodeExecutionData(nodeName, false, outputIndex, runIndex);
|
|
1272
|
+
},
|
|
1273
|
+
$tool: {}, // Placeholder
|
|
1274
|
+
$json: {}, // Placeholder
|
|
1275
|
+
$node: this.nodeGetter(),
|
|
1276
|
+
$self: this.selfGetter(),
|
|
1277
|
+
$parameter: this.nodeParameterGetter(this.activeNodeName),
|
|
1278
|
+
$rawParameter: this.nodeParameterGetter(this.activeNodeName, false),
|
|
1279
|
+
$prevNode: this.prevNodeGetter(),
|
|
1280
|
+
$runIndex: this.runIndex,
|
|
1281
|
+
$mode: this.mode,
|
|
1282
|
+
$workflow: this.workflowGetter(),
|
|
1283
|
+
$itemIndex: this.itemIndex,
|
|
1284
|
+
$now: luxon_1.DateTime.now(),
|
|
1285
|
+
$today: luxon_1.DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }),
|
|
1286
|
+
$jmesPath: jmespathWrapper,
|
|
1287
|
+
DateTime: luxon_1.DateTime,
|
|
1288
|
+
Interval: luxon_1.Interval,
|
|
1289
|
+
Duration: luxon_1.Duration,
|
|
1290
|
+
...that.additionalKeys,
|
|
1291
|
+
$getPairedItem: getPairedItem,
|
|
1292
|
+
// deprecated
|
|
1293
|
+
$jmespath: jmespathWrapper,
|
|
1294
|
+
$position: this.itemIndex,
|
|
1295
|
+
$thisItem: that.connectionInputData[that.itemIndex],
|
|
1296
|
+
$thisItemIndex: this.itemIndex,
|
|
1297
|
+
$thisRunIndex: this.runIndex,
|
|
1298
|
+
$nodeVersion: that.workflow.getNode(that.activeNodeName)?.typeVersion,
|
|
1299
|
+
$nodeId: that.workflow.getNode(that.activeNodeName)?.id,
|
|
1300
|
+
$agentInfo: this.agentInfo(),
|
|
1301
|
+
$webhookId: that.workflow.getNode(that.activeNodeName)?.webhookId,
|
|
1302
|
+
};
|
|
1303
|
+
const throwOnMissingExecutionData = opts?.throwOnMissingExecutionData ?? true;
|
|
1304
|
+
return new Proxy(base, {
|
|
1305
|
+
has: () => true,
|
|
1306
|
+
get(target, name, receiver) {
|
|
1307
|
+
if (name === 'isProxy')
|
|
1308
|
+
return true;
|
|
1309
|
+
const JSON_ACCESS_KEYS = ['$data', '$json'];
|
|
1310
|
+
if (that.workflow.settings?.binaryMode === constants_1.BINARY_MODE_COMBINED) {
|
|
1311
|
+
JSON_ACCESS_KEYS.push('$item');
|
|
1312
|
+
}
|
|
1313
|
+
if (typeof name === 'string' && JSON_ACCESS_KEYS.includes(name)) {
|
|
1314
|
+
return that.nodeDataGetter(that.contextNodeName, true, throwOnMissingExecutionData)?.json;
|
|
1315
|
+
}
|
|
1316
|
+
if (name === '$binary') {
|
|
1317
|
+
return that.nodeDataGetter(that.contextNodeName, true, throwOnMissingExecutionData)
|
|
1318
|
+
?.binary;
|
|
1319
|
+
}
|
|
1320
|
+
if (name === '$tool') {
|
|
1321
|
+
return handleTool(throwOnMissingExecutionData);
|
|
1322
|
+
}
|
|
1323
|
+
return Reflect.get(target, name, receiver);
|
|
1324
|
+
},
|
|
1325
|
+
});
|
|
1336
1326
|
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1327
|
+
}
|
|
1328
|
+
exports.WorkflowDataProxy = WorkflowDataProxy;
|
|
1339
1329
|
//# sourceMappingURL=workflow-data-proxy.js.map
|