@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.
Files changed (48) hide show
  1. package/CLAUDE.md +836 -0
  2. package/dist/controls/base.d.ts +14 -0
  3. package/dist/controls/base.js +0 -0
  4. package/dist/controls/expression.d.ts +15 -0
  5. package/dist/controls/expression.js +0 -0
  6. package/dist/controls/index.d.ts +155 -0
  7. package/dist/controls/index.js +30 -0
  8. package/dist/controls/select.d.ts +32 -0
  9. package/dist/controls/select.js +0 -0
  10. package/dist/controls/switch.d.ts +6 -0
  11. package/dist/controls/switch.js +0 -0
  12. package/dist/controls/text.d.ts +29 -0
  13. package/dist/controls/text.js +7 -0
  14. package/dist/env.d.ts +46 -0
  15. package/dist/env.js +19 -0
  16. package/dist/generic.d.ts +37 -0
  17. package/dist/generic.js +31 -0
  18. package/dist/index.d.ts +8 -0
  19. package/dist/index.js +8 -0
  20. package/dist/integration.d.ts +84 -0
  21. package/dist/integration.js +5 -0
  22. package/dist/nodes/base.d.ts +45 -0
  23. package/dist/nodes/base.js +0 -0
  24. package/dist/nodes/callable.d.ts +98 -0
  25. package/dist/nodes/callable.js +0 -0
  26. package/dist/nodes/index.d.ts +111 -0
  27. package/dist/nodes/index.js +48 -0
  28. package/dist/nodes/pure.d.ts +77 -0
  29. package/dist/nodes/pure.js +0 -0
  30. package/dist/nodes/trigger.d.ts +124 -0
  31. package/dist/nodes/trigger.js +0 -0
  32. package/dist/nodes/utils.d.ts +13 -0
  33. package/dist/nodes/utils.js +1 -0
  34. package/dist/pins/base.d.ts +13 -0
  35. package/dist/pins/base.js +0 -0
  36. package/dist/pins/data.d.ts +95 -0
  37. package/dist/pins/data.js +0 -0
  38. package/dist/pins/exec.d.ts +61 -0
  39. package/dist/pins/exec.js +0 -0
  40. package/dist/pins/index.d.ts +97 -0
  41. package/dist/pins/index.js +47 -0
  42. package/dist/pins/utils.d.ts +25 -0
  43. package/dist/pins/utils.js +0 -0
  44. package/dist/utils.d.ts +10 -0
  45. package/dist/utils.js +1 -0
  46. package/dist/webhook.d.ts +33 -0
  47. package/dist/webhook.js +0 -0
  48. package/package.json +34 -0
