JSPM

@avallo/workflow-sdk

0.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q66174F
  • License MIT

SDK for building custom Avallo Workflow nodes

Package Exports

  • @avallo/workflow-sdk

Readme

@avallo/workflow-sdk

Official SDK for building custom integrations with Avallo Workflow Engine

npm version License: MIT

Build production-ready workflow actions and triggers for the Avallo Workflow Engine with a simple, TypeScript-first API.

Features

  • Simple API: Define actions and triggers with minimal boilerplate
  • 🔒 Type-Safe: Full TypeScript support with intelligent autocomplete
  • 🎯 Best-in-Class DX: Optimized for developer experience
  • 🔄 Variable Interpolation: Built-in support for {{variable}} syntax
  • 📊 Schema Generation: Automatic JSON Schema + UI Schema generation
  • 🔌 Plug & Play: Works seamlessly with the Avallo Workflow Engine

Installation

npm install @avallo/workflow-sdk
# or
pnpm add @avallo/workflow-sdk
# or
yarn add @avallo/workflow-sdk

Quick Start

Creating an Action

import { defineAction } from '@avallo/workflow-sdk';

export default defineAction({
  id: 'send-email',
  name: 'Send Email',
  description: 'Sends an email via SMTP',
  
  config: {
    to: {
      type: 'string',
      label: 'To',
      description: 'Recipient email address',
      required: true,
      supportsVariables: true,
    },
    subject: {
      type: 'string',
      label: 'Subject',
      required: true,
      supportsVariables: true,
    },
    body: {
      type: 'textarea',
      label: 'Body',
      required: true,
      supportsVariables: true,
    },
  },
  
  async execute(context) {
    // Interpolate variables like {{previous_node.email}}
    const to = context.utils.interpolate(context.config.to);
    const subject = context.utils.interpolate(context.config.subject);
    const body = context.utils.interpolate(context.config.body);
    
    // Your email sending logic here
    await sendEmail({ to, subject, body });
    
    return {
      success: true,
      message_id: 'msg_123',
      sent_at: new Date().toISOString(),
    };
  },
  
  outputs: {
    success: {
      type: 'boolean',
      label: 'Success',
      description: 'Whether the email was sent successfully',
    },
    message_id: {
      type: 'string',
      label: 'Message ID',
      description: 'Unique identifier for the sent email',
    },
    sent_at: {
      type: 'string',
      label: 'Sent At',
      description: 'Timestamp when the email was sent',
    },
  },
});

Creating a Trigger

import { defineTrigger } from '@avallo/workflow-sdk';

export default defineTrigger({
  id: 'new-email',
  name: 'New Email',
  description: 'Triggers when a new email arrives',
  type: 'polling',
  
  config: {
    folder: {
      type: 'select',
      label: 'Folder',
      description: 'Which folder to monitor',
      required: true,
      options: [
        { label: 'Inbox', value: 'inbox' },
        { label: 'Sent', value: 'sent' },
        { label: 'Drafts', value: 'drafts' },
      ],
    },
  },
  
  async execute(context) {
    const folder = context.trigger_config.folder;
    
    // Fetch new emails
    const emails = await fetchNewEmails(folder);
    
    // Return result
    return context.utils.createResult(
      emails.length > 0,
      emails,
      {
        checked_at: new Date(),
        items_found: emails.length,
      }
    );
  },
  
  outputs: {
    from: {
      type: 'string',
      label: 'From',
      description: 'Sender email address',
    },
    subject: {
      type: 'string',
      label: 'Subject',
      description: 'Email subject',
    },
    body: {
      type: 'string',
      label: 'Body',
      description: 'Email body content',
    },
    received_at: {
      type: 'string',
      label: 'Received At',
      description: 'Timestamp when email was received',
    },
  },
  
  polling_config: {
    interval_seconds: 300, // Check every 5 minutes
    dedupe_key: 'email_id',
  },
});

Creating a Complete App

import { defineApp } from '@avallo/workflow-sdk';
import sendEmailAction from './actions/send-email';
import newEmailTrigger from './triggers/new-email';

export default defineApp({
  app_id: 'my-email-app',
  name: 'My Email App',
  description: 'Email integration for workflows',
  category: 'communication',
  icon_url: 'https://example.com/icon.png',
  
  actions: [sendEmailAction],
  triggers: [newEmailTrigger],
});

