imean-service-engine 1.7.3 → 1.8.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/mod.cjs +43 -151
- package/dist/mod.d.cts +6 -15
- package/dist/mod.d.ts +6 -15
- package/dist/mod.js +44 -151
- package/package.json +86 -87
package/dist/mod.cjs
CHANGED
@@ -14,10 +14,6 @@ var prettier = require('prettier');
|
|
14
14
|
var crypto2 = require('crypto');
|
15
15
|
var zlib = require('zlib');
|
16
16
|
var nodeWs = require('@hono/node-ws');
|
17
|
-
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
18
|
-
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
19
|
-
var streaming = require('hono/streaming');
|
20
|
-
var ulid = require('ulid');
|
21
17
|
var html = require('hono/html');
|
22
18
|
var jsxRuntime = require('hono/jsx/jsx-runtime');
|
23
19
|
var dayjs = require('dayjs');
|
@@ -92,8 +88,7 @@ function Action(options) {
|
|
92
88
|
printError: options.printError ?? false,
|
93
89
|
cache: options.cache,
|
94
90
|
ttl: options.ttl,
|
95
|
-
stream: options.stream
|
96
|
-
mcp: options.mcp
|
91
|
+
stream: options.stream
|
97
92
|
};
|
98
93
|
prototype[ACTION_METADATA] = existingMetadata;
|
99
94
|
});
|
@@ -471,14 +466,14 @@ var ActionHandler = class {
|
|
471
466
|
this.microservice = microservice;
|
472
467
|
this.moduleName = moduleName;
|
473
468
|
}
|
474
|
-
async handle(req) {
|
469
|
+
async handle(req, ctx) {
|
475
470
|
return await tracer2.startActiveSpan(
|
476
471
|
`handle ${this.moduleName}.${this.actionName}`,
|
477
472
|
async (span) => {
|
478
473
|
span.setAttribute("module", this.moduleName);
|
479
474
|
span.setAttribute("action", this.actionName);
|
480
475
|
try {
|
481
|
-
return await this._handle(req);
|
476
|
+
return await this._handle(req, ctx);
|
482
477
|
} catch (error) {
|
483
478
|
span.recordException(error);
|
484
479
|
span.setStatus({
|
@@ -523,7 +518,7 @@ var ActionHandler = class {
|
|
523
518
|
span.end();
|
524
519
|
}
|
525
520
|
}
|
526
|
-
async _handle(req) {
|
521
|
+
async _handle(req, ctx) {
|
527
522
|
const span = api.trace.getActiveSpan();
|
528
523
|
const { args, requestHash } = await this._validate(req);
|
529
524
|
const cacheHash = typeof this.metadata.cache === "function" ? this.metadata.cache(...args) : requestHash;
|
@@ -541,7 +536,7 @@ var ActionHandler = class {
|
|
541
536
|
try {
|
542
537
|
const result = await this.moduleInstance[this.actionName].apply(
|
543
538
|
this.moduleInstance,
|
544
|
-
args
|
539
|
+
args.concat(ctx)
|
545
540
|
);
|
546
541
|
if (this.metadata.stream) {
|
547
542
|
span?.setAttribute("stream", true);
|
@@ -610,9 +605,10 @@ function Page(options) {
|
|
610
605
|
existingMetadata[methodName] = {
|
611
606
|
name: methodName,
|
612
607
|
description: options.description || "",
|
613
|
-
method: options.method,
|
608
|
+
method: options.method || "get",
|
614
609
|
path: normalizePath(options.path),
|
615
|
-
absolutePath: options.absolutePath ?? false
|
610
|
+
absolutePath: options.absolutePath ?? false,
|
611
|
+
middlewares: options.middlewares ?? []
|
616
612
|
};
|
617
613
|
prototype[PAGE_METADATA] = existingMetadata;
|
618
614
|
});
|
@@ -667,8 +663,9 @@ var PageHandler = class {
|
|
667
663
|
}
|
668
664
|
};
|
669
665
|
var WebSocketHandler = class {
|
670
|
-
constructor(microservice, options) {
|
666
|
+
constructor(microservice, ctx, options) {
|
671
667
|
this.microservice = microservice;
|
668
|
+
this.ctx = ctx;
|
672
669
|
this.options = {
|
673
670
|
timeout: options?.timeout || 3e4
|
674
671
|
};
|
@@ -708,7 +705,7 @@ var WebSocketHandler = class {
|
|
708
705
|
await this.sendMessage(ws, { type: "pong" });
|
709
706
|
return;
|
710
707
|
}
|
711
|
-
const response = await this.handleRequest(ws, message);
|
708
|
+
const response = await this.handleRequest(ws, message, this.ctx);
|
712
709
|
if (response) {
|
713
710
|
await this.sendMessage(ws, response);
|
714
711
|
}
|
@@ -735,7 +732,7 @@ var WebSocketHandler = class {
|
|
735
732
|
onError(_error, ws) {
|
736
733
|
this.onClose(ws);
|
737
734
|
}
|
738
|
-
async handleRequest(ws, message) {
|
735
|
+
async handleRequest(ws, message, ctx) {
|
739
736
|
if (!message.id || !message.module || !message.action) {
|
740
737
|
throw new Error("Invalid request message");
|
741
738
|
}
|
@@ -771,7 +768,7 @@ var WebSocketHandler = class {
|
|
771
768
|
message.action
|
772
769
|
);
|
773
770
|
const args = message.args ? Object.values(message.args) : [];
|
774
|
-
const result = await handler.handle(args);
|
771
|
+
const result = await handler.handle(args, ctx);
|
775
772
|
if (handler.metadata.stream) {
|
776
773
|
try {
|
777
774
|
for await (const value of result) {
|
@@ -932,20 +929,20 @@ var Microservice = class {
|
|
932
929
|
);
|
933
930
|
this.actionHandlers.set(`${moduleName}.${actionName}`, handler);
|
934
931
|
logger_default.info(
|
935
|
-
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}
|
932
|
+
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}`
|
936
933
|
);
|
937
934
|
}
|
938
935
|
for (const [_, page] of Object.entries(pages)) {
|
939
|
-
const handler = new PageHandler(
|
940
|
-
moduleInstance,
|
941
|
-
page,
|
942
|
-
moduleName
|
943
|
-
);
|
936
|
+
const handler = new PageHandler(moduleInstance, page, moduleName);
|
944
937
|
this.pageHandlers.set(`${moduleName}.${page.name}`, handler);
|
945
938
|
const paths = Array.isArray(page.path) ? page.path : [page.path];
|
946
939
|
for (let path of paths) {
|
947
940
|
path = page.absolutePath ? path : `${this.options.prefix}${path}`;
|
948
|
-
this.app[page.method](
|
941
|
+
this.app[page.method](
|
942
|
+
path,
|
943
|
+
...page.middlewares ?? [],
|
944
|
+
(ctx) => handler.handle(ctx)
|
945
|
+
);
|
949
946
|
logger_default.info(
|
950
947
|
`[ \u6CE8\u518C\u9875\u9762 ] ${moduleName}.${page.name} ${page.method.toUpperCase()} ${page.path} ${page.description}`
|
951
948
|
);
|
@@ -1007,11 +1004,10 @@ var Microservice = class {
|
|
1007
1004
|
});
|
1008
1005
|
this.app.post(`${prefix}/:moduleName/:actionName`, this.handleRequest);
|
1009
1006
|
if (this.options.websocket?.enabled) {
|
1010
|
-
this.wsHandler = new WebSocketHandler(this);
|
1011
1007
|
this.app.get(
|
1012
1008
|
`${prefix}/ws`,
|
1013
|
-
this.nodeWebSocket.upgradeWebSocket((
|
1014
|
-
const wsHandler = new WebSocketHandler(this, {
|
1009
|
+
this.nodeWebSocket.upgradeWebSocket((ctx) => {
|
1010
|
+
const wsHandler = new WebSocketHandler(this, ctx, {
|
1015
1011
|
timeout: this.options.websocket?.timeout
|
1016
1012
|
});
|
1017
1013
|
return {
|
@@ -1233,7 +1229,9 @@ Received SIGTERM signal`);
|
|
1233
1229
|
async waitForActiveRequests() {
|
1234
1230
|
const timeout = this.options.gracefulShutdown?.timeout || 3e4;
|
1235
1231
|
const startTime = Date.now();
|
1236
|
-
logger_default.info(
|
1232
|
+
logger_default.info(
|
1233
|
+
`Waiting for ${this.activeRequests.size} active requests to complete...`
|
1234
|
+
);
|
1237
1235
|
return new Promise((resolve) => {
|
1238
1236
|
const checkInterval = setInterval(() => {
|
1239
1237
|
const elapsed = Date.now() - startTime;
|
@@ -1243,10 +1241,14 @@ Received SIGTERM signal`);
|
|
1243
1241
|
resolve();
|
1244
1242
|
} else if (elapsed >= timeout) {
|
1245
1243
|
clearInterval(checkInterval);
|
1246
|
-
logger_default.warn(
|
1244
|
+
logger_default.warn(
|
1245
|
+
`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`
|
1246
|
+
);
|
1247
1247
|
resolve();
|
1248
1248
|
} else {
|
1249
|
-
logger_default.info(
|
1249
|
+
logger_default.info(
|
1250
|
+
`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`
|
1251
|
+
);
|
1250
1252
|
}
|
1251
1253
|
}, 1e3);
|
1252
1254
|
});
|
@@ -1268,7 +1270,10 @@ Received SIGTERM signal`);
|
|
1268
1270
|
await Promise.race([
|
1269
1271
|
Promise.resolve(hook.cleanup()),
|
1270
1272
|
new Promise(
|
1271
|
-
(_, reject) => setTimeout(
|
1273
|
+
(_, reject) => setTimeout(
|
1274
|
+
() => reject(new Error(`Cleanup hook ${hook.name} timeout`)),
|
1275
|
+
timeout
|
1276
|
+
)
|
1272
1277
|
)
|
1273
1278
|
]);
|
1274
1279
|
logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
|
@@ -1349,10 +1354,13 @@ Received SIGTERM signal`);
|
|
1349
1354
|
const requestId = crypto.randomUUID();
|
1350
1355
|
const startTime = Date.now();
|
1351
1356
|
if (this.status === "shutting_down") {
|
1352
|
-
return ctx.json(
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1357
|
+
return ctx.json(
|
1358
|
+
{
|
1359
|
+
success: false,
|
1360
|
+
error: "Service is shutting down"
|
1361
|
+
},
|
1362
|
+
503
|
1363
|
+
);
|
1356
1364
|
}
|
1357
1365
|
try {
|
1358
1366
|
const paramsText = await ctx.req.text();
|
@@ -1363,7 +1371,7 @@ Received SIGTERM signal`);
|
|
1363
1371
|
startTime,
|
1364
1372
|
params: paramsText
|
1365
1373
|
});
|
1366
|
-
const result = await handler.handle(paramsText);
|
1374
|
+
const result = await handler.handle(paramsText, ctx);
|
1367
1375
|
if (handler.metadata.stream) {
|
1368
1376
|
const encoder = new TextEncoder();
|
1369
1377
|
const microservice = this;
|
@@ -1422,121 +1430,6 @@ Received SIGTERM signal`);
|
|
1422
1430
|
await this.waitingInitialization;
|
1423
1431
|
}
|
1424
1432
|
};
|
1425
|
-
var HonoTransport = class {
|
1426
|
-
constructor(url, stream, closeStream) {
|
1427
|
-
this.url = url;
|
1428
|
-
this.stream = stream;
|
1429
|
-
this.closeStream = closeStream;
|
1430
|
-
this.sessionId = ulid.ulid();
|
1431
|
-
}
|
1432
|
-
sessionId;
|
1433
|
-
onclose;
|
1434
|
-
onerror;
|
1435
|
-
onmessage;
|
1436
|
-
async start() {
|
1437
|
-
await this.stream.writeSSE({
|
1438
|
-
event: "endpoint",
|
1439
|
-
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1440
|
-
});
|
1441
|
-
this.stream.onAbort(() => {
|
1442
|
-
this.close();
|
1443
|
-
});
|
1444
|
-
}
|
1445
|
-
async handleMessage(message) {
|
1446
|
-
let parsedMessage;
|
1447
|
-
try {
|
1448
|
-
parsedMessage = types_js.JSONRPCMessageSchema.parse(message);
|
1449
|
-
} catch (error) {
|
1450
|
-
this.onerror?.(error);
|
1451
|
-
throw error;
|
1452
|
-
}
|
1453
|
-
this.onmessage?.(parsedMessage);
|
1454
|
-
}
|
1455
|
-
async send(message) {
|
1456
|
-
await this.stream.writeln(
|
1457
|
-
`event: message
|
1458
|
-
data: ${JSON.stringify(message)}
|
1459
|
-
|
1460
|
-
`
|
1461
|
-
);
|
1462
|
-
}
|
1463
|
-
async close() {
|
1464
|
-
this.onclose?.();
|
1465
|
-
this.closeStream();
|
1466
|
-
}
|
1467
|
-
};
|
1468
|
-
var ModelContextProtocolPlugin = class extends Plugin {
|
1469
|
-
mcpServer;
|
1470
|
-
transports = {};
|
1471
|
-
registerMcpTools(engine) {
|
1472
|
-
const modules = engine.getModules(true);
|
1473
|
-
for (const module of Object.values(modules)) {
|
1474
|
-
for (const action of Object.values(module.actions)) {
|
1475
|
-
if (action.mcp?.type !== "tool") {
|
1476
|
-
continue;
|
1477
|
-
}
|
1478
|
-
const args = {};
|
1479
|
-
const argsIndex = {};
|
1480
|
-
for (const [index, param] of (action.params ?? []).entries()) {
|
1481
|
-
args[param.description] = param;
|
1482
|
-
argsIndex[param.description] = index;
|
1483
|
-
}
|
1484
|
-
this.mcpServer.tool(
|
1485
|
-
`${module.name}.${action.name}`,
|
1486
|
-
action.description ?? "",
|
1487
|
-
args,
|
1488
|
-
async (params) => {
|
1489
|
-
const argsList = [];
|
1490
|
-
for (const [key, value] of Object.entries(params)) {
|
1491
|
-
argsList[argsIndex[key]] = value;
|
1492
|
-
}
|
1493
|
-
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1494
|
-
return {
|
1495
|
-
content: [{ type: "text", text: JSON.stringify(result) }]
|
1496
|
-
};
|
1497
|
-
}
|
1498
|
-
);
|
1499
|
-
}
|
1500
|
-
}
|
1501
|
-
}
|
1502
|
-
initialize = async (engine) => {
|
1503
|
-
const app = engine.getApp();
|
1504
|
-
this.mcpServer = new mcp_js.McpServer({
|
1505
|
-
name: engine.options.name,
|
1506
|
-
version: engine.options.version
|
1507
|
-
});
|
1508
|
-
this.registerMcpTools(engine);
|
1509
|
-
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1510
|
-
return streaming.streamSSE(ctx, async (stream) => {
|
1511
|
-
return new Promise(async (resolve) => {
|
1512
|
-
const transport = new HonoTransport(
|
1513
|
-
`${engine.options.prefix}/mcp_messages`,
|
1514
|
-
stream,
|
1515
|
-
() => {
|
1516
|
-
delete this.transports[transport.sessionId];
|
1517
|
-
resolve();
|
1518
|
-
}
|
1519
|
-
);
|
1520
|
-
this.transports[transport.sessionId] = transport;
|
1521
|
-
await this.mcpServer.connect(transport);
|
1522
|
-
});
|
1523
|
-
});
|
1524
|
-
});
|
1525
|
-
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1526
|
-
const sessionId = ctx.req.query("sessionId");
|
1527
|
-
if (!sessionId) {
|
1528
|
-
return ctx.text("No transport found for sessionId", 400);
|
1529
|
-
}
|
1530
|
-
const transport = this.transports[sessionId];
|
1531
|
-
const message = await ctx.req.json();
|
1532
|
-
await transport.handleMessage(message);
|
1533
|
-
return ctx.text("Accepted", 202);
|
1534
|
-
});
|
1535
|
-
logger_default.info(
|
1536
|
-
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1537
|
-
);
|
1538
|
-
};
|
1539
|
-
};
|
1540
1433
|
var DEFAULT_FAVICON = /* @__PURE__ */ jsxRuntime.jsx(
|
1541
1434
|
"link",
|
1542
1435
|
{
|
@@ -1749,7 +1642,6 @@ exports.CacheAdapter = CacheAdapter;
|
|
1749
1642
|
exports.HtmxLayout = HtmxLayout;
|
1750
1643
|
exports.MemoryCacheAdapter = MemoryCacheAdapter;
|
1751
1644
|
exports.Microservice = Microservice;
|
1752
|
-
exports.ModelContextProtocolPlugin = ModelContextProtocolPlugin;
|
1753
1645
|
exports.Module = Module;
|
1754
1646
|
exports.Page = Page;
|
1755
1647
|
exports.PageRenderPlugin = PageRenderPlugin;
|
package/dist/mod.d.cts
CHANGED
@@ -3,7 +3,7 @@ export * from 'zod';
|
|
3
3
|
import { Redis, Cluster } from 'ioredis';
|
4
4
|
import { LRUCache } from 'lru-cache';
|
5
5
|
import { Lease, Etcd3 } from 'etcd3';
|
6
|
-
import { Hono } from 'hono';
|
6
|
+
import { MiddlewareHandler, Context, Hono } from 'hono';
|
7
7
|
export { default as dayjs } from 'dayjs';
|
8
8
|
import winston from 'winston';
|
9
9
|
import * as hono_utils_html from 'hono/utils/html';
|
@@ -27,9 +27,6 @@ declare class MemoryCacheAdapter extends CacheAdapter {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
type CacheFn = (...args: any[]) => any;
|
30
|
-
type McpOptions = {
|
31
|
-
type: "tool";
|
32
|
-
};
|
33
30
|
interface ActionOptions {
|
34
31
|
params?: z.ZodType<any>[];
|
35
32
|
returns?: z.ZodType<any>;
|
@@ -39,16 +36,17 @@ interface ActionOptions {
|
|
39
36
|
cache?: boolean | CacheFn;
|
40
37
|
ttl?: number;
|
41
38
|
stream?: boolean;
|
42
|
-
mcp?: McpOptions;
|
43
39
|
}
|
44
40
|
interface PageOptions {
|
45
|
-
method
|
41
|
+
method?: "get" | "post" | "put" | "delete" | "patch" | "options";
|
42
|
+
middlewares?: MiddlewareHandler[];
|
46
43
|
path: string | string[];
|
47
44
|
absolutePath?: boolean;
|
48
45
|
description?: string;
|
49
46
|
}
|
50
47
|
interface PageMetadata extends PageOptions {
|
51
48
|
name: string;
|
49
|
+
method: "get" | "post" | "put" | "delete" | "patch" | "options";
|
52
50
|
}
|
53
51
|
interface ActionMetadata extends ActionOptions {
|
54
52
|
name: string;
|
@@ -213,7 +211,7 @@ declare class ActionHandler {
|
|
213
211
|
private microservice;
|
214
212
|
private moduleName;
|
215
213
|
constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
|
216
|
-
handle(req: string | any[]): Promise<any>;
|
214
|
+
handle(req: string | any[], ctx: Context): Promise<any>;
|
217
215
|
private _validate;
|
218
216
|
private _handle;
|
219
217
|
}
|
@@ -316,13 +314,6 @@ declare class Microservice {
|
|
316
314
|
init(): Promise<void>;
|
317
315
|
}
|
318
316
|
|
319
|
-
declare class ModelContextProtocolPlugin extends Plugin {
|
320
|
-
private mcpServer;
|
321
|
-
private transports;
|
322
|
-
private registerMcpTools;
|
323
|
-
initialize: (engine: Microservice) => Promise<void>;
|
324
|
-
}
|
325
|
-
|
326
317
|
declare const BaseLayout: (props?: {
|
327
318
|
children?: any;
|
328
319
|
title?: string;
|
@@ -381,4 +372,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
381
372
|
|
382
373
|
declare const logger: winston.Logger;
|
383
374
|
|
384
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout,
|
375
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Page, type PageMetadata, type PageOptions, PageRenderPlugin, type PageRenderPluginOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, ServiceInfoCards, type ServiceStats, ServiceStatusPage, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.d.ts
CHANGED
@@ -3,7 +3,7 @@ export * from 'zod';
|
|
3
3
|
import { Redis, Cluster } from 'ioredis';
|
4
4
|
import { LRUCache } from 'lru-cache';
|
5
5
|
import { Lease, Etcd3 } from 'etcd3';
|
6
|
-
import { Hono } from 'hono';
|
6
|
+
import { MiddlewareHandler, Context, Hono } from 'hono';
|
7
7
|
export { default as dayjs } from 'dayjs';
|
8
8
|
import winston from 'winston';
|
9
9
|
import * as hono_utils_html from 'hono/utils/html';
|
@@ -27,9 +27,6 @@ declare class MemoryCacheAdapter extends CacheAdapter {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
type CacheFn = (...args: any[]) => any;
|
30
|
-
type McpOptions = {
|
31
|
-
type: "tool";
|
32
|
-
};
|
33
30
|
interface ActionOptions {
|
34
31
|
params?: z.ZodType<any>[];
|
35
32
|
returns?: z.ZodType<any>;
|
@@ -39,16 +36,17 @@ interface ActionOptions {
|
|
39
36
|
cache?: boolean | CacheFn;
|
40
37
|
ttl?: number;
|
41
38
|
stream?: boolean;
|
42
|
-
mcp?: McpOptions;
|
43
39
|
}
|
44
40
|
interface PageOptions {
|
45
|
-
method
|
41
|
+
method?: "get" | "post" | "put" | "delete" | "patch" | "options";
|
42
|
+
middlewares?: MiddlewareHandler[];
|
46
43
|
path: string | string[];
|
47
44
|
absolutePath?: boolean;
|
48
45
|
description?: string;
|
49
46
|
}
|
50
47
|
interface PageMetadata extends PageOptions {
|
51
48
|
name: string;
|
49
|
+
method: "get" | "post" | "put" | "delete" | "patch" | "options";
|
52
50
|
}
|
53
51
|
interface ActionMetadata extends ActionOptions {
|
54
52
|
name: string;
|
@@ -213,7 +211,7 @@ declare class ActionHandler {
|
|
213
211
|
private microservice;
|
214
212
|
private moduleName;
|
215
213
|
constructor(moduleInstance: any, actionName: string, metadata: ActionMetadata, microservice: Microservice, moduleName: string);
|
216
|
-
handle(req: string | any[]): Promise<any>;
|
214
|
+
handle(req: string | any[], ctx: Context): Promise<any>;
|
217
215
|
private _validate;
|
218
216
|
private _handle;
|
219
217
|
}
|
@@ -316,13 +314,6 @@ declare class Microservice {
|
|
316
314
|
init(): Promise<void>;
|
317
315
|
}
|
318
316
|
|
319
|
-
declare class ModelContextProtocolPlugin extends Plugin {
|
320
|
-
private mcpServer;
|
321
|
-
private transports;
|
322
|
-
private registerMcpTools;
|
323
|
-
initialize: (engine: Microservice) => Promise<void>;
|
324
|
-
}
|
325
|
-
|
326
317
|
declare const BaseLayout: (props?: {
|
327
318
|
children?: any;
|
328
319
|
title?: string;
|
@@ -381,4 +372,4 @@ declare function Schedule(options: ScheduleOptions): Function;
|
|
381
372
|
|
382
373
|
declare const logger: winston.Logger;
|
383
374
|
|
384
|
-
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout,
|
375
|
+
export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, BaseLayout, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, HtmxLayout, MemoryCacheAdapter, Microservice, type MicroserviceOptions, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Page, type PageMetadata, type PageOptions, PageRenderPlugin, type PageRenderPluginOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, ServiceInfoCards, type ServiceStats, ServiceStatusPage, type StatisticsEvent, type StreamResponse, logger, startCheck };
|
package/dist/mod.js
CHANGED
@@ -14,10 +14,6 @@ import crypto2 from 'node:crypto';
|
|
14
14
|
import { brotliDecompress } from 'node:zlib';
|
15
15
|
import { brotliCompress, constants } from 'zlib';
|
16
16
|
import { createNodeWebSocket } from '@hono/node-ws';
|
17
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
18
|
-
import { JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
|
19
|
-
import { streamSSE } from 'hono/streaming';
|
20
|
-
import { ulid } from 'ulid';
|
21
17
|
import { html } from 'hono/html';
|
22
18
|
import { jsx, jsxs } from 'hono/jsx/jsx-runtime';
|
23
19
|
export { default as dayjs } from 'dayjs';
|
@@ -83,8 +79,7 @@ function Action(options) {
|
|
83
79
|
printError: options.printError ?? false,
|
84
80
|
cache: options.cache,
|
85
81
|
ttl: options.ttl,
|
86
|
-
stream: options.stream
|
87
|
-
mcp: options.mcp
|
82
|
+
stream: options.stream
|
88
83
|
};
|
89
84
|
prototype[ACTION_METADATA] = existingMetadata;
|
90
85
|
});
|
@@ -462,14 +457,14 @@ var ActionHandler = class {
|
|
462
457
|
this.microservice = microservice;
|
463
458
|
this.moduleName = moduleName;
|
464
459
|
}
|
465
|
-
async handle(req) {
|
460
|
+
async handle(req, ctx) {
|
466
461
|
return await tracer2.startActiveSpan(
|
467
462
|
`handle ${this.moduleName}.${this.actionName}`,
|
468
463
|
async (span) => {
|
469
464
|
span.setAttribute("module", this.moduleName);
|
470
465
|
span.setAttribute("action", this.actionName);
|
471
466
|
try {
|
472
|
-
return await this._handle(req);
|
467
|
+
return await this._handle(req, ctx);
|
473
468
|
} catch (error) {
|
474
469
|
span.recordException(error);
|
475
470
|
span.setStatus({
|
@@ -514,7 +509,7 @@ var ActionHandler = class {
|
|
514
509
|
span.end();
|
515
510
|
}
|
516
511
|
}
|
517
|
-
async _handle(req) {
|
512
|
+
async _handle(req, ctx) {
|
518
513
|
const span = trace.getActiveSpan();
|
519
514
|
const { args, requestHash } = await this._validate(req);
|
520
515
|
const cacheHash = typeof this.metadata.cache === "function" ? this.metadata.cache(...args) : requestHash;
|
@@ -532,7 +527,7 @@ var ActionHandler = class {
|
|
532
527
|
try {
|
533
528
|
const result = await this.moduleInstance[this.actionName].apply(
|
534
529
|
this.moduleInstance,
|
535
|
-
args
|
530
|
+
args.concat(ctx)
|
536
531
|
);
|
537
532
|
if (this.metadata.stream) {
|
538
533
|
span?.setAttribute("stream", true);
|
@@ -601,9 +596,10 @@ function Page(options) {
|
|
601
596
|
existingMetadata[methodName] = {
|
602
597
|
name: methodName,
|
603
598
|
description: options.description || "",
|
604
|
-
method: options.method,
|
599
|
+
method: options.method || "get",
|
605
600
|
path: normalizePath(options.path),
|
606
|
-
absolutePath: options.absolutePath ?? false
|
601
|
+
absolutePath: options.absolutePath ?? false,
|
602
|
+
middlewares: options.middlewares ?? []
|
607
603
|
};
|
608
604
|
prototype[PAGE_METADATA] = existingMetadata;
|
609
605
|
});
|
@@ -658,8 +654,9 @@ var PageHandler = class {
|
|
658
654
|
}
|
659
655
|
};
|
660
656
|
var WebSocketHandler = class {
|
661
|
-
constructor(microservice, options) {
|
657
|
+
constructor(microservice, ctx, options) {
|
662
658
|
this.microservice = microservice;
|
659
|
+
this.ctx = ctx;
|
663
660
|
this.options = {
|
664
661
|
timeout: options?.timeout || 3e4
|
665
662
|
};
|
@@ -699,7 +696,7 @@ var WebSocketHandler = class {
|
|
699
696
|
await this.sendMessage(ws, { type: "pong" });
|
700
697
|
return;
|
701
698
|
}
|
702
|
-
const response = await this.handleRequest(ws, message);
|
699
|
+
const response = await this.handleRequest(ws, message, this.ctx);
|
703
700
|
if (response) {
|
704
701
|
await this.sendMessage(ws, response);
|
705
702
|
}
|
@@ -726,7 +723,7 @@ var WebSocketHandler = class {
|
|
726
723
|
onError(_error, ws) {
|
727
724
|
this.onClose(ws);
|
728
725
|
}
|
729
|
-
async handleRequest(ws, message) {
|
726
|
+
async handleRequest(ws, message, ctx) {
|
730
727
|
if (!message.id || !message.module || !message.action) {
|
731
728
|
throw new Error("Invalid request message");
|
732
729
|
}
|
@@ -762,7 +759,7 @@ var WebSocketHandler = class {
|
|
762
759
|
message.action
|
763
760
|
);
|
764
761
|
const args = message.args ? Object.values(message.args) : [];
|
765
|
-
const result = await handler.handle(args);
|
762
|
+
const result = await handler.handle(args, ctx);
|
766
763
|
if (handler.metadata.stream) {
|
767
764
|
try {
|
768
765
|
for await (const value of result) {
|
@@ -923,20 +920,20 @@ var Microservice = class {
|
|
923
920
|
);
|
924
921
|
this.actionHandlers.set(`${moduleName}.${actionName}`, handler);
|
925
922
|
logger_default.info(
|
926
|
-
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}
|
923
|
+
`[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description}`
|
927
924
|
);
|
928
925
|
}
|
929
926
|
for (const [_, page] of Object.entries(pages)) {
|
930
|
-
const handler = new PageHandler(
|
931
|
-
moduleInstance,
|
932
|
-
page,
|
933
|
-
moduleName
|
934
|
-
);
|
927
|
+
const handler = new PageHandler(moduleInstance, page, moduleName);
|
935
928
|
this.pageHandlers.set(`${moduleName}.${page.name}`, handler);
|
936
929
|
const paths = Array.isArray(page.path) ? page.path : [page.path];
|
937
930
|
for (let path of paths) {
|
938
931
|
path = page.absolutePath ? path : `${this.options.prefix}${path}`;
|
939
|
-
this.app[page.method](
|
932
|
+
this.app[page.method](
|
933
|
+
path,
|
934
|
+
...page.middlewares ?? [],
|
935
|
+
(ctx) => handler.handle(ctx)
|
936
|
+
);
|
940
937
|
logger_default.info(
|
941
938
|
`[ \u6CE8\u518C\u9875\u9762 ] ${moduleName}.${page.name} ${page.method.toUpperCase()} ${page.path} ${page.description}`
|
942
939
|
);
|
@@ -998,11 +995,10 @@ var Microservice = class {
|
|
998
995
|
});
|
999
996
|
this.app.post(`${prefix}/:moduleName/:actionName`, this.handleRequest);
|
1000
997
|
if (this.options.websocket?.enabled) {
|
1001
|
-
this.wsHandler = new WebSocketHandler(this);
|
1002
998
|
this.app.get(
|
1003
999
|
`${prefix}/ws`,
|
1004
|
-
this.nodeWebSocket.upgradeWebSocket((
|
1005
|
-
const wsHandler = new WebSocketHandler(this, {
|
1000
|
+
this.nodeWebSocket.upgradeWebSocket((ctx) => {
|
1001
|
+
const wsHandler = new WebSocketHandler(this, ctx, {
|
1006
1002
|
timeout: this.options.websocket?.timeout
|
1007
1003
|
});
|
1008
1004
|
return {
|
@@ -1224,7 +1220,9 @@ Received SIGTERM signal`);
|
|
1224
1220
|
async waitForActiveRequests() {
|
1225
1221
|
const timeout = this.options.gracefulShutdown?.timeout || 3e4;
|
1226
1222
|
const startTime = Date.now();
|
1227
|
-
logger_default.info(
|
1223
|
+
logger_default.info(
|
1224
|
+
`Waiting for ${this.activeRequests.size} active requests to complete...`
|
1225
|
+
);
|
1228
1226
|
return new Promise((resolve) => {
|
1229
1227
|
const checkInterval = setInterval(() => {
|
1230
1228
|
const elapsed = Date.now() - startTime;
|
@@ -1234,10 +1232,14 @@ Received SIGTERM signal`);
|
|
1234
1232
|
resolve();
|
1235
1233
|
} else if (elapsed >= timeout) {
|
1236
1234
|
clearInterval(checkInterval);
|
1237
|
-
logger_default.warn(
|
1235
|
+
logger_default.warn(
|
1236
|
+
`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`
|
1237
|
+
);
|
1238
1238
|
resolve();
|
1239
1239
|
} else {
|
1240
|
-
logger_default.info(
|
1240
|
+
logger_default.info(
|
1241
|
+
`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`
|
1242
|
+
);
|
1241
1243
|
}
|
1242
1244
|
}, 1e3);
|
1243
1245
|
});
|
@@ -1259,7 +1261,10 @@ Received SIGTERM signal`);
|
|
1259
1261
|
await Promise.race([
|
1260
1262
|
Promise.resolve(hook.cleanup()),
|
1261
1263
|
new Promise(
|
1262
|
-
(_, reject) => setTimeout(
|
1264
|
+
(_, reject) => setTimeout(
|
1265
|
+
() => reject(new Error(`Cleanup hook ${hook.name} timeout`)),
|
1266
|
+
timeout
|
1267
|
+
)
|
1263
1268
|
)
|
1264
1269
|
]);
|
1265
1270
|
logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
|
@@ -1340,10 +1345,13 @@ Received SIGTERM signal`);
|
|
1340
1345
|
const requestId = crypto.randomUUID();
|
1341
1346
|
const startTime = Date.now();
|
1342
1347
|
if (this.status === "shutting_down") {
|
1343
|
-
return ctx.json(
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1348
|
+
return ctx.json(
|
1349
|
+
{
|
1350
|
+
success: false,
|
1351
|
+
error: "Service is shutting down"
|
1352
|
+
},
|
1353
|
+
503
|
1354
|
+
);
|
1347
1355
|
}
|
1348
1356
|
try {
|
1349
1357
|
const paramsText = await ctx.req.text();
|
@@ -1354,7 +1362,7 @@ Received SIGTERM signal`);
|
|
1354
1362
|
startTime,
|
1355
1363
|
params: paramsText
|
1356
1364
|
});
|
1357
|
-
const result = await handler.handle(paramsText);
|
1365
|
+
const result = await handler.handle(paramsText, ctx);
|
1358
1366
|
if (handler.metadata.stream) {
|
1359
1367
|
const encoder = new TextEncoder();
|
1360
1368
|
const microservice = this;
|
@@ -1413,121 +1421,6 @@ Received SIGTERM signal`);
|
|
1413
1421
|
await this.waitingInitialization;
|
1414
1422
|
}
|
1415
1423
|
};
|
1416
|
-
var HonoTransport = class {
|
1417
|
-
constructor(url, stream, closeStream) {
|
1418
|
-
this.url = url;
|
1419
|
-
this.stream = stream;
|
1420
|
-
this.closeStream = closeStream;
|
1421
|
-
this.sessionId = ulid();
|
1422
|
-
}
|
1423
|
-
sessionId;
|
1424
|
-
onclose;
|
1425
|
-
onerror;
|
1426
|
-
onmessage;
|
1427
|
-
async start() {
|
1428
|
-
await this.stream.writeSSE({
|
1429
|
-
event: "endpoint",
|
1430
|
-
data: `${encodeURI(this.url)}?sessionId=${this.sessionId}`
|
1431
|
-
});
|
1432
|
-
this.stream.onAbort(() => {
|
1433
|
-
this.close();
|
1434
|
-
});
|
1435
|
-
}
|
1436
|
-
async handleMessage(message) {
|
1437
|
-
let parsedMessage;
|
1438
|
-
try {
|
1439
|
-
parsedMessage = JSONRPCMessageSchema.parse(message);
|
1440
|
-
} catch (error) {
|
1441
|
-
this.onerror?.(error);
|
1442
|
-
throw error;
|
1443
|
-
}
|
1444
|
-
this.onmessage?.(parsedMessage);
|
1445
|
-
}
|
1446
|
-
async send(message) {
|
1447
|
-
await this.stream.writeln(
|
1448
|
-
`event: message
|
1449
|
-
data: ${JSON.stringify(message)}
|
1450
|
-
|
1451
|
-
`
|
1452
|
-
);
|
1453
|
-
}
|
1454
|
-
async close() {
|
1455
|
-
this.onclose?.();
|
1456
|
-
this.closeStream();
|
1457
|
-
}
|
1458
|
-
};
|
1459
|
-
var ModelContextProtocolPlugin = class extends Plugin {
|
1460
|
-
mcpServer;
|
1461
|
-
transports = {};
|
1462
|
-
registerMcpTools(engine) {
|
1463
|
-
const modules = engine.getModules(true);
|
1464
|
-
for (const module of Object.values(modules)) {
|
1465
|
-
for (const action of Object.values(module.actions)) {
|
1466
|
-
if (action.mcp?.type !== "tool") {
|
1467
|
-
continue;
|
1468
|
-
}
|
1469
|
-
const args = {};
|
1470
|
-
const argsIndex = {};
|
1471
|
-
for (const [index, param] of (action.params ?? []).entries()) {
|
1472
|
-
args[param.description] = param;
|
1473
|
-
argsIndex[param.description] = index;
|
1474
|
-
}
|
1475
|
-
this.mcpServer.tool(
|
1476
|
-
`${module.name}.${action.name}`,
|
1477
|
-
action.description ?? "",
|
1478
|
-
args,
|
1479
|
-
async (params) => {
|
1480
|
-
const argsList = [];
|
1481
|
-
for (const [key, value] of Object.entries(params)) {
|
1482
|
-
argsList[argsIndex[key]] = value;
|
1483
|
-
}
|
1484
|
-
const result = await engine.getActionHandler(module.name, action.name).handle(argsList);
|
1485
|
-
return {
|
1486
|
-
content: [{ type: "text", text: JSON.stringify(result) }]
|
1487
|
-
};
|
1488
|
-
}
|
1489
|
-
);
|
1490
|
-
}
|
1491
|
-
}
|
1492
|
-
}
|
1493
|
-
initialize = async (engine) => {
|
1494
|
-
const app = engine.getApp();
|
1495
|
-
this.mcpServer = new McpServer({
|
1496
|
-
name: engine.options.name,
|
1497
|
-
version: engine.options.version
|
1498
|
-
});
|
1499
|
-
this.registerMcpTools(engine);
|
1500
|
-
app.get(`${engine.options.prefix}/mcp_sse`, async (ctx) => {
|
1501
|
-
return streamSSE(ctx, async (stream) => {
|
1502
|
-
return new Promise(async (resolve) => {
|
1503
|
-
const transport = new HonoTransport(
|
1504
|
-
`${engine.options.prefix}/mcp_messages`,
|
1505
|
-
stream,
|
1506
|
-
() => {
|
1507
|
-
delete this.transports[transport.sessionId];
|
1508
|
-
resolve();
|
1509
|
-
}
|
1510
|
-
);
|
1511
|
-
this.transports[transport.sessionId] = transport;
|
1512
|
-
await this.mcpServer.connect(transport);
|
1513
|
-
});
|
1514
|
-
});
|
1515
|
-
});
|
1516
|
-
app.post(`${engine.options.prefix}/mcp_messages`, async (ctx) => {
|
1517
|
-
const sessionId = ctx.req.query("sessionId");
|
1518
|
-
if (!sessionId) {
|
1519
|
-
return ctx.text("No transport found for sessionId", 400);
|
1520
|
-
}
|
1521
|
-
const transport = this.transports[sessionId];
|
1522
|
-
const message = await ctx.req.json();
|
1523
|
-
await transport.handleMessage(message);
|
1524
|
-
return ctx.text("Accepted", 202);
|
1525
|
-
});
|
1526
|
-
logger_default.info(
|
1527
|
-
`ModelContextProtocolPlugin endpoint: ${engine.options.prefix}/mcp_sse`
|
1528
|
-
);
|
1529
|
-
};
|
1530
|
-
};
|
1531
1424
|
var DEFAULT_FAVICON = /* @__PURE__ */ jsx(
|
1532
1425
|
"link",
|
1533
1426
|
{
|
@@ -1730,4 +1623,4 @@ async function startCheck(checkers, pass) {
|
|
1730
1623
|
if (pass) await pass();
|
1731
1624
|
}
|
1732
1625
|
|
1733
|
-
export { Action, BaseLayout, CacheAdapter, HtmxLayout, MemoryCacheAdapter, Microservice,
|
1626
|
+
export { Action, BaseLayout, CacheAdapter, HtmxLayout, MemoryCacheAdapter, Microservice, Module, Page, PageRenderPlugin, Plugin, RedisCacheAdapter, Schedule, ScheduleMode, ServiceContext, ServiceInfoCards, ServiceStatusPage, logger_default as logger, startCheck };
|
package/package.json
CHANGED
@@ -1,87 +1,86 @@
|
|
1
|
-
{
|
2
|
-
"name": "imean-service-engine",
|
3
|
-
"version": "1.
|
4
|
-
"description": "microservice engine",
|
5
|
-
"keywords": [
|
6
|
-
"microservice",
|
7
|
-
"websocket",
|
8
|
-
"http",
|
9
|
-
"node"
|
10
|
-
],
|
11
|
-
"author": "imean",
|
12
|
-
"type": "module",
|
13
|
-
"license": "MIT",
|
14
|
-
"repository": {
|
15
|
-
"type": "git",
|
16
|
-
"url": "git+https://git.imean.tech/imean/imean-microservice-framework.git"
|
17
|
-
},
|
18
|
-
"main": "dist/mod.js",
|
19
|
-
"module": "dist/mod.js",
|
20
|
-
"types": "dist/mod.d.ts",
|
21
|
-
"exports": {
|
22
|
-
".": {
|
23
|
-
"types": "./dist/mod.d.ts",
|
24
|
-
"import": "./dist/mod.js",
|
25
|
-
"require": "./dist/mod.cjs"
|
26
|
-
}
|
27
|
-
},
|
28
|
-
"files": [
|
29
|
-
"dist",
|
30
|
-
"README.md",
|
31
|
-
"LICENSE"
|
32
|
-
],
|
33
|
-
"scripts": {
|
34
|
-
"dev": "tsx watch dev/index.ts",
|
35
|
-
"build": "tsup",
|
36
|
-
"test": "vitest run",
|
37
|
-
"prepublishOnly": "npm run build && npm run test"
|
38
|
-
},
|
39
|
-
"dependencies": {
|
40
|
-
"@hono/node-server": "^1.13.7",
|
41
|
-
"@hono/node-ws": "^1.0.6",
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
"@opentelemetry/
|
60
|
-
"@opentelemetry/exporter-
|
61
|
-
"@opentelemetry/exporter-
|
62
|
-
"@opentelemetry/
|
63
|
-
"@opentelemetry/
|
64
|
-
"@opentelemetry/sdk-
|
65
|
-
"@opentelemetry/sdk-
|
66
|
-
"@opentelemetry/sdk-node": "^
|
67
|
-
"@opentelemetry/
|
68
|
-
"@
|
69
|
-
"@types/
|
70
|
-
"@types/
|
71
|
-
"@types/
|
72
|
-
"@
|
73
|
-
"
|
74
|
-
"
|
75
|
-
"
|
76
|
-
"
|
77
|
-
"
|
78
|
-
"
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}
|
1
|
+
{
|
2
|
+
"name": "imean-service-engine",
|
3
|
+
"version": "1.8.0",
|
4
|
+
"description": "microservice engine",
|
5
|
+
"keywords": [
|
6
|
+
"microservice",
|
7
|
+
"websocket",
|
8
|
+
"http",
|
9
|
+
"node"
|
10
|
+
],
|
11
|
+
"author": "imean",
|
12
|
+
"type": "module",
|
13
|
+
"license": "MIT",
|
14
|
+
"repository": {
|
15
|
+
"type": "git",
|
16
|
+
"url": "git+https://git.imean.tech/imean/imean-microservice-framework.git"
|
17
|
+
},
|
18
|
+
"main": "dist/mod.js",
|
19
|
+
"module": "dist/mod.js",
|
20
|
+
"types": "dist/mod.d.ts",
|
21
|
+
"exports": {
|
22
|
+
".": {
|
23
|
+
"types": "./dist/mod.d.ts",
|
24
|
+
"import": "./dist/mod.js",
|
25
|
+
"require": "./dist/mod.cjs"
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"files": [
|
29
|
+
"dist",
|
30
|
+
"README.md",
|
31
|
+
"LICENSE"
|
32
|
+
],
|
33
|
+
"scripts": {
|
34
|
+
"dev": "tsx watch dev/index.ts",
|
35
|
+
"build": "tsup",
|
36
|
+
"test": "vitest run",
|
37
|
+
"prepublishOnly": "npm run build && npm run test"
|
38
|
+
},
|
39
|
+
"dependencies": {
|
40
|
+
"@hono/node-server": "^1.13.7",
|
41
|
+
"@hono/node-ws": "^1.0.6",
|
42
|
+
"dayjs": "^1.11.13",
|
43
|
+
"ejson": "^2.2.3",
|
44
|
+
"etcd3": "^1.1.2",
|
45
|
+
"fs-extra": "^11.3.0",
|
46
|
+
"hono": "^4.6.17",
|
47
|
+
"lru-cache": "^11.0.2",
|
48
|
+
"prettier": "^3.4.2",
|
49
|
+
"ulid": "^3.0.0",
|
50
|
+
"winston": "^3.17.0",
|
51
|
+
"zod": "^3.24.1"
|
52
|
+
},
|
53
|
+
"peerDependencies": {
|
54
|
+
"@opentelemetry/api": "^1.x",
|
55
|
+
"ioredis": "^5.6.0"
|
56
|
+
},
|
57
|
+
"devDependencies": {
|
58
|
+
"@opentelemetry/auto-instrumentations-node": "^0.55.3",
|
59
|
+
"@opentelemetry/exporter-logs-otlp-proto": "^0.57.1",
|
60
|
+
"@opentelemetry/exporter-metrics-otlp-proto": "^0.57.1",
|
61
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.57.1",
|
62
|
+
"@opentelemetry/instrumentation-winston": "^0.44.0",
|
63
|
+
"@opentelemetry/sdk-logs": "^0.57.1",
|
64
|
+
"@opentelemetry/sdk-metrics": "^1.30.1",
|
65
|
+
"@opentelemetry/sdk-node": "^0.57.1",
|
66
|
+
"@opentelemetry/sdk-trace-node": "^1.30.1",
|
67
|
+
"@opentelemetry/winston-transport": "^0.10.0",
|
68
|
+
"@types/ejson": "^2.2.2",
|
69
|
+
"@types/fs-extra": "^11.0.4",
|
70
|
+
"@types/ioredis-mock": "^8.2.5",
|
71
|
+
"@types/node": "^20.0.0",
|
72
|
+
"@vitest/coverage-v8": "^3.0.4",
|
73
|
+
"imean-service-client": "^1.5.0",
|
74
|
+
"ioredis-mock": "^8.9.0",
|
75
|
+
"opentelemetry-instrumentation-fetch-node": "^1.2.3",
|
76
|
+
"tslib": "^2.8.1",
|
77
|
+
"tsup": "^8.0.1",
|
78
|
+
"tsx": "^4.19.2",
|
79
|
+
"typescript": "^5.3.3",
|
80
|
+
"vite-tsconfig-paths": "^5.1.4",
|
81
|
+
"vitest": "^3.0.3"
|
82
|
+
},
|
83
|
+
"engines": {
|
84
|
+
"node": ">=20"
|
85
|
+
}
|
86
|
+
}
|