imean-service-engine 2.0.0 → 2.0.2
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.d.mts +77 -52
- package/dist/index.d.ts +77 -52
- package/dist/index.js +2078 -1945
- package/dist/index.mjs +2076 -1944
- package/package.json +9 -2
- package/.vscode/settings.json +0 -8
- package/src/core/checker.ts +0 -33
- package/src/core/decorators.test.ts +0 -96
- package/src/core/decorators.ts +0 -68
- package/src/core/engine.test.ts +0 -218
- package/src/core/engine.ts +0 -635
- package/src/core/errors.ts +0 -28
- package/src/core/factory.test.ts +0 -73
- package/src/core/factory.ts +0 -92
- package/src/core/logger.ts +0 -65
- package/src/core/testing.ts +0 -73
- package/src/core/types.ts +0 -191
- package/src/index.ts +0 -49
- package/src/metadata/README.md +0 -422
- package/src/metadata/metadata.test.ts +0 -369
- package/src/metadata/metadata.ts +0 -512
- package/src/plugins/action/action-plugin.test.ts +0 -660
- package/src/plugins/action/decorator.ts +0 -14
- package/src/plugins/action/index.ts +0 -4
- package/src/plugins/action/plugin.ts +0 -349
- package/src/plugins/action/types.ts +0 -49
- package/src/plugins/action/utils.test.ts +0 -196
- package/src/plugins/action/utils.ts +0 -111
- package/src/plugins/cache/adapter.test.ts +0 -689
- package/src/plugins/cache/adapter.ts +0 -324
- package/src/plugins/cache/cache-plugin.test.ts +0 -269
- package/src/plugins/cache/decorator.ts +0 -26
- package/src/plugins/cache/index.ts +0 -20
- package/src/plugins/cache/plugin.ts +0 -299
- package/src/plugins/cache/types.ts +0 -69
- package/src/plugins/client-code/client-code-plugin.test.ts +0 -511
- package/src/plugins/client-code/format.ts +0 -9
- package/src/plugins/client-code/generator.test.ts +0 -52
- package/src/plugins/client-code/generator.ts +0 -263
- package/src/plugins/client-code/index.ts +0 -15
- package/src/plugins/client-code/plugin.ts +0 -158
- package/src/plugins/client-code/types.ts +0 -52
- package/src/plugins/client-code/utils.ts +0 -164
- package/src/plugins/graceful-shutdown/graceful-shutdown-plugin.test.ts +0 -401
- package/src/plugins/graceful-shutdown/index.ts +0 -3
- package/src/plugins/graceful-shutdown/plugin.ts +0 -279
- package/src/plugins/graceful-shutdown/types.ts +0 -17
- package/src/plugins/rate-limit/rate-limit-plugin.example.ts +0 -171
- package/src/plugins/route/components/Layout.tsx +0 -42
- package/src/plugins/route/components/ServiceStatusPage.tsx +0 -141
- package/src/plugins/route/decorator.ts +0 -50
- package/src/plugins/route/index.ts +0 -16
- package/src/plugins/route/plugin.ts +0 -218
- package/src/plugins/route/route-plugin.test.ts +0 -759
- package/src/plugins/route/types.ts +0 -72
- package/src/plugins/schedule/README.md +0 -309
- package/src/plugins/schedule/decorator.ts +0 -25
- package/src/plugins/schedule/index.ts +0 -12
- package/src/plugins/schedule/mock-etcd.ts +0 -145
- package/src/plugins/schedule/plugin.ts +0 -164
- package/src/plugins/schedule/schedule-plugin.test.ts +0 -312
- package/src/plugins/schedule/scheduler.ts +0 -164
- package/src/plugins/schedule/types.ts +0 -94
- package/src/plugins/schedule/utils.test.ts +0 -163
- package/src/plugins/schedule/utils.ts +0 -41
- package/tests/integration/client.test.ts +0 -203
- package/tests/integration/dev-service.ts +0 -301
- package/tests/integration/generated/client.ts +0 -123
- package/tests/integration/start-service.ts +0 -21
- package/tsconfig.json +0 -27
- package/tsup.config.ts +0 -16
- package/vitest.config.ts +0 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imean-service-engine",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "基于Hono的轻量级微服务引擎框架",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"dev": "tsx tests/integration/start-service.ts",
|
|
10
10
|
"test": "vitest --run",
|
|
11
11
|
"test:ui": "vitest --ui",
|
|
12
|
-
"test:coverage": "vitest --coverage",
|
|
12
|
+
"test:coverage": "vitest --run --coverage",
|
|
13
13
|
"prepublishOnly": "npm run build && npm run test"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
"framework",
|
|
19
19
|
"typescript"
|
|
20
20
|
],
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"docs",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
21
27
|
"author": "",
|
|
22
28
|
"license": "MIT",
|
|
23
29
|
"dependencies": {
|
|
@@ -32,6 +38,7 @@
|
|
|
32
38
|
"devDependencies": {
|
|
33
39
|
"@types/ejson": "^2.2.2",
|
|
34
40
|
"@types/node": "^25.0.1",
|
|
41
|
+
"@vitest/coverage-v8": "4.0.15",
|
|
35
42
|
"@vitest/ui": "^4.0.15",
|
|
36
43
|
"imean-service-client": "^1.6.0",
|
|
37
44
|
"tsup": "^8.5.1",
|
package/.vscode/settings.json
DELETED
package/src/core/checker.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import logger from "./logger";
|
|
2
|
-
|
|
3
|
-
export interface PreStartChecker {
|
|
4
|
-
name: string;
|
|
5
|
-
check: () => Promise<void> | void;
|
|
6
|
-
skip?: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export async function startCheck(
|
|
10
|
-
checkers: PreStartChecker[],
|
|
11
|
-
pass?: () => void | Promise<void>
|
|
12
|
-
) {
|
|
13
|
-
logger.info("[ 预检开始 ]");
|
|
14
|
-
|
|
15
|
-
for (const [index, checker] of checkers.entries()) {
|
|
16
|
-
const seq = index + 1;
|
|
17
|
-
logger.info(`${seq}. ${checker.name}`);
|
|
18
|
-
try {
|
|
19
|
-
if (checker.skip) {
|
|
20
|
-
logger.warn(`${seq}. ${checker.name} [跳过]`);
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
await checker.check();
|
|
24
|
-
logger.info(`${seq}. ${checker.name} [成功]`);
|
|
25
|
-
} catch (error) {
|
|
26
|
-
logger.error(`${seq}. ${checker.name} [失败]`);
|
|
27
|
-
throw error;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
logger.info("[ 预检完成 ]");
|
|
32
|
-
if (pass) await pass();
|
|
33
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
Handler,
|
|
4
|
-
getAllHandlerMetadata,
|
|
5
|
-
getHandlerMetadata,
|
|
6
|
-
} from "./decorators";
|
|
7
|
-
|
|
8
|
-
describe("Handler装饰器", () => {
|
|
9
|
-
describe("Handler装饰器", () => {
|
|
10
|
-
it("应该能够标注方法为Handler", () => {
|
|
11
|
-
class TestService {
|
|
12
|
-
@Handler({ type: "route", options: { method: "GET" } })
|
|
13
|
-
getUser() {}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// 实例化类以确保装饰器的 addInitializer 执行
|
|
17
|
-
new TestService();
|
|
18
|
-
|
|
19
|
-
const metadata = getHandlerMetadata(TestService, "getUser");
|
|
20
|
-
expect(metadata).toHaveLength(1);
|
|
21
|
-
expect(metadata[0].type).toBe("route");
|
|
22
|
-
expect(metadata[0].options.method).toBe("GET");
|
|
23
|
-
expect(metadata[0].methodName).toBe("getUser");
|
|
24
|
-
expect(metadata[0].module).toBe(TestService);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("应该支持多应用Handler装饰器", () => {
|
|
28
|
-
class TestService {
|
|
29
|
-
@Handler({ type: "route", options: { method: "GET" } })
|
|
30
|
-
@Handler({ type: "cache", options: { ttl: 60 } })
|
|
31
|
-
@Handler({ type: "rate-limit", options: { limit: 100 } })
|
|
32
|
-
getUser() {}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 实例化类以确保装饰器的 addInitializer 执行
|
|
36
|
-
new TestService();
|
|
37
|
-
|
|
38
|
-
const metadata = getHandlerMetadata(TestService, "getUser");
|
|
39
|
-
expect(metadata).toHaveLength(3);
|
|
40
|
-
|
|
41
|
-
const routeMeta = metadata.find((m) => m.type === "route");
|
|
42
|
-
const cacheMeta = metadata.find((m) => m.type === "cache");
|
|
43
|
-
const rateLimitMeta = metadata.find((m) => m.type === "rate-limit");
|
|
44
|
-
|
|
45
|
-
expect(routeMeta).toBeDefined();
|
|
46
|
-
expect(cacheMeta).toBeDefined();
|
|
47
|
-
expect(rateLimitMeta).toBeDefined();
|
|
48
|
-
expect(routeMeta?.options.method).toBe("GET");
|
|
49
|
-
expect(cacheMeta?.options.ttl).toBe(60);
|
|
50
|
-
expect(rateLimitMeta?.options.limit).toBe(100);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("应该能够获取所有Handler元数据", () => {
|
|
54
|
-
class TestService {
|
|
55
|
-
@Handler({ type: "route" })
|
|
56
|
-
getUser() {}
|
|
57
|
-
|
|
58
|
-
@Handler({ type: "route" })
|
|
59
|
-
createUser() {}
|
|
60
|
-
|
|
61
|
-
// 没有装饰器的方法不应该出现
|
|
62
|
-
deleteUser() {}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 实例化类以确保装饰器的 addInitializer 执行
|
|
66
|
-
new TestService();
|
|
67
|
-
|
|
68
|
-
const allMetadata = getAllHandlerMetadata(TestService);
|
|
69
|
-
expect(allMetadata.size).toBe(2);
|
|
70
|
-
expect(allMetadata.has("getUser")).toBe(true);
|
|
71
|
-
expect(allMetadata.has("createUser")).toBe(true);
|
|
72
|
-
expect(allMetadata.has("deleteUser")).toBe(false);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("Handler元数据应该包含完整信息", () => {
|
|
76
|
-
class TestService {
|
|
77
|
-
@Handler({ type: "route", options: { path: "/user" } })
|
|
78
|
-
getUser() {
|
|
79
|
-
return { id: 1 };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// 实例化类以确保装饰器的 addInitializer 执行
|
|
84
|
-
new TestService();
|
|
85
|
-
|
|
86
|
-
const metadata = getHandlerMetadata(TestService, "getUser");
|
|
87
|
-
expect(metadata[0]).toMatchObject({
|
|
88
|
-
type: "route",
|
|
89
|
-
options: { path: "/user" },
|
|
90
|
-
methodName: "getUser",
|
|
91
|
-
module: TestService,
|
|
92
|
-
});
|
|
93
|
-
expect(typeof metadata[0].method).toBe("function");
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
});
|
package/src/core/decorators.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createMethodDecorator,
|
|
3
|
-
getAllMethodMetadata as getAllMetadata,
|
|
4
|
-
} from "../metadata/metadata";
|
|
5
|
-
import { HandlerMetadata } from "./types";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Handler装饰器元数据键
|
|
9
|
-
*/
|
|
10
|
-
const HANDLER_METADATA_KEY = Symbol.for("imean:handlerMetadata");
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 创建Handler装饰器(基于通用元数据工具)
|
|
14
|
-
*/
|
|
15
|
-
const createHandlerDecorator = createMethodDecorator(HANDLER_METADATA_KEY);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 通用Handler装饰器(支持多应用)
|
|
19
|
-
* 使用最新的 Stage 3 装饰器标准
|
|
20
|
-
*
|
|
21
|
-
* @param config Handler配置
|
|
22
|
-
* @returns 方法装饰器
|
|
23
|
-
*/
|
|
24
|
-
export function Handler<T = Record<string, any>>(config: {
|
|
25
|
-
type: string;
|
|
26
|
-
options?: T;
|
|
27
|
-
}) {
|
|
28
|
-
return createHandlerDecorator({
|
|
29
|
-
type: config.type,
|
|
30
|
-
options: config.options || {},
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 获取方法的Handler元数据列表
|
|
36
|
-
*/
|
|
37
|
-
export function getHandlerMetadata(
|
|
38
|
-
target: any,
|
|
39
|
-
methodName: string | symbol
|
|
40
|
-
): HandlerMetadata[] {
|
|
41
|
-
const allMetadata = getAllMetadata(target, HANDLER_METADATA_KEY);
|
|
42
|
-
const metadataList = allMetadata.get(methodName) || [];
|
|
43
|
-
const prototype = target.prototype || target;
|
|
44
|
-
|
|
45
|
-
// 转换为HandlerMetadata格式,补充method和module信息
|
|
46
|
-
return metadataList.map((meta) => ({
|
|
47
|
-
...meta,
|
|
48
|
-
method: prototype[methodName],
|
|
49
|
-
methodName: String(methodName),
|
|
50
|
-
module: prototype.constructor,
|
|
51
|
-
})) as HandlerMetadata[];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* 获取类的所有Handler元数据
|
|
56
|
-
*/
|
|
57
|
-
export function getAllHandlerMetadata(
|
|
58
|
-
target: any
|
|
59
|
-
): Map<string | symbol, HandlerMetadata[]> {
|
|
60
|
-
const allMetadata = getAllMetadata(target, HANDLER_METADATA_KEY);
|
|
61
|
-
const result = new Map<string | symbol, HandlerMetadata[]>();
|
|
62
|
-
|
|
63
|
-
for (const [methodName, metadataList] of allMetadata.entries()) {
|
|
64
|
-
result.set(methodName, metadataList as HandlerMetadata[]);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return result;
|
|
68
|
-
}
|
package/src/core/engine.test.ts
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { Route, RoutePlugin } from "../plugins/route";
|
|
3
|
-
import { Handler } from "./decorators";
|
|
4
|
-
import { DuplicateModuleError } from "./errors";
|
|
5
|
-
import { Testing } from "./testing";
|
|
6
|
-
import { Plugin } from "./types";
|
|
7
|
-
|
|
8
|
-
describe("MicroserviceEngine", () => {
|
|
9
|
-
let engine: ReturnType<typeof Testing.createTestEngine>["engine"];
|
|
10
|
-
let Module: ReturnType<typeof Testing.createTestEngine>["Module"];
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
// 每个测试都会创建新的 Factory,使用不同的 key,自动隔离
|
|
14
|
-
const testEngine = Testing.createTestEngine({ plugins: [] });
|
|
15
|
-
engine = testEngine.engine;
|
|
16
|
-
Module = testEngine.Module;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe("Module装饰器", () => {
|
|
20
|
-
it("应该能够使用Module装饰器装饰类", () => {
|
|
21
|
-
@Module("test-module")
|
|
22
|
-
class TestService {}
|
|
23
|
-
|
|
24
|
-
const modules = engine.getModules();
|
|
25
|
-
expect(modules).toHaveLength(1);
|
|
26
|
-
expect(modules[0].name).toBe("test-module");
|
|
27
|
-
expect(modules[0].clazz).toBe(TestService);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("应该防止重复注册同名模块", () => {
|
|
31
|
-
@Module("test-module")
|
|
32
|
-
class TestService1 {}
|
|
33
|
-
|
|
34
|
-
@Module("test-module")
|
|
35
|
-
class TestService2 {}
|
|
36
|
-
|
|
37
|
-
// 错误会在引擎加载模块时抛出(调用 getModules 或 start)
|
|
38
|
-
expect(() => {
|
|
39
|
-
engine.getModules();
|
|
40
|
-
}).toThrow(DuplicateModuleError);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("应该支持模块配置", () => {
|
|
44
|
-
@Module("test-module", {
|
|
45
|
-
routePrefix: "/api",
|
|
46
|
-
})
|
|
47
|
-
class TestService {}
|
|
48
|
-
|
|
49
|
-
const modules = engine.getModules();
|
|
50
|
-
expect(modules[0].options.routePrefix).toBe("/api");
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe("引擎启动", () => {
|
|
55
|
-
it("应该能够启动引擎", async () => {
|
|
56
|
-
const plugin: Plugin = {
|
|
57
|
-
name: "test-plugin",
|
|
58
|
-
onInit: vi.fn(),
|
|
59
|
-
onModuleLoad: vi.fn(),
|
|
60
|
-
onHandlerLoad: vi.fn(),
|
|
61
|
-
onBeforeStart: vi.fn(),
|
|
62
|
-
onAfterStart: vi.fn(),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// 使用 Testing 创建带插件的引擎
|
|
66
|
-
const { engine: testEngine, Module: TestModule } =
|
|
67
|
-
Testing.createTestEngine({
|
|
68
|
-
plugins: [plugin],
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
@TestModule("test-module")
|
|
72
|
-
class TestService {
|
|
73
|
-
@Handler({ type: "test" })
|
|
74
|
-
getUser() {}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
await testEngine.start();
|
|
78
|
-
|
|
79
|
-
expect(plugin.onInit).toHaveBeenCalled();
|
|
80
|
-
expect(plugin.onModuleLoad).toHaveBeenCalled();
|
|
81
|
-
expect(plugin.onHandlerLoad).toHaveBeenCalled();
|
|
82
|
-
expect(plugin.onBeforeStart).toHaveBeenCalled();
|
|
83
|
-
expect(plugin.onAfterStart).toHaveBeenCalled();
|
|
84
|
-
|
|
85
|
-
await testEngine.stop();
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("应该防止重复启动", async () => {
|
|
89
|
-
await engine.start();
|
|
90
|
-
|
|
91
|
-
await expect(engine.start()).rejects.toThrow("already started");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("应该能够停止引擎", async () => {
|
|
95
|
-
const plugin: Plugin = {
|
|
96
|
-
name: "test-plugin",
|
|
97
|
-
onDestroy: vi.fn(),
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const { engine: testEngine } = Testing.createTestEngine({
|
|
101
|
-
plugins: [plugin],
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
await testEngine.start();
|
|
105
|
-
await testEngine.stop();
|
|
106
|
-
|
|
107
|
-
expect(plugin.onDestroy).toHaveBeenCalled();
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe("模块实例管理", () => {
|
|
112
|
-
it("应该能够获取模块实例(单例)", () => {
|
|
113
|
-
@Module("test-module")
|
|
114
|
-
class TestService {}
|
|
115
|
-
|
|
116
|
-
const instance1 = engine.get(TestService);
|
|
117
|
-
const instance2 = engine.get(TestService);
|
|
118
|
-
|
|
119
|
-
expect(instance1).toBe(instance2); // 应该是同一个实例
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
describe("配置管理", () => {
|
|
124
|
-
it("应该能够获取引擎配置", () => {
|
|
125
|
-
expect(engine.options.name).toBe("test-service");
|
|
126
|
-
expect(engine.options.version).toBe("1.0.0");
|
|
127
|
-
expect(engine.options.hostname).toBe("0.0.0.0");
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("应该使用默认配置", () => {
|
|
131
|
-
const { engine: defaultEngine } = Testing.createTestEngine({
|
|
132
|
-
plugins: [],
|
|
133
|
-
options: {
|
|
134
|
-
name: "default-service",
|
|
135
|
-
version: "1.0.0",
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
expect(defaultEngine.options.hostname).toBe("0.0.0.0");
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("配置应该是冻结的,无法修改", () => {
|
|
143
|
-
expect(() => {
|
|
144
|
-
(engine.options as any).name = "modified";
|
|
145
|
-
}).toThrow();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("应该能够获取实际使用的端口", async () => {
|
|
149
|
-
const port = await engine.start();
|
|
150
|
-
expect(port).toBeGreaterThanOrEqual(3000);
|
|
151
|
-
expect(engine.getPort()).toBe(port);
|
|
152
|
-
await engine.stop();
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
describe("版本路由", () => {
|
|
157
|
-
it("应该自动注册版本路由", async () => {
|
|
158
|
-
const port = await engine.start();
|
|
159
|
-
const response = await fetch(`http://127.0.0.1:${port}`);
|
|
160
|
-
expect(response.ok).toBe(true);
|
|
161
|
-
const data = await response.json();
|
|
162
|
-
expect(data).toEqual({
|
|
163
|
-
name: "test-service",
|
|
164
|
-
version: "1.0.0",
|
|
165
|
-
status: "running",
|
|
166
|
-
});
|
|
167
|
-
await engine.stop();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("应该支持引擎 prefix", async () => {
|
|
171
|
-
const { engine: testEngine } = Testing.createTestEngine({
|
|
172
|
-
plugins: [],
|
|
173
|
-
options: {
|
|
174
|
-
name: "test-service",
|
|
175
|
-
version: "1.0.0",
|
|
176
|
-
prefix: "/api",
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const port = await testEngine.start();
|
|
181
|
-
const response = await fetch(`http://127.0.0.1:${port}/api`);
|
|
182
|
-
expect(response.ok).toBe(true);
|
|
183
|
-
const data = await response.json();
|
|
184
|
-
expect(data).toEqual({
|
|
185
|
-
name: "test-service",
|
|
186
|
-
version: "1.0.0",
|
|
187
|
-
status: "running",
|
|
188
|
-
});
|
|
189
|
-
await testEngine.stop();
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it("如果用户已注册版本路由,应该跳过注册", async () => {
|
|
193
|
-
const { engine: testEngine, Module: TestModule } =
|
|
194
|
-
Testing.createTestEngine({
|
|
195
|
-
plugins: [new RoutePlugin()],
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
@TestModule("test-module")
|
|
199
|
-
class TestService {
|
|
200
|
-
@Route({
|
|
201
|
-
method: "GET",
|
|
202
|
-
path: "/version",
|
|
203
|
-
})
|
|
204
|
-
getVersion() {
|
|
205
|
-
return { custom: "version" };
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const port = await testEngine.start();
|
|
210
|
-
const response = await fetch(`http://127.0.0.1:${port}/version`);
|
|
211
|
-
expect(response.ok).toBe(true);
|
|
212
|
-
// 应该返回用户自定义的版本路由,而不是引擎的版本路由
|
|
213
|
-
const data = await response.json();
|
|
214
|
-
expect(data).toEqual({ custom: "version" });
|
|
215
|
-
await testEngine.stop();
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
});
|