Skip to main content

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

type
string
required
Unique identifier used in workflows.
name
string
required
Display name shown in the editor.
description
string
required
Description shown in the node palette.
category
NodeCategory
required
'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.
estimatedDuration
number
Estimated execution time in seconds.
capabilities
NodeCapabilities
Feature flags (supportsRerun, supportsCancel, etc.).

prepareNodeInput

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.