Skip to main content

BasePlugin

Abstract base class for creating MuluTime plugins.

Class: BasePlugin

abstract class BasePlugin implements IntegrationPlugin {
abstract manifest: PluginManifest;
}

The BasePlugin class provides a foundation for building MuluTime plugins with built-in functionality for lifecycle management, action system integration, and SDK access.

Properties

manifest

abstract manifest: PluginManifest

Required. Plugin manifest containing metadata and configuration.

Example:

export class MyPlugin extends BasePlugin {
manifest: PluginManifest = {
id: 'com.example.my-plugin',
name: 'My Plugin',
version: '1.0.0',
description: 'A sample plugin',
author: { name: 'John Doe', email: 'john@example.com' },
category: PluginCategory.INTEGRATION,
permissions: [PluginPermission.READ_BOOKING_DATA],
// ... other manifest properties
};
}

Methods

getSDK()

Returns the SDK instance for the current plugin context.

protected getSDK(): PluginSDK

Returns: PluginSDK instance with full access to platform capabilities.

Example:

export class MyPlugin extends BasePlugin {
async someMethod() {
const sdk = this.getSDK();
await sdk.storage.set('key', 'value');
sdk.logger.info('Data stored');
}
}

Lifecycle Methods

onInstall()

Called when the plugin is installed.

async onInstall?(context: PluginContext): Promise<void>

Parameters:

  • context - The plugin context

Example:

async onInstall(context: PluginContext): Promise<void> {
const sdk = this.getSDK();

// Initialize plugin data
await sdk.storage.set('install-date', new Date().toISOString());
await sdk.storage.set('version', this.manifest.version);

sdk.logger.info('Plugin installed successfully');
}

onUninstall()

Called when the plugin is uninstalled.

async onUninstall?(context: PluginContext): Promise<void>

Example:

async onUninstall(context: PluginContext): Promise<void> {
const sdk = this.getSDK();

// Cleanup plugin data
const keys = await sdk.storage.list();
for (const key of keys) {
await sdk.storage.delete(key);
}

sdk.logger.info('Plugin uninstalled and cleaned up');
}

onUpdate()

Called when the plugin is updated to a new version.

async onUpdate?(context: PluginContext, oldVersion: string): Promise<void>

Parameters:

  • context - The plugin context
  • oldVersion - The previous version string

Example:

async onUpdate(context: PluginContext, oldVersion: string): Promise<void> {
const sdk = this.getSDK();

sdk.logger.info(`Updating from ${oldVersion} to ${this.manifest.version}`);

// Perform migration logic
if (oldVersion === '1.0.0' && this.manifest.version === '1.1.0') {
await this.migrateV1ToV1_1();
}

await sdk.storage.set('version', this.manifest.version);
}

onActivate()

Called when the plugin is activated.

async onActivate?(context: PluginContext): Promise<void>

onDeactivate()

Called when the plugin is deactivated.

async onDeactivate?(context: PluginContext): Promise<void>

validateConfig()

Validates plugin configuration.

async validateConfig?(config: Record<string, any>): Promise<ValidationResult>

Parameters:

  • config - Configuration object to validate

Returns: ValidationResult indicating validation success/failure.

Example:

async validateConfig(config: Record<string, any>): Promise<ValidationResult> {
const errors: string[] = [];

if (!config.apiKey) {
errors.push('API key is required');
}

if (!config.webhookUrl || !config.webhookUrl.startsWith('https://')) {
errors.push('Webhook URL must be a valid HTTPS URL');
}

return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : undefined
};
}

Action System Integration

BasePlugin automatically integrates with the Action System through decorators:

Event Handling

import { OnEvent, SystemEventType } from '@mulutime/plugin-sdk';

export class MyPlugin extends BasePlugin {
@OnEvent(SystemEventType.BOOKING_CREATED)
async handleBookingCreated(event: SystemEventPayload, context: PluginContext) {
const sdk = this.getSDK();
sdk.logger.info(`New booking: ${event.data.id}`);
}
}

Scheduled Actions

import { Scheduled, PluginScheduleType } from '@mulutime/plugin-sdk';

export class MyPlugin extends BasePlugin {
@Scheduled(PluginScheduleType.DAILY, { time: '09:00' })
async dailyReport(context: PluginContext) {
const sdk = this.getSDK();
// Generate and send daily report
}
}

API Endpoints

import { Get, Post } from '@mulutime/plugin-sdk';

export class MyPlugin extends BasePlugin {
@Get('/stats')
async getStats(request: APIRequest, context: PluginContext): Promise<APIResponse> {
const sdk = this.getSDK();
const stats = await sdk.storage.get('plugin-stats');

return {
status: 200,
data: stats
};
}

@Post('/webhook')
async handleWebhook(request: APIRequest, context: PluginContext): Promise<APIResponse> {
const sdk = this.getSDK();
// Process webhook data

return { status: 200 };
}
}

Configuration Schema

Define configuration schema for your plugin:

export class MyPlugin extends BasePlugin {
getConfigSchema(): JSONSchema7 {
return {
type: 'object',
properties: {
apiKey: {
type: 'string',
title: 'API Key',
description: 'Your service API key'
},
webhookUrl: {
type: 'string',
format: 'uri',
title: 'Webhook URL',
description: 'URL to receive webhook notifications'
},
enableLogging: {
type: 'boolean',
title: 'Enable Debug Logging',
default: false
}
},
required: ['apiKey']
};
}
}

Error Handling

BasePlugin provides built-in error handling:

export class MyPlugin extends BasePlugin {
@OnEvent(SystemEventType.BOOKING_CREATED)
async handleBookingCreated(event: SystemEventPayload, context: PluginContext) {
try {
const sdk = this.getSDK();
await this.processBooking(event.data);
} catch (error) {
// Error is automatically logged and handled
throw error; // Re-throw to trigger retry logic if configured
}
}
}

Best Practices

  1. Always call super() in constructor if you override it
  2. Use getSDK() to access platform capabilities
  3. Implement proper error handling in all methods
  4. Validate configuration in validateConfig() method
  5. Clean up resources in onUninstall() method
  6. Use decorators for action system integration
  7. Provide meaningful log messages for debugging