Skip to content

escalated-dev/escalated-plugin-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@escalated-dev/plugin-sdk

SDK for building Escalated plugins. Write plugins once in TypeScript, run them across all Escalated backend frameworks (Laravel, Django, AdonisJS, Rails).

Quick Start

import { definePlugin } from '@escalated-dev/plugin-sdk'

export default definePlugin({
  name: 'my-plugin',
  version: '1.0.0',

  actions: {
    'ticket.created': async (event, ctx) => {
      ctx.log.info('New ticket!', event)
    },
  },
})

Installation

npm install @escalated-dev/plugin-sdk

Core API

definePlugin(definition)

The single entry point for defining a plugin. Returns a ResolvedPlugin with normalized filters and endpoints and a toManifest() method used by the Escalated host to register your plugin.

import { definePlugin, type PluginContext } from '@escalated-dev/plugin-sdk'

export default definePlugin({
  name: 'my-plugin',
  version: '1.0.0',
  description: 'Does something useful',

  // Config fields shown in the admin settings UI
  config: [
    { name: 'api_key', label: 'API Key', type: 'password', required: true },
    { name: 'notify_channel', label: 'Notify Channel', type: 'text' },
  ],

  // Action hooks — fire-and-forget
  actions: {
    'ticket.created': async (event, ctx) => { /* ... */ },
    'ticket.resolved': async (event, ctx) => { /* ... */ },
  },

  // Filter hooks — must return the (possibly modified) value
  filters: {
    'ticket.reply.compose': async (data, ctx) => {
      return { ...data, extra_field: 'value' }
    },
    // Shorthand with explicit priority
    'ticket.statuses': {
      priority: 5,
      handler: async (statuses, ctx) => [...statuses, { key: 'custom', name: 'Custom' }],
    },
  },

  // REST endpoints exposed by the plugin
  endpoints: {
    'GET /my-plugin/status': async (ctx, req) => ({ ok: true }),
    'POST /my-plugin/action': {
      capability: 'manage_settings',
      handler: async (ctx, req) => { /* ... */ },
    },
  },

  // Incoming webhooks
  webhooks: {
    'POST /webhooks/my-service': async (ctx, req) => { /* ... */ },
  },

  // Scheduled tasks (cron expression as key)
  cron: {
    '0 9 * * 1': async (ctx) => {
      ctx.log.info('Running weekly report')
    },
  },

  // Lifecycle
  onActivate: async (ctx) => { await ctx.store.set('data', 'init', { activated: true }) },
  onDeactivate: async (ctx) => { /* cleanup */ },
})

Plugin Context (ctx)

Every handler receives a PluginContext with the following services:

Property Type Description
ctx.config ConfigStore Read/write plugin configuration values
ctx.store DataStore Persistent key-value and query store scoped to the plugin
ctx.http HttpClient Make outbound HTTP requests
ctx.broadcast BroadcastClient Push real-time events to channels, users, or tickets
ctx.log Logger Structured logging (info, warn, error, debug)
ctx.tickets TicketRepository Find, query, create, and update tickets
ctx.replies ReplyRepository Find, query, and create replies
ctx.contacts ContactRepository Find contacts by ID or email, create contacts
ctx.tags TagRepository List and create tags
ctx.departments DepartmentRepository List and find departments
ctx.agents AgentRepository List and find agents
ctx.emit function Emit a custom hook for other plugins to listen to
ctx.currentUser function Returns the currently authenticated user, or null

UI Extensions

definePlugin({
  // ...

  // Full-page routes
  pages: [
    {
      route: '/admin/my-plugin',
      component: 'MySettingsPage',
      layout: 'admin',
      capability: 'manage_settings',
      menu: { label: 'My Plugin', section: 'admin', position: 50 },
    },
  ],

  // Inject components into existing pages
  components: [
    {
      page: 'ticket.show',
      slot: 'sidebar',
      component: 'MyTicketPanel',
      order: 20,
    },
  ],

  // Dashboard widgets
  widgets: [
    {
      component: 'MyWidget',
      label: 'My Stats',
      size: 'half',
      badge: async (ctx) => {
        const count = await ctx.store.query('alerts', { unread: true })
        return count.length || null
      },
    },
  ],
})

Documentation

See the Escalated Docs for the full plugin development guide.

Requirements

  • Node.js >= 18
  • TypeScript >= 5.4

About

SDK for building Escalated plugins — framework-agnostic, TypeScript-first

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors