@codemation/core 0.13.2 → 0.14.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/CHANGELOG.md +99 -0
- package/dist/{CostCatalogContract-Dxq1BTyi.d.cts → CostCatalogContract-B9aYIqJu.d.cts} +2 -2
- package/dist/{EngineRuntimeRegistration.types-CqcTWexS.d.cts → EngineRuntimeRegistration.types-BYAmGMdS.d.cts} +3 -3
- package/dist/{EngineRuntimeRegistration.types-Cr75cSfL.d.ts → EngineRuntimeRegistration.types-CVLI8DsJ.d.ts} +2 -2
- package/dist/{InMemoryRunDataFactory-Csy2evr_.d.cts → InMemoryRunDataFactory-C3rIszrW.d.cts} +4 -2
- package/dist/{ItemsInputNormalizer-BbQTSEkZ.cjs → ItemsInputNormalizer-B9SdLG24.cjs} +2 -2
- package/dist/{ItemsInputNormalizer-BbQTSEkZ.cjs.map → ItemsInputNormalizer-B9SdLG24.cjs.map} +1 -1
- package/dist/{ItemsInputNormalizer-CSZGMgl3.js → ItemsInputNormalizer-CZEODg94.js} +2 -2
- package/dist/{ItemsInputNormalizer-CSZGMgl3.js.map → ItemsInputNormalizer-CZEODg94.js.map} +1 -1
- package/dist/{ItemsInputNormalizer-BYljnXU0.d.ts → ItemsInputNormalizer-DoOawd9R.d.ts} +2 -2
- package/dist/{ItemsInputNormalizer-Bi8m-Ijs.d.cts → ItemsInputNormalizer-UCpn7luX.d.cts} +3 -3
- package/dist/{RunIntentService-BitgkKaT.d.cts → RunIntentService-0f3ICjAz.d.cts} +2 -2
- package/dist/{RunIntentService-DYpqfu6D.d.ts → RunIntentService-Dx_HHxDX.d.ts} +2 -2
- package/dist/{agentMcpTypes-DGIwk6Ue.d.cts → agentMcpTypes-B11B3Hd-.d.cts} +8 -1
- package/dist/bootstrap/index.cjs +3 -3
- package/dist/bootstrap/index.d.cts +5 -5
- package/dist/bootstrap/index.d.ts +5 -5
- package/dist/bootstrap/index.js +3 -3
- package/dist/{bootstrap-DIv-vloi.cjs → bootstrap-Be0LB0nh.cjs} +3 -3
- package/dist/{bootstrap-DIv-vloi.cjs.map → bootstrap-Be0LB0nh.cjs.map} +1 -1
- package/dist/{bootstrap-Bkd-Nfbn.js → bootstrap-pSQdsMfa.js} +3 -3
- package/dist/{bootstrap-Bkd-Nfbn.js.map → bootstrap-pSQdsMfa.js.map} +1 -1
- package/dist/browser.cjs +2 -2
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +2 -2
- package/dist/contracts.d.cts +4 -4
- package/dist/contracts.d.ts +1 -1
- package/dist/{di-tom0pM2h.js → di-CEV6wTc4.js} +4 -5
- package/dist/di-CEV6wTc4.js.map +1 -0
- package/dist/{di-LP2qSHkY.cjs → di-DhwtDRgs.cjs} +4 -5
- package/dist/di-DhwtDRgs.cjs.map +1 -0
- package/dist/{executionPersistenceContracts-CN9d7AnL.d.cts → executionPersistenceContracts-CX9Ql8N1.d.cts} +2 -2
- package/dist/{index-rllWL4r-.d.ts → index-CbJdbIHe.d.ts} +93 -6
- package/dist/{index-BSQ2LoIh.d.ts → index-uPnD9EE6.d.ts} +51 -11
- package/dist/index.cjs +20 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -16
- package/dist/index.d.ts +5 -5
- package/dist/index.js +19 -8
- package/dist/index.js.map +1 -1
- package/dist/{params-DRUr0F5v.d.cts → params-Dwl10Ws9.d.cts} +3 -4
- package/dist/{runtime-CWPdvJpC.js → runtime-CSunvf7A.js} +112 -15
- package/dist/runtime-CSunvf7A.js.map +1 -0
- package/dist/{runtime-_VdHwGkJ.cjs → runtime-n2tqRwaf.cjs} +117 -14
- package/dist/runtime-n2tqRwaf.cjs.map +1 -0
- package/dist/testing.cjs +3 -3
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +3 -3
- package/package.json +1 -1
- package/src/authoring/defineNode.types.ts +18 -7
- package/src/authoring/definePollingTrigger.types.ts +20 -5
- package/src/authoring/index.ts +1 -0
- package/src/authoring/nodeBaseOptions.types.ts +18 -0
- package/src/contracts/itemExpr.ts +15 -11
- package/src/contracts/workflowTypes.ts +7 -0
- package/src/contracts/workspaceFileTypes.ts +42 -2
- package/src/execution/NodeOutputNormalizer.ts +8 -1
- package/src/execution/RunnableOutputBehaviorResolver.ts +12 -0
- package/src/index.ts +10 -2
- package/src/workflow/dsl/ChainCursorResolver.ts +13 -0
- package/src/workflow/dsl/WhenBuilder.ts +66 -2
- package/src/workflow/dsl/workflowBuilderTypes.ts +29 -0
- package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +1 -0
- package/dist/di-LP2qSHkY.cjs.map +0 -1
- package/dist/di-tom0pM2h.js.map +0 -1
- package/dist/runtime-CWPdvJpC.js.map +0 -1
- package/dist/runtime-_VdHwGkJ.cjs.map +0 -1
package/dist/testing.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const require_di = require('./di-
|
|
1
|
+
const require_di = require('./di-DhwtDRgs.cjs');
|
|
2
2
|
require('./contracts-CK0x6w_G.cjs');
|
|
3
|
-
const require_runtime = require('./runtime-
|
|
3
|
+
const require_runtime = require('./runtime-n2tqRwaf.cjs');
|
|
4
4
|
const require_InMemoryRunEventBusRegistry = require('./InMemoryRunEventBusRegistry-Sa86VxuV.cjs');
|
|
5
|
-
const require_bootstrap = require('./bootstrap-
|
|
5
|
+
const require_bootstrap = require('./bootstrap-Be0LB0nh.cjs');
|
|
6
6
|
let tsyringe = require("tsyringe");
|
|
7
7
|
tsyringe = require_di.__toESM(tsyringe);
|
|
8
8
|
|
package/dist/testing.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $t as RunnableNodeConfig, Cr as TriggerSetupStateRepository, Ct as Item, H as WorkflowExecutionRepository, Ht as NodeOffloadPolicy, N as RunResult, Or as WorkflowRunnerService, Pi as CredentialSessionService, Tt as Items, U as Container, Un as ExecutionContextFactory, Ut as NodeOutputs, Xi as WorkflowId, Y as TypeToken, Yt as RunDataFactory, ct as EngineExecutionLimitsPolicy, dt as RunEventBus, hr as RunnableNodeExecuteArgs, ir as NodeExecutionRequest, mr as RunnableNode, nn as TriggerNodeConfig, on as WorkflowDefinition, or as NodeExecutionScheduler, qi as NodeId, qt as ParentExecutionRef, rr as NodeExecutionContext, xr as TriggerSetupContext, yr as TriggerNode } from "./agentMcpTypes-
|
|
2
|
-
import { n as InMemoryLiveWorkflowRepository, r as Engine, t as RunIntentService } from "./RunIntentService-
|
|
3
|
-
import { a as WorkflowSnapshotCodec, i as EngineWorkflowRunnerService, t as EngineRuntimeRegistrationOptions } from "./EngineRuntimeRegistration.types-
|
|
1
|
+
import { $t as RunnableNodeConfig, Cr as TriggerSetupStateRepository, Ct as Item, H as WorkflowExecutionRepository, Ht as NodeOffloadPolicy, N as RunResult, Or as WorkflowRunnerService, Pi as CredentialSessionService, Tt as Items, U as Container, Un as ExecutionContextFactory, Ut as NodeOutputs, Xi as WorkflowId, Y as TypeToken, Yt as RunDataFactory, ct as EngineExecutionLimitsPolicy, dt as RunEventBus, hr as RunnableNodeExecuteArgs, ir as NodeExecutionRequest, mr as RunnableNode, nn as TriggerNodeConfig, on as WorkflowDefinition, or as NodeExecutionScheduler, qi as NodeId, qt as ParentExecutionRef, rr as NodeExecutionContext, xr as TriggerSetupContext, yr as TriggerNode } from "./agentMcpTypes-B11B3Hd-.cjs";
|
|
2
|
+
import { n as InMemoryLiveWorkflowRepository, r as Engine, t as RunIntentService } from "./RunIntentService-0f3ICjAz.cjs";
|
|
3
|
+
import { a as WorkflowSnapshotCodec, i as EngineWorkflowRunnerService, t as EngineRuntimeRegistrationOptions } from "./EngineRuntimeRegistration.types-BYAmGMdS.cjs";
|
|
4
4
|
import { ZodType } from "zod";
|
|
5
5
|
import { DependencyContainer, InjectionToken } from "tsyringe";
|
|
6
6
|
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as WorkflowSnapshotCodec, n as InMemoryLiveWorkflowRepository, r as EngineWorkflowRunnerService, t as RunIntentService, u as Engine } from "./RunIntentService-
|
|
3
|
-
import { t as EngineRuntimeRegistrationOptions } from "./EngineRuntimeRegistration.types-
|
|
1
|
+
import { An as TypeToken, Ar as RunDataFactory, Cn as WorkflowExecutionRepository, Cr as NodeOffloadPolicy, Kn as RunEventBus, Lr as TriggerNodeConfig, Oo as NodeId, Or as ParentExecutionRef, Pr as RunnableNodeConfig, Ri as NodeExecutionContext, Un as EngineExecutionLimitsPolicy, Vi as NodeExecutionScheduler, Vr as WorkflowDefinition, Xi as RunnableNodeExecuteArgs, Yi as RunnableNode, ea as TriggerNode, ho as CredentialSessionService, ia as TriggerSetupStateRepository, ir as Item, jo as WorkflowId, la as WorkflowRunnerService, mn as RunResult, na as TriggerSetupContext, or as Items, wi as ExecutionContextFactory, wn as Container, wr as NodeOutputs, zi as NodeExecutionRequest } from "./index-CbJdbIHe.js";
|
|
2
|
+
import { i as WorkflowSnapshotCodec, n as InMemoryLiveWorkflowRepository, r as EngineWorkflowRunnerService, t as RunIntentService, u as Engine } from "./RunIntentService-Dx_HHxDX.js";
|
|
3
|
+
import { t as EngineRuntimeRegistrationOptions } from "./EngineRuntimeRegistration.types-CVLI8DsJ.js";
|
|
4
4
|
import { DependencyContainer, InjectionToken } from "tsyringe";
|
|
5
5
|
import { ZodType } from "zod";
|
|
6
6
|
|
package/dist/testing.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { d as CoreTokens } from "./di-
|
|
1
|
+
import { d as CoreTokens } from "./di-CEV6wTc4.js";
|
|
2
2
|
import "./contracts-DXdfTdpW.js";
|
|
3
|
-
import { A as PersistedWorkflowTokenRegistry, C as DefaultDrivingScheduler, G as AllWorkflowsActiveWorkflowActivationPolicy, N as NodeExecutor, O as NodeInstanceFactory, S as HintOnlyOffloadPolicy, V as DefaultExecutionContextFactory, a as InMemoryLiveWorkflowRepository, i as RunIntentService, it as emitPorts, k as WorkflowSnapshotCodec, l as Engine, p as InMemoryRunDataFactory, st as DefaultAsyncSleeper, x as InlineDrivingScheduler, yt as WorkflowBuilder, z as InProcessRetryRunner } from "./runtime-
|
|
3
|
+
import { A as PersistedWorkflowTokenRegistry, C as DefaultDrivingScheduler, G as AllWorkflowsActiveWorkflowActivationPolicy, N as NodeExecutor, O as NodeInstanceFactory, S as HintOnlyOffloadPolicy, V as DefaultExecutionContextFactory, a as InMemoryLiveWorkflowRepository, i as RunIntentService, it as emitPorts, k as WorkflowSnapshotCodec, l as Engine, p as InMemoryRunDataFactory, st as DefaultAsyncSleeper, x as InlineDrivingScheduler, yt as WorkflowBuilder, z as InProcessRetryRunner } from "./runtime-CSunvf7A.js";
|
|
4
4
|
import { t as InMemoryRunEventBus } from "./InMemoryRunEventBusRegistry-Bwunvt1T.js";
|
|
5
|
-
import { a as InMemoryWorkflowExecutionRepository, t as EngineRuntimeRegistrar } from "./bootstrap-
|
|
5
|
+
import { a as InMemoryWorkflowExecutionRepository, t as EngineRuntimeRegistrar } from "./bootstrap-pSQdsMfa.js";
|
|
6
6
|
import { container } from "tsyringe";
|
|
7
7
|
|
|
8
8
|
//#region src/testing/RejectingCredentialSessionService.ts
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import { node as persistedNode } from "../runtime-types/runtimeTypeDecorators.ty
|
|
|
12
12
|
import type { ZodType } from "zod";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
import { DefinedNodeRegistry } from "./DefinedNodeRegistry";
|
|
15
|
+
import type { NodeBaseOptions } from "./nodeBaseOptions.types";
|
|
15
16
|
|
|
16
17
|
type MaybePromise<TValue> = TValue | Promise<TValue>;
|
|
17
18
|
|
|
@@ -87,7 +88,7 @@ export interface DefinedNode<
|
|
|
87
88
|
create<TConfigItemJson = TInputJson>(
|
|
88
89
|
config: DefinedNodeConfigInput<TConfig, TConfigItemJson>,
|
|
89
90
|
name?: string,
|
|
90
|
-
|
|
91
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
91
92
|
): RunnableNodeConfig<TInputJson, TOutputJson>;
|
|
92
93
|
register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;
|
|
93
94
|
}
|
|
@@ -271,12 +272,17 @@ export function defineNode<
|
|
|
271
272
|
readonly icon = options.icon;
|
|
272
273
|
readonly inputSchema = options.inputSchema;
|
|
273
274
|
readonly keepBinaries = options.keepBinaries ?? false;
|
|
275
|
+
readonly id?: string;
|
|
276
|
+
readonly description?: string;
|
|
274
277
|
|
|
275
278
|
constructor(
|
|
276
279
|
public readonly name: string,
|
|
277
280
|
config: DefinedNodeConfigInput<TConfig, unknown>,
|
|
278
|
-
|
|
281
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
279
282
|
) {
|
|
283
|
+
const resolved = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
284
|
+
this.id = resolved?.id;
|
|
285
|
+
this.description = resolved?.description;
|
|
280
286
|
this.config = config as unknown as TConfig;
|
|
281
287
|
}
|
|
282
288
|
|
|
@@ -299,9 +305,9 @@ export function defineNode<
|
|
|
299
305
|
create<TConfigItemJson = TInputJson>(
|
|
300
306
|
config: DefinedNodeConfigInput<TConfig, TConfigItemJson>,
|
|
301
307
|
name = options.title,
|
|
302
|
-
|
|
308
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
303
309
|
) {
|
|
304
|
-
return new DefinedRunnableNodeConfig(name, config as DefinedNodeConfigInput<TConfig, unknown>,
|
|
310
|
+
return new DefinedRunnableNodeConfig(name, config as DefinedNodeConfigInput<TConfig, unknown>, idOrOptions);
|
|
305
311
|
},
|
|
306
312
|
register(context) {
|
|
307
313
|
context.registerNode(DefinedNodeRuntime);
|
|
@@ -358,12 +364,17 @@ export function defineBatchNode<
|
|
|
358
364
|
readonly kind = "node" as const;
|
|
359
365
|
readonly type: TypeToken<unknown> = DefinedNodeRuntime;
|
|
360
366
|
readonly icon = options.icon;
|
|
367
|
+
readonly id?: string;
|
|
368
|
+
readonly description?: string;
|
|
361
369
|
|
|
362
370
|
constructor(
|
|
363
371
|
public readonly name: string,
|
|
364
372
|
config: DefinedNodeConfigInput<TConfig, unknown>,
|
|
365
|
-
|
|
373
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
366
374
|
) {
|
|
375
|
+
const resolved = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
376
|
+
this.id = resolved?.id;
|
|
377
|
+
this.description = resolved?.description;
|
|
367
378
|
this.config = config as unknown as TConfig;
|
|
368
379
|
}
|
|
369
380
|
|
|
@@ -386,9 +397,9 @@ export function defineBatchNode<
|
|
|
386
397
|
create<TConfigItemJson = TInputJson>(
|
|
387
398
|
config: DefinedNodeConfigInput<TConfig, TConfigItemJson>,
|
|
388
399
|
name = options.title,
|
|
389
|
-
|
|
400
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
390
401
|
) {
|
|
391
|
-
return new DefinedRunnableNodeConfig(name, config as DefinedNodeConfigInput<TConfig, unknown>,
|
|
402
|
+
return new DefinedRunnableNodeConfig(name, config as DefinedNodeConfigInput<TConfig, unknown>, idOrOptions);
|
|
392
403
|
},
|
|
393
404
|
register(context) {
|
|
394
405
|
context.registerNode(DefinedNodeRuntime);
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
} from "..";
|
|
22
22
|
import type { CredentialJsonRecord, CredentialRequirement } from "../contracts/credentialTypes";
|
|
23
23
|
import type { DefinedNodeCredentialAccessors, DefinedNodeCredentialBindings } from "./defineNode.types";
|
|
24
|
+
import type { NodeBaseOptions } from "./nodeBaseOptions.types";
|
|
24
25
|
import { node as persistedNode } from "../runtime-types/runtimeTypeDecorators.types";
|
|
25
26
|
import {
|
|
26
27
|
definedNodeCredentialRequirementFactory,
|
|
@@ -170,9 +171,14 @@ export interface DefinedPollingTrigger<
|
|
|
170
171
|
* Create the trigger config for use in workflow definitions.
|
|
171
172
|
* @param cfg - User-facing trigger configuration.
|
|
172
173
|
* @param name - Display name (defaults to `title`).
|
|
173
|
-
* @param
|
|
174
|
+
* @param idOrOptions - Optional stable node id, or `{ id?, description? }` authoring options
|
|
175
|
+
* (a bare string id still works — back-compat).
|
|
174
176
|
*/
|
|
175
|
-
create(
|
|
177
|
+
create(
|
|
178
|
+
cfg: TConfig,
|
|
179
|
+
name?: string,
|
|
180
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
181
|
+
): DefinedPollingTriggerConfig<TConfig, TItemJson>;
|
|
176
182
|
/**
|
|
177
183
|
* Test seam: call `poll` directly without starting the runtime.
|
|
178
184
|
* Returns `{ items, nextState }` just like the real runtime receives.
|
|
@@ -203,6 +209,8 @@ export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, T
|
|
|
203
209
|
readonly kind = "trigger" as const;
|
|
204
210
|
readonly type: TypeToken<unknown>;
|
|
205
211
|
readonly icon: string | undefined;
|
|
212
|
+
readonly id?: string;
|
|
213
|
+
readonly description?: string;
|
|
206
214
|
|
|
207
215
|
constructor(
|
|
208
216
|
public readonly name: string,
|
|
@@ -210,13 +218,16 @@ export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, T
|
|
|
210
218
|
typeToken: TypeToken<unknown>,
|
|
211
219
|
icon: string | undefined,
|
|
212
220
|
private readonly credentialRequirements: ReadonlyArray<CredentialRequirement>,
|
|
213
|
-
|
|
221
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
214
222
|
private readonly inspectorSummaryFn?: (
|
|
215
223
|
args: Readonly<{ config: TConfig }>,
|
|
216
224
|
) => ReadonlyArray<NodeInspectorSummaryRow> | undefined,
|
|
217
225
|
) {
|
|
218
226
|
this.type = typeToken;
|
|
219
227
|
this.icon = icon;
|
|
228
|
+
const resolved = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
229
|
+
this.id = resolved?.id;
|
|
230
|
+
this.description = resolved?.description;
|
|
220
231
|
}
|
|
221
232
|
|
|
222
233
|
getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {
|
|
@@ -385,14 +396,18 @@ export function definePollingTrigger<
|
|
|
385
396
|
title: options.title,
|
|
386
397
|
description: options.description,
|
|
387
398
|
|
|
388
|
-
create(
|
|
399
|
+
create(
|
|
400
|
+
cfg: TConfig,
|
|
401
|
+
name = options.title,
|
|
402
|
+
idOrOptions?: string | NodeBaseOptions,
|
|
403
|
+
): DefinedPollingTriggerConfig<TConfig, TItemJson> {
|
|
389
404
|
return new DefinedPollingTriggerConfig<TConfig, TItemJson>(
|
|
390
405
|
name,
|
|
391
406
|
cfg,
|
|
392
407
|
DefinedPollingTriggerRuntime,
|
|
393
408
|
options.icon,
|
|
394
409
|
credentialRequirements,
|
|
395
|
-
|
|
410
|
+
idOrOptions,
|
|
396
411
|
options.inspectorSummary as
|
|
397
412
|
| ((args: Readonly<{ config: TConfig }>) => ReadonlyArray<NodeInspectorSummaryRow> | undefined)
|
|
398
413
|
| undefined,
|
package/src/authoring/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core-local copy of the per-instance authoring options every `define*` factory's `create(...)`
|
|
3
|
+
* accepts in its trailing argument: a stable `id` plus a plain-language `description` (the
|
|
4
|
+
* non-technical "what does this step do" line surfaced in the node sidebar).
|
|
5
|
+
*
|
|
6
|
+
* `description` is a first-class option — passed inline exactly like `id` — and is threaded onto
|
|
7
|
+
* the config instance as an OWN ENUMERABLE field so it flows into the persisted workflow snapshot
|
|
8
|
+
* (`WorkflowSnapshotCodec` serializes via `JSON.parse(JSON.stringify(config))`, which only captures
|
|
9
|
+
* own enumerable properties — never a getter).
|
|
10
|
+
*
|
|
11
|
+
* `@codemation/core-nodes` declares an identical `NodeBaseOptions` for its bare-id built-in nodes;
|
|
12
|
+
* core keeps its own copy because core must not depend on `@codemation/core-nodes` (dependency
|
|
13
|
+
* direction). The two types are structurally identical by design.
|
|
14
|
+
*/
|
|
15
|
+
export interface NodeBaseOptions {
|
|
16
|
+
readonly id?: string;
|
|
17
|
+
readonly description?: string;
|
|
18
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { NodeExecutionContext } from "./runtimeTypes";
|
|
2
2
|
import type { Item, Items, NodeActivationId, NodeId, RunDataSnapshot, RunId, WorkflowId } from "./workflowTypes";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Structural string-literal brand (NOT a `unique symbol`): independently-bundled copies of
|
|
5
|
+
// `ItemExpr` across node packages must be STRUCTURALLY identical to stay cross-assignable. A
|
|
6
|
+
// `unique symbol` makes each bundled copy a nominally-distinct type, which breaks passing an
|
|
7
|
+
// `itemExpr()` into a node-config field whose package resolved a different (duplicated) copy of
|
|
8
|
+
// core. A plain string-literal property is identical across copies and also survives JSON.
|
|
5
9
|
|
|
6
10
|
export type ItemExprResolvedContext = Readonly<{
|
|
7
11
|
runId: RunId;
|
|
@@ -26,12 +30,12 @@ export type ItemExprArgs<TItemJson = unknown> = Readonly<{
|
|
|
26
30
|
export type ItemExprCallback<T, TItemJson = unknown> = (args: ItemExprArgs<TItemJson>) => T | Promise<T>;
|
|
27
31
|
|
|
28
32
|
export type ItemExpr<T, TItemJson = unknown> = Readonly<{
|
|
29
|
-
readonly
|
|
33
|
+
readonly __codemationItemExpr: "codemation.itemExpr";
|
|
30
34
|
readonly fn: ItemExprCallback<T, TItemJson>;
|
|
31
35
|
}>;
|
|
32
36
|
|
|
33
37
|
export function itemExpr<T, TItemJson = unknown>(fn: ItemExprCallback<T, TItemJson>): ItemExpr<T, TItemJson> {
|
|
34
|
-
return {
|
|
38
|
+
return { __codemationItemExpr: "codemation.itemExpr", fn };
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export function isItemExpr<T, TItemJson = unknown>(value: unknown): value is ItemExpr<T, TItemJson> {
|
|
@@ -39,21 +43,21 @@ export function isItemExpr<T, TItemJson = unknown>(value: unknown): value is Ite
|
|
|
39
43
|
return false;
|
|
40
44
|
}
|
|
41
45
|
const v = value as Record<PropertyKey, unknown>;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
// Support snapshot-hydrated itemExpr wrappers where the symbol brand was lost but the callback survived.
|
|
46
|
-
// Workflow snapshot hydration currently restores function-valued fields (like `fn`) but may drop symbol-keyed brands.
|
|
47
|
-
// We treat the minimal `{ fn: Function }` shape as an itemExpr wrapper to keep runnable configs working.
|
|
48
|
-
const keys = Object.keys(v);
|
|
49
|
-
if (keys.length === 1 && keys[0] === "fn" && typeof (v as { fn?: unknown }).fn === "function") {
|
|
46
|
+
// Current structural brand (a plain string property; survives JSON serialization).
|
|
47
|
+
if (v["__codemationItemExpr"] === "codemation.itemExpr" && typeof v["fn"] === "function") {
|
|
50
48
|
return true;
|
|
51
49
|
}
|
|
50
|
+
// Legacy: the old `Symbol.for("codemation.itemExpr")` brand (configs from an older core build).
|
|
52
51
|
for (const sym of Object.getOwnPropertySymbols(v)) {
|
|
53
52
|
if (sym.description === "codemation.itemExpr" && v[sym] === true) {
|
|
54
53
|
return true;
|
|
55
54
|
}
|
|
56
55
|
}
|
|
56
|
+
// Snapshot-hydrated wrappers where the brand was dropped but the callback survived.
|
|
57
|
+
const keys = Object.keys(v);
|
|
58
|
+
if (keys.length === 1 && keys[0] === "fn" && typeof (v as { fn?: unknown }).fn === "function") {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
57
61
|
return false;
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -76,6 +76,13 @@ export interface NodeConfigBase {
|
|
|
76
76
|
readonly name?: string;
|
|
77
77
|
readonly id?: NodeId;
|
|
78
78
|
readonly icon?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Plain-language, non-technical explanation of what this node does, surfaced in the workflow
|
|
81
|
+
* inspector / node properties sidebar. A first-class config option every authorable node accepts
|
|
82
|
+
* directly (alongside `id`), so it flows into the persisted config the mappers read. Distinct from
|
|
83
|
+
* {@link inspectorSummary} (config-derived label/value rows).
|
|
84
|
+
*/
|
|
85
|
+
readonly description?: string;
|
|
79
86
|
readonly execution?: Readonly<{ hint?: "local" | "worker"; queue?: string }>;
|
|
80
87
|
/** In-process execute retries (runnable nodes). Triggers typically omit this. */
|
|
81
88
|
readonly retryPolicy?: RetryPolicySpec;
|
|
@@ -19,11 +19,11 @@ export interface WorkspaceFileMetadata {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Workspace-scoped port for accessing the shared workspace file pool.
|
|
23
23
|
* Implemented in `@codemation/host`; nodes reach it via `ctx.resolve(WorkspaceFileStorageToken)`.
|
|
24
24
|
*
|
|
25
25
|
* Key scheme: `<workspaceId>/files/<fileId>` — but nodes never construct raw keys.
|
|
26
|
-
* Use the workspace-level helpers (`listFiles`, `getFileByName`, `getFileById`) instead.
|
|
26
|
+
* Use the workspace-level helpers (`listFiles`, `getFileByName`, `getFileById`, `writeFile`) instead.
|
|
27
27
|
*
|
|
28
28
|
* This adapter is SEPARATE from the run-scoped BinaryStorage — do not confuse the two.
|
|
29
29
|
*/
|
|
@@ -52,6 +52,25 @@ export interface IWorkspaceFileStorage {
|
|
|
52
52
|
* @throws WorkspaceFileNotFoundError when the key does not exist.
|
|
53
53
|
*/
|
|
54
54
|
getStream(key: string): Promise<ReadableStream<Uint8Array>>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Writes a file into the workspace's shared file pool.
|
|
58
|
+
*
|
|
59
|
+
* Generates a new fileId internally; the caller never constructs a raw key.
|
|
60
|
+
* Stamps the filename into object metadata so read-side adapters can resolve
|
|
61
|
+
* files by name without querying a registry.
|
|
62
|
+
*
|
|
63
|
+
* Returns the stored file's metadata (fileId, key, filename, contentType, size,
|
|
64
|
+
* lastModified). Callers that need concierge visibility must also register a
|
|
65
|
+
* WorkspaceFile row on the CP side via the HMAC-paired
|
|
66
|
+
* `POST /internal/workspace-files/register` endpoint — see the host-side
|
|
67
|
+
* `WorkspaceFileRegistrarClient`.
|
|
68
|
+
*
|
|
69
|
+
* @param filename Original filename; stored in object metadata.
|
|
70
|
+
* @param body Bytes to write (contiguous — required for presigned PUT Content-Length).
|
|
71
|
+
* @param contentType MIME type.
|
|
72
|
+
*/
|
|
73
|
+
writeFile(filename: string, body: Uint8Array, contentType: string): Promise<WorkspaceFileMetadata>;
|
|
55
74
|
}
|
|
56
75
|
|
|
57
76
|
/**
|
|
@@ -64,6 +83,17 @@ export class WorkspaceFileNotFoundError extends Error {
|
|
|
64
83
|
}
|
|
65
84
|
}
|
|
66
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Port for registering a workflow-written file in the CP's WorkspaceFile table.
|
|
88
|
+
* Optional: only wired when the host is paired with a control plane.
|
|
89
|
+
* Implemented by `WorkspaceFileRegistrarClient` in `@codemation/host`.
|
|
90
|
+
* Nodes call this after `writeFile` so the concierge can see the file via
|
|
91
|
+
* `list_files` / `get_file`.
|
|
92
|
+
*/
|
|
93
|
+
export interface IWorkspaceFileRegistrar {
|
|
94
|
+
register(meta: WorkspaceFileMetadata): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
67
97
|
/**
|
|
68
98
|
* DI token for the workspace-scoped file storage adapter.
|
|
69
99
|
* Registered by `@codemation/host`; resolved by workspace-file nodes via `ctx.resolve(...)`.
|
|
@@ -71,3 +101,13 @@ export class WorkspaceFileNotFoundError extends Error {
|
|
|
71
101
|
export const WorkspaceFileStorageToken = Symbol.for("codemation.core.WorkspaceFileStorage") as TypeToken<
|
|
72
102
|
IWorkspaceFileStorage | undefined
|
|
73
103
|
>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* DI token for the optional CP registry hook.
|
|
107
|
+
* Present only when the host is paired (managed mode). Standalone / local-fs
|
|
108
|
+
* deployments leave this undefined — workflow-written files will be in S3/local
|
|
109
|
+
* but will not appear in the concierge's list_files.
|
|
110
|
+
*/
|
|
111
|
+
export const WorkspaceFileRegistrarToken = Symbol.for("codemation.core.WorkspaceFileRegistrar") as TypeToken<
|
|
112
|
+
IWorkspaceFileRegistrar | undefined
|
|
113
|
+
>;
|
|
@@ -73,10 +73,17 @@ export class NodeOutputNormalizer {
|
|
|
73
73
|
return typeof value === "object" && value !== null && "json" in value;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
private isPlainJsonObject(value: unknown): value is Record<string, unknown> {
|
|
77
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
private applyOutput(baseItem: Item, next: Item, behavior: RunnableOutputBehavior): Item {
|
|
77
81
|
const explicitBinary = next.binary;
|
|
78
82
|
return {
|
|
79
|
-
json:
|
|
83
|
+
json:
|
|
84
|
+
behavior.mergeJson && this.isPlainJsonObject(baseItem.json) && this.isPlainJsonObject(next.json)
|
|
85
|
+
? { ...baseItem.json, ...next.json }
|
|
86
|
+
: next.json,
|
|
80
87
|
...(explicitBinary !== undefined
|
|
81
88
|
? { binary: explicitBinary }
|
|
82
89
|
: behavior.keepBinaries && baseItem.binary
|
|
@@ -5,14 +5,21 @@ type BinaryKeepingRunnableNodeConfig = RunnableNodeConfig &
|
|
|
5
5
|
keepBinaries?: boolean;
|
|
6
6
|
}>;
|
|
7
7
|
|
|
8
|
+
type MergeJsonRunnableNodeConfig = RunnableNodeConfig &
|
|
9
|
+
Readonly<{
|
|
10
|
+
mergeJson?: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
8
13
|
export type RunnableOutputBehavior = Readonly<{
|
|
9
14
|
keepBinaries: boolean;
|
|
15
|
+
mergeJson: boolean;
|
|
10
16
|
}>;
|
|
11
17
|
|
|
12
18
|
export class RunnableOutputBehaviorResolver {
|
|
13
19
|
resolve(config: RunnableNodeConfig): RunnableOutputBehavior {
|
|
14
20
|
return {
|
|
15
21
|
keepBinaries: this.isKeepBinariesEnabled(config),
|
|
22
|
+
mergeJson: this.isMergeJsonEnabled(config),
|
|
16
23
|
};
|
|
17
24
|
}
|
|
18
25
|
|
|
@@ -20,4 +27,9 @@ export class RunnableOutputBehaviorResolver {
|
|
|
20
27
|
const candidate = config as BinaryKeepingRunnableNodeConfig;
|
|
21
28
|
return candidate.keepBinaries === true;
|
|
22
29
|
}
|
|
30
|
+
|
|
31
|
+
private isMergeJsonEnabled(config: RunnableNodeConfig): boolean {
|
|
32
|
+
const candidate = config as MergeJsonRunnableNodeConfig;
|
|
33
|
+
return candidate.mergeJson === true;
|
|
34
|
+
}
|
|
23
35
|
}
|
package/src/index.ts
CHANGED
|
@@ -84,5 +84,13 @@ export type {
|
|
|
84
84
|
export { IllegalMaterialSourceError } from "./credentials/CredentialMaterialProvider.types";
|
|
85
85
|
export { ManagedCredentialMaterialWriteError } from "./credentials/ManagedCredentialMaterialWriteError";
|
|
86
86
|
export { ManagedMaterialFetchError } from "./credentials/ManagedMaterialFetchError";
|
|
87
|
-
export type {
|
|
88
|
-
|
|
87
|
+
export type {
|
|
88
|
+
IWorkspaceFileStorage,
|
|
89
|
+
IWorkspaceFileRegistrar,
|
|
90
|
+
WorkspaceFileMetadata,
|
|
91
|
+
} from "./contracts/workspaceFileTypes";
|
|
92
|
+
export {
|
|
93
|
+
WorkspaceFileNotFoundError,
|
|
94
|
+
WorkspaceFileStorageToken,
|
|
95
|
+
WorkspaceFileRegistrarToken,
|
|
96
|
+
} from "./contracts/workspaceFileTypes";
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
BranchStepsArg,
|
|
20
20
|
StepSequenceOutput,
|
|
21
21
|
} from "./workflowBuilderTypes";
|
|
22
|
+
import { mergeForward } from "./workflowBuilderTypes";
|
|
22
23
|
|
|
23
24
|
type ChainCursorEndpoint = Readonly<{ node: NodeRef; output: OutputPortKey; inputPortHint?: InputPortKey }>;
|
|
24
25
|
|
|
@@ -56,6 +57,18 @@ export class ChainCursor<TCurrentJson> {
|
|
|
56
57
|
]);
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Append a step whose output is MERGED onto `item.json` (shallow, output-wins) instead of
|
|
62
|
+
* replacing it — so earlier fields (e.g. trigger metadata) survive a transform/OCR/extraction
|
|
63
|
+
* node. Use for any node in a pipeline where you need data from before it.
|
|
64
|
+
*/
|
|
65
|
+
thenMerge<TOutputJson, TConfig extends RunnableNodeConfig<TCurrentJson, TOutputJson>>(
|
|
66
|
+
config: TConfig,
|
|
67
|
+
): ChainCursor<TCurrentJson & RunnableNodeOutputJson<TConfig>> {
|
|
68
|
+
mergeForward(config);
|
|
69
|
+
return this.then(config) as unknown as ChainCursor<TCurrentJson & RunnableNodeOutputJson<TConfig>>;
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
thenIntoInputHints<TOutputJson, TConfig extends RunnableNodeConfig<any, TOutputJson>>(
|
|
60
73
|
config: TConfig,
|
|
61
74
|
): ChainCursor<RunnableNodeOutputJson<TConfig>> {
|
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
InputPortKey,
|
|
3
|
+
NodeId,
|
|
4
|
+
NodeRef,
|
|
5
|
+
OutputPortKey,
|
|
6
|
+
RunnableNodeConfig,
|
|
7
|
+
RunnableNodeOutputJson,
|
|
8
|
+
UpstreamRefPlaceholder,
|
|
9
|
+
WorkflowDefinition,
|
|
10
|
+
} from "../../types";
|
|
2
11
|
|
|
12
|
+
import type { DefinedNodeCredentialBindings } from "../../authoring/defineNode.types";
|
|
13
|
+
import type { DefinedHumanApprovalNode, HumanApprovalOutputJson } from "../../authoring/defineHumanApprovalNode.types";
|
|
3
14
|
import { WorkflowBuilder } from "./WorkflowBuilder";
|
|
15
|
+
import { ChainCursor } from "./ChainCursorResolver";
|
|
4
16
|
import type { AnyRunnableNodeConfig, BooleanWhenOverloads, ValidStepSequence } from "./workflowBuilderTypes";
|
|
5
17
|
|
|
18
|
+
/** Structurally identical to ChainCursorResolver's (unexported) ChainCursorEndpoint. */
|
|
19
|
+
type WhenEndpoint = Readonly<{ node: NodeRef; output: OutputPortKey; inputPortHint?: InputPortKey }>;
|
|
20
|
+
|
|
6
21
|
export class WhenBuilder<TCurrentJson> {
|
|
22
|
+
/** Tail endpoint of the arm this builder added (set by addBranch). */
|
|
23
|
+
private armEndpoint: WhenEndpoint | undefined;
|
|
24
|
+
|
|
7
25
|
constructor(
|
|
8
26
|
private readonly wf: WorkflowBuilder,
|
|
9
27
|
private readonly from: NodeRef,
|
|
10
28
|
private readonly branchPort: OutputPortKey,
|
|
29
|
+
/** Tails of arms added by earlier `.when(...)` calls in this chain. */
|
|
30
|
+
private readonly priorEndpoints: ReadonlyArray<WhenEndpoint> = [],
|
|
11
31
|
) {}
|
|
12
32
|
|
|
13
33
|
addBranch<TSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(
|
|
@@ -36,6 +56,12 @@ export class WhenBuilder<TCurrentJson> {
|
|
|
36
56
|
});
|
|
37
57
|
}
|
|
38
58
|
|
|
59
|
+
// An empty arm rejoins straight from the `from` node's branch port (mirrors the
|
|
60
|
+
// object-form `buildBranch` returning `{ end: cursor, endOutput: port }`).
|
|
61
|
+
this.armEndpoint = prev
|
|
62
|
+
? { node: prev, output: "main", inputPortHint: this.branchPort }
|
|
63
|
+
: { node: this.from, output: this.branchPort, inputPortHint: this.branchPort };
|
|
64
|
+
|
|
39
65
|
return this;
|
|
40
66
|
}
|
|
41
67
|
|
|
@@ -46,12 +72,50 @@ export class WhenBuilder<TCurrentJson> {
|
|
|
46
72
|
): WhenBuilder<TCurrentJson> => {
|
|
47
73
|
const list = Array.isArray(steps) ? steps : [steps, ...more];
|
|
48
74
|
const port: OutputPortKey = branch ? "true" : "false";
|
|
49
|
-
const b = new WhenBuilder<TCurrentJson>(this.wf, this.from, port);
|
|
75
|
+
const b = new WhenBuilder<TCurrentJson>(this.wf, this.from, port, this.accumulatedEndpoints);
|
|
50
76
|
b.addBranch(list);
|
|
51
77
|
return b;
|
|
52
78
|
};
|
|
53
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Continue the trunk after a boolean `.when(...)` branch chain, auto-merging EVERY branch
|
|
82
|
+
* tail accumulated across the chain into the next node — the same fan-in the object form
|
|
83
|
+
* produces. Typed as `ChainCursor<TCurrentJson>` (the pre-branch item type): boolean arms
|
|
84
|
+
* carry no output guard so the merged item type is underdetermined — use the object form
|
|
85
|
+
* `.when({ true: [...], false: [...] })` when you need a precise merged type inline.
|
|
86
|
+
*/
|
|
87
|
+
then<TOutputJson, TConfig extends RunnableNodeConfig<TCurrentJson, TOutputJson>>(
|
|
88
|
+
config: TConfig,
|
|
89
|
+
): ChainCursor<RunnableNodeOutputJson<TConfig>> {
|
|
90
|
+
return this.toCursor().then(config);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Chainable human-approval step after a boolean `.when(...)` branch chain — merges every
|
|
95
|
+
* branch tail into the approval node. Mirrors `ChainCursor.humanApproval`.
|
|
96
|
+
*/
|
|
97
|
+
humanApproval<
|
|
98
|
+
TKey extends string,
|
|
99
|
+
TConfig extends Record<string, unknown>,
|
|
100
|
+
TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
|
|
101
|
+
>(
|
|
102
|
+
node: DefinedHumanApprovalNode<TKey, TConfig, TCurrentJson & Record<string, unknown>, TBindings>,
|
|
103
|
+
config: TConfig,
|
|
104
|
+
metadata?: { name?: string; nodeId?: string },
|
|
105
|
+
): ChainCursor<HumanApprovalOutputJson<TCurrentJson & Record<string, unknown>>> {
|
|
106
|
+
return this.toCursor().humanApproval(node, config, metadata);
|
|
107
|
+
}
|
|
108
|
+
|
|
54
109
|
build(): WorkflowDefinition {
|
|
55
110
|
return this.wf.build();
|
|
56
111
|
}
|
|
112
|
+
|
|
113
|
+
/** Endpoints of every arm added so far in this chain (prior arms + this one). */
|
|
114
|
+
private get accumulatedEndpoints(): ReadonlyArray<WhenEndpoint> {
|
|
115
|
+
return this.armEndpoint ? [...this.priorEndpoints, this.armEndpoint] : this.priorEndpoints;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private toCursor(): ChainCursor<TCurrentJson> {
|
|
119
|
+
return new ChainCursor<TCurrentJson>(this.wf, this.accumulatedEndpoints);
|
|
120
|
+
}
|
|
57
121
|
}
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import type { RunnableNodeConfig, RunnableNodeOutputJson, TriggerNodeConfig } from "../../types";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Flags a node's config so its output is MERGED onto `item.json` (shallow, output-wins) instead of
|
|
5
|
+
* replacing it — the config-level twin of {@link ChainCursor.thenMerge}.
|
|
6
|
+
*
|
|
7
|
+
* Unlike `.thenMerge` (a cursor method that only works on the trunk), `mergeForward` operates on a
|
|
8
|
+
* bare config, so it is usable in ANY position — including inside a `.when({ true: [...] })` branch
|
|
9
|
+
* arm, where the steps are a flat array of configs (not a cursor). Wrap a payload-REPLACING node
|
|
10
|
+
* (e.g. an extractor) in `mergeForward(node.create(...))` so prior fields survive into the next step.
|
|
11
|
+
*
|
|
12
|
+
* The OUTPUT type becomes `TIn & TOut` (the intersection), mirroring `.thenMerge`'s return type at
|
|
13
|
+
* the config level — so the next step in the branch array sees both the prior fields and the node's
|
|
14
|
+
* output. The INPUT type stays `TIn` (the node still receives the pre-merge item).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* workflow
|
|
19
|
+
* .trigger(...)
|
|
20
|
+
* .when({
|
|
21
|
+
* true: [mergeForward(extractor.create(...))], // output merges onto item.json; { a } survives
|
|
22
|
+
* false: [...],
|
|
23
|
+
* })
|
|
24
|
+
* .build();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function mergeForward<TIn, TOut>(config: RunnableNodeConfig<TIn, TOut>): RunnableNodeConfig<TIn, TIn & TOut> {
|
|
28
|
+
(config as { mergeJson?: boolean }).mergeJson = true;
|
|
29
|
+
return config as unknown as RunnableNodeConfig<TIn, TIn & TOut>;
|
|
30
|
+
}
|
|
31
|
+
|
|
3
32
|
export type AnyRunnableNodeConfig = RunnableNodeConfig<any, any>;
|
|
4
33
|
|
|
5
34
|
export type AnyTriggerNodeConfig = TriggerNodeConfig<any>;
|