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.
@@ -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 platformSize = await store.getSize(dependency.libName, dependency.commit, platform);
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
- size: platformSize,
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 sharedSize = await getDirSize(sharedPath);
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
- size: sharedSize,
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 sharedSize = await getDirSize(sharedPath);
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
- size: sharedSize,
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 platformSize = await store.getSize(dependency.libName, dependency.commit, platform);
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
- size: platformSize,
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 platformSize = await store.getSize(dependency.libName, dependency.commit, platform);
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
- size: platformSize,
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 sharedSize = await getDirSize(sharedPath);
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
- size: sharedSize,
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 sharedSize = await getDirSize(sharedPath);
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
- size: sharedSize,
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 platformSize = await store.getSize(dependency.libName, dependency.commit, platform);
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
- size: platformSize,
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 sharedSize = await getDirSize(sharedPath);
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
- size: sharedSize,
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(sharedSize)})`);
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
- size: nested.size,
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 platformSize = await store.getSize(nested.libName, nested.commit, platform);
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
- size: platformSize,
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 platformSize = await store.getSize(dependency.libName, dependency.commit, platform);
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
- size: platformSize,
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
- break;
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