n8n-workflow 2.31.3 → 2.32.1
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 +9 -8
|
@@ -1,485 +1,475 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return acc;
|
|
24
|
-
switch (node.type) {
|
|
25
|
-
case 'Identifier': {
|
|
26
|
-
if (typeof node.name === 'string')
|
|
27
|
-
acc.push(node.name);
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizer = exports.PrototypeSanitizer = exports.DollarSignValidator = exports.ThisSanitizer = exports.DOLLAR_SIGN_ERROR = exports.sanitizerName = void 0;
|
|
4
|
+
const tournament_1 = require("@n8n/tournament");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
exports.sanitizerName = '__sanitize';
|
|
8
|
+
const sanitizerIdentifier = tournament_1.astBuilders.identifier(exports.sanitizerName);
|
|
9
|
+
const DATA_NODE_NAME = '___n8n_data';
|
|
10
|
+
const RESERVED_VARIABLE_NAMES = new Set([DATA_NODE_NAME, exports.sanitizerName]);
|
|
11
|
+
const isAstNode = (value) => typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string';
|
|
12
|
+
const getBoundIdentifiers = (node, acc = []) => {
|
|
13
|
+
if (!isAstNode(node))
|
|
14
|
+
return acc;
|
|
15
|
+
switch (node.type) {
|
|
16
|
+
case 'Identifier': {
|
|
17
|
+
if (typeof node.name === 'string')
|
|
18
|
+
acc.push(node.name);
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
case 'ObjectPattern': {
|
|
22
|
+
if (!Array.isArray(node.properties))
|
|
28
23
|
break;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (!isAstNode(property))
|
|
35
|
-
continue;
|
|
36
|
-
if (property.type === 'Property') {
|
|
37
|
-
getBoundIdentifiers(property.value, acc);
|
|
38
|
-
}
|
|
39
|
-
else if (property.type === 'RestElement') {
|
|
40
|
-
getBoundIdentifiers(property.argument, acc);
|
|
41
|
-
}
|
|
24
|
+
for (const property of node.properties) {
|
|
25
|
+
if (!isAstNode(property))
|
|
26
|
+
continue;
|
|
27
|
+
if (property.type === 'Property') {
|
|
28
|
+
getBoundIdentifiers(property.value, acc);
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
case 'ArrayPattern': {
|
|
46
|
-
if (!Array.isArray(node.elements))
|
|
47
|
-
break;
|
|
48
|
-
for (const element of node.elements) {
|
|
49
|
-
getBoundIdentifiers(element, acc);
|
|
30
|
+
else if (property.type === 'RestElement') {
|
|
31
|
+
getBoundIdentifiers(property.argument, acc);
|
|
50
32
|
}
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
case 'AssignmentPattern': {
|
|
54
|
-
getBoundIdentifiers(node.left, acc);
|
|
55
|
-
break;
|
|
56
33
|
}
|
|
57
|
-
|
|
58
|
-
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'ArrayPattern': {
|
|
37
|
+
if (!Array.isArray(node.elements))
|
|
59
38
|
break;
|
|
39
|
+
for (const element of node.elements) {
|
|
40
|
+
getBoundIdentifiers(element, acc);
|
|
60
41
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case 'AssignmentPattern': {
|
|
45
|
+
getBoundIdentifiers(node.left, acc);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case 'RestElement': {
|
|
49
|
+
getBoundIdentifiers(node.argument, acc);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'VariableDeclaration': {
|
|
53
|
+
if (!Array.isArray(node.declarations))
|
|
69
54
|
break;
|
|
55
|
+
for (const declaration of node.declarations) {
|
|
56
|
+
if (!isAstNode(declaration) || declaration.type !== 'VariableDeclarator')
|
|
57
|
+
continue;
|
|
58
|
+
getBoundIdentifiers(declaration.id, acc);
|
|
70
59
|
}
|
|
60
|
+
break;
|
|
71
61
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
])
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
const fnExpression = node.callee;
|
|
128
|
-
/**
|
|
129
|
-
* Called function expressions (IIFEs) - both anonymous and named:
|
|
130
|
-
*
|
|
131
|
-
* ```js
|
|
132
|
-
* (function(x) { return x * 2; })(5)
|
|
133
|
-
* (function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); })(5)
|
|
134
|
-
*
|
|
135
|
-
* // become
|
|
136
|
-
*
|
|
137
|
-
* (function(x) { return x * 2; }).call({ process: {} }, 5)
|
|
138
|
-
* (function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); }).call({ process: {} }, 5)
|
|
139
|
-
* ```
|
|
140
|
-
*/
|
|
141
|
-
this.traverse(path); // depth first to transform inside out
|
|
142
|
-
const callExpression = tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(fnExpression, tournament_1.astBuilders.identifier('call')), [EMPTY_CONTEXT, ...node.arguments]);
|
|
143
|
-
path.replace(callExpression);
|
|
144
|
-
return false;
|
|
145
|
-
},
|
|
146
|
-
visitFunctionExpression(path) {
|
|
147
|
-
const { node } = path;
|
|
148
|
-
/**
|
|
149
|
-
* Callable function expressions (callbacks) - both anonymous and named:
|
|
150
|
-
*
|
|
151
|
-
* ```js
|
|
152
|
-
* [1, 2, 3].map(function(n) { return n * 2; })
|
|
153
|
-
* [1, 2, 3].map(function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); })
|
|
154
|
-
*
|
|
155
|
-
* // become
|
|
156
|
-
*
|
|
157
|
-
* [1, 2, 3].map((function(n) { return n * 2; }).bind({ process: {} }))
|
|
158
|
-
* [1, 2, 3].map((function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); }).bind({ process: {} }))
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
|
-
this.traverse(path);
|
|
162
|
-
const boundFunction = tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(node, tournament_1.astBuilders.identifier('bind')), [
|
|
163
|
-
EMPTY_CONTEXT,
|
|
164
|
-
]);
|
|
165
|
-
path.replace(boundFunction);
|
|
166
|
-
return false;
|
|
167
|
-
},
|
|
168
|
-
visitIdentifier(path) {
|
|
169
|
-
this.traverse(path);
|
|
170
|
-
const { node } = path;
|
|
171
|
-
if (GLOBAL_IDENTIFIERS.has(node.name)) {
|
|
172
|
-
const parent = path.parent;
|
|
173
|
-
const isPropertyName = typeof parent === 'object' &&
|
|
174
|
-
parent !== null &&
|
|
175
|
-
'name' in parent &&
|
|
176
|
-
parent.name === 'property';
|
|
177
|
-
if (!isPropertyName)
|
|
178
|
-
path.replace(SAFE_GLOBAL);
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
visitThisExpression(path) {
|
|
182
|
-
this.traverse(path);
|
|
183
|
-
/**
|
|
184
|
-
* Replace `this` with a safe context object.
|
|
185
|
-
* This prevents arrow functions from accessing the real global context:
|
|
186
|
-
*
|
|
187
|
-
* ```js
|
|
188
|
-
* (() => this?.process)() // becomes (() => (0, { process: {} })?.process)()
|
|
189
|
-
* ```
|
|
190
|
-
*
|
|
191
|
-
* Arrow functions don't have their own `this` binding - they inherit from
|
|
192
|
-
* the outer lexical scope. Without this fix, `this` inside an arrow function
|
|
193
|
-
* would resolve to the Node.js global object, exposing process.env and other
|
|
194
|
-
* sensitive data.
|
|
195
|
-
*
|
|
196
|
-
* We use SAFE_THIS (a sequence expression) instead of EMPTY_CONTEXT directly
|
|
197
|
-
* to ensure the object literal is unambiguously parsed as an expression.
|
|
198
|
-
*/
|
|
199
|
-
path.replace(SAFE_THIS);
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
};
|
|
203
|
-
exports.ThisSanitizer = ThisSanitizer;
|
|
204
|
-
/**
|
|
205
|
-
* Validates that the $ identifier is only used in allowed contexts.
|
|
206
|
-
* This prevents user errors like `{{ $ }}` which would return the function object itself.
|
|
207
|
-
*
|
|
208
|
-
* Allowed contexts:
|
|
209
|
-
* - As a function call: $()
|
|
210
|
-
* - As a property name: obj.$ (where $ is a valid property name in JavaScript)
|
|
211
|
-
*
|
|
212
|
-
* Disallowed contexts:
|
|
213
|
-
* - Bare identifier: $
|
|
214
|
-
* - As object in member expression: $.property
|
|
215
|
-
* - In expressions: "prefix" + $, [1, 2, $], etc.
|
|
216
|
-
*/
|
|
217
|
-
const DollarSignValidator = (ast, _dataNode) => {
|
|
218
|
-
(0, tournament_1.astVisit)(ast, {
|
|
219
|
-
visitIdentifier(path) {
|
|
62
|
+
}
|
|
63
|
+
return acc;
|
|
64
|
+
};
|
|
65
|
+
const getReservedIdentifier = (node) => getBoundIdentifiers(node).find((name) => RESERVED_VARIABLE_NAMES.has(name));
|
|
66
|
+
exports.DOLLAR_SIGN_ERROR = 'Cannot access "$" without calling it as a function';
|
|
67
|
+
const EMPTY_CONTEXT = tournament_1.astBuilders.objectExpression([
|
|
68
|
+
tournament_1.astBuilders.property('init', tournament_1.astBuilders.identifier('process'), tournament_1.astBuilders.objectExpression([])),
|
|
69
|
+
tournament_1.astBuilders.property('init', tournament_1.astBuilders.identifier('require'), tournament_1.astBuilders.objectExpression([])),
|
|
70
|
+
tournament_1.astBuilders.property('init', tournament_1.astBuilders.identifier('module'), tournament_1.astBuilders.objectExpression([])),
|
|
71
|
+
tournament_1.astBuilders.property('init', tournament_1.astBuilders.identifier('Buffer'), tournament_1.astBuilders.objectExpression([])),
|
|
72
|
+
]);
|
|
73
|
+
const SAFE_GLOBAL = tournament_1.astBuilders.objectExpression([]);
|
|
74
|
+
const SAFE_THIS = tournament_1.astBuilders.sequenceExpression([tournament_1.astBuilders.literal(0), EMPTY_CONTEXT]);
|
|
75
|
+
/**
|
|
76
|
+
* Helper to check if an expression is a valid property access with $ as the property.
|
|
77
|
+
* Returns true for obj.$ or obj.nested.$ but false for bare $ or other expression contexts.
|
|
78
|
+
*/
|
|
79
|
+
const isValidDollarPropertyAccess = (expr) => {
|
|
80
|
+
if (typeof expr !== 'object' ||
|
|
81
|
+
expr === null ||
|
|
82
|
+
!('type' in expr) ||
|
|
83
|
+
expr.type !== 'MemberExpression' ||
|
|
84
|
+
!('property' in expr) ||
|
|
85
|
+
!('object' in expr)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const property = expr.property;
|
|
89
|
+
const object = expr.object;
|
|
90
|
+
// $ must be the property
|
|
91
|
+
const isPropertyDollar = typeof property === 'object' &&
|
|
92
|
+
property !== null &&
|
|
93
|
+
'name' in property &&
|
|
94
|
+
property.name === '$';
|
|
95
|
+
// $ must NOT be the object (to block $.something)
|
|
96
|
+
const isObjectDollar = typeof object === 'object' && object !== null && 'name' in object && object.name === '$';
|
|
97
|
+
// Object must be an Identifier (obj) or MemberExpression (obj.nested)
|
|
98
|
+
// This excludes bare $ or $ in other expression contexts
|
|
99
|
+
const isObjectValid = typeof object === 'object' &&
|
|
100
|
+
object !== null &&
|
|
101
|
+
'type' in object &&
|
|
102
|
+
(object.type === 'Identifier' || object.type === 'MemberExpression');
|
|
103
|
+
return isPropertyDollar && !isObjectDollar && isObjectValid;
|
|
104
|
+
};
|
|
105
|
+
const GLOBAL_IDENTIFIERS = new Set(['globalThis']);
|
|
106
|
+
const BLOCKED_SPREAD_GLOBALS = new Set(['process', 'global', 'globalThis', 'Buffer']);
|
|
107
|
+
/**
|
|
108
|
+
* Prevents regular functions from binding their `this` to the Node.js global.
|
|
109
|
+
*/
|
|
110
|
+
const ThisSanitizer = (ast, dataNode) => {
|
|
111
|
+
(0, tournament_1.astVisit)(ast, {
|
|
112
|
+
visitCallExpression(path) {
|
|
113
|
+
const { node } = path;
|
|
114
|
+
if (node.callee.type !== 'FunctionExpression') {
|
|
220
115
|
this.traverse(path);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const fnExpression = node.callee;
|
|
119
|
+
/**
|
|
120
|
+
* Called function expressions (IIFEs) - both anonymous and named:
|
|
121
|
+
*
|
|
122
|
+
* ```js
|
|
123
|
+
* (function(x) { return x * 2; })(5)
|
|
124
|
+
* (function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); })(5)
|
|
125
|
+
*
|
|
126
|
+
* // become
|
|
127
|
+
*
|
|
128
|
+
* (function(x) { return x * 2; }).call({ process: {} }, 5)
|
|
129
|
+
* (function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); }).call({ process: {} }, 5)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
this.traverse(path); // depth first to transform inside out
|
|
133
|
+
const callExpression = tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(fnExpression, tournament_1.astBuilders.identifier('call')), [EMPTY_CONTEXT, ...node.arguments]);
|
|
134
|
+
path.replace(callExpression);
|
|
135
|
+
return false;
|
|
136
|
+
},
|
|
137
|
+
visitFunctionExpression(path) {
|
|
138
|
+
const { node } = path;
|
|
139
|
+
/**
|
|
140
|
+
* Callable function expressions (callbacks) - both anonymous and named:
|
|
141
|
+
*
|
|
142
|
+
* ```js
|
|
143
|
+
* [1, 2, 3].map(function(n) { return n * 2; })
|
|
144
|
+
* [1, 2, 3].map(function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); })
|
|
145
|
+
*
|
|
146
|
+
* // become
|
|
147
|
+
*
|
|
148
|
+
* [1, 2, 3].map((function(n) { return n * 2; }).bind({ process: {} }))
|
|
149
|
+
* [1, 2, 3].map((function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); }).bind({ process: {} }))
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
this.traverse(path);
|
|
153
|
+
const boundFunction = tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(node, tournament_1.astBuilders.identifier('bind')), [
|
|
154
|
+
EMPTY_CONTEXT,
|
|
155
|
+
]);
|
|
156
|
+
path.replace(boundFunction);
|
|
157
|
+
return false;
|
|
158
|
+
},
|
|
159
|
+
visitIdentifier(path) {
|
|
160
|
+
this.traverse(path);
|
|
161
|
+
const { node } = path;
|
|
162
|
+
if (GLOBAL_IDENTIFIERS.has(node.name)) {
|
|
226
163
|
const parent = path.parent;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
164
|
+
const isPropertyName = typeof parent === 'object' &&
|
|
165
|
+
parent !== null &&
|
|
166
|
+
'name' in parent &&
|
|
167
|
+
parent.name === 'property';
|
|
168
|
+
if (!isPropertyName)
|
|
169
|
+
path.replace(SAFE_GLOBAL);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
visitThisExpression(path) {
|
|
173
|
+
this.traverse(path);
|
|
174
|
+
/**
|
|
175
|
+
* Replace `this` with a safe context object.
|
|
176
|
+
* This prevents arrow functions from accessing the real global context:
|
|
177
|
+
*
|
|
178
|
+
* ```js
|
|
179
|
+
* (() => this?.process)() // becomes (() => (0, { process: {} })?.process)()
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* Arrow functions don't have their own `this` binding - they inherit from
|
|
183
|
+
* the outer lexical scope. Without this fix, `this` inside an arrow function
|
|
184
|
+
* would resolve to the Node.js global object, exposing process.env and other
|
|
185
|
+
* sensitive data.
|
|
186
|
+
*
|
|
187
|
+
* We use SAFE_THIS (a sequence expression) instead of EMPTY_CONTEXT directly
|
|
188
|
+
* to ensure the object literal is unambiguously parsed as an expression.
|
|
189
|
+
*/
|
|
190
|
+
path.replace(SAFE_THIS);
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
exports.ThisSanitizer = ThisSanitizer;
|
|
195
|
+
/**
|
|
196
|
+
* Validates that the $ identifier is only used in allowed contexts.
|
|
197
|
+
* This prevents user errors like `{{ $ }}` which would return the function object itself.
|
|
198
|
+
*
|
|
199
|
+
* Allowed contexts:
|
|
200
|
+
* - As a function call: $()
|
|
201
|
+
* - As a property name: obj.$ (where $ is a valid property name in JavaScript)
|
|
202
|
+
*
|
|
203
|
+
* Disallowed contexts:
|
|
204
|
+
* - Bare identifier: $
|
|
205
|
+
* - As object in member expression: $.property
|
|
206
|
+
* - In expressions: "prefix" + $, [1, 2, $], etc.
|
|
207
|
+
*/
|
|
208
|
+
const DollarSignValidator = (ast, _dataNode) => {
|
|
209
|
+
(0, tournament_1.astVisit)(ast, {
|
|
210
|
+
visitIdentifier(path) {
|
|
211
|
+
this.traverse(path);
|
|
212
|
+
const node = path.node;
|
|
213
|
+
// Only check for the exact identifier '$'
|
|
214
|
+
if (node.name !== '$')
|
|
215
|
+
return;
|
|
216
|
+
// Runtime type checking since path properties are typed as 'any'
|
|
217
|
+
const parent = path.parent;
|
|
218
|
+
// Check if parent is a path object with a 'name' property
|
|
219
|
+
if (typeof parent !== 'object' || parent === null || !('name' in parent)) {
|
|
220
|
+
throw new errors_1.ExpressionError(exports.DOLLAR_SIGN_ERROR);
|
|
221
|
+
}
|
|
222
|
+
// Allow $ when it's the callee: $()
|
|
223
|
+
// parent.name === 'callee' means the parent path represents the callee field
|
|
224
|
+
if (parent.name === 'callee') {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// Block when $ is the object in a MemberExpression: $.something
|
|
228
|
+
// parent.name === 'object' means the parent path represents the object field
|
|
229
|
+
if (parent.name === 'object') {
|
|
230
|
+
throw new errors_1.ExpressionError(exports.DOLLAR_SIGN_ERROR);
|
|
231
|
+
}
|
|
232
|
+
// Check if $ is the property of a MemberExpression: obj.$
|
|
233
|
+
// For obj.$: parent.name is 'expression' and grandparent has ExpressionStatement
|
|
234
|
+
// The ExpressionStatement should contain a MemberExpression with $ as property
|
|
235
|
+
if ('parent' in parent && typeof parent.parent === 'object' && parent.parent !== null) {
|
|
236
|
+
const grandparent = parent.parent;
|
|
237
|
+
if ('value' in grandparent &&
|
|
238
|
+
typeof grandparent.value === 'object' &&
|
|
239
|
+
grandparent.value !== null) {
|
|
240
|
+
const gpNode = grandparent.value;
|
|
241
|
+
// ExpressionStatement has an 'expression' field containing the actual expression
|
|
242
|
+
if ('type' in gpNode && gpNode.type === 'ExpressionStatement' && 'expression' in gpNode) {
|
|
243
|
+
// Check if this is a valid property access like obj.$
|
|
244
|
+
if (isValidDollarPropertyAccess(gpNode.expression)) {
|
|
245
|
+
return;
|
|
256
246
|
}
|
|
257
247
|
}
|
|
258
248
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
|
|
249
|
+
}
|
|
250
|
+
// Disallow all other cases (bare $, $ in expressions, etc.)
|
|
251
|
+
throw new errors_1.ExpressionError(exports.DOLLAR_SIGN_ERROR);
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
exports.DollarSignValidator = DollarSignValidator;
|
|
256
|
+
const blockedBaseClasses = new Set([
|
|
257
|
+
'Function',
|
|
258
|
+
'GeneratorFunction',
|
|
259
|
+
'AsyncFunction',
|
|
260
|
+
'AsyncGeneratorFunction',
|
|
261
|
+
]);
|
|
262
|
+
/**
|
|
263
|
+
* Builds an AST node that safely resolves a spread argument like `...process`.
|
|
264
|
+
*
|
|
265
|
+
* Tournament's VariablePolyfill rewrites plain identifiers (e.g. `process`)
|
|
266
|
+
* to look them up from the data context, but it does NOT handle identifiers
|
|
267
|
+
* inside SpreadElement / SpreadProperty nodes. Without this fix, `{...process}`
|
|
268
|
+
* would resolve to the real Node.js `process` object.
|
|
269
|
+
*
|
|
270
|
+
* The generated code checks the data context first, falling back to a throw:
|
|
271
|
+
*
|
|
272
|
+
* ("process" in data) ? data.process : (() => { throw new Error("...") })()
|
|
273
|
+
*
|
|
274
|
+
* - If the workflow has a variable called "process" → spread that (safe, user-defined)
|
|
275
|
+
* - Otherwise → throw at runtime, blocking access to the real global
|
|
276
|
+
*/
|
|
277
|
+
const buildSafeSpreadArg = (name, dataNode) => {
|
|
278
|
+
// "process" in ___n8n_data
|
|
279
|
+
const isInDataContext = tournament_1.astBuilders.binaryExpression('in', tournament_1.astBuilders.literal(name), dataNode);
|
|
280
|
+
// ___n8n_data.process
|
|
281
|
+
const readFromDataContext = tournament_1.astBuilders.memberExpression(dataNode, tournament_1.astBuilders.identifier(name));
|
|
282
|
+
// (() => { throw new Error('Cannot spread "process" ...') })()
|
|
283
|
+
//
|
|
284
|
+
// This is an IIFE because `throw` is a statement, not an expression,
|
|
285
|
+
// so it cannot appear directly inside a ternary's falsy branch.
|
|
286
|
+
const throwSecurityError = tournament_1.astBuilders.callExpression(tournament_1.astBuilders.arrowFunctionExpression([], tournament_1.astBuilders.blockStatement([
|
|
287
|
+
tournament_1.astBuilders.throwStatement(tournament_1.astBuilders.newExpression(tournament_1.astBuilders.identifier('Error'), [
|
|
288
|
+
tournament_1.astBuilders.literal(`Cannot spread "${name}" due to security concerns`),
|
|
289
|
+
])),
|
|
290
|
+
])), []);
|
|
291
|
+
// Full result:
|
|
292
|
+
// ("process" in ___n8n_data) ? ___n8n_data.process : (() => { throw ... })()
|
|
293
|
+
return tournament_1.astBuilders.conditionalExpression(isInDataContext, readFromDataContext, throwSecurityError);
|
|
294
|
+
};
|
|
295
|
+
const PrototypeSanitizer = (ast, dataNode) => {
|
|
296
|
+
(0, tournament_1.astVisit)(ast, {
|
|
297
|
+
visitVariableDeclarator(path) {
|
|
298
|
+
this.traverse(path);
|
|
299
|
+
const node = path.node;
|
|
300
|
+
const reservedIdentifier = getReservedIdentifier(node.id);
|
|
301
|
+
if (reservedIdentifier === undefined)
|
|
302
|
+
return;
|
|
303
|
+
throw new errors_1.ExpressionReservedVariableError(reservedIdentifier);
|
|
304
|
+
},
|
|
305
|
+
visitFunction(path) {
|
|
306
|
+
this.traverse(path);
|
|
307
|
+
const node = path.node;
|
|
308
|
+
const functionName = getReservedIdentifier(node.id);
|
|
309
|
+
if (functionName !== undefined) {
|
|
310
|
+
throw new errors_1.ExpressionReservedVariableError(functionName);
|
|
311
|
+
}
|
|
312
|
+
for (const param of node.params) {
|
|
313
|
+
const paramName = getReservedIdentifier(param);
|
|
314
|
+
if (paramName !== undefined) {
|
|
315
|
+
throw new errors_1.ExpressionReservedVariableError(paramName);
|
|
320
316
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
visitCatchClause(path) {
|
|
320
|
+
this.traverse(path);
|
|
321
|
+
const node = path.node;
|
|
322
|
+
const catchParamName = getReservedIdentifier(node.param);
|
|
323
|
+
if (catchParamName === undefined)
|
|
324
|
+
return;
|
|
325
|
+
throw new errors_1.ExpressionReservedVariableError(catchParamName);
|
|
326
|
+
},
|
|
327
|
+
visitClassDeclaration(path) {
|
|
328
|
+
this.traverse(path);
|
|
329
|
+
const node = path.node;
|
|
330
|
+
const className = getReservedIdentifier(node.id);
|
|
331
|
+
if (className !== undefined) {
|
|
332
|
+
throw new errors_1.ExpressionReservedVariableError(className);
|
|
333
|
+
}
|
|
334
|
+
if (node.superClass) {
|
|
335
|
+
if (node.superClass.type === 'Identifier') {
|
|
336
|
+
if (blockedBaseClasses.has(node.superClass.name)) {
|
|
337
|
+
throw new errors_1.ExpressionClassExtensionError(node.superClass.name);
|
|
325
338
|
}
|
|
326
339
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
this.traverse(path);
|
|
330
|
-
const node = path.node;
|
|
331
|
-
const catchParamName = getReservedIdentifier(node.param);
|
|
332
|
-
if (catchParamName === undefined)
|
|
333
|
-
return;
|
|
334
|
-
throw new errors_1.ExpressionReservedVariableError(catchParamName);
|
|
335
|
-
},
|
|
336
|
-
visitClassDeclaration(path) {
|
|
337
|
-
this.traverse(path);
|
|
338
|
-
const node = path.node;
|
|
339
|
-
const className = getReservedIdentifier(node.id);
|
|
340
|
-
if (className !== undefined) {
|
|
341
|
-
throw new errors_1.ExpressionReservedVariableError(className);
|
|
340
|
+
else {
|
|
341
|
+
throw new errors_1.ExpressionError('Cannot use dynamic class extension due to security concerns');
|
|
342
342
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
visitClassExpression(path) {
|
|
346
|
+
this.traverse(path);
|
|
347
|
+
const node = path.node;
|
|
348
|
+
const className = getReservedIdentifier(node.id);
|
|
349
|
+
if (className !== undefined) {
|
|
350
|
+
throw new errors_1.ExpressionReservedVariableError(className);
|
|
351
|
+
}
|
|
352
|
+
if (node.superClass) {
|
|
353
|
+
if (node.superClass.type === 'Identifier') {
|
|
354
|
+
if (blockedBaseClasses.has(node.superClass.name)) {
|
|
355
|
+
throw new errors_1.ExpressionClassExtensionError(node.superClass.name);
|
|
351
356
|
}
|
|
352
357
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
this.traverse(path);
|
|
356
|
-
const node = path.node;
|
|
357
|
-
const className = getReservedIdentifier(node.id);
|
|
358
|
-
if (className !== undefined) {
|
|
359
|
-
throw new errors_1.ExpressionReservedVariableError(className);
|
|
358
|
+
else {
|
|
359
|
+
throw new errors_1.ExpressionError('Cannot use dynamic class extension due to security concerns');
|
|
360
360
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
visitAssignmentExpression(path) {
|
|
364
|
+
this.traverse(path);
|
|
365
|
+
const node = path.node;
|
|
366
|
+
const assignedIdentifier = getReservedIdentifier(node.left);
|
|
367
|
+
if (assignedIdentifier === undefined)
|
|
368
|
+
return;
|
|
369
|
+
throw new errors_1.ExpressionReservedVariableError(assignedIdentifier);
|
|
370
|
+
},
|
|
371
|
+
visitUpdateExpression(path) {
|
|
372
|
+
this.traverse(path);
|
|
373
|
+
const node = path.node;
|
|
374
|
+
const updatedIdentifier = getReservedIdentifier(node.argument);
|
|
375
|
+
if (updatedIdentifier === undefined)
|
|
376
|
+
return;
|
|
377
|
+
throw new errors_1.ExpressionReservedVariableError(updatedIdentifier);
|
|
378
|
+
},
|
|
379
|
+
visitForOfStatement(path) {
|
|
380
|
+
this.traverse(path);
|
|
381
|
+
const node = path.node;
|
|
382
|
+
const loopBinding = getReservedIdentifier(node.left);
|
|
383
|
+
if (loopBinding === undefined)
|
|
384
|
+
return;
|
|
385
|
+
throw new errors_1.ExpressionReservedVariableError(loopBinding);
|
|
386
|
+
},
|
|
387
|
+
visitForInStatement(path) {
|
|
388
|
+
this.traverse(path);
|
|
389
|
+
const node = path.node;
|
|
390
|
+
const loopBinding = getReservedIdentifier(node.left);
|
|
391
|
+
if (loopBinding === undefined)
|
|
392
|
+
return;
|
|
393
|
+
throw new errors_1.ExpressionReservedVariableError(loopBinding);
|
|
394
|
+
},
|
|
395
|
+
visitMemberExpression(path) {
|
|
396
|
+
this.traverse(path);
|
|
397
|
+
const node = path.node;
|
|
398
|
+
if (!node.computed) {
|
|
399
|
+
// This is static, so we're safe to error here
|
|
400
|
+
if (node.property.type !== 'Identifier') {
|
|
401
|
+
throw new errors_1.ExpressionError(`Unknown property type ${node.property.type} while sanitising expression`);
|
|
370
402
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const loopBinding = getReservedIdentifier(node.left);
|
|
400
|
-
if (loopBinding === undefined)
|
|
401
|
-
return;
|
|
402
|
-
throw new errors_1.ExpressionReservedVariableError(loopBinding);
|
|
403
|
-
},
|
|
404
|
-
visitMemberExpression(path) {
|
|
405
|
-
this.traverse(path);
|
|
406
|
-
const node = path.node;
|
|
407
|
-
if (!node.computed) {
|
|
408
|
-
// This is static, so we're safe to error here
|
|
409
|
-
if (node.property.type !== 'Identifier') {
|
|
410
|
-
throw new errors_1.ExpressionError(`Unknown property type ${node.property.type} while sanitising expression`);
|
|
403
|
+
if (!(0, utils_1.isSafeObjectProperty)(node.property.name)) {
|
|
404
|
+
throw new errors_1.ExpressionError(`Cannot access "${node.property.name}" due to security concerns`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else if (node.property.type === 'StringLiteral' || node.property.type === 'Literal') {
|
|
408
|
+
// Check any static strings against our forbidden list
|
|
409
|
+
if (!(0, utils_1.isSafeObjectProperty)(node.property.value)) {
|
|
410
|
+
throw new errors_1.ExpressionError(`Cannot access "${node.property.value}" due to security concerns`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
path.replace(tournament_1.astBuilders.memberExpression(
|
|
415
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
416
|
+
node.object,
|
|
417
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
418
|
+
tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(dataNode, sanitizerIdentifier), [
|
|
419
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
420
|
+
node.property,
|
|
421
|
+
]), true));
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
visitObjectPattern(path) {
|
|
425
|
+
this.traverse(path);
|
|
426
|
+
const node = path.node;
|
|
427
|
+
for (const prop of node.properties) {
|
|
428
|
+
if (prop.type === 'Property') {
|
|
429
|
+
if (prop.computed) {
|
|
430
|
+
throw new errors_1.ExpressionComputedDestructuringError();
|
|
411
431
|
}
|
|
412
|
-
|
|
413
|
-
|
|
432
|
+
let keyName;
|
|
433
|
+
if (prop.key.type === 'Identifier') {
|
|
434
|
+
keyName = prop.key.name;
|
|
414
435
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
// Check any static strings against our forbidden list
|
|
418
|
-
if (!(0, utils_1.isSafeObjectProperty)(node.property.value)) {
|
|
419
|
-
throw new errors_1.ExpressionError(`Cannot access "${node.property.value}" due to security concerns`);
|
|
436
|
+
else if (prop.key.type === 'StringLiteral' || prop.key.type === 'Literal') {
|
|
437
|
+
keyName = String(prop.key.value);
|
|
420
438
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
path.replace(tournament_1.astBuilders.memberExpression(
|
|
424
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
425
|
-
node.object,
|
|
426
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
427
|
-
tournament_1.astBuilders.callExpression(tournament_1.astBuilders.memberExpression(dataNode, sanitizerIdentifier), [
|
|
428
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
429
|
-
node.property,
|
|
430
|
-
]), true));
|
|
431
|
-
}
|
|
432
|
-
},
|
|
433
|
-
visitObjectPattern(path) {
|
|
434
|
-
this.traverse(path);
|
|
435
|
-
const node = path.node;
|
|
436
|
-
for (const prop of node.properties) {
|
|
437
|
-
if (prop.type === 'Property') {
|
|
438
|
-
if (prop.computed) {
|
|
439
|
-
throw new errors_1.ExpressionComputedDestructuringError();
|
|
440
|
-
}
|
|
441
|
-
let keyName;
|
|
442
|
-
if (prop.key.type === 'Identifier') {
|
|
443
|
-
keyName = prop.key.name;
|
|
444
|
-
}
|
|
445
|
-
else if (prop.key.type === 'StringLiteral' || prop.key.type === 'Literal') {
|
|
446
|
-
keyName = String(prop.key.value);
|
|
447
|
-
}
|
|
448
|
-
if (keyName !== undefined && !(0, utils_1.isSafeObjectProperty)(keyName)) {
|
|
449
|
-
throw new errors_1.ExpressionDestructuringError(keyName);
|
|
450
|
-
}
|
|
439
|
+
if (keyName !== undefined && !(0, utils_1.isSafeObjectProperty)(keyName)) {
|
|
440
|
+
throw new errors_1.ExpressionDestructuringError(keyName);
|
|
451
441
|
}
|
|
452
442
|
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
visitSpreadElement(path) {
|
|
446
|
+
this.traverse(path);
|
|
447
|
+
const { argument } = path.node;
|
|
448
|
+
if (argument.type === 'Identifier' && BLOCKED_SPREAD_GLOBALS.has(argument.name)) {
|
|
449
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
450
|
+
path.node.argument = buildSafeSpreadArg(argument.name, dataNode);
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
visitSpreadProperty(path) {
|
|
454
|
+
this.traverse(path);
|
|
455
|
+
const { argument } = path.node;
|
|
456
|
+
if (argument.type === 'Identifier' && BLOCKED_SPREAD_GLOBALS.has(argument.name)) {
|
|
457
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
458
|
+
path.node.argument = buildSafeSpreadArg(argument.name, dataNode);
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
visitWithStatement() {
|
|
462
|
+
throw new errors_1.ExpressionWithStatementError();
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
};
|
|
466
|
+
exports.PrototypeSanitizer = PrototypeSanitizer;
|
|
467
|
+
const sanitizer = (value) => {
|
|
468
|
+
const propertyKey = String(value);
|
|
469
|
+
if (!(0, utils_1.isSafeObjectProperty)(propertyKey)) {
|
|
470
|
+
throw new errors_1.ExpressionError(`Cannot access "${propertyKey}" due to security concerns`);
|
|
471
|
+
}
|
|
472
|
+
return propertyKey;
|
|
473
|
+
};
|
|
474
|
+
exports.sanitizer = sanitizer;
|
|
485
475
|
//# sourceMappingURL=expression-sandboxing.js.map
|