@n8n/expression-runtime 0.14.2 → 0.14.3

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.
Files changed (91) hide show
  1. package/dist/bundle/runtime.esm.js +17 -17
  2. package/dist/bundle/runtime.esm.js.map +4 -4
  3. package/dist/bundle/runtime.iife.js +17 -17
  4. package/dist/bundle/runtime.iife.js.map +4 -4
  5. package/dist/cjs/bridge/bridge-messages.d.ts +594 -0
  6. package/dist/cjs/bridge/bridge-messages.d.ts.map +1 -0
  7. package/dist/cjs/bridge/bridge-messages.js +263 -0
  8. package/dist/cjs/bridge/bridge-messages.js.map +1 -0
  9. package/dist/cjs/bridge/isolated-vm-bridge.d.ts +134 -11
  10. package/dist/cjs/bridge/isolated-vm-bridge.d.ts.map +1 -1
  11. package/dist/cjs/bridge/isolated-vm-bridge.js +225 -50
  12. package/dist/cjs/bridge/isolated-vm-bridge.js.map +1 -1
  13. package/dist/cjs/build.tsbuildinfo +1 -1
  14. package/dist/cjs/extensions/extend.d.ts +5 -0
  15. package/dist/cjs/extensions/extend.d.ts.map +1 -1
  16. package/dist/cjs/extensions/extend.js +14 -14
  17. package/dist/cjs/extensions/extend.js.map +1 -1
  18. package/dist/cjs/pool/idle-scaling-pool.js +2 -2
  19. package/dist/cjs/pool/idle-scaling-pool.js.map +1 -1
  20. package/dist/cjs/runtime/context.d.ts +43 -4
  21. package/dist/cjs/runtime/context.d.ts.map +1 -1
  22. package/dist/cjs/runtime/context.js +183 -31
  23. package/dist/cjs/runtime/context.js.map +1 -1
  24. package/dist/cjs/runtime/index.d.ts +3 -3
  25. package/dist/cjs/runtime/index.d.ts.map +1 -1
  26. package/dist/cjs/runtime/index.js.map +1 -1
  27. package/dist/cjs/runtime/jmespath.d.ts +5 -3
  28. package/dist/cjs/runtime/jmespath.d.ts.map +1 -1
  29. package/dist/cjs/runtime/jmespath.js +5 -3
  30. package/dist/cjs/runtime/jmespath.js.map +1 -1
  31. package/dist/cjs/runtime/lazy-proxy.d.ts +7 -5
  32. package/dist/cjs/runtime/lazy-proxy.d.ts.map +1 -1
  33. package/dist/cjs/runtime/lazy-proxy.js +8 -16
  34. package/dist/cjs/runtime/lazy-proxy.js.map +1 -1
  35. package/dist/cjs/runtime/safe-globals.d.ts.map +1 -1
  36. package/dist/cjs/runtime/safe-globals.js +8 -3
  37. package/dist/cjs/runtime/safe-globals.js.map +1 -1
  38. package/dist/cjs/runtime/utils.d.ts +16 -0
  39. package/dist/cjs/runtime/utils.d.ts.map +1 -0
  40. package/dist/cjs/runtime/utils.js +31 -0
  41. package/dist/cjs/runtime/utils.js.map +1 -0
  42. package/dist/cjs/types/bridge.d.ts +2 -1
  43. package/dist/cjs/types/bridge.d.ts.map +1 -1
  44. package/dist/cjs/types/bridge.js.map +1 -1
  45. package/dist/cjs/types/evaluator.d.ts +86 -4
  46. package/dist/cjs/types/evaluator.d.ts.map +1 -1
  47. package/dist/cjs/types/evaluator.js.map +1 -1
  48. package/dist/esm/bridge/bridge-messages.d.ts +594 -0
  49. package/dist/esm/bridge/bridge-messages.d.ts.map +1 -0
  50. package/dist/esm/bridge/bridge-messages.js +250 -0
  51. package/dist/esm/bridge/bridge-messages.js.map +1 -0
  52. package/dist/esm/bridge/isolated-vm-bridge.d.ts +134 -11
  53. package/dist/esm/bridge/isolated-vm-bridge.d.ts.map +1 -1
  54. package/dist/esm/bridge/isolated-vm-bridge.js +224 -49
  55. package/dist/esm/bridge/isolated-vm-bridge.js.map +1 -1
  56. package/dist/esm/build.tsbuildinfo +1 -1
  57. package/dist/esm/extensions/extend.d.ts +5 -0
  58. package/dist/esm/extensions/extend.d.ts.map +1 -1
  59. package/dist/esm/extensions/extend.js +12 -12
  60. package/dist/esm/extensions/extend.js.map +1 -1
  61. package/dist/esm/pool/idle-scaling-pool.js +2 -2
  62. package/dist/esm/pool/idle-scaling-pool.js.map +1 -1
  63. package/dist/esm/runtime/context.d.ts +43 -4
  64. package/dist/esm/runtime/context.d.ts.map +1 -1
  65. package/dist/esm/runtime/context.js +182 -30
  66. package/dist/esm/runtime/context.js.map +1 -1
  67. package/dist/esm/runtime/index.d.ts +3 -3
  68. package/dist/esm/runtime/index.d.ts.map +1 -1
  69. package/dist/esm/runtime/index.js.map +1 -1
  70. package/dist/esm/runtime/jmespath.d.ts +5 -3
  71. package/dist/esm/runtime/jmespath.d.ts.map +1 -1
  72. package/dist/esm/runtime/jmespath.js +5 -3
  73. package/dist/esm/runtime/jmespath.js.map +1 -1
  74. package/dist/esm/runtime/lazy-proxy.d.ts +7 -5
  75. package/dist/esm/runtime/lazy-proxy.d.ts.map +1 -1
  76. package/dist/esm/runtime/lazy-proxy.js +8 -16
  77. package/dist/esm/runtime/lazy-proxy.js.map +1 -1
  78. package/dist/esm/runtime/safe-globals.d.ts.map +1 -1
  79. package/dist/esm/runtime/safe-globals.js +8 -3
  80. package/dist/esm/runtime/safe-globals.js.map +1 -1
  81. package/dist/esm/runtime/utils.d.ts +16 -0
  82. package/dist/esm/runtime/utils.d.ts.map +1 -0
  83. package/dist/esm/runtime/utils.js +18 -0
  84. package/dist/esm/runtime/utils.js.map +1 -0
  85. package/dist/esm/types/bridge.d.ts +2 -1
  86. package/dist/esm/types/bridge.d.ts.map +1 -1
  87. package/dist/esm/types/bridge.js.map +1 -1
  88. package/dist/esm/types/evaluator.d.ts +86 -4
  89. package/dist/esm/types/evaluator.d.ts.map +1 -1
  90. package/dist/esm/types/evaluator.js.map +1 -1
  91. package/package.json +10 -9
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Schemas for messages the in-isolate runtime sends to the host via the
3
+ * `callHost` typed-RPC dispatcher.
4
+ *
5
+ * The isolate is an untrusted source: anything that crosses the bridge must
6
+ * be validated for shape and types at the boundary. We do that with zod
7
+ * rather than relying on TypeScript discriminated unions, because TS types
8
+ * are erased at runtime and contribute zero security.
9
+ *
10
+ * Each operation has its own schema. The dispatcher entry validates the
11
+ * envelope against the discriminated union, throws on any deviation
12
+ * (unknown `type`, missing/typo'd fields, wrong field types), and then
13
+ * delegates to a handler that operates on the parsed (statically narrowed)
14
+ * message.
15
+ *
16
+ * Each additional typed RPC lands as a new schema here plus a new `case`
17
+ * in the bridge's dispatcher switch.
18
+ */
19
+ (function (factory) {
20
+ if (typeof module === "object" && typeof module.exports === "object") {
21
+ var v = factory(require, exports);
22
+ if (v !== undefined) module.exports = v;
23
+ }
24
+ else if (typeof define === "function" && define.amd) {
25
+ define(["require", "exports", "zod"], factory);
26
+ }
27
+ })(function (require, exports) {
28
+ "use strict";
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.bridgeMessageSchema = exports.getPairedItemMessage = exports.evaluateExpressionMessage = exports.getNodeItemMessage = exports.getNodeItemMatchingMessage = exports.getNodePairedItemMessage = exports.fromAiMessage = exports.getItemsMessage = exports.getInputAllMessage = exports.getInputLastMessage = exports.getInputFirstMessage = exports.getNodeAllMessage = exports.getNodeLastMessage = exports.getNodeFirstMessage = void 0;
31
+ const zod_1 = require("zod");
32
+ /**
33
+ * `$('NodeName').first(branchIndex?, runIndex?)` — fetch the first item of
34
+ * a named node's most recent execution data.
35
+ */
36
+ exports.getNodeFirstMessage = zod_1.z
37
+ .object({
38
+ type: zod_1.z.literal('getNodeFirst'),
39
+ nodeName: zod_1.z.string(),
40
+ branchIndex: zod_1.z.number().int().nonnegative().optional(),
41
+ runIndex: zod_1.z.number().int().nonnegative().optional(),
42
+ })
43
+ .strict();
44
+ /**
45
+ * `$('NodeName').last(branchIndex?, runIndex?)` — fetch the last item of
46
+ * a named node's most recent execution data.
47
+ */
48
+ exports.getNodeLastMessage = zod_1.z
49
+ .object({
50
+ type: zod_1.z.literal('getNodeLast'),
51
+ nodeName: zod_1.z.string(),
52
+ branchIndex: zod_1.z.number().int().nonnegative().optional(),
53
+ runIndex: zod_1.z.number().int().nonnegative().optional(),
54
+ })
55
+ .strict();
56
+ /**
57
+ * `$('NodeName').all(branchIndex?, runIndex?)` — fetch every item of a
58
+ * named node's most recent execution data as an array.
59
+ */
60
+ exports.getNodeAllMessage = zod_1.z
61
+ .object({
62
+ type: zod_1.z.literal('getNodeAll'),
63
+ nodeName: zod_1.z.string(),
64
+ branchIndex: zod_1.z.number().int().nonnegative().optional(),
65
+ runIndex: zod_1.z.number().int().nonnegative().optional(),
66
+ })
67
+ .strict();
68
+ /**
69
+ * `$input.first()` — fetch the first item of the current node's input.
70
+ * Host enforces zero arguments; the schema has no fields besides `type`.
71
+ */
72
+ exports.getInputFirstMessage = zod_1.z.object({ type: zod_1.z.literal('getInputFirst') }).strict();
73
+ /**
74
+ * `$input.last()` — fetch the last item of the current node's input.
75
+ */
76
+ exports.getInputLastMessage = zod_1.z.object({ type: zod_1.z.literal('getInputLast') }).strict();
77
+ /**
78
+ * `$input.all()` — fetch every item of the current node's input.
79
+ */
80
+ exports.getInputAllMessage = zod_1.z.object({ type: zod_1.z.literal('getInputAll') }).strict();
81
+ /**
82
+ * `$items(nodeName?, outputIndex?, runIndex?)` — fetch the execution data of
83
+ * a node by name (or the current node's input if `nodeName` is omitted).
84
+ *
85
+ * `runIndex` accepts negative values: the host uses `-1` as a sentinel for
86
+ * "latest run" (see `WorkflowDataProxy.$items` —
87
+ * `runIndex === undefined ? -1 : runIndex`). The schema uses
88
+ * `z.number().int()` without `.nonnegative()` so expressions can pass `-1`
89
+ * explicitly if they need to.
90
+ */
91
+ exports.getItemsMessage = zod_1.z
92
+ .object({
93
+ type: zod_1.z.literal('getItems'),
94
+ nodeName: zod_1.z.string().optional(),
95
+ outputIndex: zod_1.z.number().int().nonnegative().optional(),
96
+ runIndex: zod_1.z.number().int().optional(),
97
+ })
98
+ .strict();
99
+ /**
100
+ * `$fromAI(name, description?, type?, defaultValue?)` — the AI-builder
101
+ * placeholder accessor (aliases: `$fromAi`, `$fromai`).
102
+ *
103
+ * Two deliberate looseness points in this schema, both to preserve host
104
+ * contract / parity:
105
+ *
106
+ * 1. `name` is `z.string().optional()` (not required) so a call missing
107
+ * the argument or passing an empty string reaches the host, which
108
+ * throws the user-friendly `ExpressionError("Add a key, e.g. $fromAI('placeholder_name')")`.
109
+ * Requiring it here would replace that error with a generic zod
110
+ * message. The host also validates the regex `[a-zA-Z0-9_-]{0,64}`;
111
+ * we don't pre-empt that either.
112
+ * 2. `defaultValue` is `z.unknown()` because the host accepts any value
113
+ * as the fallback return (`handleFromAi` returns it directly via
114
+ * `??`). Structured-clone at the bridge boundary still prevents
115
+ * functions and other non-cloneable values from crossing.
116
+ *
117
+ * `description` and `type` are forwarded even though the host currently
118
+ * ignores them (`_description`, `_type`), so the protocol matches the
119
+ * documented call signature.
120
+ */
121
+ exports.fromAiMessage = zod_1.z
122
+ .object({
123
+ type: zod_1.z.literal('fromAi'),
124
+ name: zod_1.z.string().optional(),
125
+ description: zod_1.z.string().optional(),
126
+ valueType: zod_1.z.string().optional(),
127
+ // `z.unknown()` already accepts `undefined`, so no `.optional()` needed.
128
+ defaultValue: zod_1.z.unknown(),
129
+ })
130
+ .strict();
131
+ /**
132
+ * `$('NodeName').pairedItem(itemIndex?)` / `.itemMatching(itemIndex)` /
133
+ * `.item` — resolve the paired item for a referenced node.
134
+ *
135
+ * All three host-side surface forms share one internal resolver
136
+ * (`pairedItemMethod` in `WorkflowDataProxy`), but the resolver closes
137
+ * over the literal property name the bridge accessed on the host proxy
138
+ * — so the error message and getter-vs-method form depend on *which*
139
+ * property the bridge reads. Three separate discriminators, each
140
+ * mapping a handler to a fixed literal property name, are the only way
141
+ * to preserve the host's friendly errors (e.g. "Missing item index for
142
+ * .itemMatching()") and the `.item` getter semantics without
143
+ * duplicating logic in-isolate.
144
+ *
145
+ * `itemIndex` is optional on all three at the schema level; the host
146
+ * throws the appropriate `ExpressionError` when it's missing for
147
+ * `.itemMatching()`, and applies the current-itemIndex default for
148
+ * `.pairedItem` and `.item`.
149
+ */
150
+ exports.getNodePairedItemMessage = zod_1.z
151
+ .object({
152
+ type: zod_1.z.literal('getNodePairedItem'),
153
+ nodeName: zod_1.z.string(),
154
+ itemIndex: zod_1.z.number().int().nonnegative().optional(),
155
+ })
156
+ .strict();
157
+ /**
158
+ * `itemIndex` is `.optional()` even though `.itemMatching()` requires it
159
+ * at the host. The host's `pairedItemMethod` closure throws the friendly
160
+ * `"Missing item index for .itemMatching()"` error when the field is
161
+ * absent — keeping the schema permissive lets that host error surface
162
+ * verbatim instead of being replaced by a generic zod parse failure.
163
+ */
164
+ exports.getNodeItemMatchingMessage = zod_1.z
165
+ .object({
166
+ type: zod_1.z.literal('getNodeItemMatching'),
167
+ nodeName: zod_1.z.string(),
168
+ itemIndex: zod_1.z.number().int().nonnegative().optional(),
169
+ })
170
+ .strict();
171
+ exports.getNodeItemMessage = zod_1.z
172
+ .object({
173
+ type: zod_1.z.literal('getNodeItem'),
174
+ nodeName: zod_1.z.string(),
175
+ })
176
+ .strict();
177
+ /**
178
+ * `$evaluateExpression(expression, itemIndex?)` — evaluate a nested
179
+ * expression string at runtime against the same execution context.
180
+ *
181
+ * The host recursively invokes the expression engine on the `expression`
182
+ * string — under the VM engine this re-enters the bridge with a fresh
183
+ * evaluation. `itemIndex` is optional and defaults to the current item;
184
+ * the schema mirrors the existing "nonnegative int" constraint used by
185
+ * the node-data RPCs.
186
+ */
187
+ exports.evaluateExpressionMessage = zod_1.z
188
+ .object({
189
+ type: zod_1.z.literal('evaluateExpression'),
190
+ expression: zod_1.z.string(),
191
+ itemIndex: zod_1.z.number().int().nonnegative().optional(),
192
+ })
193
+ .strict();
194
+ /**
195
+ * `ISourceData` — the source record that accompanies a paired-item
196
+ * traversal step. Mirrors the host interface used by
197
+ * `WorkflowDataProxy.getPairedItem`.
198
+ */
199
+ const sourceDataSchema = zod_1.z
200
+ .object({
201
+ previousNode: zod_1.z.string(),
202
+ previousNodeOutput: zod_1.z.number().int().nonnegative().optional(),
203
+ previousNodeRun: zod_1.z.number().int().nonnegative().optional(),
204
+ })
205
+ .strict();
206
+ /**
207
+ * `IPairedItemData` — one paired-item record. `sourceOverwrite` lets a
208
+ * node override the upstream source while the helper walks the ancestry
209
+ * chain; the field is optional and recurses through the same schema.
210
+ */
211
+ const pairedItemDataSchema = zod_1.z
212
+ .object({
213
+ item: zod_1.z.number().int().nonnegative(),
214
+ input: zod_1.z.number().int().nonnegative().optional(),
215
+ sourceOverwrite: sourceDataSchema.optional(),
216
+ })
217
+ .strict();
218
+ /**
219
+ * `$getPairedItem(destinationNodeName, incomingSourceData, initialPairedItem)` —
220
+ * traverse the paired-item ancestry chain back to the named upstream node
221
+ * and return the matching execution item.
222
+ *
223
+ * Two host-side fields are deliberately omitted from the schema:
224
+ * - `usedMethodName` defaults to `$getPairedItem` on the host; the isolate
225
+ * has no reason to spoof a different method name in the error path.
226
+ * - `nodeBeforeLast` is an internal recursion argument; only the host
227
+ * itself sets it during the recursive walk.
228
+ *
229
+ * `incomingSourceData` is nullable because the host's signature accepts
230
+ * `ISourceData | null` (and throws a paired-item-not-found error when null).
231
+ */
232
+ exports.getPairedItemMessage = zod_1.z
233
+ .object({
234
+ type: zod_1.z.literal('getPairedItem'),
235
+ destinationNodeName: zod_1.z.string(),
236
+ incomingSourceData: sourceDataSchema.nullable(),
237
+ initialPairedItem: pairedItemDataSchema,
238
+ })
239
+ .strict();
240
+ /**
241
+ * The full set of messages the bridge will accept. Discriminator is `type`.
242
+ *
243
+ * Use `.strict()` on each member so unknown fields are rejected rather than
244
+ * silently ignored — this catches typos in the runtime stubs and keeps the
245
+ * protocol surface tight.
246
+ */
247
+ exports.bridgeMessageSchema = zod_1.z.discriminatedUnion('type', [
248
+ exports.getNodeFirstMessage,
249
+ exports.getNodeLastMessage,
250
+ exports.getNodeAllMessage,
251
+ exports.getInputFirstMessage,
252
+ exports.getInputLastMessage,
253
+ exports.getInputAllMessage,
254
+ exports.getItemsMessage,
255
+ exports.fromAiMessage,
256
+ exports.getNodePairedItemMessage,
257
+ exports.getNodeItemMatchingMessage,
258
+ exports.getNodeItemMessage,
259
+ exports.evaluateExpressionMessage,
260
+ exports.getPairedItemMessage,
261
+ ]);
262
+ });
263
+ //# sourceMappingURL=bridge-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-messages.js","sourceRoot":"","sources":["../../../src/bridge/bridge-messages.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { RuntimeBridge, BridgeConfig, ExecuteOptions } from '../types';
1
+ import type { RuntimeBridge, BridgeConfig, ExecuteOptions, WorkflowData } from '../types';
2
2
  /**
3
3
  * IsolatedVmBridge - Runtime bridge using isolated-vm for secure expression evaluation.
4
4
  *
@@ -81,7 +81,13 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
81
81
  * Create an ivm.Reference callback for getting value/metadata at a path.
82
82
  *
83
83
  * Used by createDeepLazyProxy when accessing properties. Returns metadata
84
- * markers for functions, arrays, and objects, or the primitive value directly.
84
+ * markers for arrays and objects, or the primitive value directly.
85
+ *
86
+ * Function-typed values are returned as `undefined` — every callable on
87
+ * the host data surface (`$('Foo').first()`, `$items()`, `$fromAI()`,
88
+ * `$evaluateExpression()`, `$getPairedItem()`) is wired in-isolate via
89
+ * the typed-RPC dispatcher (`callHost`). No expression form should
90
+ * reach a function through this path.
85
91
  *
86
92
  * @param data - Current workflow data to use for callback responses
87
93
  * @private
@@ -97,23 +103,140 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
97
103
  */
98
104
  private createGetArrayElementRef;
99
105
  /**
100
- * Create an ivm.Reference callback for calling functions at a path.
106
+ * Create the single typed-RPC dispatcher.
101
107
  *
102
- * Used when expressions invoke functions from workflow data.
108
+ * The isolate sends one envelope per typed RPC invocation:
109
+ * `callHost({ type: 'getNodeFirst', nodeName, branchIndex?, runIndex? })`
110
+ *
111
+ * Inputs cross a trust boundary, so the dispatcher parses every envelope
112
+ * with the host-side zod schema (`bridgeMessageSchema`) before any
113
+ * dispatch happens. Anything that deviates from the declared shape —
114
+ * unknown `type`, missing required fields, extra unexpected fields,
115
+ * wrong field types — fails the parse and an error sentinel is returned
116
+ * to the caller.
117
+ *
118
+ * After parsing, `switch (msg.type)` dispatches to a private handler with
119
+ * a fully narrowed message type. The operation set is exactly the cases
120
+ * in this switch; the `type` field selects a static branch in source,
121
+ * not a property lookup on a runtime object.
122
+ *
123
+ * @param data - Current workflow data
124
+ * @private
125
+ */
126
+ private createCallHostRef;
127
+ /**
128
+ * Handlers for the `$('Foo').{first,last,all}` typed RPCs.
129
+ *
130
+ * Each handler reads a fixed literal property name off the host-side node
131
+ * proxy — the isolate cannot influence which property is dereferenced.
132
+ * Eliminating `data.$` as a host-callable entirely would require reaching
133
+ * the `WorkflowDataProxy` internals (e.g. `getNodeExecutionOrPinnedData`)
134
+ * rather than the public `$()` API; that's a follow-up.
135
+ *
136
+ * `data.$` is a host-wired function (`WorkflowDataProxy`'s `$`). If it
137
+ * ever isn't, optional chaining short-circuits to `undefined` — the same
138
+ * observable result the runtime's `E()` handler produces from any thrown
139
+ * error here.
140
+ *
141
+ * @private
142
+ */
143
+ private handleGetNodeFirst;
144
+ private handleGetNodeLast;
145
+ private handleGetNodeAll;
146
+ /**
147
+ * Handlers for the `$input.{first,last,all}` typed RPCs.
148
+ *
149
+ * Each reads a fixed literal property name off `data.$input` (the host's
150
+ * `WorkflowDataProxy` input proxy). The host enforces zero arguments on
151
+ * these methods — the schemas have no fields besides `type`, so the
152
+ * isolate cannot pass anything that would trigger the "should have no
153
+ * arguments" error path on the host side.
154
+ *
155
+ * @private
156
+ */
157
+ private handleGetInputFirst;
158
+ private handleGetInputLast;
159
+ private handleGetInputAll;
160
+ /**
161
+ * Handler for `$items(nodeName?, outputIndex?, runIndex?)` — the
162
+ * global accessor for a node's execution data. Reads the literal
163
+ * `$items` property off `data` (host-wired by `WorkflowDataProxy`)
164
+ * and forwards the validated args verbatim. The host applies its own
165
+ * defaults when fields are `undefined`.
166
+ *
167
+ * @private
168
+ */
169
+ private handleGetItems;
170
+ /**
171
+ * Handler for `$fromAI(name, description?, type?, defaultValue?)` and its
172
+ * `$fromAi` / `$fromai` aliases. Reads the literal `$fromAI` property
173
+ * off `data` (host-wired) and forwards the args. The host validates
174
+ * `name` (required + regex) and applies its own resolution / fallback
175
+ * logic, so empty / invalid names surface as the host's structured
176
+ * `ExpressionError` rather than a generic zod parse error.
177
+ *
178
+ * Note: `msg.valueType` maps to the host's third positional parameter
179
+ * (`_type` in `WorkflowDataProxy.handleFromAi`). The bridge protocol
180
+ * renames it to avoid collision with the `type` discriminator on the
181
+ * envelope — the host parameter currently goes unused, but if it ever
182
+ * gains a name (`type`), this mapping should stay explicit.
183
+ *
184
+ * @private
185
+ */
186
+ private handleFromAi;
187
+ /**
188
+ * Handlers for the `$('Foo').pairedItem(itemIndex?)` / `.itemMatching(...)` /
189
+ * `.item` cluster. Three separate typed RPCs, each reading exactly one
190
+ * literal property off the host node proxy.
191
+ *
192
+ * The split is load-bearing: the host's `pairedItemMethod` closure
193
+ * captures which property name the proxy `get` trap saw, and uses
194
+ * that to pick the right error message (e.g. "Missing item index for
195
+ * .itemMatching()") and to decide between method-call vs getter
196
+ * semantics for `.item`. Reading the matching property here lets
197
+ * those host-side branches fire exactly as they do in the legacy
198
+ * engine; no in-isolate validation needed.
199
+ *
200
+ * @private
201
+ */
202
+ private handleGetNodePairedItem;
203
+ private handleGetNodeItemMatching;
204
+ private handleGetNodeItem;
205
+ /**
206
+ * Handler for `$evaluateExpression(expression, itemIndex?)`. Forwards
207
+ * the string to the host's nested-evaluation helper, which re-enters
208
+ * the expression engine on the inner expression. Under the VM engine
209
+ * this round-trips through the bridge again on a fresh evaluation
210
+ * cycle, which is the same shape the legacy engine supports.
211
+ *
212
+ * @private
213
+ */
214
+ private handleEvaluateExpression;
215
+ /**
216
+ * Handler for `$getPairedItem(destinationNodeName, incomingSourceData,
217
+ * initialPairedItem)`. Forwards directly to the host binding, which
218
+ * walks the paired-item ancestry chain back to the named upstream node
219
+ * and returns the matching execution item.
220
+ *
221
+ * The two trailing host parameters — `usedMethodName` and
222
+ * `nodeBeforeLast` — are deliberately not part of the wire protocol:
223
+ * the host's default for `usedMethodName` is already `$getPairedItem`,
224
+ * and `nodeBeforeLast` is an internal recursion argument the host sets
225
+ * during traversal.
103
226
  *
104
- * @param data - Current workflow data to use for callback responses
105
227
  * @private
106
228
  */
107
- private createCallFunctionAtPathRef;
229
+ private handleGetPairedItem;
108
230
  /**
109
231
  * Execute JavaScript code in the isolated context.
110
232
  *
111
233
  * Flow:
112
- * 1. Create three ivm.Reference callbacks scoped to the current data
113
- * 2. Use evalClosureSync to run the code in a closure where $0/$1/$2
114
- * are the callback references no global mutable state
234
+ * 1. Create three ivm.Reference callbacks scoped to the current data:
235
+ * `getValueAtPath`, `getArrayElement`, `callHost`.
236
+ * 2. Use evalClosureSync to run the code in a closure where `$0`/`$1`/`$2`
237
+ * are the callback references — no global mutable state.
115
238
  * 3. buildContext() inside the isolate creates a fresh evaluation context
116
- * from the closure-scoped references
239
+ * from the closure-scoped references.
117
240
  *
118
241
  * Each call gets its own closure, so nested and concurrent evaluations
119
242
  * cannot interfere with each other.
@@ -123,7 +246,7 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
123
246
  * @returns Result of the expression
124
247
  * @throws {Error} If bridge not initialized or execution fails
125
248
  */
126
- execute(code: string, data: Record<string, unknown>, options?: ExecuteOptions): unknown;
249
+ execute(code: string, data: WorkflowData, options?: ExecuteOptions): unknown;
127
250
  /**
128
251
  * Reconstruct an error from serialized isolate data.
129
252
  *
@@ -1 +1 @@
1
- {"version":3,"file":"isolated-vm-bridge.d.ts","sourceRoot":"","sources":["../../../src/bridge/isolated-vm-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA0E5E;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACrD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAmC;gBAErC,MAAM,GAAE,YAAiB;IAYrC;;;;;;;;;;OAUG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BjC;;;;;;;;;;;OAWG;YACW,mBAAmB;IAgCjC;;;;;;;;OAQG;YACW,iBAAiB;IA4B/B;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,kBAAkB;IAwBhC;;;;;;;;OAQG;IACH,OAAO,CAAC,uBAAuB;IAgE/B;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;IAyDhC;;;;;;;OAOG;IACH,OAAO,CAAC,2BAA2B;IAkCnC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO;IAsFvF;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B;;;;OAIG;IACH,UAAU,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"isolated-vm-bridge.d.ts","sourceRoot":"","sources":["../../../src/bridge/isolated-vm-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA2E1F;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACrD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAmC;gBAErC,MAAM,GAAE,YAAiB;IAYrC;;;;;;;;;;OAUG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BjC;;;;;;;;;;;OAWG;YACW,mBAAmB;IAgCjC;;;;;;;;OAQG;YACW,iBAAiB;IA4B/B;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,kBAAkB;IAwBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,uBAAuB;IA+D/B;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;IAyDhC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,iBAAiB;IA+CzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,iBAAiB;IAIzB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;OAQG;IACH,OAAO,CAAC,wBAAwB;IAOhC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO;IA6F5E;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B;;;;OAIG;IACH,UAAU,IAAI,OAAO;CAGrB"}