@xiaozhi-client/cli 1.9.4-beta.9 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/Container.ts +4 -4
- package/src/commands/CommandHandlerFactory.ts +5 -13
- package/src/commands/ServiceCommandHandler.ts +1 -1
- package/src/commands/__tests__/McpCommandHandler.test.ts +2 -2
- package/src/global.d.ts +4 -0
- package/src/index.ts +1 -10
- package/src/services/__tests__/DaemonManager.test.ts +4 -4
- package/src/services/__tests__/DaemonMode.integration.test.ts +3 -3
- package/src/services/__tests__/ProcessManager.test.ts +6 -6
- package/src/services/__tests__/ServiceManager.test.ts +5 -5
- package/src/services/__tests__/TemplateManager.test.ts +7 -7
- package/src/utils/VersionUtils.ts +8 -85
- package/src/utils/__tests__/PathUtils.test.ts +3 -3
- package/src/utils/__tests__/VersionUtils.test.ts +16 -310
- package/src/version.ts +5 -0
- package/tsconfig.json +6 -27
- package/tsup.config.ts +11 -2
- package/vitest.config.ts +5 -11
- package/fix-imports.js +0 -32
package/README.md
CHANGED
package/package.json
CHANGED
package/src/Container.ts
CHANGED
|
@@ -140,18 +140,18 @@ export class DIContainer implements IDIContainer {
|
|
|
140
140
|
|
|
141
141
|
// 注册服务层
|
|
142
142
|
container.registerSingleton("processManager", () => {
|
|
143
|
-
const ProcessManagerModule = require("
|
|
143
|
+
const ProcessManagerModule = require("./services/ProcessManager.js");
|
|
144
144
|
return new ProcessManagerModule.ProcessManagerImpl();
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
container.registerSingleton("daemonManager", () => {
|
|
148
|
-
const DaemonManagerModule = require("
|
|
148
|
+
const DaemonManagerModule = require("./services/DaemonManager.js");
|
|
149
149
|
const processManager = container.get("processManager") as any;
|
|
150
150
|
return new DaemonManagerModule.DaemonManagerImpl(processManager);
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
container.registerSingleton("serviceManager", () => {
|
|
154
|
-
const ServiceManagerModule = require("
|
|
154
|
+
const ServiceManagerModule = require("./services/ServiceManager.js");
|
|
155
155
|
const processManager = container.get("processManager") as any;
|
|
156
156
|
const configManager = container.get("configManager") as any;
|
|
157
157
|
return new ServiceManagerModule.ServiceManagerImpl(
|
|
@@ -162,7 +162,7 @@ export class DIContainer implements IDIContainer {
|
|
|
162
162
|
|
|
163
163
|
container.registerSingleton("templateManager", () => {
|
|
164
164
|
// 使用动态导入的同步版本
|
|
165
|
-
const TemplateManagerModule = require("
|
|
165
|
+
const TemplateManagerModule = require("./services/TemplateManager.js");
|
|
166
166
|
return new TemplateManagerModule.TemplateManagerImpl();
|
|
167
167
|
});
|
|
168
168
|
|
|
@@ -52,9 +52,7 @@ export class CommandHandlerFactory implements ICommandHandlerFactory {
|
|
|
52
52
|
*/
|
|
53
53
|
private createServiceCommandHandler(): CommandHandler {
|
|
54
54
|
// 动态导入以避免循环依赖
|
|
55
|
-
const {
|
|
56
|
-
ServiceCommandHandler,
|
|
57
|
-
} = require("@cli/commands/ServiceCommandHandler.js");
|
|
55
|
+
const { ServiceCommandHandler } = require("./ServiceCommandHandler.js");
|
|
58
56
|
return new ServiceCommandHandler(this.container);
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -62,9 +60,7 @@ export class CommandHandlerFactory implements ICommandHandlerFactory {
|
|
|
62
60
|
* 创建配置命令处理器
|
|
63
61
|
*/
|
|
64
62
|
private createConfigCommandHandler(): CommandHandler {
|
|
65
|
-
const {
|
|
66
|
-
ConfigCommandHandler,
|
|
67
|
-
} = require("@cli/commands/ConfigCommandHandler.js");
|
|
63
|
+
const { ConfigCommandHandler } = require("./ConfigCommandHandler.js");
|
|
68
64
|
return new ConfigCommandHandler(this.container);
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -72,9 +68,7 @@ export class CommandHandlerFactory implements ICommandHandlerFactory {
|
|
|
72
68
|
* 创建项目命令处理器
|
|
73
69
|
*/
|
|
74
70
|
private createProjectCommandHandler(): CommandHandler {
|
|
75
|
-
const {
|
|
76
|
-
ProjectCommandHandler,
|
|
77
|
-
} = require("@cli/commands/ProjectCommandHandler.js");
|
|
71
|
+
const { ProjectCommandHandler } = require("./ProjectCommandHandler.js");
|
|
78
72
|
return new ProjectCommandHandler(this.container);
|
|
79
73
|
}
|
|
80
74
|
|
|
@@ -82,7 +76,7 @@ export class CommandHandlerFactory implements ICommandHandlerFactory {
|
|
|
82
76
|
* 创建MCP命令处理器
|
|
83
77
|
*/
|
|
84
78
|
private createMcpCommandHandler(): CommandHandler {
|
|
85
|
-
const { McpCommandHandler } = require("
|
|
79
|
+
const { McpCommandHandler } = require("./McpCommandHandler.js");
|
|
86
80
|
return new McpCommandHandler(this.container);
|
|
87
81
|
}
|
|
88
82
|
|
|
@@ -90,9 +84,7 @@ export class CommandHandlerFactory implements ICommandHandlerFactory {
|
|
|
90
84
|
* 创建端点命令处理器
|
|
91
85
|
*/
|
|
92
86
|
private createEndpointCommandHandler(): CommandHandler {
|
|
93
|
-
const {
|
|
94
|
-
EndpointCommandHandler,
|
|
95
|
-
} = require("@cli/commands/EndpointCommandHandler.js");
|
|
87
|
+
const { EndpointCommandHandler } = require("./EndpointCommandHandler.js");
|
|
96
88
|
return new EndpointCommandHandler(this.container);
|
|
97
89
|
}
|
|
98
90
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { IDIContainer } from "@cli/interfaces/Config.js";
|
|
2
1
|
import { configManager } from "@xiaozhi-client/config";
|
|
3
2
|
import type {
|
|
4
3
|
MCPServerConfig,
|
|
@@ -7,6 +6,7 @@ import type {
|
|
|
7
6
|
} from "@xiaozhi-client/config";
|
|
8
7
|
import ora from "ora";
|
|
9
8
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
9
|
+
import type { IDIContainer } from "../../interfaces/Config.js";
|
|
10
10
|
import { McpCommandHandler } from "../McpCommandHandler.js";
|
|
11
11
|
|
|
12
12
|
// 测试专用类型定义
|
|
@@ -143,7 +143,7 @@ const mockGetServiceStatus = vi
|
|
|
143
143
|
.fn()
|
|
144
144
|
.mockReturnValue({ running: false, pid: null });
|
|
145
145
|
|
|
146
|
-
vi.mock("
|
|
146
|
+
vi.mock("../../services/ProcessManager.js", () => ({
|
|
147
147
|
ProcessManagerImpl: vi.fn().mockImplementation(() => ({
|
|
148
148
|
getServiceStatus: mockGetServiceStatus,
|
|
149
149
|
})),
|
package/src/global.d.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -39,15 +39,6 @@ async function initializeCLI(): Promise<void> {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
// 使用更可靠的检测方法,兼容 Windows 路径
|
|
44
|
-
// 将路径转换为 URL 格式进行比较
|
|
45
|
-
const scriptPath = process.argv[1].replace(/\\/g, "/");
|
|
46
|
-
const isMainModule =
|
|
47
|
-
import.meta.url === `file:///${scriptPath}` ||
|
|
48
|
-
import.meta.url === `file://${scriptPath}`;
|
|
49
|
-
if (isMainModule) {
|
|
50
|
-
initializeCLI();
|
|
51
|
-
}
|
|
42
|
+
initializeCLI();
|
|
52
43
|
|
|
53
44
|
export { initializeCLI };
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* 守护进程管理服务单元测试
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { ServiceError } from "@cli/errors/index.js";
|
|
6
|
-
import type { ProcessManager } from "@cli/interfaces/Service.js";
|
|
7
5
|
import consola from "consola";
|
|
8
6
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { ServiceError } from "../../errors/index.js";
|
|
8
|
+
import type { ProcessManager } from "../../interfaces/Service.js";
|
|
9
9
|
import type { DaemonOptions } from "../DaemonManager";
|
|
10
10
|
import { DaemonManagerImpl } from "../DaemonManager";
|
|
11
11
|
|
|
@@ -49,7 +49,7 @@ vi.mock("node:fs", () => ({
|
|
|
49
49
|
}));
|
|
50
50
|
|
|
51
51
|
// Mock utils
|
|
52
|
-
vi.mock("
|
|
52
|
+
vi.mock("../../utils/PathUtils.js", () => ({
|
|
53
53
|
PathUtils: {
|
|
54
54
|
getWebServerLauncherPath: vi.fn(() => "/path/to/webserver.js"),
|
|
55
55
|
getConfigDir: vi.fn(() => "/config"),
|
|
@@ -57,7 +57,7 @@ vi.mock("@cli/utils/PathUtils.js", () => ({
|
|
|
57
57
|
},
|
|
58
58
|
}));
|
|
59
59
|
|
|
60
|
-
vi.mock("
|
|
60
|
+
vi.mock("../../utils/PlatformUtils.js", () => ({
|
|
61
61
|
PlatformUtils: {
|
|
62
62
|
getTailCommand: vi.fn(() => ({
|
|
63
63
|
command: "tail",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ServiceStartOptions } from "@cli/interfaces/Service.js";
|
|
2
|
-
import { PathUtils } from "@cli/utils/PathUtils.js";
|
|
3
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { ServiceStartOptions } from "../../interfaces/Service.js";
|
|
3
|
+
import { PathUtils } from "../../utils/PathUtils.js";
|
|
4
4
|
import { ServiceManagerImpl } from "../ServiceManager";
|
|
5
5
|
|
|
6
6
|
// Mock external dependencies
|
|
@@ -19,7 +19,7 @@ vi.mock("node:fs", () => ({
|
|
|
19
19
|
mkdirSync: vi.fn(),
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
|
-
vi.mock("
|
|
22
|
+
vi.mock("../../utils/PathUtils.js", () => ({
|
|
23
23
|
PathUtils: {
|
|
24
24
|
getWebServerLauncherPath: vi.fn(),
|
|
25
25
|
getExecutablePath: vi.fn(),
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* 进程管理服务单元测试
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { FileUtils } from "@cli/utils/FileUtils.js";
|
|
6
|
-
import { PathUtils } from "@cli/utils/PathUtils.js";
|
|
7
|
-
import { PlatformUtils } from "@cli/utils/PlatformUtils.js";
|
|
8
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { FileUtils } from "../../utils/FileUtils.js";
|
|
7
|
+
import { PathUtils } from "../../utils/PathUtils.js";
|
|
8
|
+
import { PlatformUtils } from "../../utils/PlatformUtils.js";
|
|
9
9
|
import { ProcessManagerImpl } from "../ProcessManager";
|
|
10
10
|
|
|
11
11
|
// Mock 依赖
|
|
12
|
-
vi.mock("
|
|
13
|
-
vi.mock("
|
|
14
|
-
vi.mock("
|
|
12
|
+
vi.mock("../../utils/FileUtils.js");
|
|
13
|
+
vi.mock("../../utils/PathUtils.js");
|
|
14
|
+
vi.mock("../../utils/PlatformUtils.js");
|
|
15
15
|
|
|
16
16
|
const mockFileUtils = vi.mocked(FileUtils);
|
|
17
17
|
const mockPathUtils = vi.mocked(PathUtils);
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* 服务管理服务单元测试
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { ConfigError, ServiceError } from "../../errors/index.js";
|
|
6
7
|
import type {
|
|
7
8
|
ProcessManager,
|
|
8
9
|
ServiceStartOptions,
|
|
9
|
-
} from "
|
|
10
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
10
|
+
} from "../../interfaces/Service.js";
|
|
11
11
|
import { ServiceManagerImpl } from "../ServiceManager";
|
|
12
12
|
|
|
13
13
|
// Mock 依赖
|
|
@@ -62,7 +62,7 @@ vi.mock("@services/MCPServer.js", () => ({
|
|
|
62
62
|
}));
|
|
63
63
|
|
|
64
64
|
// Mock PathUtils
|
|
65
|
-
vi.mock("
|
|
65
|
+
vi.mock("../../utils/PathUtils.js", () => ({
|
|
66
66
|
PathUtils: {
|
|
67
67
|
getWebServerLauncherPath: vi
|
|
68
68
|
.fn()
|
|
@@ -158,7 +158,7 @@ describe("ServiceManagerImpl 服务管理器实现", () => {
|
|
|
158
158
|
mockProcessExit.mockClear();
|
|
159
159
|
|
|
160
160
|
// Reset PathUtils mocks
|
|
161
|
-
const { PathUtils } = await import("
|
|
161
|
+
const { PathUtils } = await import("../../utils/PathUtils.js");
|
|
162
162
|
vi.mocked(PathUtils.getWebServerLauncherPath).mockReturnValue(
|
|
163
163
|
"/mock/path/WebServerLauncher.js"
|
|
164
164
|
);
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
* 模板管理服务单元测试
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { FileError, ValidationError } from "@cli/errors/index.js";
|
|
6
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { FileError, ValidationError } from "../../errors/index.js";
|
|
7
7
|
import type { TemplateCreateOptions } from "../TemplateManager";
|
|
8
8
|
import { TemplateManagerImpl } from "../TemplateManager";
|
|
9
9
|
|
|
10
10
|
// Mock 依赖
|
|
11
|
-
vi.mock("
|
|
11
|
+
vi.mock("../../utils/PathUtils.js", () => ({
|
|
12
12
|
PathUtils: {
|
|
13
13
|
findTemplatesDir: vi.fn(),
|
|
14
14
|
getTemplatePath: vi.fn(),
|
|
15
15
|
},
|
|
16
16
|
}));
|
|
17
17
|
|
|
18
|
-
vi.mock("
|
|
18
|
+
vi.mock("../../utils/FileUtils.js", () => ({
|
|
19
19
|
FileUtils: {
|
|
20
20
|
exists: vi.fn(),
|
|
21
21
|
readFile: vi.fn(),
|
|
@@ -26,7 +26,7 @@ vi.mock("@cli/utils/FileUtils.js", () => ({
|
|
|
26
26
|
},
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
-
vi.mock("
|
|
29
|
+
vi.mock("../../utils/Validation.js", () => ({
|
|
30
30
|
Validation: {
|
|
31
31
|
validateTemplateName: vi.fn(),
|
|
32
32
|
validateRequired: vi.fn(),
|
|
@@ -48,9 +48,9 @@ vi.mock("node:path", () => ({
|
|
|
48
48
|
},
|
|
49
49
|
}));
|
|
50
50
|
|
|
51
|
-
const { PathUtils } = await import("
|
|
52
|
-
const { FileUtils } = await import("
|
|
53
|
-
const { Validation } = await import("
|
|
51
|
+
const { PathUtils } = await import("../../utils/PathUtils.js");
|
|
52
|
+
const { FileUtils } = await import("../../utils/FileUtils.js");
|
|
53
|
+
const { Validation } = await import("../../utils/Validation.js");
|
|
54
54
|
const fs = await import("node:fs");
|
|
55
55
|
|
|
56
56
|
describe("TemplateManagerImpl", () => {
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
* 版本管理工具
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { FileError } from "../errors/index";
|
|
5
|
+
import { APP_NAME, VERSION } from "../version";
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* 版本信息接口
|
|
@@ -21,88 +18,21 @@ export interface VersionInfo {
|
|
|
21
18
|
* 版本工具类
|
|
22
19
|
*/
|
|
23
20
|
export class VersionUtils {
|
|
24
|
-
private static cachedVersion: string | null = null;
|
|
25
|
-
|
|
26
21
|
/**
|
|
27
|
-
*
|
|
22
|
+
* 获取版本号(构建时注入)
|
|
28
23
|
*/
|
|
29
24
|
static getVersion(): string {
|
|
30
|
-
|
|
31
|
-
return VersionUtils.cachedVersion;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
// 在 ES 模块环境中获取当前目录
|
|
36
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
37
|
-
const currentDir = path.dirname(__filename);
|
|
38
|
-
|
|
39
|
-
// 尝试多个可能的 package.json 路径
|
|
40
|
-
const possiblePaths = [
|
|
41
|
-
// 构建后环境:dist/cli.js -> dist/package.json (优先)
|
|
42
|
-
path.join(currentDir, "package.json"),
|
|
43
|
-
// 构建后环境:dist/cli.js -> package.json
|
|
44
|
-
path.join(currentDir, "..", "package.json"),
|
|
45
|
-
// 开发环境:src/cli/utils/VersionUtils.ts -> package.json
|
|
46
|
-
path.join(currentDir, "..", "..", "..", "package.json"),
|
|
47
|
-
// 全局安装环境
|
|
48
|
-
path.join(currentDir, "..", "..", "..", "..", "package.json"),
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
for (const packagePath of possiblePaths) {
|
|
52
|
-
if (fs.existsSync(packagePath)) {
|
|
53
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
54
|
-
if (packageJson.version) {
|
|
55
|
-
VersionUtils.cachedVersion = packageJson.version;
|
|
56
|
-
return packageJson.version;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// 如果都找不到,返回默认版本
|
|
62
|
-
VersionUtils.cachedVersion = "unknown";
|
|
63
|
-
return "unknown";
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.warn("无法从 package.json 读取版本信息:", error);
|
|
66
|
-
VersionUtils.cachedVersion = "unknown";
|
|
67
|
-
return "unknown";
|
|
68
|
-
}
|
|
25
|
+
return VERSION;
|
|
69
26
|
}
|
|
70
27
|
|
|
71
28
|
/**
|
|
72
|
-
*
|
|
29
|
+
* 获取完整版本信息(构建时注入)
|
|
73
30
|
*/
|
|
74
31
|
static getVersionInfo(): VersionInfo {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const possiblePaths = [
|
|
80
|
-
// 构建后环境:dist/cli.js -> dist/package.json (优先)
|
|
81
|
-
path.join(currentDir, "package.json"),
|
|
82
|
-
// 构建后环境:dist/cli.js -> package.json
|
|
83
|
-
path.join(currentDir, "..", "package.json"),
|
|
84
|
-
// 开发环境:src/cli/utils/VersionUtils.ts -> package.json
|
|
85
|
-
path.join(currentDir, "..", "..", "..", "package.json"),
|
|
86
|
-
// 全局安装环境
|
|
87
|
-
path.join(currentDir, "..", "..", "..", "..", "package.json"),
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
for (const packagePath of possiblePaths) {
|
|
91
|
-
if (fs.existsSync(packagePath)) {
|
|
92
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
93
|
-
return {
|
|
94
|
-
version: packageJson.version || "unknown",
|
|
95
|
-
name: packageJson.name,
|
|
96
|
-
description: packageJson.description,
|
|
97
|
-
author: packageJson.author,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return { version: "unknown" };
|
|
103
|
-
} catch (error) {
|
|
104
|
-
throw new FileError("无法读取版本信息", "package.json");
|
|
105
|
-
}
|
|
32
|
+
return {
|
|
33
|
+
version: VERSION,
|
|
34
|
+
name: APP_NAME,
|
|
35
|
+
};
|
|
106
36
|
}
|
|
107
37
|
|
|
108
38
|
/**
|
|
@@ -131,11 +61,4 @@ export class VersionUtils {
|
|
|
131
61
|
const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
|
|
132
62
|
return versionRegex.test(version);
|
|
133
63
|
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* 清除版本缓存
|
|
137
|
-
*/
|
|
138
|
-
static clearCache(): void {
|
|
139
|
-
VersionUtils.cachedVersion = null;
|
|
140
|
-
}
|
|
141
64
|
}
|
|
@@ -2,11 +2,11 @@ import { realpathSync } from "node:fs";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { PathUtils } from "@cli/utils/PathUtils.js";
|
|
6
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { PathUtils } from "../PathUtils.js";
|
|
7
7
|
|
|
8
8
|
// Mock dependencies - 需要使用与源文件相同的导入方式
|
|
9
|
-
vi.mock("
|
|
9
|
+
vi.mock("../FileUtils.js", () => ({
|
|
10
10
|
FileUtils: {
|
|
11
11
|
exists: vi.fn(),
|
|
12
12
|
},
|
|
@@ -38,7 +38,7 @@ describe("PathUtils 路径工具", () => {
|
|
|
38
38
|
vi.clearAllMocks();
|
|
39
39
|
|
|
40
40
|
// Setup mocks
|
|
41
|
-
const { FileUtils } = await import("
|
|
41
|
+
const { FileUtils } = await import("../FileUtils.js");
|
|
42
42
|
mockFileExists = vi.mocked(FileUtils.exists);
|
|
43
43
|
mockTmpdir = vi.mocked(tmpdir);
|
|
44
44
|
mockFileURLToPath = vi.mocked(fileURLToPath);
|
|
@@ -2,261 +2,43 @@
|
|
|
2
2
|
* 版本管理工具单元测试
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
9
|
-
import { FileError } from "../../errors/index";
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
10
6
|
import { VersionUtils } from "../VersionUtils";
|
|
11
7
|
|
|
12
|
-
// Mock fileURLToPath
|
|
13
|
-
vi.mock("node:url");
|
|
14
|
-
const mockedFileURLToPath = vi.mocked(fileURLToPath);
|
|
15
|
-
|
|
16
|
-
// Mock path module
|
|
17
|
-
vi.mock("node:path");
|
|
18
|
-
const mockedPath = vi.mocked(path);
|
|
19
|
-
|
|
20
|
-
// Mock fs module
|
|
21
|
-
vi.mock("node:fs");
|
|
22
|
-
const mockedFs = vi.mocked(fs);
|
|
23
|
-
|
|
24
8
|
describe("VersionUtils", () => {
|
|
25
|
-
beforeEach
|
|
26
|
-
|
|
27
|
-
// Clear static cache
|
|
28
|
-
VersionUtils.clearCache();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
vi.restoreAllMocks();
|
|
33
|
-
});
|
|
9
|
+
// 不再需要 beforeEach 和 afterEach,因为不再使用缓存
|
|
10
|
+
// 也不再需要 mock fs、path、url 模块,因为不再读取文件
|
|
34
11
|
|
|
35
12
|
describe("获取版本号", () => {
|
|
36
|
-
it("
|
|
37
|
-
// Set cache directly
|
|
38
|
-
VersionUtils.clearCache();
|
|
39
|
-
(VersionUtils as any).cachedVersion = "1.0.0";
|
|
40
|
-
|
|
41
|
-
const result = VersionUtils.getVersion();
|
|
42
|
-
|
|
43
|
-
expect(result).toBe("1.0.0");
|
|
44
|
-
expect(mockedFs.existsSync).not.toHaveBeenCalled();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("应从dist目录中的package.json读取版本号", () => {
|
|
48
|
-
const mockPackageJson = { version: "1.2.3", name: "test-package" };
|
|
49
|
-
|
|
50
|
-
// Mock fileURLToPath
|
|
51
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
52
|
-
|
|
53
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
54
|
-
mockedPath.join
|
|
55
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
56
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
57
|
-
.mockReturnValueOnce("/package.json")
|
|
58
|
-
.mockReturnValueOnce("/../package.json");
|
|
59
|
-
|
|
60
|
-
mockedFs.existsSync.mockImplementation((filePath) => {
|
|
61
|
-
return filePath === "/dist/cli/utils/package.json";
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
65
|
-
|
|
66
|
-
const result = VersionUtils.getVersion();
|
|
67
|
-
|
|
68
|
-
expect(result).toBe("1.2.3");
|
|
69
|
-
expect(mockedFs.existsSync).toHaveBeenCalledWith(
|
|
70
|
-
"/dist/cli/utils/package.json"
|
|
71
|
-
);
|
|
72
|
-
expect(mockedFs.readFileSync).toHaveBeenCalledWith(
|
|
73
|
-
"/dist/cli/utils/package.json",
|
|
74
|
-
"utf8"
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("当前目录中未找到时应从父级package.json读取版本号", () => {
|
|
79
|
-
const mockPackageJson = { version: "2.0.0", name: "test-package" };
|
|
80
|
-
|
|
81
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
82
|
-
|
|
83
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
84
|
-
mockedPath.join
|
|
85
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
86
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
87
|
-
.mockReturnValueOnce("/package.json")
|
|
88
|
-
.mockReturnValueOnce("/../package.json");
|
|
89
|
-
|
|
90
|
-
mockedFs.existsSync.mockImplementation((filePath) => {
|
|
91
|
-
return filePath === "/package.json";
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
95
|
-
|
|
13
|
+
it("应返回编译时注入的版本号", () => {
|
|
96
14
|
const result = VersionUtils.getVersion();
|
|
97
|
-
|
|
98
|
-
expect(result).toBe("
|
|
99
|
-
expect(mockedFs.existsSync).toHaveBeenCalledTimes(3);
|
|
100
|
-
expect(mockedFs.readFileSync).toHaveBeenCalledWith(
|
|
101
|
-
"/package.json",
|
|
102
|
-
"utf8"
|
|
103
|
-
);
|
|
15
|
+
// 在测试环境中,版本号被定义为 "1.0.0-test"
|
|
16
|
+
expect(result).toBe("1.0.0-test");
|
|
104
17
|
});
|
|
105
18
|
|
|
106
|
-
it("
|
|
107
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
108
|
-
|
|
109
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
110
|
-
mockedPath.join
|
|
111
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
112
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
113
|
-
.mockReturnValueOnce("/package.json")
|
|
114
|
-
.mockReturnValueOnce("/../package.json");
|
|
115
|
-
|
|
116
|
-
mockedFs.existsSync.mockReturnValue(false);
|
|
117
|
-
|
|
118
|
-
const result = VersionUtils.getVersion();
|
|
119
|
-
|
|
120
|
-
expect(result).toBe("unknown");
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("package.json没有版本字段时应返回 'unknown'", () => {
|
|
124
|
-
const mockPackageJson = { name: "test-package" };
|
|
125
|
-
|
|
126
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
127
|
-
|
|
128
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
129
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
130
|
-
|
|
131
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
132
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
133
|
-
|
|
134
|
-
const result = VersionUtils.getVersion();
|
|
135
|
-
|
|
136
|
-
expect(result).toBe("unknown");
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it("读取package.json失败时应返回 'unknown'", () => {
|
|
140
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
141
|
-
|
|
142
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
143
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
144
|
-
|
|
145
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
146
|
-
mockedFs.readFileSync.mockImplementation(() => {
|
|
147
|
-
throw new Error("Read error");
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const result = VersionUtils.getVersion();
|
|
151
|
-
|
|
152
|
-
expect(result).toBe("unknown");
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("首次成功读取后应缓存版本号", () => {
|
|
156
|
-
const mockPackageJson = { version: "1.0.0", name: "test-package" };
|
|
157
|
-
|
|
158
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
159
|
-
|
|
160
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
161
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
162
|
-
|
|
163
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
164
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
165
|
-
|
|
166
|
-
// First call
|
|
19
|
+
it("多次调用应返回相同的版本号", () => {
|
|
167
20
|
const result1 = VersionUtils.getVersion();
|
|
168
|
-
expect(result1).toBe("1.0.0");
|
|
169
|
-
expect(mockedFs.readFileSync).toHaveBeenCalledTimes(1);
|
|
170
|
-
|
|
171
|
-
// Second call should use cache
|
|
172
21
|
const result2 = VersionUtils.getVersion();
|
|
173
|
-
expect(
|
|
174
|
-
expect(
|
|
22
|
+
expect(result1).toBe(result2);
|
|
23
|
+
expect(result1).toBe("1.0.0-test");
|
|
175
24
|
});
|
|
176
25
|
});
|
|
177
26
|
|
|
178
27
|
describe("获取版本信息", () => {
|
|
179
|
-
it("
|
|
180
|
-
const mockPackageJson = {
|
|
181
|
-
version: "1.2.3",
|
|
182
|
-
name: "xiaozhi-client",
|
|
183
|
-
description: "A test package",
|
|
184
|
-
author: "Test Author",
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
188
|
-
|
|
189
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
190
|
-
mockedPath.join
|
|
191
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
192
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
193
|
-
.mockReturnValueOnce("/package.json")
|
|
194
|
-
.mockReturnValueOnce("/../package.json");
|
|
195
|
-
|
|
196
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
197
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
198
|
-
|
|
28
|
+
it("应返回完整的版本信息", () => {
|
|
199
29
|
const result = VersionUtils.getVersionInfo();
|
|
200
|
-
|
|
201
30
|
expect(result).toEqual({
|
|
202
|
-
version: "1.
|
|
31
|
+
version: "1.0.0-test",
|
|
203
32
|
name: "xiaozhi-client",
|
|
204
|
-
description: "A test package",
|
|
205
|
-
author: "Test Author",
|
|
206
33
|
});
|
|
207
34
|
});
|
|
208
35
|
|
|
209
|
-
it("
|
|
210
|
-
const mockPackageJson = { version: "1.0.0" };
|
|
211
|
-
|
|
212
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
213
|
-
|
|
214
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
215
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
216
|
-
|
|
217
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
218
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
219
|
-
|
|
36
|
+
it("应包含版本号和名称", () => {
|
|
220
37
|
const result = VersionUtils.getVersionInfo();
|
|
221
|
-
|
|
222
|
-
expect(result).
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
description: undefined,
|
|
226
|
-
author: undefined,
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it("未找到package.json时应返回默认版本信息", () => {
|
|
231
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
232
|
-
|
|
233
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
234
|
-
mockedPath.join
|
|
235
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
236
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
237
|
-
.mockReturnValueOnce("/package.json")
|
|
238
|
-
.mockReturnValueOnce("/../package.json");
|
|
239
|
-
|
|
240
|
-
mockedFs.existsSync.mockReturnValue(false);
|
|
241
|
-
|
|
242
|
-
const result = VersionUtils.getVersionInfo();
|
|
243
|
-
|
|
244
|
-
expect(result).toEqual({ version: "unknown" });
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it("读取失败时应抛出文件错误", () => {
|
|
248
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
249
|
-
|
|
250
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
251
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
252
|
-
|
|
253
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
254
|
-
mockedFs.readFileSync.mockImplementation(() => {
|
|
255
|
-
throw new Error("Read error");
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
expect(() => VersionUtils.getVersionInfo()).toThrow(FileError);
|
|
259
|
-
expect(() => VersionUtils.getVersionInfo()).toThrow("无法读取版本信息");
|
|
38
|
+
expect(result.version).toBeDefined();
|
|
39
|
+
expect(result.name).toBeDefined();
|
|
40
|
+
expect(typeof result.version).toBe("string");
|
|
41
|
+
expect(typeof result.name).toBe("string");
|
|
260
42
|
});
|
|
261
43
|
});
|
|
262
44
|
|
|
@@ -331,80 +113,4 @@ describe("VersionUtils", () => {
|
|
|
331
113
|
expect(VersionUtils.isValidVersion("1.0.0.1")).toBe(false);
|
|
332
114
|
});
|
|
333
115
|
});
|
|
334
|
-
|
|
335
|
-
describe("清除缓存", () => {
|
|
336
|
-
it("应清除缓存的版本号", () => {
|
|
337
|
-
// Set cache first
|
|
338
|
-
(VersionUtils as any).cachedVersion = "1.0.0";
|
|
339
|
-
|
|
340
|
-
VersionUtils.clearCache();
|
|
341
|
-
|
|
342
|
-
expect((VersionUtils as any).cachedVersion).toBeNull();
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it("应处理null缓存", () => {
|
|
346
|
-
// Ensure cache is null
|
|
347
|
-
VersionUtils.clearCache();
|
|
348
|
-
|
|
349
|
-
// Should not throw
|
|
350
|
-
VersionUtils.clearCache();
|
|
351
|
-
|
|
352
|
-
expect((VersionUtils as any).cachedVersion).toBeNull();
|
|
353
|
-
});
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
describe("集成测试", () => {
|
|
357
|
-
it("清除缓存后应正常工作", () => {
|
|
358
|
-
const mockPackageJson = { version: "1.0.0" };
|
|
359
|
-
|
|
360
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
361
|
-
|
|
362
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
363
|
-
mockedPath.join.mockReturnValue("/dist/cli/utils/package.json");
|
|
364
|
-
|
|
365
|
-
mockedFs.existsSync.mockReturnValue(true);
|
|
366
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
367
|
-
|
|
368
|
-
// First call
|
|
369
|
-
const result1 = VersionUtils.getVersion();
|
|
370
|
-
expect(result1).toBe("1.0.0");
|
|
371
|
-
|
|
372
|
-
// Clear cache
|
|
373
|
-
VersionUtils.clearCache();
|
|
374
|
-
|
|
375
|
-
// Should read file again
|
|
376
|
-
const result2 = VersionUtils.getVersion();
|
|
377
|
-
expect(result2).toBe("1.0.0");
|
|
378
|
-
expect(mockedFs.readFileSync).toHaveBeenCalledTimes(2);
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it("应正确处理多次路径尝试", () => {
|
|
382
|
-
const mockPackageJson = { version: "2.0.0" };
|
|
383
|
-
|
|
384
|
-
mockedFileURLToPath.mockReturnValue("/dist/cli/utils/VersionUtils.js");
|
|
385
|
-
|
|
386
|
-
mockedPath.dirname.mockReturnValue("/dist/cli/utils");
|
|
387
|
-
mockedPath.join
|
|
388
|
-
.mockReturnValueOnce("/dist/cli/utils/package.json")
|
|
389
|
-
.mockReturnValueOnce("/dist/cli/package.json")
|
|
390
|
-
.mockReturnValueOnce("/package.json")
|
|
391
|
-
.mockReturnValueOnce("/../package.json");
|
|
392
|
-
|
|
393
|
-
// Simulate finding package.json in the third attempt
|
|
394
|
-
mockedFs.existsSync.mockImplementation((filePath) => {
|
|
395
|
-
return filePath === "/package.json";
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockPackageJson));
|
|
399
|
-
|
|
400
|
-
const result = VersionUtils.getVersion();
|
|
401
|
-
|
|
402
|
-
expect(result).toBe("2.0.0");
|
|
403
|
-
expect(mockedFs.existsSync).toHaveBeenCalledTimes(3);
|
|
404
|
-
expect(mockedFs.readFileSync).toHaveBeenCalledWith(
|
|
405
|
-
"/package.json",
|
|
406
|
-
"utf8"
|
|
407
|
-
);
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
116
|
});
|
package/src/version.ts
ADDED
package/tsconfig.json
CHANGED
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
2
3
|
"compilerOptions": {
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"lib": ["ES2022"],
|
|
7
|
-
"strict": false,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"allowSyntheticDefaultImports": true,
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
"baseUrl": ".",
|
|
15
|
-
"moduleSuffixes": [".ts", ".js"],
|
|
16
|
-
"paths": {
|
|
17
|
-
"@/*": ["src/*"],
|
|
18
|
-
"@cli/commands": ["src/commands"],
|
|
19
|
-
"@cli/commands/*": ["src/commands/*"],
|
|
20
|
-
"@cli/services": ["src/services"],
|
|
21
|
-
"@cli/services/*": ["src/services/*"],
|
|
22
|
-
"@cli/utils": ["src/utils"],
|
|
23
|
-
"@cli/utils/*": ["src/utils/*"],
|
|
24
|
-
"@cli/errors": ["src/errors"],
|
|
25
|
-
"@cli/errors/*": ["src/errors/*"],
|
|
26
|
-
"@cli/interfaces": ["src/interfaces"],
|
|
27
|
-
"@cli/interfaces/*": ["src/interfaces/*"]
|
|
28
|
-
}
|
|
4
|
+
"composite": true,
|
|
5
|
+
"outDir": "../../dist/cli",
|
|
6
|
+
"rootDir": "src"
|
|
29
7
|
},
|
|
30
8
|
"include": ["src/**/*.ts"],
|
|
31
|
-
"exclude": ["node_modules", "dist", "**/*.test.ts",
|
|
9
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"],
|
|
10
|
+
"references": [{ "path": "../../apps/backend" }, { "path": "../config" }]
|
|
32
11
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { defineConfig } from "tsup";
|
|
4
4
|
|
|
5
|
+
// 读取根目录 package.json 获取版本号
|
|
6
|
+
const rootPkgPath = resolve("../../package.json");
|
|
7
|
+
const pkg = JSON.parse(readFileSync(rootPkgPath, "utf-8"));
|
|
8
|
+
|
|
5
9
|
export default defineConfig({
|
|
6
10
|
entry: {
|
|
7
11
|
index: "src/index.ts",
|
|
@@ -19,8 +23,13 @@ export default defineConfig({
|
|
|
19
23
|
platform: "node",
|
|
20
24
|
esbuildOptions: (options) => {
|
|
21
25
|
options.resolveExtensions = [".ts", ".js", ".json"];
|
|
22
|
-
|
|
23
|
-
//
|
|
26
|
+
|
|
27
|
+
// 构建时注入版本号常量
|
|
28
|
+
options.define = {
|
|
29
|
+
...options.define, // 保留已有的 define
|
|
30
|
+
__VERSION__: JSON.stringify(pkg.version),
|
|
31
|
+
__APP_NAME__: JSON.stringify(pkg.name),
|
|
32
|
+
};
|
|
24
33
|
},
|
|
25
34
|
external: [
|
|
26
35
|
// Node.js 内置模块
|
package/vitest.config.ts
CHANGED
|
@@ -13,6 +13,11 @@ export default defineConfig({
|
|
|
13
13
|
// 添加 tsconfig 路径解析插件
|
|
14
14
|
tsconfigPaths(),
|
|
15
15
|
],
|
|
16
|
+
// 定义构建时注入的全局变量,用于测试环境
|
|
17
|
+
define: {
|
|
18
|
+
__VERSION__: JSON.stringify("1.0.0-test"),
|
|
19
|
+
__APP_NAME__: JSON.stringify("xiaozhi-client"),
|
|
20
|
+
},
|
|
16
21
|
test: {
|
|
17
22
|
globals: true,
|
|
18
23
|
environment: "node",
|
|
@@ -46,17 +51,6 @@ export default defineConfig({
|
|
|
46
51
|
},
|
|
47
52
|
resolve: {
|
|
48
53
|
alias: {
|
|
49
|
-
// CLI 内部路径别名(__dirname 是 packages/cli,所以使用相对路径)
|
|
50
|
-
"@cli/commands": resolve(__dirname, "./src/commands"),
|
|
51
|
-
"@cli/commands/*": resolve(__dirname, "./src/commands/*"),
|
|
52
|
-
"@cli/services": resolve(__dirname, "./src/services"),
|
|
53
|
-
"@cli/services/*": resolve(__dirname, "./src/services/*"),
|
|
54
|
-
"@cli/utils": resolve(__dirname, "./src/utils"),
|
|
55
|
-
"@cli/utils/*": resolve(__dirname, "./src/utils/*"),
|
|
56
|
-
"@cli/errors": resolve(__dirname, "./src/errors"),
|
|
57
|
-
"@cli/errors/*": resolve(__dirname, "./src/errors/*"),
|
|
58
|
-
"@cli/interfaces": resolve(__dirname, "./src/interfaces"),
|
|
59
|
-
"@cli/interfaces/*": resolve(__dirname, "./src/interfaces/*"),
|
|
60
54
|
// Backend 路径别名(从 packages/cli 向上到项目根目录)
|
|
61
55
|
"@handlers": resolve(__dirname, "../../apps/backend/handlers"),
|
|
62
56
|
"@handlers/*": resolve(__dirname, "../../apps/backend/handlers/*"),
|
package/fix-imports.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 构建后处理脚本
|
|
3
|
-
* 将路径别名替换为相对路径
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
7
|
-
import { resolve } from "node:path";
|
|
8
|
-
|
|
9
|
-
const filePath = resolve("./dist/cli/index.js");
|
|
10
|
-
let content = readFileSync(filePath, "utf-8");
|
|
11
|
-
|
|
12
|
-
// 替换 @root/* 为指向 dist/backend 的相对路径
|
|
13
|
-
content = content
|
|
14
|
-
.replace(
|
|
15
|
-
/from "@\/lib\/config\/manager\.js"/g,
|
|
16
|
-
'from "../../dist/backend/lib/config/manager.js"'
|
|
17
|
-
)
|
|
18
|
-
.replace(
|
|
19
|
-
/from "@\/lib\/config\/manager"/g,
|
|
20
|
-
'from "../../dist/backend/lib/config/manager.js"'
|
|
21
|
-
)
|
|
22
|
-
.replace(
|
|
23
|
-
/from "@root\/WebServer\.js"/g,
|
|
24
|
-
'from "../../dist/backend/WebServer.js"'
|
|
25
|
-
)
|
|
26
|
-
.replace(
|
|
27
|
-
/from "@root\/WebServer"/g,
|
|
28
|
-
'from "../../dist/backend/WebServer.js"'
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
writeFileSync(filePath, content);
|
|
32
|
-
console.log("✅ 已修复 dist/cli/index.js 中的导入路径");
|