@@ -0,0 +1,14 @@
1
+ export interface BaseControl<S = never> {
2
+ /**
3
+ * A short label describing the purpose of the control.
4
+ */
5
+ label?: string;
6
+ /**
7
+ * Optional help text providing additional context or guidance for the control.
8
+ */
9
+ description?: string;
10
+ /**
11
+ * The default value used when no user input is provided.
12
+ */
13
+ defaultValue?: S;
14
+ }
File without changes
@@ -0,0 +1,15 @@
1
+ import { type ControlType } from '.';
2
+ import { type BaseControl } from './base';
3
+ export interface ExpressionControl<S = never> extends BaseControl<S> {
4
+ type: ControlType.Expression;
5
+ /**
6
+ * Placeholder text displayed when the input is empty.
7
+ */
8
+ placeholder?: string;
9
+ /**
10
+ * The number of rows to display in the text area.
11
+ * This is particularly useful for multiline text inputs.
12
+ */
13
+ rows?: number;
14
+ }
15
+ export type ExpressionControlBuilder = <S = never>(definition?: Omit<ExpressionControl<S>, 'type'>) => ExpressionControl<NoInfer<S>>;
File without changes
@@ -0,0 +1,155 @@
1
+ import { type ExpressionControl, type ExpressionControlBuilder } from './expression';
2
+ import { type SelectControl, type SelectControlBuilder } from './select';
3
+ import { type SwitchControl, type SwitchControlBuilder } from './switch';
4
+ import { type TextControl, type TextControlBuilder } from './text';
5
+ export * from './base';
6
+ export * from './expression';
7
+ export * from './select';
8
+ export * from './switch';
9
+ export * from './text';
10
+ export declare enum ControlType {
11
+ Text = "text",
12
+ Expression = "expression",
13
+ Select = "select",
14
+ Switch = "switch"
15
+ }
16
+ export type Control<S = never> = TextControl<S> | ExpressionControl<S> | SelectControl<S> | SwitchControl<S>;
17
+ export declare const controls: {
18
+ /**
19
+ * Text control fields allow users to input plain text, either for an node pin or an environment variable.
20
+ * For node pins, users can include template expressions (e.g., {{ myVariable }}), which will be evaluated at runtime.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * i.controls.text();
25
+ * ```
26
+ *
27
+ * @example
28
+ * Customizing the control with additional properties:
29
+ * ```ts
30
+ * i.controls.text({
31
+ * defaultValue: 'Hello, world!',
32
+ * });
33
+ * ```
34
+ *
35
+ * @example
36
+ * Using inside a node pin:
37
+ * ```ts
38
+ * i.pins.data({
39
+ * control: i.controls.text(),
40
+ * });
41
+ * ```
42
+ *
43
+ * @example
44
+ * Using for environment variables:
45
+ * ```ts
46
+ * i.env({
47
+ * control: i.controls.text({
48
+ * label: 'API Key',
49
+ * description: 'Your service API key for authentication.',
50
+ * placeholder: 'sk-...',
51
+ * }),
52
+ * });
53
+ * ```
54
+ */
55
+ text: TextControlBuilder;
56
+ /**
57
+ * Expression control fields allow users to input JavaScript code that is evaluated at runtime.
58
+ * Variables can be referenced directly within the expression, and the result is used as the pin's value.
59
+ * This control is only supported for node pins, not environment variables.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * i.controls.expression();
64
+ * ```
65
+ *
66
+ * @example
67
+ * Customizing the control with additional properties:
68
+ * ```ts
69
+ * i.controls.expression({
70
+ * defaultValue: {
71
+ * id: '123',
72
+ * name: 'Example',
73
+ * },
74
+ * });
75
+ * ```
76
+ *
77
+ * @example
78
+ * Using inside a node pin:
79
+ * ```ts
80
+ * i.pins.data({
81
+ * control: i.controls.expression(),
82
+ * });
83
+ * ```
84
+ */
85
+ expression: ExpressionControlBuilder;
86
+ /**
87
+ * Select control fields allow users to choose from a predefined set of options.
88
+ * Options can be either static or dynamically generated via an asynchronous callback function (only supported for node pins).
89
+ *
90
+ * @example
91
+ * Static options:
92
+ * ```ts
93
+ * i.controls.select({
94
+ * options: [
95
+ * { value: 'option1', label: 'Option 1' },
96
+ * { value: 'option2', label: 'Option 2' },
97
+ * ],
98
+ * });
99
+ *
100
+ * @example
101
+ * Dynamic options using a callback:
102
+ * ```ts
103
+ * i.controls.select({
104
+ * options(opts) {
105
+ * return [
106
+ * { value: 'option1', label: 'Option 1' },
107
+ * { value: 'option2', label: 'Option 2' },
108
+ * ];
109
+ * },
110
+ * });
111
+ * ```
112
+ *
113
+ * @example
114
+ * Using inside a node pin:
115
+ * ```ts
116
+ * i.pins.data({
117
+ * control: i.controls.select({
118
+ * options: [
119
+ * { value: 'option1', label: 'Option 1' },
120
+ * { value: 'option2', label: 'Option 2' },
121
+ * ],
122
+ * }),
123
+ * });
124
+ * ```
125
+ */
126
+ select: SelectControlBuilder;
127
+ /**
128
+ * Switch control fields allow users to toggle a boolean value (true/false).
129
+ * This control is useful for enabling or disabling features or options within an node pin.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * i.controls.switch();
134
+ * ```
135
+ *
136
+ * @example
137
+ * Customizing the control with additional properties:
138
+ * ```ts
139
+ * i.controls.switch({
140
+ * label: 'Enable Feature',
141
+ * description: 'Toggle this to enable the feature.',
142
+ * defaultValue: true,
143
+ * });
144
+ * ```
145
+ *
146
+ * @example
147
+ * Using inside a node pin:
148
+ * ```ts
149
+ * i.pins.data({
150
+ * control: i.controls.switch(),
151
+ * });
152
+ * ```
153
+ */
154
+ switch: SwitchControlBuilder;
155
+ };
@@ -0,0 +1,30 @@
1
+ export * from './base';
2
+ export * from './expression';
3
+ export * from './select';
4
+ export * from './switch';
5
+ export * from './text';
6
+ export var ControlType;
7
+ (function (ControlType) {
8
+ ControlType["Text"] = "text";
9
+ ControlType["Expression"] = "expression";
10
+ ControlType["Select"] = "select";
11
+ ControlType["Switch"] = "switch";
12
+ })(ControlType || (ControlType = {}));
13
+ export const controls = {
14
+ text: (definition) => ({
15
+ ...definition,
16
+ type: ControlType.Text,
17
+ }),
18
+ expression: (definition) => ({
19
+ ...definition,
20
+ type: ControlType.Expression,
21
+ }),
22
+ select: (definition) => ({
23
+ ...definition,
24
+ type: ControlType.Select,
25
+ }),
26
+ switch: (definition) => ({
27
+ ...definition,
28
+ type: ControlType.Switch,
29
+ }),
30
+ };
@@ -0,0 +1,32 @@
1
+ import { type ControlType } from '.';
2
+ import { type IntegrationOptions } from '../integration';
3
+ import { type BaseControl } from './base';
4
+ export interface SelectControl<S = never, Options = SelectControlOptions<S> | SelectControlOptionsCallback<S>> extends BaseControl<S> {
5
+ type: ControlType.Select;
6
+ /**
7
+ * Defines the options available for selection.
8
+ * Can be a static array of options or a callback function that returns options dynamically.
9
+ */
10
+ options: Options;
11
+ /**
12
+ * Placeholder text displayed when no option is selected.
13
+ */
14
+ placeholder?: string;
15
+ }
16
+ export type SelectControlOptions<S = never> = SelectControlOption<S>[];
17
+ export type SelectControlOptionsCallback<S = never> = (opts: IntegrationOptions) => Promise<SelectControlOption<S>[]> | SelectControlOption<S>[];
18
+ export interface SelectControlOption<S = never> {
19
+ /**
20
+ * The value associated with the option, which will be used as the pin's value.
21
+ */
22
+ value: S;
23
+ /**
24
+ * A human-readable label for the option, displayed in the UI.
25
+ */
26
+ label?: string;
27
+ /**
28
+ * An optional description providing additional context about the option.
29
+ */
30
+ description?: string;
31
+ }
32
+ export type SelectControlBuilder = <const S = never>(definition: Omit<SelectControl<S>, 'type'>) => SelectControl<S>;
File without changes
@@ -0,0 +1,6 @@
1
+ import { type ControlType } from '.';
2
+ import { type BaseControl } from './base';
3
+ export interface SwitchControl<S = never> extends BaseControl<S> {
4
+ type: ControlType.Switch;
5
+ }
6
+ export type SwitchControlBuilder = (definition?: Omit<SwitchControl<boolean>, 'type'>) => SwitchControl<boolean>;
File without changes
@@ -0,0 +1,29 @@
1
+ import { type ControlType } from '.';
2
+ import { type BaseControl } from './base';
3
+ export interface TextControl<S = string> extends BaseControl<S> {
4
+ type: ControlType.Text;
5
+ /**
6
+ * Specifies the syntax highlighting language used in the text control, if applicable.
7
+ */
8
+ language?: TextControlLanguage;
9
+ /**
10
+ * Placeholder text displayed when the input is empty.
11
+ */
12
+ placeholder?: string;
13
+ /**
14
+ * Marks the input as sensitive; content may be hidden or obfuscated in the UI.
15
+ */
16
+ sensitive?: boolean;
17
+ /**
18
+ * The number of rows to display in the text area.
19
+ * This is particularly useful for multiline text inputs.
20
+ */
21
+ rows?: number;
22
+ }
23
+ export declare enum TextControlLanguage {
24
+ Plain = "plain",
25
+ Html = "html",
26
+ Markdown = "markdown",
27
+ JavaScript = "javascript"
28
+ }
29
+ export type TextControlBuilder = (definition?: Omit<TextControl<string>, 'type'>) => TextControl<string>;
@@ -0,0 +1,7 @@
1
+ export var TextControlLanguage;
2
+ (function (TextControlLanguage) {
3
+ TextControlLanguage["Plain"] = "plain";
4
+ TextControlLanguage["Html"] = "html";
5
+ TextControlLanguage["Markdown"] = "markdown";
6
+ TextControlLanguage["JavaScript"] = "javascript";
7
+ })(TextControlLanguage || (TextControlLanguage = {}));
package/dist/env.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { type StandardSchemaV1 } from '@standard-schema/spec';
2
+ import { type SelectControl, type SelectControlOptions, type SwitchControl, type TextControl } from './controls';
3
+ export interface Env<O = unknown> {
4
+ /**
5
+ * Defines the UI control used to configure the environment variable.
6
+ * Can be a text input, a switch (boolean), or a select dropdown.
7
+ */
8
+ control: TextControl<string> | SwitchControl<boolean> | SelectControl<string, SelectControlOptions<string>>;
9
+ /**
10
+ * Validation schema compatible with the Standard Schema specification.
11
+ * Can be used with any validator that conforms to the Standard Schema interface.
12
+ *
13
+ * @see {@link https://github.com/standard-schema/standard-schema}
14
+ *
15
+ * @example
16
+ * Using Valibot for validation:
17
+ * ```ts
18
+ * v.pipe(v.string(), v.startsWith('sk-'))
19
+ * ```
20
+ */
21
+ schema?: StandardSchemaV1<string | undefined, O>;
22
+ }
23
+ export type EnvRecord = Record<string, Env>;
24
+ export type InferEnvRecordOutput<ER extends EnvRecord> = {
25
+ [K in keyof ER]: InterEnvOutput<ER[K]>;
26
+ };
27
+ export type InterEnvOutput<E extends Env> = E extends Env<infer O> ? O : string | undefined;
28
+ /**
29
+ * Defines an environment variable for an integration.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * export default i.integration({
34
+ * env: {
35
+ * API_KEY: i.env({
36
+ * control: i.controls.text({
37
+ * label: 'API Key',
38
+ * description: 'Your service API key for authentication',
39
+ * placeholder: 'sk-...',
40
+ * }),
41
+ * }),
42
+ * },
43
+ * });
44
+ * ```
45
+ */
46
+ export declare const env: <O = string>(definition: Env<O>) => NoInfer<Env<O>>;
package/dist/env.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Defines an environment variable for an integration.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * export default i.integration({
7
+ * env: {
8
+ * API_KEY: i.env({
9
+ * control: i.controls.text({
10
+ * label: 'API Key',
11
+ * description: 'Your service API key for authentication',
12
+ * placeholder: 'sk-...',
13
+ * }),
14
+ * }),
15
+ * },
16
+ * });
17
+ * ```
18
+ */
19
+ export const env = (definition) => definition;
@@ -0,0 +1,37 @@
1
+ import { type CallableNode, type PureNode, type TriggerNode } from './nodes';
2
+ import { type InferPinRecordOutput, type PinRecord } from './pins';
3
+ export type GenericInputs<R extends PinRecord> = InferPinRecordOutput<R>;
4
+ export type GenericNode<N extends () => NodeWithAnyIO = () => NodeWithAnyIO> = ReturnType<N> & {
5
+ _generic: N;
6
+ };
7
+ type NodeWithAnyIO = CallableNode<any, any> | PureNode<any, any> | TriggerNode<any, any>;
8
+ /**
9
+ * Wraps a node definition and makes it generic.
10
+ * This allows the output type to dynamically adapt based on the provided inputs.
11
+ *
12
+ * Generic nodes are useful when the structure of inputs affects the shape of the outputs -
13
+ * for example, when a transformation or mapping depends on input fields at runtime.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * export const passthrough = i.generic(<
18
+ * I extends i.GenericInputs<typeof inputs>
19
+ * >() => {
20
+ * const inputs = {
21
+ * value: i.pins.data(),
22
+ * };
23
+ *
24
+ * return i.nodes.pure({
25
+ * inputs,
26
+ * outputs: {
27
+ * value: i.pins.data<I['value']>(),
28
+ * },
29
+ * run({ inputs, outputs }) {
30
+ * outputs.value = inputs.value;
31
+ * },
32
+ * });
33
+ * });
34
+ * ```
35
+ */
36
+ export declare function generic<N extends () => NodeWithAnyIO>(node: N): GenericNode<N>;
37
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Wraps a node definition and makes it generic.
3
+ * This allows the output type to dynamically adapt based on the provided inputs.
4
+ *
5
+ * Generic nodes are useful when the structure of inputs affects the shape of the outputs -
6
+ * for example, when a transformation or mapping depends on input fields at runtime.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * export const passthrough = i.generic(<
11
+ * I extends i.GenericInputs<typeof inputs>
12
+ * >() => {
13
+ * const inputs = {
14
+ * value: i.pins.data(),
15
+ * };
16
+ *
17
+ * return i.nodes.pure({
18
+ * inputs,
19
+ * outputs: {
20
+ * value: i.pins.data<I['value']>(),
21
+ * },
22
+ * run({ inputs, outputs }) {
23
+ * outputs.value = inputs.value;
24
+ * },
25
+ * });
26
+ * });
27
+ * ```
28
+ */
29
+ export function generic(node) {
30
+ return node();
31
+ }
@@ -0,0 +1,8 @@
1
+ export * from './nodes';
2
+ export * from './controls';
3
+ export * from './env';
4
+ export * from './generic';
5
+ export * from './integration';
6
+ export * from './pins';
7
+ export * from './utils';
8
+ export * from './webhook';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './nodes';
2
+ export * from './controls';
3
+ export * from './env';
4
+ export * from './generic';
5
+ export * from './integration';
6
+ export * from './pins';
7
+ export * from './utils';
8
+ export * from './webhook';
@@ -0,0 +1,84 @@
1
+ import { type EnvRecord, type InferEnvRecordOutput } from './env';
2
+ import { type InferNodeRecordOutput, type NodeRecord } from './nodes';
3
+ import { type Serialize } from './utils';
4
+ import { type Webhook } from './webhook';
5
+ export interface Integration<NR extends NodeRecord = NodeRecord, E extends EnvRecord = EnvRecord> {
6
+ /**
7
+ * Nodes that are available in this integration.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * nodes: {
12
+ * trigger: i.nodes.trigger({
13
+ * subscribe(opts) {
14
+ * opts.next();
15
+ * },
16
+ * }),
17
+ * },
18
+ * ```
19
+ */
20
+ nodes: NR;
21
+ /**
22
+ * Environment variables that are required by this integration.
23
+ * These variables will be prompted for during integration setup
24
+ * and securely stored for use across all nodes.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * env: {
29
+ * API_KEY: i.env({
30
+ * control: i.controls.text({
31
+ * label: 'API Key',
32
+ * description: 'Your service API key for authentication',
33
+ * placeholder: 'sk-...'
34
+ * sensitive: true,
35
+ * })
36
+ * }),
37
+ * },
38
+ * ```
39
+ */
40
+ env?: E;
41
+ /**
42
+ * This function is called when the integration starts.
43
+ * You can initialize shared state or perform setup tasks here.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * start({ state }) {
48
+ * state.apiClient = new ApiClient();
49
+ * },
50
+ * ```
51
+ */
52
+ start?: (opts: IntegrationOptions) => Promise<void> | void;
53
+ /**
54
+ * This function is called when the integration stops.
55
+ * You can clean up resources or save state here.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * stop({ state }) {
60
+ * state.apiClient.close();
61
+ * },
62
+ * ```
63
+ */
64
+ stop?: (opts: IntegrationOptions) => Promise<void> | void;
65
+ }
66
+ export interface IntegrationOptions {
67
+ state: IntegrationState;
68
+ webhook: Webhook;
69
+ }
70
+ /**
71
+ * In-memory state for the integration, shared across all nodes.
72
+ * Can be used to manage reusable resources like API clients or caches.
73
+ * This state is not persisted across restarts.
74
+ */
75
+ export interface IntegrationState {
76
+ }
77
+ export type IntegrationDefinition = Serialize<Integration>;
78
+ export interface InferIntegrationOutput<I extends Integration> {
79
+ nodes: InferNodeRecordOutput<I['nodes']>;
80
+ env: InferEnvRecordOutput<NonNullable<I['env']>>;
81
+ }
82
+ export declare function integration<NR extends NodeRecord<any>, E extends EnvRecord>(definition: Integration<NR, E>): Integration<NR, E> & {
83
+ $infer: InferIntegrationOutput<Integration<NR, E>>;
84
+ };
@@ -0,0 +1,5 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
+ export function integration(definition) {
3
+ // @ts-expect-error - '$infer' is used solely for type inference and does not affect runtime
4
+ return definition;
5
+ }
@@ -0,0 +1,45 @@
1
+ import { type DataPin, type ExecPin, type PinRecord } from '../pins';
2
+ export type BaseNodeInputs = PinRecord<DataPin>;
3
+ export type BaseNodeOutputs = PinRecord<DataPin | ExecPin>;
4
+ /**
5
+ * BaseNode is the base type for all nodes. It contains the common properties that all nodes share.
6
+ */
7
+ export interface BaseNode<I extends BaseNodeInputs = BaseNodeInputs, O extends BaseNodeOutputs = BaseNodeOutputs> {
8
+ /**
9
+ * Category used to organize the node in a hierarchical structure.
10
+ * Helps with grouping and filtering nodes in the UI.
11
+ */
12
+ category?: NodeCategory;
13
+ /**
14
+ * Optional display name for the node, used in the UI.
15
+ * If not specified, the node's exported identifier will be used and automatically converted to title case.
16
+ */
17
+ displayName?: string;
18
+ /**
19
+ * Optional description that explains the purpose and behavior of the node.
20
+ * Typically shown as a tooltip or inline help text in the UI.
21
+ *
22
+ * Helpful for both users and AI assistance to understand the node's intent and how it should be used.
23
+ */
24
+ description?: string;
25
+ /**
26
+ * Defines the input pins for the node.
27
+ * These specify the data required for the node to run.
28
+ */
29
+ inputs?: I;
30
+ /**
31
+ * Defines the output pins for the node.
32
+ * These represent the result or side effects of running the node.
33
+ */
34
+ outputs?: O;
35
+ }
36
+ export interface NodeCategory {
37
+ /**
38
+ * Defines the category path used to group the node in the UI.
39
+ * Each segment in the array represents a level in the category hierarchy.
40
+ *
41
+ * @example
42
+ * ['AI', 'Text']
43
+ */
44
+ path: string[];
45
+ }
File without changes