pre-dev.mjs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import fs from "fs-extra";
  2. import zlib from "zlib";
  3. import path from "path";
  4. import AdmZip from "adm-zip";
  5. import fetch from "node-fetch";
  6. import { execSync } from "child_process";
  7. const cwd = process.cwd();
  8. const CLASH_URL_PREFIX =
  9. "https://github.com/Dreamacro/clash/releases/download/premium/";
  10. const CLASH_LATEST_DATE = "2021.12.07";
  11. /**
  12. * get the correct clash release infomation
  13. */
  14. function resolveClash() {
  15. const { platform, arch } = process;
  16. // todo
  17. const map = {
  18. "win32-x64": "clash-windows-386",
  19. "darwin-x64": "clash-darwin-amd64",
  20. "darwin-arm64": "clash-darwin-arm64",
  21. };
  22. const name = map[`${platform}-${arch}`];
  23. if (!name) {
  24. throw new Error(`unsupport platform "${platform}-${arch}"`);
  25. }
  26. const isWin = platform === "win32";
  27. const zip = isWin ? "zip" : "gz";
  28. const url = `${CLASH_URL_PREFIX}${name}-${CLASH_LATEST_DATE}.${zip}`;
  29. const exefile = `${name}${isWin ? ".exe" : ""}`;
  30. const zipfile = `${name}.${zip}`;
  31. return { url, zip, exefile, zipfile };
  32. }
  33. /**
  34. * get the sidecar bin
  35. */
  36. async function resolveSidecar() {
  37. const sidecarDir = path.join(cwd, "src-tauri", "sidecar");
  38. const host = execSync("rustc -vV | grep host").toString().slice(6).trim();
  39. const ext = process.platform === "win32" ? ".exe" : "";
  40. const sidecarFile = `clash-${host}${ext}`;
  41. const sidecarPath = path.join(sidecarDir, sidecarFile);
  42. if (!(await fs.pathExists(sidecarDir))) await fs.mkdir(sidecarDir);
  43. if (await fs.pathExists(sidecarPath)) return;
  44. // download sidecar
  45. const binInfo = resolveClash();
  46. const tempDir = path.join(cwd, "pre-dev-temp");
  47. const tempZip = path.join(tempDir, binInfo.zipfile);
  48. const tempExe = path.join(tempDir, binInfo.exefile);
  49. if (!(await fs.pathExists(tempDir))) await fs.mkdir(tempDir);
  50. if (!(await fs.pathExists(tempZip))) await downloadFile(binInfo.url, tempZip);
  51. // Todo: support gz
  52. if (binInfo.zip === "zip") {
  53. const zip = new AdmZip(tempZip);
  54. zip.getEntries().forEach((entry) => {
  55. console.log("[INFO]: entry name", entry.entryName);
  56. });
  57. zip.extractAllTo(tempDir, true);
  58. // save as sidecar
  59. await fs.rename(tempExe, sidecarPath);
  60. console.log(`[INFO]: unzip finished`);
  61. } else {
  62. // gz
  63. const readStream = fs.createReadStream(tempZip);
  64. const writeStream = fs.createWriteStream(sidecarPath);
  65. readStream
  66. .pipe(zlib.createGunzip())
  67. .pipe(writeStream)
  68. .on("finish", () => {
  69. console.log(`[INFO]: gunzip finished`);
  70. execSync(`chmod 755 ${sidecarPath}`);
  71. console.log(`[INFO]: chmod binary finished`);
  72. });
  73. }
  74. // delete temp dir
  75. await fs.remove(tempDir);
  76. }
  77. /**
  78. * get the Country.mmdb (not required)
  79. */
  80. async function resolveMmdb() {
  81. const url =
  82. "https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb";
  83. const resPath = path.join(cwd, "src-tauri", "resources", "Country.mmdb");
  84. if (await fs.pathExists(resPath)) return;
  85. await downloadFile(url, resPath);
  86. }
  87. /**
  88. * download file and save to `path`
  89. */
  90. async function downloadFile(url, path) {
  91. console.log(`[INFO]: downloading from "${url}"`);
  92. const response = await fetch(url, {
  93. method: "GET",
  94. headers: { "Content-Type": "application/octet-stream" },
  95. });
  96. const buffer = await response.arrayBuffer();
  97. await fs.writeFile(path, new Uint8Array(buffer));
  98. console.log(`[INFO]: download finished "${url}"`);
  99. }
  100. /// main
  101. resolveSidecar();
  102. resolveMmdb();