@codemation/core 0.2.3 → 0.3.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.
@@ -4,10 +4,11 @@ import type {
4
4
  CredentialRequirement,
5
5
  CredentialTypeId,
6
6
  } from "../contracts/credentialTypes";
7
- import type { Node, NodeExecutionContext } from "../contracts/runtimeTypes";
8
- import type { Items, NodeOutputs, RunnableNodeConfig } from "../contracts/workflowTypes";
7
+ import type { ItemNode, Node, NodeExecutionContext } from "../contracts/runtimeTypes";
8
+ import type { Item, ItemInputMapper, Items, NodeOutputs, RunnableNodeConfig } from "../contracts/workflowTypes";
9
9
  import type { TypeToken } from "../di";
10
10
  import { node as persistedNode } from "../runtime-types/runtimeTypeDecorators.types";
11
+ import type { ZodType } from "zod";
11
12
  import { z } from "zod";
12
13
  import { DefinedNodeRegistry } from "./DefinedNodeRegistry";
13
14
 
@@ -54,27 +55,46 @@ export interface DefinedNodeRunContext<
54
55
  readonly execution: NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>;
55
56
  }
56
57
 
58
+ /**
59
+ * Arguments for {@link defineNode} `executeOne` (engine `ctx` matches {@link ItemNode.executeOne};
60
+ * the second callback parameter adds {@link DefinedNodeRunContext} for credential accessors).
61
+ */
62
+ export type DefineNodeExecuteOneArgs<TConfig extends CredentialJsonRecord, TInputJson, TWireJson> = Readonly<{
63
+ input: TInputJson;
64
+ item: Item;
65
+ itemIndex: number;
66
+ items: Items;
67
+ ctx: NodeExecutionContext<RunnableNodeConfig<TInputJson, unknown, TWireJson> & Readonly<{ config: TConfig }>>;
68
+ }>;
69
+
57
70
  export interface DefinedNode<
58
71
  TKey extends string,
59
72
  TConfig extends CredentialJsonRecord,
60
73
  TInputJson,
61
74
  TOutputJson,
62
75
  _TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
76
+ TWireJson = TInputJson,
63
77
  > {
64
78
  readonly kind: "defined-node";
65
79
  readonly key: TKey;
66
80
  readonly title: string;
67
81
  readonly description?: string;
68
- create(config: TConfig, name?: string, id?: string): RunnableNodeConfig<TInputJson, TOutputJson>;
82
+ create(config: TConfig, name?: string, id?: string): RunnableNodeConfig<TInputJson, TOutputJson, TWireJson>;
69
83
  register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;
70
84
  }
71
85
 
86
+ /**
87
+ * Plugin / DSL-friendly node: **one item in, one item out** per engine activation step.
88
+ * The engine applies {@link RunnableNodeConfig.mapInput} (if any) + {@link RunnableNodeConfig.inputSchema}
89
+ * before `executeOne`. Use {@link defineBatchNode} for legacy batch `run(items, …)` semantics.
90
+ */
72
91
  export interface DefineNodeOptions<
73
92
  TKey extends string,
74
93
  TConfig extends CredentialJsonRecord,
75
94
  TInputJson,
76
95
  TOutputJson,
77
96
  TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
