@mulutime/plugin-sdk
Version:
SDK for developing MuluTime booking platform plugins
274 lines (249 loc) • 10.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPlugin = exports.createManifest = exports.PluginTemplateGenerator = exports.PluginScheduleType = exports.SystemEventType = exports.PluginCategory = exports.IntegrationType = exports.PluginPermission = void 0;
exports.createEnhancedPlugin = createEnhancedPlugin;
// Re-export commonly used types for convenience
var plugin_types_1 = require("@mulutime/plugin-types");
Object.defineProperty(exports, "PluginPermission", { enumerable: true, get: function () { return plugin_types_1.PluginPermission; } });
Object.defineProperty(exports, "IntegrationType", { enumerable: true, get: function () { return plugin_types_1.IntegrationType; } });
Object.defineProperty(exports, "PluginCategory", { enumerable: true, get: function () { return plugin_types_1.PluginCategory; } });
Object.defineProperty(exports, "SystemEventType", { enumerable: true, get: function () { return plugin_types_1.SystemEventType; } });
Object.defineProperty(exports, "PluginScheduleType", { enumerable: true, get: function () { return plugin_types_1.PluginScheduleType; } });
class PluginTemplateGenerator {
static generateBasicTemplate(options) {
const { pluginId, name, description, author, category, integrationType, permissions } = options;
return {
name: 'Basic Plugin Template',
description: 'A basic plugin template with lifecycle hooks',
category,
files: {
'package.json': JSON.stringify({
name: pluginId,
version: '1.0.0',
description,
main: 'dist/index.js',
scripts: {
build: 'tsc',
dev: 'tsc --watch'
},
dependencies: {
'@mulutime/plugin-sdk': '^1.0.0'
},
devDependencies: {
'typescript': '^5.0.0',
'@types/node': '^20.0.0'
}
}, null, 2),
'tsconfig.json': JSON.stringify({
compilerOptions: {
target: 'ES2020',
module: 'commonjs',
lib: ['ES2020'],
outDir: './dist',
rootDir: './src',
strict: true,
esModuleInterop: true,
skipLibCheck: true,
forceConsistentCasingInFileNames: true,
declaration: true,
declarationMap: true,
sourceMap: true
},
include: ['src/**/*'],
exclude: ['node_modules', 'dist']
}, null, 2),
'src/manifest.ts': this.generateManifestTemplate(options),
'src/index.ts': this.generateIndexTemplate(options),
'src/actions/lifecycle.ts': this.generateLifecycleTemplate(),
'README.md': this.generateReadmeTemplate(options)
},
dependencies: ['@mulutime/plugin-sdk'],
devDependencies: ['typescript', '@types/node']
};
}
static generateManifestTemplate(options) {
return `import { PluginManifest, PluginCategory, IntegrationType, PluginPermission } from '@mulutime/plugin-sdk';
export const manifest: PluginManifest = {
id: '${options.pluginId}',
name: '${options.name}',
version: '1.0.0',
description: '${options.description}',
author: {
name: '${options.author.name}',
email: '${options.author.email}'
},
license: 'MIT',
provider: '${options.pluginId.split('.')[1] || 'provider'}',
type: [${options.integrationType.map((t) => `IntegrationType.${t}`).join(', ')}],
tags: ['${options.category.toLowerCase()}'],
category: PluginCategory.${options.category},
permissions: [${options.permissions.map((p) => `PluginPermission.${p}`).join(', ')}],
apiVersion: '1.0.0',
minSystemVersion: '1.0.0',
main: 'index.js'
};
`;
}
static generateIndexTemplate(options) {
return `import { BasePlugin, PluginContext } from '@mulutime/plugin-sdk';
import { manifest } from './manifest';
import { lifecycleActions } from './actions/lifecycle';
export class ${options.name.replace(/\s+/g, '')}Plugin extends BasePlugin {
manifest = manifest;
async onInstall(context: PluginContext): Promise<void> {
await lifecycleActions.onInstall?.(context);
}
async onUninstall(context: PluginContext): Promise<void> {
await lifecycleActions.onUninstall?.(context);
}
async onUpdate(context: PluginContext, oldVersion: string): Promise<void> {
await lifecycleActions.onUpdate?.(context, oldVersion);
}
}
// Export the plugin instance
export default new ${options.name.replace(/\s+/g, '')}Plugin();
`;
}
static generateLifecycleTemplate() {
return `import { PluginContext, LifecycleAction, ValidationResult } from '@mulutime/plugin-sdk';
export const lifecycleActions: LifecycleAction = {
async onInstall(context: PluginContext): Promise<void> {
context.logger.info('Plugin installed successfully');
// Initialize plugin data
await context.storage.set('install-date', new Date().toISOString());
await context.storage.set('version', '1.0.0');
// Perform any setup tasks here
},
async onUninstall(context: PluginContext): Promise<void> {
context.logger.info('Plugin uninstalled');
// Cleanup plugin data
const keys = await context.storage.list();
for (const key of keys) {
await context.storage.delete(key);
}
},
async onUpdate(context: PluginContext, oldVersion: string): Promise<void> {
context.logger.info(\`Plugin updated from \${oldVersion}\`);
// Perform migration logic here
await context.storage.set('version', '1.0.0');
await context.storage.set('last-update', new Date().toISOString());
},
async validateConfig(config: Record<string, any>): Promise<ValidationResult> {
const errors: string[] = [];
// Add your configuration validation logic here
// Example:
// if (!config.apiKey) {
// errors.push('API key is required');
// }
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : undefined
};
}
};
`;
}
static generateReadmeTemplate(options) {
return `# ${options.name}
${options.description}
## Installation
This plugin can be installed through the MuluTime Plugin Store.
## Configuration
Configure the plugin through the MuluTime admin panel.
## Development
\`\`\`bash
npm install
npm run build
\`\`\`
## License
MIT
`;
}
}
exports.PluginTemplateGenerator = PluginTemplateGenerator;
// =============================================================================
// PLUGIN CREATION HELPERS
// =============================================================================
const createManifest = (manifest) => {
// Basic validation
if (!manifest.id || !manifest.name || !manifest.version) {
throw new Error('Manifest must include id, name, and version');
}
if (!manifest.provider || manifest.provider.length === 0) {
throw new Error('Manifest must specify a unique provider name');
}
if (!manifest.type || manifest.type.length === 0) {
throw new Error('Manifest must specify at least one integration type');
}
return manifest;
};
exports.createManifest = createManifest;
const createPlugin = (plugin) => {
// Validate plugin structure
if (!plugin.manifest) {
throw new Error('Plugin must include a manifest');
}
// Validate manifest
(0, exports.createManifest)(plugin.manifest);
return plugin;
};
exports.createPlugin = createPlugin;
function createEnhancedPlugin(structure) {
// Validate the structure
const validatedManifest = (0, exports.createManifest)(structure.manifest);
// Create base plugin
const plugin = {
manifest: validatedManifest,
// Convert action structures to plugin methods
async onInstall(context) {
if (structure.lifecycleActions?.onInstall) {
await structure.lifecycleActions.onInstall(context);
}
},
async onUninstall(context) {
if (structure.lifecycleActions?.onUninstall) {
await structure.lifecycleActions.onUninstall(context);
}
},
async onUpdate(context, oldVersion) {
if (structure.lifecycleActions?.onUpdate) {
await structure.lifecycleActions.onUpdate(context, oldVersion);
}
},
async validateConfig(config) {
if (structure.lifecycleActions?.validateConfig) {
return await structure.lifecycleActions.validateConfig(config);
}
return { valid: true };
},
getEventSubscriptions() {
return structure.eventActions?.map(action => ({
eventTypes: [action.eventType],
actionMethod: action.handler.name,
filters: action.filters,
enabled: action.enabled,
priority: action.priority
})) || [];
}
};
// Add event handlers as methods
if (structure.eventActions) {
for (const action of structure.eventActions) {
plugin[action.handler.name] = action.handler;
}
}
// Add scheduled handlers as methods
if (structure.scheduledActions) {
for (const action of structure.scheduledActions) {
plugin[action.handler.name] = action.handler;
}
}
// Add API handlers as methods
if (structure.apiActions) {
for (const action of structure.apiActions) {
plugin[action.handler.name] = action.handler;
}
}
return plugin;
}
//# sourceMappingURL=helpers.js.map