@lark-apaas/nestjs-capability 0.0.1-alpha.0 → 0.0.1-alpha.2
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/README.md +107 -5
- package/dist/index.cjs +261 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -9
- package/dist/index.d.ts +86 -9
- package/dist/index.js +263 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 /**\n * 调用 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n\n /**\n * 流式调用 capability\n * - 返回原始 AsyncIterable\n * - 如果 action 是 unary,包装为单次 yield\n */\n callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;\n\n /**\n * 检查 action 是否为流式\n */\n isStream(actionName: string): Promise<boolean>;\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 this.createExecutor(config);\n }\n\n /**\n * 使用传入的配置加载能力执行器\n * 用于 debug 场景,支持用户传入自定义配置\n */\n loadWithConfig(config: CapabilityConfig): CapabilityExecutor {\n return this.createExecutor(config);\n }\n\n private createExecutor(config: CapabilityConfig): CapabilityExecutor {\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCall(config, actionName, input, contextOverride);\n },\n\n callStream: (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCallStream(config, actionName, input, contextOverride);\n },\n\n isStream: async (actionName: string) => {\n return this.checkIsStream(config, actionName);\n },\n };\n }\n\n /**\n * 检查 action 是否为流式\n */\n private async checkIsStream(config: CapabilityConfig, actionName: string): Promise<boolean> {\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 return pluginInstance.isStreamAction?.(actionName) ?? false;\n }\n\n /**\n * 执行 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n private async executeCall(\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 const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n isStream,\n });\n\n let result: unknown;\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:聚合所有 chunk\n const chunks: unknown[] = [];\n for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n chunks.push(chunk);\n }\n // 使用插件的聚合方法,或默认返回 chunks 数组\n result = pluginInstance.aggregate\n ? pluginInstance.aggregate(actionName, chunks)\n : chunks;\n } else {\n // 非流式 action:直接调用\n result = await pluginInstance.run(actionName, context, resolvedParams);\n }\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 /**\n * 流式执行 capability\n * - stream action: 返回原始 AsyncIterable\n * - unary action: 包装为单次 yield\n */\n private async *executeCallStream(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): AsyncIterable<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 const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability (stream)',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n isStream,\n });\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:透传 AsyncIterable\n yield* pluginInstance.runStream(actionName, context, resolvedParams);\n } else {\n // 非流式 action:包装为单次 yield\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n yield result;\n }\n\n this.logger.log({\n message: 'Capability stream completed',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n } catch (error) {\n this.logger.error({\n message: 'Capability stream 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 Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginLoaderService, PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\nimport type { CapabilityConfig } from '../interfaces';\n\ninterface DebugRequestBody {\n action?: string;\n params?: Record<string, unknown>;\n capability?: CapabilityConfig;\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 action: 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 pluginLoaderService: PluginLoaderService,\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 /**\n * 获取 capability 配置\n * 优先使用 body.capability,否则从服务获取\n */\n private getCapabilityConfig(\n capabilityId: string,\n bodyCapability?: CapabilityConfig,\n ): CapabilityConfig {\n if (bodyCapability) {\n return bodyCapability;\n }\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 return config;\n }\n\n /**\n * 获取 action 名称\n * 优先使用传入的 action,否则使用插件第一个 action\n */\n private async getActionName(pluginID: string, bodyAction?: string): Promise<string> {\n if (bodyAction) {\n return bodyAction;\n }\n\n const pluginInstance = await this.pluginLoaderService.loadPlugin(pluginID);\n const actions = pluginInstance.listActions();\n\n if (actions.length === 0) {\n throw new HttpException(\n {\n code: 1,\n message: `Plugin ${pluginID} has no actions`,\n error: 'NO_ACTIONS',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n return actions[0];\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n const params = body.params ?? {};\n\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginID, body.action);\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n params,\n );\n\n try {\n const result = await this.capabilityService\n .loadWithConfig(config)\n .call(action, 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 action,\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, action },\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, action },\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 action,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n\n @Post('debug/:capability_id/stream')\n async debugStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n const params = body.params ?? {};\n\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginID, body.action);\n\n const capability = this.capabilityService.loadWithConfig(config);\n const stream = capability.callStream(action, params);\n\n for await (const chunk of stream) {\n res.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n\n // 发送结束标记\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n // 错误时发送错误信息\n const message = error instanceof Error ? error.message : String(error);\n let errorCode = 'EXECUTION_ERROR';\n\n if (error instanceof CapabilityNotFoundError) {\n errorCode = 'CAPABILITY_NOT_FOUND';\n } else if (error instanceof PluginNotFoundError) {\n errorCode = 'PLUGIN_NOT_FOUND';\n } else if (error instanceof ActionNotFoundError) {\n errorCode = 'ACTION_NOT_FOUND';\n } else if (error instanceof HttpException) {\n const response = error.getResponse() as { error?: string };\n errorCode = response.error ?? 'EXECUTION_ERROR';\n }\n\n res.write(`data: ${JSON.stringify({ error: message, code: errorCode })}\\n\\n`);\n } finally {\n res.end();\n }\n }\n}\n","import {\n Controller,\n Get,\n Post,\n Param,\n Body,\n Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\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 @Post(':capability_id/stream')\n async executeStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const capability = this.capabilityService.load(capabilityId);\n const stream = capability.callStream(body.action, body.params);\n\n for await (const chunk of stream) {\n res.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n\n // 发送结束标记\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n // 错误时发送错误信息\n const message = error instanceof Error ? error.message : String(error);\n let errorCode = 'EXECUTION_ERROR';\n\n if (error instanceof CapabilityNotFoundError) {\n errorCode = 'CAPABILITY_NOT_FOUND';\n } else if (error instanceof PluginNotFoundError) {\n errorCode = 'PLUGIN_NOT_FOUND';\n } else if (error instanceof ActionNotFoundError) {\n errorCode = 'ACTION_NOT_FOUND';\n }\n\n res.write(`data: ${JSON.stringify({ error: message, code: errorCode })}\\n\\n`);\n } finally {\n res.end();\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","createExecutor","loadWithConfig","call","input","contextOverride","executeCall","callStream","executeCallStream","isStream","checkIsStream","pluginInstance","loadPlugin","hasAction","isStreamAction","startTime","Date","now","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","runStream","chunks","chunk","push","aggregate","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","import_common","DebugController","capabilityService","pluginLoaderService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","getCapabilityConfig","capabilityId","bodyCapability","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","getActionName","bodyAction","pluginInstance","loadPlugin","actions","listActions","length","BAD_REQUEST","debug","body","startTime","Date","now","params","capability","action","resolvedParams","resolve","formValue","result","loadWithConfig","call","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","Error","String","debugStream","res","setHeader","stream","callStream","chunk","write","JSON","stringify","errorCode","response","getResponse","end","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","executeStream","res","setHeader","capability","stream","callStream","chunk","write","JSON","stringify","errorCode","end","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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Logger, OnModuleInit, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { PlatformHttpClient, RequestContextService } from '@lark-apaas/nestjs-common';
|
|
3
3
|
import { ZodSchema } from 'zod';
|
|
4
|
+
import { Response } from 'express';
|
|
4
5
|
|
|
5
6
|
interface UserContext {
|
|
6
7
|
userId: string;
|
|
@@ -17,12 +18,24 @@ interface ActionSchema {
|
|
|
17
18
|
output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema);
|
|
18
19
|
}
|
|
19
20
|
interface PluginInstance {
|
|
21
|
+
/** 执行指定 action(unary) */
|
|
20
22
|
run(actionName: string, context: PluginActionContext, input: unknown): Promise<unknown>;
|
|
23
|
+
/** 检查 action 是否存在 */
|
|
21
24
|
hasAction(actionName: string): boolean;
|
|
25
|
+
/** 获取 action 的 schema */
|
|
22
26
|
getActionSchema(actionName: string): ActionSchema | null;
|
|
27
|
+
/** 获取解析后的 input schema */
|
|
23
28
|
getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined;
|
|
29
|
+
/** 获取解析后的 output schema */
|
|
24
30
|
getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
|
|
31
|
+
/** 列出所有 action */
|
|
25
32
|
listActions(): string[];
|
|
33
|
+
/** 流式执行指定 action */
|
|
34
|
+
runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<unknown>;
|
|
35
|
+
/** 检查 action 是否为流式 */
|
|
36
|
+
isStreamAction?(actionName: string): boolean;
|
|
37
|
+
/** 聚合流式结果(可选,插件自定义聚合逻辑) */
|
|
38
|
+
aggregate?(actionName: string, chunks: unknown[]): unknown;
|
|
26
39
|
}
|
|
27
40
|
interface PluginPackage {
|
|
28
41
|
create(): PluginInstance;
|
|
@@ -64,7 +77,7 @@ declare class PluginLoadError extends Error {
|
|
|
64
77
|
declare class PluginLoaderService {
|
|
65
78
|
private readonly logger;
|
|
66
79
|
private readonly pluginInstances;
|
|
67
|
-
loadPlugin(pluginID: string): PluginInstance
|
|
80
|
+
loadPlugin(pluginID: string): Promise<PluginInstance>;
|
|
68
81
|
isPluginInstalled(pluginID: string): boolean;
|
|
69
82
|
clearCache(pluginID?: string): void;
|
|
70
83
|
}
|
|
@@ -76,7 +89,22 @@ declare class ActionNotFoundError extends Error {
|
|
|
76
89
|
constructor(pluginID: string, actionName: string);
|
|
77
90
|
}
|
|
78
91
|
interface CapabilityExecutor {
|
|
92
|
+
/**
|
|
93
|
+
* 调用 capability(始终返回 Promise)
|
|
94
|
+
* - unary action: 直接返回结果
|
|
95
|
+
* - stream action: 内部聚合所有 chunk 后返回
|
|
96
|
+
*/
|
|
79
97
|
call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* 流式调用 capability
|
|
100
|
+
* - 返回原始 AsyncIterable
|
|
101
|
+
* - 如果 action 是 unary,包装为单次 yield
|
|
102
|
+
*/
|
|
103
|
+
callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;
|
|
104
|
+
/**
|
|
105
|
+
* 检查 action 是否为流式
|
|
106
|
+
*/
|
|
107
|
+
isStream(actionName: string): Promise<boolean>;
|
|
80
108
|
}
|
|
81
109
|
interface CapabilityModuleOptions {
|
|
82
110
|
capabilitiesDir?: string;
|
|
@@ -96,14 +124,36 @@ declare class CapabilityService implements OnModuleInit {
|
|
|
96
124
|
listCapabilities(): CapabilityConfig[];
|
|
97
125
|
getCapability(capabilityId: string): CapabilityConfig | null;
|
|
98
126
|
load(capabilityId: string): CapabilityExecutor;
|
|
99
|
-
|
|
127
|
+
/**
|
|
128
|
+
* 使用传入的配置加载能力执行器
|
|
129
|
+
* 用于 debug 场景,支持用户传入自定义配置
|
|
130
|
+
*/
|
|
131
|
+
loadWithConfig(config: CapabilityConfig): CapabilityExecutor;
|
|
132
|
+
private createExecutor;
|
|
133
|
+
/**
|
|
134
|
+
* 检查 action 是否为流式
|
|
135
|
+
*/
|
|
136
|
+
private checkIsStream;
|
|
137
|
+
/**
|
|
138
|
+
* 执行 capability(始终返回 Promise)
|
|
139
|
+
* - unary action: 直接返回结果
|
|
140
|
+
* - stream action: 内部聚合所有 chunk 后返回
|
|
141
|
+
*/
|
|
142
|
+
private executeCall;
|
|
143
|
+
/**
|
|
144
|
+
* 流式执行 capability
|
|
145
|
+
* - stream action: 返回原始 AsyncIterable
|
|
146
|
+
* - unary action: 包装为单次 yield
|
|
147
|
+
*/
|
|
148
|
+
private executeCallStream;
|
|
100
149
|
private buildActionContext;
|
|
101
150
|
private getUserContext;
|
|
102
151
|
}
|
|
103
152
|
|
|
104
|
-
interface
|
|
105
|
-
action
|
|
106
|
-
params
|
|
153
|
+
interface DebugRequestBody {
|
|
154
|
+
action?: string;
|
|
155
|
+
params?: Record<string, unknown>;
|
|
156
|
+
capability?: CapabilityConfig;
|
|
107
157
|
}
|
|
108
158
|
interface DebugResponse {
|
|
109
159
|
code: number;
|
|
@@ -114,9 +164,10 @@ interface DebugResponse {
|
|
|
114
164
|
resolvedParams: unknown;
|
|
115
165
|
duration: number;
|
|
116
166
|
pluginID: string;
|
|
167
|
+
action: string;
|
|
117
168
|
};
|
|
118
169
|
}
|
|
119
|
-
interface ListResponse {
|
|
170
|
+
interface ListResponse$1 {
|
|
120
171
|
code: number;
|
|
121
172
|
message: string;
|
|
122
173
|
data: Array<{
|
|
@@ -128,10 +179,22 @@ interface ListResponse {
|
|
|
128
179
|
}
|
|
129
180
|
declare class DebugController {
|
|
130
181
|
private readonly capabilityService;
|
|
182
|
+
private readonly pluginLoaderService;
|
|
131
183
|
private readonly templateEngineService;
|
|
132
|
-
constructor(capabilityService: CapabilityService, templateEngineService: TemplateEngineService);
|
|
133
|
-
list(): ListResponse;
|
|
134
|
-
|
|
184
|
+
constructor(capabilityService: CapabilityService, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
|
|
185
|
+
list(): ListResponse$1;
|
|
186
|
+
/**
|
|
187
|
+
* 获取 capability 配置
|
|
188
|
+
* 优先使用 body.capability,否则从服务获取
|
|
189
|
+
*/
|
|
190
|
+
private getCapabilityConfig;
|
|
191
|
+
/**
|
|
192
|
+
* 获取 action 名称
|
|
193
|
+
* 优先使用传入的 action,否则使用插件第一个 action
|
|
194
|
+
*/
|
|
195
|
+
private getActionName;
|
|
196
|
+
debug(capabilityId: string, body: DebugRequestBody): Promise<DebugResponse>;
|
|
197
|
+
debugStream(capabilityId: string, body: DebugRequestBody, res: Response): Promise<void>;
|
|
135
198
|
}
|
|
136
199
|
|
|
137
200
|
interface ExecuteRequestBody {
|
|
@@ -143,10 +206,24 @@ interface ExecuteResponse {
|
|
|
143
206
|
message: string;
|
|
144
207
|
data: unknown;
|
|
145
208
|
}
|
|
209
|
+
interface CapabilityInfo {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
description: string;
|
|
213
|
+
pluginID: string;
|
|
214
|
+
pluginVersion: string;
|
|
215
|
+
}
|
|
216
|
+
interface ListResponse {
|
|
217
|
+
code: number;
|
|
218
|
+
message: string;
|
|
219
|
+
data: CapabilityInfo[];
|
|
220
|
+
}
|
|
146
221
|
declare class WebhookController {
|
|
147
222
|
private readonly capabilityService;
|
|
148
223
|
constructor(capabilityService: CapabilityService);
|
|
224
|
+
list(): ListResponse;
|
|
149
225
|
execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
|
|
226
|
+
executeStream(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise<void>;
|
|
150
227
|
}
|
|
151
228
|
|
|
152
229
|
declare class CapabilityModule {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Logger, OnModuleInit, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { PlatformHttpClient, RequestContextService } from '@lark-apaas/nestjs-common';
|
|
3
3
|
import { ZodSchema } from 'zod';
|
|
4
|
+
import { Response } from 'express';
|
|
4
5
|
|
|
5
6
|
interface UserContext {
|
|
6
7
|
userId: string;
|
|
@@ -17,12 +18,24 @@ interface ActionSchema {
|
|
|
17
18
|
output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema);
|
|
18
19
|
}
|
|
19
20
|
interface PluginInstance {
|
|
21
|
+
/** 执行指定 action(unary) */
|
|
20
22
|
run(actionName: string, context: PluginActionContext, input: unknown): Promise<unknown>;
|
|
23
|
+
/** 检查 action 是否存在 */
|
|
21
24
|
hasAction(actionName: string): boolean;
|
|
25
|
+
/** 获取 action 的 schema */
|
|
22
26
|
getActionSchema(actionName: string): ActionSchema | null;
|
|
27
|
+
/** 获取解析后的 input schema */
|
|
23
28
|
getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined;
|
|
29
|
+
/** 获取解析后的 output schema */
|
|
24
30
|
getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
|
|
31
|
+
/** 列出所有 action */
|
|
25
32
|
listActions(): string[];
|
|
33
|
+
/** 流式执行指定 action */
|
|
34
|
+
runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<unknown>;
|
|
35
|
+
/** 检查 action 是否为流式 */
|
|
36
|
+
isStreamAction?(actionName: string): boolean;
|
|
37
|
+
/** 聚合流式结果(可选,插件自定义聚合逻辑) */
|
|
38
|
+
aggregate?(actionName: string, chunks: unknown[]): unknown;
|
|
26
39
|
}
|
|
27
40
|
interface PluginPackage {
|
|
28
41
|
create(): PluginInstance;
|
|
@@ -64,7 +77,7 @@ declare class PluginLoadError extends Error {
|
|
|
64
77
|
declare class PluginLoaderService {
|
|
65
78
|
private readonly logger;
|
|
66
79
|
private readonly pluginInstances;
|
|
67
|
-
loadPlugin(pluginID: string): PluginInstance
|
|
80
|
+
loadPlugin(pluginID: string): Promise<PluginInstance>;
|
|
68
81
|
isPluginInstalled(pluginID: string): boolean;
|
|
69
82
|
clearCache(pluginID?: string): void;
|
|
70
83
|
}
|
|
@@ -76,7 +89,22 @@ declare class ActionNotFoundError extends Error {
|
|
|
76
89
|
constructor(pluginID: string, actionName: string);
|
|
77
90
|
}
|
|
78
91
|
interface CapabilityExecutor {
|
|
92
|
+
/**
|
|
93
|
+
* 调用 capability(始终返回 Promise)
|
|
94
|
+
* - unary action: 直接返回结果
|
|
95
|
+
* - stream action: 内部聚合所有 chunk 后返回
|
|
96
|
+
*/
|
|
79
97
|
call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* 流式调用 capability
|
|
100
|
+
* - 返回原始 AsyncIterable
|
|
101
|
+
* - 如果 action 是 unary,包装为单次 yield
|
|
102
|
+
*/
|
|
103
|
+
callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;
|
|
104
|
+
/**
|
|
105
|
+
* 检查 action 是否为流式
|
|
106
|
+
*/
|
|
107
|
+
isStream(actionName: string): Promise<boolean>;
|
|
80
108
|
}
|
|
81
109
|
interface CapabilityModuleOptions {
|
|
82
110
|
capabilitiesDir?: string;
|
|
@@ -96,14 +124,36 @@ declare class CapabilityService implements OnModuleInit {
|
|
|
96
124
|
listCapabilities(): CapabilityConfig[];
|
|
97
125
|
getCapability(capabilityId: string): CapabilityConfig | null;
|
|
98
126
|
load(capabilityId: string): CapabilityExecutor;
|
|
99
|
-
|
|
127
|
+
/**
|
|
128
|
+
* 使用传入的配置加载能力执行器
|
|
129
|
+
* 用于 debug 场景,支持用户传入自定义配置
|
|
130
|
+
*/
|
|
131
|
+
loadWithConfig(config: CapabilityConfig): CapabilityExecutor;
|
|
132
|
+
private createExecutor;
|
|
133
|
+
/**
|
|
134
|
+
* 检查 action 是否为流式
|
|
135
|
+
*/
|
|
136
|
+
private checkIsStream;
|
|
137
|
+
/**
|
|
138
|
+
* 执行 capability(始终返回 Promise)
|
|
139
|
+
* - unary action: 直接返回结果
|
|
140
|
+
* - stream action: 内部聚合所有 chunk 后返回
|
|
141
|
+
*/
|
|
142
|
+
private executeCall;
|
|
143
|
+
/**
|
|
144
|
+
* 流式执行 capability
|
|
145
|
+
* - stream action: 返回原始 AsyncIterable
|
|
146
|
+
* - unary action: 包装为单次 yield
|
|
147
|
+
*/
|
|
148
|
+
private executeCallStream;
|
|
100
149
|
private buildActionContext;
|
|
101
150
|
private getUserContext;
|
|
102
151
|
}
|
|
103
152
|
|
|
104
|
-
interface
|
|
105
|
-
action
|
|
106
|
-
params
|
|
153
|
+
interface DebugRequestBody {
|
|
154
|
+
action?: string;
|
|
155
|
+
params?: Record<string, unknown>;
|
|
156
|
+
capability?: CapabilityConfig;
|
|
107
157
|
}
|
|
108
158
|
interface DebugResponse {
|
|
109
159
|
code: number;
|
|
@@ -114,9 +164,10 @@ interface DebugResponse {
|
|
|
114
164
|
resolvedParams: unknown;
|
|
115
165
|
duration: number;
|
|
116
166
|
pluginID: string;
|
|
167
|
+
action: string;
|
|
117
168
|
};
|
|
118
169
|
}
|
|
119
|
-
interface ListResponse {
|
|
170
|
+
interface ListResponse$1 {
|
|
120
171
|
code: number;
|
|
121
172
|
message: string;
|
|
122
173
|
data: Array<{
|
|
@@ -128,10 +179,22 @@ interface ListResponse {
|
|
|
128
179
|
}
|
|
129
180
|
declare class DebugController {
|
|
130
181
|
private readonly capabilityService;
|
|
182
|
+
private readonly pluginLoaderService;
|
|
131
183
|
private readonly templateEngineService;
|
|
132
|
-
constructor(capabilityService: CapabilityService, templateEngineService: TemplateEngineService);
|
|
133
|
-
list(): ListResponse;
|
|
134
|
-
|
|
184
|
+
constructor(capabilityService: CapabilityService, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
|
|
185
|
+
list(): ListResponse$1;
|
|
186
|
+
/**
|
|
187
|
+
* 获取 capability 配置
|
|
188
|
+
* 优先使用 body.capability,否则从服务获取
|
|
189
|
+
*/
|
|
190
|
+
private getCapabilityConfig;
|
|
191
|
+
/**
|
|
192
|
+
* 获取 action 名称
|
|
193
|
+
* 优先使用传入的 action,否则使用插件第一个 action
|
|
194
|
+
*/
|
|
195
|
+
private getActionName;
|
|
196
|
+
debug(capabilityId: string, body: DebugRequestBody): Promise<DebugResponse>;
|
|
197
|
+
debugStream(capabilityId: string, body: DebugRequestBody, res: Response): Promise<void>;
|
|
135
198
|
}
|
|
136
199
|
|
|
137
200
|
interface ExecuteRequestBody {
|
|
@@ -143,10 +206,24 @@ interface ExecuteResponse {
|
|
|
143
206
|
message: string;
|
|
144
207
|
data: unknown;
|
|
145
208
|
}
|
|
209
|
+
interface CapabilityInfo {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
description: string;
|
|
213
|
+
pluginID: string;
|
|
214
|
+
pluginVersion: string;
|
|
215
|
+
}
|
|
216
|
+
interface ListResponse {
|
|
217
|
+
code: number;
|
|
218
|
+
message: string;
|
|
219
|
+
data: CapabilityInfo[];
|
|
220
|
+
}
|
|
146
221
|
declare class WebhookController {
|
|
147
222
|
private readonly capabilityService;
|
|
148
223
|
constructor(capabilityService: CapabilityService);
|
|
224
|
+
list(): ListResponse;
|
|
149
225
|
execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
|
|
226
|
+
executeStream(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise<void>;
|
|
150
227
|
}
|
|
151
228
|
|
|
152
229
|
declare class CapabilityModule {
|