🏡 index : github.com/captn3m0/which-electron.git

author Nemo <commits@captnemo.in> 2022-04-17 20:14:32.0 +05:30:00
committer Nemo <commits@captnemo.in> 2022-04-17 20:14:32.0 +05:30:00
commit
2833c36bf131f2f560b4286909839500cd87058c [patch]
tree
bf5c3db164985df6be753b3f119d9654e53708ae
parent
65049c9ed2d585d9defbd32e5399040af225a855
download
2833c36bf131f2f560b4286909839500cd87058c.tar.gz

next version

- switch to uvu
- switch to ESM
- still broken
need to fix

Diff

 elftest.js           |  29 +++++++++++++++++++++++++++++
 package-lock.json    | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 package.json         |  13 ++++++++++---
 src/archive.js       |  88 +++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
 src/elf.js           |  35 +++++++++++++++++++++++++++++++++++
 src/finder.js        | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/fingerprint.js   |  78 ++++++++++++++++++++++++++++++++++++++++--------------------------------------
 src/index.js         | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 src/os.js            |  81 ++++++++++++++++++++++++++++++++++++++++++++------------------------------------
 src/utils.js         |   8 +++-----
 src/version.js       |  29 +++++++++++++----------------
 src/versions.json    |  21 ++++++++++++++++-----
 tests/finder.js      |  66 ++++++++++++++++++++++++++++++++++++------------------------------
 tests/fingerprint.js |  20 +++++++++++---------
 tests/os.js          |  94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 tests/utils.js       |  24 +++++++++++-------------
 16 files changed, 647 insertions(+), 345 deletions(-)

diff --git a/elftest.js b/elftest.js
new file mode 100644
index 0000000..e2d8b5d 100644
--- /dev/null
+++ a/elftest.js
@@ -1,0 +1,29 @@
const E = require('elfinfo')
const fs = require('fs')

// Parse the specified ELF file.
const path ='../aur-notable/notable'
const elfdata = fs.readFileSync(path);
let info = null
E.open(elfdata).then((info)=>{
  let rodata = info.elf.sections.filter((x)=>{return x.name=='.rodata'})[0]

  const data = fs.createReadStream(path, {
    start: Number(rodata.addr),
    end: Number(rodata.addr) + rodata.size,
    highWaterMark: rodata.addralign
  })

    data.on('data', function(data){
    let found = data.toString().match(/Electron\/(\d+\.\d+\.\d+)/)
    if(found) {
      console.log(found[1])
    }
  });
})






