tanmi-dock 0.7.3 → 0.8.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/check.d.ts +61 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +170 -6
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/link.d.ts +30 -0
- package/dist/commands/link.d.ts.map +1 -1
- package/dist/commands/link.js +108 -27
- package/dist/commands/link.js.map +1 -1
- package/dist/core/linker.d.ts +10 -0
- package/dist/core/linker.d.ts.map +1 -1
- package/dist/core/linker.js +51 -2
- package/dist/core/linker.js.map +1 -1
- package/dist/core/store.d.ts +55 -0
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +70 -1
- package/dist/core/store.js.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/fs-utils.d.ts +26 -0
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +127 -0
- package/dist/utils/fs-utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/CLAUDE.md +0 -7
- package/dist/core/CLAUDE.md +0 -7
package/dist/commands/link.js
CHANGED
|
@@ -609,14 +609,14 @@ export async function linkProject(projectPath, options) {
|
|
|
609
609
|
for (const platform of absorbLinkPlatforms) {
|
|
610
610
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
|
|
611
611
|
if (!registry.getStore(storeKey)) {
|
|
612
|
-
const
|
|
612
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
|
|
613
613
|
registry.addStore({
|
|
614
614
|
libName: dependency.libName,
|
|
615
615
|
commit: dependency.commit,
|
|
616
616
|
platform,
|
|
617
617
|
branch: dependency.branch,
|
|
618
618
|
url: dependency.url,
|
|
619
|
-
|
|
619
|
+
...integrity,
|
|
620
620
|
usedBy: [],
|
|
621
621
|
createdAt: new Date().toISOString(),
|
|
622
622
|
lastAccess: new Date().toISOString(),
|
|
@@ -668,14 +668,14 @@ export async function linkProject(projectPath, options) {
|
|
|
668
668
|
// Registry: StoreEntry 记录
|
|
669
669
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
670
670
|
if (!registry.getStore(storeKey)) {
|
|
671
|
-
const
|
|
671
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
672
672
|
registry.addStore({
|
|
673
673
|
libName: dependency.libName,
|
|
674
674
|
commit: dependency.commit,
|
|
675
675
|
platform: GENERAL_PLATFORM,
|
|
676
676
|
branch: dependency.branch,
|
|
677
677
|
url: dependency.url,
|
|
678
|
-
|
|
678
|
+
...integrity,
|
|
679
679
|
usedBy: [],
|
|
680
680
|
createdAt: new Date().toISOString(),
|
|
681
681
|
lastAccess: new Date().toISOString(),
|
|
@@ -775,14 +775,14 @@ export async function linkProject(projectPath, options) {
|
|
|
775
775
|
// StoreEntry 记录
|
|
776
776
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
777
777
|
if (!registry.getStore(storeKey)) {
|
|
778
|
-
const
|
|
778
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
779
779
|
registry.addStore({
|
|
780
780
|
libName: dependency.libName,
|
|
781
781
|
commit: dependency.commit,
|
|
782
782
|
platform: GENERAL_PLATFORM,
|
|
783
783
|
branch: dependency.branch,
|
|
784
784
|
url: dependency.url,
|
|
785
|
-
|
|
785
|
+
...integrity,
|
|
786
786
|
usedBy: [],
|
|
787
787
|
createdAt: new Date().toISOString(),
|
|
788
788
|
lastAccess: new Date().toISOString(),
|
|
@@ -825,14 +825,14 @@ export async function linkProject(projectPath, options) {
|
|
|
825
825
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
|
|
826
826
|
// 如果 StoreEntry 不存在,创建它
|
|
827
827
|
if (!registry.getStore(storeKey)) {
|
|
828
|
-
const
|
|
828
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
|
|
829
829
|
registry.addStore({
|
|
830
830
|
libName: dependency.libName,
|
|
831
831
|
commit: dependency.commit,
|
|
832
832
|
platform,
|
|
833
833
|
branch: dependency.branch,
|
|
834
834
|
url: dependency.url,
|
|
835
|
-
|
|
835
|
+
...integrity,
|
|
836
836
|
usedBy: [],
|
|
837
837
|
createdAt: new Date().toISOString(),
|
|
838
838
|
lastAccess: new Date().toISOString(),
|
|
@@ -891,14 +891,14 @@ export async function linkProject(projectPath, options) {
|
|
|
891
891
|
for (const platform of platforms) {
|
|
892
892
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
|
|
893
893
|
if (!registry.getStore(storeKey)) {
|
|
894
|
-
const
|
|
894
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
|
|
895
895
|
registry.addStore({
|
|
896
896
|
libName: dependency.libName,
|
|
897
897
|
commit: dependency.commit,
|
|
898
898
|
platform,
|
|
899
899
|
branch: dependency.branch,
|
|
900
900
|
url: dependency.url,
|
|
901
|
-
|
|
901
|
+
...integrity,
|
|
902
902
|
usedBy: [],
|
|
903
903
|
createdAt: new Date().toISOString(),
|
|
904
904
|
lastAccess: new Date().toISOString(),
|
|
@@ -999,14 +999,14 @@ export async function linkProject(projectPath, options) {
|
|
|
999
999
|
// StoreEntry 记录
|
|
1000
1000
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
1001
1001
|
if (!registry.getStore(storeKey)) {
|
|
1002
|
-
const
|
|
1002
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
1003
1003
|
registry.addStore({
|
|
1004
1004
|
libName: dependency.libName,
|
|
1005
1005
|
commit: dependency.commit,
|
|
1006
1006
|
platform: GENERAL_PLATFORM,
|
|
1007
1007
|
branch: dependency.branch,
|
|
1008
1008
|
url: dependency.url,
|
|
1009
|
-
|
|
1009
|
+
...integrity,
|
|
1010
1010
|
usedBy: [],
|
|
1011
1011
|
createdAt: new Date().toISOString(),
|
|
1012
1012
|
lastAccess: new Date().toISOString(),
|
|
@@ -1087,14 +1087,14 @@ export async function linkProject(projectPath, options) {
|
|
|
1087
1087
|
// StoreEntry 记录
|
|
1088
1088
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
1089
1089
|
if (!registry.getStore(storeKey)) {
|
|
1090
|
-
const
|
|
1090
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, GENERAL_PLATFORM);
|
|
1091
1091
|
registry.addStore({
|
|
1092
1092
|
libName: dependency.libName,
|
|
1093
1093
|
commit: dependency.commit,
|
|
1094
1094
|
platform: GENERAL_PLATFORM,
|
|
1095
1095
|
branch: dependency.branch,
|
|
1096
1096
|
url: dependency.url,
|
|
1097
|
-
|
|
1097
|
+
...integrity,
|
|
1098
1098
|
usedBy: [],
|
|
1099
1099
|
createdAt: new Date().toISOString(),
|
|
1100
1100
|
lastAccess: new Date().toISOString(),
|
|
@@ -1144,14 +1144,14 @@ export async function linkProject(projectPath, options) {
|
|
|
1144
1144
|
for (const platform of linkPlatforms) {
|
|
1145
1145
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
|
|
1146
1146
|
if (!registry.getStore(storeKey)) {
|
|
1147
|
-
const
|
|
1147
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
|
|
1148
1148
|
registry.addStore({
|
|
1149
1149
|
libName: dependency.libName,
|
|
1150
1150
|
commit: dependency.commit,
|
|
1151
1151
|
platform,
|
|
1152
1152
|
branch: dependency.branch,
|
|
1153
1153
|
url: dependency.url,
|
|
1154
|
-
|
|
1154
|
+
...integrity,
|
|
1155
1155
|
usedBy: [],
|
|
1156
1156
|
createdAt: new Date().toISOString(),
|
|
1157
1157
|
lastAccess: new Date().toISOString(),
|
|
@@ -1441,20 +1441,20 @@ async function registerSharedStore(libName, commit, branch = '', url = '') {
|
|
|
1441
1441
|
catch {
|
|
1442
1442
|
return false; // 目录不存在
|
|
1443
1443
|
}
|
|
1444
|
-
// 计算 _shared
|
|
1445
|
-
const
|
|
1444
|
+
// 计算 _shared 完整性信息并注册
|
|
1445
|
+
const integrity = await store.captureIntegrity(libName, commit, SHARED_PLATFORM);
|
|
1446
1446
|
registry.addStore({
|
|
1447
1447
|
libName,
|
|
1448
1448
|
commit,
|
|
1449
1449
|
platform: SHARED_PLATFORM,
|
|
1450
1450
|
branch,
|
|
1451
1451
|
url,
|
|
1452
|
-
|
|
1452
|
+
...integrity,
|
|
1453
1453
|
usedBy: [], // _shared 不追踪引用,生命周期跟随平台
|
|
1454
1454
|
createdAt: new Date().toISOString(),
|
|
1455
1455
|
lastAccess: new Date().toISOString(),
|
|
1456
1456
|
});
|
|
1457
|
-
debug(`注册 _shared: ${libName}:${commit.slice(0, 8)} (${formatSize(
|
|
1457
|
+
debug(`注册 _shared: ${libName}:${commit.slice(0, 8)} (${formatSize(integrity.size)})`);
|
|
1458
1458
|
return true;
|
|
1459
1459
|
}
|
|
1460
1460
|
/**
|
|
@@ -1473,13 +1473,14 @@ async function registerNestedLibraries(nestedLibraries, projectHash) {
|
|
|
1473
1473
|
// General 库:单个 StoreEntry
|
|
1474
1474
|
const storeKey = registry.getStoreKey(nested.libName, nested.commit, GENERAL_PLATFORM);
|
|
1475
1475
|
if (!registry.getStore(storeKey)) {
|
|
1476
|
+
const integrity = await store.captureIntegrity(nested.libName, nested.commit, GENERAL_PLATFORM);
|
|
1476
1477
|
registry.addStore({
|
|
1477
1478
|
libName: nested.libName,
|
|
1478
1479
|
commit: nested.commit,
|
|
1479
1480
|
platform: GENERAL_PLATFORM,
|
|
1480
1481
|
branch: '',
|
|
1481
1482
|
url: '',
|
|
1482
|
-
|
|
1483
|
+
...integrity,
|
|
1483
1484
|
usedBy: [],
|
|
1484
1485
|
createdAt: new Date().toISOString(),
|
|
1485
1486
|
lastAccess: new Date().toISOString(),
|
|
@@ -1507,14 +1508,14 @@ async function registerNestedLibraries(nestedLibraries, projectHash) {
|
|
|
1507
1508
|
for (const platform of nested.platforms) {
|
|
1508
1509
|
const storeKey = registry.getStoreKey(nested.libName, nested.commit, platform);
|
|
1509
1510
|
if (!registry.getStore(storeKey)) {
|
|
1510
|
-
const
|
|
1511
|
+
const integrity = await store.captureIntegrity(nested.libName, nested.commit, platform);
|
|
1511
1512
|
registry.addStore({
|
|
1512
1513
|
libName: nested.libName,
|
|
1513
1514
|
commit: nested.commit,
|
|
1514
1515
|
platform,
|
|
1515
1516
|
branch: '',
|
|
1516
1517
|
url: '',
|
|
1517
|
-
|
|
1518
|
+
...integrity,
|
|
1518
1519
|
usedBy: [],
|
|
1519
1520
|
createdAt: new Date().toISOString(),
|
|
1520
1521
|
lastAccess: new Date().toISOString(),
|
|
@@ -1561,7 +1562,20 @@ async function classifyDependencies(dependencies, projectPath, configPath, platf
|
|
|
1561
1562
|
const localPath = path.join(thirdPartyDir, dep.libName);
|
|
1562
1563
|
const storeLibPath = store.getLibraryPath(storePath, dep.libName, dep.commit, primaryPlatform);
|
|
1563
1564
|
// 检查 Store 中是否有任意请求的平台(而非只检查主平台)
|
|
1564
|
-
const { existing } = await store.checkPlatformCompleteness(dep.libName, dep.commit, platforms);
|
|
1565
|
+
const { existing: rawExisting } = await store.checkPlatformCompleteness(dep.libName, dep.commit, platforms);
|
|
1566
|
+
// 完整性校验:验证 existing 平台的文件完整性
|
|
1567
|
+
const { valid: verifiedExisting, corrupted } = await verifyExistingPlatforms(dep.libName, dep.commit, rawExisting);
|
|
1568
|
+
// 清除损坏的平台数据
|
|
1569
|
+
if (corrupted.length > 0) {
|
|
1570
|
+
const registry = getRegistry();
|
|
1571
|
+
for (const platform of corrupted) {
|
|
1572
|
+
const storeKey = registry.getStoreKey(dep.libName, dep.commit, platform);
|
|
1573
|
+
registry.removeStore(storeKey);
|
|
1574
|
+
const platformPath = store.getLibraryPath(storePath, dep.libName, dep.commit, platform);
|
|
1575
|
+
await fs.rm(platformPath, { recursive: true, force: true }).catch(() => { });
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
const existing = verifiedExisting;
|
|
1565
1579
|
// 也检查是否为 General 库(有 _shared 且有内容)
|
|
1566
1580
|
const isGeneral = await store.isGeneralLib(dep.libName, dep.commit);
|
|
1567
1581
|
const inStore = existing.length > 0 || isGeneral;
|
|
@@ -1753,14 +1767,14 @@ async function supplementMissingPlatforms(dependency, platforms, registry, tx, o
|
|
|
1753
1767
|
for (const platform of downloaded) {
|
|
1754
1768
|
const storeKey = registry.getStoreKey(dependency.libName, dependency.commit, platform);
|
|
1755
1769
|
if (!registry.getStore(storeKey)) {
|
|
1756
|
-
const
|
|
1770
|
+
const integrity = await store.captureIntegrity(dependency.libName, dependency.commit, platform);
|
|
1757
1771
|
registry.addStore({
|
|
1758
1772
|
libName: dependency.libName,
|
|
1759
1773
|
commit: dependency.commit,
|
|
1760
1774
|
platform,
|
|
1761
1775
|
branch: dependency.branch,
|
|
1762
1776
|
url: dependency.url,
|
|
1763
|
-
|
|
1777
|
+
...integrity,
|
|
1764
1778
|
usedBy: [],
|
|
1765
1779
|
createdAt: new Date().toISOString(),
|
|
1766
1780
|
lastAccess: new Date().toISOString(),
|
|
@@ -1963,10 +1977,24 @@ async function linkNestedDependencies(dependencies, params) {
|
|
|
1963
1977
|
const availablePlatforms = platforms.filter(p => !unavailablePlatforms.includes(p));
|
|
1964
1978
|
const knownUnavailable = platforms.filter(p => unavailablePlatforms.includes(p));
|
|
1965
1979
|
let storeHas = false;
|
|
1980
|
+
const existingPlatforms = [];
|
|
1966
1981
|
for (const p of availablePlatforms) {
|
|
1967
1982
|
if (await store.exists(dep.libName, dep.commit, p)) {
|
|
1983
|
+
existingPlatforms.push(p);
|
|
1968
1984
|
storeHas = true;
|
|
1969
|
-
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
// 完整性校验:验证 existing 平台的文件完整性(与 classifyDependencies 同逻辑)
|
|
1988
|
+
if (existingPlatforms.length > 0) {
|
|
1989
|
+
const { valid: verifiedPlatforms, corrupted } = await verifyExistingPlatforms(dep.libName, dep.commit, existingPlatforms);
|
|
1990
|
+
if (corrupted.length > 0) {
|
|
1991
|
+
for (const p of corrupted) {
|
|
1992
|
+
const storeKey = registry.getStoreKey(dep.libName, dep.commit, p);
|
|
1993
|
+
registry.removeStore(storeKey);
|
|
1994
|
+
const platformPath = store.getLibraryPath(await store.getStorePath(), dep.libName, dep.commit, p);
|
|
1995
|
+
await fs.rm(platformPath, { recursive: true, force: true }).catch(() => { });
|
|
1996
|
+
}
|
|
1997
|
+
storeHas = verifiedPlatforms.length > 0;
|
|
1970
1998
|
}
|
|
1971
1999
|
}
|
|
1972
2000
|
let isGeneral = await store.isGeneralLib(dep.libName, dep.commit);
|
|
@@ -2257,5 +2285,58 @@ function mergeDepLists(main, optional) {
|
|
|
2257
2285
|
}
|
|
2258
2286
|
return Array.from(depMap.values());
|
|
2259
2287
|
}
|
|
2288
|
+
/**
|
|
2289
|
+
* 校验已有平台的完整性
|
|
2290
|
+
* 遍历 existing 平台列表,查询 Registry 中的 StoreEntry,
|
|
2291
|
+
* 如果有 fileCount,调用 quickVerify 校验;匹配则保留,不匹配则标记为 corrupted。
|
|
2292
|
+
* 没有 fileCount 的条目跳过校验(视为合法)。
|
|
2293
|
+
*
|
|
2294
|
+
* @param libName 库名
|
|
2295
|
+
* @param commit commit hash
|
|
2296
|
+
* @param existingPlatforms Store 中已有的平台列表
|
|
2297
|
+
* @returns { valid: string[]; corrupted: string[] } 合法和损坏的平台列表
|
|
2298
|
+
*/
|
|
2299
|
+
export async function verifyExistingPlatforms(libName, commit, existingPlatforms) {
|
|
2300
|
+
const valid = [];
|
|
2301
|
+
const corrupted = [];
|
|
2302
|
+
const registry = getRegistry();
|
|
2303
|
+
for (const platform of existingPlatforms) {
|
|
2304
|
+
const storeKey = registry.getStoreKey(libName, commit, platform);
|
|
2305
|
+
const entry = registry.getStore(storeKey);
|
|
2306
|
+
// 没有 StoreEntry 或没有 fileCount 的条目,跳过校验视为合法
|
|
2307
|
+
if (!entry || entry.fileCount == null) {
|
|
2308
|
+
valid.push(platform);
|
|
2309
|
+
continue;
|
|
2310
|
+
}
|
|
2311
|
+
const result = await store.quickVerify(libName, commit, platform, {
|
|
2312
|
+
size: entry.size,
|
|
2313
|
+
fileCount: entry.fileCount,
|
|
2314
|
+
});
|
|
2315
|
+
if (result.valid) {
|
|
2316
|
+
valid.push(platform);
|
|
2317
|
+
}
|
|
2318
|
+
else {
|
|
2319
|
+
corrupted.push(platform);
|
|
2320
|
+
warn(`${libName} (${commit.slice(0, 7)}) ${platform}: 完整性校验失败 - ${result.reason}`);
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
return { valid, corrupted };
|
|
2324
|
+
}
|
|
2325
|
+
/**
|
|
2326
|
+
* 创建带完整性信息的 StoreEntry
|
|
2327
|
+
* 在 addStore 时自动采集 fileCount 和 contentHash
|
|
2328
|
+
* @param params StoreEntry 基础参数(不含 fileCount/contentHash)
|
|
2329
|
+
* @returns 包含完整性信息的 StoreEntry
|
|
2330
|
+
*/
|
|
2331
|
+
export async function createStoreEntryWithIntegrity(params) {
|
|
2332
|
+
const integrity = await store.captureIntegrity(params.libName, params.commit, params.platform);
|
|
2333
|
+
return {
|
|
2334
|
+
...params,
|
|
2335
|
+
...integrity,
|
|
2336
|
+
usedBy: [],
|
|
2337
|
+
createdAt: new Date().toISOString(),
|
|
2338
|
+
lastAccess: new Date().toISOString(),
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2260
2341
|
export default createLinkCommand;
|
|
2261
2342
|
//# sourceMappingURL=link.js.map
|