Parcourir la source

ref: add build nbr, colors, general refactor

Sv443 il y a 1 an
Parent
commit
e93ba31d5f
7 fichiers modifiés avec 104 ajouts et 61 suppressions
  1. 1 1
      package.json
  2. 45 46
      src/BetterYTM.user.ts
  3. 24 0
      src/colors.ts
  4. 5 11
      src/config.ts
  5. 2 0
      src/constants.ts
  6. 23 3
      src/tools/post-build.ts
  7. 4 0
      tsconfig.json

+ 1 - 1
package.json

@@ -66,4 +66,4 @@
       "dev/*"
     ]
   }
-}
+}

+ 45 - 46
src/BetterYTM.user.ts

@@ -14,17 +14,13 @@ import {
   initMenu, addMenu,
 } from "./features/index";
 
-(async () => {
-  //#MARKER init
-
-  const features = await getFeatures();
-
+async function init() {
   await preInitLayout();
 
   try {
     // TODO: add some style
-    console.log(`${info.name} v${info.version} - ${info.namespace}`);
-    console.log(`Powered by lots of ambition and my song metadata API called geniURL: ${geniUrlBase}`);
+    console.log(`${info.name} v${info.version} (${info.lastCommit}) - ${info.namespace}`);
+    console.log(`Powered by lots of ambition and my song metadata API: ${geniUrlBase}`);
 
     document.addEventListener("DOMContentLoaded", onDomLoad);
   }
@@ -32,58 +28,61 @@ import {
     console.error("BetterYTM - General Error:", err);
   }
 
-  /** Called when the DOM has finished loading (after `DOMContentLoaded` is emitted) */
-  async function onDomLoad() {
-    const domain = getDomain();
+  try {
+    initMenu();
+  }
+  catch(err) {
+    console.error("BetterYTM: Couldn't initialize menu:", err);
+  }
+}
+
+/** Called when the DOM has finished loading and can be queried and altered by the userscript */
+async function onDomLoad() {
+  const features = await getFeatures();
+  const domain = getDomain();
 
-    dbg && console.log(`BetterYTM: Initializing features for domain '${domain}'`);
+  dbg && console.log(`BetterYTM: Initializing features for domain '${domain}'`);
 
-    initSiteEvents();
+  initSiteEvents();
 
-    try {
-      if(domain === "ytm") {
-        if(features.arrowKeySupport)
-          initArrowKeySkip();
+  try {
+    if(domain === "ytm") {
+      if(features.arrowKeySupport)
+        initArrowKeySkip();
 
-        if(features.removeUpgradeTab)
-          removeUpgradeTab();
+      if(features.removeUpgradeTab)
+        removeUpgradeTab();
 
-        if(features.watermarkEnabled)
-          addWatermark();
+      if(features.watermarkEnabled)
+        addWatermark();
 
-        if(features.geniusLyrics)
-          addMediaCtrlGeniusBtn();
+      if(features.geniusLyrics)
+        addMediaCtrlGeniusBtn();
 
-        if(features.queueButtons)
-          initQueueButtons();
+      if(features.queueButtons)
+        initQueueButtons();
 
-        if(typeof features.volumeSliderSize === "number")
-          setVolSliderSize();
+      if(typeof features.volumeSliderSize === "number")
+        setVolSliderSize();
 
-        setVolSliderStep();
-      }
+      setVolSliderStep();
+    }
 
-      if(["ytm", "yt"].includes(domain)) {
-        if(features.switchBetweenSites)
-          initSiteSwitch(domain);
+    if(["ytm", "yt"].includes(domain)) {
+      if(features.switchBetweenSites)
+        initSiteSwitch(domain);
 
-        try {
-          addMenu(); // TODO: remove
-        }
-        catch(err) {
-          console.error("BetterYTM: Couldn't add menu:", err);
-        }
+      try {
+        addMenu(); // TODO: remove
+      }
+      catch(err) {
+        console.error("BetterYTM: Couldn't add menu:", err);
       }
-    }
-    catch(err) {
-      console.error("BetterYTM: General error while executing feature:", err);
     }
   }
-
-  try {
-    initMenu();
-  }
   catch(err) {
-    console.error("BetterYTM: Couldn't initialize menu:", err);
+    console.error("BetterYTM: General error while executing feature:", err);
   }
-})();
+}
+
+init();

+ 24 - 0
src/colors.ts

@@ -0,0 +1,24 @@
+export const col = {
+  rst:        "\x1b[0m", fat:     "\x1b[1m",
+  blink:      "\x1b[5m", dim:     "\x1b[2m",
+  underscore: "\x1b[4m", reverse: "\x1b[7m",
+  hidden:     "\x1b[8m",
+
+  black: "\x1b[30m", red:     "\x1b[31m",
+  green: "\x1b[32m", yellow:  "\x1b[33m",
+  blue:  "\x1b[34m", magenta: "\x1b[35m",
+  cyan:  "\x1b[36m", white:   "\x1b[37m",
+  fgb: {
+    black: "\x1b[1m\x1b[30m", red:     "\x1b[1m\x1b[31m",
+    green: "\x1b[1m\x1b[32m", yellow:  "\x1b[1m\x1b[33m",
+    blue:  "\x1b[1m\x1b[34m", magenta: "\x1b[1m\x1b[35m",
+    cyan:  "\x1b[1m\x1b[36m", white:   "\x1b[1m\x1b[37m",
+  },
+  bg: {
+    black: "\x1b[40m", red:     "\x1b[41m",
+    green: "\x1b[42m", yellow:  "\x1b[43m",
+    blue:  "\x1b[44m", magenta: "\x1b[45m",
+    cyan:  "\x1b[46m", white:   "\x1b[47m",
+    rst:   "\x1b[0m",
+  }
+};

+ 5 - 11
src/config.ts

@@ -14,15 +14,8 @@ let featuresCache: FeatureConfig | undefined;
  * @param forceRead Set to true to force reading the config from GM storage
  */
 export async function getFeatures(forceRead = false) {
-  let features: FeatureConfig | undefined;
-
-  if(featuresCache === undefined || forceRead) {
-    const featureConf = await loadFeatureConf();
-
-    featuresCache = features = { ...defaultFeatures, ...featureConf };
-
-    await saveFeatureConf(features);
-  }
+  if(featuresCache === undefined || forceRead)
+    await saveFeatureConf(featuresCache = { ...defaultFeatures, ...await loadFeatureConf() }); // look at this sexy one liner
   return featuresCache;
 }
 
@@ -31,8 +24,7 @@ export async function loadFeatureConf(): Promise<FeatureConfig> {
   const defConf = Object.freeze({ ...defaultFeatures });
 
   try {
-    /** @type {string} */
-    const featureConf = await GM.getValue("betterytm-config");
+    const featureConf = await GM.getValue("betterytm-config") as string;
 
     if(typeof featureConf !== "string") {
       await setDefaultFeatConf();
@@ -55,9 +47,11 @@ export function saveFeatureConf(featureConf: FeatureConfig) {
   if(!featureConf || typeof featureConf != "object")
     throw new TypeError("Feature config not provided or invalid");
 
+  featuresCache = { ...featureConf };
   return GM.setValue("betterytm-config", JSON.stringify(featureConf));
 }
 
 function setDefaultFeatConf() {
+  featuresCache = { ...defaultFeatures };
   return GM.setValue("betterytm-config", JSON.stringify(defaultFeatures));
 }

+ 2 - 0
src/constants.ts

@@ -1,5 +1,6 @@
 /** Set to true to enable debug mode for more output in the JS console */
 export const dbg = true;
+
 /** Specifies the hard limit for repetitive tasks */
 export const triesLimit = 50;
 /** Specifies the interval for repetitive tasks */
@@ -10,4 +11,5 @@ export const info = Object.freeze({
   name: GM.info.script.name,
   version: GM.info.script.version,
   namespace: GM.info.script.namespace,
+  lastCommit: "{{BUILD_NUMBER}}" as string, // assert as generic string instead of union
 });

+ 23 - 3
src/tools/post-build.ts

@@ -1,6 +1,7 @@
 import { readFile, writeFile, stat } from "fs/promises";
 import { dirname, join } from "path";
 import { fileURLToPath } from "url";
+import { exec } from "child_process";
 import pkg from "../../package.json" assert { type: "json" };
 
 const repo = "Sv443/BetterYTM";
@@ -47,10 +48,16 @@ const header = `\
 
 (async () => {
   try {
+    const lastCommitSha = await getLastCommitSha();
     const path = join(dirname(fileURLToPath(import.meta.url)), `../../${userscriptDistPath}`);
-    const input = String(await readFile(path));
-    await writeFile(path, `${header}\n${input}${input.endsWith("\n") ? "" : "\n"}`);
-    console.info("Successfully added the userscript header.");
+
+    // read userscript and inject build number
+    const userscript = String(await readFile(path))
+      .replace(/{{BUILD_NUMBER}}/gm, lastCommitSha);
+
+    await writeFile(path, `${header}\n${userscript}${userscript.endsWith("\n") ? "" : "\n"}`);
+
+    console.info(`Successfully added the userscript header. Last commit SHA is ${lastCommitSha}`);
     console.info(`Final size is \x1b[32m${((await stat(path)).size / 1024).toFixed(2)} KiB\x1b[0m\n`);
   }
   catch(err) {
@@ -59,3 +66,16 @@ const header = `\
     setImmediate(() => process.exit(1));
   }
 })();
+
+/** Used as a kind of "build number", though note it is always behind by at least one commit, as the act of putting this number in the userscript changes the hash again, indefinitely */
+function getLastCommitSha() {
+  return new Promise<string>((res, rej) => {
+    exec("git rev-parse HEAD", (err, stdout, stderr) => {
+      if(err) {
+        console.error("\x1b[31mError while checking for last Git commit. Do you have Git installed?\x1b[0m\n", stderr);
+        return rej(err);
+      }
+      return res(String(stdout).replace(/\r?\n/gm, "").trim().substring(0, 7));
+    });
+  });
+}

+ 4 - 0
tsconfig.json

@@ -21,6 +21,10 @@
     "strict": true,
     "useDefineForClassFields": true,
   },
+  "ts-node": {
+    "esm": true,
+    "preferTsExts": true,
+  },
   "exclude": [
     "**/*.js",
     "dist/**",