defineNode
Type-safe helper for creating node definitions. Returns a NodeDefinition with full TypeScript inference from your Zod schemas.
import { defineNode } from '@jam-nodes/core';
import { z } from 'zod';
export const myNode = defineNode({
type: 'my_node',
name: 'My Node',
description: 'Does something useful',
category: 'action',
inputSchema: z.object({ message: z.string() }),
outputSchema: z.object({ result: z.string() }),
estimatedDuration: 5,
capabilities: {
supportsRerun: true,
},
executor: async (input) => ({
success: true,
output: { result: `Processed: ${input.message}` },
}),
});
DefineNodeConfig
Unique identifier used in workflows.
Display name shown in the editor.
Description shown in the node palette.
'action' | 'logic' | 'integration' | 'transform'
inputSchema
z.ZodSchema<TInput>
required
Zod schema for input validation.
outputSchema
z.ZodSchema<TOutput>
required
Zod schema for output validation.
executor
NodeExecutor<TInput, TOutput>
required
Async function implementing the node’s logic.
Estimated execution time in seconds.
Feature flags (supportsRerun, supportsCancel, etc.).
Resolves all {{variable}} references in a node’s configuration object using an ExecutionContext.
import { prepareNodeInput, ExecutionContext } from '@jam-nodes/core';
const ctx = new ExecutionContext({
apiUrl: 'https://api.example.com',
token: 'abc123',
});
const resolvedInput = prepareNodeInput(
{
url: '{{apiUrl}}/users',
headers: { Authorization: 'Bearer {{token}}' },
},
ctx
);
// { url: 'https://api.example.com/users', headers: { Authorization: 'Bearer abc123' } }
prepareNodeInput calls context.interpolateObject(nodeSettings) internally. It’s a convenience wrapper for the common pattern of resolving node config before execution.