@lark-apaas/nestjs-capability 0.0.1-alpha.9 → 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 +387 -129
- 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 +383 -136
- 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,7 +392,11 @@ 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;
|
|
@@ -293,12 +405,140 @@ var CapabilityService = class _CapabilityService {
|
|
|
293
405
|
const isDev = process.env.NODE_ENV === "development";
|
|
294
406
|
this.capabilitiesDir = path.join(process.cwd(), isDev ? "server/capabilities" : "capabilities");
|
|
295
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* 设置模块配置
|
|
410
|
+
*/
|
|
411
|
+
setOptions(options) {
|
|
412
|
+
this.options = options;
|
|
413
|
+
if (options.capabilitiesDir) {
|
|
414
|
+
this.capabilitiesDir = options.capabilitiesDir;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
296
417
|
setCapabilitiesDir(dir) {
|
|
297
418
|
this.capabilitiesDir = dir;
|
|
298
419
|
}
|
|
299
420
|
async onModuleInit() {
|
|
300
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
|
+
}
|
|
301
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
|
+
// ==================== 原有方法 ====================
|
|
302
542
|
async loadCapabilities() {
|
|
303
543
|
this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);
|
|
304
544
|
if (!fs.existsSync(this.capabilitiesDir)) {
|
|
@@ -309,14 +549,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
309
549
|
for (const file of files) {
|
|
310
550
|
try {
|
|
311
551
|
const filePath = path.join(this.capabilitiesDir, file);
|
|
312
|
-
|
|
313
|
-
const config = JSON.parse(content);
|
|
314
|
-
if (!config.id) {
|
|
315
|
-
this.logger.warn(`Skipping capability without id: ${file}`);
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
this.capabilities.set(config.id, config);
|
|
319
|
-
this.logger.log(`Loaded capability: ${config.id} (${config.name})`);
|
|
552
|
+
this.loadCapabilityFromFile(filePath);
|
|
320
553
|
} catch (error) {
|
|
321
554
|
this.logger.error(`Failed to load capability from ${file}:`, error);
|
|
322
555
|
}
|
|
@@ -593,6 +826,7 @@ CapabilityService = _ts_decorate3([
|
|
|
593
826
|
|
|
594
827
|
// src/controllers/debug.controller.ts
|
|
595
828
|
var import_common4 = require("@nestjs/common");
|
|
829
|
+
var import_swagger = require("@nestjs/swagger");
|
|
596
830
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
597
831
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
598
832
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -623,19 +857,27 @@ var DebugController = class _DebugController {
|
|
|
623
857
|
this.pluginLoaderService = pluginLoaderService;
|
|
624
858
|
this.templateEngineService = templateEngineService;
|
|
625
859
|
}
|
|
626
|
-
list() {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
+
}
|
|
639
881
|
}
|
|
640
882
|
/**
|
|
641
883
|
* 获取 capability 配置
|
|
@@ -647,11 +889,7 @@ var DebugController = class _DebugController {
|
|
|
647
889
|
}
|
|
648
890
|
const config = this.capabilityService.getCapability(capabilityId);
|
|
649
891
|
if (!config) {
|
|
650
|
-
throw new
|
|
651
|
-
code: 1,
|
|
652
|
-
message: `Capability not found: ${capabilityId}`,
|
|
653
|
-
error: "CAPABILITY_NOT_FOUND"
|
|
654
|
-
}, import_common4.HttpStatus.NOT_FOUND);
|
|
892
|
+
throw new CapabilityNotFoundError(capabilityId);
|
|
655
893
|
}
|
|
656
894
|
return config;
|
|
657
895
|
}
|
|
@@ -666,25 +904,21 @@ var DebugController = class _DebugController {
|
|
|
666
904
|
const pluginInstance = await this.pluginLoaderService.loadPlugin(pluginKey);
|
|
667
905
|
const actions = pluginInstance.listActions();
|
|
668
906
|
if (actions.length === 0) {
|
|
669
|
-
throw new
|
|
670
|
-
code: 1,
|
|
671
|
-
message: `Plugin ${pluginKey} has no actions`,
|
|
672
|
-
error: "NO_ACTIONS"
|
|
673
|
-
}, import_common4.HttpStatus.BAD_REQUEST);
|
|
907
|
+
throw new Error(`Plugin ${pluginKey} has no actions`);
|
|
674
908
|
}
|
|
675
909
|
return actions[0];
|
|
676
910
|
}
|
|
677
|
-
async debug(capabilityId, body) {
|
|
911
|
+
async debug(capabilityId, body, res) {
|
|
678
912
|
const startTime = Date.now();
|
|
679
913
|
const params = body.params ?? {};
|
|
680
|
-
const config = this.getCapabilityConfig(capabilityId, body.capability);
|
|
681
|
-
const action = await this.getActionName(config.pluginKey, body.action);
|
|
682
|
-
const resolvedParams = this.templateEngineService.resolve(config.formValue, params);
|
|
683
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);
|
|
684
918
|
const result = await this.capabilityService.loadWithConfig(config).call(action, params, {
|
|
685
919
|
isDebug: true
|
|
686
920
|
});
|
|
687
|
-
|
|
921
|
+
res.status(import_common4.HttpStatus.OK).json({
|
|
688
922
|
status_code: ErrorCodes.SUCCESS,
|
|
689
923
|
data: {
|
|
690
924
|
output: result,
|
|
@@ -696,32 +930,39 @@ var DebugController = class _DebugController {
|
|
|
696
930
|
action
|
|
697
931
|
}
|
|
698
932
|
}
|
|
699
|
-
};
|
|
933
|
+
});
|
|
700
934
|
} catch (error) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
704
|
-
error_msg: `Capability not found: ${capabilityId}`
|
|
705
|
-
}, import_common4.HttpStatus.NOT_FOUND);
|
|
706
|
-
}
|
|
707
|
-
if (error instanceof PluginNotFoundError) {
|
|
708
|
-
throw new import_common4.HttpException({
|
|
709
|
-
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
710
|
-
error_msg: `Plugin not found: ${config.pluginKey}`
|
|
711
|
-
}, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
712
|
-
}
|
|
713
|
-
if (error instanceof ActionNotFoundError) {
|
|
714
|
-
throw new import_common4.HttpException({
|
|
715
|
-
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
716
|
-
error_msg: `Action '${action}' not found in plugin ${config.pluginKey}`
|
|
717
|
-
}, import_common4.HttpStatus.BAD_REQUEST);
|
|
718
|
-
}
|
|
719
|
-
throw new import_common4.HttpException({
|
|
720
|
-
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
721
|
-
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
722
|
-
}, 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));
|
|
723
937
|
}
|
|
724
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
|
+
}
|
|
725
966
|
async debugStream(capabilityId, body, res) {
|
|
726
967
|
const params = body.params ?? {};
|
|
727
968
|
res.setHeader("Content-Type", "text/event-stream");
|
|
@@ -752,9 +993,7 @@ var DebugController = class _DebugController {
|
|
|
752
993
|
status_code: ErrorCodes.SUCCESS,
|
|
753
994
|
data: {
|
|
754
995
|
type: "content",
|
|
755
|
-
delta:
|
|
756
|
-
content: pendingChunk
|
|
757
|
-
}
|
|
996
|
+
delta: pendingChunk
|
|
758
997
|
}
|
|
759
998
|
};
|
|
760
999
|
res.write(`data: ${JSON.stringify(response)}
|
|
@@ -770,9 +1009,7 @@ var DebugController = class _DebugController {
|
|
|
770
1009
|
status_code: ErrorCodes.SUCCESS,
|
|
771
1010
|
data: {
|
|
772
1011
|
type: "content",
|
|
773
|
-
delta:
|
|
774
|
-
content: pendingChunk
|
|
775
|
-
},
|
|
1012
|
+
delta: pendingChunk,
|
|
776
1013
|
finished: true
|
|
777
1014
|
}
|
|
778
1015
|
};
|
|
@@ -812,9 +1049,7 @@ var DebugController = class _DebugController {
|
|
|
812
1049
|
status_code: ErrorCodes.SUCCESS,
|
|
813
1050
|
data: {
|
|
814
1051
|
type: "content",
|
|
815
|
-
delta:
|
|
816
|
-
content: pendingChunk
|
|
817
|
-
},
|
|
1052
|
+
delta: pendingChunk,
|
|
818
1053
|
finished: true
|
|
819
1054
|
}
|
|
820
1055
|
};
|
|
@@ -844,18 +1079,23 @@ var DebugController = class _DebugController {
|
|
|
844
1079
|
};
|
|
845
1080
|
_ts_decorate4([
|
|
846
1081
|
(0, import_common4.Get)("list"),
|
|
1082
|
+
_ts_param2(0, (0, import_common4.Res)()),
|
|
847
1083
|
_ts_metadata2("design:type", Function),
|
|
848
|
-
_ts_metadata2("design:paramtypes", [
|
|
849
|
-
|
|
1084
|
+
_ts_metadata2("design:paramtypes", [
|
|
1085
|
+
typeof Response === "undefined" ? Object : Response
|
|
1086
|
+
]),
|
|
1087
|
+
_ts_metadata2("design:returntype", void 0)
|
|
850
1088
|
], DebugController.prototype, "list", null);
|
|
851
1089
|
_ts_decorate4([
|
|
852
1090
|
(0, import_common4.Post)("debug/:capability_id"),
|
|
853
1091
|
_ts_param2(0, (0, import_common4.Param)("capability_id")),
|
|
854
1092
|
_ts_param2(1, (0, import_common4.Body)()),
|
|
1093
|
+
_ts_param2(2, (0, import_common4.Res)()),
|
|
855
1094
|
_ts_metadata2("design:type", Function),
|
|
856
1095
|
_ts_metadata2("design:paramtypes", [
|
|
857
1096
|
String,
|
|
858
|
-
typeof DebugRequestBody === "undefined" ? Object : DebugRequestBody
|
|
1097
|
+
typeof DebugRequestBody === "undefined" ? Object : DebugRequestBody,
|
|
1098
|
+
typeof Response === "undefined" ? Object : Response
|
|
859
1099
|
]),
|
|
860
1100
|
_ts_metadata2("design:returntype", Promise)
|
|
861
1101
|
], DebugController.prototype, "debug", null);
|
|
@@ -873,6 +1113,7 @@ _ts_decorate4([
|
|
|
873
1113
|
_ts_metadata2("design:returntype", Promise)
|
|
874
1114
|
], DebugController.prototype, "debugStream", null);
|
|
875
1115
|
DebugController = _ts_decorate4([
|
|
1116
|
+
(0, import_swagger.ApiExcludeController)(),
|
|
876
1117
|
(0, import_common4.Controller)("__innerapi__/capability"),
|
|
877
1118
|
_ts_metadata2("design:type", Function),
|
|
878
1119
|
_ts_metadata2("design:paramtypes", [
|
|
@@ -884,6 +1125,7 @@ DebugController = _ts_decorate4([
|
|
|
884
1125
|
|
|
885
1126
|
// src/controllers/webhook.controller.ts
|
|
886
1127
|
var import_common5 = require("@nestjs/common");
|
|
1128
|
+
var import_swagger2 = require("@nestjs/swagger");
|
|
887
1129
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
888
1130
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
889
1131
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -910,54 +1152,69 @@ var WebhookController = class _WebhookController {
|
|
|
910
1152
|
constructor(capabilityService) {
|
|
911
1153
|
this.capabilityService = capabilityService;
|
|
912
1154
|
}
|
|
913
|
-
list() {
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
+
}
|
|
926
1176
|
}
|
|
927
|
-
async execute(capabilityId, body) {
|
|
1177
|
+
async execute(capabilityId, body, res) {
|
|
928
1178
|
try {
|
|
929
1179
|
const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
|
|
930
|
-
|
|
1180
|
+
res.status(import_common5.HttpStatus.OK).json({
|
|
931
1181
|
status_code: ErrorCodes.SUCCESS,
|
|
932
1182
|
data: {
|
|
933
1183
|
output: result
|
|
934
1184
|
}
|
|
935
|
-
};
|
|
1185
|
+
});
|
|
936
1186
|
} catch (error) {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
940
|
-
error_msg: `Capability not found: ${capabilityId}`
|
|
941
|
-
}, import_common5.HttpStatus.NOT_FOUND);
|
|
942
|
-
}
|
|
943
|
-
if (error instanceof PluginNotFoundError) {
|
|
944
|
-
throw new import_common5.HttpException({
|
|
945
|
-
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
946
|
-
error_msg: `Plugin not found`
|
|
947
|
-
}, import_common5.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
948
|
-
}
|
|
949
|
-
if (error instanceof ActionNotFoundError) {
|
|
950
|
-
throw new import_common5.HttpException({
|
|
951
|
-
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
952
|
-
error_msg: `Action '${body.action}' not found`
|
|
953
|
-
}, import_common5.HttpStatus.BAD_REQUEST);
|
|
954
|
-
}
|
|
955
|
-
throw new import_common5.HttpException({
|
|
956
|
-
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
957
|
-
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
958
|
-
}, 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));
|
|
959
1189
|
}
|
|
960
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
|
+
}
|
|
961
1218
|
async executeStream(capabilityId, body, res) {
|
|
962
1219
|
const loggerContext = {
|
|
963
1220
|
capability_id: capabilityId,
|
|
@@ -982,9 +1239,7 @@ var WebhookController = class _WebhookController {
|
|
|
982
1239
|
status_code: ErrorCodes.SUCCESS,
|
|
983
1240
|
data: {
|
|
984
1241
|
type: "content",
|
|
985
|
-
delta:
|
|
986
|
-
content: pendingChunk
|
|
987
|
-
}
|
|
1242
|
+
delta: pendingChunk
|
|
988
1243
|
}
|
|
989
1244
|
};
|
|
990
1245
|
res.write(`data: ${JSON.stringify(response)}
|
|
@@ -1000,9 +1255,7 @@ var WebhookController = class _WebhookController {
|
|
|
1000
1255
|
status_code: ErrorCodes.SUCCESS,
|
|
1001
1256
|
data: {
|
|
1002
1257
|
type: "content",
|
|
1003
|
-
delta:
|
|
1004
|
-
content: pendingChunk
|
|
1005
|
-
},
|
|
1258
|
+
delta: pendingChunk,
|
|
1006
1259
|
finished: true
|
|
1007
1260
|
}
|
|
1008
1261
|
};
|
|
@@ -1042,9 +1295,7 @@ var WebhookController = class _WebhookController {
|
|
|
1042
1295
|
status_code: ErrorCodes.SUCCESS,
|
|
1043
1296
|
data: {
|
|
1044
1297
|
type: "content",
|
|
1045
|
-
delta:
|
|
1046
|
-
content: pendingChunk
|
|
1047
|
-
},
|
|
1298
|
+
delta: pendingChunk,
|
|
1048
1299
|
finished: true
|
|
1049
1300
|
}
|
|
1050
1301
|
};
|
|
@@ -1074,18 +1325,23 @@ var WebhookController = class _WebhookController {
|
|
|
1074
1325
|
};
|
|
1075
1326
|
_ts_decorate5([
|
|
1076
1327
|
(0, import_common5.Get)("list"),
|
|
1328
|
+
_ts_param3(0, (0, import_common5.Res)()),
|
|
1077
1329
|
_ts_metadata3("design:type", Function),
|
|
1078
|
-
_ts_metadata3("design:paramtypes", [
|
|
1079
|
-
|
|
1330
|
+
_ts_metadata3("design:paramtypes", [
|
|
1331
|
+
typeof Response === "undefined" ? Object : Response
|
|
1332
|
+
]),
|
|
1333
|
+
_ts_metadata3("design:returntype", void 0)
|
|
1080
1334
|
], WebhookController.prototype, "list", null);
|
|
1081
1335
|
_ts_decorate5([
|
|
1082
1336
|
(0, import_common5.Post)(":capability_id"),
|
|
1083
1337
|
_ts_param3(0, (0, import_common5.Param)("capability_id")),
|
|
1084
1338
|
_ts_param3(1, (0, import_common5.Body)()),
|
|
1339
|
+
_ts_param3(2, (0, import_common5.Res)()),
|
|
1085
1340
|
_ts_metadata3("design:type", Function),
|
|
1086
1341
|
_ts_metadata3("design:paramtypes", [
|
|
1087
1342
|
String,
|
|
1088
|
-
typeof ExecuteRequestBody === "undefined" ? Object : ExecuteRequestBody
|
|
1343
|
+
typeof ExecuteRequestBody === "undefined" ? Object : ExecuteRequestBody,
|
|
1344
|
+
typeof Response === "undefined" ? Object : Response
|
|
1089
1345
|
]),
|
|
1090
1346
|
_ts_metadata3("design:returntype", Promise)
|
|
1091
1347
|
], WebhookController.prototype, "execute", null);
|
|
@@ -1103,6 +1359,7 @@ _ts_decorate5([
|
|
|
1103
1359
|
_ts_metadata3("design:returntype", Promise)
|
|
1104
1360
|
], WebhookController.prototype, "executeStream", null);
|
|
1105
1361
|
WebhookController = _ts_decorate5([
|
|
1362
|
+
(0, import_swagger2.ApiExcludeController)(),
|
|
1106
1363
|
(0, import_common5.Controller)("api/capability"),
|
|
1107
1364
|
_ts_metadata3("design:type", Function),
|
|
1108
1365
|
_ts_metadata3("design:paramtypes", [
|
|
@@ -1152,8 +1409,8 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
1152
1409
|
provide: CapabilityService,
|
|
1153
1410
|
useFactory: /* @__PURE__ */ __name((requestContextService, httpClient, pluginLoader, templateEngine, moduleOptions) => {
|
|
1154
1411
|
const service = new CapabilityService(requestContextService, httpClient, pluginLoader, templateEngine);
|
|
1155
|
-
if (moduleOptions
|
|
1156
|
-
service.
|
|
1412
|
+
if (moduleOptions) {
|
|
1413
|
+
service.setOptions(moduleOptions);
|
|
1157
1414
|
}
|
|
1158
1415
|
return service;
|
|
1159
1416
|
}, "useFactory"),
|
|
@@ -1202,6 +1459,7 @@ CapabilityModule = _ts_decorate6([
|
|
|
1202
1459
|
PluginLoaderService,
|
|
1203
1460
|
PluginNotFoundError,
|
|
1204
1461
|
TemplateEngineService,
|
|
1205
|
-
WebhookController
|
|
1462
|
+
WebhookController,
|
|
1463
|
+
migrationAdaptor
|
|
1206
1464
|
});
|
|
1207
1465
|
//# sourceMappingURL=index.cjs.map
|