API Reference

defineAction(options)

Define a workflow action node.

Options:

  • id (string): Unique identifier for the action
  • name (string): Display name
  • description (string): Short description
  • category (string, optional): Category for grouping
  • icon (string, optional): Icon name or URL
  • config (SimplifiedConfigSchema): Configuration fields
  • execute (function): Execution handler
  • outputs (SimplifiedOutputSchema): Output field definitions
  • requires_connection (boolean, optional): Whether connection is needed
  • is_premium (boolean, optional): Whether action requires premium plan
  • documentation_url (string, optional): Link to documentation

Returns: { definition, execute }

defineTrigger(options)

Define a workflow trigger node.

Options:

  • id (string): Unique identifier for the trigger
  • name (string): Display name
  • description (string): Short description
  • type ('webhook' | 'polling' | 'event'): Trigger type
  • category (string, optional): Category for grouping
  • icon (string, optional): Icon name or URL
  • config (SimplifiedConfigSchema): Configuration fields
  • execute (function): Execution handler
  • outputs (SimplifiedOutputSchema): Output field definitions
  • polling_config (object, optional): Polling configuration
    • interval_seconds (number): Check interval in seconds
    • dedupe_key (string, optional): Field to deduplicate on
  • requires_connection (boolean, optional): Whether connection is needed
  • is_premium (boolean, optional): Whether trigger requires premium plan
  • documentation_url (string, optional): Link to documentation

Returns: { definition, execute }

defineApp(options)

Define a complete app with multiple actions and triggers.

Options:

  • app_id (string): Unique app identifier
  • name (string): App name
  • description (string, optional): App description
  • icon_url (string, optional): App icon URL
  • category (string, optional): App category
  • actions (array): Array of defined actions
  • triggers (array, optional): Array of defined triggers

Returns: App registration object

Configuration Field Types

Type Description Example
string Text input Email address, name
number Numeric input Age, count
boolean Checkbox Enable feature
select Dropdown Choose option
multiselect Multi-select Tags
textarea Multi-line text Message body
date Date picker Birth date
datetime Date + time picker Scheduled time

Context Utilities

Action Context

context.config                    // Parsed configuration
context.workflow_id               // Current workflow ID
context.execution_id              // Current execution ID
context.node_id                   // Current node ID
context.previous_outputs          // All previous node outputs

// Utilities
context.utils.interpolate(str)    // Interpolate {{variables}}
context.utils.fetch(url, options) // Make HTTP requests
context.utils.log(level, msg)     // Log messages

Trigger Context

context.trigger_config            // Trigger configuration
context.workflow_id               // Workflow ID
context.client_id                 // Client ID
context.account_id                // Account ID

// Utilities
context.utils.interpolate(str)           // Interpolate {{variables}}
context.utils.fetch(url, options)        // Make HTTP requests
context.utils.log(level, msg)            // Log messages
context.utils.createResult(hasData, data) // Create trigger result

Variable Interpolation

The SDK supports variable interpolation using {{variable}} syntax:

// In config
{
  email: {
    type: 'string',
    label: 'Email',
    supportsVariables: true, // Enable variable interpolation
  }
}

// In execute function
const email = context.utils.interpolate(context.config.email);
// "{{webhook.body.email}}" → "user@example.com"

Error Handling

import { createActionError, createActionSuccess } from '@avallo/workflow-sdk';

async execute(context) {
  try {
    const result = await doSomething();
    return createActionSuccess(result, {
      duration_ms: 150,
      records_processed: 5,
    });
  } catch (error) {
    return createActionError(error.message, {
      error_code: error.code,
    });
  }
}

Best Practices

  1. Validate Configuration: Use the validate hook to validate configuration before execution
  2. Use Type Safety: Leverage TypeScript for better DX
  3. Log Appropriately: Use context.utils.log() for debugging
  4. Handle Errors Gracefully: Always wrap execution in try/catch
  5. Document Outputs: Provide clear descriptions for all output fields
  6. Support Variables: Enable supportsVariables for user-facing strings
  7. Test Thoroughly: Test with real workflow executions

Examples

See the examples directory for more complete examples:

Support

License

MIT © Avallo