@xentom/integration-framework 0.0.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/CLAUDE.md +836 -0
- package/dist/controls/base.d.ts +14 -0
- package/dist/controls/base.js +0 -0
- package/dist/controls/expression.d.ts +15 -0
- package/dist/controls/expression.js +0 -0
- package/dist/controls/index.d.ts +155 -0
- package/dist/controls/index.js +30 -0
- package/dist/controls/select.d.ts +32 -0
- package/dist/controls/select.js +0 -0
- package/dist/controls/switch.d.ts +6 -0
- package/dist/controls/switch.js +0 -0
- package/dist/controls/text.d.ts +29 -0
- package/dist/controls/text.js +7 -0
- package/dist/env.d.ts +46 -0
- package/dist/env.js +19 -0
- package/dist/generic.d.ts +37 -0
- package/dist/generic.js +31 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/integration.d.ts +84 -0
- package/dist/integration.js +5 -0
- package/dist/nodes/base.d.ts +45 -0
- package/dist/nodes/base.js +0 -0
- package/dist/nodes/callable.d.ts +98 -0
- package/dist/nodes/callable.js +0 -0
- package/dist/nodes/index.d.ts +111 -0
- package/dist/nodes/index.js +48 -0
- package/dist/nodes/pure.d.ts +77 -0
- package/dist/nodes/pure.js +0 -0
- package/dist/nodes/trigger.d.ts +124 -0
- package/dist/nodes/trigger.js +0 -0
- package/dist/nodes/utils.d.ts +13 -0
- package/dist/nodes/utils.js +1 -0
- package/dist/pins/base.d.ts +13 -0
- package/dist/pins/base.js +0 -0
- package/dist/pins/data.d.ts +95 -0
- package/dist/pins/data.js +0 -0
- package/dist/pins/exec.d.ts +61 -0
- package/dist/pins/exec.js +0 -0
- package/dist/pins/index.d.ts +97 -0
- package/dist/pins/index.js +47 -0
- package/dist/pins/utils.d.ts +25 -0
- package/dist/pins/utils.js +0 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +1 -0
- package/dist/webhook.d.ts +33 -0
- package/dist/webhook.js +0 -0
- package/package.json +34 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type NodeType } from '.';
|
|
2
|
+
import { type IntegrationState } from '../integration';
|
|
3
|
+
import { type DataPin, type ExecPin, type ExtractPinsOfType, type InferPinRecordInput, type InferPinRecordOutput, type PinRecord, type PinRecordHasPinType } from '../pins';
|
|
4
|
+
import { type HasRequiredKeys } from '../utils';
|
|
5
|
+
import { type Webhook } from '../webhook';
|
|
6
|
+
import { type BaseNode } from './base';
|
|
7
|
+
import { type TriggerRunContext } from './trigger';
|
|
8
|
+
export type CallableNodeInputs = PinRecord<DataPin>;
|
|
9
|
+
export type CallableNodeOutputs = PinRecord<DataPin | ExecPin>;
|
|
10
|
+
/**
|
|
11
|
+
* CallableNode is a type of node that can be called by other nodes.
|
|
12
|
+
*/
|
|
13
|
+
export interface CallableNode<I extends CallableNodeInputs = CallableNodeInputs, O extends CallableNodeOutputs = CallableNodeOutputs> extends BaseNode<I, O> {
|
|
14
|
+
type: NodeType.Callable;
|
|
15
|
+
/**
|
|
16
|
+
* Runs the node with the provided inputs, state, and context.
|
|
17
|
+
* This method is invoked when the node is called by another node.
|
|
18
|
+
*
|
|
19
|
+
* @param opts - Options containing the execution context, state, inputs, variables, webhook, and next callback.
|
|
20
|
+
*/
|
|
21
|
+
run(opts: CallableNodeRunOptions<I, O>): void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* CallableNodeRunOptions defines the options passed to the run method of a CallableNode.
|
|
25
|
+
*/
|
|
26
|
+
export interface CallableNodeRunOptions<I extends CallableNodeInputs, O extends CallableNodeOutputs> {
|
|
27
|
+
/**
|
|
28
|
+
* Information about the node instance being executed.
|
|
29
|
+
* Includes the unique identifier for this node within the workflow.
|
|
30
|
+
*/
|
|
31
|
+
node: {
|
|
32
|
+
id: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Execution context for the node run, which may include metadata such as
|
|
36
|
+
* workflow identifiers, timestamps, or invocation sources.
|
|
37
|
+
* Useful for tracking or handling logic that depends on when or how the node is triggered.
|
|
38
|
+
*/
|
|
39
|
+
ctx: TriggerRunContext;
|
|
40
|
+
/**
|
|
41
|
+
* In-memory state for the integration, shared across all nodes.
|
|
42
|
+
* Can be used to manage reusable resources like API clients or caches.
|
|
43
|
+
* This state is not persisted across restarts.
|
|
44
|
+
*/
|
|
45
|
+
state: IntegrationState;
|
|
46
|
+
/**
|
|
47
|
+
* The resolved input values for the node, typically based on user configuration
|
|
48
|
+
* or outputs from preceding nodes in the workflow.
|
|
49
|
+
*/
|
|
50
|
+
inputs: InferPinRecordOutput<I>;
|
|
51
|
+
/**
|
|
52
|
+
* A key-value map of variables defined by the user or resolved from other connected nodes.
|
|
53
|
+
*
|
|
54
|
+
* Useful for AI-powered nodes that can use these variables as additional context
|
|
55
|
+
* during execution or generation.
|
|
56
|
+
*/
|
|
57
|
+
variables: Record<string, unknown>;
|
|
58
|
+
/**
|
|
59
|
+
* Webhook utility exposing the integration's public URL.
|
|
60
|
+
* Can be shared with external systems to send data back into the workflow.
|
|
61
|
+
*/
|
|
62
|
+
webhook: Pick<Webhook, 'url'>;
|
|
63
|
+
/**
|
|
64
|
+
* Function used to programmatically run an output pin of the node.
|
|
65
|
+
* Calling this starts a workflow run with optional execution context and output values.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* If the node has no exec pins defined, you can call `next` directly with the output values:
|
|
69
|
+
* ```ts
|
|
70
|
+
* next({
|
|
71
|
+
* value: Math.random(),
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* If the node defines one or more exec pins, you must specify the pin name
|
|
77
|
+
* and provide the corresponding output values:
|
|
78
|
+
* ```ts
|
|
79
|
+
* next('myCustomExecPin', {
|
|
80
|
+
* value: Math.random(),
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
next: NodeNextCallback<O>;
|
|
85
|
+
}
|
|
86
|
+
export type NodeNextCallback<PR extends PinRecord = PinRecord, AdditionalNextArgs extends unknown[] = []> = <P extends keyof ExtractPinsOfType<PR, ExecPin>>(this: void, ...args: PinRecordHasPinType<PR, ExecPin> extends true ? NodeNextCallbackArgsWithCustomExecPin<PR, P, AdditionalNextArgs> : NodeNextCallbackArgsWithDefaultExecPin<PR, AdditionalNextArgs>) => Promise<void>;
|
|
87
|
+
export type NodeNextCallbackArgsWithCustomExecPin<PR extends PinRecord, P extends string, AdditionalNextArgs extends unknown[] = []> = HasRequiredKeys<NodeNextCallbackArgsWithCustomExecPinOutputs<PR, P>> extends true ? [
|
|
88
|
+
pin: P,
|
|
89
|
+
outputs: NodeNextCallbackArgsWithCustomExecPinOutputs<PR, P>,
|
|
90
|
+
...AdditionalNextArgs
|
|
91
|
+
] : [
|
|
92
|
+
pin: P,
|
|
93
|
+
outputs?: NodeNextCallbackArgsWithCustomExecPinOutputs<PR, P>,
|
|
94
|
+
...AdditionalNextArgs
|
|
95
|
+
];
|
|
96
|
+
export type NodeNextCallbackArgsWithCustomExecPinOutputs<PR extends PinRecord, P extends string> = PR[P] extends ExecPin<infer R> ? string extends keyof R ? InferPinRecordInput<PR> : InferPinRecordInput<R> : never;
|
|
97
|
+
export type NodeNextCallbackArgsWithDefaultExecPin<PR extends PinRecord, AdditionalNextArgs extends unknown[] = never[]> = HasRequiredKeys<InferPinRecordInput<PR>> extends true ? [outputs: InferPinRecordInput<PR>, ...AdditionalNextArgs] : [outputs?: InferPinRecordInput<PR>, ...AdditionalNextArgs];
|
|
98
|
+
export type CallableNodeBuilder = <I extends CallableNodeInputs, O extends CallableNodeOutputs>(definition: Omit<CallableNode<I, O>, 'type'>) => CallableNode<I, O>;
|
|
File without changes
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { type CallableNode, type CallableNodeBuilder } from './callable';
|
|
2
|
+
import { type PureNode, type PureNodeBuilder } from './pure';
|
|
3
|
+
import { type TriggerNode, type TriggerNodeBuilder } from './trigger';
|
|
4
|
+
export * from './base';
|
|
5
|
+
export * from './callable';
|
|
6
|
+
export * from './pure';
|
|
7
|
+
export * from './trigger';
|
|
8
|
+
export * from './utils';
|
|
9
|
+
export type Node = TriggerNode | CallableNode | PureNode;
|
|
10
|
+
export type NodeRecord<N extends Node = Node> = Record<string, N>;
|
|
11
|
+
export declare enum NodeType {
|
|
12
|
+
/**
|
|
13
|
+
* Trigger nodes are entry points that can invoke other nodes but cannot be invoked by any.
|
|
14
|
+
* They represent the starting point of a workflow, typically triggered by external events
|
|
15
|
+
* such as webhooks, scheduled timers, or user interactions.
|
|
16
|
+
*/
|
|
17
|
+
Trigger = "trigger",
|
|
18
|
+
/**
|
|
19
|
+
* Callable nodes can both invoke other nodes and be invoked by them.
|
|
20
|
+
* They represent intermediate processing steps in a workflow, allowing for
|
|
21
|
+
* complex branching and chaining of operations.
|
|
22
|
+
*/
|
|
23
|
+
Callable = "callable",
|
|
24
|
+
/**
|
|
25
|
+
* Pure nodes are isolated - they neither invoke other nodes nor can be invoked by them.
|
|
26
|
+
* They represent standalone operations that perform calculations or transformations
|
|
27
|
+
* without any side effects or dependencies on other nodes.
|
|
28
|
+
*/
|
|
29
|
+
Pure = "pure"
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Collection of utilities for defining workflow nodes.
|
|
33
|
+
*
|
|
34
|
+
* Includes:
|
|
35
|
+
* - `trigger`: Defines a trigger that starts a workflow in response to internal or external events.
|
|
36
|
+
* - `callable`: Defines a node that performs side effects and explicitly control workflow execution.
|
|
37
|
+
* - `pure`: Defines a side-effect-free, deterministic node that computes outputs from inputs.
|
|
38
|
+
*/
|
|
39
|
+
export declare const nodes: {
|
|
40
|
+
/**
|
|
41
|
+
* Defines a trigger that starts a workflow in response to internal or external events
|
|
42
|
+
* such as incoming webhooks, scheduled timers, or custom event sources.
|
|
43
|
+
*
|
|
44
|
+
* A trigger includes a `subscribe` function, where you can listen for events and
|
|
45
|
+
* call `next()` to emit outputs and initiate the workflow.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* export const onMessage = i.nodes.trigger({
|
|
50
|
+
* outputs: {
|
|
51
|
+
* message: i.pins.data(),
|
|
52
|
+
* },
|
|
53
|
+
* subscribe(opts) {
|
|
54
|
+
* const unsubscribe = opts.state.client.on('message', (data) => {
|
|
55
|
+
* opts.next({ message: data });
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* return () => unsubscribe();
|
|
59
|
+
* },
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
trigger: TriggerNodeBuilder;
|
|
64
|
+
/**
|
|
65
|
+
* Defines a callable node that is executed during a workflow run.
|
|
66
|
+
* Callable nodes are typically used to perform side effects such as API requests,
|
|
67
|
+
* data mutations, or interacting with external systems.
|
|
68
|
+
*
|
|
69
|
+
* The `run` function is executed when the workflow reaches this node. To continue
|
|
70
|
+
* the workflow through an exec pin, the node must call `next()` explicitly.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* export const logMessage = i.nodes.callable({
|
|
75
|
+
* displayName: 'Log Message',
|
|
76
|
+
* inputs: {
|
|
77
|
+
* message: i.pins.data(),
|
|
78
|
+
* },
|
|
79
|
+
* run({ inputs, next }) {
|
|
80
|
+
* console.log(inputs.message);
|
|
81
|
+
* next(); // Required to continue workflow execution
|
|
82
|
+
* },
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
callable: CallableNodeBuilder;
|
|
87
|
+
/**
|
|
88
|
+
* Defines a pure node that computes outputs based only on its inputs.
|
|
89
|
+
* Pure nodes are deterministic and side-effect-free. They cannot be executed directly
|
|
90
|
+
* instead, they are evaluated automatically when their outputs are needed in the workflow.
|
|
91
|
+
*
|
|
92
|
+
* The `run` function is used to assign outputs based on the resolved inputs.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* export const addition = i.nodes.pure({
|
|
97
|
+
* inputs: {
|
|
98
|
+
* a: i.pins.data(),
|
|
99
|
+
* b: i.pins.data(),
|
|
100
|
+
* },
|
|
101
|
+
* outputs: {
|
|
102
|
+
* result: i.pins.data(),
|
|
103
|
+
* },
|
|
104
|
+
* run({ inputs, outputs }) {
|
|
105
|
+
* outputs.result = inputs.a + inputs.b;
|
|
106
|
+
* },
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
pure: PureNodeBuilder;
|
|
111
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export * from './base';
|
|
2
|
+
export * from './callable';
|
|
3
|
+
export * from './pure';
|
|
4
|
+
export * from './trigger';
|
|
5
|
+
export * from './utils';
|
|
6
|
+
export var NodeType;
|
|
7
|
+
(function (NodeType) {
|
|
8
|
+
/**
|
|
9
|
+
* Trigger nodes are entry points that can invoke other nodes but cannot be invoked by any.
|
|
10
|
+
* They represent the starting point of a workflow, typically triggered by external events
|
|
11
|
+
* such as webhooks, scheduled timers, or user interactions.
|
|
12
|
+
*/
|
|
13
|
+
NodeType["Trigger"] = "trigger";
|
|
14
|
+
/**
|
|
15
|
+
* Callable nodes can both invoke other nodes and be invoked by them.
|
|
16
|
+
* They represent intermediate processing steps in a workflow, allowing for
|
|
17
|
+
* complex branching and chaining of operations.
|
|
18
|
+
*/
|
|
19
|
+
NodeType["Callable"] = "callable";
|
|
20
|
+
/**
|
|
21
|
+
* Pure nodes are isolated - they neither invoke other nodes nor can be invoked by them.
|
|
22
|
+
* They represent standalone operations that perform calculations or transformations
|
|
23
|
+
* without any side effects or dependencies on other nodes.
|
|
24
|
+
*/
|
|
25
|
+
NodeType["Pure"] = "pure";
|
|
26
|
+
})(NodeType || (NodeType = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Collection of utilities for defining workflow nodes.
|
|
29
|
+
*
|
|
30
|
+
* Includes:
|
|
31
|
+
* - `trigger`: Defines a trigger that starts a workflow in response to internal or external events.
|
|
32
|
+
* - `callable`: Defines a node that performs side effects and explicitly control workflow execution.
|
|
33
|
+
* - `pure`: Defines a side-effect-free, deterministic node that computes outputs from inputs.
|
|
34
|
+
*/
|
|
35
|
+
export const nodes = {
|
|
36
|
+
trigger: (definition) => ({
|
|
37
|
+
...definition,
|
|
38
|
+
type: NodeType.Trigger,
|
|
39
|
+
}),
|
|
40
|
+
callable: (definition) => ({
|
|
41
|
+
...definition,
|
|
42
|
+
type: NodeType.Callable,
|
|
43
|
+
}),
|
|
44
|
+
pure: (definition) => ({
|
|
45
|
+
...definition,
|
|
46
|
+
type: NodeType.Pure,
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type NodeType } from '.';
|
|
2
|
+
import { type IntegrationState } from '../integration';
|
|
3
|
+
import { type DataPin, type InferPinRecordInput, type InferPinRecordOutput, type PinRecord } from '../pins';
|
|
4
|
+
import { type Webhook } from '../webhook';
|
|
5
|
+
import { type BaseNode } from './base';
|
|
6
|
+
import { type TriggerRunContext } from './trigger';
|
|
7
|
+
export type PureNodeInputs = PinRecord<DataPin>;
|
|
8
|
+
export type PureNodeOutputs = PinRecord<DataPin>;
|
|
9
|
+
/**
|
|
10
|
+
* PureNode is a type of node that is isolated and does not invoke other nodes or can be invoked by them.
|
|
11
|
+
*/
|
|
12
|
+
export interface PureNode<I extends PureNodeInputs = PureNodeInputs, O extends PureNodeOutputs = PureNodeOutputs> extends BaseNode<I, O> {
|
|
13
|
+
/**
|
|
14
|
+
* Identifies the node as a pure node.
|
|
15
|
+
* Pure nodes do not mutate any external or internal state and produce outputs solely based on their inputs.
|
|
16
|
+
* They cannot be triggered directly or independently, they must be connected to an input pin.
|
|
17
|
+
* The `run` function is executed automatically when the node is required as part of a data flow.
|
|
18
|
+
*/
|
|
19
|
+
type: NodeType.Pure;
|
|
20
|
+
/**
|
|
21
|
+
* Optional function that contains the core logic of the pure node.
|
|
22
|
+
* It is executed automatically when the node is evaluated as part of the workflow.
|
|
23
|
+
* Should compute outputs purely from the inputs without causing side effects.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* run(opts) {
|
|
28
|
+
* opts.outputs.result = opts.inputs.a + opts.inputs.b;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
run?(opts: PureNodeRunOptions<I, O>): Promise<void> | void;
|
|
33
|
+
}
|
|
34
|
+
export interface PureNodeRunOptions<I extends PureNodeInputs = PureNodeInputs, O extends PureNodeOutputs = PureNodeOutputs> {
|
|
35
|
+
/**
|
|
36
|
+
* Information about the node instance being executed.
|
|
37
|
+
* Includes the unique identifier for this node within the workflow.
|
|
38
|
+
*/
|
|
39
|
+
node: {
|
|
40
|
+
id: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Execution context for the node run, which may include metadata such as
|
|
44
|
+
* workflow identifiers, timestamps, or invocation sources.
|
|
45
|
+
* Useful for tracking or handling logic that depends on when or how the node is triggered.
|
|
46
|
+
*/
|
|
47
|
+
ctx: TriggerRunContext;
|
|
48
|
+
/**
|
|
49
|
+
* In-memory state for the integration, shared across all nodes.
|
|
50
|
+
* Can be used to manage reusable resources like API clients or caches.
|
|
51
|
+
* This state is not persisted across restarts.
|
|
52
|
+
*/
|
|
53
|
+
state: IntegrationState;
|
|
54
|
+
/**
|
|
55
|
+
* The resolved input values for the node, typically based on user configuration
|
|
56
|
+
* or outputs from preceding steps in the workflow.
|
|
57
|
+
*/
|
|
58
|
+
inputs: InferPinRecordOutput<I>;
|
|
59
|
+
/**
|
|
60
|
+
* The object used to assign output values from the node.
|
|
61
|
+
* Each output pin should be populated within the `run` function to pass values forward in the workflow.
|
|
62
|
+
*/
|
|
63
|
+
outputs: InferPinRecordInput<O>;
|
|
64
|
+
/**
|
|
65
|
+
* A key-value map of variables defined by the user or resolved from other connected nodes.
|
|
66
|
+
*
|
|
67
|
+
* Useful for AI-powered nodes that can use these variables as additional context
|
|
68
|
+
* during execution or generation.
|
|
69
|
+
*/
|
|
70
|
+
variables: Record<string, unknown>;
|
|
71
|
+
/**
|
|
72
|
+
* Webhook utility exposing the integration's public URL.
|
|
73
|
+
* Can be shared with external systems to send data back into the workflow.
|
|
74
|
+
*/
|
|
75
|
+
webhook: Pick<Webhook, 'url'>;
|
|
76
|
+
}
|
|
77
|
+
export type PureNodeBuilder = <I extends PureNodeInputs, O extends PureNodeOutputs>(definition: Omit<PureNode<I, O>, 'type'>) => PureNode<I, O>;
|
|
File without changes
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { type IntegrationState } from '../integration';
|
|
2
|
+
import { type DataPin, type ExecPin, type InferPinRecordOutput, type PinRecord } from '../pins';
|
|
3
|
+
import { type Webhook } from '../webhook';
|
|
4
|
+
import { type BaseNode } from './base';
|
|
5
|
+
import { type NodeNextCallback } from './callable';
|
|
6
|
+
import { type NodeType } from './index';
|
|
7
|
+
/**
|
|
8
|
+
* TriggerNode is a type of node that can be triggered by an external event, such as a webhook or a timer.
|
|
9
|
+
*/
|
|
10
|
+
export type TriggerNodeInputs = PinRecord<DataPin>;
|
|
11
|
+
export type TriggerNodeOutputs = PinRecord<DataPin | ExecPin>;
|
|
12
|
+
export interface TriggerNode<I extends TriggerNodeInputs = TriggerNodeInputs, O extends TriggerNodeOutputs = TriggerNodeOutputs> extends BaseNode<I, O> {
|
|
13
|
+
type: NodeType.Trigger;
|
|
14
|
+
/**
|
|
15
|
+
* Registers a callback to subscribe to internal or external events.
|
|
16
|
+
* This allows the trigger to listen for changes (e.g. webhooks, timers, system events)
|
|
17
|
+
* and initiate a workflow run when the event occurs.
|
|
18
|
+
*
|
|
19
|
+
* The callback is called during setup and can return a cleanup function to unsubscribe when the workflow is stopped or reconfigured.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* Listening for a webhook event:
|
|
23
|
+
* ```ts
|
|
24
|
+
* subscribe(opts) {
|
|
25
|
+
* const unsubscribe = opts.webhook.subscribe((req) => {
|
|
26
|
+
* // Handle incoming webhook requests
|
|
27
|
+
* return new Response('OK');
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* return () => {
|
|
31
|
+
* unsubscribe();
|
|
32
|
+
* };
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* Listening for a timer event:
|
|
38
|
+
* ```ts
|
|
39
|
+
* subscribe(opts) {
|
|
40
|
+
* const interval = setInterval(() => {
|
|
41
|
+
* opts.next({
|
|
42
|
+
* timestamp: new Date().getTime(),
|
|
43
|
+
* });
|
|
44
|
+
* }, 60000); // Trigger every minute
|
|
45
|
+
|
|
46
|
+
* return () => {
|
|
47
|
+
* clearInterval(interval);
|
|
48
|
+
* };
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* Listening for a external event via client:
|
|
54
|
+
* ```ts
|
|
55
|
+
* subscribe(opts) {
|
|
56
|
+
* const unsubscribe = opts.state.client.on('message', (content: string) => {
|
|
57
|
+
* // Handle the incoming message content
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* return () => {
|
|
61
|
+
* unsubscribe();
|
|
62
|
+
* };
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
subscribe(opts: TriggerSubscribeOptions<I, O>): TriggerSubscribeCleanup;
|
|
67
|
+
}
|
|
68
|
+
export type TriggerSubscribeCleanup = Promise<(() => void) | void> | (() => void) | void;
|
|
69
|
+
export interface TriggerSubscribeOptions<I extends TriggerNodeInputs, O extends TriggerNodeOutputs> {
|
|
70
|
+
/**
|
|
71
|
+
* Information about the node instance being executed.
|
|
72
|
+
* Includes the unique identifier for this node within the workflow.
|
|
73
|
+
*/
|
|
74
|
+
node: {
|
|
75
|
+
id: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* In-memory state for the integration, shared across all nodes.
|
|
79
|
+
* Can be used to manage reusable resources like API clients or caches.
|
|
80
|
+
* This state is not persisted across restarts.
|
|
81
|
+
*/
|
|
82
|
+
state: IntegrationState;
|
|
83
|
+
/**
|
|
84
|
+
* Webhook utility for registering handlers that respond to incoming HTTP requests.
|
|
85
|
+
* Typically used when the trigger relies on external events via webhooks.
|
|
86
|
+
*/
|
|
87
|
+
webhook: Webhook;
|
|
88
|
+
/**
|
|
89
|
+
* The resolved input values for the trigger, typically based on user configuration
|
|
90
|
+
* or outputs from preceding steps in the workflow.
|
|
91
|
+
*/
|
|
92
|
+
inputs: InferPinRecordOutput<I>;
|
|
93
|
+
/**
|
|
94
|
+
* A key-value map of variables defined by the user or resolved from other connected nodes.
|
|
95
|
+
*
|
|
96
|
+
* Useful for AI-powered nodes that can use these variables as additional context
|
|
97
|
+
* during execution or generation.
|
|
98
|
+
*/
|
|
99
|
+
variables: Record<string, unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* Function used to programmatically run an output pin of the trigger.
|
|
102
|
+
* Calling this starts a workflow run with optional execution context and output values.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* If the trigger has no exec pins defined, you can call `next` directly with the output values:
|
|
106
|
+
* ```ts
|
|
107
|
+
* next({
|
|
108
|
+
* value: Math.random(),
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* If the trigger defines one or more exec pins, you must specify the pin name
|
|
114
|
+
* and provide the corresponding output values:
|
|
115
|
+
* ```ts
|
|
116
|
+
* next('myCustomExecPin', {
|
|
117
|
+
* value: Math.random(),
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
next: NodeNextCallback<O, [ctx?: TriggerRunContext]>;
|
|
122
|
+
}
|
|
123
|
+
export type TriggerRunContext = Record<string, any>;
|
|
124
|
+
export type TriggerNodeBuilder = <I extends TriggerNodeInputs, O extends TriggerNodeOutputs>(definition: Omit<TriggerNode<I, O>, 'type'>) => TriggerNode<I, O>;
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Node, type NodeRecord } from '.';
|
|
2
|
+
import { type InferPinRecordInput, type InferPinRecordOutput, type PinRecord } from '../pins';
|
|
3
|
+
export declare const DefaultExecPinName = "__exec";
|
|
4
|
+
export type InferNodeRecordOutput<R extends NodeRecord> = {
|
|
5
|
+
[K in keyof R]: InferNodeOutput<R[K]>;
|
|
6
|
+
};
|
|
7
|
+
export type InferNodeOutput<N extends Node> = N extends {
|
|
8
|
+
inputs?: infer I;
|
|
9
|
+
outputs?: infer O;
|
|
10
|
+
} ? {
|
|
11
|
+
inputs: I extends PinRecord ? InferPinRecordInput<I> : never;
|
|
12
|
+
outputs: O extends PinRecord ? InferPinRecordOutput<O> : never;
|
|
13
|
+
} : never;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DefaultExecPinName = '__exec';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface BasePin {
|
|
2
|
+
/**
|
|
3
|
+
* Custom display name for the pin. If set to a string, it overrides the default label.
|
|
4
|
+
* If set to `false`, the label is hidden but the pin remains visible. Useful for reducing
|
|
5
|
+
* visual clutter when the pin's purpose is self-explanatory.
|
|
6
|
+
*/
|
|
7
|
+
displayName?: string | false;
|
|
8
|
+
/**
|
|
9
|
+
* Optional description providing additional context or guidance for the pin.
|
|
10
|
+
* Typically shown as a tooltip or inline help text.
|
|
11
|
+
*/
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import { type PinType } from '.';
|
|
3
|
+
import { type Control } from '../controls';
|
|
4
|
+
import { type IntegrationOptions } from '../integration';
|
|
5
|
+
import { type ConditionalOptional } from '../utils';
|
|
6
|
+
import { type BasePin } from './base';
|
|
7
|
+
export interface DataPin<Input = any, Output = Input, Optional extends boolean = boolean> extends BasePin {
|
|
8
|
+
type: PinType.Data;
|
|
9
|
+
/**
|
|
10
|
+
* Validation schema compatible with the Standard Schema specification.
|
|
11
|
+
* Defines the structure and constraints for the pin's data.
|
|
12
|
+
* Can be used with any validator that conforms to the Standard Schema interface.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://github.com/standard-schema/standard-schema}
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* Using Valibot for validation:
|
|
18
|
+
* ```ts
|
|
19
|
+
* v.pipe(v.string(), v.trim())
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
schema?: StandardSchemaV1<Input, Output> | ((opts: IntegrationOptions) => StandardSchemaV1<Input, Output>);
|
|
23
|
+
/**
|
|
24
|
+
* Optional control configuration that defines how the pin should be rendered in the UI.
|
|
25
|
+
* Supports various input types such as text fields, select dropdowns, and toggles.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* control: i.controls.text({
|
|
30
|
+
* label: 'Message',
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
control?: false | Control<ConditionalOptional<Optional, Input & {}>>;
|
|
35
|
+
/**
|
|
36
|
+
* Optional examples that provide users with predefined values for the pin.
|
|
37
|
+
* Each example includes a title and a value to illustrate the expected input format
|
|
38
|
+
* or showcase common use cases.
|
|
39
|
+
*
|
|
40
|
+
* These examples are helpful both for users and for AI assistance,
|
|
41
|
+
* as they provide context and practical references for how the pin can be used.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* examples: [
|
|
46
|
+
* {
|
|
47
|
+
* title: 'Example 1',
|
|
48
|
+
* value: 'This is an example input',
|
|
49
|
+
* },
|
|
50
|
+
* {
|
|
51
|
+
* title: 'Example 2',
|
|
52
|
+
* value: [
|
|
53
|
+
* 'This is another example input',
|
|
54
|
+
* 'It can be an array or any other type',
|
|
55
|
+
* ],
|
|
56
|
+
* },
|
|
57
|
+
* ]
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
examples?: DataPinExample<ConditionalOptional<Optional, Input & {}>>[];
|
|
61
|
+
/**
|
|
62
|
+
* Determines if the pin is optional in the UI.
|
|
63
|
+
* When `true`, the pin does not appear initially but can be manually added by the user if needed.
|
|
64
|
+
* This is useful for reducing visual clutter or showing context-specific pins when required.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* optional: true,
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
optional?: Optional;
|
|
72
|
+
}
|
|
73
|
+
export interface DataPinExample<I> {
|
|
74
|
+
/**
|
|
75
|
+
* A human-readable title for the example, providing context or a brief description.
|
|
76
|
+
*/
|
|
77
|
+
title: string;
|
|
78
|
+
/**
|
|
79
|
+
* The value of the example, which can be any valid input type for the pin.
|
|
80
|
+
* This value is used to illustrate how the pin can be utilized in practice.
|
|
81
|
+
*/
|
|
82
|
+
value: I;
|
|
83
|
+
}
|
|
84
|
+
export type DataPinBuilder<ParentInput = any, ParentOutput = ParentInput, ParentOptional extends boolean = false> = <Input = ParentInput, Output = undefined extends ParentOutput ? Input : ParentOutput, Optional extends boolean = ParentOptional>(definition?: Omit<DataPin<Input, Output, Optional>, 'type' | 'with'>) => NoInfer<DataPin<ConditionalOptional<Optional, Input>, ConditionalOptional<Optional, Output>, Optional> & {
|
|
85
|
+
/**
|
|
86
|
+
* A function that builds a new pin with the given definition.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* i.pins.data().with({
|
|
91
|
+
* description: 'A message to send',
|
|
92
|
+
* })
|
|
93
|
+
*/
|
|
94
|
+
with: DataPinBuilder<Input, Output, Optional>;
|
|
95
|
+
}>;
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type PinRecord, type PinType } from '.';
|
|
2
|
+
import { type BasePin } from './base';
|
|
3
|
+
import { type DataPin } from './data';
|
|
4
|
+
export interface ExecPin<PR extends PinRecord<DataPin> = PinRecord<DataPin>> extends BasePin {
|
|
5
|
+
type: PinType.Exec;
|
|
6
|
+
/**
|
|
7
|
+
* Optional outputs for the exec pin, defined as a set of named data pins.
|
|
8
|
+
* These outputs are scoped locally to the exec pin and are separate from the node's global outputs.
|
|
9
|
+
* Useful for cases like iteration, where the exec pin is triggered for each item in a list.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* outputs: {
|
|
14
|
+
* item: i.pins.data(),
|
|
15
|
+
* index: i.pins.data(),
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Full example of an exec pin that iterates over an array:
|
|
21
|
+
* ```ts
|
|
22
|
+
* i.nodes.callable({
|
|
23
|
+
* inputs: {
|
|
24
|
+
* array: i.pins.data<unknown[]>(),
|
|
25
|
+
* },
|
|
26
|
+
* outputs: {
|
|
27
|
+
* completed: i.pins.exec(),
|
|
28
|
+
* iteration: i.pins.exec({
|
|
29
|
+
* outputs: {
|
|
30
|
+
* element: i.pins.data(),
|
|
31
|
+
* index: i.pins.data(),
|
|
32
|
+
* },
|
|
33
|
+
* }),
|
|
34
|
+
* },
|
|
35
|
+
* run(opts) {
|
|
36
|
+
* opts.inputs.array.forEach((element, index) => {
|
|
37
|
+
* opts.next('iteration', {
|
|
38
|
+
* element,
|
|
39
|
+
* index,
|
|
40
|
+
* });
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* opts.next('completed');
|
|
44
|
+
* },
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
outputs?: PR;
|
|
49
|
+
}
|
|
50
|
+
export type ExecPinBuilder<ParentPR extends PinRecord<DataPin> = PinRecord<DataPin>> = <PR extends PinRecord<DataPin> = ParentPR>(definition?: Omit<ExecPin<PR>, 'type' | 'with'>) => ExecPin<PR> & {
|
|
51
|
+
/**
|
|
52
|
+
* A function that builds a new pin with the given definition.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* i.pins.exec().with({
|
|
57
|
+
* description: 'A message to send',
|
|
58
|
+
* })
|
|
59
|
+
*/
|
|
60
|
+
with: ExecPinBuilder<PR>;
|
|
61
|
+
};
|
|
File without changes
|