97
+ TWireJson = TInputJson,
78
98
  > {
79
99
  readonly key: TKey;
80
100
  readonly title: string;
@@ -84,6 +104,38 @@ export interface DefineNodeOptions<
84
104
  * The Next host resolves Lucide (`lucide:…`), built-in SVGs (`builtin:…`), Simple Icons (`si:…`), and image URLs (`https:`, `data:`, `/…`).
85
105
  */
86
106
  readonly icon?: string;
107
+ /** Default values / form hints for **static** node configuration (credentials, retry, IDs), not per-item payload. */
108
+ readonly input?: Readonly<Record<keyof TConfig & string, unknown>>;
109
+ readonly configSchema?: z.ZodType<TConfig>;
110
+ readonly credentials?: TBindings;
111
+ /**
112
+ * Validates **`input`** after optional {@link mapInput} (engine also accepts `inputSchema` on the node class).
113
+ */
114
+ readonly inputSchema?: ZodType<TInputJson>;
115
+ /**
116
+ * Maps wire JSON (`item.json` from upstream) to execute input before validation.
117
+ */
118
+ readonly mapInput?: ItemInputMapper<TWireJson, TInputJson>;
119
+ executeOne(
120
+ args: DefineNodeExecuteOneArgs<TConfig, TInputJson, TWireJson>,
121
+ context: DefinedNodeRunContext<TConfig, TBindings>,
122
+ ): MaybePromise<TOutputJson>;
123
+ }
124
+
125
+ /**
126
+ * Batch-oriented defined node (legacy): receives all items at once via `run`.
127
+ */
128
+ export interface DefineBatchNodeOptions<
129
+ TKey extends string,
130
+ TConfig extends CredentialJsonRecord,
131
+ TInputJson,
132
+ TOutputJson,
133
+ TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
134
+ > {
135
+ readonly key: TKey;
136
+ readonly title: string;
137
+ readonly description?: string;
138
+ readonly icon?: string;
87
139
  readonly input?: Readonly<Record<keyof TConfig & string, unknown>>;
88
140
  readonly configSchema?: z.ZodType<TConfig>;
89
141
  readonly credentials?: TBindings;
@@ -161,11 +213,100 @@ export function defineNode<
161
213
  TInputJson,
162
214
  TOutputJson,
163
215
  TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
216
+ TWireJson = TInputJson,
217
+ >(
218
+ options: DefineNodeOptions<TKey, TConfig, TInputJson, TOutputJson, TBindings, TWireJson>,
219
+ ): DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings, TWireJson> {
220
+ const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);
221
+ type DefinedRunnableNodeConfigShape = RunnableNodeConfig<TInputJson, TOutputJson, TWireJson> &
222
+ Readonly<{ config: TConfig }>;
223
+
224
+ const DefinedNodeRuntime = class implements ItemNode<DefinedRunnableNodeConfigShape, TInputJson, TOutputJson> {
225
+ readonly kind = "node" as const;
226
+ readonly outputPorts = ["main"] as const;
227
+ readonly inputSchema = options.inputSchema;
228
+
229
+ async executeOne(
230
+ args: Readonly<{
231
+ input: TInputJson;
232
+ item: Item;
233
+ itemIndex: number;
234
+ items: Items;
235
+ ctx: NodeExecutionContext<DefinedRunnableNodeConfigShape>;
236
+ }>,
237
+ ): Promise<TOutputJson> {
238
+ const ctx = args.ctx;
239
+ const context: DefinedNodeRunContext<TConfig, TBindings> = {
240
+ config: ctx.config.config,
241
+ credentials: definedNodeCredentialAccessorFactory.create(
242
+ options.credentials,
243
+ ctx,
244
+ ) as DefinedNodeCredentialAccessors<TBindings>,
245
+ execution: ctx as unknown as NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>,
246
+ };
247
+ const payload: DefineNodeExecuteOneArgs<TConfig, TInputJson, TWireJson> = {
248
+ input: args.input,
249
+ item: args.item,
250
+ itemIndex: args.itemIndex,
251
+ items: args.items,
252
+ ctx,
253
+ };
254
+ return await options.executeOne(payload, context);
255
+ }
256
+ };
257
+
258
+ persistedNode({ name: options.key })(DefinedNodeRuntime);
259
+
260
+ const DefinedRunnableNodeConfig = class implements RunnableNodeConfig<TInputJson, TOutputJson, TWireJson> {
261
+ readonly kind = "node" as const;
262
+ readonly type: TypeToken<unknown> = DefinedNodeRuntime;
263
+ readonly icon = options.icon;
264
+ readonly inputSchema = options.inputSchema;
265
+ readonly mapInput = options.mapInput;
266
+
267
+ constructor(
268
+ public readonly name: string,
269
+ public readonly config: TConfig,
270
+ public readonly id?: string,
271
+ ) {}
272
+
273
+ getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {
274
+ return credentialRequirements;
275
+ }
276
+ };
277
+
278
+ const definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings, TWireJson> = {
279
+ kind: "defined-node",
280
+ key: options.key,
281
+ title: options.title,
282
+ description: options.description,
283
+ create(config, name = options.title, id) {
284
+ return new DefinedRunnableNodeConfig(name, config, id);
285
+ },
286
+ register(context) {
287
+ context.registerNode(DefinedNodeRuntime);
288
+ },
289
+ };
290
+
291
+ DefinedNodeRegistry.register(
292
+ definition as DefinedNode<string, Record<string, unknown>, unknown, unknown, undefined, unknown>,
293
+ );
294
+
295
+ return definition;
296
+ }
297
+
298
+ export function defineBatchNode<
299
+ TKey extends string,
300
+ TConfig extends CredentialJsonRecord,
301
+ TInputJson,
302
+ TOutputJson,
303
+ TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
164
304
  >(
165
- options: DefineNodeOptions<TKey, TConfig, TInputJson, TOutputJson, TBindings>,
166
- ): DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> {
305
+ options: DefineBatchNodeOptions<TKey, TConfig, TInputJson, TOutputJson, TBindings>,
306
+ ): DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings, TInputJson> {
167
307
  const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);
