imean-service-engine 1.6.0 → 1.7.1

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.js CHANGED
@@ -6,6 +6,7 @@ import { serve } from '@hono/node-server';
6
6
  import { Etcd3 } from 'etcd3';
7
7
  import fs from 'fs-extra';
8
8
  import { Hono } from 'hono';
9
+ import { timing } from 'hono/timing';
9
10
  import { trace, SpanStatusCode } from '@opentelemetry/api';
10
11
  import winston, { format } from 'winston';
11
12
  import prettier from 'prettier';
@@ -17,6 +18,8 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
17
18
  import { JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
18
19
  import { streamSSE } from 'hono/streaming';
19
20
  import { ulid } from 'ulid';
21
+ import { html } from 'hono/html';
22
+ import { jsx, jsxs } from 'hono/jsx/jsx-runtime';
20
23
  export { default as dayjs } from 'dayjs';
21
24
 
22
25
  // mod.ts
@@ -586,6 +589,62 @@ var ActionHandler = class {
586
589
  function isAsyncIterable(obj) {
587
590
  return obj != null && typeof obj[Symbol.asyncIterator] === "function";
588
591
  }
592
+
593
+ // decorators/page.ts
594
+ var PAGE_METADATA = Symbol("page:metadata");
595
+ function Page(options) {
596
+ return function(_target, context) {
597
+ const methodName = context.name;
598
+ context.addInitializer(function() {
599
+ const prototype = this.constructor.prototype;
600
+ const existingMetadata = prototype[PAGE_METADATA] || {};
601
+ existingMetadata[methodName] = {
602
+ name: methodName,
603
+ description: options.description || "",
604
+ method: options.method,
605
+ path: options.path
606
+ };
607
+ prototype[PAGE_METADATA] = existingMetadata;
608
+ });
609
+ };
610
+ }
611
+ function getPageMetadata(target) {
612
+ return target.constructor.prototype[PAGE_METADATA] ?? {};
613
+ }
614
+ var tracer3 = trace.getTracer("page-handler");
615
+ var PageHandler = class {
616
+ constructor(moduleInstance, options, moduleName) {
617
+ this.moduleInstance = moduleInstance;
618
+ this.options = options;
619
+ this.moduleName = moduleName;
620
+ }
621
+ async handle(ctx) {
622
+ return await tracer3.startActiveSpan(
623
+ `handle ${this.moduleName}.${this.options.name}`,
624
+ async (span) => {
625
+ span.setAttribute("module", this.moduleName);
626
+ span.setAttribute("page", this.options.name);
627
+ span.setAttribute("path", this.options.path);
628
+ try {
629
+ const result = await this.moduleInstance[this.options.name].apply(
630
+ this.moduleInstance,
631
+ [ctx]
632
+ );
633
+ return ctx.html(result);
634
+ } catch (error) {
635
+ span.recordException(error);
636
+ span.setStatus({
637
+ code: SpanStatusCode.ERROR,
638
+ message: error.message
639
+ });
640
+ throw error;
641
+ } finally {
642
+ span.end();
643
+ }
644
+ }
645
+ );
646
+ }
647
+ };
589
648
  var WebSocketHandler = class {
590
649
  constructor(microservice, options) {
591
650
  this.microservice = microservice;
@@ -773,6 +832,7 @@ var Microservice = class {
773
832
  statisticsTimer;
774
833
  wsHandler;
775
834
  actionHandlers = /* @__PURE__ */ new Map();
835
+ pageHandlers = /* @__PURE__ */ new Map();
776
836
  activeRequests = /* @__PURE__ */ new Map();
777
837
  status = "running";
778
838
  modules = /* @__PURE__ */ new Map();
@@ -782,6 +842,7 @@ var Microservice = class {
782
842
  serviceId;
783
843
  constructor(options) {
784
844
  this.app = new Hono();
845
+ this.app.use(timing());
785
846
  this.nodeWebSocket = createNodeWebSocket({ app: this.app });
786
847
  this.serviceId = crypto.randomUUID();
787
848
  this.options = {
@@ -820,6 +881,11 @@ var Microservice = class {
820
881
  }
821
882
  await this.registerService(true);
822
883
  await this.initPlugins();
884
+ this.app.get(this.options.prefix, (ctx) => {
885
+ const name = this.options.name ?? "Microservice";
886
+ const version = this.options.version ?? "1.0.0";
887
+ return ctx.text(`${name} is ${this.status}. version: ${version}`);
888
+ });
823
889
  }
824
890
  async initModules() {
825
891
  for (const ModuleClass of this.options.modules) {
@@ -834,6 +900,7 @@ var Microservice = class {
834
900
  logger_default.info(`[ \u6CE8\u518C\u6A21\u5757 ] ${moduleName} ${metadata.options.description}`);
835
901
  this.modules.set(moduleName, moduleInstance);
836
902
  const actions = getActionMetadata(ModuleClass.prototype);
903
+ const pages = getPageMetadata(ModuleClass.prototype);
837
904
  for (const [actionName, actionMetadata] of Object.entries(actions)) {
838
905
  const handler = new ActionHandler(
839
906
  moduleInstance,
@@ -847,6 +914,18 @@ var Microservice = class {
847
914
  `[ \u6CE8\u518C\u52A8\u4F5C ] ${moduleName}.${actionName} ${actionMetadata.description} ${actionMetadata.mcp ? "MCP:" + actionMetadata.mcp?.type : ""}`
848
915
  );
849
916
  }
917
+ for (const [_, page] of Object.entries(pages)) {
918
+ const handler = new PageHandler(
919
+ moduleInstance,
920
+ page,
921
+ moduleName
922
+ );
923
+ this.pageHandlers.set(`${moduleName}.${page.name}`, handler);
924
+ this.app[page.method](`${this.options.prefix}${page.path}`, (ctx) => handler.handle(ctx));
925
+ logger_default.info(
926
+ `[ \u6CE8\u518C\u9875\u9762 ] ${moduleName}.${page.name} ${page.method.toUpperCase()} ${page.path} ${page.description}`
927
+ );
928
+ }
850
929
  const schedules = getScheduleMetadata(ModuleClass.prototype);
851
930
  if (schedules && Object.keys(schedules).length > 0) {
852
931
  if (!this.scheduler && this.etcdClient) {
@@ -876,11 +955,6 @@ var Microservice = class {
876
955
  initRoutes() {
877
956
  const startTime = Date.now();
878
957
  const prefix = this.options.prefix || "/api";
879
- this.app.get(prefix, (ctx) => {
880
- const name = this.options.name ?? "Microservice";
881
- const version = this.options.version ?? "1.0.0";
882
- return ctx.text(`${name} is ${this.status}. version: ${version}`);
883
- });
884
958
  this.app.get(`${prefix}/health`, (ctx) => {
885
959
  return ctx.json({
886
960
  status: "ok",
@@ -1323,28 +1397,6 @@ Received SIGTERM signal`);
1323
1397
  await this.waitingInitialization;
1324
1398
  }
1325
1399
  };
1326
-
1327
- // utils/checker.ts
1328
- async function startCheck(checkers, pass) {
1329
- logger_default.info("[ \u9884\u68C0\u5F00\u59CB ]");
1330
- for (const [index, checker] of checkers.entries()) {
1331
- const seq = index + 1;
1332
- logger_default.info(`${seq}. ${checker.name}`);
1333
- try {
1334
- if (checker.skip) {
1335
- logger_default.warn(`${seq}. ${checker.name} [\u8DF3\u8FC7]`);
1336
- continue;
1337
- }
1338
- await checker.check();
1339
- logger_default.info(`${seq}. ${checker.name} [\u6210\u529F]`);
1340
- } catch (error) {
1341
- logger_default.error(`${seq}. ${checker.name} [\u5931\u8D25]`);
1342
- throw error;
1343
- }
1344
- }
1345
- logger_default.info("[ \u9884\u68C0\u5B8C\u6210 ]");
1346
- if (pass) await pass();
1347
- }
1348
1400
  var HonoTransport = class {
1349
1401
  constructor(url, stream, closeStream) {
1350
1402
  this.url = url;
@@ -1460,5 +1512,204 @@ var ModelContextProtocolPlugin = class extends Plugin {
1460
1512
  );
1461
1513
  };
1462
1514
  };
1515
+ var DEFAULT_FAVICON = /* @__PURE__ */ jsx(
1516
+ "link",
1517
+ {
1518
+ rel: "icon",
1519
+ href: "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' width='100' height='100'><defs><linearGradient id='nodeGradient' x1='0%' y1='0%' x2='100%' y2='100%'><stop offset='0%' stop-color='%233498db'/><stop offset='100%' stop-color='%232980b9'/></linearGradient><linearGradient id='centerNodeGradient' x1='0%' y1='0%' x2='100%' y2='100%'><stop offset='0%' stop-color='%232ecc71'/><stop offset='100%' stop-color='%2327ae60'/></linearGradient></defs><circle cx='50' cy='50' r='45' fill='%23f5f7fa'/><path d='M30,30 L50,50' stroke='%23bdc3c7' stroke-width='2' stroke-linecap='round'/><path d='M70,30 L50,50' stroke='%23bdc3c7' stroke-width='2' stroke-linecap='round'/><path d='M30,70 L50,50' stroke='%23bdc3c7' stroke-width='2' stroke-linecap='round'/><path d='M70,70 L50,50' stroke='%23bdc3c7' stroke-width='2' stroke-linecap='round'/><polygon points='30,15 45,25 45,45 30,55 15,45 15,25' fill='url(%23nodeGradient)' stroke='%232980b9' stroke-width='1.5'/><polygon points='70,15 85,25 85,45 70,55 55,45 55,25' fill='url(%23nodeGradient)' stroke='%232980b9' stroke-width='1.5'/><polygon points='30,45 45,55 45,75 30,85 15,75 15,55' fill='url(%23nodeGradient)' stroke='%232980b9' stroke-width='1.5'/><polygon points='70,45 85,55 85,75 70,85 55,75 55,55' fill='url(%23nodeGradient)' stroke='%232980b9' stroke-width='1.5'/><polygon points='50,30 65,40 65,60 50,70 35,60 35,40' fill='url(%23centerNodeGradient)' stroke='%2327ae60' stroke-width='2'/><circle cx='30' cy='30' r='3' fill='%23ffffff'/><circle cx='70' cy='30' r='3' fill='%23ffffff'/><circle cx='30' cy='70' r='3' fill='%23ffffff'/><circle cx='70' cy='70' r='3' fill='%23ffffff'/><circle cx='50' cy='50' r='4' fill='%23ffffff'/></svg>",
1520
+ type: "image/svg+xml"
1521
+ }
1522
+ );
1523
+ var BaseLayout = (props = {
1524
+ title: "Microservice Template"
1525
+ }) => html`<!DOCTYPE html>
1526
+ <html>
1527
+ <head>
1528
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1529
+ <title>${props.title}</title>
1530
+ ${props.heads}
1531
+ </head>
1532
+ <body>
1533
+ ${props.children}
1534
+ </body>
1535
+ </html>`;
1536
+ var HtmxLayout = (props = {
1537
+ title: "Microservice Template"
1538
+ }) => BaseLayout({
1539
+ title: props.title,
1540
+ heads: html`
1541
+ <script src="https://unpkg.com/htmx.org@latest"></script>
1542
+ <script src="https://unpkg.com/hyperscript.org@latest"></script>
1543
+ <script src="https://cdn.tailwindcss.com"></script>
1544
+ ${props.favicon || DEFAULT_FAVICON}
1545
+ `,
1546
+ children: props.children
1547
+ });
1548
+ var InfoCard = ({
1549
+ icon,
1550
+ iconColor,
1551
+ bgColor,
1552
+ label,
1553
+ value
1554
+ }) => /* @__PURE__ */ jsxs("div", { className: `${bgColor} p-4 rounded-lg`, children: [
1555
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center mb-2", children: [
1556
+ /* @__PURE__ */ jsx(
1557
+ "svg",
1558
+ {
1559
+ className: `w-5 h-5 ${iconColor} mr-2`,
1560
+ fill: "none",
1561
+ stroke: "currentColor",
1562
+ viewBox: "0 0 24 24",
1563
+ children: /* @__PURE__ */ jsx(
1564
+ "path",
1565
+ {
1566
+ strokeLinecap: "round",
1567
+ strokeLinejoin: "round",
1568
+ strokeWidth: 2,
1569
+ d: icon
1570
+ }
1571
+ )
1572
+ }
1573
+ ),
1574
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-600", children: label })
1575
+ ] }),
1576
+ /* @__PURE__ */ jsx("p", { className: `text-xl font-semibold text-gray-900`, children: value })
1577
+ ] });
1578
+ var getEnvironmentBadgeClass = (env) => {
1579
+ switch (env) {
1580
+ case "prod":
1581
+ return "bg-red-100 text-red-800";
1582
+ case "stg":
1583
+ return "bg-yellow-100 text-yellow-800";
1584
+ case "dev":
1585
+ default:
1586
+ return "bg-blue-100 text-blue-800";
1587
+ }
1588
+ };
1589
+ var ServiceInfoCards = ({
1590
+ serviceInfo
1591
+ }) => {
1592
+ const infoCards = [
1593
+ {
1594
+ icon: "M7 4V2a1 1 0 011-1h8a1 1 0 011 1v2m-9 0h10m-10 0a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 002-2V6a2 2 0 00-2-2",
1595
+ iconColor: "text-blue-600",
1596
+ bgColor: "bg-blue-50",
1597
+ label: "\u670D\u52A1\u540D\u79F0",
1598
+ value: serviceInfo.name
1599
+ },
1600
+ {
1601
+ icon: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1",
1602
+ iconColor: "text-orange-600",
1603
+ bgColor: "bg-orange-50",
1604
+ label: "\u670D\u52A1\u8DEF\u5F84",
1605
+ value: serviceInfo.prefix || "/",
1606
+ isMonospace: true
1607
+ },
1608
+ {
1609
+ icon: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z",
1610
+ iconColor: "text-green-600",
1611
+ bgColor: "bg-green-50",
1612
+ label: "\u8FD0\u884C\u73AF\u5883",
1613
+ value: /* @__PURE__ */ jsx(
1614
+ "span",
1615
+ {
1616
+ className: `px-2 py-1 rounded-full text-sm ${getEnvironmentBadgeClass(serviceInfo.env ?? "dev")}`,
1617
+ children: serviceInfo.env ?? "dev"
1618
+ }
1619
+ )
1620
+ },
1621
+ {
1622
+ icon: "M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z",
1623
+ iconColor: "text-purple-600",
1624
+ bgColor: "bg-purple-50",
1625
+ label: "\u7248\u672C\u53F7",
1626
+ value: serviceInfo.version || "unknown"
1627
+ }
1628
+ ];
1629
+ return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-md p-6 mb-8", children: [
1630
+ /* @__PURE__ */ jsxs("h2", { className: "text-2xl font-semibold text-gray-800 mb-6 flex items-center", children: [
1631
+ /* @__PURE__ */ jsx(
1632
+ "svg",
1633
+ {
1634
+ className: "w-6 h-6 mr-2 text-blue-600",
1635
+ fill: "none",
1636
+ stroke: "currentColor",
1637
+ viewBox: "0 0 24 24",
1638
+ children: /* @__PURE__ */ jsx(
1639
+ "path",
1640
+ {
1641
+ strokeLinecap: "round",
1642
+ strokeLinejoin: "round",
1643
+ strokeWidth: 2,
1644
+ d: "M13 10V3L4 14h7v7l9-11h-7z"
1645
+ }
1646
+ )
1647
+ }
1648
+ ),
1649
+ "\u670D\u52A1\u57FA\u672C\u4FE1\u606F"
1650
+ ] }),
1651
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6", children: infoCards.map((card, index) => /* @__PURE__ */ jsx(InfoCard, { ...card }, index)) })
1652
+ ] });
1653
+ };
1654
+ var ServiceStatusPage = ({
1655
+ serviceInfo
1656
+ }) => {
1657
+ return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-gray-50 py-8", children: /* @__PURE__ */ jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [
1658
+ /* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold text-gray-900 mb-2", children: "Service Status" }) }),
1659
+ /* @__PURE__ */ jsx(ServiceInfoCards, { serviceInfo })
1660
+ ] }) });
1661
+ };
1662
+ var ServiceStatusPage_default = ServiceStatusPage;
1663
+
1664
+ // core/plugins/page/mod.ts
1665
+ var PageRenderPlugin = class extends Plugin {
1666
+ constructor(options = {}) {
1667
+ super();
1668
+ this.options = options;
1669
+ }
1670
+ initialize = async (engine) => {
1671
+ const app = engine.getApp();
1672
+ if (this.options.useDefaultStatusPage) {
1673
+ app.get(`${engine.options.prefix}`, async (ctx) => {
1674
+ return ctx.html(HtmxLayout({
1675
+ title: engine.options.name,
1676
+ children: ServiceStatusPage_default({
1677
+ serviceInfo: {
1678
+ name: engine.options.name,
1679
+ prefix: engine.options.prefix,
1680
+ version: engine.options.version,
1681
+ env: engine.options.env,
1682
+ id: engine.serviceId,
1683
+ modules: engine.getModules(false)
1684
+ }
1685
+ })
1686
+ }));
1687
+ });
1688
+ }
1689
+ logger_default.info(`PageRenderPlugin enabled`);
1690
+ };
1691
+ };
1692
+
1693
+ // utils/checker.ts
1694
+ async function startCheck(checkers, pass) {
1695
+ logger_default.info("[ \u9884\u68C0\u5F00\u59CB ]");
1696
+ for (const [index, checker] of checkers.entries()) {
1697
+ const seq = index + 1;
1698
+ logger_default.info(`${seq}. ${checker.name}`);
1699
+ try {
1700
+ if (checker.skip) {
1701
+ logger_default.warn(`${seq}. ${checker.name} [\u8DF3\u8FC7]`);
1702
+ continue;
1703
+ }
1704
+ await checker.check();
1705
+ logger_default.info(`${seq}. ${checker.name} [\u6210\u529F]`);
1706
+ } catch (error) {
1707
+ logger_default.error(`${seq}. ${checker.name} [\u5931\u8D25]`);
1708
+ throw error;
1709
+ }
1710
+ }
1711
+ logger_default.info("[ \u9884\u68C0\u5B8C\u6210 ]");
1712
+ if (pass) await pass();
1713
+ }
1463
1714
 
1464
- export { Action, CacheAdapter, MemoryCacheAdapter, Microservice, ModelContextProtocolPlugin, Module, Plugin, RedisCacheAdapter, Schedule, ScheduleMode, ServiceContext, logger_default as logger, startCheck };
1715
+ export { Action, BaseLayout, CacheAdapter, HtmxLayout, MemoryCacheAdapter, Microservice, ModelContextProtocolPlugin, 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.6.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
- "@modelcontextprotocol/sdk": "^1.8.0",
43
- "dayjs": "^1.11.13",
44
- "ejson": "^2.2.3",
45
- "etcd3": "^1.1.2",
46
- "fs-extra": "^11.3.0",
47
- "hono": "^4.6.17",
48
- "lru-cache": "^11.0.2",
49
- "prettier": "^3.4.2",
50
- "ulid": "^3.0.0",
51
- "winston": "^3.17.0",
52
- "zod": "^3.24.1"
53
- },
54
- "peerDependencies": {
55
- "@opentelemetry/api": "^1.x",
56
- "ioredis": "^5.6.0"
57
- },
58
- "devDependencies": {
59
- "@opentelemetry/auto-instrumentations-node": "^0.55.3",
60
- "@opentelemetry/exporter-logs-otlp-proto": "^0.57.1",
61
- "@opentelemetry/exporter-metrics-otlp-proto": "^0.57.1",
62
- "@opentelemetry/exporter-trace-otlp-proto": "^0.57.1",
63
- "@opentelemetry/instrumentation-winston": "^0.44.0",
64
- "@opentelemetry/sdk-logs": "^0.57.1",
65
- "@opentelemetry/sdk-metrics": "^1.30.1",
66
- "@opentelemetry/sdk-node": "^0.57.1",
67
- "@opentelemetry/sdk-trace-node": "^1.30.1",
68
- "@opentelemetry/winston-transport": "^0.10.0",
69
- "@types/ejson": "^2.2.2",
70
- "@types/fs-extra": "^11.0.4",
71
- "@types/ioredis-mock": "^8.2.5",
72
- "@types/node": "^20.0.0",
73
- "@vitest/coverage-v8": "^3.0.4",
74
- "imean-service-client": "^1.5.0",
75
- "ioredis-mock": "^8.9.0",
76
- "opentelemetry-instrumentation-fetch-node": "^1.2.3",
77
- "tslib": "^2.8.1",
78
- "tsup": "^8.0.1",
79
- "tsx": "^4.19.2",
80
- "typescript": "^5.3.3",
81
- "vite-tsconfig-paths": "^5.1.4",
82
- "vitest": "^3.0.3"
83
- },
84
- "engines": {
85
- "node": ">=20"
86
- }
87
- }
1
+ {
2
+ "name": "imean-service-engine",
3
+ "version": "1.7.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
+ "dependencies": {
34
+ "@hono/node-server": "^1.13.7",
35
+ "@hono/node-ws": "^1.0.6",
36
+ "@modelcontextprotocol/sdk": "^1.8.0",
37
+ "dayjs": "^1.11.13",
38
+ "ejson": "^2.2.3",
39
+ "etcd3": "^1.1.2",
40
+ "fs-extra": "^11.3.0",
41
+ "hono": "^4.6.17",
42
+ "lru-cache": "^11.0.2",
43
+ "prettier": "^3.4.2",
44
+ "ulid": "^3.0.0",
45
+ "winston": "^3.17.0",
46
+ "zod": "^3.24.1"
47
+ },
48
+ "peerDependencies": {
49
+ "@opentelemetry/api": "^1.x",
50
+ "ioredis": "^5.6.0"
51
+ },
52
+ "devDependencies": {
53
+ "@opentelemetry/auto-instrumentations-node": "^0.55.3",
54
+ "@opentelemetry/exporter-logs-otlp-proto": "^0.57.1",
55
+ "@opentelemetry/exporter-metrics-otlp-proto": "^0.57.1",
56
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.57.1",
57
+ "@opentelemetry/instrumentation-winston": "^0.44.0",
58
+ "@opentelemetry/sdk-logs": "^0.57.1",
59
+ "@opentelemetry/sdk-metrics": "^1.30.1",
60
+ "@opentelemetry/sdk-node": "^0.57.1",
61
+ "@opentelemetry/sdk-trace-node": "^1.30.1",
62
+ "@opentelemetry/winston-transport": "^0.10.0",
63
+ "@types/ejson": "^2.2.2",
64
+ "@types/fs-extra": "^11.0.4",
65
+ "@types/ioredis-mock": "^8.2.5",
66
+ "@types/node": "^20.0.0",
67
+ "@vitest/coverage-v8": "^3.0.4",
68
+ "imean-service-client": "^1.5.0",
69
+ "ioredis-mock": "^8.9.0",
70
+ "opentelemetry-instrumentation-fetch-node": "^1.2.3",
71
+ "tslib": "^2.8.1",
72
+ "tsup": "^8.0.1",
73
+ "tsx": "^4.19.2",
74
+ "typescript": "^5.3.3",
75
+ "vite-tsconfig-paths": "^5.1.4",
76
+ "vitest": "^3.0.3"
77
+ },
78
+ "engines": {
79
+ "node": ">=20"
80
+ },
81
+ "scripts": {
82
+ "dev": "tsx watch dev/index.ts",
83
+ "build": "tsup",
84
+ "test": "vitest run"
85
+ }
86
+ }