CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pipedream--types

TypeScript types for Pipedream components (sources and actions)

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

component-context.mddocs/

Component Context

Runtime context types available during component execution, including access to props, services, and authentication.

Capabilities

Component This Context

The main runtime context available in component methods with access to props, services, and special methods.

/**
 * Runtime context object available in component methods (this)
 */
interface ComponentThis {
  /** Dynamic access to all component props */
  [propName: string]: any;
  
  /** Method for emitting events */
  $emit: EmitMethod;
  
  /** Authentication context when using app integrations (optional) */
  $auth?: AuthContext;
  
  /** Database service when using $.service.db (optional) */
  db?: DatabaseService;
  
  /** HTTP interface when using $.interface.http (optional) */
  http?: HttpEndpoint & { respond: HttpRespondMethod };
  
  /** Timer interface when using $.interface.timer (optional) */
  timer?: { type: "$.interface.timer" };
}

Usage Examples:

import { PipedreamComponent, ComponentThis } from "@pipedream/types";

const contextAwareComponent: PipedreamComponent = {
  name: "Context Aware Component",
  version: "1.0.0",
  props: {
    apiKey: {
      type: "string",
      label: "API Key",
      secret: true
    },
    maxResults: {
      type: "integer",
      label: "Max Results",
      default: 10
    },
    db: "$.service.db"
  },
  async run(event) {
    // Access props directly
    console.log("API Key configured:", !!this.apiKey);
    console.log("Max results:", this.maxResults);
    
    // Use database service
    const lastRun = this.db.get("lastRunTime") || 0;
    this.db.set("lastRunTime", Date.now());
    
    // Emit events
    this.$emit({
      message: "Component executed",
      lastRun,
      currentRun: Date.now()
    });
  }
};

Authentication Context

Authentication information available when using app integrations.

/**
 * Authentication context for app integrations
 */
interface AuthContext {
  /** OAuth 2.0 access token (optional) */
  oauth_access_token?: string;
  
  /** OAuth 2.0 refresh token (optional) */
  oauth_refresh_token?: string;
  
  /** API key for services that use API key authentication (optional) */
  api_key?: string;
  
  /** Discord bot token (optional) */
  bot_token?: string;
  
  /** Twilio Account SID (optional) */
  Sid?: string;
  
  /** Twilio Auth Token (optional) */
  Secret?: string;
  
  /** Twilio Account SID (optional) */
  AccountSid?: string;
  
  /** Salesforce instance identifier (optional) */
  yourinstance?: string;
  
  /** Salesforce instance URL (optional) */
  instance_url?: string;
  
  /** Additional service-specific authentication fields */
  [key: string]: any;
}

Usage Examples:

// OAuth-based component
const oauthComponent: PipedreamComponent = {
  name: "OAuth Component",
  version: "1.0.0",
  props: {
    github: {
      type: "app",
      app: "github"
    }
  },
  async run(event) {
    // Access OAuth token from app authentication
    const token = this.github.$auth.oauth_access_token;
    
    const response = await fetch("https://api.github.com/user/repos", {
      headers: {
        "Authorization": `Bearer ${token}`,
        "Accept": "application/vnd.github.v3+json"
      }
    });
    
    const repos = await response.json();
    
    repos.forEach(repo => {
      this.$emit(repo, {
        id: repo.id,
        summary: `Repository: ${repo.full_name}`
      });
    });
  }
};

// API key-based component
const apiKeyComponent: PipedreamComponent = {
  name: "API Key Component",
  version: "1.0.0",
  props: {
    openai: {
      type: "app",
      app: "openai"
    },
    prompt: {
      type: "string",
      label: "Prompt",
      description: "Text prompt for OpenAI"
    }
  },
  async run(event) {
    const apiKey = this.openai.$auth.api_key;
    
    const response = await fetch("https://api.openai.com/v1/completions", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        model: "text-davinci-003",
        prompt: this.prompt,
        max_tokens: 100
      })
    });
    
    const completion = await response.json();
    
    this.$emit(completion, {
      id: completion.id,
      summary: "OpenAI completion generated"
    });
  }
};

Database Service Context

Database service interface available when using $.service.db.

/**
 * Database service for persistent storage
 */
interface DatabaseService {
  /** Service type identifier */
  type: "$.service.db";
  
  /**
   * Retrieve a value by key
   * @param key - The key to retrieve
   * @returns The stored value or undefined if not found
   */
  get: (key: string) => any;
  
  /**
   * Store a value by key
   * @param key - The key to store under
   * @param value - The value to store
   */
  set: (key: string, value: any) => void;
}

Usage Examples:

// State management with database
const statefulComponent: PipedreamComponent = {
  name: "Stateful Component",
  version: "1.0.0",
  props: {
    timer: {
      type: "$.interface.timer",
      default: { intervalSeconds: 300 }
    },
    db: "$.service.db"
  },
  async run(event) {
    // Get previous state
    const runCount = this.db.get("runCount") || 0;
    const lastItems = this.db.get("lastItems") || [];
    
    // Fetch new data
    const newItems = await fetchNewItems();
    
    // Update state
    this.db.set("runCount", runCount + 1);
    this.db.set("lastItems", newItems);
    this.db.set("lastRunTime", Date.now());
    
    // Use state in processing
    console.log(`Run #${runCount + 1}, found ${newItems.length} items`);
    
    // Emit only new items (not in lastItems)
    const actuallyNew = newItems.filter(item => 
      !lastItems.some(prev => prev.id === item.id)
    );
    
    actuallyNew.forEach(item => {
      this.$emit(item, {
        id: item.id,
        summary: `New item: ${item.name}`,
        ts: Date.now()
      });
    });
  }
};