168
- type DefinedRunnableNodeConfigShape = RunnableNodeConfig<TInputJson, TOutputJson> & Readonly<{ config: TConfig }>;
308
+ type DefinedRunnableNodeConfigShape = RunnableNodeConfig<TInputJson, TOutputJson, TInputJson> &
309
+ Readonly<{ config: TConfig }>;
169
310
 
170
311
  const DefinedNodeRuntime = class implements Node<DefinedRunnableNodeConfigShape> {
171
312
  readonly kind = "node" as const;
@@ -198,7 +339,7 @@ export function defineNode<
198
339
 
199
340
  persistedNode({ name: options.key })(DefinedNodeRuntime);
200
341
 
201
- const DefinedRunnableNodeConfig = class implements RunnableNodeConfig<TInputJson, TOutputJson> {
342
+ const DefinedRunnableNodeConfig = class implements RunnableNodeConfig<TInputJson, TOutputJson, TInputJson> {
202
343
  readonly kind = "node" as const;
203
344
  readonly type: TypeToken<unknown> = DefinedNodeRuntime;
204
345
  readonly icon = options.icon;
@@ -214,7 +355,7 @@ export function defineNode<
214
355
  }
215
356
  };
216
357
 
217
- const definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> = {
358
+ const definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings, TInputJson> = {
218
359
  kind: "defined-node",
219
360
  key: options.key,
220
361
  title: options.title,
@@ -227,7 +368,9 @@ export function defineNode<
227
368
  },
228
369
  };
229
370
 
230
- DefinedNodeRegistry.register(definition as DefinedNode<string, Record<string, unknown>, unknown, unknown>);
371
+ DefinedNodeRegistry.register(
372
+ definition as DefinedNode<string, Record<string, unknown>, unknown, unknown, undefined, unknown>,
373
+ );
231
374
 
232
375
  return definition;
233
376
  }
@@ -5,8 +5,10 @@ export type {
5
5
  DefinedNodeCredentialBinding,
6
6
  DefinedNodeCredentialBindings,
7
7
  DefinedNodeRunContext,
8
+ DefineBatchNodeOptions,
9
+ DefineNodeExecuteOneArgs,
8
10
  DefineNodeOptions,
9
11
  } from "./defineNode.types";
10
- export { defineNode } from "./defineNode.types";
12
+ export { defineBatchNode, defineNode } from "./defineNode.types";
11
13
  export type { DefineCredentialOptions } from "./defineCredential.types";
12
14
  export { defineCredential } from "./defineCredential.types";