@lark-apaas/nestjs-capability 0.1.4-beta.4 → 0.1.4-beta.5
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 +7 -1
- package/dist/index.cjs +102 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +104 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -419,8 +419,9 @@ interface PluginInstance {
|
|
|
419
419
|
|
|
420
420
|
```typescript
|
|
421
421
|
interface PluginActionContext {
|
|
422
|
+
pluginKey: string; // 插件标识(如 @official/ai-chat)
|
|
422
423
|
logger: Logger; // 日志记录器
|
|
423
|
-
|
|
424
|
+
platformHttpClient: PlatformHttpClient; // HTTP 客户端(自动携带 x-plugin-key header)
|
|
424
425
|
userContext: {
|
|
425
426
|
userId: string; // 用户 ID
|
|
426
427
|
tenantId: string; // 租户 ID
|
|
@@ -430,6 +431,11 @@ interface PluginActionContext {
|
|
|
430
431
|
}
|
|
431
432
|
```
|
|
432
433
|
|
|
434
|
+
**pluginKey 说明:**
|
|
435
|
+
- 每次插件调用都会传入当前插件的标识
|
|
436
|
+
- 插件的 HttpClient 会自动在请求头中携带 `x-plugin-key` header
|
|
437
|
+
- 用于计费追踪、日志关联等场景
|
|
438
|
+
|
|
433
439
|
**isDebug 说明:**
|
|
434
440
|
- `DebugController` 调用时 `isDebug = true`
|
|
435
441
|
- `WebhookController` 或其他调用时 `isDebug = false`
|
package/dist/index.cjs
CHANGED
|
@@ -63,7 +63,9 @@ var ErrorCodes = {
|
|
|
63
63
|
/** 参数验证失败 */
|
|
64
64
|
PARAMS_VALIDATION_ERROR: "k_ec_cap_004",
|
|
65
65
|
/** 执行失败 */
|
|
66
|
-
EXECUTION_ERROR: "k_ec_cap_005"
|
|
66
|
+
EXECUTION_ERROR: "k_ec_cap_005",
|
|
67
|
+
/** 计费受限 */
|
|
68
|
+
RATE_LIMIT_EXCEEDED: "k_ec_cap_006"
|
|
67
69
|
};
|
|
68
70
|
|
|
69
71
|
// src/services/template-engine.service.ts
|
|
@@ -538,7 +540,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
538
540
|
__name(this, "CapabilityService");
|
|
539
541
|
}
|
|
540
542
|
requestContextService;
|
|
541
|
-
|
|
543
|
+
httpClientFactory;
|
|
542
544
|
pluginLoaderService;
|
|
543
545
|
templateEngineService;
|
|
544
546
|
logger = new import_common3.Logger(_CapabilityService.name);
|
|
@@ -548,9 +550,9 @@ var CapabilityService = class _CapabilityService {
|
|
|
548
550
|
capabilitiesDir;
|
|
549
551
|
fileWatcher = null;
|
|
550
552
|
options = {};
|
|
551
|
-
constructor(requestContextService,
|
|
553
|
+
constructor(requestContextService, httpClientFactory, pluginLoaderService, templateEngineService) {
|
|
552
554
|
this.requestContextService = requestContextService;
|
|
553
|
-
this.
|
|
555
|
+
this.httpClientFactory = httpClientFactory;
|
|
554
556
|
this.pluginLoaderService = pluginLoaderService;
|
|
555
557
|
this.templateEngineService = templateEngineService;
|
|
556
558
|
const isDev = process.env.NODE_ENV === "development";
|
|
@@ -790,7 +792,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
790
792
|
if (!pluginInstance.hasAction(actionName)) {
|
|
791
793
|
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
792
794
|
}
|
|
793
|
-
const context = this.buildActionContext(contextOverride);
|
|
795
|
+
const context = this.buildActionContext(config.pluginKey, contextOverride);
|
|
794
796
|
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
795
797
|
this.logger.log("Executing capability (call)", {
|
|
796
798
|
...loggerContext,
|
|
@@ -840,7 +842,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
840
842
|
if (!pluginInstance.hasAction(actionName)) {
|
|
841
843
|
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
842
844
|
}
|
|
843
|
-
const context = this.buildActionContext(contextOverride);
|
|
845
|
+
const context = this.buildActionContext(config.pluginKey, contextOverride);
|
|
844
846
|
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
845
847
|
this.logger.log("Executing capability (stream)", {
|
|
846
848
|
...loggerContext,
|
|
@@ -890,7 +892,7 @@ var CapabilityService = class _CapabilityService {
|
|
|
890
892
|
if (!pluginInstance.hasAction(actionName)) {
|
|
891
893
|
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
892
894
|
}
|
|
893
|
-
const context = this.buildActionContext(contextOverride);
|
|
895
|
+
const context = this.buildActionContext(config.pluginKey, contextOverride);
|
|
894
896
|
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
895
897
|
this.logger.log("Executing capability (streamWithEvents)", {
|
|
896
898
|
...loggerContext,
|
|
@@ -956,21 +958,69 @@ var CapabilityService = class _CapabilityService {
|
|
|
956
958
|
});
|
|
957
959
|
yield {
|
|
958
960
|
type: "error",
|
|
959
|
-
error:
|
|
960
|
-
code: "EXECUTION_ERROR",
|
|
961
|
-
message: error instanceof Error ? error.message : String(error)
|
|
962
|
-
}
|
|
961
|
+
error: this.extractErrorInfo(error)
|
|
963
962
|
};
|
|
964
963
|
}
|
|
965
964
|
}
|
|
966
|
-
|
|
965
|
+
/**
|
|
966
|
+
* 从错误对象提取错误信息
|
|
967
|
+
* 支持 PluginError 和 RateLimitError
|
|
968
|
+
*/
|
|
969
|
+
extractErrorInfo(error) {
|
|
970
|
+
const err = error;
|
|
971
|
+
const code = err?.code ?? "EXECUTION_ERROR";
|
|
972
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
973
|
+
if (code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
|
|
974
|
+
return {
|
|
975
|
+
code,
|
|
976
|
+
message,
|
|
977
|
+
rateLimitCode: err.rateLimitCode,
|
|
978
|
+
rateLimitMessage: err.rateLimitMessage
|
|
979
|
+
};
|
|
980
|
+
}
|
|
967
981
|
return {
|
|
982
|
+
code,
|
|
983
|
+
message
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
buildActionContext(pluginKey, override) {
|
|
987
|
+
return {
|
|
988
|
+
pluginKey,
|
|
968
989
|
logger: this.logger,
|
|
969
|
-
platformHttpClient: this.
|
|
990
|
+
platformHttpClient: this.createPluginHttpClient(pluginKey),
|
|
970
991
|
userContext: override?.userContext ?? this.getUserContext(),
|
|
971
992
|
isDebug: override?.isDebug ?? false
|
|
972
993
|
};
|
|
973
994
|
}
|
|
995
|
+
/**
|
|
996
|
+
* 为指定插件创建独立的 HttpClient 实例
|
|
997
|
+
* 自动添加 x-plugin-key header
|
|
998
|
+
*/
|
|
999
|
+
createPluginHttpClient(pluginKey) {
|
|
1000
|
+
const client = this.httpClientFactory.create();
|
|
1001
|
+
client.interceptors.request.use((config) => {
|
|
1002
|
+
config.headers = {
|
|
1003
|
+
...config.headers,
|
|
1004
|
+
"x-plugin-key": pluginKey
|
|
1005
|
+
};
|
|
1006
|
+
return config;
|
|
1007
|
+
});
|
|
1008
|
+
return this.wrapAsProtectedClient(client);
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* 将 HttpClient 包装为受保护的 PlatformHttpClient
|
|
1012
|
+
* 只暴露请求方法,不暴露 interceptors
|
|
1013
|
+
*/
|
|
1014
|
+
wrapAsProtectedClient(client) {
|
|
1015
|
+
return {
|
|
1016
|
+
request: /* @__PURE__ */ __name((config) => client.request(config), "request"),
|
|
1017
|
+
get: /* @__PURE__ */ __name((url, config) => client.get(url, config), "get"),
|
|
1018
|
+
post: /* @__PURE__ */ __name((url, data, config) => client.post(url, data, config), "post"),
|
|
1019
|
+
put: /* @__PURE__ */ __name((url, data, config) => client.put(url, data, config), "put"),
|
|
1020
|
+
patch: /* @__PURE__ */ __name((url, data, config) => client.patch(url, data, config), "patch"),
|
|
1021
|
+
delete: /* @__PURE__ */ __name((url, config) => client.delete(url, config), "delete")
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
974
1024
|
getUserContext() {
|
|
975
1025
|
const ctx = this.requestContextService.getContext();
|
|
976
1026
|
return {
|
|
@@ -982,11 +1032,11 @@ var CapabilityService = class _CapabilityService {
|
|
|
982
1032
|
};
|
|
983
1033
|
CapabilityService = _ts_decorate3([
|
|
984
1034
|
(0, import_common3.Injectable)(),
|
|
985
|
-
_ts_param(1, (0, import_common3.Inject)(import_nestjs_common.
|
|
1035
|
+
_ts_param(1, (0, import_common3.Inject)(import_nestjs_common.HTTP_CLIENT_FACTORY)),
|
|
986
1036
|
_ts_metadata("design:type", Function),
|
|
987
1037
|
_ts_metadata("design:paramtypes", [
|
|
988
1038
|
typeof import_nestjs_common.RequestContextService === "undefined" ? Object : import_nestjs_common.RequestContextService,
|
|
989
|
-
typeof
|
|
1039
|
+
typeof HttpClientFactory === "undefined" ? Object : HttpClientFactory,
|
|
990
1040
|
typeof PluginLoaderService === "undefined" ? Object : PluginLoaderService,
|
|
991
1041
|
typeof TemplateEngineService === "undefined" ? Object : TemplateEngineService
|
|
992
1042
|
])
|
|
@@ -1127,6 +1177,14 @@ var DebugController = class _DebugController {
|
|
|
1127
1177
|
error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
|
|
1128
1178
|
};
|
|
1129
1179
|
}
|
|
1180
|
+
const err = error;
|
|
1181
|
+
if (err?.code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
|
|
1182
|
+
return {
|
|
1183
|
+
status_code: err.rateLimitCode,
|
|
1184
|
+
error_msg: err.rateLimitMessage || err.message,
|
|
1185
|
+
is_rate_limit_error: true
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1130
1188
|
return {
|
|
1131
1189
|
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
1132
1190
|
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -1195,13 +1253,15 @@ var DebugController = class _DebugController {
|
|
|
1195
1253
|
return;
|
|
1196
1254
|
}
|
|
1197
1255
|
case "error": {
|
|
1256
|
+
const isRateLimitError = event.error.code === "RATE_LIMIT_EXCEEDED" && !!event.error.rateLimitCode;
|
|
1198
1257
|
const response = {
|
|
1199
1258
|
status_code: ErrorCodes.SUCCESS,
|
|
1200
1259
|
data: {
|
|
1201
1260
|
type: "error",
|
|
1202
1261
|
error: {
|
|
1203
|
-
code:
|
|
1204
|
-
message: event.error.message
|
|
1262
|
+
code: isRateLimitError ? event.error.rateLimitCode : event.error.code,
|
|
1263
|
+
message: isRateLimitError ? event.error.rateLimitMessage : event.error.message,
|
|
1264
|
+
isRateLimitError: isRateLimitError || void 0
|
|
1205
1265
|
}
|
|
1206
1266
|
}
|
|
1207
1267
|
};
|
|
@@ -1228,14 +1288,16 @@ var DebugController = class _DebugController {
|
|
|
1228
1288
|
}
|
|
1229
1289
|
res.end();
|
|
1230
1290
|
} catch (error) {
|
|
1231
|
-
const
|
|
1291
|
+
const err = error;
|
|
1292
|
+
const isRateLimitError = err?.code === "RATE_LIMIT_EXCEEDED" && !!err?.rateLimitCode;
|
|
1232
1293
|
const response = {
|
|
1233
1294
|
status_code: ErrorCodes.SUCCESS,
|
|
1234
1295
|
data: {
|
|
1235
1296
|
type: "error",
|
|
1236
1297
|
error: {
|
|
1237
|
-
code:
|
|
1238
|
-
message:
|
|
1298
|
+
code: isRateLimitError ? err.rateLimitCode : err?.code ?? "EXECUTION_ERROR",
|
|
1299
|
+
message: isRateLimitError ? err.rateLimitMessage : error instanceof Error ? error.message : String(error),
|
|
1300
|
+
isRateLimitError: isRateLimitError || void 0
|
|
1239
1301
|
}
|
|
1240
1302
|
}
|
|
1241
1303
|
};
|
|
@@ -1379,6 +1441,14 @@ var WebhookController = class _WebhookController {
|
|
|
1379
1441
|
error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
|
|
1380
1442
|
};
|
|
1381
1443
|
}
|
|
1444
|
+
const err = error;
|
|
1445
|
+
if (err?.code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
|
|
1446
|
+
return {
|
|
1447
|
+
status_code: err.rateLimitCode,
|
|
1448
|
+
error_msg: err.rateLimitMessage || err.message,
|
|
1449
|
+
is_rate_limit_error: true
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1382
1452
|
return {
|
|
1383
1453
|
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
1384
1454
|
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -1441,13 +1511,15 @@ var WebhookController = class _WebhookController {
|
|
|
1441
1511
|
return;
|
|
1442
1512
|
}
|
|
1443
1513
|
case "error": {
|
|
1514
|
+
const isRateLimitError = event.error.code === "RATE_LIMIT_EXCEEDED" && !!event.error.rateLimitCode;
|
|
1444
1515
|
const response = {
|
|
1445
1516
|
status_code: ErrorCodes.SUCCESS,
|
|
1446
1517
|
data: {
|
|
1447
1518
|
type: "error",
|
|
1448
1519
|
error: {
|
|
1449
|
-
code:
|
|
1450
|
-
message: event.error.message
|
|
1520
|
+
code: isRateLimitError ? event.error.rateLimitCode : event.error.code,
|
|
1521
|
+
message: isRateLimitError ? event.error.rateLimitMessage : event.error.message,
|
|
1522
|
+
isRateLimitError: isRateLimitError || void 0
|
|
1451
1523
|
}
|
|
1452
1524
|
}
|
|
1453
1525
|
};
|
|
@@ -1474,14 +1546,16 @@ var WebhookController = class _WebhookController {
|
|
|
1474
1546
|
}
|
|
1475
1547
|
res.end();
|
|
1476
1548
|
} catch (error) {
|
|
1477
|
-
const
|
|
1549
|
+
const err = error;
|
|
1550
|
+
const isRateLimitError = err?.code === "RATE_LIMIT_EXCEEDED" && !!err?.rateLimitCode;
|
|
1478
1551
|
const response = {
|
|
1479
1552
|
status_code: ErrorCodes.SUCCESS,
|
|
1480
1553
|
data: {
|
|
1481
1554
|
type: "error",
|
|
1482
1555
|
error: {
|
|
1483
|
-
code:
|
|
1484
|
-
message:
|
|
1556
|
+
code: isRateLimitError ? err.rateLimitCode : err?.code ?? "EXECUTION_ERROR",
|
|
1557
|
+
message: isRateLimitError ? err.rateLimitMessage : error instanceof Error ? error.message : String(error),
|
|
1558
|
+
isRateLimitError: isRateLimitError || void 0
|
|
1485
1559
|
}
|
|
1486
1560
|
}
|
|
1487
1561
|
};
|
|
@@ -1576,8 +1650,8 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
1576
1650
|
},
|
|
1577
1651
|
{
|
|
1578
1652
|
provide: CapabilityService,
|
|
1579
|
-
useFactory: /* @__PURE__ */ __name((requestContextService,
|
|
1580
|
-
const service = new CapabilityService(requestContextService,
|
|
1653
|
+
useFactory: /* @__PURE__ */ __name((requestContextService, httpClientFactory, pluginLoader, templateEngine, moduleOptions) => {
|
|
1654
|
+
const service = new CapabilityService(requestContextService, httpClientFactory, pluginLoader, templateEngine);
|
|
1581
1655
|
if (moduleOptions) {
|
|
1582
1656
|
service.setOptions(moduleOptions);
|
|
1583
1657
|
}
|
|
@@ -1585,7 +1659,7 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
1585
1659
|
}, "useFactory"),
|
|
1586
1660
|
inject: [
|
|
1587
1661
|
import_nestjs_common2.RequestContextService,
|
|
1588
|
-
import_nestjs_common2.
|
|
1662
|
+
import_nestjs_common2.HTTP_CLIENT_FACTORY,
|
|
1589
1663
|
PluginLoaderService,
|
|
1590
1664
|
TemplateEngineService,
|
|
1591
1665
|
CAPABILITY_OPTIONS
|