@lark-apaas/nestjs-capability 0.0.1-alpha.8 → 0.1.0
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 +389 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -10
- package/dist/index.d.ts +147 -10
- package/dist/index.js +385 -137
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.cjs
CHANGED
|
@@ -41,10 +41,15 @@ __export(index_exports, {
|
|
|
41
41
|
PluginLoaderService: () => PluginLoaderService,
|
|
42
42
|
PluginNotFoundError: () => PluginNotFoundError,
|
|
43
43
|
TemplateEngineService: () => TemplateEngineService,
|
|
44
|
-
WebhookController: () => WebhookController
|
|
44
|
+
WebhookController: () => WebhookController,
|
|
45
|
+
migrationAdaptor: () => migrationAdaptor
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(index_exports);
|
|
47
48
|
|
|
49
|
+
// ../../../node_modules/tsup/assets/cjs_shims.js
|
|
50
|
+
var getImportMetaUrl = /* @__PURE__ */ __name(() => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href, "getImportMetaUrl");
|
|
51
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
52
|
+
|
|
48
53
|
// src/interfaces/error-codes.ts
|
|
49
54
|
var ErrorCodes = {
|
|
50
55
|
/** 成功 */
|
|
@@ -75,9 +80,9 @@ var TemplateEngineService = class {
|
|
|
75
80
|
__name(this, "TemplateEngineService");
|
|
76
81
|
}
|
|
77
82
|
// 匹配 {{input.xxx}} 或 {{input.xxx.yyy}} 表达式
|
|
78
|
-
EXPR_REGEX = /\{\{input\.([a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*)\}\}/g;
|
|
83
|
+
EXPR_REGEX = /\{\{\s*input\.([a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*\s*)\}\}/g;
|
|
79
84
|
// 匹配整串单个表达式
|
|
80
|
-
WHOLE_STRING_EXPR_REGEX = /^\{\{input\.([a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*)\}\}$/;
|
|
85
|
+
WHOLE_STRING_EXPR_REGEX = /^\{\{\s*input\.([a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*)\s*\}\}$/;
|
|
81
86
|
resolve(template, input) {
|
|
82
87
|
if (typeof template === "string") {
|
|
83
88
|
return this.resolveString(template, input);
|
|
@@ -136,6 +141,8 @@ TemplateEngineService = _ts_decorate([
|
|
|
136
141
|
|
|
137
142
|
// src/services/plugin-loader.service.ts
|
|
138
143
|
var import_common2 = require("@nestjs/common");
|
|
144
|
+
var import_node_module = require("module");
|
|
145
|
+
var import_node_url = require("url");
|
|
139
146
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
140
147
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
141
148
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -143,13 +150,16 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
143
150
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
144
151
|
}
|
|
145
152
|
__name(_ts_decorate2, "_ts_decorate");
|
|
153
|
+
var require2 = (0, import_node_module.createRequire)(importMetaUrl);
|
|
146
154
|
var PluginNotFoundError = class extends Error {
|
|
147
155
|
static {
|
|
148
156
|
__name(this, "PluginNotFoundError");
|
|
149
157
|
}
|
|
158
|
+
pluginKey;
|
|
150
159
|
constructor(pluginKey) {
|
|
151
160
|
super(`Plugin not found: ${pluginKey}`);
|
|
152
161
|
this.name = "PluginNotFoundError";
|
|
162
|
+
this.pluginKey = pluginKey;
|
|
153
163
|
}
|
|
154
164
|
};
|
|
155
165
|
var PluginLoadError = class extends Error {
|
|
@@ -167,6 +177,8 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
167
177
|
}
|
|
168
178
|
logger = new import_common2.Logger(_PluginLoaderService.name);
|
|
169
179
|
pluginInstances = /* @__PURE__ */ new Map();
|
|
180
|
+
/** 记录每个插件的加载版本(时间戳),用于 ESM 缓存绕过 */
|
|
181
|
+
pluginVersions = /* @__PURE__ */ new Map();
|
|
170
182
|
async loadPlugin(pluginKey) {
|
|
171
183
|
const cached = this.pluginInstances.get(pluginKey);
|
|
172
184
|
if (cached) {
|
|
@@ -175,7 +187,12 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
175
187
|
}
|
|
176
188
|
this.logger.log(`Loading plugin: ${pluginKey}`);
|
|
177
189
|
try {
|
|
178
|
-
const
|
|
190
|
+
const resolvedPath = require2.resolve(pluginKey);
|
|
191
|
+
const version = this.pluginVersions.get(pluginKey) ?? 0;
|
|
192
|
+
const fileUrl = (0, import_node_url.pathToFileURL)(resolvedPath).href;
|
|
193
|
+
const importPath = version > 0 ? `${fileUrl}?v=${version}` : fileUrl;
|
|
194
|
+
const mod = await import(importPath);
|
|
195
|
+
const pluginPackage = mod.default ?? mod;
|
|
179
196
|
if (typeof pluginPackage.create !== "function") {
|
|
180
197
|
throw new PluginLoadError(pluginKey, "Plugin does not export create() function");
|
|
181
198
|
}
|
|
@@ -192,21 +209,68 @@ var PluginLoaderService = class _PluginLoaderService {
|
|
|
192
209
|
}
|
|
193
210
|
isPluginInstalled(pluginKey) {
|
|
194
211
|
try {
|
|
195
|
-
|
|
212
|
+
require2.resolve(pluginKey);
|
|
196
213
|
return true;
|
|
197
214
|
} catch {
|
|
198
215
|
return false;
|
|
199
216
|
}
|
|
200
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* 清除插件缓存
|
|
220
|
+
* - 清除应用层 pluginInstances 缓存
|
|
221
|
+
* - 清除 Node.js CJS 模块缓存(require.cache)
|
|
222
|
+
* - 更新版本号,下次 import 时绕过 ESM 缓存
|
|
223
|
+
* @param pluginKey - 插件标识,不传则清除所有
|
|
224
|
+
*/
|
|
201
225
|
clearCache(pluginKey) {
|
|
202
226
|
if (pluginKey) {
|
|
203
227
|
this.pluginInstances.delete(pluginKey);
|
|
228
|
+
this.clearNodeModuleCache(pluginKey);
|
|
229
|
+
this.pluginVersions.set(pluginKey, Date.now());
|
|
204
230
|
this.logger.log(`Cleared cache for plugin: ${pluginKey}`);
|
|
205
231
|
} else {
|
|
232
|
+
for (const key of this.pluginInstances.keys()) {
|
|
233
|
+
this.clearNodeModuleCache(key);
|
|
234
|
+
this.pluginVersions.set(key, Date.now());
|
|
235
|
+
}
|
|
206
236
|
this.pluginInstances.clear();
|
|
207
237
|
this.logger.log("Cleared all plugin caches");
|
|
208
238
|
}
|
|
209
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* 清除 CJS 模块缓存
|
|
242
|
+
*/
|
|
243
|
+
clearNodeModuleCache(pluginKey) {
|
|
244
|
+
try {
|
|
245
|
+
const resolvedPath = require2.resolve(pluginKey);
|
|
246
|
+
const mod = require2.cache[resolvedPath];
|
|
247
|
+
if (mod) {
|
|
248
|
+
this.clearModuleAndChildren(mod, pluginKey);
|
|
249
|
+
}
|
|
250
|
+
delete require2.cache[resolvedPath];
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* 递归清除子模块缓存
|
|
256
|
+
*/
|
|
257
|
+
clearModuleAndChildren(mod, pluginKey) {
|
|
258
|
+
const pluginScope = pluginKey.startsWith("@") ? pluginKey.split("/").slice(0, 2).join("/") : pluginKey;
|
|
259
|
+
mod.children.forEach((child) => {
|
|
260
|
+
if (child.filename.includes(`node_modules/${pluginScope}`)) {
|
|
261
|
+
this.clearModuleAndChildren(child, pluginKey);
|
|
262
|
+
delete require2.cache[child.filename];
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 强制重新加载插件
|
|
268
|
+
* @param pluginKey - 插件标识
|
|
269
|
+
*/
|
|
270
|
+
async reloadPlugin(pluginKey) {
|
|
271
|
+
this.clearCache(pluginKey);
|
|
272
|
+
return this.loadPlugin(pluginKey);
|
|
273
|
+
}
|
|
210
274
|
};
|
|
211
275
|
PluginLoaderService = _ts_decorate2([
|
|
212
276
|
(0, import_common2.Injectable)()
|
|
@@ -217,6 +281,7 @@ var import_common3 = require("@nestjs/common");
|
|
|
217
281
|
var import_nestjs_common = require("@lark-apaas/nestjs-common");
|
|
218
282
|
var fs = __toESM(require("fs"), 1);
|
|
219
283
|
var path = __toESM(require("path"), 1);
|
|
284
|
+
var chokidar = __toESM(require("chokidar"), 1);
|
|
220
285
|
|
|
221
286
|
// src/utils/log-utils.ts
|
|
222
287
|
var DEFAULT_MAX_LENGTH = 1e3;
|
|
@@ -238,6 +303,43 @@ function stringifyForLog(value, maxLength = DEFAULT_MAX_LENGTH) {
|
|
|
238
303
|
}
|
|
239
304
|
__name(stringifyForLog, "stringifyForLog");
|
|
240
305
|
|
|
306
|
+
// src/utils/migration-adaptor.ts
|
|
307
|
+
async function migrationAdaptor(promise) {
|
|
308
|
+
try {
|
|
309
|
+
const result = await promise;
|
|
310
|
+
return {
|
|
311
|
+
code: 0,
|
|
312
|
+
data: {
|
|
313
|
+
output: result,
|
|
314
|
+
outcome: "success"
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
} catch (error) {
|
|
318
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
319
|
+
const appStatusCode = error instanceof Error && "code" in error ? String(error.code) : "EXECUTION_ERROR";
|
|
320
|
+
return {
|
|
321
|
+
code: -1,
|
|
322
|
+
data: {
|
|
323
|
+
outcome: "error",
|
|
324
|
+
failureOutput: {
|
|
325
|
+
response: {
|
|
326
|
+
status: {
|
|
327
|
+
protocolStatusCode: "500",
|
|
328
|
+
appStatusCode
|
|
329
|
+
},
|
|
330
|
+
body: JSON.stringify({
|
|
331
|
+
error: errorMessage,
|
|
332
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
message: errorMessage
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
__name(migrationAdaptor, "migrationAdaptor");
|
|
342
|
+
|
|
241
343
|
// src/services/capability.service.ts
|
|
242
344
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
243
345
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -260,18 +362,24 @@ var CapabilityNotFoundError = class extends Error {
|
|
|
260
362
|
static {
|
|
261
363
|
__name(this, "CapabilityNotFoundError");
|
|
262
364
|
}
|
|
365
|
+
capabilityId;
|
|
263
366
|
constructor(capabilityId) {
|
|
264
367
|
super(`Capability not found: ${capabilityId}`);
|
|
265
368
|
this.name = "CapabilityNotFoundError";
|
|
369
|
+
this.capabilityId = capabilityId;
|
|
266
370
|
}
|
|
267
371
|
};
|
|
268
372
|
var ActionNotFoundError = class extends Error {
|
|
269
373
|
static {
|
|
270
374
|
__name(this, "ActionNotFoundError");
|
|
271
375
|
}
|
|
376
|
+
pluginKey;
|
|
377
|
+
actionName;
|
|
272
378
|
constructor(pluginKey, actionName) {
|
|
273
379
|
super(`Action '${actionName}' not found in plugin ${pluginKey}`);
|
|
274
380
|
this.name = "ActionNotFoundError";
|
|
381
|
+
this.pluginKey = pluginKey;
|
|
382
|
+
this.actionName = actionName;
|
|
275
383
|
}
|
|
276
384
|
};
|
|
277
385
|
var CapabilityService = class _CapabilityService {
|
|
@@ -284,20 +392,153 @@ var CapabilityService = class _CapabilityService {
|
|
|
284
392
|
templateEngineService;
|
|
285
393
|
logger = new import_common3.Logger(_CapabilityService.name);
|
|
286
394
|
capabilities = /* @__PURE__ */ new Map();
|
|
395
|
+
/** 文件路径到 capability id 的映射,用于文件删除时查找 */
|
|
396
|
+
filePathToId = /* @__PURE__ */ new Map();
|
|
287
397
|
capabilitiesDir;
|
|
398
|
+
fileWatcher = null;
|
|
399
|
+
options = {};
|
|
288
400
|
constructor(requestContextService, platformHttpClient, pluginLoaderService, templateEngineService) {
|
|
289
401
|
this.requestContextService = requestContextService;
|
|
290
402
|
this.platformHttpClient = platformHttpClient;
|
|
291
403
|
this.pluginLoaderService = pluginLoaderService;
|
|
292
404
|
this.templateEngineService = templateEngineService;
|
|
293
|
-
|
|
405
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
406
|
+
this.capabilitiesDir = path.join(process.cwd(), isDev ? "server/capabilities" : "capabilities");
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* 设置模块配置
|
|
410
|
+
*/
|
|
411
|
+
setOptions(options) {
|
|
412
|
+
this.options = options;
|
|
413
|
+
if (options.capabilitiesDir) {
|
|
414
|
+
this.capabilitiesDir = options.capabilitiesDir;
|
|
415
|
+
}
|
|
294
416
|
}
|
|
295
417
|
setCapabilitiesDir(dir) {
|
|
296
418
|
this.capabilitiesDir = dir;
|
|
297
419
|
}
|
|
298
420
|
async onModuleInit() {
|
|
299
421
|
await this.loadCapabilities();
|
|
422
|
+
if (this.options.enableWatching) {
|
|
423
|
+
this.startWatching();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async onModuleDestroy() {
|
|
427
|
+
this.stopWatching();
|
|
428
|
+
}
|
|
429
|
+
// ==================== 文件监听相关方法 ====================
|
|
430
|
+
/**
|
|
431
|
+
* 启动文件监听(沙箱环境自动调用)
|
|
432
|
+
*/
|
|
433
|
+
startWatching() {
|
|
434
|
+
if (this.fileWatcher) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (!fs.existsSync(this.capabilitiesDir)) {
|
|
438
|
+
this.logger.warn(`Cannot start watching: directory not found: ${this.capabilitiesDir}`);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const pattern = path.join(this.capabilitiesDir, "*.json");
|
|
442
|
+
const debounce = this.options.watchDebounce ?? 300;
|
|
443
|
+
this.logger.log(`Starting file watcher: ${pattern}`);
|
|
444
|
+
this.fileWatcher = chokidar.watch(pattern, {
|
|
445
|
+
persistent: true,
|
|
446
|
+
ignoreInitial: true,
|
|
447
|
+
awaitWriteFinish: {
|
|
448
|
+
// 等待写入完成
|
|
449
|
+
stabilityThreshold: debounce,
|
|
450
|
+
pollInterval: 100
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
this.fileWatcher.on("add", (filePath) => this.handleFileAdd(filePath)).on("change", (filePath) => this.handleFileChange(filePath)).on("unlink", (filePath) => this.handleFileUnlink(filePath)).on("error", (error) => this.logger.error("File watcher error:", error));
|
|
454
|
+
this.logger.log("File watcher started");
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* 停止文件监听
|
|
458
|
+
*/
|
|
459
|
+
stopWatching() {
|
|
460
|
+
if (this.fileWatcher) {
|
|
461
|
+
this.fileWatcher.close();
|
|
462
|
+
this.fileWatcher = null;
|
|
463
|
+
this.logger.log("File watcher stopped");
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* 重新加载所有能力配置
|
|
468
|
+
*/
|
|
469
|
+
async reloadAllCapabilities() {
|
|
470
|
+
this.capabilities.clear();
|
|
471
|
+
this.filePathToId.clear();
|
|
472
|
+
await this.loadCapabilities();
|
|
473
|
+
}
|
|
474
|
+
handleFileAdd(filePath) {
|
|
475
|
+
this.logger.log(`Capability file added: ${filePath}`);
|
|
476
|
+
try {
|
|
477
|
+
this.loadCapabilityFromFile(filePath);
|
|
478
|
+
const capabilityId = this.filePathToId.get(filePath);
|
|
479
|
+
if (capabilityId) {
|
|
480
|
+
const config = this.capabilities.get(capabilityId);
|
|
481
|
+
if (config?.pluginKey) {
|
|
482
|
+
this.pluginLoaderService.clearCache(config.pluginKey);
|
|
483
|
+
this.logger.log(`Cleared plugin cache for new capability: ${config.pluginKey}`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
} catch (error) {
|
|
487
|
+
this.logger.error(`Failed to load new capability: ${filePath}`, error);
|
|
488
|
+
}
|
|
300
489
|
}
|
|
490
|
+
handleFileChange(filePath) {
|
|
491
|
+
this.logger.log(`Capability file changed: ${filePath}`);
|
|
492
|
+
try {
|
|
493
|
+
this.reloadCapabilityFromFile(filePath);
|
|
494
|
+
} catch (error) {
|
|
495
|
+
this.logger.error(`Failed to reload capability: ${filePath}`, error);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
handleFileUnlink(filePath) {
|
|
499
|
+
this.logger.log(`Capability file removed: ${filePath}`);
|
|
500
|
+
this.removeCapabilityByFile(filePath);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* 从文件加载单个能力配置
|
|
504
|
+
*/
|
|
505
|
+
loadCapabilityFromFile(filePath) {
|
|
506
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
507
|
+
const config = JSON.parse(content);
|
|
508
|
+
if (!config.id) {
|
|
509
|
+
this.logger.warn(`Skipping capability without id: ${filePath}`);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
this.capabilities.set(config.id, config);
|
|
513
|
+
this.filePathToId.set(filePath, config.id);
|
|
514
|
+
this.logger.log(`Loaded capability: ${config.id} (${config.name})`);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* 重新加载单个能力配置
|
|
518
|
+
*/
|
|
519
|
+
reloadCapabilityFromFile(filePath) {
|
|
520
|
+
const oldId = this.filePathToId.get(filePath);
|
|
521
|
+
if (oldId) {
|
|
522
|
+
const oldConfig = this.capabilities.get(oldId);
|
|
523
|
+
if (oldConfig) {
|
|
524
|
+
this.pluginLoaderService.clearCache(oldConfig.pluginKey);
|
|
525
|
+
}
|
|
526
|
+
this.capabilities.delete(oldId);
|
|
527
|
+
}
|
|
528
|
+
this.loadCapabilityFromFile(filePath);
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* 根据文件路径移除能力配置
|
|
532
|
+
*/
|
|
533
|
+
removeCapabilityByFile(filePath) {
|
|
534
|
+
const capabilityId = this.filePathToId.get(filePath);
|
|
535
|
+
if (capabilityId) {
|
|
536
|
+
this.capabilities.delete(capabilityId);
|
|
537
|
+
this.filePathToId.delete(filePath);
|
|
538
|
+
this.logger.log(`Removed capability: ${capabilityId}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// ==================== 原有方法 ====================
|
|
301
542
|
async loadCapabilities() {
|
|
302
543
|
this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);
|
|
303
544
|
if (!fs.existsSync(this.capabilitiesDir)) {
|
|
@@ -308,14 +549,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
308
549
|
for (const file of files) {
|
|
309
550
|
try {
|
|
310
551
|
const filePath = path.join(this.capabilitiesDir, file);
|
|
311
|
-
|
|
312
|
-
const config = JSON.parse(content);
|
|
313
|
-
if (!config.id) {
|
|
314
|
-
this.logger.warn(`Skipping capability without id: ${file}`);
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
this.capabilities.set(config.id, config);
|
|
318
|
-
this.logger.log(`Loaded capability: ${config.id} (${config.name})`);
|
|
552
|
+
this.loadCapabilityFromFile(filePath);
|
|
319
553
|
} catch (error) {
|
|
320
554
|
this.logger.error(`Failed to load capability from ${file}:`, error);
|
|
321
555
|
}
|
|
@@ -592,6 +826,7 @@ CapabilityService = _ts_decorate3([
|
|
|
592
826
|
|
|
593
827
|
// src/controllers/debug.controller.ts
|
|
594
828
|
var import_common4 = require("@nestjs/common");
|
|
829
|
+
var import_swagger = require("@nestjs/swagger");
|
|
595
830
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
596
831
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
597
832
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -622,19 +857,27 @@ var DebugController = class _DebugController {
|
|
|
622
857
|
this.pluginLoaderService = pluginLoaderService;
|
|
623
858
|
this.templateEngineService = templateEngineService;
|
|
624
859
|
}
|
|
625
|
-
list() {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
860
|
+
list(res) {
|
|
861
|
+
try {
|
|
862
|
+
const capabilities = this.capabilityService.listCapabilities();
|
|
863
|
+
res.status(import_common4.HttpStatus.OK).json({
|
|
864
|
+
status_code: ErrorCodes.SUCCESS,
|
|
865
|
+
data: {
|
|
866
|
+
capabilities: capabilities.map((c) => ({
|
|
867
|
+
id: c.id,
|
|
868
|
+
name: c.name,
|
|
869
|
+
pluginID: c.pluginKey,
|
|
870
|
+
pluginVersion: c.pluginVersion
|
|
871
|
+
}))
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
} catch (error) {
|
|
875
|
+
this.logger.error("Failed to list capabilities", error);
|
|
876
|
+
res.status(import_common4.HttpStatus.INTERNAL_SERVER_ERROR).json({
|
|
877
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
878
|
+
error_msg: `Failed to list capabilities: ${error instanceof Error ? error.message : String(error)}`
|
|
879
|
+
});
|
|
880
|
+
}
|
|
638
881
|
}
|
|
639
882
|
/**
|
|
640
883
|
* 获取 capability 配置
|
|
@@ -646,11 +889,7 @@ var DebugController = class _DebugController {
|
|
|
646
889
|
}
|
|
647
890
|
const config = this.capabilityService.getCapability(capabilityId);
|
|
648
891
|
if (!config) {
|
|
649
|
-
throw new
|
|
650
|
-
code: 1,
|
|
651
|
-
message: `Capability not found: ${capabilityId}`,
|
|
652
|
-
error: "CAPABILITY_NOT_FOUND"
|
|
653
|
-
}, import_common4.HttpStatus.NOT_FOUND);
|
|
892
|
+
throw new CapabilityNotFoundError(capabilityId);
|
|
654
893
|
}
|
|
655
894
|
return config;
|
|
656
895
|
}
|
|
@@ -665,25 +904,21 @@ var DebugController = class _DebugController {
|
|
|
665
904
|
const pluginInstance = await this.pluginLoaderService.loadPlugin(pluginKey);
|
|
666
905
|
const actions = pluginInstance.listActions();
|
|
667
906
|
if (actions.length === 0) {
|
|
668
|
-
throw new
|
|
669
|
-
code: 1,
|
|
670
|
-
message: `Plugin ${pluginKey} has no actions`,
|
|
671
|
-
error: "NO_ACTIONS"
|
|
672
|
-
}, import_common4.HttpStatus.BAD_REQUEST);
|
|
907
|
+
throw new Error(`Plugin ${pluginKey} has no actions`);
|
|
673
908
|
}
|
|
674
909
|
return actions[0];
|
|
675
910
|
}
|
|
676
|
-
async debug(capabilityId, body) {
|
|
911
|
+
async debug(capabilityId, body, res) {
|
|
677
912
|
const startTime = Date.now();
|
|
678
913
|
const params = body.params ?? {};
|
|
679
|
-
const config = this.getCapabilityConfig(capabilityId, body.capability);
|
|
680
|
-
const action = await this.getActionName(config.pluginKey, body.action);
|
|
681
|
-
const resolvedParams = this.templateEngineService.resolve(config.formValue, params);
|
|
682
914
|
try {
|
|
915
|
+
const config = this.getCapabilityConfig(capabilityId, body.capability);
|
|
916
|
+
const action = await this.getActionName(config.pluginKey, body.action);
|
|
917
|
+
const resolvedParams = this.templateEngineService.resolve(config.formValue, params);
|
|
683
918
|
const result = await this.capabilityService.loadWithConfig(config).call(action, params, {
|
|
684
919
|
isDebug: true
|
|
685
920
|
});
|
|
686
|
-
|
|
921
|
+
res.status(import_common4.HttpStatus.OK).json({
|
|
687
922
|
status_code: ErrorCodes.SUCCESS,
|
|
688
923
|
data: {
|
|
689
924
|
output: result,
|
|
@@ -695,32 +930,39 @@ var DebugController = class _DebugController {
|
|
|
695
930
|
action
|
|
696
931
|
}
|
|
697
932
|
}
|
|
698
|
-
};
|
|
933
|
+
});
|
|
699
934
|
} catch (error) {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
703
|
-
error_msg: `Capability not found: ${capabilityId}`
|
|
704
|
-
}, import_common4.HttpStatus.NOT_FOUND);
|
|
705
|
-
}
|
|
706
|
-
if (error instanceof PluginNotFoundError) {
|
|
707
|
-
throw new import_common4.HttpException({
|
|
708
|
-
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
709
|
-
error_msg: `Plugin not found: ${config.pluginKey}`
|
|
710
|
-
}, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
711
|
-
}
|
|
712
|
-
if (error instanceof ActionNotFoundError) {
|
|
713
|
-
throw new import_common4.HttpException({
|
|
714
|
-
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
715
|
-
error_msg: `Action '${action}' not found in plugin ${config.pluginKey}`
|
|
716
|
-
}, import_common4.HttpStatus.BAD_REQUEST);
|
|
717
|
-
}
|
|
718
|
-
throw new import_common4.HttpException({
|
|
719
|
-
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
720
|
-
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
721
|
-
}, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
935
|
+
this.logger.error("Debug execution failed", error);
|
|
936
|
+
res.status(import_common4.HttpStatus.INTERNAL_SERVER_ERROR).json(this.buildErrorResponse(error));
|
|
722
937
|
}
|
|
723
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* 构建错误响应
|
|
941
|
+
*/
|
|
942
|
+
buildErrorResponse(error) {
|
|
943
|
+
if (error instanceof CapabilityNotFoundError) {
|
|
944
|
+
return {
|
|
945
|
+
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
946
|
+
error_msg: `Capability not found: ${error.capabilityId}`
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
if (error instanceof PluginNotFoundError) {
|
|
950
|
+
return {
|
|
951
|
+
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
952
|
+
error_msg: `Plugin not found, please install plugin: ${error.pluginKey}`
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
if (error instanceof ActionNotFoundError) {
|
|
956
|
+
return {
|
|
957
|
+
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
958
|
+
error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
return {
|
|
962
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
963
|
+
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
964
|
+
};
|
|
965
|
+
}
|
|
724
966
|
async debugStream(capabilityId, body, res) {
|
|
725
967
|
const params = body.params ?? {};
|
|
726
968
|
res.setHeader("Content-Type", "text/event-stream");
|
|
@@ -751,9 +993,7 @@ var DebugController = class _DebugController {
|
|
|
751
993
|
status_code: ErrorCodes.SUCCESS,
|
|
752
994
|
data: {
|
|
753
995
|
type: "content",
|
|
754
|
-
delta:
|
|
755
|
-
content: pendingChunk
|
|
756
|
-
}
|
|
996
|
+
delta: pendingChunk
|
|
757
997
|
}
|
|
758
998
|
};
|
|
759
999
|
res.write(`data: ${JSON.stringify(response)}
|
|
@@ -769,9 +1009,7 @@ var DebugController = class _DebugController {
|
|
|
769
1009
|
status_code: ErrorCodes.SUCCESS,
|
|
770
1010
|
data: {
|
|
771
1011
|
type: "content",
|
|
772
|
-
delta:
|
|
773
|
-
content: pendingChunk
|
|
774
|
-
},
|
|
1012
|
+
delta: pendingChunk,
|
|
775
1013
|
finished: true
|
|
776
1014
|
}
|
|
777
1015
|
};
|
|
@@ -811,9 +1049,7 @@ var DebugController = class _DebugController {
|
|
|
811
1049
|
status_code: ErrorCodes.SUCCESS,
|
|
812
1050
|
data: {
|
|
813
1051
|
type: "content",
|
|
814
|
-
delta:
|
|
815
|
-
content: pendingChunk
|
|
816
|
-
},
|
|
1052
|
+
delta: pendingChunk,
|
|
817
1053
|
finished: true
|
|
818
1054
|
}
|
|
819
1055
|
};
|
|
@@ -843,18 +1079,23 @@ var DebugController = class _DebugController {
|
|
|
843
1079
|
};
|
|
844
1080
|
_ts_decorate4([
|
|
845
1081
|
(0, import_common4.Get)("list"),
|
|
1082
|
+
_ts_param2(0, (0, import_common4.Res)()),
|
|
846
1083
|
_ts_metadata2("design:type", Function),
|
|
847
|
-
_ts_metadata2("design:paramtypes", [
|
|
848
|
-
|
|
1084
|
+
_ts_metadata2("design:paramtypes", [
|
|
1085
|
+
typeof Response === "undefined" ? Object : Response
|
|
1086
|
+
]),
|
|
1087
|
+
_ts_metadata2("design:returntype", void 0)
|
|
849
1088
|
], DebugController.prototype, "list", null);
|
|
850
1089
|
_ts_decorate4([
|
|
851
1090
|
(0, import_common4.Post)("debug/:capability_id"),
|
|
852
1091
|
_ts_param2(0, (0, import_common4.Param)("capability_id")),
|
|
853
1092
|
_ts_param2(1, (0, import_common4.Body)()),
|
|
1093
|
+
_ts_param2(2, (0, import_common4.Res)()),
|
|
854
1094
|
_ts_metadata2("design:type", Function),
|
|
855
1095
|
_ts_metadata2("design:paramtypes", [
|
|
856
1096
|
String,
|
|
857
|
-
typeof DebugRequestBody === "undefined" ? Object : DebugRequestBody
|
|
1097
|
+
typeof DebugRequestBody === "undefined" ? Object : DebugRequestBody,
|
|
1098
|
+
typeof Response === "undefined" ? Object : Response
|
|
858
1099
|
]),
|
|
859
1100
|
_ts_metadata2("design:returntype", Promise)
|
|
860
1101
|
], DebugController.prototype, "debug", null);
|
|
@@ -872,6 +1113,7 @@ _ts_decorate4([
|
|
|
872
1113
|
_ts_metadata2("design:returntype", Promise)
|
|
873
1114
|
], DebugController.prototype, "debugStream", null);
|
|
874
1115
|
DebugController = _ts_decorate4([
|
|
1116
|
+
(0, import_swagger.ApiExcludeController)(),
|
|
875
1117
|
(0, import_common4.Controller)("__innerapi__/capability"),
|
|
876
1118
|
_ts_metadata2("design:type", Function),
|
|
877
1119
|
_ts_metadata2("design:paramtypes", [
|
|
@@ -883,6 +1125,7 @@ DebugController = _ts_decorate4([
|
|
|
883
1125
|
|
|
884
1126
|
// src/controllers/webhook.controller.ts
|
|
885
1127
|
var import_common5 = require("@nestjs/common");
|
|
1128
|
+
var import_swagger2 = require("@nestjs/swagger");
|
|
886
1129
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
887
1130
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
888
1131
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -909,54 +1152,69 @@ var WebhookController = class _WebhookController {
|
|
|
909
1152
|
constructor(capabilityService) {
|
|
910
1153
|
this.capabilityService = capabilityService;
|
|
911
1154
|
}
|
|
912
|
-
list() {
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1155
|
+
list(res) {
|
|
1156
|
+
try {
|
|
1157
|
+
const capabilities = this.capabilityService.listCapabilities();
|
|
1158
|
+
res.status(import_common5.HttpStatus.OK).json({
|
|
1159
|
+
status_code: ErrorCodes.SUCCESS,
|
|
1160
|
+
data: {
|
|
1161
|
+
capabilities: capabilities.map((c) => ({
|
|
1162
|
+
id: c.id,
|
|
1163
|
+
name: c.name,
|
|
1164
|
+
pluginID: c.pluginKey,
|
|
1165
|
+
pluginVersion: c.pluginVersion
|
|
1166
|
+
}))
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
} catch (error) {
|
|
1170
|
+
this.logger.error("Failed to list capabilities", error);
|
|
1171
|
+
res.status(import_common5.HttpStatus.INTERNAL_SERVER_ERROR).json({
|
|
1172
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
1173
|
+
error_msg: `Failed to list capabilities: ${error instanceof Error ? error.message : String(error)}`
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
925
1176
|
}
|
|
926
|
-
async execute(capabilityId, body) {
|
|
1177
|
+
async execute(capabilityId, body, res) {
|
|
927
1178
|
try {
|
|
928
1179
|
const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
|
|
929
|
-
|
|
1180
|
+
res.status(import_common5.HttpStatus.OK).json({
|
|
930
1181
|
status_code: ErrorCodes.SUCCESS,
|
|
931
1182
|
data: {
|
|
932
1183
|
output: result
|
|
933
1184
|
}
|
|
934
|
-
};
|
|
1185
|
+
});
|
|
935
1186
|
} catch (error) {
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
939
|
-
error_msg: `Capability not found: ${capabilityId}`
|
|
940
|
-
}, import_common5.HttpStatus.NOT_FOUND);
|
|
941
|
-
}
|
|
942
|
-
if (error instanceof PluginNotFoundError) {
|
|
943
|
-
throw new import_common5.HttpException({
|
|
944
|
-
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
945
|
-
error_msg: `Plugin not found`
|
|
946
|
-
}, import_common5.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
947
|
-
}
|
|
948
|
-
if (error instanceof ActionNotFoundError) {
|
|
949
|
-
throw new import_common5.HttpException({
|
|
950
|
-
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
951
|
-
error_msg: `Action '${body.action}' not found`
|
|
952
|
-
}, import_common5.HttpStatus.BAD_REQUEST);
|
|
953
|
-
}
|
|
954
|
-
throw new import_common5.HttpException({
|
|
955
|
-
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
956
|
-
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
957
|
-
}, import_common5.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1187
|
+
this.logger.error("Capability execution failed", error);
|
|
1188
|
+
res.status(import_common5.HttpStatus.INTERNAL_SERVER_ERROR).json(this.buildErrorResponse(error));
|
|
958
1189
|
}
|
|
959
1190
|
}
|
|
1191
|
+
/**
|
|
1192
|
+
* 构建错误响应
|
|
1193
|
+
*/
|
|
1194
|
+
buildErrorResponse(error) {
|
|
1195
|
+
if (error instanceof CapabilityNotFoundError) {
|
|
1196
|
+
return {
|
|
1197
|
+
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
1198
|
+
error_msg: `Capability not found: ${error.capabilityId}`
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
if (error instanceof PluginNotFoundError) {
|
|
1202
|
+
return {
|
|
1203
|
+
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
1204
|
+
error_msg: `Plugin not found, please install plugin: ${error.pluginKey}`
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
if (error instanceof ActionNotFoundError) {
|
|
1208
|
+
return {
|
|
1209
|
+
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
1210
|
+
error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
return {
|
|
1214
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
1215
|
+
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
960
1218
|
async executeStream(capabilityId, body, res) {
|
|
961
1219
|
const loggerContext = {
|
|
962
1220
|
capability_id: capabilityId,
|
|
@@ -981,9 +1239,7 @@ var WebhookController = class _WebhookController {
|
|
|
981
1239
|
status_code: ErrorCodes.SUCCESS,
|
|
982
1240
|
data: {
|
|
983
1241
|
type: "content",
|
|
984
|
-
delta:
|
|
985
|
-
content: pendingChunk
|
|
986
|
-
}
|
|
1242
|
+
delta: pendingChunk
|
|
987
1243
|
}
|
|
988
1244
|
};
|
|
989
1245
|
res.write(`data: ${JSON.stringify(response)}
|
|
@@ -999,9 +1255,7 @@ var WebhookController = class _WebhookController {
|
|
|
999
1255
|
status_code: ErrorCodes.SUCCESS,
|
|
1000
1256
|
data: {
|
|
1001
1257
|
type: "content",
|
|
1002
|
-
delta:
|
|
1003
|
-
content: pendingChunk
|
|
1004
|
-
},
|
|
1258
|
+
delta: pendingChunk,
|
|
1005
1259
|
finished: true
|
|
1006
1260
|
}
|
|
1007
1261
|
};
|
|
@@ -1041,9 +1295,7 @@ var WebhookController = class _WebhookController {
|
|
|
1041
1295
|
status_code: ErrorCodes.SUCCESS,
|
|
1042
1296
|
data: {
|
|
1043
1297
|
type: "content",
|
|
1044
|
-
delta:
|
|
1045
|
-
content: pendingChunk
|
|
1046
|
-
},
|
|
1298
|
+
delta: pendingChunk,
|
|
1047
1299
|
finished: true
|
|
1048
1300
|
}
|
|
1049
1301
|
};
|
|
@@ -1073,18 +1325,23 @@ var WebhookController = class _WebhookController {
|
|
|
1073
1325
|
};
|
|
1074
1326
|
_ts_decorate5([
|
|
1075
1327
|
(0, import_common5.Get)("list"),
|
|
1328
|
+
_ts_param3(0, (0, import_common5.Res)()),
|
|
1076
1329
|
_ts_metadata3("design:type", Function),
|
|
1077
|
-
_ts_metadata3("design:paramtypes", [
|
|
1078
|
-
|
|
1330
|
+
_ts_metadata3("design:paramtypes", [
|
|
1331
|
+
typeof Response === "undefined" ? Object : Response
|
|
1332
|
+
]),
|
|
1333
|
+
_ts_metadata3("design:returntype", void 0)
|
|
1079
1334
|
], WebhookController.prototype, "list", null);
|
|
1080
1335
|
_ts_decorate5([
|
|
1081
1336
|
(0, import_common5.Post)(":capability_id"),
|
|
1082
1337
|
_ts_param3(0, (0, import_common5.Param)("capability_id")),
|
|
1083
1338
|
_ts_param3(1, (0, import_common5.Body)()),
|
|
1339
|
+
_ts_param3(2, (0, import_common5.Res)()),
|
|
1084
1340
|
_ts_metadata3("design:type", Function),
|
|
1085
1341
|
_ts_metadata3("design:paramtypes", [
|
|
1086
1342
|
String,
|
|
1087
|
-
typeof ExecuteRequestBody === "undefined" ? Object : ExecuteRequestBody
|
|
1343
|
+
typeof ExecuteRequestBody === "undefined" ? Object : ExecuteRequestBody,
|
|
1344
|
+
typeof Response === "undefined" ? Object : Response
|
|
1088
1345
|
]),
|
|
1089
1346
|
_ts_metadata3("design:returntype", Promise)
|
|
1090
1347
|
], WebhookController.prototype, "execute", null);
|
|
@@ -1102,6 +1359,7 @@ _ts_decorate5([
|
|
|
1102
1359
|
_ts_metadata3("design:returntype", Promise)
|
|
1103
1360
|
], WebhookController.prototype, "executeStream", null);
|
|
1104
1361
|
WebhookController = _ts_decorate5([
|
|
1362
|
+
(0, import_swagger2.ApiExcludeController)(),
|
|
1105
1363
|
(0, import_common5.Controller)("api/capability"),
|
|
1106
1364
|
_ts_metadata3("design:type", Function),
|
|
1107
1365
|
_ts_metadata3("design:paramtypes", [
|
|
@@ -1151,8 +1409,8 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
1151
1409
|
provide: CapabilityService,
|
|
1152
1410
|
useFactory: /* @__PURE__ */ __name((requestContextService, httpClient, pluginLoader, templateEngine, moduleOptions) => {
|
|
1153
1411
|
const service = new CapabilityService(requestContextService, httpClient, pluginLoader, templateEngine);
|
|
1154
|
-
if (moduleOptions
|
|
1155
|
-
service.
|
|
1412
|
+
if (moduleOptions) {
|
|
1413
|
+
service.setOptions(moduleOptions);
|
|
1156
1414
|
}
|
|
1157
1415
|
return service;
|
|
1158
1416
|
}, "useFactory"),
|
|
@@ -1201,6 +1459,7 @@ CapabilityModule = _ts_decorate6([
|
|
|
1201
1459
|
PluginLoaderService,
|
|
1202
1460
|
PluginNotFoundError,
|
|
1203
1461
|
TemplateEngineService,
|
|
1204
|
-
WebhookController
|
|
1462
|
+
WebhookController,
|
|
1463
|
+
migrationAdaptor
|
|
1205
1464
|
});
|
|
1206
1465
|
//# sourceMappingURL=index.cjs.map
|