tanmi-dock 0.4.0-beta.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/LICENSE +21 -0
- package/README.md +302 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +215 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/config.d.ts +10 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +105 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +127 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +153 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link.d.ts +7 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +522 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/migrate.d.ts +7 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +137 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/projects.d.ts +7 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +126 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/repair.d.ts +7 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +256 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +172 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/unlink.d.ts +7 -0
- package/dist/commands/unlink.d.ts.map +1 -0
- package/dist/commands/unlink.js +104 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/commands/verify.d.ts +7 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +190 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/codepac.d.ts +79 -0
- package/dist/core/codepac.d.ts.map +1 -0
- package/dist/core/codepac.js +188 -0
- package/dist/core/codepac.js.map +1 -0
- package/dist/core/config.d.ts +70 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +210 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/guard.d.ts +18 -0
- package/dist/core/guard.d.ts.map +1 -0
- package/dist/core/guard.js +82 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/linker.d.ts +76 -0
- package/dist/core/linker.d.ts.map +1 -0
- package/dist/core/linker.js +263 -0
- package/dist/core/linker.js.map +1 -0
- package/dist/core/parser.d.ts +43 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +133 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/platform.d.ts +100 -0
- package/dist/core/platform.d.ts.map +1 -0
- package/dist/core/platform.js +193 -0
- package/dist/core/platform.js.map +1 -0
- package/dist/core/registry.d.ts +181 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +443 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/store.d.ts +77 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +226 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/transaction.d.ts +106 -0
- package/dist/core/transaction.d.ts.map +1 -0
- package/dist/core/transaction.js +295 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +174 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +47 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/disk.d.ts +57 -0
- package/dist/utils/disk.d.ts.map +1 -0
- package/dist/utils/disk.js +313 -0
- package/dist/utils/disk.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +42 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +91 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/fs-utils.d.ts +44 -0
- package/dist/utils/fs-utils.d.ts.map +1 -0
- package/dist/utils/fs-utils.js +107 -0
- package/dist/utils/fs-utils.js.map +1 -0
- package/dist/utils/global-lock.d.ts +28 -0
- package/dist/utils/global-lock.d.ts.map +1 -0
- package/dist/utils/global-lock.js +89 -0
- package/dist/utils/global-lock.js.map +1 -0
- package/dist/utils/lock.d.ts +26 -0
- package/dist/utils/lock.d.ts.map +1 -0
- package/dist/utils/lock.js +68 -0
- package/dist/utils/lock.js.map +1 -0
- package/dist/utils/logger.d.ts +98 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +190 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompt.d.ts +32 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +131 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codepac 命令封装
|
|
3
|
+
* 提供对 codepac CLI 工具的调用接口
|
|
4
|
+
*/
|
|
5
|
+
import { exec, spawn } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
/**
|
|
10
|
+
* codepac 命令名称
|
|
11
|
+
*/
|
|
12
|
+
const CODEPAC_CMD = 'codepac';
|
|
13
|
+
/**
|
|
14
|
+
* 检查 codepac 是否已安装
|
|
15
|
+
*/
|
|
16
|
+
export async function isCodepacInstalled() {
|
|
17
|
+
try {
|
|
18
|
+
await execAsync(`${CODEPAC_CMD} --version`, { encoding: 'utf8' });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 获取 codepac 版本
|
|
27
|
+
*/
|
|
28
|
+
export async function getVersion() {
|
|
29
|
+
try {
|
|
30
|
+
const { stdout } = await execAsync(`${CODEPAC_CMD} --version`, { encoding: 'utf8' });
|
|
31
|
+
return stdout.trim();
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 使用 codepac 安装依赖
|
|
39
|
+
*/
|
|
40
|
+
export async function install(options) {
|
|
41
|
+
const { configPath, targetDir, platform, onProgress, silent } = options;
|
|
42
|
+
// 检查 codepac 是否安装
|
|
43
|
+
if (!(await isCodepacInstalled())) {
|
|
44
|
+
throw new Error('codepac 未安装,请先安装 codepac 工具');
|
|
45
|
+
}
|
|
46
|
+
// 构建命令参数
|
|
47
|
+
const args = ['install', '-c', configPath, '-d', targetDir];
|
|
48
|
+
// 添加平台参数
|
|
49
|
+
if (platform) {
|
|
50
|
+
args.push('-p', platform);
|
|
51
|
+
}
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const proc = spawn(CODEPAC_CMD, args, {
|
|
54
|
+
cwd: path.dirname(configPath),
|
|
55
|
+
stdio: silent ? 'ignore' : 'pipe',
|
|
56
|
+
});
|
|
57
|
+
let stderr = '';
|
|
58
|
+
if (proc.stdout && onProgress) {
|
|
59
|
+
proc.stdout.on('data', (data) => {
|
|
60
|
+
const message = data.toString().trim();
|
|
61
|
+
if (message) {
|
|
62
|
+
onProgress(message);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (proc.stderr) {
|
|
67
|
+
proc.stderr.on('data', (data) => {
|
|
68
|
+
stderr += data.toString();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
proc.on('error', (err) => {
|
|
72
|
+
reject(new Error(`无法执行 codepac 命令: ${err.message}`));
|
|
73
|
+
});
|
|
74
|
+
proc.on('close', (code) => {
|
|
75
|
+
if (code === 0) {
|
|
76
|
+
resolve();
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const errorMsg = stderr.trim() || `codepac 命令执行失败,退出码: ${code}`;
|
|
80
|
+
reject(new Error(errorMsg));
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 使用 codepac 安装单个库
|
|
87
|
+
* 注意:这需要 codepac 支持单库安装,如果不支持则需要创建临时配置文件
|
|
88
|
+
*/
|
|
89
|
+
export async function installSingle(options) {
|
|
90
|
+
const { url, commit, branch, targetDir, platform, sparse, onProgress, silent } = options;
|
|
91
|
+
// 检查 codepac 是否安装
|
|
92
|
+
if (!(await isCodepacInstalled())) {
|
|
93
|
+
throw new Error('codepac 未安装,请先安装 codepac 工具');
|
|
94
|
+
}
|
|
95
|
+
// 创建临时配置
|
|
96
|
+
const fs = await import('fs/promises');
|
|
97
|
+
const os = await import('os');
|
|
98
|
+
const tempDir = os.tmpdir();
|
|
99
|
+
const tempConfigPath = path.join(tempDir, `codepac-temp-${Date.now()}.json`);
|
|
100
|
+
const tempConfig = {
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
repos: {
|
|
103
|
+
common: [
|
|
104
|
+
{
|
|
105
|
+
url,
|
|
106
|
+
commit,
|
|
107
|
+
branch,
|
|
108
|
+
dir: path.basename(targetDir),
|
|
109
|
+
...(sparse && { sparse }),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
try {
|
|
115
|
+
await fs.writeFile(tempConfigPath, JSON.stringify(tempConfig, null, 2), 'utf-8');
|
|
116
|
+
await install({
|
|
117
|
+
configPath: tempConfigPath,
|
|
118
|
+
targetDir: path.dirname(targetDir),
|
|
119
|
+
platform,
|
|
120
|
+
onProgress,
|
|
121
|
+
silent,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
// 清理临时文件
|
|
126
|
+
try {
|
|
127
|
+
await fs.unlink(tempConfigPath);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// 忽略清理错误
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 更新依赖
|
|
136
|
+
*/
|
|
137
|
+
export async function update(options) {
|
|
138
|
+
const { configPath, targetDir, libName, onProgress } = options;
|
|
139
|
+
// 检查 codepac 是否安装
|
|
140
|
+
if (!(await isCodepacInstalled())) {
|
|
141
|
+
throw new Error('codepac 未安装,请先安装 codepac 工具');
|
|
142
|
+
}
|
|
143
|
+
// 构建命令参数
|
|
144
|
+
const args = ['update', '-c', configPath, '-d', targetDir];
|
|
145
|
+
if (libName) {
|
|
146
|
+
args.push('-n', libName);
|
|
147
|
+
}
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
const proc = spawn(CODEPAC_CMD, args, {
|
|
150
|
+
cwd: path.dirname(configPath),
|
|
151
|
+
stdio: 'pipe',
|
|
152
|
+
});
|
|
153
|
+
let stderr = '';
|
|
154
|
+
if (proc.stdout && onProgress) {
|
|
155
|
+
proc.stdout.on('data', (data) => {
|
|
156
|
+
const message = data.toString().trim();
|
|
157
|
+
if (message) {
|
|
158
|
+
onProgress(message);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (proc.stderr) {
|
|
163
|
+
proc.stderr.on('data', (data) => {
|
|
164
|
+
stderr += data.toString();
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
proc.on('error', (err) => {
|
|
168
|
+
reject(new Error(`无法执行 codepac 命令: ${err.message}`));
|
|
169
|
+
});
|
|
170
|
+
proc.on('close', (code) => {
|
|
171
|
+
if (code === 0) {
|
|
172
|
+
resolve();
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const errorMsg = stderr.trim() || `codepac update 命令执行失败,退出码: ${code}`;
|
|
176
|
+
reject(new Error(errorMsg));
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
export default {
|
|
182
|
+
isCodepacInstalled,
|
|
183
|
+
getVersion,
|
|
184
|
+
install,
|
|
185
|
+
installSingle,
|
|
186
|
+
update,
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=codepac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codepac.js","sourceRoot":"","sources":["../../src/core/codepac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { DockConfig, CleanStrategy } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 获取默认配置
|
|
4
|
+
*/
|
|
5
|
+
export declare function getDefaultConfig(storePath: string): DockConfig;
|
|
6
|
+
/**
|
|
7
|
+
* 确保配置目录存在
|
|
8
|
+
*/
|
|
9
|
+
export declare function ensureConfigDir(): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* 配置版本状态
|
|
12
|
+
*/
|
|
13
|
+
export type ConfigVersionStatus = 'current' | 'migrate' | 'unsupported';
|
|
14
|
+
/**
|
|
15
|
+
* 检查配置版本
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkConfigVersion(config: DockConfig): ConfigVersionStatus;
|
|
18
|
+
/**
|
|
19
|
+
* 加载配置
|
|
20
|
+
* 文件不存在时返回 null
|
|
21
|
+
* 版本不兼容时抛出错误
|
|
22
|
+
*/
|
|
23
|
+
export declare function load(): Promise<DockConfig | null>;
|
|
24
|
+
/**
|
|
25
|
+
* 保存配置(带文件锁保护)
|
|
26
|
+
*/
|
|
27
|
+
export declare function save(config: DockConfig): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 获取单个配置项
|
|
30
|
+
*/
|
|
31
|
+
export declare function get<K extends keyof DockConfig>(key: K): Promise<DockConfig[K] | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* 设置单个配置项并保存(带文件锁保护读-改-写操作)
|
|
34
|
+
*/
|
|
35
|
+
export declare function set<K extends keyof DockConfig>(key: K, value: DockConfig[K]): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* 获取 Store 路径
|
|
38
|
+
*/
|
|
39
|
+
export declare function getStorePath(): Promise<string | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* 设置 Store 路径
|
|
42
|
+
*/
|
|
43
|
+
export declare function setStorePath(path: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 验证配置项名称是否有效
|
|
46
|
+
*/
|
|
47
|
+
export declare function isValidConfigKey(key: string): key is keyof DockConfig;
|
|
48
|
+
/**
|
|
49
|
+
* 验证 cleanStrategy 值是否有效
|
|
50
|
+
*/
|
|
51
|
+
export declare function isValidCleanStrategy(value: string): value is CleanStrategy;
|
|
52
|
+
/**
|
|
53
|
+
* 解析配置值
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseConfigValue(key: keyof DockConfig, value: string): DockConfig[keyof DockConfig];
|
|
56
|
+
declare const _default: {
|
|
57
|
+
load: typeof load;
|
|
58
|
+
save: typeof save;
|
|
59
|
+
get: typeof get;
|
|
60
|
+
set: typeof set;
|
|
61
|
+
getDefaultConfig: typeof getDefaultConfig;
|
|
62
|
+
ensureConfigDir: typeof ensureConfigDir;
|
|
63
|
+
getStorePath: typeof getStorePath;
|
|
64
|
+
setStorePath: typeof setStorePath;
|
|
65
|
+
isValidConfigKey: typeof isValidConfigKey;
|
|
66
|
+
isValidCleanStrategy: typeof isValidCleanStrategy;
|
|
67
|
+
parseConfigValue: typeof parseConfigValue;
|
|
68
|
+
};
|
|
69
|
+
export default _default;
|
|
70
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGnE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAM9D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAGrD;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAExE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,mBAAmB,CAa1E;AAED;;;;GAIG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAsBvD;AAwDD;;GAEG;AACH,wBAAsB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5D;AAED;;GAEG;AACH,wBAAsB,GAAG,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAGhG;AAED;;GAEG;AACH,wBAAsB,GAAG,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjG;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEhE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,MAAM,UAAU,CAUrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,UAAU,EACrB,KAAK,EAAE,MAAM,GACZ,UAAU,CAAC,MAAM,UAAU,CAAC,CAe9B;;;;;;;;;;;;;;AAED,wBAYE"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 全局配置管理
|
|
3
|
+
* 配置文件位置: ~/.tanmi-dock/config.json
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import semver from 'semver';
|
|
7
|
+
import { getConfigPath, getConfigDir, expandHome } from './platform.js';
|
|
8
|
+
import { withFileLock } from '../utils/lock.js';
|
|
9
|
+
import { DEFAULT_CONFIG, CURRENT_CONFIG_VERSION, MIN_SUPPORTED_VERSION } from '../types/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* 获取默认配置
|
|
12
|
+
*/
|
|
13
|
+
export function getDefaultConfig(storePath) {
|
|
14
|
+
return {
|
|
15
|
+
...DEFAULT_CONFIG,
|
|
16
|
+
initialized: true,
|
|
17
|
+
storePath: expandHome(storePath),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 确保配置目录存在
|
|
22
|
+
*/
|
|
23
|
+
export async function ensureConfigDir() {
|
|
24
|
+
const dir = getConfigDir();
|
|
25
|
+
await fs.mkdir(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 检查配置版本
|
|
29
|
+
*/
|
|
30
|
+
export function checkConfigVersion(config) {
|
|
31
|
+
const version = config.version || '1.0.0';
|
|
32
|
+
if (semver.eq(version, CURRENT_CONFIG_VERSION)) {
|
|
33
|
+
return 'current'; // 版本一致
|
|
34
|
+
}
|
|
35
|
+
if (semver.lt(version, CURRENT_CONFIG_VERSION) && semver.gte(version, MIN_SUPPORTED_VERSION)) {
|
|
36
|
+
return 'migrate'; // 需要迁移
|
|
37
|
+
}
|
|
38
|
+
if (semver.gt(version, CURRENT_CONFIG_VERSION)) {
|
|
39
|
+
return 'unsupported'; // 配置版本高于程序,需升级程序
|
|
40
|
+
}
|
|
41
|
+
return 'unsupported';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 加载配置
|
|
45
|
+
* 文件不存在时返回 null
|
|
46
|
+
* 版本不兼容时抛出错误
|
|
47
|
+
*/
|
|
48
|
+
export async function load() {
|
|
49
|
+
try {
|
|
50
|
+
const configPath = getConfigPath();
|
|
51
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
52
|
+
const config = JSON.parse(content);
|
|
53
|
+
const versionStatus = checkConfigVersion(config);
|
|
54
|
+
if (versionStatus === 'unsupported') {
|
|
55
|
+
throw new Error(`配置版本 ${config.version} 高于程序支持版本 ${CURRENT_CONFIG_VERSION},请升级 tanmi-dock`);
|
|
56
|
+
}
|
|
57
|
+
if (versionStatus === 'migrate') {
|
|
58
|
+
return await migrateConfig(config);
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof Error && err.message.includes('配置版本')) {
|
|
64
|
+
throw err; // 重新抛出版本错误
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 迁移函数映射: 从哪个版本迁移
|
|
71
|
+
*/
|
|
72
|
+
const migrations = {
|
|
73
|
+
'1.0.0': (config) => {
|
|
74
|
+
// v1.0.0 → v1.1.0 的迁移逻辑
|
|
75
|
+
return {
|
|
76
|
+
...config,
|
|
77
|
+
version: '1.1.0',
|
|
78
|
+
// 未来可在此添加新字段的默认值
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* 迁移配置到最新版本
|
|
84
|
+
* 逐版本迁移,出错时保留原配置
|
|
85
|
+
*/
|
|
86
|
+
async function migrateConfig(config) {
|
|
87
|
+
const originalVersion = config.version || '1.0.0';
|
|
88
|
+
let current = { ...config };
|
|
89
|
+
let version = originalVersion;
|
|
90
|
+
try {
|
|
91
|
+
// 逐版本迁移
|
|
92
|
+
while (version !== CURRENT_CONFIG_VERSION) {
|
|
93
|
+
const migrateFn = migrations[version];
|
|
94
|
+
if (!migrateFn) {
|
|
95
|
+
throw new Error(`无法从版本 ${version} 迁移,缺少迁移函数`);
|
|
96
|
+
}
|
|
97
|
+
console.log(`[info] 迁移配置: ${version} → ...`);
|
|
98
|
+
current = migrateFn(current);
|
|
99
|
+
version = current.version;
|
|
100
|
+
}
|
|
101
|
+
// 保存迁移后的配置
|
|
102
|
+
const migrated = current;
|
|
103
|
+
await save(migrated);
|
|
104
|
+
console.log(`[ok] 配置已从 ${originalVersion} 迁移到 ${CURRENT_CONFIG_VERSION}`);
|
|
105
|
+
return migrated;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
console.error(`[err] 配置迁移失败: ${err.message}`);
|
|
109
|
+
console.log('[info] 保留原配置不覆盖');
|
|
110
|
+
return config;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 保存配置(带文件锁保护)
|
|
115
|
+
*/
|
|
116
|
+
export async function save(config) {
|
|
117
|
+
await ensureConfigDir();
|
|
118
|
+
const configPath = getConfigPath();
|
|
119
|
+
await withFileLock(configPath, async () => {
|
|
120
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 获取单个配置项
|
|
125
|
+
*/
|
|
126
|
+
export async function get(key) {
|
|
127
|
+
const config = await load();
|
|
128
|
+
return config?.[key];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 设置单个配置项并保存(带文件锁保护读-改-写操作)
|
|
132
|
+
*/
|
|
133
|
+
export async function set(key, value) {
|
|
134
|
+
await ensureConfigDir();
|
|
135
|
+
const configPath = getConfigPath();
|
|
136
|
+
await withFileLock(configPath, async () => {
|
|
137
|
+
const content = await fs.readFile(configPath, 'utf-8').catch(() => null);
|
|
138
|
+
if (!content) {
|
|
139
|
+
throw new Error('配置文件不存在,请先运行 tanmi-dock init');
|
|
140
|
+
}
|
|
141
|
+
const config = JSON.parse(content);
|
|
142
|
+
config[key] = value;
|
|
143
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 获取 Store 路径
|
|
148
|
+
*/
|
|
149
|
+
export async function getStorePath() {
|
|
150
|
+
return get('storePath');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 设置 Store 路径
|
|
154
|
+
*/
|
|
155
|
+
export async function setStorePath(path) {
|
|
156
|
+
await set('storePath', expandHome(path));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 验证配置项名称是否有效
|
|
160
|
+
*/
|
|
161
|
+
export function isValidConfigKey(key) {
|
|
162
|
+
const validKeys = [
|
|
163
|
+
'version',
|
|
164
|
+
'initialized',
|
|
165
|
+
'storePath',
|
|
166
|
+
'cleanStrategy',
|
|
167
|
+
'maxStoreSize',
|
|
168
|
+
'autoDownload',
|
|
169
|
+
];
|
|
170
|
+
return validKeys.includes(key);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 验证 cleanStrategy 值是否有效
|
|
174
|
+
*/
|
|
175
|
+
export function isValidCleanStrategy(value) {
|
|
176
|
+
return ['unreferenced', 'lru', 'manual'].includes(value);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 解析配置值
|
|
180
|
+
*/
|
|
181
|
+
export function parseConfigValue(key, value) {
|
|
182
|
+
switch (key) {
|
|
183
|
+
case 'autoDownload':
|
|
184
|
+
case 'initialized':
|
|
185
|
+
return value === 'true';
|
|
186
|
+
case 'maxStoreSize':
|
|
187
|
+
return parseInt(value, 10);
|
|
188
|
+
case 'cleanStrategy':
|
|
189
|
+
if (!isValidCleanStrategy(value)) {
|
|
190
|
+
throw new Error(`无效的 cleanStrategy 值: ${value},有效值: unreferenced, lru, manual`);
|
|
191
|
+
}
|
|
192
|
+
return value;
|
|
193
|
+
default:
|
|
194
|
+
return value;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export default {
|
|
198
|
+
load,
|
|
199
|
+
save,
|
|
200
|
+
get,
|
|
201
|
+
set,
|
|
202
|
+
getDefaultConfig,
|
|
203
|
+
ensureConfigDir,
|
|
204
|
+
getStorePath,
|
|
205
|
+
setStorePath,
|
|
206
|
+
isValidConfigKey,
|
|
207
|
+
isValidCleanStrategy,
|
|
208
|
+
parseConfigValue,
|
|
209
|
+
};
|
|
210
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { InitStatus } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 检查是否已初始化
|
|
4
|
+
*/
|
|
5
|
+
export declare function isInitialized(): Promise<boolean>;
|
|
6
|
+
/**
|
|
7
|
+
* 确保已初始化,否则输出错误并退出
|
|
8
|
+
*/
|
|
9
|
+
export declare function ensureInitialized(): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* 获取详细的初始化状态
|
|
12
|
+
*/
|
|
13
|
+
export declare function getInitStatus(): Promise<InitStatus>;
|
|
14
|
+
/**
|
|
15
|
+
* 检查配置目录是否存在
|
|
16
|
+
*/
|
|
17
|
+
export declare function configDirExists(): Promise<boolean>;
|
|
18
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/core/guard.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAStD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOvD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAmCzD;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAOxD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 初始化状态检查
|
|
3
|
+
* 未初始化时阻止其他命令执行
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import { getConfigPath, getConfigDir } from './platform.js';
|
|
7
|
+
import { error, hint } from '../utils/logger.js';
|
|
8
|
+
import { EXIT_CODES } from '../utils/exit-codes.js';
|
|
9
|
+
/**
|
|
10
|
+
* 检查是否已初始化
|
|
11
|
+
*/
|
|
12
|
+
export async function isInitialized() {
|
|
13
|
+
try {
|
|
14
|
+
const configPath = getConfigPath();
|
|
15
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
16
|
+
const config = JSON.parse(content);
|
|
17
|
+
return config.initialized === true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 确保已初始化,否则输出错误并退出
|
|
25
|
+
*/
|
|
26
|
+
export async function ensureInitialized() {
|
|
27
|
+
const initialized = await isInitialized();
|
|
28
|
+
if (!initialized) {
|
|
29
|
+
error('TanmiDock 尚未初始化');
|
|
30
|
+
hint('请先运行: tanmi-dock init');
|
|
31
|
+
process.exit(EXIT_CODES.NOT_INITIALIZED);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 获取详细的初始化状态
|
|
36
|
+
*/
|
|
37
|
+
export async function getInitStatus() {
|
|
38
|
+
const configPath = getConfigPath();
|
|
39
|
+
let configExists = false;
|
|
40
|
+
let initialized = false;
|
|
41
|
+
let storePathExists = false;
|
|
42
|
+
let storePath;
|
|
43
|
+
try {
|
|
44
|
+
await fs.access(configPath);
|
|
45
|
+
configExists = true;
|
|
46
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
47
|
+
const config = JSON.parse(content);
|
|
48
|
+
initialized = config.initialized === true;
|
|
49
|
+
storePath = config.storePath;
|
|
50
|
+
if (storePath) {
|
|
51
|
+
try {
|
|
52
|
+
await fs.access(storePath);
|
|
53
|
+
storePathExists = true;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
storePathExists = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// config file doesn't exist
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
initialized,
|
|
65
|
+
configExists,
|
|
66
|
+
storePathExists,
|
|
67
|
+
storePath,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 检查配置目录是否存在
|
|
72
|
+
*/
|
|
73
|
+
export async function configDirExists() {
|
|
74
|
+
try {
|
|
75
|
+
await fs.access(getConfigDir());
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/core/guard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,MAAM,GAAe,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,WAAW,GAAG,MAAM,aAAa,EAAE,CAAC;IAC1C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,SAA6B,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5B,YAAY,GAAG,IAAI,CAAC;QAEpB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,MAAM,GAAe,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,WAAW,GAAG,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC;QAC1C,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAE7B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC3B,eAAe,GAAG,IAAI,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe,GAAG,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,OAAO;QACL,WAAW;QACX,YAAY;QACZ,eAAe;QACf,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 创建符号链接
|
|
3
|
+
* @param target 目标路径(链接指向的位置)
|
|
4
|
+
* @param linkPath 链接路径(创建链接的位置)
|
|
5
|
+
*/
|
|
6
|
+
export declare function link(target: string, linkPath: string): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* 检查路径是否为符号链接
|
|
9
|
+
*/
|
|
10
|
+
export declare function isSymlink(linkPath: string): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* 读取符号链接目标
|
|
13
|
+
*/
|
|
14
|
+
export declare function readLink(linkPath: string): Promise<string | null>;
|
|
15
|
+
/**
|
|
16
|
+
* 删除符号链接
|
|
17
|
+
*/
|
|
18
|
+
export declare function unlink(linkPath: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* 检查符号链接是否有效(目标存在)
|
|
21
|
+
*/
|
|
22
|
+
export declare function isValidLink(linkPath: string): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* 检查符号链接是否指向正确的目标
|
|
25
|
+
*/
|
|
26
|
+
export declare function isCorrectLink(linkPath: string, expectedTarget: string): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* 将普通目录替换为符号链接
|
|
29
|
+
* @param dirPath 要替换的目录路径
|
|
30
|
+
* @param target 链接目标
|
|
31
|
+
* @param backup 是否备份原目录(默认删除)
|
|
32
|
+
* @returns 备份路径(如果有)
|
|
33
|
+
*/
|
|
34
|
+
export declare function replaceWithLink(dirPath: string, target: string, backup?: boolean): Promise<string | null>;
|
|
35
|
+
/**
|
|
36
|
+
* 将符号链接还原为普通目录(从目标复制内容)
|
|
37
|
+
*/
|
|
38
|
+
export declare function restoreFromLink(linkPath: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* 检查路径状态
|
|
41
|
+
*/
|
|
42
|
+
export declare function getPathStatus(localPath: string, expectedTarget: string): Promise<'linked' | 'wrong_link' | 'directory' | 'missing'>;
|
|
43
|
+
/**
|
|
44
|
+
* 链接库到项目(自动选择单平台/多平台策略)
|
|
45
|
+
* @param localPath 本地路径 (3rdparty/libXxx)
|
|
46
|
+
* @param storePath Store 根路径
|
|
47
|
+
* @param libName 库名
|
|
48
|
+
* @param commit commit hash
|
|
49
|
+
* @param platforms 选择的平台列表
|
|
50
|
+
*/
|
|
51
|
+
export declare function linkLibrary(localPath: string, storePath: string, libName: string, commit: string, platforms: string[]): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* 多平台组合链接
|
|
54
|
+
* 创建真实目录,内部分别链接各平台内容和共享内容
|
|
55
|
+
* @param localPath 本地路径
|
|
56
|
+
* @param storePath Store 根路径
|
|
57
|
+
* @param libName 库名
|
|
58
|
+
* @param commit commit hash
|
|
59
|
+
* @param platforms 平台列表
|
|
60
|
+
*/
|
|
61
|
+
export declare function linkMultiPlatform(localPath: string, storePath: string, libName: string, commit: string, platforms: string[]): Promise<void>;
|
|
62
|
+
declare const _default: {
|
|
63
|
+
link: typeof link;
|
|
64
|
+
isSymlink: typeof isSymlink;
|
|
65
|
+
readLink: typeof readLink;
|
|
66
|
+
unlink: typeof unlink;
|
|
67
|
+
isValidLink: typeof isValidLink;
|
|
68
|
+
isCorrectLink: typeof isCorrectLink;
|
|
69
|
+
replaceWithLink: typeof replaceWithLink;
|
|
70
|
+
restoreFromLink: typeof restoreFromLink;
|
|
71
|
+
getPathStatus: typeof getPathStatus;
|
|
72
|
+
linkLibrary: typeof linkLibrary;
|
|
73
|
+
linkMultiPlatform: typeof linkMultiPlatform;
|
|
74
|
+
};
|
|
75
|
+
export default _default;
|
|
76
|
+
//# sourceMappingURL=linker.d.ts.map
|