@xyne/workflow-sdk 3.2.37 → 3.2.38
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/agents/agent-step.d.ts +2 -2
- package/dist/agents/host-agent-step.d.ts +1 -1
- package/dist/builder/index.d.ts +2 -2
- package/dist/builder/index.d.ts.map +1 -1
- package/dist/builder/index.js +1 -1
- package/dist/builder/index.js.map +1 -1
- package/dist/client/types.d.ts +7 -5
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/workflow-client.d.ts.map +1 -1
- package/dist/client/workflow-client.js +7 -0
- package/dist/client/workflow-client.js.map +1 -1
- package/dist/common/citation-ref.d.ts +4 -4
- package/dist/common/credentials.d.ts +107 -0
- package/dist/common/credentials.d.ts.map +1 -1
- package/dist/common/credentials.js +67 -0
- package/dist/common/credentials.js.map +1 -1
- package/dist/common/index.d.ts +2 -2
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +2 -2
- package/dist/common/index.js.map +1 -1
- package/dist/connectors/builtin/builtin-connector.d.ts +32 -0
- package/dist/connectors/builtin/builtin-connector.d.ts.map +1 -0
- package/dist/connectors/builtin/builtin-connector.js +62 -0
- package/dist/connectors/builtin/builtin-connector.js.map +1 -0
- package/dist/connectors/builtin/credentials.d.ts +18 -0
- package/dist/connectors/builtin/credentials.d.ts.map +1 -0
- package/dist/connectors/builtin/credentials.js +50 -0
- package/dist/connectors/builtin/credentials.js.map +1 -0
- package/dist/connectors/builtin/steps/code.step.d.ts +99 -0
- package/dist/connectors/builtin/steps/code.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/code.step.js +152 -0
- package/dist/connectors/builtin/steps/code.step.js.map +1 -0
- package/dist/connectors/builtin/steps/conditional.step.d.ts +182 -0
- package/dist/connectors/builtin/steps/conditional.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/conditional.step.js +82 -0
- package/dist/connectors/builtin/steps/conditional.step.js.map +1 -0
- package/dist/connectors/builtin/steps/dedup.step.d.ts +65 -0
- package/dist/connectors/builtin/steps/dedup.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/dedup.step.js +61 -0
- package/dist/connectors/builtin/steps/dedup.step.js.map +1 -0
- package/dist/connectors/builtin/steps/http-request.step.d.ts +1027 -0
- package/dist/connectors/builtin/steps/http-request.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/http-request.step.js +497 -0
- package/dist/connectors/builtin/steps/http-request.step.js.map +1 -0
- package/dist/connectors/builtin/steps/loop.step.d.ts +100 -0
- package/dist/connectors/builtin/steps/loop.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/loop.step.js +73 -0
- package/dist/connectors/builtin/steps/loop.step.js.map +1 -0
- package/dist/connectors/builtin/steps/map.step.d.ts +148 -0
- package/dist/connectors/builtin/steps/map.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/map.step.js +111 -0
- package/dist/connectors/builtin/steps/map.step.js.map +1 -0
- package/dist/connectors/builtin/steps/parallel.step.d.ts +246 -0
- package/dist/connectors/builtin/steps/parallel.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/parallel.step.js +175 -0
- package/dist/connectors/builtin/steps/parallel.step.js.map +1 -0
- package/dist/connectors/builtin/steps/ssrf-guard.d.ts +9 -0
- package/dist/connectors/builtin/steps/ssrf-guard.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/ssrf-guard.js +115 -0
- package/dist/connectors/builtin/steps/ssrf-guard.js.map +1 -0
- package/dist/connectors/builtin/steps/switch.step.d.ts +235 -0
- package/dist/connectors/builtin/steps/switch.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/switch.step.js +101 -0
- package/dist/connectors/builtin/steps/switch.step.js.map +1 -0
- package/dist/connectors/builtin/steps/wait.step.d.ts +1072 -0
- package/dist/connectors/builtin/steps/wait.step.d.ts.map +1 -0
- package/dist/connectors/builtin/steps/wait.step.js +254 -0
- package/dist/connectors/builtin/steps/wait.step.js.map +1 -0
- package/dist/connectors/builtin/triggers/default-cron-trigger.d.ts +44 -0
- package/dist/connectors/builtin/triggers/default-cron-trigger.d.ts.map +1 -0
- package/dist/connectors/builtin/triggers/default-cron-trigger.js +31 -0
- package/dist/connectors/builtin/triggers/default-cron-trigger.js.map +1 -0
- package/dist/connectors/builtin/triggers/default-event-trigger.d.ts +32 -0
- package/dist/connectors/builtin/triggers/default-event-trigger.d.ts.map +1 -0
- package/dist/connectors/builtin/triggers/default-event-trigger.js +21 -0
- package/dist/connectors/builtin/triggers/default-event-trigger.js.map +1 -0
- package/dist/connectors/builtin/triggers/default-manual-trigger.d.ts +45 -0
- package/dist/connectors/builtin/triggers/default-manual-trigger.d.ts.map +1 -0
- package/dist/connectors/builtin/triggers/default-manual-trigger.js +51 -0
- package/dist/connectors/builtin/triggers/default-manual-trigger.js.map +1 -0
- package/dist/connectors/builtin/triggers/default-webhook-v2-trigger.d.ts +31 -0
- package/dist/connectors/builtin/triggers/default-webhook-v2-trigger.d.ts.map +1 -0
- package/dist/connectors/builtin/triggers/default-webhook-v2-trigger.js +40 -0
- package/dist/connectors/builtin/triggers/default-webhook-v2-trigger.js.map +1 -0
- package/dist/connectors/core/base-connector.d.ts +45 -0
- package/dist/connectors/core/base-connector.d.ts.map +1 -0
- package/dist/connectors/core/base-connector.js +3 -0
- package/dist/connectors/core/base-connector.js.map +1 -0
- package/dist/connectors/core/connector-registry.d.ts +130 -0
- package/dist/connectors/core/connector-registry.d.ts.map +1 -0
- package/dist/connectors/core/connector-registry.js +357 -0
- package/dist/connectors/core/connector-registry.js.map +1 -0
- package/dist/connectors/core/credentials.d.ts +104 -0
- package/dist/connectors/core/credentials.d.ts.map +1 -0
- package/dist/connectors/core/credentials.js +67 -0
- package/dist/connectors/core/credentials.js.map +1 -0
- package/dist/connectors/core/index.d.ts +7 -0
- package/dist/connectors/core/index.d.ts.map +1 -0
- package/dist/connectors/core/index.js +5 -0
- package/dist/connectors/core/index.js.map +1 -0
- package/dist/engine/available-context.d.ts +3 -4
- package/dist/engine/available-context.d.ts.map +1 -1
- package/dist/engine/available-context.js +17 -13
- package/dist/engine/available-context.js.map +1 -1
- package/dist/engine/config-validator.d.ts +13 -5
- package/dist/engine/config-validator.d.ts.map +1 -1
- package/dist/engine/config-validator.js +89 -11
- package/dist/engine/config-validator.js.map +1 -1
- package/dist/engine/credential-resolver.d.ts +42 -0
- package/dist/engine/credential-resolver.d.ts.map +1 -0
- package/dist/engine/credential-resolver.js +63 -0
- package/dist/engine/credential-resolver.js.map +1 -0
- package/dist/engine/workflow-executor.d.ts +4 -5
- package/dist/engine/workflow-executor.d.ts.map +1 -1
- package/dist/engine/workflow-executor.js +16 -38
- package/dist/engine/workflow-executor.js.map +1 -1
- package/dist/index.d.ts +43 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -15
- package/dist/index.js.map +1 -1
- package/dist/ingest/body.d.ts +18 -0
- package/dist/ingest/body.d.ts.map +1 -0
- package/dist/ingest/body.js +47 -0
- package/dist/ingest/body.js.map +1 -0
- package/dist/ingest/filter.d.ts +11 -0
- package/dist/ingest/filter.d.ts.map +1 -0
- package/dist/ingest/filter.js +23 -0
- package/dist/ingest/filter.js.map +1 -0
- package/dist/ingest/headers.d.ts +3 -0
- package/dist/ingest/headers.d.ts.map +1 -0
- package/dist/ingest/headers.js +11 -0
- package/dist/ingest/headers.js.map +1 -0
- package/dist/ingest/types.d.ts +50 -0
- package/dist/ingest/types.d.ts.map +1 -0
- package/dist/ingest/types.js +9 -0
- package/dist/ingest/types.js.map +1 -0
- package/dist/persistence/in-memory-adapter.d.ts +4 -8
- package/dist/persistence/in-memory-adapter.d.ts.map +1 -1
- package/dist/persistence/in-memory-adapter.js +8 -25
- package/dist/persistence/in-memory-adapter.js.map +1 -1
- package/dist/persistence/types.d.ts +5 -19
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/router/types.d.ts +31 -3
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/workflow-router.d.ts +4 -3
- package/dist/router/workflow-router.d.ts.map +1 -1
- package/dist/router/workflow-router.js +66 -40
- package/dist/router/workflow-router.js.map +1 -1
- package/dist/runtime/types.d.ts +6 -4
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/workflow-runtime.d.ts +43 -37
- package/dist/runtime/workflow-runtime.d.ts.map +1 -1
- package/dist/runtime/workflow-runtime.js +158 -133
- package/dist/runtime/workflow-runtime.js.map +1 -1
- package/dist/steps/base-step.d.ts +23 -0
- package/dist/steps/base-step.d.ts.map +1 -1
- package/dist/steps/base-step.js +22 -0
- package/dist/steps/base-step.js.map +1 -1
- package/dist/steps/step-descriptor.d.ts +52 -0
- package/dist/steps/step-descriptor.d.ts.map +1 -0
- package/dist/steps/step-descriptor.js +32 -0
- package/dist/steps/step-descriptor.js.map +1 -0
- package/dist/testing/authz-conformance.d.ts.map +1 -1
- package/dist/testing/authz-conformance.js +6 -7
- package/dist/testing/authz-conformance.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock-step-context.d.ts +1 -0
- package/dist/testing/mock-step-context.d.ts.map +1 -1
- package/dist/testing/mock-step-context.js +1 -0
- package/dist/testing/mock-step-context.js.map +1 -1
- package/dist/testing/test-connector.d.ts +40 -0
- package/dist/testing/test-connector.d.ts.map +1 -0
- package/dist/testing/test-connector.js +39 -0
- package/dist/testing/test-connector.js.map +1 -0
- package/dist/triggers/api-trigger.d.ts +15 -0
- package/dist/triggers/api-trigger.d.ts.map +1 -0
- package/dist/triggers/api-trigger.js +14 -0
- package/dist/triggers/api-trigger.js.map +1 -0
- package/dist/triggers/base-trigger.d.ts +29 -0
- package/dist/triggers/base-trigger.d.ts.map +1 -1
- package/dist/triggers/base-trigger.js +16 -0
- package/dist/triggers/base-trigger.js.map +1 -1
- package/dist/triggers/trigger-descriptor.d.ts +42 -0
- package/dist/triggers/trigger-descriptor.d.ts.map +1 -0
- package/dist/triggers/trigger-descriptor.js +29 -0
- package/dist/triggers/trigger-descriptor.js.map +1 -0
- package/dist/triggers/webhook-trigger.d.ts +31 -38
- package/dist/triggers/webhook-trigger.d.ts.map +1 -1
- package/dist/triggers/webhook-trigger.js +19 -6
- package/dist/triggers/webhook-trigger.js.map +1 -1
- package/dist/types/known-types.d.ts +0 -1
- package/dist/types/known-types.d.ts.map +1 -1
- package/dist/types/known-types.js +0 -1
- package/dist/types/known-types.js.map +1 -1
- package/dist/types/validation.d.ts +3 -1
- package/dist/types/validation.d.ts.map +1 -1
- package/dist/types/validation.js +2 -0
- package/dist/types/validation.js.map +1 -1
- package/dist/types/workflow-config.d.ts +23 -0
- package/dist/types/workflow-config.d.ts.map +1 -1
- package/dist/types/workflow-config.js +8 -0
- package/dist/types/workflow-config.js.map +1 -1
- package/dist/util/credential-slot-schema.d.ts +20 -0
- package/dist/util/credential-slot-schema.d.ts.map +1 -0
- package/dist/util/credential-slot-schema.js +30 -0
- package/dist/util/credential-slot-schema.js.map +1 -0
- package/package.json +1 -1
|
@@ -22,9 +22,8 @@ import type { CredentialSummary, CredentialListItem, ResolvedCredential, CreateC
|
|
|
22
22
|
import type { Action } from '../authz/types.js';
|
|
23
23
|
import type { ResourceAttributes } from '../authz/attributes.js';
|
|
24
24
|
import type { IdScope } from '../authz/id-scope.js';
|
|
25
|
-
import type {
|
|
26
|
-
import type {
|
|
27
|
-
import type { WebhookRequest } from '../triggers/webhook-trigger.js';
|
|
25
|
+
import type { ConnectorRegistry } from '../connectors/core/connector-registry.js';
|
|
26
|
+
import type { InboundHttpRequest, WebhookIngestResult } from '../ingest/types.js';
|
|
28
27
|
export declare class WorkflowRuntime<TServices extends Record<string, unknown> = Record<string, unknown>, TCtx = unknown, TFilter = IdScope> {
|
|
29
28
|
private readonly persistence;
|
|
30
29
|
/** Authorization port — host-supplied, always. See {@link RuntimeOptions.authorizer}. */
|
|
@@ -32,9 +31,9 @@ export declare class WorkflowRuntime<TServices extends Record<string, unknown> =
|
|
|
32
31
|
private readonly queue;
|
|
33
32
|
private readonly scheduler;
|
|
34
33
|
private readonly services;
|
|
35
|
-
readonly
|
|
36
|
-
readonly triggers: TriggerRegistry;
|
|
34
|
+
readonly connectors: ConnectorRegistry;
|
|
37
35
|
private readonly executor;
|
|
36
|
+
private readonly credentialResolver;
|
|
38
37
|
private readonly log;
|
|
39
38
|
private readonly baseUrl;
|
|
40
39
|
/** Pub/sub transport for live execution events. Exposed for the router's SSE stream. */
|
|
@@ -114,9 +113,11 @@ export declare class WorkflowRuntime<TServices extends Record<string, unknown> =
|
|
|
114
113
|
/**
|
|
115
114
|
* Activate a workflow's trigger.
|
|
116
115
|
*
|
|
117
|
-
* -
|
|
116
|
+
* - Every trigger: its credential slots must resolve to accepted credentials
|
|
118
117
|
* - CronTrigger: registers with the scheduler
|
|
119
|
-
*
|
|
118
|
+
*
|
|
119
|
+
* Only then is the workflow marked ACTIVE. Webhook ingest and event dispatch
|
|
120
|
+
* both key off that status, so it is what actually turns a workflow on.
|
|
120
121
|
*/
|
|
121
122
|
activateWorkflow(ctx: TCtx, workflowId: string, opts?: MutationOptions): Promise<void>;
|
|
122
123
|
/**
|
|
@@ -157,19 +158,23 @@ export declare class WorkflowRuntime<TServices extends Record<string, unknown> =
|
|
|
157
158
|
*/
|
|
158
159
|
dispatchEvent(event: DispatchEventInput): Promise<string[]>;
|
|
159
160
|
/**
|
|
160
|
-
*
|
|
161
|
+
* Ingest a request to a workflow's webhook URL, `<baseUrl>/webhooks/<workflowId>`.
|
|
161
162
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
163
|
+
* The order is fixed, and the trigger's own code runs only after the sender is
|
|
164
|
+
* authenticated:
|
|
165
|
+
*
|
|
166
|
+
* 1. The workflow exists, is ACTIVE and uses a webhook trigger — else 404, the
|
|
167
|
+
* same answer for each so workflow ids cannot be probed.
|
|
168
|
+
* 2. The trigger's credentials resolve — else 401, before any connector code runs.
|
|
169
|
+
* 3. The trigger's own `verify` accepts the request — else 401.
|
|
170
|
+
* 4. The body is parsed from the raw bytes — else 400.
|
|
171
|
+
* 5. The trigger turns the request into events and a reply.
|
|
172
|
+
* 6. Each event must pass the workflow's trigger filter, or it is dropped.
|
|
173
|
+
* 7. Survivors are enqueued before the reply is returned.
|
|
174
|
+
*
|
|
175
|
+
* Reasons for a rejection go to the log; responses stay generic.
|
|
176
|
+
*/
|
|
177
|
+
handleWebhook(workflowId: string, request: InboundHttpRequest): Promise<WebhookIngestResult>;
|
|
173
178
|
/**
|
|
174
179
|
* Handle an incoming wait-callback at `POST /wait/callback/<secret>/<executionId>`.
|
|
175
180
|
*
|
|
@@ -208,31 +213,32 @@ export declare class WorkflowRuntime<TServices extends Record<string, unknown> =
|
|
|
208
213
|
*/
|
|
209
214
|
triggerManual(ctx: TCtx, workflowId: string, payload: Record<string, unknown>): Promise<string>;
|
|
210
215
|
/**
|
|
211
|
-
*
|
|
216
|
+
* Start a workflow from the API trigger route.
|
|
217
|
+
*
|
|
218
|
+
* No caller reaches the SDK here: the route has no session, and the SDK does
|
|
219
|
+
* not authorize whoever calls it. A host that exposes the route guards it
|
|
220
|
+
* itself, for example with an API key. The workflow must use an API trigger,
|
|
221
|
+
* and the payload must satisfy its input schema.
|
|
212
222
|
*
|
|
213
|
-
*
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
223
|
+
* Runs are marked as public triggers, so privileged steps refuse them.
|
|
224
|
+
*/
|
|
225
|
+
triggerViaApi(workflowId: string, payload: Record<string, unknown>): Promise<string>;
|
|
226
|
+
/**
|
|
227
|
+
* What the API trigger route needs before it builds a payload: the trigger's
|
|
228
|
+
* input schema, and the workflow's scope for storing uploaded files. Checked
|
|
229
|
+
* the same way as {@link triggerViaApi}.
|
|
217
230
|
*/
|
|
218
|
-
|
|
231
|
+
getApiTriggerTarget(workflowId: string): Promise<{
|
|
232
|
+
inputSchema: Record<string, unknown> | undefined;
|
|
233
|
+
storageScope: ResourceAttributes<'workflow'>;
|
|
234
|
+
}>;
|
|
235
|
+
/** The workflow exists and uses an API trigger. */
|
|
236
|
+
private apiTriggerWorkflow;
|
|
219
237
|
/**
|
|
220
238
|
* Return the configured trigger input schema for routes that need to translate
|
|
221
239
|
* transport-level payloads before calling `triggerManual()`.
|
|
222
240
|
*/
|
|
223
241
|
getWorkflowTriggerInputSchema(ctx: TCtx, workflowId: string): Promise<Record<string, unknown> | undefined>;
|
|
224
|
-
/**
|
|
225
|
-
* Return trigger input schema for public transport routes.
|
|
226
|
-
*
|
|
227
|
-
* Unlike getWorkflowTriggerInputSchema(), this does not authorize a caller;
|
|
228
|
-
* it only verifies the workflow exists and opted into the expected public
|
|
229
|
-
* trigger type.
|
|
230
|
-
*/
|
|
231
|
-
getWorkflowTriggerInputSchemaPublic(workflowId: string, expectedTriggerType: string): Promise<Record<string, unknown> | undefined>;
|
|
232
|
-
/**
|
|
233
|
-
* Return the workflow-owned storage scope for public transport routes.
|
|
234
|
-
*/
|
|
235
|
-
getWorkflowStorageScopePublic(workflowId: string, expectedTriggerType: string): Promise<ResourceAttributes<'workflow'>>;
|
|
236
242
|
/**
|
|
237
243
|
* Resume a paused execution. Guards `execution:approve`, then does the work.
|
|
238
244
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/workflow-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAEV,eAAe,EAIhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,EACV,sBAAsB,EAIvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAEV,MAAM,EAGP,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"workflow-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/workflow-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,10 +18,18 @@ import { validateTriggerPayload } from '../common/validate-payload.js';
|
|
|
18
18
|
import { AccessDeniedError, ResourceNotFoundError } from '../authz/default.js';
|
|
19
19
|
import { EventTrigger } from '../triggers/event-trigger.js';
|
|
20
20
|
import { WebhookTrigger } from '../triggers/webhook-trigger.js';
|
|
21
|
+
import { ApiTrigger } from '../triggers/api-trigger.js';
|
|
22
|
+
import { CredentialResolver } from '../engine/credential-resolver.js';
|
|
23
|
+
import { headerValue } from '../ingest/headers.js';
|
|
24
|
+
import { parseInboundBody } from '../ingest/body.js';
|
|
25
|
+
import { matchesTriggerFilter } from '../ingest/filter.js';
|
|
21
26
|
import { CronTrigger } from '../triggers/cron-trigger.js';
|
|
22
27
|
import { PauseStep } from '../engine/pause-step.js';
|
|
23
28
|
import { leafStepId } from '../engine/node-path.js';
|
|
24
29
|
// ─── Helpers ───
|
|
30
|
+
function messageOf(err) {
|
|
31
|
+
return err instanceof Error ? err.message : String(err);
|
|
32
|
+
}
|
|
25
33
|
const noopLogger = {
|
|
26
34
|
info: () => { },
|
|
27
35
|
warn: () => { },
|
|
@@ -32,6 +40,13 @@ function generateSecret() {
|
|
|
32
40
|
crypto.getRandomValues(bytes);
|
|
33
41
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
34
42
|
}
|
|
43
|
+
/** The trigger's author-supplied input schema, when it has one. */
|
|
44
|
+
function inputSchemaOf(config) {
|
|
45
|
+
const inputSchema = (config.trigger.config ?? {})['inputSchema'];
|
|
46
|
+
return inputSchema && typeof inputSchema === 'object' && !Array.isArray(inputSchema)
|
|
47
|
+
? inputSchema
|
|
48
|
+
: undefined;
|
|
49
|
+
}
|
|
35
50
|
function parseWorkflowConfig(raw) {
|
|
36
51
|
return JSON.parse(raw ?? '{}');
|
|
37
52
|
}
|
|
@@ -69,9 +84,9 @@ export class WorkflowRuntime {
|
|
|
69
84
|
queue;
|
|
70
85
|
scheduler;
|
|
71
86
|
services;
|
|
72
|
-
|
|
73
|
-
triggers;
|
|
87
|
+
connectors;
|
|
74
88
|
executor;
|
|
89
|
+
credentialResolver;
|
|
75
90
|
log;
|
|
76
91
|
baseUrl;
|
|
77
92
|
/** Pub/sub transport for live execution events. Exposed for the router's SSE stream. */
|
|
@@ -95,9 +110,9 @@ export class WorkflowRuntime {
|
|
|
95
110
|
this.queue = opts.queue;
|
|
96
111
|
this.scheduler = opts.scheduler;
|
|
97
112
|
this.services = opts.services;
|
|
98
|
-
this.
|
|
99
|
-
this.triggers = opts.triggers;
|
|
113
|
+
this.connectors = opts.connectors;
|
|
100
114
|
this.executor = opts.executor;
|
|
115
|
+
this.credentialResolver = new CredentialResolver(opts.persistence);
|
|
101
116
|
this.log = opts.logger ?? noopLogger;
|
|
102
117
|
this.eventBus = opts.eventBus;
|
|
103
118
|
this.storage = opts.storage;
|
|
@@ -247,23 +262,26 @@ export class WorkflowRuntime {
|
|
|
247
262
|
* can render inline in the workflow builder.
|
|
248
263
|
*/
|
|
249
264
|
validateConfig(config) {
|
|
250
|
-
const validator = new ConfigValidator(this.
|
|
265
|
+
const validator = new ConfigValidator(this.connectors);
|
|
251
266
|
return validator.validate(config);
|
|
252
267
|
}
|
|
253
268
|
// ─── Workflow Lifecycle ───
|
|
254
269
|
/**
|
|
255
270
|
* Activate a workflow's trigger.
|
|
256
271
|
*
|
|
257
|
-
* -
|
|
272
|
+
* - Every trigger: its credential slots must resolve to accepted credentials
|
|
258
273
|
* - CronTrigger: registers with the scheduler
|
|
259
|
-
*
|
|
274
|
+
*
|
|
275
|
+
* Only then is the workflow marked ACTIVE. Webhook ingest and event dispatch
|
|
276
|
+
* both key off that status, so it is what actually turns a workflow on.
|
|
260
277
|
*/
|
|
261
278
|
async activateWorkflow(ctx, workflowId, opts) {
|
|
262
279
|
// Guard up front, before any external side-effects (webhook/scheduler).
|
|
263
280
|
const { record } = await this.authorizedWorkflow(ctx, workflowId, 'workflow:activate');
|
|
264
281
|
await this.activateInternal(record);
|
|
265
|
-
|
|
266
|
-
//
|
|
282
|
+
await this.persistence.updateWorkflow(workflowId, { status: 'ACTIVE' });
|
|
283
|
+
// After the side-effects, never before: an activation that failed is not a
|
|
284
|
+
// change worth telling anyone about.
|
|
267
285
|
this.publishWorkflowChange(workflowId, 'activated', opts?.origin);
|
|
268
286
|
}
|
|
269
287
|
/**
|
|
@@ -274,20 +292,16 @@ export class WorkflowRuntime {
|
|
|
274
292
|
async activateInternal(workflow) {
|
|
275
293
|
const workflowId = workflow.id;
|
|
276
294
|
const config = parseWorkflowConfig(workflow.config);
|
|
277
|
-
if (!this.
|
|
295
|
+
if (!this.connectors.hasTrigger(config.trigger.type)) {
|
|
278
296
|
throw new Error(`Trigger type "${config.trigger.type}" is not registered`);
|
|
279
297
|
}
|
|
280
|
-
const trigger = this.
|
|
298
|
+
const trigger = this.connectors.getTrigger(config.trigger.type);
|
|
299
|
+
// A missing, revoked or wrong-type credential fails here, naming the slot,
|
|
300
|
+
// rather than on the first event.
|
|
301
|
+
if (trigger.credentialSlots?.length) {
|
|
302
|
+
await this.credentialResolver.resolve(workflow.attributes, trigger, config.trigger.config);
|
|
303
|
+
}
|
|
281
304
|
if (trigger instanceof WebhookTrigger) {
|
|
282
|
-
const secret = generateSecret();
|
|
283
|
-
const path = `/webhooks/${workflowId}/${secret}`;
|
|
284
|
-
await this.persistence.storeWebhookPath(workflowId, path, secret);
|
|
285
|
-
if (trigger.onActivate) {
|
|
286
|
-
await trigger.onActivate(config.trigger.config, {
|
|
287
|
-
webhookUrl: this.baseUrl + path,
|
|
288
|
-
credentials: {},
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
305
|
this.log.info(`activated webhook trigger for workflow ${workflowId}`);
|
|
292
306
|
}
|
|
293
307
|
else if (trigger instanceof CronTrigger) {
|
|
@@ -310,24 +324,16 @@ export class WorkflowRuntime {
|
|
|
310
324
|
// Falls through rather than returning early on an unregistered trigger type:
|
|
311
325
|
// the call still succeeded, and every successful call must leave by the same
|
|
312
326
|
// door so that none of them can quietly skip the notification below.
|
|
313
|
-
const trigger = this.
|
|
314
|
-
? this.
|
|
327
|
+
const trigger = this.connectors.hasTrigger(config.trigger.type)
|
|
328
|
+
? this.connectors.getTrigger(config.trigger.type)
|
|
315
329
|
: null;
|
|
316
|
-
if (trigger instanceof
|
|
317
|
-
if (trigger.onDeactivate) {
|
|
318
|
-
await trigger.onDeactivate(config.trigger.config, {
|
|
319
|
-
webhookUrl: '',
|
|
320
|
-
credentials: {},
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
await this.persistence.removeWebhookPath(workflowId);
|
|
324
|
-
this.log.info(`deactivated webhook trigger for workflow ${workflowId}`);
|
|
325
|
-
}
|
|
326
|
-
else if (trigger instanceof CronTrigger) {
|
|
330
|
+
if (trigger instanceof CronTrigger) {
|
|
327
331
|
await this.scheduler.unschedule(workflowId);
|
|
328
332
|
this.log.info(`deactivated cron trigger for workflow ${workflowId}`);
|
|
329
333
|
}
|
|
330
|
-
//
|
|
334
|
+
// Webhook, event and manual triggers need no teardown: webhook ingest and
|
|
335
|
+
// event dispatch only reach ACTIVE workflows, so the status below stops them.
|
|
336
|
+
await this.persistence.updateWorkflow(workflowId, { status: 'DISABLED' });
|
|
331
337
|
this.publishWorkflowChange(workflowId, 'deactivated', opts?.origin);
|
|
332
338
|
}
|
|
333
339
|
// ─── Workflow callback secret ───
|
|
@@ -379,9 +385,9 @@ export class WorkflowRuntime {
|
|
|
379
385
|
const executionIds = [];
|
|
380
386
|
for (const workflow of workflows) {
|
|
381
387
|
const config = parseWorkflowConfig(workflow.config);
|
|
382
|
-
if (!this.
|
|
388
|
+
if (!this.connectors.hasTrigger(config.trigger.type))
|
|
383
389
|
continue;
|
|
384
|
-
const trigger = this.
|
|
390
|
+
const trigger = this.connectors.getTrigger(config.trigger.type);
|
|
385
391
|
if (!(trigger instanceof EventTrigger))
|
|
386
392
|
continue;
|
|
387
393
|
// Hydrate lightweight payload → full context
|
|
@@ -399,6 +405,10 @@ export class WorkflowRuntime {
|
|
|
399
405
|
if (!trigger.matchFilters(config.trigger.config, payload)) {
|
|
400
406
|
continue;
|
|
401
407
|
}
|
|
408
|
+
// And the author's filter, before a run exists.
|
|
409
|
+
if (!matchesTriggerFilter(config.trigger.filter, payload, config.variables)) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
402
412
|
const execId = await this.createAndEnqueue(workflow, {
|
|
403
413
|
type: event.type,
|
|
404
414
|
...payload,
|
|
@@ -408,43 +418,80 @@ export class WorkflowRuntime {
|
|
|
408
418
|
return executionIds;
|
|
409
419
|
}
|
|
410
420
|
/**
|
|
411
|
-
*
|
|
421
|
+
* Ingest a request to a workflow's webhook URL, `<baseUrl>/webhooks/<workflowId>`.
|
|
422
|
+
*
|
|
423
|
+
* The order is fixed, and the trigger's own code runs only after the sender is
|
|
424
|
+
* authenticated:
|
|
412
425
|
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
426
|
+
* 1. The workflow exists, is ACTIVE and uses a webhook trigger — else 404, the
|
|
427
|
+
* same answer for each so workflow ids cannot be probed.
|
|
428
|
+
* 2. The trigger's credentials resolve — else 401, before any connector code runs.
|
|
429
|
+
* 3. The trigger's own `verify` accepts the request — else 401.
|
|
430
|
+
* 4. The body is parsed from the raw bytes — else 400.
|
|
431
|
+
* 5. The trigger turns the request into events and a reply.
|
|
432
|
+
* 6. Each event must pass the workflow's trigger filter, or it is dropped.
|
|
433
|
+
* 7. Survivors are enqueued before the reply is returned.
|
|
434
|
+
*
|
|
435
|
+
* Reasons for a rejection go to the log; responses stay generic.
|
|
415
436
|
*/
|
|
416
|
-
async handleWebhook(
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
437
|
+
async handleWebhook(workflowId, request) {
|
|
438
|
+
const notFound = {
|
|
439
|
+
reply: { status: 404, body: { error: 'Webhook not found' } },
|
|
440
|
+
executionIds: [],
|
|
441
|
+
};
|
|
442
|
+
const unauthorized = {
|
|
443
|
+
reply: { status: 401, body: { error: 'Unauthorized' } },
|
|
444
|
+
executionIds: [],
|
|
445
|
+
};
|
|
446
|
+
const workflow = await this.persistence.getWorkflow(workflowId);
|
|
447
|
+
if (!workflow || workflow.status !== 'ACTIVE')
|
|
448
|
+
return notFound;
|
|
449
|
+
const config = parseWorkflowConfig(workflow.config);
|
|
450
|
+
const trigger = this.connectors.findTrigger(config.trigger.type)?.trigger;
|
|
451
|
+
if (!(trigger instanceof WebhookTrigger))
|
|
452
|
+
return notFound;
|
|
453
|
+
const attributes = workflow.attributes;
|
|
454
|
+
const triggerConfig = config.trigger.config;
|
|
455
|
+
let ctx;
|
|
456
|
+
try {
|
|
457
|
+
const credentials = await this.credentialResolver.resolve(attributes, trigger, triggerConfig);
|
|
458
|
+
ctx = { credentials, attributes, baseUrl: this.baseUrl };
|
|
423
459
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
httpResponse: { status: 404, body: { error: 'Workflow not active' } },
|
|
429
|
-
};
|
|
460
|
+
catch (err) {
|
|
461
|
+
// Fail closed: verification never runs without the credentials it needs.
|
|
462
|
+
this.log.warn(`webhook ${workflowId}: rejected, ${messageOf(err)}`);
|
|
463
|
+
return unauthorized;
|
|
430
464
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
return {
|
|
435
|
-
executionId: '',
|
|
436
|
-
httpResponse: {
|
|
437
|
-
status: 400,
|
|
438
|
-
body: { error: 'Workflow does not use a webhook trigger' },
|
|
439
|
-
},
|
|
440
|
-
};
|
|
465
|
+
let verified = false;
|
|
466
|
+
try {
|
|
467
|
+
verified = await trigger.verify(request, triggerConfig, ctx);
|
|
441
468
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
469
|
+
catch (err) {
|
|
470
|
+
this.log.warn(`webhook ${workflowId}: verification threw: ${messageOf(err)}`);
|
|
471
|
+
}
|
|
472
|
+
if (!verified) {
|
|
473
|
+
this.log.warn(`webhook ${workflowId}: rejected by ${trigger.type} verification`);
|
|
474
|
+
return unauthorized;
|
|
475
|
+
}
|
|
476
|
+
let body;
|
|
477
|
+
try {
|
|
478
|
+
body = parseInboundBody(request.rawBody, headerValue(request.headers, 'content-type'));
|
|
479
|
+
}
|
|
480
|
+
catch (err) {
|
|
481
|
+
this.log.warn(`webhook ${workflowId}: rejected, ${messageOf(err)}`);
|
|
482
|
+
return { reply: { status: 400, body: { error: 'Malformed request body' } }, executionIds: [] };
|
|
483
|
+
}
|
|
484
|
+
const translation = await trigger.handleRequest({ ...request, body }, triggerConfig, ctx);
|
|
485
|
+
const executionIds = [];
|
|
486
|
+
for (const event of translation.events) {
|
|
487
|
+
if (!matchesTriggerFilter(config.trigger.filter, event.payload, config.variables))
|
|
488
|
+
continue;
|
|
489
|
+
executionIds.push(await this.createAndEnqueue(workflow, { type: event.type, ...event.payload }, { publicTrigger: true }));
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
reply: translation.reply ?? { status: 200, body: { ok: true } },
|
|
493
|
+
executionIds,
|
|
494
|
+
};
|
|
448
495
|
}
|
|
449
496
|
/**
|
|
450
497
|
* Handle an incoming wait-callback at `POST /wait/callback/<secret>/<executionId>`.
|
|
@@ -524,91 +571,67 @@ export class WorkflowRuntime {
|
|
|
524
571
|
return this.createAndEnqueue(workflow, triggerPayload);
|
|
525
572
|
}
|
|
526
573
|
/**
|
|
527
|
-
*
|
|
574
|
+
* Start a workflow from the API trigger route.
|
|
575
|
+
*
|
|
576
|
+
* No caller reaches the SDK here: the route has no session, and the SDK does
|
|
577
|
+
* not authorize whoever calls it. A host that exposes the route guards it
|
|
578
|
+
* itself, for example with an API key. The workflow must use an API trigger,
|
|
579
|
+
* and the payload must satisfy its input schema.
|
|
528
580
|
*
|
|
529
|
-
*
|
|
530
|
-
* the route publicly. The workflow itself must opt in by using WEBHOOK_V2,
|
|
531
|
-
* and the execution is marked as public so privileged steps can enforce their
|
|
532
|
-
* own public-trigger restrictions.
|
|
581
|
+
* Runs are marked as public triggers, so privileged steps refuse them.
|
|
533
582
|
*/
|
|
534
|
-
async
|
|
535
|
-
const workflow = await this.
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const
|
|
540
|
-
if (config.trigger.type !== 'WEBHOOK_V2') {
|
|
541
|
-
throw new Error(`Workflow ${workflowId} does not use a WEBHOOK_V2 trigger`);
|
|
542
|
-
}
|
|
543
|
-
const triggerCfg = (config.trigger.config ?? {});
|
|
544
|
-
const inputSchema = triggerCfg['inputSchema'];
|
|
545
|
-
const webhookV2InputSchema = inputSchema && Array.isArray(inputSchema['required'])
|
|
583
|
+
async triggerViaApi(workflowId, payload) {
|
|
584
|
+
const { workflow, config } = await this.apiTriggerWorkflow(workflowId);
|
|
585
|
+
const inputSchema = inputSchemaOf(config);
|
|
586
|
+
// Uploaded documents are optional on this route even when the schema lists
|
|
587
|
+
// them as required.
|
|
588
|
+
const apiInputSchema = inputSchema && Array.isArray(inputSchema['required'])
|
|
546
589
|
? {
|
|
547
590
|
...inputSchema,
|
|
548
591
|
required: inputSchema['required'].filter((field) => field !== 'documents'),
|
|
549
592
|
}
|
|
550
593
|
: inputSchema;
|
|
551
|
-
const errors = validateTriggerPayload(
|
|
594
|
+
const errors = validateTriggerPayload(apiInputSchema, payload);
|
|
552
595
|
if (errors.length > 0) {
|
|
553
596
|
throw new Error(`Invalid trigger payload: ${errors.map((e) => e.message).join('; ')}`);
|
|
554
597
|
}
|
|
555
|
-
return this.createAndEnqueue(workflow, {
|
|
556
|
-
type: config.trigger.type,
|
|
557
|
-
...payload,
|
|
558
|
-
}, { publicTrigger: true });
|
|
598
|
+
return this.createAndEnqueue(workflow, { type: config.trigger.type, ...payload }, { publicTrigger: true });
|
|
559
599
|
}
|
|
560
600
|
/**
|
|
561
|
-
*
|
|
562
|
-
*
|
|
601
|
+
* What the API trigger route needs before it builds a payload: the trigger's
|
|
602
|
+
* input schema, and the workflow's scope for storing uploaded files. Checked
|
|
603
|
+
* the same way as {@link triggerViaApi}.
|
|
563
604
|
*/
|
|
564
|
-
async
|
|
565
|
-
const workflow = await this.
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const config = parseWorkflowConfig(workflow.config);
|
|
571
|
-
const triggerCfg = (config.trigger.config ?? {});
|
|
572
|
-
const inputSchema = triggerCfg['inputSchema'];
|
|
573
|
-
return inputSchema && typeof inputSchema === 'object' && !Array.isArray(inputSchema)
|
|
574
|
-
? inputSchema
|
|
575
|
-
: undefined;
|
|
605
|
+
async getApiTriggerTarget(workflowId) {
|
|
606
|
+
const { workflow, config } = await this.apiTriggerWorkflow(workflowId);
|
|
607
|
+
return {
|
|
608
|
+
inputSchema: inputSchemaOf(config),
|
|
609
|
+
storageScope: workflow.attributes,
|
|
610
|
+
};
|
|
576
611
|
}
|
|
577
|
-
/**
|
|
578
|
-
|
|
579
|
-
*
|
|
580
|
-
* Unlike getWorkflowTriggerInputSchema(), this does not authorize a caller;
|
|
581
|
-
* it only verifies the workflow exists and opted into the expected public
|
|
582
|
-
* trigger type.
|
|
583
|
-
*/
|
|
584
|
-
async getWorkflowTriggerInputSchemaPublic(workflowId, expectedTriggerType) {
|
|
612
|
+
/** The workflow exists and uses an API trigger. */
|
|
613
|
+
async apiTriggerWorkflow(workflowId) {
|
|
585
614
|
const workflow = await this.persistence.getWorkflow(workflowId);
|
|
586
|
-
if (!workflow)
|
|
587
|
-
throw new
|
|
588
|
-
}
|
|
615
|
+
if (!workflow)
|
|
616
|
+
throw new ResourceNotFoundError('Workflow', workflowId);
|
|
589
617
|
const config = parseWorkflowConfig(workflow.config);
|
|
590
|
-
|
|
591
|
-
|
|
618
|
+
const trigger = this.connectors.findTrigger(config.trigger.type)?.trigger;
|
|
619
|
+
if (!(trigger instanceof ApiTrigger)) {
|
|
620
|
+
throw new Error(`Workflow ${workflowId} does not use an API trigger`);
|
|
592
621
|
}
|
|
593
|
-
|
|
594
|
-
const inputSchema = triggerCfg['inputSchema'];
|
|
595
|
-
return inputSchema && typeof inputSchema === 'object' && !Array.isArray(inputSchema)
|
|
596
|
-
? inputSchema
|
|
597
|
-
: undefined;
|
|
622
|
+
return { workflow, config };
|
|
598
623
|
}
|
|
599
624
|
/**
|
|
600
|
-
* Return the
|
|
625
|
+
* Return the configured trigger input schema for routes that need to translate
|
|
626
|
+
* transport-level payloads before calling `triggerManual()`.
|
|
601
627
|
*/
|
|
602
|
-
async
|
|
628
|
+
async getWorkflowTriggerInputSchema(ctx, workflowId) {
|
|
603
629
|
const workflow = await this.persistence.getWorkflow(workflowId);
|
|
604
630
|
if (!workflow) {
|
|
605
631
|
throw new Error(`Workflow ${workflowId} not found`);
|
|
606
632
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
throw new Error(`Workflow ${workflowId} does not use a ${expectedTriggerType} trigger`);
|
|
610
|
-
}
|
|
611
|
-
return workflow.attributes;
|
|
633
|
+
await this.require(ctx, 'workflow:run', this.workflowRef(workflow));
|
|
634
|
+
return inputSchemaOf(parseWorkflowConfig(workflow.config));
|
|
612
635
|
}
|
|
613
636
|
/**
|
|
614
637
|
* Resume a paused execution. Guards `execution:approve`, then does the work.
|
|
@@ -766,8 +789,10 @@ export class WorkflowRuntime {
|
|
|
766
789
|
// Internal post-create activation — already authorized by the create above.
|
|
767
790
|
await this.activateInternal(record);
|
|
768
791
|
}
|
|
769
|
-
catch {
|
|
770
|
-
// Non-fatal — workflow is created
|
|
792
|
+
catch (err) {
|
|
793
|
+
// Non-fatal — the workflow is created, and its trigger can be activated
|
|
794
|
+
// once whatever failed is fixed.
|
|
795
|
+
this.log.warn(`created workflow ${id} but could not activate its trigger: ${messageOf(err)}`);
|
|
771
796
|
}
|
|
772
797
|
}
|
|
773
798
|
this.log.info(`created workflow ${id} (${input.name})`);
|
|
@@ -1208,9 +1233,9 @@ export class WorkflowRuntime {
|
|
|
1208
1233
|
if (!workflow || workflow.status !== 'ACTIVE')
|
|
1209
1234
|
return null;
|
|
1210
1235
|
const config = parseWorkflowConfig(workflow.config);
|
|
1211
|
-
if (!this.
|
|
1236
|
+
if (!this.connectors.hasTrigger(config.trigger.type))
|
|
1212
1237
|
return null;
|
|
1213
|
-
const trigger = this.
|
|
1238
|
+
const trigger = this.connectors.getTrigger(config.trigger.type);
|
|
1214
1239
|
if (!(trigger instanceof CronTrigger))
|
|
1215
1240
|
return null;
|
|
1216
1241
|
const metadata = JSON.parse(workflow.metadata ?? '{}');
|