@axiom-lattice/gateway 2.1.97 → 2.1.98
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/.turbo/turbo-build.log +18 -14
- package/CHANGELOG.md +12 -0
- package/dist/WechatChannelAdapter-QQYOHZTL.mjs +249 -0
- package/dist/WechatChannelAdapter-QQYOHZTL.mjs.map +1 -0
- package/dist/chunk-6CUQGDJI.mjs +238 -0
- package/dist/chunk-6CUQGDJI.mjs.map +1 -0
- package/dist/index.js +828 -355
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -145
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/channels/lark/LarkChannelAdapter.ts +20 -0
- package/src/channels/routes.ts +2 -0
- package/src/channels/wechat/WechatChannelAdapter.ts +294 -0
- package/src/channels/wechat/context-store.ts +47 -0
- package/src/channels/wechat/controller.ts +59 -0
- package/src/channels/wechat/routes.ts +7 -0
- package/src/channels/wechat/types.ts +62 -0
- package/src/channels/wechat/wechat-client.ts +162 -0
- package/src/controllers/__tests__/run.test.ts +1 -1
- package/src/controllers/__tests__/tasks.test.ts +6 -6
- package/src/controllers/channel-installations.ts +52 -0
- package/src/controllers/database-configs.ts +1 -1
- package/src/controllers/metrics-configs.ts +1 -1
- package/src/controllers/workspace.ts +2 -2
- package/src/index.ts +9 -5
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Logger,
|
|
3
|
+
getQrCode,
|
|
4
|
+
getQrCodeStatus
|
|
5
|
+
} from "./chunk-6CUQGDJI.mjs";
|
|
6
|
+
|
|
1
7
|
// src/index.ts
|
|
2
8
|
import fastify from "fastify";
|
|
3
9
|
import cors from "@fastify/cors";
|
|
@@ -3487,7 +3493,7 @@ var WorkspaceController = class {
|
|
|
3487
3493
|
}
|
|
3488
3494
|
const inferredContentType = this.getMimeType(filename2);
|
|
3489
3495
|
try {
|
|
3490
|
-
|
|
3496
|
+
const contentType = inferredContentType;
|
|
3491
3497
|
const isHtml = contentType?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
|
|
3492
3498
|
let outputBuf = buf;
|
|
3493
3499
|
if (isHtml) {
|
|
@@ -3599,7 +3605,7 @@ var WorkspaceController = class {
|
|
|
3599
3605
|
const filename = data.filename || "file";
|
|
3600
3606
|
const pathEntry = data.fields?.path;
|
|
3601
3607
|
const pathValue = pathEntry && typeof pathEntry === "object" && "value" in pathEntry ? String(pathEntry.value) : typeof pathEntry === "string" ? pathEntry : void 0;
|
|
3602
|
-
if (pathValue && !/^[a-zA-Z0-9_
|
|
3608
|
+
if (pathValue && !/^[a-zA-Z0-9_./~-]+$/.test(pathValue)) {
|
|
3603
3609
|
return reply.status(400).send({ success: false, error: "Invalid path parameter" });
|
|
3604
3610
|
}
|
|
3605
3611
|
if (workspace.storageType === "sandbox") {
|
|
@@ -6167,144 +6173,6 @@ function normalizeChatType(chatType) {
|
|
|
6167
6173
|
return chatType === "p2p" ? "direct" : "group";
|
|
6168
6174
|
}
|
|
6169
6175
|
|
|
6170
|
-
// src/logger/Logger.ts
|
|
6171
|
-
import pino from "pino";
|
|
6172
|
-
import "pino-pretty";
|
|
6173
|
-
import "pino-roll";
|
|
6174
|
-
var PinoLoggerFactory = class _PinoLoggerFactory {
|
|
6175
|
-
constructor() {
|
|
6176
|
-
const isProd = process.env.NODE_ENV === "production";
|
|
6177
|
-
const loggerConfig = {
|
|
6178
|
-
// 自定义时间戳格式
|
|
6179
|
-
timestamp: () => `,"@timestamp":"${(/* @__PURE__ */ new Date()).toISOString()}"`,
|
|
6180
|
-
// 关闭默认的时间戳键
|
|
6181
|
-
base: {
|
|
6182
|
-
"@version": "1",
|
|
6183
|
-
app_name: "lattice",
|
|
6184
|
-
service_name: "lattice/graph-server",
|
|
6185
|
-
thread_name: "main",
|
|
6186
|
-
logger_name: "lattice-graph-logger"
|
|
6187
|
-
},
|
|
6188
|
-
formatters: {
|
|
6189
|
-
level: (label, number) => {
|
|
6190
|
-
return {
|
|
6191
|
-
level: label.toUpperCase(),
|
|
6192
|
-
level_value: number * 1e3
|
|
6193
|
-
};
|
|
6194
|
-
}
|
|
6195
|
-
}
|
|
6196
|
-
};
|
|
6197
|
-
if (isProd) {
|
|
6198
|
-
try {
|
|
6199
|
-
this.pinoLogger = pino(
|
|
6200
|
-
loggerConfig,
|
|
6201
|
-
pino.transport({
|
|
6202
|
-
target: "pino-roll",
|
|
6203
|
-
options: {
|
|
6204
|
-
file: "./logs/fin_ai_graph_server",
|
|
6205
|
-
frequency: "daily",
|
|
6206
|
-
mkdir: true
|
|
6207
|
-
}
|
|
6208
|
-
})
|
|
6209
|
-
);
|
|
6210
|
-
} catch (error) {
|
|
6211
|
-
console.error(
|
|
6212
|
-
"\u65E0\u6CD5\u521D\u59CB\u5316 pino-roll \u65E5\u5FD7\u8BB0\u5F55\u5668\uFF0C\u56DE\u9000\u5230\u63A7\u5236\u53F0\u65E5\u5FD7",
|
|
6213
|
-
error
|
|
6214
|
-
);
|
|
6215
|
-
this.pinoLogger = pino({
|
|
6216
|
-
...loggerConfig,
|
|
6217
|
-
transport: {
|
|
6218
|
-
target: "pino-pretty",
|
|
6219
|
-
options: {
|
|
6220
|
-
colorize: true
|
|
6221
|
-
}
|
|
6222
|
-
}
|
|
6223
|
-
});
|
|
6224
|
-
}
|
|
6225
|
-
} else {
|
|
6226
|
-
this.pinoLogger = pino({
|
|
6227
|
-
...loggerConfig,
|
|
6228
|
-
transport: {
|
|
6229
|
-
target: "pino-pretty",
|
|
6230
|
-
options: {
|
|
6231
|
-
colorize: true
|
|
6232
|
-
}
|
|
6233
|
-
}
|
|
6234
|
-
});
|
|
6235
|
-
}
|
|
6236
|
-
}
|
|
6237
|
-
static getInstance() {
|
|
6238
|
-
if (!_PinoLoggerFactory.instance) {
|
|
6239
|
-
_PinoLoggerFactory.instance = new _PinoLoggerFactory();
|
|
6240
|
-
}
|
|
6241
|
-
return _PinoLoggerFactory.instance;
|
|
6242
|
-
}
|
|
6243
|
-
getPinoLogger() {
|
|
6244
|
-
return this.pinoLogger;
|
|
6245
|
-
}
|
|
6246
|
-
};
|
|
6247
|
-
var Logger = class _Logger {
|
|
6248
|
-
constructor(options) {
|
|
6249
|
-
this.context = options?.context || {};
|
|
6250
|
-
this.name = options?.name || "lattice-graph-logger";
|
|
6251
|
-
this.serviceName = options?.serviceName || "lattice/graph-server";
|
|
6252
|
-
}
|
|
6253
|
-
/**
|
|
6254
|
-
* 获取合并了上下文的日志对象
|
|
6255
|
-
* @param additionalContext 额外的上下文数据
|
|
6256
|
-
* @returns 带有上下文的pino日志对象
|
|
6257
|
-
*/
|
|
6258
|
-
getContextualLogger(additionalContext) {
|
|
6259
|
-
const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();
|
|
6260
|
-
const contextObj = {
|
|
6261
|
-
"x-user-id": this.context["x-user-id"] || "",
|
|
6262
|
-
"x-tenant-id": this.context["x-tenant-id"] || "",
|
|
6263
|
-
"x-request-id": this.context["x-request-id"] || "",
|
|
6264
|
-
"x-task-id": this.context["x-task-id"] || "",
|
|
6265
|
-
"x-thread-id": this.context["x-thread-id"] || "",
|
|
6266
|
-
service_name: this.serviceName,
|
|
6267
|
-
logger_name: this.name,
|
|
6268
|
-
...additionalContext
|
|
6269
|
-
};
|
|
6270
|
-
return pinoLogger.child(contextObj);
|
|
6271
|
-
}
|
|
6272
|
-
info(msg, obj) {
|
|
6273
|
-
this.getContextualLogger(obj).info(msg);
|
|
6274
|
-
}
|
|
6275
|
-
error(msg, obj) {
|
|
6276
|
-
this.getContextualLogger(obj).error(msg);
|
|
6277
|
-
}
|
|
6278
|
-
warn(msg, obj) {
|
|
6279
|
-
this.getContextualLogger(obj).warn(msg);
|
|
6280
|
-
}
|
|
6281
|
-
debug(msg, obj) {
|
|
6282
|
-
this.getContextualLogger(obj).debug(msg);
|
|
6283
|
-
}
|
|
6284
|
-
/**
|
|
6285
|
-
* 更新Logger实例的上下文
|
|
6286
|
-
*/
|
|
6287
|
-
updateContext(context) {
|
|
6288
|
-
this.context = {
|
|
6289
|
-
...this.context,
|
|
6290
|
-
...context
|
|
6291
|
-
};
|
|
6292
|
-
}
|
|
6293
|
-
/**
|
|
6294
|
-
* 创建一个新的Logger实例,继承当前Logger的上下文
|
|
6295
|
-
*/
|
|
6296
|
-
child(options) {
|
|
6297
|
-
return new _Logger({
|
|
6298
|
-
name: options.name || this.name,
|
|
6299
|
-
serviceName: options.serviceName || this.serviceName,
|
|
6300
|
-
context: {
|
|
6301
|
-
...this.context,
|
|
6302
|
-
...options.context
|
|
6303
|
-
}
|
|
6304
|
-
});
|
|
6305
|
-
}
|
|
6306
|
-
};
|
|
6307
|
-
|
|
6308
6176
|
// src/channels/lark/LarkChannelAdapter.ts
|
|
6309
6177
|
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
6310
6178
|
var logger = new Logger({ serviceName: "lattice/gateway/lark" });
|
|
@@ -6437,6 +6305,24 @@ var larkChannelAdapter = {
|
|
|
6437
6305
|
await client.start({ eventDispatcher });
|
|
6438
6306
|
activeConnections.set(installationId, client);
|
|
6439
6307
|
logger.info("Lark WS client connected", { installationId });
|
|
6308
|
+
},
|
|
6309
|
+
async disconnect(installationId) {
|
|
6310
|
+
const client = activeConnections.get(installationId);
|
|
6311
|
+
if (!client) {
|
|
6312
|
+
logger.warn("Lark WS not connected, nothing to disconnect", { installationId });
|
|
6313
|
+
return;
|
|
6314
|
+
}
|
|
6315
|
+
logger.info("Lark WS client disconnecting", { installationId });
|
|
6316
|
+
try {
|
|
6317
|
+
client.close({ force: true });
|
|
6318
|
+
} catch (err) {
|
|
6319
|
+
logger.error("Lark WS client stop error", {
|
|
6320
|
+
installationId,
|
|
6321
|
+
error: err instanceof Error ? err.message : String(err)
|
|
6322
|
+
});
|
|
6323
|
+
}
|
|
6324
|
+
activeConnections.delete(installationId);
|
|
6325
|
+
logger.info("Lark WS client disconnected", { installationId });
|
|
6440
6326
|
}
|
|
6441
6327
|
};
|
|
6442
6328
|
|
|
@@ -6504,9 +6390,62 @@ function registerLarkChannelRoutes(app2, deps) {
|
|
|
6504
6390
|
);
|
|
6505
6391
|
}
|
|
6506
6392
|
|
|
6393
|
+
// src/channels/wechat/controller.ts
|
|
6394
|
+
var qrSessions = /* @__PURE__ */ new Map();
|
|
6395
|
+
var SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
6396
|
+
function cleanupExpiredSessions() {
|
|
6397
|
+
const now = Date.now();
|
|
6398
|
+
for (const [key, session] of qrSessions) {
|
|
6399
|
+
if (now - session.createdAt > SESSION_TTL_MS) {
|
|
6400
|
+
qrSessions.delete(key);
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
async function handleGetQrCode(_request, reply) {
|
|
6405
|
+
try {
|
|
6406
|
+
cleanupExpiredSessions();
|
|
6407
|
+
const { qrcode, qrcodeImgUrl } = await getQrCode();
|
|
6408
|
+
qrSessions.set(qrcode, { qrcode, createdAt: Date.now() });
|
|
6409
|
+
reply.send({ success: true, data: { qrcode, qrcodeImgUrl } });
|
|
6410
|
+
} catch (err) {
|
|
6411
|
+
reply.status(500).send({
|
|
6412
|
+
success: false,
|
|
6413
|
+
message: err instanceof Error ? err.message : "Failed to get QR code"
|
|
6414
|
+
});
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
async function handleGetQrCodeStatus(request, reply) {
|
|
6418
|
+
const { qrcode } = request.query;
|
|
6419
|
+
if (!qrcode) {
|
|
6420
|
+
reply.status(400).send({ success: false, message: "qrcode is required" });
|
|
6421
|
+
return;
|
|
6422
|
+
}
|
|
6423
|
+
const session = qrSessions.get(qrcode);
|
|
6424
|
+
if (!session) {
|
|
6425
|
+
reply.status(404).send({ success: false, message: "Session not found or expired" });
|
|
6426
|
+
return;
|
|
6427
|
+
}
|
|
6428
|
+
try {
|
|
6429
|
+
const result = await getQrCodeStatus(qrcode);
|
|
6430
|
+
reply.send({ success: true, data: result });
|
|
6431
|
+
} catch (err) {
|
|
6432
|
+
reply.status(500).send({
|
|
6433
|
+
success: false,
|
|
6434
|
+
message: err instanceof Error ? err.message : "Failed to check QR status"
|
|
6435
|
+
});
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6438
|
+
|
|
6439
|
+
// src/channels/wechat/routes.ts
|
|
6440
|
+
function registerWechatChannelRoutes(app2) {
|
|
6441
|
+
app2.get("/api/channels/wechat/setup/qrcode", handleGetQrCode);
|
|
6442
|
+
app2.get("/api/channels/wechat/setup/status", handleGetQrCodeStatus);
|
|
6443
|
+
}
|
|
6444
|
+
|
|
6507
6445
|
// src/channels/routes.ts
|
|
6508
6446
|
var channelRouteRegistrars = [
|
|
6509
|
-
(app2, deps) => registerLarkChannelRoutes(app2, deps)
|
|
6447
|
+
(app2, deps) => registerLarkChannelRoutes(app2, deps),
|
|
6448
|
+
(app2, _deps) => registerWechatChannelRoutes(app2)
|
|
6510
6449
|
];
|
|
6511
6450
|
function registerChannelRoutes(app2, dependencies) {
|
|
6512
6451
|
if (!dependencies) return;
|
|
@@ -6517,6 +6456,12 @@ function registerChannelRoutes(app2, dependencies) {
|
|
|
6517
6456
|
|
|
6518
6457
|
// src/controllers/channel-installations.ts
|
|
6519
6458
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
6459
|
+
var _adapterRegistry;
|
|
6460
|
+
var _router;
|
|
6461
|
+
function setChannelControllerDeps(deps) {
|
|
6462
|
+
_adapterRegistry = deps.adapterRegistry;
|
|
6463
|
+
_router = deps.router;
|
|
6464
|
+
}
|
|
6520
6465
|
function getTenantId13(request) {
|
|
6521
6466
|
const userTenantId = request.user?.tenantId;
|
|
6522
6467
|
if (userTenantId) {
|
|
@@ -6638,6 +6583,16 @@ async function createChannelInstallation(request, reply) {
|
|
|
6638
6583
|
installationId,
|
|
6639
6584
|
body
|
|
6640
6585
|
);
|
|
6586
|
+
if (body.enabled !== false && _adapterRegistry) {
|
|
6587
|
+
const adapter = _adapterRegistry.get(body.channel);
|
|
6588
|
+
if (adapter?.connect) {
|
|
6589
|
+
try {
|
|
6590
|
+
await adapter.connect(installation, { router: _router });
|
|
6591
|
+
} catch (err) {
|
|
6592
|
+
console.error("Failed to start channel connection after creation:", err);
|
|
6593
|
+
}
|
|
6594
|
+
}
|
|
6595
|
+
}
|
|
6641
6596
|
reply.code(201);
|
|
6642
6597
|
return {
|
|
6643
6598
|
success: true,
|
|
@@ -6692,6 +6647,14 @@ async function updateChannelInstallation(request, reply) {
|
|
|
6692
6647
|
message: "Channel installation not found"
|
|
6693
6648
|
};
|
|
6694
6649
|
}
|
|
6650
|
+
if (body.enabled !== void 0 && body.enabled !== existing.enabled) {
|
|
6651
|
+
const adapter = _adapterRegistry?.get(existing.channel);
|
|
6652
|
+
if (body.enabled && adapter?.connect) {
|
|
6653
|
+
await adapter.connect(installation, { router: _router });
|
|
6654
|
+
} else if (!body.enabled && adapter?.disconnect) {
|
|
6655
|
+
await adapter.disconnect(installationId);
|
|
6656
|
+
}
|
|
6657
|
+
}
|
|
6695
6658
|
return {
|
|
6696
6659
|
success: true,
|
|
6697
6660
|
message: "Channel installation updated successfully",
|
|
@@ -6725,6 +6688,16 @@ async function deleteChannelInstallation(request, reply) {
|
|
|
6725
6688
|
message: "Access denied"
|
|
6726
6689
|
};
|
|
6727
6690
|
}
|
|
6691
|
+
if (_adapterRegistry) {
|
|
6692
|
+
const adapter = _adapterRegistry.get(existing.channel);
|
|
6693
|
+
if (adapter?.disconnect) {
|
|
6694
|
+
try {
|
|
6695
|
+
await adapter.disconnect(installationId);
|
|
6696
|
+
} catch (err) {
|
|
6697
|
+
console.error("Failed to disconnect channel adapter:", err);
|
|
6698
|
+
}
|
|
6699
|
+
}
|
|
6700
|
+
}
|
|
6728
6701
|
const deleted = await store.deleteInstallation(tenantId, installationId);
|
|
6729
6702
|
if (!deleted) {
|
|
6730
6703
|
reply.code(404);
|
|
@@ -8337,12 +8310,12 @@ var start = async (config) => {
|
|
|
8337
8310
|
let channelDeps;
|
|
8338
8311
|
const adapterRegistry = new ChannelAdapterRegistry();
|
|
8339
8312
|
adapterRegistry.register(larkChannelAdapter);
|
|
8313
|
+
const { wechatChannelAdapter } = await import("./WechatChannelAdapter-QQYOHZTL.mjs");
|
|
8314
|
+
adapterRegistry.register(wechatChannelAdapter);
|
|
8340
8315
|
try {
|
|
8341
8316
|
const { getStoreLattice: getStore2 } = await import("@axiom-lattice/core");
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
bindingStore = getStore2("default", "channelBinding").store;
|
|
8345
|
-
installationStore = getStore2("default", "channelInstallation").store;
|
|
8317
|
+
const bindingStore = getStore2("default", "channelBinding").store;
|
|
8318
|
+
const installationStore = getStore2("default", "channelInstallation").store;
|
|
8346
8319
|
setBindingRegistry(bindingStore);
|
|
8347
8320
|
const router = new MessageRouter({
|
|
8348
8321
|
middlewares: [
|
|
@@ -8374,6 +8347,9 @@ var start = async (config) => {
|
|
|
8374
8347
|
logger4.info("Menu registry initialized");
|
|
8375
8348
|
} catch {
|
|
8376
8349
|
}
|
|
8350
|
+
if (channelDeps?.router) {
|
|
8351
|
+
setChannelControllerDeps({ adapterRegistry, router: channelDeps.router });
|
|
8352
|
+
}
|
|
8377
8353
|
registerLatticeRoutes(app, channelDeps);
|
|
8378
8354
|
if (!sandboxLatticeManager2.hasLattice("default")) {
|
|
8379
8355
|
sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
|