@lark-apaas/nestjs-capability 0.0.1-alpha.0 → 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +23 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +24 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -134,7 +134,7 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
134
134
|
}
|
|
135
135
|
logger = new import_common2.Logger(_PluginLoaderService.name);
|
|
136
136
|
pluginInstances = /* @__PURE__ */ new Map();
|
|
137
|
-
loadPlugin(pluginID) {
|
|
137
|
+
async loadPlugin(pluginID) {
|
|
138
138
|
const cached = this.pluginInstances.get(pluginID);
|
|
139
139
|
if (cached) {
|
|
140
140
|
this.logger.debug(`Using cached plugin instance: ${pluginID}`);
|
|
@@ -142,7 +142,7 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
142
142
|
}
|
|
143
143
|
this.logger.log(`Loading plugin: ${pluginID}`);
|
|
144
144
|
try {
|
|
145
|
-
const pluginPackage =
|
|
145
|
+
const pluginPackage = (await import(pluginID)).default;
|
|
146
146
|
if (typeof pluginPackage.create !== "function") {
|
|
147
147
|
throw new PluginLoadError(pluginID, "Plugin does not export create() function");
|
|
148
148
|
}
|
|
@@ -287,7 +287,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
287
287
|
async execute(config, actionName, input, contextOverride) {
|
|
288
288
|
const startTime = Date.now();
|
|
289
289
|
try {
|
|
290
|
-
const pluginInstance = this.pluginLoaderService.loadPlugin(config.pluginID);
|
|
290
|
+
const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);
|
|
291
291
|
if (!pluginInstance.hasAction(actionName)) {
|
|
292
292
|
throw new ActionNotFoundError(config.pluginID, actionName);
|
|
293
293
|
}
|
|
@@ -511,6 +511,20 @@ var WebhookController = class {
|
|
|
511
511
|
constructor(capabilityService) {
|
|
512
512
|
this.capabilityService = capabilityService;
|
|
513
513
|
}
|
|
514
|
+
list() {
|
|
515
|
+
const capabilities = this.capabilityService.listCapabilities();
|
|
516
|
+
return {
|
|
517
|
+
code: 0,
|
|
518
|
+
message: "success",
|
|
519
|
+
data: capabilities.map((c) => ({
|
|
520
|
+
id: c.id,
|
|
521
|
+
name: c.name,
|
|
522
|
+
description: c.description,
|
|
523
|
+
pluginID: c.pluginID,
|
|
524
|
+
pluginVersion: c.pluginVersion
|
|
525
|
+
}))
|
|
526
|
+
};
|
|
527
|
+
}
|
|
514
528
|
async execute(capabilityId, body) {
|
|
515
529
|
try {
|
|
516
530
|
const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
|
|
@@ -549,6 +563,12 @@ var WebhookController = class {
|
|
|
549
563
|
}
|
|
550
564
|
}
|
|
551
565
|
};
|
|
566
|
+
_ts_decorate5([
|
|
567
|
+
(0, import_common5.Get)("list"),
|
|
568
|
+
_ts_metadata3("design:type", Function),
|
|
569
|
+
_ts_metadata3("design:paramtypes", []),
|
|
570
|
+
_ts_metadata3("design:returntype", typeof ListResponse === "undefined" ? Object : ListResponse)
|
|
571
|
+
], WebhookController.prototype, "list", null);
|
|
552
572
|
_ts_decorate5([
|
|
553
573
|
(0, import_common5.Post)(":capability_id"),
|
|
554
574
|
_ts_param3(0, (0, import_common5.Param)("capability_id")),
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["export * from './interfaces';\nexport * from './services';\nexport * from './controllers';\nexport * from './capability.module';\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class TemplateEngineService {\n private readonly TEMPLATE_REGEX = /^\\{\\{input\\.(.+)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n const match = template.match(this.TEMPLATE_REGEX);\n if (!match) {\n return template;\n }\n\n const path = match[1];\n return this.getValueByPath(input, path);\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginID: string) {\n super(`Plugin not found: ${pluginID}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginID: string, reason: string) {\n super(`Failed to load plugin ${pluginID}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n loadPlugin(pluginID: string): PluginInstance {\n const cached = this.pluginInstances.get(pluginID);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginID}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginID}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = require(pluginID) as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginID, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginID, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginID}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginID);\n }\n throw new PluginLoadError(\n pluginID,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginID: string): boolean {\n try {\n require.resolve(pluginID);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginID?: string): void {\n if (pluginID) {\n this.pluginInstances.delete(pluginID);\n this.logger.log(`Cleared cache for plugin: ${pluginID}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { CapabilityConfig, PluginActionContext, UserContext } from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginID: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginID}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.execute(config, actionName, input, contextOverride);\n },\n };\n }\n\n private async execute(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n });\n\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface DebugResponse {\n code: number;\n message: string;\n data: unknown;\n debug?: {\n capabilityConfig: unknown;\n resolvedParams: unknown;\n duration: number;\n pluginID: string;\n };\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: Array<{\n id: string;\n name: string;\n pluginID: string;\n pluginVersion: string;\n }>;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n body.params,\n );\n\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginID,\n },\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n debug: { duration },\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n debug: {\n duration,\n pluginID: config.pluginID,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import {\n Controller,\n Post,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface ExecuteResponse {\n code: number;\n message: string;\n data: unknown;\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<ExecuteResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":"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","names":["TemplateEngineService","TEMPLATE_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","match","path","getValueByPath","result","key","value","Object","entries","obj","keys","split","current","undefined","import_common","PluginNotFoundError","Error","pluginID","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","require","create","instance","set","error","code","message","String","isPluginInstalled","resolve","clearCache","delete","clear","import_common","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginID","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","call","input","contextOverride","execute","startTime","Date","now","pluginInstance","loadPlugin","hasAction","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","import_common","DebugController","capabilityService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","debug","capabilityId","body","startTime","Date","now","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","resolvedParams","resolve","formValue","params","result","load","call","action","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","import_common","WebhookController","capabilityService","execute","capabilityId","body","result","load","call","action","params","code","message","data","error","CapabilityNotFoundError","HttpException","HttpStatus","NOT_FOUND","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","import_common","import_nestjs_common","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["export * from './interfaces';\nexport * from './services';\nexport * from './controllers';\nexport * from './capability.module';\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class TemplateEngineService {\n private readonly TEMPLATE_REGEX = /^\\{\\{input\\.(.+)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n const match = template.match(this.TEMPLATE_REGEX);\n if (!match) {\n return template;\n }\n\n const path = match[1];\n return this.getValueByPath(input, path);\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginID: string) {\n super(`Plugin not found: ${pluginID}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginID: string, reason: string) {\n super(`Failed to load plugin ${pluginID}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n async loadPlugin(pluginID: string): Promise<PluginInstance> {\n const cached = this.pluginInstances.get(pluginID);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginID}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginID}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = (await import(pluginID)).default as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginID, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginID, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginID}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginID);\n }\n throw new PluginLoadError(\n pluginID,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginID: string): boolean {\n try {\n require.resolve(pluginID);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginID?: string): void {\n if (pluginID) {\n this.pluginInstances.delete(pluginID);\n this.logger.log(`Cleared cache for plugin: ${pluginID}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { CapabilityConfig, PluginActionContext, UserContext } from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginID: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginID}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.execute(config, actionName, input, contextOverride);\n },\n };\n }\n\n private async execute(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n });\n\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface DebugResponse {\n code: number;\n message: string;\n data: unknown;\n debug?: {\n capabilityConfig: unknown;\n resolvedParams: unknown;\n duration: number;\n pluginID: string;\n };\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: Array<{\n id: string;\n name: string;\n pluginID: string;\n pluginVersion: string;\n }>;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n body.params,\n );\n\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginID,\n },\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n debug: { duration },\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n debug: {\n duration,\n pluginID: config.pluginID,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import {\n Controller,\n Get,\n Post,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface ExecuteResponse {\n code: number;\n message: string;\n data: unknown;\n}\n\ninterface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n pluginID: string;\n pluginVersion: string;\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: CapabilityInfo[];\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n description: c.description,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<ExecuteResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":"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","names":["TemplateEngineService","TEMPLATE_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","match","path","getValueByPath","result","key","value","Object","entries","obj","keys","split","current","undefined","import_common","PluginNotFoundError","Error","pluginID","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","default","create","instance","set","error","code","message","String","isPluginInstalled","require","resolve","clearCache","delete","clear","import_common","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginID","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","call","input","contextOverride","execute","startTime","Date","now","pluginInstance","loadPlugin","hasAction","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","import_common","DebugController","capabilityService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","debug","capabilityId","body","startTime","Date","now","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","resolvedParams","resolve","formValue","params","result","load","call","action","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","import_common","WebhookController","capabilityService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","description","pluginID","pluginVersion","execute","capabilityId","body","result","load","call","action","params","error","CapabilityNotFoundError","HttpException","HttpStatus","NOT_FOUND","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","import_common","import_nestjs_common","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -64,7 +64,7 @@ declare class PluginLoadError extends Error {
|
|
|
64
64
|
declare class PluginLoaderService {
|
|
65
65
|
private readonly logger;
|
|
66
66
|
private readonly pluginInstances;
|
|
67
|
-
loadPlugin(pluginID: string): PluginInstance
|
|
67
|
+
loadPlugin(pluginID: string): Promise<PluginInstance>;
|
|
68
68
|
isPluginInstalled(pluginID: string): boolean;
|
|
69
69
|
clearCache(pluginID?: string): void;
|
|
70
70
|
}
|
|
@@ -116,7 +116,7 @@ interface DebugResponse {
|
|
|
116
116
|
pluginID: string;
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
interface ListResponse {
|
|
119
|
+
interface ListResponse$1 {
|
|
120
120
|
code: number;
|
|
121
121
|
message: string;
|
|
122
122
|
data: Array<{
|
|
@@ -130,7 +130,7 @@ declare class DebugController {
|
|
|
130
130
|
private readonly capabilityService;
|
|
131
131
|
private readonly templateEngineService;
|
|
132
132
|
constructor(capabilityService: CapabilityService, templateEngineService: TemplateEngineService);
|
|
133
|
-
list(): ListResponse;
|
|
133
|
+
list(): ListResponse$1;
|
|
134
134
|
debug(capabilityId: string, body: ExecuteRequestBody$1): Promise<DebugResponse>;
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -143,9 +143,22 @@ interface ExecuteResponse {
|
|
|
143
143
|
message: string;
|
|
144
144
|
data: unknown;
|
|
145
145
|
}
|
|
146
|
+
interface CapabilityInfo {
|
|
147
|
+
id: string;
|
|
148
|
+
name: string;
|
|
149
|
+
description: string;
|
|
150
|
+
pluginID: string;
|
|
151
|
+
pluginVersion: string;
|
|
152
|
+
}
|
|
153
|
+
interface ListResponse {
|
|
154
|
+
code: number;
|
|
155
|
+
message: string;
|
|
156
|
+
data: CapabilityInfo[];
|
|
157
|
+
}
|
|
146
158
|
declare class WebhookController {
|
|
147
159
|
private readonly capabilityService;
|
|
148
160
|
constructor(capabilityService: CapabilityService);
|
|
161
|
+
list(): ListResponse;
|
|
149
162
|
execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
|
|
150
163
|
}
|
|
151
164
|
|
package/dist/index.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ declare class PluginLoadError extends Error {
|
|
|
64
64
|
declare class PluginLoaderService {
|
|
65
65
|
private readonly logger;
|
|
66
66
|
private readonly pluginInstances;
|
|
67
|
-
loadPlugin(pluginID: string): PluginInstance
|
|
67
|
+
loadPlugin(pluginID: string): Promise<PluginInstance>;
|
|
68
68
|
isPluginInstalled(pluginID: string): boolean;
|
|
69
69
|
clearCache(pluginID?: string): void;
|
|
70
70
|
}
|
|
@@ -116,7 +116,7 @@ interface DebugResponse {
|
|
|
116
116
|
pluginID: string;
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
interface ListResponse {
|
|
119
|
+
interface ListResponse$1 {
|
|
120
120
|
code: number;
|
|
121
121
|
message: string;
|
|
122
122
|
data: Array<{
|
|
@@ -130,7 +130,7 @@ declare class DebugController {
|
|
|
130
130
|
private readonly capabilityService;
|
|
131
131
|
private readonly templateEngineService;
|
|
132
132
|
constructor(capabilityService: CapabilityService, templateEngineService: TemplateEngineService);
|
|
133
|
-
list(): ListResponse;
|
|
133
|
+
list(): ListResponse$1;
|
|
134
134
|
debug(capabilityId: string, body: ExecuteRequestBody$1): Promise<DebugResponse>;
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -143,9 +143,22 @@ interface ExecuteResponse {
|
|
|
143
143
|
message: string;
|
|
144
144
|
data: unknown;
|
|
145
145
|
}
|
|
146
|
+
interface CapabilityInfo {
|
|
147
|
+
id: string;
|
|
148
|
+
name: string;
|
|
149
|
+
description: string;
|
|
150
|
+
pluginID: string;
|
|
151
|
+
pluginVersion: string;
|
|
152
|
+
}
|
|
153
|
+
interface ListResponse {
|
|
154
|
+
code: number;
|
|
155
|
+
message: string;
|
|
156
|
+
data: CapabilityInfo[];
|
|
157
|
+
}
|
|
146
158
|
declare class WebhookController {
|
|
147
159
|
private readonly capabilityService;
|
|
148
160
|
constructor(capabilityService: CapabilityService);
|
|
161
|
+
list(): ListResponse;
|
|
149
162
|
execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
|
|
150
163
|
}
|
|
151
164
|
|
package/dist/index.js
CHANGED
|
@@ -97,7 +97,7 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
97
97
|
}
|
|
98
98
|
logger = new Logger(_PluginLoaderService.name);
|
|
99
99
|
pluginInstances = /* @__PURE__ */ new Map();
|
|
100
|
-
loadPlugin(pluginID) {
|
|
100
|
+
async loadPlugin(pluginID) {
|
|
101
101
|
const cached = this.pluginInstances.get(pluginID);
|
|
102
102
|
if (cached) {
|
|
103
103
|
this.logger.debug(`Using cached plugin instance: ${pluginID}`);
|
|
@@ -105,7 +105,7 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
105
105
|
}
|
|
106
106
|
this.logger.log(`Loading plugin: ${pluginID}`);
|
|
107
107
|
try {
|
|
108
|
-
const pluginPackage =
|
|
108
|
+
const pluginPackage = (await import(pluginID)).default;
|
|
109
109
|
if (typeof pluginPackage.create !== "function") {
|
|
110
110
|
throw new PluginLoadError(pluginID, "Plugin does not export create() function");
|
|
111
111
|
}
|
|
@@ -250,7 +250,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
250
250
|
async execute(config, actionName, input, contextOverride) {
|
|
251
251
|
const startTime = Date.now();
|
|
252
252
|
try {
|
|
253
|
-
const pluginInstance = this.pluginLoaderService.loadPlugin(config.pluginID);
|
|
253
|
+
const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);
|
|
254
254
|
if (!pluginInstance.hasAction(actionName)) {
|
|
255
255
|
throw new ActionNotFoundError(config.pluginID, actionName);
|
|
256
256
|
}
|
|
@@ -448,7 +448,7 @@ DebugController = _ts_decorate4([
|
|
|
448
448
|
], DebugController);
|
|
449
449
|
|
|
450
450
|
// src/controllers/webhook.controller.ts
|
|
451
|
-
import { Controller as Controller2, Post as Post2, Param as Param2, Body as Body2, HttpException as HttpException2, HttpStatus as HttpStatus2 } from "@nestjs/common";
|
|
451
|
+
import { Controller as Controller2, Get as Get2, Post as Post2, Param as Param2, Body as Body2, HttpException as HttpException2, HttpStatus as HttpStatus2 } from "@nestjs/common";
|
|
452
452
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
453
453
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
454
454
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -474,6 +474,20 @@ var WebhookController = class {
|
|
|
474
474
|
constructor(capabilityService) {
|
|
475
475
|
this.capabilityService = capabilityService;
|
|
476
476
|
}
|
|
477
|
+
list() {
|
|
478
|
+
const capabilities = this.capabilityService.listCapabilities();
|
|
479
|
+
return {
|
|
480
|
+
code: 0,
|
|
481
|
+
message: "success",
|
|
482
|
+
data: capabilities.map((c) => ({
|
|
483
|
+
id: c.id,
|
|
484
|
+
name: c.name,
|
|
485
|
+
description: c.description,
|
|
486
|
+
pluginID: c.pluginID,
|
|
487
|
+
pluginVersion: c.pluginVersion
|
|
488
|
+
}))
|
|
489
|
+
};
|
|
490
|
+
}
|
|
477
491
|
async execute(capabilityId, body) {
|
|
478
492
|
try {
|
|
479
493
|
const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
|
|
@@ -512,6 +526,12 @@ var WebhookController = class {
|
|
|
512
526
|
}
|
|
513
527
|
}
|
|
514
528
|
};
|
|
529
|
+
_ts_decorate5([
|
|
530
|
+
Get2("list"),
|
|
531
|
+
_ts_metadata3("design:type", Function),
|
|
532
|
+
_ts_metadata3("design:paramtypes", []),
|
|
533
|
+
_ts_metadata3("design:returntype", typeof ListResponse === "undefined" ? Object : ListResponse)
|
|
534
|
+
], WebhookController.prototype, "list", null);
|
|
515
535
|
_ts_decorate5([
|
|
516
536
|
Post2(":capability_id"),
|
|
517
537
|
_ts_param3(0, Param2("capability_id")),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class TemplateEngineService {\n private readonly TEMPLATE_REGEX = /^\\{\\{input\\.(.+)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n const match = template.match(this.TEMPLATE_REGEX);\n if (!match) {\n return template;\n }\n\n const path = match[1];\n return this.getValueByPath(input, path);\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginID: string) {\n super(`Plugin not found: ${pluginID}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginID: string, reason: string) {\n super(`Failed to load plugin ${pluginID}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n loadPlugin(pluginID: string): PluginInstance {\n const cached = this.pluginInstances.get(pluginID);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginID}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginID}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = require(pluginID) as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginID, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginID, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginID}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginID);\n }\n throw new PluginLoadError(\n pluginID,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginID: string): boolean {\n try {\n require.resolve(pluginID);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginID?: string): void {\n if (pluginID) {\n this.pluginInstances.delete(pluginID);\n this.logger.log(`Cleared cache for plugin: ${pluginID}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { CapabilityConfig, PluginActionContext, UserContext } from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginID: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginID}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.execute(config, actionName, input, contextOverride);\n },\n };\n }\n\n private async execute(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n });\n\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface DebugResponse {\n code: number;\n message: string;\n data: unknown;\n debug?: {\n capabilityConfig: unknown;\n resolvedParams: unknown;\n duration: number;\n pluginID: string;\n };\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: Array<{\n id: string;\n name: string;\n pluginID: string;\n pluginVersion: string;\n }>;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n body.params,\n );\n\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginID,\n },\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n debug: { duration },\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n debug: {\n duration,\n pluginID: config.pluginID,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import {\n Controller,\n Post,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface ExecuteResponse {\n code: number;\n message: string;\n data: unknown;\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<ExecuteResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAASA,kBAAkB;;;;;;;;AAGpB,IAAMC,wBAAN,MAAMA;SAAAA;;;EACMC,iBAAiB;EAElCC,QAAQC,UAAmBC,OAAyC;AAClE,QAAI,OAAOD,aAAa,UAAU;AAChC,aAAO,KAAKE,cAAcF,UAAUC,KAAAA;IACtC;AAEA,QAAIE,MAAMC,QAAQJ,QAAAA,GAAW;AAC3B,aAAOA,SAASK,IAAIC,CAAAA,SAAQ,KAAKP,QAAQO,MAAML,KAAAA,CAAAA;IACjD;AAEA,QAAID,aAAa,QAAQ,OAAOA,aAAa,UAAU;AACrD,aAAO,KAAKO,cAAcP,UAAqCC,KAAAA;IACjE;AAEA,WAAOD;EACT;EAEQE,cAAcF,UAAkBC,OAAyC;AAC/E,UAAMO,QAAQR,SAASQ,MAAM,KAAKV,cAAc;AAChD,QAAI,CAACU,OAAO;AACV,aAAOR;IACT;AAEA,UAAMS,QAAOD,MAAM,CAAA;AACnB,WAAO,KAAKE,eAAeT,OAAOQ,KAAAA;EACpC;EAEQF,cACNP,UACAC,OACyB;AACzB,UAAMU,SAAkC,CAAC;AAEzC,eAAW,CAACC,KAAKC,KAAAA,KAAUC,OAAOC,QAAQf,QAAAA,GAAW;AACnDW,aAAOC,GAAAA,IAAO,KAAKb,QAAQc,OAAOZ,KAAAA;IACpC;AAEA,WAAOU;EACT;EAEQD,eAAeM,KAA8BP,OAAuB;AAC1E,UAAMQ,OAAOR,MAAKS,MAAM,GAAA;AACxB,QAAIC,UAAmBH;AAEvB,eAAWJ,OAAOK,MAAM;AACtB,UAAIE,YAAY,QAAQA,YAAYC,QAAW;AAC7C,eAAOA;MACT;AACAD,gBAAWA,QAAoCP,GAAAA;IACjD;AAEA,WAAOO;EACT;AACF;;;;;;AC1DA,SAASE,cAAAA,aAAYC,cAAc;;;;;;;;AAG5B,IAAMC,sBAAN,cAAkCC,MAAAA;SAAAA;;;EACvC,YAAYC,UAAkB;AAC5B,UAAM,qBAAqBA,QAAAA,EAAU;AACrC,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,kBAAN,cAA8BH,MAAAA;SAAAA;;;EACnC,YAAYC,UAAkBG,QAAgB;AAC5C,UAAM,yBAAyBH,QAAAA,KAAaG,MAAAA,EAAQ;AACpD,SAAKF,OAAO;EACd;AACF;AAGO,IAAMG,sBAAN,MAAMA,qBAAAA;SAAAA;;;EACMC,SAAS,IAAIC,OAAOF,qBAAoBH,IAAI;EAC5CM,kBAAkB,oBAAIC,IAAAA;EAEvCC,WAAWT,UAAkC;AAC3C,UAAMU,SAAS,KAAKH,gBAAgBI,IAAIX,QAAAA;AACxC,QAAIU,QAAQ;AACV,WAAKL,OAAOO,MAAM,iCAAiCZ,QAAAA,EAAU;AAC7D,aAAOU;IACT;AAEA,SAAKL,OAAOQ,IAAI,mBAAmBb,QAAAA,EAAU;AAE7C,QAAI;AAEF,YAAMc,gBAAgBC,UAAQf,QAAAA;AAE9B,UAAI,OAAOc,cAAcE,WAAW,YAAY;AAC9C,cAAM,IAAId,gBAAgBF,UAAU,0CAAA;MACtC;AAEA,YAAMiB,WAAWH,cAAcE,OAAM;AACrC,WAAKT,gBAAgBW,IAAIlB,UAAUiB,QAAAA;AAEnC,WAAKZ,OAAOQ,IAAI,+BAA+Bb,QAAAA,EAAU;AACzD,aAAOiB;IACT,SAASE,OAAO;AACd,UAAKA,MAAgCC,SAAS,oBAAoB;AAChE,cAAM,IAAItB,oBAAoBE,QAAAA;MAChC;AACA,YAAM,IAAIE,gBACRF,UACAmB,iBAAiBpB,QAAQoB,MAAME,UAAUC,OAAOH,KAAAA,CAAAA;IAEpD;EACF;EAEAI,kBAAkBvB,UAA2B;AAC3C,QAAI;AACFe,gBAAQS,QAAQxB,QAAAA;AAChB,aAAO;IACT,QAAQ;AACN,aAAO;IACT;EACF;EAEAyB,WAAWzB,UAAyB;AAClC,QAAIA,UAAU;AACZ,WAAKO,gBAAgBmB,OAAO1B,QAAAA;AAC5B,WAAKK,OAAOQ,IAAI,6BAA6Bb,QAAAA,EAAU;IACzD,OAAO;AACL,WAAKO,gBAAgBoB,MAAK;AAC1B,WAAKtB,OAAOQ,IAAI,2BAAA;IAClB;EACF;AACF;;;;;;ACzEA,SAASe,cAAAA,aAAYC,UAAAA,SAAQC,cAA4B;AACzD,SACEC,uBACAC,4BAEK;AACP,YAAYC,QAAQ;AACpB,YAAYC,UAAU;;;;;;;;;;;;;;;;;;AAKf,IAAMC,0BAAN,cAAsCC,MAAAA;SAAAA;;;EAC3C,YAAYC,cAAsB;AAChC,UAAM,yBAAyBA,YAAAA,EAAc;AAC7C,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,sBAAN,cAAkCH,MAAAA;SAAAA;;;EACvC,YAAYI,UAAkBC,YAAoB;AAChD,UAAM,WAAWA,UAAAA,yBAAmCD,QAAAA,EAAU;AAC9D,SAAKF,OAAO;EACd;AACF;AAWO,IAAMI,oBAAN,MAAMA,mBAAAA;SAAAA;;;;;;;EACMC,SAAS,IAAIC,QAAOF,mBAAkBJ,IAAI;EAC1CO,eAAe,oBAAIC,IAAAA;EAC5BC;EAER,YACmBC,uBAC8BC,YAC9BC,qBACAC,uBACjB;SAJiBH,wBAAAA;SAC8BC,aAAAA;SAC9BC,sBAAAA;SACAC,wBAAAA;AAEjB,SAAKJ,kBAAuBK,UAAKC,QAAQC,IAAG,GAAI,qBAAA;EAClD;EAEAC,mBAAmBC,KAAmB;AACpC,SAAKT,kBAAkBS;EACzB;EAEA,MAAMC,eAA8B;AAClC,UAAM,KAAKC,iBAAgB;EAC7B;EAEA,MAAcA,mBAAkC;AAC9C,SAAKf,OAAOgB,IAAI,6BAA6B,KAAKZ,eAAe,EAAE;AAEnE,QAAI,CAAIa,cAAW,KAAKb,eAAe,GAAG;AACxC,WAAKJ,OAAOkB,KAAK,qCAAqC,KAAKd,eAAe,EAAE;AAC5E;IACF;AAEA,UAAMe,QAAWC,eAAY,KAAKhB,eAAe,EAAEiB,OAAOC,CAAAA,MAAKA,EAAEC,SAAS,OAAA,CAAA;AAE1E,eAAWC,QAAQL,OAAO;AACxB,UAAI;AACF,cAAMM,WAAgBhB,UAAK,KAAKL,iBAAiBoB,IAAAA;AACjD,cAAME,UAAaC,gBAAaF,UAAU,OAAA;AAC1C,cAAMG,SAASC,KAAKC,MAAMJ,OAAAA;AAE1B,YAAI,CAACE,OAAOG,IAAI;AACd,eAAK/B,OAAOkB,KAAK,mCAAmCM,IAAAA,EAAM;AAC1D;QACF;AAEA,aAAKtB,aAAa8B,IAAIJ,OAAOG,IAAIH,MAAAA;AACjC,aAAK5B,OAAOgB,IAAI,sBAAsBY,OAAOG,EAAE,KAAKH,OAAOjC,IAAI,GAAG;MACpE,SAASsC,OAAO;AACd,aAAKjC,OAAOiC,MAAM,kCAAkCT,IAAAA,KAASS,KAAAA;MAC/D;IACF;AAEA,SAAKjC,OAAOgB,IAAI,UAAU,KAAKd,aAAagC,IAAI,eAAe;EACjE;EAEAC,mBAAuC;AACrC,WAAOC,MAAMC,KAAK,KAAKnC,aAAaoC,OAAM,CAAA;EAC5C;EAEAC,cAAc7C,cAA+C;AAC3D,WAAO,KAAKQ,aAAasC,IAAI9C,YAAAA,KAAiB;EAChD;EAEA+C,KAAK/C,cAA0C;AAC7C,UAAMkC,SAAS,KAAK1B,aAAasC,IAAI9C,YAAAA;AACrC,QAAI,CAACkC,QAAQ;AACX,YAAM,IAAIpC,wBAAwBE,YAAAA;IACpC;AAEA,WAAO;MACLgD,MAAM,8BACJ5C,YACA6C,OACAC,oBAAAA;AAEA,eAAO,KAAKC,QAAQjB,QAAQ9B,YAAY6C,OAAOC,eAAAA;MACjD,GANM;IAOR;EACF;EAEA,MAAcC,QACZjB,QACA9B,YACA6C,OACAC,iBACkB;AAClB,UAAME,YAAYC,KAAKC,IAAG;AAE1B,QAAI;AACF,YAAMC,iBAAiB,KAAK1C,oBAAoB2C,WAAWtB,OAAO/B,QAAQ;AAE1E,UAAI,CAACoD,eAAeE,UAAUrD,UAAAA,GAAa;AACzC,cAAM,IAAIF,oBAAoBgC,OAAO/B,UAAUC,UAAAA;MACjD;AAEA,YAAMsD,iBAAiB,KAAK5C,sBAAsB6C,QAChDzB,OAAO0B,WACPX,KAAAA;AAGF,YAAMY,UAAU,KAAKC,mBAAmBZ,eAAAA;AAExC,WAAK5C,OAAOgB,IAAI;QACdyC,SAAS;QACT/D,cAAckC,OAAOG;QACrB2B,QAAQ5D;QACRD,UAAU+B,OAAO/B;MACnB,CAAA;AAEA,YAAM8D,SAAS,MAAMV,eAAeW,IAAI9D,YAAYyD,SAASH,cAAAA;AAE7D,WAAKpD,OAAOgB,IAAI;QACdyC,SAAS;QACT/D,cAAckC,OAAOG;QACrB2B,QAAQ5D;QACR+D,UAAUd,KAAKC,IAAG,IAAKF;MACzB,CAAA;AAEA,aAAOa;IACT,SAAS1B,OAAO;AACd,WAAKjC,OAAOiC,MAAM;QAChBwB,SAAS;QACT/D,cAAckC,OAAOG;QACrB2B,QAAQ5D;QACRmC,OAAOA,iBAAiBxC,QAAQwC,MAAMwB,UAAUK,OAAO7B,KAAAA;QACvD4B,UAAUd,KAAKC,IAAG,IAAKF;MACzB,CAAA;AACA,YAAMb;IACR;EACF;EAEQuB,mBAAmBO,UAA8D;AACvF,WAAO;MACL/D,QAAQ,KAAKA;MACbM,YAAY,KAAKA;MACjB0D,aAAaD,UAAUC,eAAe,KAAKC,eAAc;IAC3D;EACF;EAEQA,iBAA8B;AACpC,UAAMC,MAAM,KAAK7D,sBAAsB8D,WAAU;AACjD,WAAO;MACLC,QAAQF,KAAKE,UAAU;MACvBC,UAAUH,KAAKG,YAAY;IAC7B;EACF;AACF;;;;;;;;;;;;;;ACnLA,SACEC,YACAC,MACAC,KACAC,OACAC,MACAC,eACAC,kBACK;;;;;;;;;;;;;;;;;;AAsCA,IAAMC,kBAAN,MAAMA;SAAAA;;;;;EACX,YACmBC,mBACAC,uBACjB;SAFiBD,oBAAAA;SACAC,wBAAAA;EAChB;EAGHC,OAAqB;AACnB,UAAMC,eAAe,KAAKH,kBAAkBI,iBAAgB;AAE5D,WAAO;MACLC,MAAM;MACNC,SAAS;MACTC,MAAMJ,aAAaK,IAAIC,CAAAA,OAAM;QAC3BC,IAAID,EAAEC;QACNC,MAAMF,EAAEE;QACRC,UAAUH,EAAEG;QACZC,eAAeJ,EAAEI;MACnB,EAAA;IACF;EACF;EAEA,MACMC,MACoBC,cAChBC,MACgB;AACxB,UAAMC,YAAYC,KAAKC,IAAG;AAE1B,UAAMC,SAAS,KAAKpB,kBAAkBqB,cAAcN,YAAAA;AACpD,QAAI,CAACK,QAAQ;AACX,YAAM,IAAIE,cACR;QACEjB,MAAM;QACNC,SAAS,yBAAyBS,YAAAA;QAClCQ,OAAO;MACT,GACAC,WAAWC,SAAS;IAExB;AAEA,UAAMC,iBAAiB,KAAKzB,sBAAsB0B,QAChDP,OAAOQ,WACPZ,KAAKa,MAAM;AAGb,QAAI;AACF,YAAMC,SAAS,MAAM,KAAK9B,kBACvB+B,KAAKhB,YAAAA,EACLiB,KAAKhB,KAAKiB,QAAQjB,KAAKa,MAAM;AAEhC,aAAO;QACLxB,MAAM;QACNC,SAAS;QACTC,MAAMuB;QACNhB,OAAO;UACLoB,kBAAkBd;UAClBM;UACAS,UAAUjB,KAAKC,IAAG,IAAKF;UACvBL,UAAUQ,OAAOR;QACnB;MACF;IACF,SAASW,OAAO;AACd,YAAMY,WAAWjB,KAAKC,IAAG,IAAKF;AAE9B,UAAIM,iBAAiBa,yBAAyB;AAC5C,cAAM,IAAId,cACR;UACEjB,MAAM;UACNC,SAASiB,MAAMjB;UACfiB,OAAO;UACPT,OAAO;YAAEqB;UAAS;QACpB,GACAX,WAAWC,SAAS;MAExB;AAEA,UAAIF,iBAAiBc,qBAAqB;AACxC,cAAM,IAAIf,cACR;UACEjB,MAAM;UACNC,SAASiB,MAAMjB;UACfiB,OAAO;UACPT,OAAO;YAAEqB;YAAUvB,UAAUQ,OAAOR;UAAS;QAC/C,GACAY,WAAWc,qBAAqB;MAEpC;AAEA,UAAIf,iBAAiBgB,qBAAqB;AACxC,cAAM,IAAIjB,cACR;UACEjB,MAAM;UACNC,SAASiB,MAAMjB;UACfiB,OAAO;UACPT,OAAO;YAAEqB;YAAUvB,UAAUQ,OAAOR;UAAS;QAC/C,GACAY,WAAWgB,WAAW;MAE1B;AAEA,YAAM,IAAIlB,cACR;QACEjB,MAAM;QACNC,SAASiB,iBAAiBkB,QAAQlB,MAAMjB,UAAUoC,OAAOnB,KAAAA;QACzDA,OAAO;QACPT,OAAO;UACLqB;UACAvB,UAAUQ,OAAOR;UACjBc;QACF;MACF,GACAF,WAAWc,qBAAqB;IAEpC;EACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClKA,SACEK,cAAAA,aACAC,QAAAA,OACAC,SAAAA,QACAC,QAAAA,OACAC,iBAAAA,gBACAC,cAAAA,mBACK;;;;;;;;;;;;;;;;;;AAoBA,IAAMC,oBAAN,MAAMA;SAAAA;;;;EACX,YAA6BC,mBAAsC;SAAtCA,oBAAAA;EAAuC;EAEpE,MACMC,QACoBC,cAChBC,MACkB;AAC1B,QAAI;AACF,YAAMC,SAAS,MAAM,KAAKJ,kBACvBK,KAAKH,YAAAA,EACLI,KAAKH,KAAKI,QAAQJ,KAAKK,MAAM;AAEhC,aAAO;QACLC,MAAM;QACNC,SAAS;QACTC,MAAMP;MACR;IACF,SAASQ,OAAO;AACd,UAAIA,iBAAiBC,yBAAyB;AAC5C,cAAM,IAAIC,eACR;UACEL,MAAM;UACNC,SAASE,MAAMF;UACfE,OAAO;QACT,GACAG,YAAWC,SAAS;MAExB;AAEA,UAAIJ,iBAAiBK,qBAAqB;AACxC,cAAM,IAAIH,eACR;UACEL,MAAM;UACNC,SAASE,MAAMF;UACfE,OAAO;QACT,GACAG,YAAWG,qBAAqB;MAEpC;AAEA,UAAIN,iBAAiBO,qBAAqB;AACxC,cAAM,IAAIL,eACR;UACEL,MAAM;UACNC,SAASE,MAAMF;UACfE,OAAO;QACT,GACAG,YAAWK,WAAW;MAE1B;AAEA,YAAM,IAAIN,eACR;QACEL,MAAM;QACNC,SAASE,iBAAiBS,QAAQT,MAAMF,UAAUY,OAAOV,KAAAA;QACzDA,OAAO;MACT,GACAG,YAAWG,qBAAqB;IAEpC;EACF;AACF;;;;;;;;;;;;;;;;;;;;;ACzFA,SAASK,cAAmC;AAC5C,SACEC,yBAAAA,wBACAC,wBAAAA,6BACK;;;;;;;;AASP,IAAMC,qBAAqBC,uBAAO,oBAAA;AAElC,IAAMC,gBAAgBC,QAAQC,IAAIC,aAAa;AAE/C,SAASC,iBAAAA;AACP,QAAMC,cAAsB;IAACC;;AAC7B,MAAIN,eAAe;AACjBK,gBAAYE,KAAKC,eAAAA;EACnB;AACA,SAAOH;AACT;AANSD;AAaF,IAAMK,mBAAN,MAAMA,kBAAAA;SAAAA;;;EACX,OAAOC,QAAQC,SAAkD;AAC/D,WAAO;MACLC,QAAQH;MACRJ,aAAaD,eAAAA;MACbS,WAAW;QACT;UACEC,SAAShB;UACTiB,UAAUJ,WAAW,CAAC;QACxB;QACA;UACEG,SAASE;UACTC,YAAY,wBACVC,uBACAC,YACAC,cACAC,gBACAC,kBAAAA;AAEA,kBAAMC,UAAU,IAAIP,kBAClBE,uBACAC,YACAC,cACAC,cAAAA;AAEF,gBAAIC,eAAeE,iBAAiB;AAClCD,sBAAQE,mBAAmBH,cAAcE,eAAe;YAC1D;AACA,mBAAOD;UACT,GAjBY;UAkBZG,QAAQ;YACNC;YACAC;YACAC;YACAC;YACAhC;;QAEJ;QACA+B;QACAC;;MAEFC,SAAS;QAACf;;IACZ;EACF;AACF;;;IAhDEX,aAAaD,eAAAA;IACbS,WAAW;MAACG;MAAmBa;MAAqBC;;IACpDC,SAAS;MAACf;;;;","names":["Injectable","TemplateEngineService","TEMPLATE_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","match","path","getValueByPath","result","key","value","Object","entries","obj","keys","split","current","undefined","Injectable","Logger","PluginNotFoundError","Error","pluginID","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","require","create","instance","set","error","code","message","String","isPluginInstalled","resolve","clearCache","delete","clear","Injectable","Logger","Inject","RequestContextService","PLATFORM_HTTP_CLIENT","fs","path","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginID","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","call","input","contextOverride","execute","startTime","Date","now","pluginInstance","loadPlugin","hasAction","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","Controller","Post","Get","Param","Body","HttpException","HttpStatus","DebugController","capabilityService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","debug","capabilityId","body","startTime","Date","now","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","resolvedParams","resolve","formValue","params","result","load","call","action","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","Controller","Post","Param","Body","HttpException","HttpStatus","WebhookController","capabilityService","execute","capabilityId","body","result","load","call","action","params","code","message","data","error","CapabilityNotFoundError","HttpException","HttpStatus","NOT_FOUND","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","Module","RequestContextService","PLATFORM_HTTP_CLIENT","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
|
|
1
|
+
{"version":3,"sources":["../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class TemplateEngineService {\n private readonly TEMPLATE_REGEX = /^\\{\\{input\\.(.+)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n const match = template.match(this.TEMPLATE_REGEX);\n if (!match) {\n return template;\n }\n\n const path = match[1];\n return this.getValueByPath(input, path);\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginID: string) {\n super(`Plugin not found: ${pluginID}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginID: string, reason: string) {\n super(`Failed to load plugin ${pluginID}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n async loadPlugin(pluginID: string): Promise<PluginInstance> {\n const cached = this.pluginInstances.get(pluginID);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginID}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginID}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = (await import(pluginID)).default as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginID, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginID, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginID}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginID);\n }\n throw new PluginLoadError(\n pluginID,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginID: string): boolean {\n try {\n require.resolve(pluginID);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginID?: string): void {\n if (pluginID) {\n this.pluginInstances.delete(pluginID);\n this.logger.log(`Cleared cache for plugin: ${pluginID}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { CapabilityConfig, PluginActionContext, UserContext } from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginID: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginID}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.execute(config, actionName, input, contextOverride);\n },\n };\n }\n\n private async execute(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n });\n\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface DebugResponse {\n code: number;\n message: string;\n data: unknown;\n debug?: {\n capabilityConfig: unknown;\n resolvedParams: unknown;\n duration: number;\n pluginID: string;\n };\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: Array<{\n id: string;\n name: string;\n pluginID: string;\n pluginVersion: string;\n }>;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n body.params,\n );\n\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginID,\n },\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n debug: { duration },\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID },\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n debug: {\n duration,\n pluginID: config.pluginID,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import {\n Controller,\n Get,\n Post,\n Param,\n Body,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface ExecuteResponse {\n code: number;\n message: string;\n data: unknown;\n}\n\ninterface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n pluginID: string;\n pluginVersion: string;\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: CapabilityInfo[];\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n description: c.description,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<ExecuteResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":"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","names":["Injectable","TemplateEngineService","TEMPLATE_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","match","path","getValueByPath","result","key","value","Object","entries","obj","keys","split","current","undefined","Injectable","Logger","PluginNotFoundError","Error","pluginID","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","default","create","instance","set","error","code","message","String","isPluginInstalled","require","resolve","clearCache","delete","clear","Injectable","Logger","Inject","RequestContextService","PLATFORM_HTTP_CLIENT","fs","path","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginID","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","call","input","contextOverride","execute","startTime","Date","now","pluginInstance","loadPlugin","hasAction","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","Controller","Post","Get","Param","Body","HttpException","HttpStatus","DebugController","capabilityService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","debug","capabilityId","body","startTime","Date","now","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","resolvedParams","resolve","formValue","params","result","load","call","action","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","Controller","Get","Post","Param","Body","HttpException","HttpStatus","WebhookController","capabilityService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","description","pluginID","pluginVersion","execute","capabilityId","body","result","load","call","action","params","error","CapabilityNotFoundError","HttpException","HttpStatus","NOT_FOUND","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","Module","RequestContextService","PLATFORM_HTTP_CLIENT","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
|