diff --git a/package-lock.json b/package-lock.json
index 5461d9d..e1abfb1 100644
--- a/package-lock.json
+++ a/package-lock.json
@@ -10,7 +10,9 @@
      "license": "MIT",
      "dependencies": {
        "7zip-bin": "^5.1.1",
        "disassembler": "^0.3.0-beta",
        "electron-fingerprints": "*",
        "elfinfo": "^0.3.0-beta",
        "hasha": "^5.2.2",
        "is-valid-http-url": "^1.0.3",
        "node-7z": "^3.0.0",
@@ -23,7 +25,11 @@
        "which-electron": "src/index.js"
      },

      "devDependencies": {
        "kuta": "*"
        "kuta": "*",
        "uvu": "^0.5.3"
      },

      "engines": {
        "node": " >=14.13.1 || >=16.0.0"
      }

    },

    "node_modules/7zip-bin": {
@@ -108,12 +114,51 @@
        "supports-color": {
          "optional": true
        }

      }

    },

    "node_modules/dequal": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz",
      "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }

    },

    "node_modules/diff": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
      "dev": true,
      "engines": {
        "node": ">=0.3.1"
      }

    },

    "node_modules/disassembler": {
      "version": "0.3.0-beta",
      "resolved": "https://registry.npmjs.org/disassembler/-/disassembler-0.3.0-beta.tgz",
      "integrity": "sha512-mcuYZPmWOhv0S28ou9qYfWswXEJ+5oKUh8GVheLTRcqiMeQisQRDfsAdh80WByB144gT6FLjSFwVBRYX+wMIAw=="
    },

    "node_modules/electron-fingerprints": {
      "version": "2022.3.30",
      "resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-2022.3.30.tgz",
      "integrity": "sha512-RciBhcnMYqNFqeibbKICOqTsCPPFgU+I2KQp3wt77Xw+3YOE3FOPD1XkE/u5k8B/c9tilJ78uowJjElnaRUtHA=="
    },

    "node_modules/elfinfo": {
      "version": "0.3.0-beta",
      "resolved": "https://registry.npmjs.org/elfinfo/-/elfinfo-0.3.0-beta.tgz",
      "integrity": "sha512-pmKnUCHGTkloCxKMoP3GL6j0IzH2MC30STKhv+GJA4uGw1Zv9dfZ3OQQjXF30IHKQlPVW3eECRWCuPJtHqkCIQ==",
      "bin": {
        "elfinfo": "dist/src/elfinfo.js"
      },

      "peerDependencies": {
        "disassembler": "^0.3.0-beta"
      },

      "peerDependenciesMeta": {
        "disassembler": {
          "optional": true
        }

      }

    },

    "node_modules/follow-redirects": {
      "version": "1.14.9",
@@ -174,9 +219,9 @@
      }

    },

    "node_modules/https-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
      "dependencies": {
        "agent-base": "6",
        "debug": "4"
@@ -222,6 +267,15 @@
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
    },

    "node_modules/kleur": {
      "version": "4.1.4",
      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
      "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }

    },

    "node_modules/kuta": {
      "version": "2.0.0-beta.7",
@@ -320,6 +374,15 @@
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
      "dev": true
    },

    "node_modules/mri": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }

    },

    "node_modules/ms": {
      "version": "2.1.2",
@@ -424,6 +487,18 @@
      },

      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }

    },

    "node_modules/sade": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
      "dev": true,
      "dependencies": {
        "mri": "^1.1.0"
      },

      "engines": {
        "node": ">=6"
      }

    },

    "node_modules/sanitize-filename": {
@@ -435,9 +510,9 @@
      }

    },

    "node_modules/semver": {
      "version": "7.3.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
      "version": "7.3.7",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
      "dependencies": {
        "lru-cache": "^6.0.0"
      },

@@ -474,6 +549,24 @@
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
    },

    "node_modules/uvu": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.3.tgz",
      "integrity": "sha512-brFwqA3FXzilmtnIyJ+CxdkInkY/i4ErvP7uV0DnUVxQcQ55reuHphorpF+tZoVHK2MniZ/VJzI7zJQoc9T9Yw==",
      "dev": true,
      "dependencies": {
        "dequal": "^2.0.0",
        "diff": "^5.0.0",
        "kleur": "^4.0.3",
        "sade": "^1.7.3"
      },

      "bin": {
        "uvu": "bin.js"
      },

      "engines": {
        "node": ">=8"
      }

    },

    "node_modules/which": {
      "version": "2.0.2",
@@ -561,11 +654,34 @@
      "requires": {
        "ms": "2.1.2"
      }

    },

    "dequal": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz",
      "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==",
      "dev": true
    },

    "diff": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
      "dev": true
    },

    "disassembler": {
      "version": "0.3.0-beta",
      "resolved": "https://registry.npmjs.org/disassembler/-/disassembler-0.3.0-beta.tgz",
      "integrity": "sha512-mcuYZPmWOhv0S28ou9qYfWswXEJ+5oKUh8GVheLTRcqiMeQisQRDfsAdh80WByB144gT6FLjSFwVBRYX+wMIAw=="
    },

    "electron-fingerprints": {
      "version": "2022.3.30",
      "resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-2022.3.30.tgz",
      "integrity": "sha512-RciBhcnMYqNFqeibbKICOqTsCPPFgU+I2KQp3wt77Xw+3YOE3FOPD1XkE/u5k8B/c9tilJ78uowJjElnaRUtHA=="
    },

    "elfinfo": {
      "version": "0.3.0-beta",
      "resolved": "https://registry.npmjs.org/elfinfo/-/elfinfo-0.3.0-beta.tgz",
      "integrity": "sha512-pmKnUCHGTkloCxKMoP3GL6j0IzH2MC30STKhv+GJA4uGw1Zv9dfZ3OQQjXF30IHKQlPVW3eECRWCuPJtHqkCIQ==",
      "requires": {}
    },

    "follow-redirects": {
      "version": "1.14.9",
@@ -600,9 +716,9 @@
      }

    },

    "https-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
      "requires": {
        "agent-base": "6",
        "debug": "4"
@@ -636,6 +752,12 @@
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
    },

    "kleur": {
      "version": "4.1.4",
      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
      "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
      "dev": true
    },

    "kuta": {
      "version": "2.0.0-beta.7",
@@ -715,6 +837,12 @@
      "version": "1.2.6",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
      "dev": true
    },

    "mri": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
      "dev": true
    },

    "ms": {
@@ -796,6 +924,15 @@
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "requires": {
        "glob": "^7.1.3"
      }

    },

    "sade": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
      "dev": true,
      "requires": {
        "mri": "^1.1.0"
      }

    },

    "sanitize-filename": {
@@ -807,9 +944,9 @@
      }

    },

    "semver": {
      "version": "7.3.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
      "version": "7.3.7",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
      "requires": {
        "lru-cache": "^6.0.0"
      }

@@ -837,6 +974,18 @@
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
    },

    "uvu": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.3.tgz",
      "integrity": "sha512-brFwqA3FXzilmtnIyJ+CxdkInkY/i4ErvP7uV0DnUVxQcQ55reuHphorpF+tZoVHK2MniZ/VJzI7zJQoc9T9Yw==",
      "dev": true,
      "requires": {
        "dequal": "^2.0.0",
        "diff": "^5.0.0",
        "kleur": "^4.0.3",
        "sade": "^1.7.3"
      }

    },

    "which": {
      "version": "2.0.2",
diff --git a/package.json b/package.json
index cab27e5..839c3d9 100644
--- a/package.json
+++ a/package.json
@@ -1,19 +1,22 @@
{
  "name": "which-electron",
  "version": "1.1.5",
  "description": "Guess which electron version is bundled in an application",
  "main": "src/index.js",
  "bin": {
    "which-electron": "src/index.js"
  },

  "scripts": {
    "test": "kuta tests/*.js",
    "test": "uvu tests",
    "release": "npm update && php _scripts/gen_versions.php && git add src/versions.json package-lock.json && git commit -m 'new release' && npm version patch"
  },

  "type": "module",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/captn3m0/which-electron.git"
  },

  "engines": {
    "node": " >=14.13.1 || >=16.0.0"
  },

  "keywords": [
    "find",
    "electron",
@@ -29,7 +32,9 @@
  "homepage": "https://github.com/captn3m0/which-electron#readme",
  "dependencies": {
    "7zip-bin": "^5.1.1",
    "disassembler": "^0.3.0-beta",
    "electron-fingerprints": "*",
    "elfinfo": "^0.3.0-beta",
    "hasha": "^5.2.2",
    "is-valid-http-url": "^1.0.3",
    "node-7z": "^3.0.0",
@@ -38,7 +43,9 @@
    "semver": "^7.3.5",
    "which": "^2.0.2"
  },

  "exports": "./src/index.js",
  "devDependencies": {
    "kuta": "*"
    "kuta": "*",
    "uvu": "^0.5.3"
  }

}

diff --git a/src/archive.js b/src/archive.js
index 7309cac..5f1d564 100644
--- a/src/archive.js
+++ a/src/archive.js
@@ -1,50 +1,50 @@
const Seven = require("node-7z");
const which = require('which');
const path = require("path");
const fs = require("fs");
import { list, extract } from "node-7z";
import which from "which";
import path from "path";
import fs from "fs";

let sevenBin = null;

try {
  sevenBin = which.sync('7z')
} catch(e) {
  sevenBin = require('7zip-bin').path7za
  console.error("Couldn't find 7-zip installed. Using the 7zip-bin package, which uses an older version of 7-zip. Not all files may work properly.")
  sevenBin = which.sync("7z");
} catch (e) {
  import { path7za } from "7zip-bin";
  console.error(
    "Couldn't find 7-zip installed. Using the 7zip-bin package, which uses an older version of 7-zip. Not all files may work properly."
  );
}

module.exports = {
  readFileContents: function(archive, filepath, dir, cb) {
    let stream = Seven.extract(archive, dir, {
      recursive: true,
      $cherryPick: filepath,
      $bin: sevenBin
    });
    let fn = path.basename(filepath);
    stream.on("end", ()=>{
      cb(fs.readFileSync(`${dir}/${fn}`, {encoding: 'utf8'}))
    });
  },
  extractSomeFiles: function(archive, list, dir, cb) {
    let stream = Seven.extract(archive, dir, {
      $cherryPick: list,
      $bin: sevenBin
    })
    stream.on('end', ()=>{
      cb()
    })
  },
  listFileContents: function(archive, cb) {
    let zip = Seven.list(archive, {
      $bin: sevenBin,
      alternateStreamExtract: true,
      alternateStreamReplace: true,
    });
    let entries = [];
    zip.on("data", (data) => {
      entries.push(data);
    });
    zip.on("end", () => {
      cb(entries);
    });
  },
};
export function readFileContents(archive, filepath, dir, cb) {
  let stream = extract(archive, dir, {
    recursive: true,
    $cherryPick: filepath,
    $bin: sevenBin,
  });
  let fn = path.basename(filepath);
  stream.on("end", () => {
    cb(fs.readFileSync(`${dir}/${fn}`, { encoding: "utf8" }));
  });
}
export function extractSomeFiles(archive, list, dir, cb) {
  let stream = extract(archive, dir, {
    $cherryPick: list,
    $bin: sevenBin,
  });
  stream.on("end", () => {
    cb();
  });
}
export function listFileContents(archive, cb) {
  let zip = list(archive, {
    $bin: sevenBin,
    alternateStreamExtract: true,
    alternateStreamReplace: true,
  });
  let entries = [];
  zip.on("data", (data) => {
    entries.push(data);
  });
  zip.on("end", () => {
    cb(entries);
  });
}
diff --git a/src/elf.js b/src/elf.js
new file mode 100644
index 0000000..4163de0 100644
--- /dev/null
+++ a/src/elf.js
@@ -1,0 +1,35 @@
import elfinfo from "elfinfo";
import fs from "fs";

// Parse the specified ELF file.
export function getVersion(path, cb) {
  const elfdata = fs.readFileSync(path);
  let info = null;
  elfinfo.open(elfdata).then((info) => {
    let rodata = info.elf.sections.filter((x) => {
      return x.name == ".rodata";
    })[0];

    const data = fs.createReadStream(path, {
      start: Number(rodata.addr),
      end: Number(rodata.addr) + rodata.size,
      highWaterMark: rodata.addralign,
    });

    let ret = false;

    data.on("data", function (data) {
      let found = data.toString().match(/Electron\/(\d+\.\d+\.\d+)/);
      if (found) {
        ret = true;
        cb(found[1]);
      }
    });

    data.on("end", function (e) {
      if (!ret) {
        cb(false);
      }
    });
  });
}
diff --git a/src/finder.js b/src/finder.js
index ff3d552..8a14bf0 100644
--- a/src/finder.js
+++ a/src/finder.js
@@ -1,56 +1,62 @@
// finds specific files from a list
const path = require("path");
const isDirectory = require('./utils').isDirectory;
import path from "path";
import { isDirectory } from "./utils.js";

module.exports = {
  // Finds the electron asar file, if we can
  asar: function(entries) {
    return entries
      .filter((e) => {
        return (
          isDirectory(e.attributes) == false &&
          path.basename(e.file) == "electron.asar"
        );
      })
      .map((e) => e.file);
  },
  binary: function(entries) {
    entries = entries.sort((a, b) => b.size - a.size);
    for (const entry of entries) {
      if (isDirectory(entry.attributes)) {
        continue;
      }
      let ext = path.extname(entry.file);
      let size = entry.size;
      // Return the first exe file
      if (ext == ".exe") {
        return entry.file;
      } else if (ext == "") {
        // or the largest file with no extension
        return entry.file;
      }
// Finds the electron asar file, if we can
export function asar(entries) {
  return entries
    .filter((e) => {
      return (
        isDirectory(e.attributes) == false &&
        path.basename(e.file) == "electron.asar"
      );
    })
    .map((e) => e.file);
}

export function binaries(entries) {
  entries = entries.sort((a, b) => b.size - a.size);
  for (const entry of entries) {
    if (isDirectory(entry.attributes)) {
      continue;
    }
    let ext = path.extname(entry.file);
    let size = entry.size;
    // Return the first exe file
    if (ext == ".exe") {
      return [entry.file];
    } else if (ext == "") {
      // or the largest file with no extension
      return [entry.file];
    }
  },
  }
}

  version: function(entries) {
    return entries
      .filter((e) => {
        return isDirectory(e.attributes) == false && path.basename(e.file) == "version";
      })
      .map((e) => e.file);
  },
export function version(entries) {
  return entries
    .filter((e) => {
      return (
        isDirectory(e.attributes) == false && path.basename(e.file) == "version"
      );
    })
    .map((e) => e.file);
}

  findElectronPackageInsideNodeModules: function(entries) {
    return entries
      .filter((e) => {
        return isDirectory(e.attributes) == false && e.file.match(/node_modules\/electron\/package\.json$/);
      })
      .map((e) => e.file);
  },
export function findElectronPackageInsideNodeModules(entries) {
  return entries
    .filter((e) => {
      return (
        isDirectory(e.attributes) == false &&
        e.file.match(/node_modules\/electron\/package\.json$/)
      );
    })
    .map((e) => e.file);
}

  // Return a list of files that might be worth fingerprinting
  fingerprintable: function(entries) {
    return entries.filter((e) =>{
// Return a list of files that might be worth fingerprinting
export function fingerprintable(entries) {
  return entries
    .filter((e) => {
      if (isDirectory(e.attributes)) {
        return false;
      }
@@ -58,17 +64,29 @@
        return false;
      }
      let ext = path.extname(e.file);
      if (['.h', '.dll', '.bin', '.asar', '.dylib', '.so', '.exe'].indexOf(ext) !== -1) {
        return true
      if (
        [".h", ".dll", ".bin", ".asar", ".dylib", ".so", ".exe"].indexOf(
          ext
        ) !== -1
      ) {
        return true;
      }
      let b = path.basename(e.file);

      if (['electron framework', 'squirrel', 'electron', 'electron helper', 'chrome_100_percent', 'chrome_200_percent'].indexOf(b)!== -1) {
      if (
        [
          "electron framework",
          "squirrel",
          "electron",
          "electron helper",
          "chrome_100_percent",
          "chrome_200_percent",
        ].indexOf(b) !== -1
      ) {
        return true;
      }

      return false;
    })
    .map((e)=>e.file)
  }
};
    .map((e) => e.file);
}
diff --git a/src/fingerprint.js b/src/fingerprint.js
index 8433570..fc16162 100644
--- a/src/fingerprint.js
+++ a/src/fingerprint.js
@@ -1,54 +1,52 @@
const DB = require("electron-fingerprints");
const fs = require("fs");
const hasha = require("hasha");
const allVersions = require("./versions")["all"];
import DB from "electron-fingerprints";
import fs from "fs";
import hasha from "hasha";
import crypto from "crypto";

function checksumFile(algorithm, path) {
  return new Promise(function(resolve, reject) {
    let fs = require("fs");
    let crypto = require("crypto");
import V from "./versions.json" assert { type: "json" };
const allVersions = V["all"];

function checksumFile(algorithm, path) {
  return new Promise(function (resolve, reject) {
    let hash = crypto.createHash(algorithm).setEncoding("hex");
    fs.createReadStream(path)
      .once("error", reject)
      .pipe(hash)
      .once("finish", function() {
      .once("finish", function () {
        resolve(hash.read());
      });
  });
}

module.exports = {
  guessFromHashes: function(os, arch, hashList) {
    let lookupTable = DB[`${os}-${arch}`];
    let allPossibleHashes = Object.keys(lookupTable);
    const intersectingHashes = allPossibleHashes.filter((value) =>
      hashList.includes(value)
    );
    // Set it to the starting list of versions.
    let possibleVersions = allVersions;
    for (i in hashList) {
      let hash = hashList[i];
      let versions = lookupTable[hash];
      if (versions) {
        possibleVersions = possibleVersions.filter((value) =>
          versions.includes(value)
        );
      }
export function guessFromHashes(os, arch, hashList) {
  let lookupTable = DB[`${os}-${arch}`];
  let allPossibleHashes = Object.keys(lookupTable);
  const intersectingHashes = allPossibleHashes.filter((value) =>
    hashList.includes(value)
  );
  // Set it to the starting list of versions.
  let possibleVersions = allVersions;
  for (i in hashList) {
    let hash = hashList[i];
    let versions = lookupTable[hash];
    if (versions) {
      possibleVersions = possibleVersions.filter((value) =>
        versions.includes(value)
      );
    }
  }

    if (possibleVersions == allVersions) {
      return [];
    } else {
      return possibleVersions;
    }
  },
  if (possibleVersions == allVersions) {
    return [];
  } else {
    return possibleVersions;
  }
}

  getHashes: function(dir) {
    let list = fs.readdirSync(dir);
    return list.map((f) => {
      let fn = `${dir}/${f}`;
      return hasha.fromFileSync(fn, { algorithm: "sha1" });
    });
  },
};
export function getHashes(dir) {
  let list = fs.readdirSync(dir);
  return list.map((f) => {
    let fn = `${dir}/${f}`;
    return hasha.fromFileSync(fn, { algorithm: "sha1" });
  });
}
diff --git a/src/index.js b/src/index.js
index c10bf65..71c6215 100644
--- a/src/index.js
+++ a/src/index.js
@@ -1,56 +1,61 @@
const osguess = require("./os");
const finder = require("./finder");
const archive = require("./archive");
const fp = require("./fingerprint");
const V = require("./version");
const elf = require("./elf");
const magic = require("file-identity");

const isUrl = require("is-valid-http-url");
const cleanup = require("rimraf");
const dl = require('nodejs-file-downloader')
const dl = require("nodejs-file-downloader");

const path = require("path");
const fs = require('fs');
const os = require('os');
const process = require('process');
const TMPDIR = path.join(os.tmpdir(), 'which-electron')
const fs = require("fs");
const os = require("os");
const process = require("process");
const TMPDIR = path.join(os.tmpdir(), "which-electron");

// Input file comes from process.argv[2]
let FILENAME = process.argv[2];

if (!FILENAME) {
  console.error("Please pass a valid URL or file as the first argument");
  process.exit(1)
  process.exit(1);
}

if(isUrl(FILENAME)) {
if (isUrl(FILENAME)) {
  let url = FILENAME;
  // Download to temporary directory
  let tmpdir = fs.mkdtempSync(TMPDIR);
  let fn = `${tmpdir}/${path.basename(url)}`;
  const downloader = new dl({
    url: url,
    directory: tmpdir,//This folder will be created, if it doesn't exist.
  })
  downloader.download().then(()=> {
    console.log(`Downloaded ${url}`)
    validateFile(fn)
  }).catch((e)=> {
    console.error(`Error while downloading ${url}`)
    console.error(e)
    process.exit(1)
  })
    directory: tmpdir, //This folder will be created, if it doesn't exist.
  });
  downloader
    .download()
    .then(() => {
      console.log(`Downloaded ${url}`);
      validateFile(fn);
    })
    .catch((e) => {
      console.error(`Error while downloading ${url}`);
      console.error(e);
      process.exit(1);
    });
} else {
  validateFile(FILENAME)
  validateFile(FILENAME);
}

function validateFile(fn) {
  fs.access(fn, fs.constants.R_OK, (err) => {
    if (err) {
      console.error(`${fn} not readable`)
      console.error(`${fn} not readable`);
      process.exit(1);
    } else {
      console.log(fn);
      whichElectron(fn)
      whichElectron(fn);
    }
  });
}
@@ -63,47 +68,63 @@
  }
}

let whichElectron = function(filename) {
let whichElectron = function (filename) {
  archive.listFileContents(filename, (entries) => {
    let osguess1 = osguess.guessFromFilename(filename);
    let osguess2 = osguess.guessFromContents(entries);

    if (osguess1 !== osguess2 && osguess1 && osguess2) {
      console.log(`Unsure about operating system. Going with ${osguess2}. Other option was ${osguess1}`);
      console.log(
        `Unsure about operating system. Going with ${osguess2}. Other option was ${osguess1}`
      );
    }
    if (osguess1 && !osguess2) {
      osguess2 = osguess1
      osguess2 = osguess1;
    }
    let arch = osguess.guessArch(filename, entries);
    let asar = finder.asar(entries);
    let binary = finder.binary(entries);
    let binaries = finder.binaries(entries);
    let versionFiles = finder.version(entries);
    let enm = finder.findElectronPackageInsideNodeModules(entries);

    let filesToHash = finder.fingerprintable(entries);

    archive.extractSomeFiles(filename, filesToHash, TMPDIR, () => {
      hashes = fp.getHashes(TMPDIR);
      guesses = fp.guessFromHashes(osguess2, arch, hashes);
      if (guesses.length == 1) {
        console.log("Fingerprint: " + guesses[0]);
        logSupport(guesses[0])
      } else if (guesses.length > 1) {
        console.log("Fingerprint: " + V.asText(guesses));
        logSupport(V.max(guesses))
      }
    archive.extractSomeFiles(
      filename,
      filesToHash.concat(binaries),
      TMPDIR,
      () => {
        hashes = fp.getHashes(TMPDIR);
        guesses = fp.guessFromHashes(osguess2, arch, hashes);
        if (guesses.length == 1) {
          console.log("Fingerprint: " + guesses[0]);
          logSupport(guesses[0]);
        } else if (guesses.length > 1) {
          console.log("Fingerprint: " + V.asText(guesses));
          logSupport(V.max(guesses));
        }

      cleanup.sync(TMPDIR);
    });
        if (binaries.length > 0) {
          for (i in binaries) {
            let binary = binaries[i];
            let type = magic.fromFile(`${TMPDIR}/${binary}`);
            if (type) {
              console.log(type);
            } else {
              console.log(fs.existsSync(`${TMPDIR}/${binary}`));
            }
          }
        }

        cleanup.sync(TMPDIR);
      }
    );

    // if (binary) {
    //   console.log(`${process.argv[2]}:${binary}`);
    // }
    if (versionFiles.length > 0) {
      versionFiles.map((f) => {
        archive.readFileContents(filename, f, TMPDIR, (c) => {
          console.log("Found Version file: " + c);
          logSupport(`${c}`)
          logSupport(`${c}`);
        });
      });
    }
@@ -120,7 +141,7 @@
            console.log(
              "Found version in package.json file: " + packageData["version"]
            );
            logSupport(`v${packageData["version"]}`)
            logSupport(`v${packageData["version"]}`);
          } catch (e) {
            // TODO: Do something
          }
@@ -128,6 +149,4 @@
      });
    }
  });
}


};
diff --git a/src/os.js b/src/os.js
index 52919b9..e900273 100644
--- a/src/os.js
+++ a/src/os.js
@@ -1,43 +1,44 @@
// Guess the OS
import path from 'path'

const path = require('path')

module.exports = {
	guessFromFilename(inputFile) {
		let fn = path.basename(inputFile)
		if (fn.match(/linux/)) {
			return 'linux'
		} else if (fn.match(/mac/)) {
			return 'darwin'
    } else if (fn.match(/darwin/)) {
      return 'darwin'
		} else if (fn.match(/win/)) {
			return 'win32'
		} else {
			let ext = path.extname(inputFile).toLowerCase()
      if (ext == '.dmg') {return 'darwin'}
      if (ext == '.exe') {return 'win32'}
      if (['.deb', '.appimage', '.pacman'].indexOf(ext) !== -1) {
        return 'linux'
      }
		}
		return null;
	},
  guessArch(filename, entries) {
    return 'x64';
  },
	guessFromContents(entries) {
		for (i in entries) {
      let entry = entries[i]
			if (path.extname(entry.file) == ".so") {
				return 'linux'
			} else if (path.extname(entry.file) == '.dll') {
				return 'win32'
			} else if (path.extname(entry.file) == '.dylib') {
				return 'darwin'
			} else if (path.extname(entry.file) == '.plist') {
				return 'darwin'
			}
		}
	}
export function guessFromFilename(inputFile) {
  let fn = path.basename(inputFile);
  if (fn.match(/linux/)) {
    return "linux";
  } else if (fn.match(/mac/)) {
    return "darwin";
  } else if (fn.match(/darwin/)) {
    return "darwin";
  } else if (fn.match(/win/)) {
    return "win32";
  } else {
    let ext = path.extname(inputFile).toLowerCase();
    if (ext == ".dmg") {
      return "darwin";
    }
    if (ext == ".exe") {
      return "win32";
    }
    if ([".deb", ".appimage", ".pacman"].indexOf(ext) !== -1) {
      return "linux";
    }
  }
  return null;
}
export function guessArch(filename, entries) {
  return "x64";
}
export function guessFromContents(entries) {
  for (let i in entries) {
    let entry = entries[i];
    if (path.extname(entry.file) == ".so") {
      return "linux";
    } else if (path.extname(entry.file) == ".dll") {
      return "win32";
    } else if (path.extname(entry.file) == ".dylib") {
      return "darwin";
    } else if (path.extname(entry.file) == ".plist") {
      return "darwin";
    }
  }
}
diff --git a/src/utils.js b/src/utils.js
index c74d212..412fdaa 100644
--- a/src/utils.js
+++ a/src/utils.js
@@ -1,5 +1,3 @@
module.exports = {
  isDirectory: function(a) {
     return (a? a[0] == "D" : null)
  },
};
export function isDirectory(a) {
  return a ? a[0] == "D" : null;
}
diff --git a/src/version.js b/src/version.js
index 85c27b0..b6aa788 100644
--- a/src/version.js
+++ a/src/version.js
@@ -1,18 +1,15 @@
const semver = require("semver");
const VERSIONS = require("./versions");
import semver from "semver";
import VERSIONS from "./versions.json" assert { type: "json" };

module.exports = {
  asText: function (listOfVersions) {
    sorted = listOfVersions.sort(semver.compare);
    return `${sorted[0]}-${sorted[sorted.length - 1]}`;
  },
export function asText(listOfVersions) {
  sorted = listOfVersions.sort(semver.compare);
  return `${sorted[0]}-${sorted[sorted.length - 1]}`;
}

  max: function (listOfVersions) {
    sorted = listOfVersions.sort(semver.compare);
    return sorted[sorted.length - 1];
  },

  isSupported: function (v) {
    return VERSIONS["supported"].indexOf(v) !== -1;
  },
};
export function max(listOfVersions) {
  sorted = listOfVersions.sort(semver.compare);
  return sorted[sorted.length - 1];
}
export function isSupported(v) {
  return VERSIONS["supported"].indexOf(v) !== -1;
}
diff --git a/src/versions.json b/src/versions.json
index ab417bd..78f0fe8 100644
--- a/src/versions.json
+++ a/src/versions.json
@@ -1,9 +1,9 @@
{
    "supported": [
        "v15.5.0",
        "v16.2.0",
        "v17.3.0",
        "v18.0.0"
        "v15.5.2",
        "v16.2.2",
        "v17.4.0",
        "v18.0.4"
    ],

    "all": [
        "v0.24.0",
@@ -495,6 +495,7 @@
        "v14.2.6",
        "v14.2.7",
        "v14.2.8",
        "v14.2.9",
        "v15.0.0",
        "v15.1.0",
        "v15.1.1",
@@ -512,6 +513,8 @@
        "v15.4.1",
        "v15.4.2",
        "v15.5.0",
        "v15.5.1",
        "v15.5.2",
        "v16.0.0",
        "v16.0.1",
        "v16.0.2",
@@ -526,6 +529,8 @@
        "v16.1.0",
        "v16.1.1",
        "v16.2.0",
        "v16.2.1",
        "v16.2.2",
        "v17.0.0",
        "v17.0.1",
        "v17.1.0",
@@ -533,6 +538,12 @@
        "v17.1.2",
        "v17.2.0",
        "v17.3.0",
        "v18.0.0"
        "v17.3.1",
        "v17.4.0",
        "v18.0.0",
        "v18.0.1",
        "v18.0.2",
        "v18.0.3",
        "v18.0.4"
    ]

}
diff --git a/tests/finder.js b/tests/finder.js
index 7b9e03f..8e99ea1 100644
--- a/tests/finder.js
+++ a/tests/finder.js
@@ -1,50 +1,50 @@
const test = require("kuta").test;
const finder = require("../src/finder");
const assert = require("assert");
const _ = require("./utils");
import * as finder from "../src/finder.js";
import { test } from "uvu";
import * as assert from "uvu/assert";
import { getEntries } from "./utils.js";

test("it should find the electron.asar file", () => {
  assert.deepEqual(
  assert.equal(
    ["Hyper.app/Contents/Resources/electron.asar"],
    finder.asar(_.getEntries("Hyper-3.0.2-mac.zip"))
    finder.asar(getEntries("Hyper-3.0.2-mac.zip"))
  );
});

test("it should find the correct binary file", () => {
  assert.deepEqual(
  assert.equal(
    "Hyper.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework",
    finder.binary(_.getEntries("Hyper-3.0.2-mac.zip"))
    finder.binary(getEntries("Hyper-3.0.2-mac.zip"))
  );
  assert.deepEqual(
  assert.equal(
    "Notable.exe",
    finder.binary(_.getEntries("Notable-1.8.4-win.zip"))
    finder.binary(getEntries("Notable-1.8.4-win.zip"))
  );
  assert.deepEqual(
  assert.equal(
    "rambox",
    finder.binary(_.getEntries("Rambox-0.7.7-linux-x64.zip"))
    finder.binary(getEntries("Rambox-0.7.7-linux-x64.zip"))
  );
});

test("it should find the version file", () => {
  assert.deepEqual(
  assert.equal(
    ["chronobreak-linux-x64/version"],
    finder.version(_.getEntries("chronobreak-linux-x64.zip"))
    finder.version(getEntries("chronobreak-linux-x64.zip"))
  );
  assert.deepEqual(
  assert.equal(
    ["release-builds/encrypt0r-darwin-x64/version"],
    finder.version(_.getEntries("encrypt0r-mac.zip"))
    finder.version(getEntries("encrypt0r-mac.zip"))
  );
  assert.deepEqual(
  assert.equal(
    [
      "Arizona v.1.0.0/resources/app/node_modules/electron/dist/version",
      "Arizona v.1.0.0/version",
    ],
    finder.version(_.getEntries("Arizona-v1.0.0-beta-Windows.zip"))
    finder.version(getEntries("Arizona-v1.0.0-beta-Windows.zip"))
  );
});

test("it should find fingerprinteable files", () => {
  assert.deepEqual(
  assert.equal(
    [
      "Arizona v.1.0.0/Arizona.exe",
      "Arizona v.1.0.0/d3dcompiler_47.dll",
@@ -74,9 +74,9 @@
      "Arizona v.1.0.0/vk_swiftshader.dll",
      "Arizona v.1.0.0/vulkan-1.dll",
    ],
    finder.fingerprintable(_.getEntries("Arizona-v1.0.0-beta-Windows.zip"))
    finder.fingerprintable(getEntries("Arizona-v1.0.0-beta-Windows.zip"))
  );
  assert.deepEqual(
  assert.equal(
    [
      "Lax-win32-x64/v8_context_snapshot.bin",
      "Lax-win32-x64/d3dcompiler_47.dll",
@@ -89,10 +89,10 @@
      "Lax-win32-x64/swiftshader/libEGL.dll",
      "Lax-win32-x64/swiftshader/libGLESv2.dll",
    ],
    finder.fingerprintable(_.getEntries("Lax-win32-x64.zip"))
    finder.fingerprintable(getEntries("Lax-win32-x64.zip"))
  );

  assert.deepEqual(
  assert.equal(
    [
      "resources/app.asar",
      "swiftshader/libvk_swiftshader.so",
@@ -105,10 +105,10 @@
      "libEGL.so",
      "natives_blob.bin",
    ],
    finder.fingerprintable(_.getEntries("Rambox-0.7.7-linux-x64.zip"))
    finder.fingerprintable(getEntries("Rambox-0.7.7-linux-x64.zip"))
  );

  assert.deepEqual(
  assert.equal(
    [
      "chronobreak-linux-x64/libEGL.so",
      "chronobreak-linux-x64/libffmpeg.so",
@@ -121,10 +121,10 @@
      "chronobreak-linux-x64/swiftshader/libGLESv2.so",
      "chronobreak-linux-x64/v8_context_snapshot.bin",
    ],
    finder.fingerprintable(_.getEntries("chronobreak-linux-x64.zip"))
    finder.fingerprintable(getEntries("chronobreak-linux-x64.zip"))
  );

  assert.deepEqual(
  assert.equal(
    [
      "Hyper.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libnode.dylib",
      "Hyper.app/Contents/Resources/app.asar",
@@ -203,10 +203,10 @@
      "Hyper.app/Contents/Frameworks/ReactiveCocoa.framework/Versions/A/Headers/RACUnit.h",
      "Hyper.app/Contents/Frameworks/ReactiveCocoa.framework/Versions/A/Headers/NSFileHandle+RACSupport.h",
    ],
    finder.fingerprintable(_.getEntries("Hyper-3.0.2-mac.zip"))
    finder.fingerprintable(getEntries("Hyper-3.0.2-mac.zip"))
  );

  assert.deepEqual(
  assert.equal(
    [
      "Notable.exe",
      "libGLESv2.dll",
@@ -220,10 +220,10 @@
      "libEGL.dll",
      "natives_blob.bin",
    ],
    finder.fingerprintable(_.getEntries("Notable-1.8.4-win.zip"))
    finder.fingerprintable(getEntries("Notable-1.8.4-win.zip"))
  );

  assert.deepEqual(
  assert.equal(
    [
      "release-builds/encrypt0r-darwin-x64/encrypt0r.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib",
      "release-builds/encrypt0r-darwin-x64/encrypt0r.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib",
@@ -247,6 +247,8 @@
      "release-builds/encrypt0r-darwin-x64/encrypt0r.app/Contents/Frameworks/Electron Framework.framework/Libraries/libswiftshader_libEGL.dylib",
      "release-builds/encrypt0r-darwin-x64/encrypt0r.app/Contents/Frameworks/Electron Framework.framework/Resources/v8_context_snapshot.x86_64.bin",
    ],
    finder.fingerprintable(_.getEntries("encrypt0r-mac.zip"))
    finder.fingerprintable(getEntries("encrypt0r-mac.zip"))
  );
});

test.run();
diff --git a/tests/fingerprint.js b/tests/fingerprint.js
index 9aa9d08..18257fd 100644
--- a/tests/fingerprint.js
+++ a/tests/fingerprint.js
@@ -1,19 +1,19 @@
const test = require("kuta").test;
const fp = require("../src/fingerprint");
const assert = require("assert");
import { test } from "uvu";
import * as assert from "uvu/assert";
import { guessFromHashes, getHashes } from "../src/fingerprint.js";

test("it should work with a single fingerprint", () => {
  guess = fp.guessFromHashes("win32", "x64", [
  guess = guessFromHashes("win32", "x64", [
    "cbdbe566564c323032c02c1a838358a314af63b4",
  ]);
  assert.deepEqual(guess, ["v0.24.0"]);
  assert.equal(guess, ["v0.24.0"]);
});

test("it should work with a ffmpeg hash", () => {
  guess = fp.guessFromHashes("win32", "x64", [
  guess = guessFromHashes("win32", "x64", [
    "baf786083f482c1f035e50e105b5f7475af1e00b",
  ]);
  assert.deepEqual(guess, ["v1.4.3", "v1.4.4", "v1.4.5"]);
  assert.equal(guess, ["v1.4.3", "v1.4.4", "v1.4.5"]);
});

test("it should work with multiple fingerprints", () => {
@@ -22,6 +22,8 @@
    "944bff8704d4b152279fbdacb911b516502be056",
    "3c592e2cdadbb0bcd8f522071a63da5febe9aa37",
  ];
  guess = fp.guessFromHashes("darwin", "x64", hashes);
  assert.deepEqual(guess, ["v1.7.6"]);
  guess = guessFromHashes("darwin", "x64", hashes);
  assert.equal(guess, ["v1.7.6"]);
});

test.run();
diff --git a/tests/os.js b/tests/os.js
index 839bf11..ee016fa 100644
--- a/tests/os.js
+++ a/tests/os.js
@@ -1,37 +1,75 @@
const test = require('kuta').test;
const os = require('../src/os')
const assert = require('assert')
const _ = require('./utils')
import { test } from "uvu";
import * as assert from "uvu/assert";

test('it should linux correctly from filename', ()=> {
  assert.deepEqual('linux', os.guessFromFilename('kube-dev-dashboard-0.10.1-linux.zip'))
  assert.deepEqual('linux', os.guessFromFilename('magiccap-linux.zip'))
  assert.deepEqual('linux', os.guessFromFilename('Rambox-0.7.7-linux-ia32.zip'))
  assert.deepEqual('linux', os.guessFromFilename('authme-2.6.0-linux-x64-portable.zip'))
  assert.deepEqual('linux', os.guessFromFilename('mojibar-linux.zip'))
  assert.deepEqual('linux', os.guessFromFilename('mojibar-linux.deb'))
  assert.deepEqual('linux', os.guessFromFilename('mojibar.AppImage'))
  assert.deepEqual('linux', os.guessFromFilename('mojibar.pacman'))
import { guessFromFilename, guessFromContents } from "../src/os.js";
import { getEntries } from "./utils.js";

test("it should linux correctly from filename", () => {
  assert.equal(
    "linux",
    guessFromFilename("kube-dev-dashboard-0.10.1-linux.zip")
  );
  assert.equal("linux", guessFromFilename("magiccap-linux.zip"));
  assert.equal("linux", guessFromFilename("Rambox-0.7.7-linux-ia32.zip"));
  assert.equal(
    "linux",
    guessFromFilename("authme-2.6.0-linux-x64-portable.zip")
  );
  assert.equal("linux", guessFromFilename("mojibar-linux.zip"));
  assert.equal("linux", guessFromFilename("mojibar-linux.deb"));
  assert.equal("linux", guessFromFilename("mojibar.AppImage"));
  assert.equal("linux", guessFromFilename("mojibar.pacman"));
});

test('it should darwin correctly from filename', ()=> {
  assert.deepEqual('darwin', os.guessFromFilename('Merge-Request-Notifier-1.9.0-mac.zip'))
  assert.deepEqual('darwin', os.guessFromFilename('Merge-Request-Notifier-1.9.0.dmg'))
test("it should darwin correctly from filename", () => {
  assert.equal(
    "darwin",
    guessFromFilename("Merge-Request-Notifier-1.9.0-mac.zip")
  );
  assert.equal(
    "darwin",
    guessFromFilename("Merge-Request-Notifier-1.9.0.dmg")
  );
});

test('it should windows correctly from filename', ()=> {
  assert.deepEqual('win32', os.guessFromFilename('particl-desktop-2.3.6-win-ia32.zip'))
  assert.deepEqual('win32', os.guessFromFilename('Multrin-1.3.0-ia32-win.zip'))
  assert.deepEqual('win32', os.guessFromFilename('Multrin-1.3.0-ia32-win.exe'))
  assert.deepEqual('win32', os.guessFromFilename('Assessment.Disaggregation-1.1.4.Setup.exe'))
test("it should windows correctly from filename", () => {
  assert.equal(
    "win32",
    guessFromFilename("particl-desktop-2.3.6-win-ia32.zip")
  );
  assert.equal("win32", guessFromFilename("Multrin-1.3.0-ia32-win.zip"));
  assert.equal("win32", guessFromFilename("Multrin-1.3.0-ia32-win.exe"));
  assert.equal(
    "win32",
    guessFromFilename("Assessment.Disaggregation-1.1.4.Setup.exe")
  );
});

test('it should guess correctly from file list', ()=> {
  assert.deepEqual('win32', os.guessFromContents(_.getEntries('Arizona-v1.0.0-beta-Windows.zip')));
  assert.deepEqual('win32', os.guessFromContents(_.getEntries('Notable-1.8.4-win.zip')));
  assert.deepEqual('darwin', os.guessFromContents(_.getEntries('encrypt0r-mac.zip')));
  assert.deepEqual('darwin', os.guessFromContents(_.getEntries('Hyper-3.0.2-mac.zip')));
  assert.deepEqual('linux', os.guessFromContents(_.getEntries('chronobreak-linux-x64.zip')));
  assert.deepEqual('linux', os.guessFromContents(_.getEntries('Rambox-0.7.7-linux-x64.zip')));
test("it should guess correctly from file list", () => {
  assert.equal(
    "win32",
    guessFromContents(getEntries("Arizona-v1.0.0-beta-Windows.zip"))
  );
  assert.equal(
    "win32",
    guessFromContents(getEntries("Notable-1.8.4-win.zip"))
  );
  assert.equal(
    "darwin",
    guessFromContents(getEntries("encrypt0r-mac.zip"))
  );
  assert.equal(
    "darwin",
    guessFromContents(getEntries("Hyper-3.0.2-mac.zip"))
  );
  assert.equal(
    "linux",
    guessFromContents(getEntries("chronobreak-linux-x64.zip"))
  );
  assert.equal(
    "linux",
    guessFromContents(getEntries("Rambox-0.7.7-linux-x64.zip"))
  );
});

test.run();
diff --git a/tests/utils.js b/tests/utils.js
index ad93687..39a958c 100644
--- a/tests/utils.js
+++ a/tests/utils.js
@@ -1,14 +1,12 @@
const fs = require("fs");
entries = {};
import fs from "fs";
let entries = {};

module.exports = {
  getEntries: function(f) {
    if (entries[f]) {
      return entries[f];
    } else {
      return (entries[f] = JSON.parse(
        fs.readFileSync(`./tests/fixtures/${f}.json`)
      ));
    }
  },
};
export function getEntries(f) {
  if (entries[f]) {
    return entries[f];
  } else {
    return (entries[f] = JSON.parse(
      fs.readFileSync(`./tests/fixtures/${f}.json`)
    ));
  }
}