@42ailab/42plugin 0.1.25 → 0.1.26
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/package.json +1 -1
- package/src/db.ts +37 -45
package/package.json
CHANGED
package/src/db.ts
CHANGED
|
@@ -581,24 +581,49 @@ export async function downloadAndExtract(
|
|
|
581
581
|
}
|
|
582
582
|
|
|
583
583
|
// 解压
|
|
584
|
-
|
|
584
|
+
if (isWindows) {
|
|
585
|
+
// Windows: 使用 tar.Parser 手动提取,解决 Bun 编译的 tar 包无法正确写入文件的问题
|
|
586
|
+
const fileBuffer = await fs.readFile(tempFile);
|
|
587
|
+
const { Parser } = await import('tar');
|
|
588
|
+
const parser = new Parser();
|
|
589
|
+
const extractPromises: Promise<void>[] = [];
|
|
590
|
+
|
|
591
|
+
parser.on('entry', (entry) => {
|
|
592
|
+
const entryPath = path.join(targetDir, entry.path);
|
|
593
|
+
if (entry.type === 'Directory') {
|
|
594
|
+
extractPromises.push(fs.mkdir(entryPath, { recursive: true }));
|
|
595
|
+
} else if (entry.type === 'File') {
|
|
596
|
+
const chunks: Buffer[] = [];
|
|
597
|
+
entry.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
598
|
+
entry.on('end', () => {
|
|
599
|
+
extractPromises.push(
|
|
600
|
+
(async () => {
|
|
601
|
+
await fs.mkdir(path.dirname(entryPath), { recursive: true });
|
|
602
|
+
await fs.writeFile(entryPath, Buffer.concat(chunks));
|
|
603
|
+
})()
|
|
604
|
+
);
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
entry.resume();
|
|
608
|
+
});
|
|
585
609
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
610
|
+
await new Promise<void>((resolve, reject) => {
|
|
611
|
+
parser.on('end', resolve);
|
|
612
|
+
parser.on('error', reject);
|
|
613
|
+
parser.write(fileBuffer);
|
|
614
|
+
parser.end();
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
await Promise.all(extractPromises);
|
|
618
|
+
} else {
|
|
619
|
+
await tar.extract({ file: tempFile, cwd: targetDir, strip: 0 });
|
|
589
620
|
}
|
|
590
621
|
|
|
591
622
|
// 清理
|
|
592
623
|
await fs.unlink(tempFile).catch(() => {});
|
|
593
624
|
|
|
594
625
|
// 返回最终路径(如果只有一个子目录则进入)
|
|
595
|
-
|
|
596
|
-
if (config.debug) {
|
|
597
|
-
console.log(`[DEBUG] 最终缓存路径: ${finalPath}`);
|
|
598
|
-
const finalEntries = await fs.readdir(finalPath).catch(() => []);
|
|
599
|
-
console.log(`[DEBUG] 最终路径内容: ${finalEntries.join(', ') || '(空)'}`);
|
|
600
|
-
}
|
|
601
|
-
return finalPath;
|
|
626
|
+
return resolveFinalPath(targetDir, pluginType);
|
|
602
627
|
} catch (error) {
|
|
603
628
|
await fs.rm(targetDir, { recursive: true, force: true }).catch(() => {});
|
|
604
629
|
throw error;
|
|
@@ -765,17 +790,6 @@ export async function createLink(
|
|
|
765
790
|
const targetDir = path.dirname(normalizedTarget);
|
|
766
791
|
await fs.mkdir(targetDir, { recursive: true });
|
|
767
792
|
|
|
768
|
-
if (config.debug) {
|
|
769
|
-
console.log(`[DEBUG] createLink: ${sourcePath} -> ${normalizedTarget}`);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
// 验证源路径存在
|
|
773
|
-
try {
|
|
774
|
-
await fs.access(sourcePath);
|
|
775
|
-
} catch {
|
|
776
|
-
throw new Error(`源路径不存在: ${sourcePath}`);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
793
|
// 移除已存在的链接
|
|
780
794
|
try {
|
|
781
795
|
const stat = await fs.lstat(normalizedTarget);
|
|
@@ -790,11 +804,6 @@ export async function createLink(
|
|
|
790
804
|
const sourceStat = await fs.stat(sourcePath);
|
|
791
805
|
const isDirectory = sourceStat.isDirectory();
|
|
792
806
|
|
|
793
|
-
if (config.debug && isDirectory) {
|
|
794
|
-
const entries = await fs.readdir(sourcePath);
|
|
795
|
-
console.log(`[DEBUG] 源目录内容 (${entries.length} 项): ${entries.join(', ')}`);
|
|
796
|
-
}
|
|
797
|
-
|
|
798
807
|
// 尝试创建符号链接
|
|
799
808
|
try {
|
|
800
809
|
const linkType = isDirectory ? 'dir' : 'file';
|
|
@@ -815,36 +824,19 @@ export async function createLink(
|
|
|
815
824
|
// 回退方案 1: 对于目录,尝试使用 Junction
|
|
816
825
|
if (isDirectory) {
|
|
817
826
|
try {
|
|
818
|
-
if (config.debug) {
|
|
819
|
-
console.log(`[DEBUG] 尝试创建 Junction: ${normalizedTarget} -> ${sourcePath}`);
|
|
820
|
-
}
|
|
821
827
|
await createJunction(sourcePath, normalizedTarget);
|
|
822
|
-
if (config.debug) {
|
|
823
|
-
console.log(`[DEBUG] Junction 创建成功`);
|
|
824
|
-
}
|
|
825
828
|
return;
|
|
826
|
-
} catch
|
|
827
|
-
if (config.debug) {
|
|
828
|
-
console.log(`[DEBUG] Junction 创建失败: ${(junctionError as Error).message}`);
|
|
829
|
-
}
|
|
829
|
+
} catch {
|
|
830
830
|
// Junction 也失败,继续尝试复制
|
|
831
831
|
}
|
|
832
832
|
}
|
|
833
833
|
|
|
834
834
|
// 回退方案 2: 直接复制文件/目录
|
|
835
|
-
// 这是最后的保底方案,虽然会占用更多磁盘空间
|
|
836
835
|
console.warn(
|
|
837
836
|
`[Windows] 符号链接创建失败,回退到文件复制模式\n` +
|
|
838
837
|
` 提示: 启用 Windows 开发者模式可使用符号链接,节省磁盘空间`
|
|
839
838
|
);
|
|
840
|
-
if (config.debug) {
|
|
841
|
-
console.log(`[DEBUG] 开始复制: ${sourcePath} -> ${normalizedTarget}`);
|
|
842
|
-
}
|
|
843
839
|
await copyRecursive(sourcePath, normalizedTarget);
|
|
844
|
-
if (config.debug) {
|
|
845
|
-
const destEntries = await fs.readdir(normalizedTarget).catch(() => []);
|
|
846
|
-
console.log(`[DEBUG] 复制完成,目标目录内容: ${destEntries.join(', ') || '(空)'}`);
|
|
847
|
-
}
|
|
848
840
|
}
|
|
849
841
|
}
|
|
850
842
|
|