From 9638eefc91cca295eb9bb1fd24fe36a1e2a92396 Mon Sep 17 00:00:00 2001
From: GyDi <zzzgydi@gmail.com>
Date: Tue, 11 Jul 2023 13:25:55 +0800
Subject: [PATCH] chore: update check script

---
 scripts/check.mjs | 107 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 74 insertions(+), 33 deletions(-)

diff --git a/scripts/check.mjs b/scripts/check.mjs
index c8a38c0..f0604f3 100644
--- a/scripts/check.mjs
+++ b/scripts/check.mjs
@@ -15,6 +15,7 @@ const SIDECAR_HOST = execSync("rustc -vV")
   .match(/(?<=host: ).+(?=\s*)/g)[0];
 
 /* ======= clash ======= */
+const CLASH_STORAGE_PREFIX = "https://release.dreamacro.workers.dev/";
 const CLASH_URL_PREFIX =
   "https://github.com/Dreamacro/clash/releases/download/premium/";
 const CLASH_LATEST_DATE = "2023.06.30";
@@ -32,11 +33,11 @@ const META_URL_PREFIX = `https://github.com/MetaCubeX/Clash.Meta/releases/downlo
 const META_VERSION = "v1.15.0";
 
 const META_MAP = {
-  "win32-x64": "Clash.Meta-windows-amd64-compatible",
-  "darwin-x64": "Clash.Meta-darwin-amd64",
-  "darwin-arm64": "Clash.Meta-darwin-arm64",
-  "linux-x64": "Clash.Meta-linux-amd64-compatible",
-  "linux-arm64": "Clash.Meta-linux-arm64",
+  "win32-x64": "clash.meta-windows-amd64-compatible",
+  "darwin-x64": "clash.meta-darwin-amd64",
+  "darwin-arm64": "clash.meta-darwin-arm64",
+  "linux-x64": "clash.meta-linux-amd64-compatible",
+  "linux-arm64": "clash.meta-linux-arm64",
 };
 
 /**
@@ -69,6 +70,24 @@ function clash() {
   };
 }
 
+function clashS3() {
+  const name = CLASH_MAP[`${platform}-${arch}`];
+
+  const isWin = platform === "win32";
+  const urlExt = isWin ? "zip" : "gz";
+  const downloadURL = `${CLASH_STORAGE_PREFIX}${CLASH_LATEST_DATE}/${name}-${CLASH_LATEST_DATE}.${urlExt}`;
+  const exeFile = `${name}${isWin ? ".exe" : ""}`;
+  const zipFile = `${name}.${urlExt}`;
+
+  return {
+    name: "clash",
+    targetFile: `clash-${SIDECAR_HOST}${isWin ? ".exe" : ""}`,
+    exeFile,
+    zipFile,
+    downloadURL,
+  };
+}
+
 function clashMeta() {
   const name = META_MAP[`${platform}-${arch}`];
   const isWin = platform === "win32";
@@ -103,36 +122,58 @@ async function resolveSidecar(binInfo) {
   const tempExe = path.join(tempDir, exeFile);
 
   await fs.mkdirp(tempDir);
-  if (!(await fs.pathExists(tempZip))) await downloadFile(downloadURL, tempZip);
-
-  if (zipFile.endsWith(".zip")) {
-    const zip = new AdmZip(tempZip);
-    zip.getEntries().forEach((entry) => {
-      console.log(`[DEBUG]: ${name} entry name`, entry.entryName);
-    });
-    zip.extractAllTo(tempDir, true);
-    await fs.rename(tempExe, sidecarPath);
-    console.log(`[INFO]: ${name} unzip finished`);
-  } else {
-    // gz
-    const readStream = fs.createReadStream(tempZip);
-    const writeStream = fs.createWriteStream(sidecarPath);
-    readStream
-      .pipe(zlib.createGunzip())
-      .pipe(writeStream)
-      .on("finish", () => {
-        console.log(`[INFO]: ${name} gunzip finished`);
-        execSync(`chmod 755 ${sidecarPath}`);
-        console.log(`[INFO]: ${name} chmod binary finished`);
-      })
-      .on("error", (error) => {
-        console.error(`[ERROR]: ${name} gz failed`, error.message);
-        throw error;
+  try {
+    if (!(await fs.pathExists(tempZip)))
+      await downloadFile(downloadURL, tempZip);
+
+    if (zipFile.endsWith(".zip")) {
+      const zip = new AdmZip(tempZip);
+      zip.getEntries().forEach((entry) => {
+        console.log(`[DEBUG]: "${name}" entry name`, entry.entryName);
+      });
+      zip.extractAllTo(tempDir, true);
+      await fs.rename(tempExe, sidecarPath);
+      console.log(`[INFO]: "${name}" unzip finished`);
+    } else {
+      // gz
+      const readStream = fs.createReadStream(tempZip);
+      const writeStream = fs.createWriteStream(sidecarPath);
+      await new Promise((resolve, reject) => {
+        const onError = (error) => {
+          console.error(`[ERROR]: "${name}" gz failed`, error.message);
+          reject(error);
+        };
+        readStream
+          .pipe(zlib.createGunzip().on("error", onError))
+          .pipe(writeStream)
+          .on("finish", () => {
+            console.log(`[INFO]: "${name}" gunzip finished`);
+            execSync(`chmod 755 ${sidecarPath}`);
+            console.log(`[INFO]: "${name}" chmod binary finished`);
+            resolve();
+          })
+          .on("error", onError);
       });
+    }
+  } catch (err) {
+    throw err;
+  } finally {
+    // delete temp dir
+    await fs.remove(tempDir);
   }
+}
 
-  // delete temp dir
-  await fs.remove(tempDir);
+/**
+ * prepare clash core
+ * if the core version is not updated in time, use S3 storage as a backup.
+ */
+async function resolveClash() {
+  try {
+    return await resolveSidecar(clash());
+  } catch {
+    console.log(`[WARN]: clash core needs to be updated`);
+    return await resolveSidecar(clashS3());
+  }
 }
 
 /**
@@ -256,7 +297,7 @@ const resolveGeoIP = () =>
   });
 
 const tasks = [
-  { name: "clash", func: () => resolveSidecar(clash()), retry: 5 },
+  { name: "clash", func: resolveClash, retry: 5 },
   { name: "clash-meta", func: () => resolveSidecar(clashMeta()), retry: 5 },
   { name: "wintun", func: resolveWintun, retry: 5, winOnly: true },
   { name: "service", func: resolveService, retry: 5, winOnly: true },
-- 
GitLab