// Pagination state management
const paginatedComponent: PipedreamComponent = {
  name: "Paginated Component",
  version: "1.0.0",
  props: {
    timer: {
      type: "$.interface.timer", 
      default: { intervalSeconds: 600 }
    },
    db: "$.service.db"
  },
  async run(event) {
    let nextPageToken = this.db.get("nextPageToken");
    let hasMorePages = true;
    
    while (hasMorePages) {
      const response = await fetchPage(nextPageToken);
      
      // Process page items
      response.items.forEach(item => {
        this.$emit(item, {
          id: item.id,
          summary: `Item: ${item.name}`
        });
      });
      
      // Update pagination state
      nextPageToken = response.nextPageToken;
      hasMorePages = !!nextPageToken;
      
      // Prevent infinite loops
      if (response.items.length === 0) {
        hasMorePages = false;
      }
    }
    
    // Store next page token for next run
    this.db.set("nextPageToken", nextPageToken);
  }
};

HTTP Context

HTTP-specific context available when using $.interface.http.

/**
 * HTTP endpoint information
 */
interface HttpEndpoint {
  /** Generated unique endpoint URL */
  endpoint: string;
}

/**
 * Combined HTTP context available in components
 */
interface HttpContext extends HttpEndpoint {
  /** Method for sending HTTP responses */
  respond: HttpRespondMethod;
}

Usage Examples:

// HTTP endpoint with response
const httpEndpointComponent: PipedreamComponent = {
  name: "HTTP Endpoint Component",
  version: "1.0.0",
  props: {
    http: {
      type: "$.interface.http",
      customResponse: true
    }
  },
  async run(event) {
    console.log("Endpoint URL:", this.http.endpoint);
    
    try {
      // Process the request
      const result = await processRequest(event.body);
      
      // Send success response
      this.http.respond({
        status: 200,
        headers: {
          "Content-Type": "application/json"
        },
        body: {
          success: true,
          data: result,
          timestamp: new Date().toISOString()
        }
      });
      
      // Emit event for downstream processing
      this.$emit(result);
      
    } catch (error) {
      // Send error response
      this.http.respond({
        status: 500,
        headers: {
          "Content-Type": "application/json"
        },
        body: {
          success: false,
          error: error.message,
          timestamp: new Date().toISOString()
        }
      });
    }
  }
};

Advanced Context Patterns

Method Context Binding

Using component methods with proper context:

const methodComponent: PipedreamComponent = {
  name: "Method Component",
  version: "1.0.0",
  props: {
    apiEndpoint: {
      type: "string",
      label: "API Endpoint",
      default: "https://api.example.com"
    },
    db: "$.service.db"
  },
  methods: {
    async makeApiCall(path: string, params?: any) {
      // Access component props and context
      const response = await fetch(`${this.apiEndpoint}${path}`, {
        method: params ? "POST" : "GET",
        headers: {
          "Content-Type": "application/json"
        },
        body: params ? JSON.stringify(params) : undefined
      });
      
      return response.json();
    },
    
    getCachedData(key: string) {
      return this.db.get(`cache:${key}`);
    },
    
    setCachedData(key: string, data: any, ttl: number = 3600) {
      this.db.set(`cache:${key}`, {
        data,
        expires: Date.now() + (ttl * 1000)
      });
    }
  },
  async run(event) {
    // Use methods with proper context
    const cachedData = this.getCachedData("users");
    
    let users;
    if (cachedData && cachedData.expires > Date.now()) {
      users = cachedData.data;
    } else {
      users = await this.makeApiCall("/users");
      this.setCachedData("users", users, 1800); // 30 minutes
    }
    
    users.forEach(user => {
      this.$emit(user, {
        id: user.id,
        summary: `User: ${user.name}`
      });
    });
  }
};

Multi-Service Context

Using multiple services in a single component:

const multiServiceComponent: PipedreamComponent = {
  name: "Multi-Service Component",
  version: "1.0.0",
  props: {
    slack: {
      type: "app",
      app: "slack"
    },
    github: {
      type: "app", 
      app: "github"
    },
    http: {
      type: "$.interface.http"
    },
    db: "$.service.db"
  },
  async run(event) {
    // Access multiple app contexts
    const slackToken = this.slack.$auth.bot_token;
    const githubToken = this.github.$auth.oauth_access_token;
    
    // Use database for coordination
    const lastSyncTime = this.db.get("lastGithubSync") || 0;
    
    // Process GitHub events
    const events = await fetchGithubEvents(githubToken, lastSyncTime);
    
    // Send notifications to Slack
    for (const ghEvent of events) {
      await sendSlackMessage(slackToken, {
        text: `GitHub: ${ghEvent.type} in ${ghEvent.repo.name}`,
        channel: "#dev-notifications"
      });
      
      // Emit for other systems
      this.$emit(ghEvent, {
        id: ghEvent.id,
        summary: `${ghEvent.type}: ${ghEvent.repo.name}`
      });
    }
    
    // Update sync time
    this.db.set("lastGithubSync", Date.now());
  }
};

Install with Tessl CLI

npx tessl i tessl/npm-pipedream--types

docs

component-context.md

component-structure.md

event-system.md

index.md

interface-types.md

prop-types.md

service-types.md

tile.json