Compare commits

...

45 Commits
v1.0.0 ... main

Author SHA1 Message Date
dependabot[bot] 30022412d0 Bump follow-redirects from 1.14.9 to 1.15.4
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.9 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.9...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 06:34:13 +00:00
dependabot[bot] df975be2a6 Bump semver from 7.3.5 to 7.5.2
Bumps [semver](https://github.com/npm/node-semver) from 7.3.5 to 7.5.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.3.5...v7.5.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-29 22:13:04 +05:30
Nemo a62e51bd2c
Create FUNDING.yml 2022-05-27 07:19:39 +00:00
Nemo b7a3ada2ef [releases] New electron releases 2022-05-24 15:10:23 +05:30
Nemo 65049c9ed2 1.1.5 2022-03-29 17:19:32 +05:30
Nemo 57eea488b2 Updates 2022-03-29 17:19:32 +05:30
Nemo 0f397fa8e0 v14 is no longer supported 2022-03-29 17:19:18 +05:30
dependabot[bot] d53399dd79 Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 15:56:00 +05:30
Nemo e7c9593183
Create dependabot.yml 2022-03-29 14:10:44 +05:30
Nemo aa282edd38 1.1.4 2022-03-11 11:13:01 +05:30
Nemo 3e83cf07cc Updates 2022-03-11 11:13:01 +05:30
Nemo 12f5162864 Update ignore files 2022-03-05 14:17:47 +05:30
Nemo 1070fb1842 1.1.3 2022-03-05 14:16:36 +05:30
Nemo 4dccf4e70b Add Makefile 2022-03-05 14:16:21 +05:30
Nemo 467001f5e5 Update supported versions 2022-03-05 14:14:52 +05:30
Nemo bd791b2a86 1.1.2 2022-03-05 14:06:23 +05:30
Nemo 80c18de4fb new releases 2022-03-05 14:06:19 +05:30
Nemo 53c7f93cee 1.1.1 2022-02-21 21:03:55 +05:30
Nemo 145d03ab72 [deps] Update dependencies 2022-02-21 21:03:41 +05:30
Nemo 1931e40778 faster version fetch script 2022-02-02 18:47:50 +05:30
Nemo 351250d2a3 update docs 2022-02-02 18:20:26 +05:30
Nemo 9b6272305f 1.1.0 2022-02-02 18:19:56 +05:30
Nemo 6cfb4f03b3 new electron releases 2022-02-02 18:19:53 +05:30
Nemo 8cc38317e7 1.0.9 2022-01-13 12:31:47 +05:30
Nemo 681c90406c bump electron-fingerprints 2022-01-13 12:31:32 +05:30
Nemo 2f25c0682c Mark Electron v12 as unsupported 2022-01-11 14:24:52 +05:30
Nemo 094730471a 1.0.7 2022-01-04 15:46:13 +05:30
Nemo 2207c3d854 dep update 2022-01-04 15:40:54 +05:30
Nemo ed2efd1d78 1.0.6 2021-12-19 20:58:23 +05:30
Nemo af21e65e20 new release 2021-12-19 20:58:22 +05:30
Nemo 56fac545ce new script for updating supporting packages 2021-12-19 20:57:46 +05:30
Nemo 907c50097d dependency updates 2021-12-19 15:39:43 +05:30
Nemo eea5b31f8c Forgot to update release in package.json 2021-12-04 13:56:36 +05:30
Nemo 2901d7fc64 v1.0.5 2021-12-04 13:55:24 +05:30
Nemo cac618013f v1.0.4 2021-11-24 15:07:42 +05:30
Nemo 9b26d7ce3d Stop using semver-sort 2021-11-24 15:05:35 +05:30
Nemo 08984ed62b Version Bump 2021-08-09 16:59:01 +05:30
Nemo 45b1e6ffd5 Adds support for downloading and checking files 2021-07-21 18:54:40 +05:30
Nemo b9cfaca8dd Adds CHANGELOG 2021-07-18 17:31:02 +05:30
Nemo 4c3cfedc9c [tests] Run tests on all supported node versions 2021-07-18 17:30:21 +05:30
Nemo 1c72d60761 Re-organize directory structure 2021-07-18 17:26:38 +05:30
Nemo 5ee877fdf3 Upgrade electron-fingerprints 2021-07-18 17:23:36 +05:30
Nemo c2d3b92091 Note more breakage 2021-07-16 22:16:33 +05:30
Nemo c9a445d063 Add badges 2021-07-16 21:49:30 +05:30
Nemo 6f96fcbfc5 [docs] Fingerprints are now used 2021-07-16 21:16:12 +05:30
27 changed files with 1211 additions and 666 deletions

View File

@ -7,3 +7,6 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[Makefile]
indent_style = tab

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
github: captn3m0
ko_fi: captn3m0
liberapay: captn3m0

View File

@ -1,13 +1,16 @@
on: push
name: Main Workflow
jobs:
runNpmStuff:
tests:
strategy:
matrix:
node: ['16', '14', '12']
name: Run NPM Stuff
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v2
with:
node-version: '16'
node-version: ${{matrix.node}}
- run: npm install
- run: npm test

6
.github/workflows/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'daily'

2
.gitignore vendored
View File

@ -1 +1 @@
node_modules
node_modules

View File

@ -3,3 +3,4 @@ tests/
_scripts/
HACKING.md
.github
Makefile

38
CHANGELOG.md Normal file
View File

@ -0,0 +1,38 @@
# Changelog
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 1.1.0
### Changed
- Electron v17 released
- Electron v13 is no longer marked as supported
## 1.0.6
### Changed
- Electron v12 is no longer marked as supported
## 1.0.5
### Changed
- Newer electron releases supported (Upto 16.0.4)
## 1.0.4
### Changed
- Now uses `semver` directly instead of `semver-sort`
### Added
- Newer electron releases supported (upto 16.0.1)
## 1.0.3
### Added
- Newer electron releases supported
## 1.0.2
### Added
- Now supports checking URLs directly.
## 1.0.1
- Support ARM64 builds for Mac/Windows/Linux
- Cleanup directory structure a bit
- Run tests on all node releases

View File

@ -3,3 +3,7 @@
## Generating Fixtures
`node _scripts/gen-fixture.js /path/to/filename.zip`
## Generating versions.json
`php _scripts/gen_versions.php`

8
Makefile Normal file
View File

@ -0,0 +1,8 @@
all:
npm update
php _scripts/gen_versions.php
git commit -am "Updates $(date)"
npm version patch
git push
git push --tags
npm publish

View File

@ -1,6 +1,6 @@
# which-electron ![](https://img.shields.io/badge/Status-WIP-orange)
# which-electron ![](https://img.shields.io/badge/Status-Beta-orange) ![npm](https://img.shields.io/npm/v/which-electron) ![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/npm/which-electron) ![NPM](https://img.shields.io/npm/l/which-electron)
Try to find out which Electron version is bundled inside an application.
Find out which Electron version is bundled inside an application.
## Usage
@ -22,7 +22,11 @@ $ which-electron Appium-linux-1.21.0.AppImage
Fingerprint: v7.2.4-v7.3.3
v7.3.3 is currently not supported
$ which-electron Google.Play.Music.Desktop.Player.deb
$ which-electron https://github.com/stoplightio/studio/releases/download/v2.3.0-stable.5931.git-67616e9/stoplight-studio-mac.dmg
Downloaded https://github.com/stoplightio/studio/releases/download/v2.3.0-stable.5931.git-67616e9/stoplight-studio-mac.dmg
/tmp/which-electronaN3QGg/stoplight-studio-mac.dmg
Fingerprint: v11.0.5-v11.1.1
v11.1.1 is currently not supported
```
## How does it work?
@ -32,10 +36,17 @@ We attempt multiple pathways:
1. The presence of a `electron.asar` file denotes an electron version `<v7.0.0`, since later releases dropped that file and embedded it in the binary instead.
2. A `version` text file is sometimes included in the final binary.
3. The `node_modules/electron/package.json` file is sometimes present.
4. A lookup table of [hashes from various electron releases](https://github.com/captn3m0/electron-fingerprints/) is used to guess the version. (WIP)
4. A lookup table of [hashes from various electron releases](https://github.com/captn3m0/electron-fingerprints/) is used to guess the version. In case of multiple matches, it returns a range of versions.
5. Get the electron version from the electron binary (WIP)
Note that this can be run against untrusted binaries as it does not _try to run the application_.
Note that this can be run against untrusted binaries as it does not _try to run the application_. It has been tested against various file formats: zip/dmg/exe/AppImage/tar.gz etc. It extracts limited files using 7-zip to a temporary directory at runtime if needed.
## Known Issues
It is known to not work against:
1. Windows setup files (ones with `-setup` in their name)
2. On systems without 7-zip installed, it falls back to an older version of 7zip via the 7z-bin package on NPM. Unfortunately, the older version can't extract AppImage files correctly.
## License

67
_scripts/gen_versions.php Normal file
View File

@ -0,0 +1,67 @@
<?php
const VERSION_EXCLUDE = ['nightly', 'beta', 'alpha'];
// The latest four stable major versions are currently supported
// till May 2022, after which only 3 major versions will be supported
const SUPPORTED_MAJOR_VERSIONS = [17, 18, 19];
// Command to fetch the list of versions from upstream
const FETCH_VERSIONS_COMMAND = "git ls-remote -q --tags https://github.com/electron/electron.git |grep -v '\^{}' |cut -f2 | sed -s 's/refs\/tags\///g' ";
function get_versions() {
$versions = [];
foreach(explode("\n", shell_exec(FETCH_VERSIONS_COMMAND)) as $version) {
foreach(VERSION_EXCLUDE as $needle) {
if (stripos($version, $needle) !== false) {
continue 2;
}
}
// Atom shell was renamed to electron in this release (17th April 2015)
if (version_compare($version, 'v0.24.0', '<')) {
continue;
}
$versions[] = $version;
}
return $versions;
}
function get_major_version($version) : int {
$r = explode('.', $version);
return intval($r[0]);
}
function get_supported_versions($versions = []) {
$result = [];
$versions = array_map(function($v) {
return substr($v, 1);
}, $versions);
foreach(SUPPORTED_MAJOR_VERSIONS as $major) {
$result[$major] = '0.0.0';
}
foreach($versions as $version) {
$major = get_major_version($version);
if (in_array($major, SUPPORTED_MAJOR_VERSIONS)) {
if (version_compare($version, $result["$major"], '>')) {
$result["$major"] = "v$version";
}
}
}
return array_values($result);
}
function json_data() {
$versions = get_versions();
usort($versions, 'version_compare');
$supported = get_supported_versions($versions);
return [
'supported' => $supported,
'all' => $versions
];
}
file_put_contents('src/versions.json', json_encode(json_data(), JSON_PRETTY_PRINT));

View File

@ -1,85 +0,0 @@
const path = require("path");
const osguess = require("./os");
const finder = require("./finder");
const zip = require("./zip");
const fp = require("./fingerprint");
const cleanup = require("rimraf");
const V = require("./version");
// Input file comes from process.argv[2]
const FILENAME = process.argv[2];
console.log(FILENAME);
function logSupport(version) {
if (V.isSupported(version)) {
console.log(`${version} is currently supported`);
} else {
console.log(`${version} is currently not supported`);
}
}
zip.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}`);
}
if (osguess1 && !osguess2) {
osguess2 = osguess1
}
let arch = osguess.guessArch(FILENAME, entries);
let asar = finder.asar(entries);
let binary = finder.binary(entries);
let versionFiles = finder.version(entries);
let enm = finder.findElectronPackageInsideNodeModules(entries);
let filesToHash = finder.fingerprintable(entries);
zip.extractSomeFiles(FILENAME, filesToHash, (dir) => {
hashes = fp.getHashes(dir);
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(dir);
});
// if (binary) {
// console.log(`${process.argv[2]}:${binary}`);
// }
if (versionFiles.length > 0) {
versionFiles.map((f) => {
zip.readFileContents(FILENAME, f, (c) => {
console.log("Found Version file: " + c);
logSupport(`${c}`)
});
});
}
if (asar.length > 0) {
asar.forEach((a) => {
console.log("Version Constraint (Unsupported): <v7.0.0");
});
}
if (enm) {
enm.forEach((a) => {
zip.readFileContents(FILENAME, a, (c) => {
try {
let packageData = JSON.parse(c);
console.log(
"Found version in package.json file: " + packageData["version"]
);
logSupport(`v${packageData["version"]}`)
} catch (e) {
// TODO: Do something
}
});
});
}
});

398
package-lock.json generated
View File

@ -1,22 +1,26 @@
{
"name": "which-electron",
"version": "1.0.0",
"version": "1.1.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"name": "which-electron",
"version": "1.1.5",
"license": "MIT",
"dependencies": {
"7zip-bin": "^5.1.1",
"electron-fingerprints": "^1.0.0",
"electron-fingerprints": "*",
"hasha": "^5.2.2",
"is-valid-http-url": "^1.0.3",
"node-7z": "^3.0.0",
"nodejs-file-downloader": "^4.7.1",
"rimraf": "^3.0.2",
"semver-sort": "^0.0.4"
"semver": "^7.3.5",
"which": "^2.0.2"
},
"bin": {
"which-electron": "index.js"
"which-electron": "src/index.js"
},
"devDependencies": {
"kuta": "*"
@ -27,6 +31,17 @@
"resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz",
"integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ=="
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -80,9 +95,9 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
@ -96,9 +111,28 @@
}
},
"node_modules/electron-fingerprints": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-1.0.0.tgz",
"integrity": "sha512-vDW8IBu4tj/ZP/JGa7lcal9/Yc+prokzHfazi0OB/GIMeyUxfGznlK3RVJzGD5XxXgPyy6GEt5xrTNxB8TU/bA=="
"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/follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
@ -106,9 +140,9 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"node_modules/glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -139,6 +173,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"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==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -154,17 +200,33 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/is-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-valid-http-url": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-valid-http-url/-/is-valid-http-url-1.0.3.tgz",
"integrity": "sha512-lrPp25k/Ft3HdusDBdXqne9lNKDtN0HWIHNuC9cfzuFBLlay/gyQeBJukUR1smjyp+zw+gJ5E9wHonpcE9kiCQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"node_modules/kuta": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.6.tgz",
"integrity": "sha512-MbBNzXs7RroFZ7aCG5tYveRCvMws3yoiK6f1dRsOkOlDa1+QRk/kGKukG7WKgcyT6Jw6W66Hc22gp3zKg2ZtPQ==",
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.7.tgz",
"integrity": "sha512-bwthe2BQ//kleJjswnUOo9AwXbknyw6Hk0wzxnPz6vP1auebKVG0O/hZsOWQwUFNdweWAt+vbdx/x8uFJI49rw==",
"dev": true,
"dependencies": {
"blessed": "^0.1.81",
@ -203,6 +265,36 @@
"resolved": "https://registry.npmjs.org/lodash.negate/-/lodash.negate-3.0.2.tgz",
"integrity": "sha1-nIl7C/YQAZ4LQ7j/Pwr+89e2bzQ="
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
@ -213,9 +305,9 @@
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -224,9 +316,9 @@
}
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/ms": {
@ -251,6 +343,17 @@
"node": ">=10"
}
},
"node_modules/nodejs-file-downloader": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.9.3.tgz",
"integrity": "sha512-1agDW6TDkdNdyMm20iF70bpRHsA8WwVdezFTcBD4FPf/nAPwV/cDK7tUeALemK1DX1k8MfhAiYTB/jmyBkgmJw==",
"dependencies": {
"follow-redirects": "^1.13.0",
"https-proxy-agent": "^5.0.0",
"mime-types": "^2.1.27",
"sanitize-filename": "^1.6.3"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -323,40 +426,42 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/semver-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz",
"integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/semver-sort": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/semver-sort/-/semver-sort-0.0.4.tgz",
"integrity": "sha1-NP293GprK0FhOYw8TbpWJDv+qos=",
"node_modules/sanitize-filename": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
"dependencies": {
"semver": "^5.0.3",
"semver-regex": "^1.0.0"
"truncate-utf8-bytes": "^1.0.0"
}
},
"node_modules/semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=0.10.0"
"node": ">=10"
}
},
"node_modules/signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"node_modules/truncate-utf8-bytes": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
"integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
"dependencies": {
"utf8-byte-length": "^1.0.1"
}
},
"node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@ -365,10 +470,34 @@
"node": ">=8"
}
},
"node_modules/utf8-byte-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
"integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
},
"dependencies": {
@ -377,6 +506,14 @@
"resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz",
"integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -418,17 +555,22 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"electron-fingerprints": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-1.0.0.tgz",
"integrity": "sha512-vDW8IBu4tj/ZP/JGa7lcal9/Yc+prokzHfazi0OB/GIMeyUxfGznlK3RVJzGD5XxXgPyy6GEt5xrTNxB8TU/bA=="
"version": "2022.3.30",
"resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-2022.3.30.tgz",
"integrity": "sha512-RciBhcnMYqNFqeibbKICOqTsCPPFgU+I2KQp3wt77Xw+3YOE3FOPD1XkE/u5k8B/c9tilJ78uowJjElnaRUtHA=="
},
"follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
},
"fs.realpath": {
"version": "1.0.0",
@ -436,9 +578,9 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -457,6 +599,15 @@
"type-fest": "^0.8.0"
}
},
"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==",
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -472,14 +623,24 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
},
"is-valid-http-url": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-valid-http-url/-/is-valid-http-url-1.0.3.tgz",
"integrity": "sha512-lrPp25k/Ft3HdusDBdXqne9lNKDtN0HWIHNuC9cfzuFBLlay/gyQeBJukUR1smjyp+zw+gJ5E9wHonpcE9kiCQ=="
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"kuta": {
"version": "2.0.0-beta.6",
"resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.6.tgz",
"integrity": "sha512-MbBNzXs7RroFZ7aCG5tYveRCvMws3yoiK6f1dRsOkOlDa1+QRk/kGKukG7WKgcyT6Jw6W66Hc22gp3zKg2ZtPQ==",
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.7.tgz",
"integrity": "sha512-bwthe2BQ//kleJjswnUOo9AwXbknyw6Hk0wzxnPz6vP1auebKVG0O/hZsOWQwUFNdweWAt+vbdx/x8uFJI49rw==",
"dev": true,
"requires": {
"blessed": "^0.1.81",
@ -515,6 +676,27 @@
"resolved": "https://registry.npmjs.org/lodash.negate/-/lodash.negate-3.0.2.tgz",
"integrity": "sha1-nIl7C/YQAZ4LQ7j/Pwr+89e2bzQ="
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"requires": {
"mime-db": "1.52.0"
}
},
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
@ -522,17 +704,17 @@
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"ms": {
@ -554,6 +736,17 @@
"normalize-path": "^3.0.0"
}
},
"nodejs-file-downloader": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.9.3.tgz",
"integrity": "sha512-1agDW6TDkdNdyMm20iF70bpRHsA8WwVdezFTcBD4FPf/nAPwV/cDK7tUeALemK1DX1k8MfhAiYTB/jmyBkgmJw==",
"requires": {
"follow-redirects": "^1.13.0",
"https-proxy-agent": "^5.0.0",
"mime-types": "^2.1.27",
"sanitize-filename": "^1.6.3"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -605,40 +798,63 @@
"glob": "^7.1.3"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"semver-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz",
"integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk="
},
"semver-sort": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/semver-sort/-/semver-sort-0.0.4.tgz",
"integrity": "sha1-NP293GprK0FhOYw8TbpWJDv+qos=",
"sanitize-filename": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
"requires": {
"semver": "^5.0.3",
"semver-regex": "^1.0.0"
"truncate-utf8-bytes": "^1.0.0"
}
},
"semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"truncate-utf8-bytes": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
"integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
"requires": {
"utf8-byte-length": "^1.0.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
},
"utf8-byte-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
"integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}

View File

@ -1,13 +1,14 @@
{
"name": "which-electron",
"version": "1.0.0",
"version": "1.1.5",
"description": "Guess which electron version is bundled in an application",
"main": "index.js",
"main": "src/index.js",
"bin": {
"which-electron": "index.js"
"which-electron": "src/index.js"
},
"scripts": {
"test": "kuta tests/*.js"
"test": "kuta tests/*.js",
"release": "npm update && php _scripts/gen_versions.php && git add src/versions.json package-lock.json && git commit -m 'new release' && npm version patch"
},
"repository": {
"type": "git",
@ -28,11 +29,14 @@
"homepage": "https://github.com/captn3m0/which-electron#readme",
"dependencies": {
"7zip-bin": "^5.1.1",
"electron-fingerprints": "^1.0.0",
"electron-fingerprints": "*",
"hasha": "^5.2.2",
"is-valid-http-url": "^1.0.3",
"node-7z": "^3.0.0",
"nodejs-file-downloader": "^4.7.1",
"rimraf": "^3.0.2",
"semver-sort": "^0.0.4"
"semver": "^7.3.5",
"which": "^2.0.2"
},
"devDependencies": {
"kuta": "*"

View File

@ -1,34 +1,43 @@
const Seven = require("node-7z");
const sevenBin = require('7zip-bin').path7za;
const which = require('which');
const path = require("path");
const fs = require("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.")
}
module.exports = {
readFileContents: function(archive, filepath, cb) {
// TODO: Create a new temp directory
let stream = Seven.extract(archive, "/tmp", {
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(`/tmp/${fn}`, {encoding: 'utf8'}))
cb(fs.readFileSync(`${dir}/${fn}`, {encoding: 'utf8'}))
});
},
extractSomeFiles: function(archive, list, cb) {
let dir = fs.mkdtempSync('/tmp/which-electron')
extractSomeFiles: function(archive, list, dir, cb) {
let stream = Seven.extract(archive, dir, {
$cherryPick: list,
$bin: sevenBin
})
stream.on('end', ()=>{
cb(dir)
cb()
})
},
listFileContents: function(archive, cb) {
let zip = Seven.list(archive, {
$bin: sevenBin
$bin: sevenBin,
alternateStreamExtract: true,
alternateStreamReplace: true,
});
let entries = [];
zip.on("data", (data) => {

133
src/index.js Normal file
View File

@ -0,0 +1,133 @@
const osguess = require("./os");
const finder = require("./finder");
const archive = require("./archive");
const fp = require("./fingerprint");
const V = require("./version");
const isUrl = require("is-valid-http-url");
const cleanup = require("rimraf");
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')
// 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)
}
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)
})
} else {
validateFile(FILENAME)
}
function validateFile(fn) {
fs.access(fn, fs.constants.R_OK, (err) => {
if (err) {
console.error(`${fn} not readable`)
process.exit(1);
} else {
console.log(fn);
whichElectron(fn)
}
});
}
function logSupport(version) {
if (V.isSupported(version)) {
console.log(`${version} is currently supported`);
} else {
console.log(`${version} is currently not supported`);
}
}
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}`);
}
if (osguess1 && !osguess2) {
osguess2 = osguess1
}
let arch = osguess.guessArch(filename, entries);
let asar = finder.asar(entries);
let binary = finder.binary(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))
}
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}`)
});
});
}
if (asar.length > 0) {
asar.forEach((a) => {
console.log("Version Constraint (Unsupported): <v7.0.0");
});
}
if (enm) {
enm.forEach((a) => {
archive.readFileContents(filename, a, (c) => {
try {
let packageData = JSON.parse(c);
console.log(
"Found version in package.json file: " + packageData["version"]
);
logSupport(`v${packageData["version"]}`)
} catch (e) {
// TODO: Do something
}
});
});
}
});
}

View File

18
src/version.js Normal file
View File

@ -0,0 +1,18 @@
const semver = require("semver");
const VERSIONS = require("./versions");
module.exports = {
asText: function (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;
},
};

570
src/versions.json Normal file
View File

@ -0,0 +1,570 @@
{
"supported": [
"v17.4.5",
"v18.3.0",
"v19.0.0"
],
"all": [
"v0.24.0",
"v0.25.0",
"v0.25.1",
"v0.25.2",
"v0.25.3",
"v0.26.0",
"v0.26.1",
"v0.27.0",
"v0.27.1",
"v0.27.2",
"v0.27.3",
"v0.28.0",
"v0.28.1",
"v0.28.2",
"v0.28.3",
"v0.29.0",
"v0.29.1",
"v0.29.2",
"v0.30.0",
"v0.30.1",
"v0.30.2",
"v0.30.3",
"v0.30.4",
"v0.30.5",
"v0.30.6",
"v0.30.7",
"v0.30.8",
"v0.31.0",
"v0.31.1",
"v0.31.2",
"v0.32.0",
"v0.32.1",
"v0.32.2",
"v0.32.3",
"v0.33.0",
"v0.33.1",
"v0.33.2",
"v0.33.3",
"v0.33.4",
"v0.33.5",
"v0.33.6",
"v0.33.7",
"v0.33.8",
"v0.33.9",
"v0.34.0",
"v0.34.1",
"v0.34.2",
"v0.34.3",
"v0.34.4",
"v0.34.5",
"v0.35.0",
"v0.35.1",
"v0.35.2",
"v0.35.3",
"v0.35.4",
"v0.35.5",
"v0.35.6",
"v0.36.0",
"v0.36.1",
"v0.36.2",
"v0.36.3",
"v0.36.4",
"v0.36.5",
"v0.36.6",
"v0.36.7",
"v0.36.8",
"v0.36.9",
"v0.36.10",
"v0.36.11",
"v0.36.12",
"v0.37.0",
"v0.37.1",
"v0.37.2",
"v0.37.3",
"v0.37.4",
"v0.37.5",
"v0.37.6",
"v0.37.7",
"v0.37.8",
"v1.0.0",
"v1.0.1",
"v1.0.2",
"v1.1.0",
"v1.1.1",
"v1.1.2",
"v1.1.3",
"v1.2.0",
"v1.2.1",
"v1.2.2",
"v1.2.3",
"v1.2.4",
"v1.2.5",
"v1.2.6",
"v1.2.7",
"v1.2.8",
"v1.3.0",
"v1.3.1",
"v1.3.2",
"v1.3.3",
"v1.3.4",
"v1.3.5",
"v1.3.6",
"v1.3.7",
"v1.3.8",
"v1.3.9",
"v1.3.10",
"v1.3.11",
"v1.3.12",
"v1.3.13",
"v1.3.14",
"v1.3.15",
"v1.4.0",
"v1.4.1",
"v1.4.2",
"v1.4.3",
"v1.4.4",
"v1.4.5",
"v1.4.6",
"v1.4.7",
"v1.4.8",
"v1.4.9",
"v1.4.10",
"v1.4.11",
"v1.4.12",
"v1.4.13",
"v1.4.14",
"v1.4.15",
"v1.4.16",
"v1.5.0",
"v1.5.1",
"v1.6.0",
"v1.6.1",
"v1.6.2",
"v1.6.3",
"v1.6.4",
"v1.6.5",
"v1.6.6",
"v1.6.7",
"v1.6.8",
"v1.6.9",
"v1.6.10",
"v1.6.11",
"v1.6.12",
"v1.6.13",
"v1.6.14",
"v1.6.15",
"v1.6.16",
"v1.6.17",
"v1.6.18",
"v1.7.0",
"v1.7.1",
"v1.7.2",
"v1.7.3",
"v1.7.4",
"v1.7.5",
"v1.7.6",
"v1.7.7",
"v1.7.8",
"v1.7.9",
"v1.7.10",
"v1.7.11",
"v1.7.12",
"v1.7.13",
"v1.7.14",
"v1.7.15",
"v1.7.16",
"v1.8.0",
"v1.8.1",
"v1.8.2",
"v1.8.3",
"v1.8.4",
"v1.8.5",
"v1.8.6",
"v1.8.7",
"v1.8.8",
"v2.0.0",
"v2.0.1",
"v2.0.2",
"v2.0.3",
"v2.0.4",
"v2.0.5",
"v2.0.6",
"v2.0.7",
"v2.0.8",
"v2.0.9",
"v2.0.10",
"v2.0.11",
"v2.0.12",
"v2.0.13",
"v2.0.14",
"v2.0.15",
"v2.0.16",
"v2.0.17",
"v2.0.18",
"v2.1.0-unsupported-20180809",
"v2.1.0-unsupported.20180809",
"v3.0.0",
"v3.0.1",
"v3.0.2",
"v3.0.3",
"v3.0.4",
"v3.0.5",
"v3.0.6",
"v3.0.7",
"v3.0.8",
"v3.0.9",
"v3.0.10",
"v3.0.11",
"v3.0.12",
"v3.0.13",
"v3.0.14",
"v3.0.15",
"v3.0.16",
"v3.1.0",
"v3.1.1",
"v3.1.2",
"v3.1.3",
"v3.1.4",
"v3.1.5",
"v3.1.6",
"v3.1.7",
"v3.1.8",
"v3.1.9",
"v3.1.10",
"v3.1.11",
"v3.1.12",
"v3.1.13",
"v4.0.0",
"v4.0.1",
"v4.0.2",
"v4.0.3",
"v4.0.4",
"v4.0.5",
"v4.0.6",
"v4.0.7",
"v4.0.8",
"v4.1.0",
"v4.1.1",
"v4.1.2",
"v4.1.3",
"v4.1.4",
"v4.1.5",
"v4.2.0",
"v4.2.1",
"v4.2.2",
"v4.2.3",
"v4.2.4",
"v4.2.5",
"v4.2.6",
"v4.2.7",
"v4.2.8",
"v4.2.9",
"v4.2.10",
"v4.2.11",
"v4.2.12",
"v5.0.0",
"v5.0.1",
"v5.0.2",
"v5.0.3",
"v5.0.4",
"v5.0.5",
"v5.0.6",
"v5.0.7",
"v5.0.8",
"v5.0.9",
"v5.0.10",
"v5.0.11",
"v5.0.12",
"v5.0.13",
"v6.0.0",
"v6.0.1",
"v6.0.2",
"v6.0.3",
"v6.0.4",
"v6.0.5",
"v6.0.6",
"v6.0.7",
"v6.0.8",
"v6.0.9",
"v6.0.10",
"v6.0.11",
"v6.0.12",
"v6.1.0",
"v6.1.1",
"v6.1.2",
"v6.1.3",
"v6.1.4",
"v6.1.5",
"v6.1.6",
"v6.1.7",
"v6.1.8",
"v6.1.9",
"v6.1.10",
"v6.1.11",
"v6.1.12",
"v7.0.0",
"v7.0.1",
"v7.1.0",
"v7.1.1",
"v7.1.2",
"v7.1.3",
"v7.1.4",
"v7.1.5",
"v7.1.6",
"v7.1.7",
"v7.1.8",
"v7.1.9",
"v7.1.10",
"v7.1.11",
"v7.1.12",
"v7.1.13",
"v7.1.14",
"v7.2.0",
"v7.2.1",
"v7.2.2",
"v7.2.3",
"v7.2.4",
"v7.3.0",
"v7.3.1",
"v7.3.2",
"v7.3.3",
"v8.0.0",
"v8.0.1",
"v8.0.2",
"v8.0.3",
"v8.1.0",
"v8.1.1",
"v8.2.0",
"v8.2.1",
"v8.2.2",
"v8.2.3",
"v8.2.4",
"v8.2.5",
"v8.3.0",
"v8.3.1",
"v8.3.2",
"v8.3.3",
"v8.3.4",
"v8.4.0",
"v8.4.1",
"v8.5.0",
"v8.5.1",
"v8.5.2",
"v8.5.3",
"v8.5.4",
"v8.5.5",
"v9.0.0",
"v9.0.1",
"v9.0.2",
"v9.0.3",
"v9.0.4",
"v9.0.5",
"v9.0.6",
"v9.1.0",
"v9.1.1",
"v9.1.2",
"v9.2.0",
"v9.2.1",
"v9.3.0",
"v9.3.1",
"v9.3.2",
"v9.3.3",
"v9.3.4",
"v9.3.5",
"v9.4.0",
"v9.4.1",
"v9.4.2",
"v9.4.3",
"v9.4.4",
"v10.0.0",
"v10.0.1",
"v10.1.0",
"v10.1.1",
"v10.1.2",
"v10.1.3",
"v10.1.4",
"v10.1.5",
"v10.1.6",
"v10.1.7",
"v10.2.0",
"v10.3.0",
"v10.3.1",
"v10.3.2",
"v10.4.0",
"v10.4.1",
"v10.4.2",
"v10.4.3",
"v10.4.4",
"v10.4.5",
"v10.4.6",
"v10.4.7",
"v11.0.0",
"v11.0.1",
"v11.0.2",
"v11.0.3",
"v11.0.4",
"v11.0.5",
"v11.1.0",
"v11.1.1",
"v11.2.0",
"v11.2.1",
"v11.2.2",
"v11.2.3",
"v11.3.0",
"v11.4.0",
"v11.4.1",
"v11.4.2",
"v11.4.3",
"v11.4.4",
"v11.4.5",
"v11.4.6",
"v11.4.7",
"v11.4.8",
"v11.4.9",
"v11.4.10",
"v11.4.11",
"v11.4.12",
"v11.5.0",
"v12.0.0",
"v12.0.1",
"v12.0.2",
"v12.0.3",
"v12.0.4",
"v12.0.5",
"v12.0.6",
"v12.0.7",
"v12.0.8",
"v12.0.9",
"v12.0.10",
"v12.0.11",
"v12.0.12",
"v12.0.13",
"v12.0.14",
"v12.0.15",
"v12.0.16",
"v12.0.17",
"v12.0.18",
"v12.1.0",
"v12.1.1",
"v12.1.2",
"v12.2.0",
"v12.2.1",
"v12.2.2",
"v12.2.3",
"v13.0.0",
"v13.0.1",
"v13.1.0",
"v13.1.1",
"v13.1.2",
"v13.1.3",
"v13.1.4",
"v13.1.5",
"v13.1.6",
"v13.1.7",
"v13.1.8",
"v13.1.9",
"v13.2.0",
"v13.2.1",
"v13.2.2",
"v13.2.3",
"v13.3.0",
"v13.4.0",
"v13.5.0",
"v13.5.1",
"v13.5.2",
"v13.6.0",
"v13.6.1",
"v13.6.2",
"v13.6.3",
"v13.6.4",
"v13.6.5",
"v13.6.6",
"v13.6.7",
"v13.6.8",
"v13.6.9",
"v14.0.0",
"v14.0.1",
"v14.0.2",
"v14.1.0",
"v14.1.1",
"v14.2.0",
"v14.2.1",
"v14.2.2",
"v14.2.3",
"v14.2.4",
"v14.2.5",
"v14.2.6",
"v14.2.7",
"v14.2.8",
"v14.2.9",
"v15.0.0",
"v15.1.0",
"v15.1.1",
"v15.1.2",
"v15.2.0",
"v15.3.0",
"v15.3.1",
"v15.3.2",
"v15.3.3",
"v15.3.4",
"v15.3.5",
"v15.3.6",
"v15.3.7",
"v15.4.0",
"v15.4.1",
"v15.4.2",
"v15.5.0",
"v15.5.1",
"v15.5.2",
"v15.5.3",
"v15.5.4",
"v15.5.5",
"v15.5.6",
"v16.0.0",
"v16.0.1",
"v16.0.2",
"v16.0.3",
"v16.0.4",
"v16.0.5",
"v16.0.6",
"v16.0.7",
"v16.0.8",
"v16.0.9",
"v16.0.10",
"v16.1.0",
"v16.1.1",
"v16.2.0",
"v16.2.1",
"v16.2.2",
"v16.2.3",
"v16.2.4",
"v16.2.5",
"v16.2.6",
"v16.2.7",
"v17.0.0",
"v17.0.1",
"v17.1.0",
"v17.1.1",
"v17.1.2",
"v17.2.0",
"v17.3.0",
"v17.3.1",
"v17.4.0",
"v17.4.1",
"v17.4.2",
"v17.4.3",
"v17.4.4",
"v17.4.5",
"v18.0.0",
"v18.0.1",
"v18.0.2",
"v18.0.3",
"v18.0.4",
"v18.1.0",
"v18.2.0",
"v18.2.1",
"v18.2.2",
"v18.2.3",
"v18.2.4",
"v18.3.0",
"v19.0.0"
]
}

View File

@ -1,5 +1,5 @@
const test = require("kuta").test;
const finder = require("../finder");
const finder = require("../src/finder");
const assert = require("assert");
const _ = require("./utils");

View File

@ -1,5 +1,5 @@
const test = require("kuta").test;
const fp = require("../fingerprint");
const fp = require("../src/fingerprint");
const assert = require("assert");
test("it should work with a single fingerprint", () => {

View File

@ -1,5 +1,5 @@
const test = require('kuta').test;
const os = require('../os')
const os = require('../src/os')
const assert = require('assert')
const _ = require('./utils')

View File

@ -1,18 +0,0 @@
const semverSort = require('semver-sort');
const VERSIONS = require('./versions')
module.exports = {
asText: function(listOfVersions) {
sorted = semverSort.asc(listOfVersions);
return `${sorted[0]}-${sorted[sorted.length-1]}`
},
max: function(listOfVersions) {
sorted = semverSort.asc(listOfVersions);
return sorted[sorted.length-1];
},
isSupported: function(v) {
return (VERSIONS['supported'].indexOf(v) !== -1)
}
}

View File

@ -1,446 +0,0 @@
{
"supported": ["13.1.6", "12.0.14", "11.4.10"],
"all": [
"v0.24.0",
"v0.25.0",
"v0.25.1",
"v0.25.2",
"v0.25.3",
"v0.26.0",
"v0.26.1",
"v0.27.0",
"v0.27.1",
"v0.27.2",
"v0.27.3",
"v0.28.0",
"v0.28.1",
"v0.28.2",
"v0.28.3",
"v0.29.0",
"v0.29.1",
"v0.29.2",
"v0.30.0",
"v0.30.1",
"v0.30.2",
"v0.30.3",
"v0.30.4",
"v0.30.5",
"v0.30.6",
"v0.30.7",
"v0.30.8",
"v0.31.0",
"v0.31.1",
"v0.31.2",
"v0.32.0",
"v0.32.1",
"v0.32.2",
"v0.32.3",
"v0.33.0",
"v0.33.1",
"v0.33.2",
"v0.33.3",
"v0.33.4",
"v0.33.5",
"v0.33.6",
"v0.33.7",
"v0.33.8",
"v0.33.9",
"v0.34.0",
"v0.34.1",
"v0.34.2",
"v0.34.3",
"v0.34.4",
"v0.34.5",
"v0.35.0",
"v0.35.1",
"v0.35.2",
"v0.35.3",
"v0.35.4",
"v0.35.5",
"v0.35.6",
"v0.36.0",
"v0.36.1",
"v0.36.10",
"v0.36.11",
"v0.36.12",
"v0.36.2",
"v0.36.3",
"v0.36.4",
"v0.36.5",
"v0.36.6",
"v0.36.7",
"v0.36.8",
"v0.36.9",
"v0.37.0",
"v0.37.1",
"v0.37.2",
"v0.37.3",
"v0.37.4",
"v0.37.5",
"v0.37.6",
"v0.37.7",
"v0.37.8",
"v1.0.0",
"v1.0.1",
"v1.0.2",
"v1.1.0",
"v1.1.1",
"v1.1.2",
"v1.1.3",
"v1.2.0",
"v1.2.1",
"v1.2.2",
"v1.2.3",
"v1.2.4",
"v1.2.5",
"v1.2.6",
"v1.2.7",
"v1.2.8",
"v1.3.0",
"v1.3.1",
"v1.3.10",
"v1.3.11",
"v1.3.12",
"v1.3.13",
"v1.3.14",
"v1.3.15",
"v1.3.2",
"v1.3.3",
"v1.3.4",
"v1.3.5",
"v1.3.6",
"v1.3.7",
"v1.3.8",
"v1.3.9",
"v1.4.0",
"v1.4.1",
"v1.4.10",
"v1.4.11",
"v1.4.12",
"v1.4.13",
"v1.4.14",
"v1.4.15",
"v1.4.16",
"v1.4.2",
"v1.4.3",
"v1.4.4",
"v1.4.5",
"v1.4.6",
"v1.4.7",
"v1.4.8",
"v1.4.9",
"v1.5.0",
"v1.5.1",
"v1.6.0",
"v1.6.1",
"v1.6.10",
"v1.6.11",
"v1.6.12",
"v1.6.13",
"v1.6.14",
"v1.6.15",
"v1.6.16",
"v1.6.17",
"v1.6.18",
"v1.6.2",
"v1.6.3",
"v1.6.4",
"v1.6.5",
"v1.6.6",
"v1.6.7",
"v1.6.8",
"v1.6.9",
"v1.7.0",
"v1.7.1",
"v1.7.10",
"v1.7.11",
"v1.7.12",
"v1.7.13",
"v1.7.14",
"v1.7.15",
"v1.7.16",
"v1.7.2",
"v1.7.3",
"v1.7.4",
"v1.7.5",
"v1.7.6",
"v1.7.7",
"v1.7.8",
"v1.7.9",
"v1.8.0",
"v1.8.1",
"v1.8.2",
"v1.8.3",
"v1.8.4",
"v1.8.5",
"v1.8.6",
"v1.8.7",
"v1.8.8",
"v10.0.0",
"v10.0.1",
"v10.1.0",
"v10.1.1",
"v10.1.2",
"v10.1.3",
"v10.1.4",
"v10.1.5",
"v10.1.6",
"v10.1.7",
"v10.2.0",
"v10.3.0",
"v10.3.1",
"v10.3.2",
"v10.4.0",
"v10.4.1",
"v10.4.2",
"v10.4.3",
"v10.4.4",
"v10.4.5",
"v10.4.6",
"v10.4.7",
"v11.0.0",
"v11.0.1",
"v11.0.2",
"v11.0.3",
"v11.0.4",
"v11.0.5",
"v11.1.0",
"v11.1.1",
"v11.2.0",
"v11.2.1",
"v11.2.2",
"v11.2.3",
"v11.3.0",
"v11.4.0",
"v11.4.1",
"v11.4.10",
"v11.4.2",
"v11.4.3",
"v11.4.4",
"v11.4.5",
"v11.4.6",
"v11.4.7",
"v11.4.8",
"v11.4.9",
"v12.0.0",
"v12.0.1",
"v12.0.10",
"v12.0.11",
"v12.0.12",
"v12.0.13",
"v12.0.14",
"v12.0.15",
"v12.0.2",
"v12.0.3",
"v12.0.4",
"v12.0.5",
"v12.0.6",
"v12.0.7",
"v12.0.8",
"v12.0.9",
"v13.0.0",
"v13.0.1",
"v13.1.0",
"v13.1.1",
"v13.1.2",
"v13.1.3",
"v13.1.4",
"v13.1.5",
"v13.1.6",
"v13.1.7",
"v2.0.0",
"v2.0.1",
"v2.0.10",
"v2.0.11",
"v2.0.12",
"v2.0.13",
"v2.0.14",
"v2.0.15",
"v2.0.16",
"v2.0.17",
"v2.0.18",
"v2.0.2",
"v2.0.3",
"v2.0.4",
"v2.0.5",
"v2.0.6",
"v2.0.7",
"v2.0.8",
"v2.0.9",
"v2.1.0-unsupported-20180809",
"v2.1.0-unsupported.20180809",
"v3.0.0",
"v3.0.1",
"v3.0.10",
"v3.0.11",
"v3.0.12",
"v3.0.13",
"v3.0.14",
"v3.0.15",
"v3.0.16",
"v3.0.2",
"v3.0.3",
"v3.0.4",
"v3.0.5",
"v3.0.6",
"v3.0.7",
"v3.0.8",
"v3.0.9",
"v3.1.0",
"v3.1.1",
"v3.1.10",
"v3.1.11",
"v3.1.12",
"v3.1.13",
"v3.1.2",
"v3.1.3",
"v3.1.4",
"v3.1.5",
"v3.1.6",
"v3.1.7",
"v3.1.8",
"v3.1.9",
"v4.0.0",
"v4.0.1",
"v4.0.2",
"v4.0.3",
"v4.0.4",
"v4.0.5",
"v4.0.6",
"v4.0.7",
"v4.0.8",
"v4.1.0",
"v4.1.1",
"v4.1.2",
"v4.1.3",
"v4.1.4",
"v4.1.5",
"v4.2.0",
"v4.2.1",
"v4.2.10",
"v4.2.11",
"v4.2.12",
"v4.2.2",
"v4.2.3",
"v4.2.4",
"v4.2.5",
"v4.2.6",
"v4.2.7",
"v4.2.8",
"v4.2.9",
"v5.0.0",
"v5.0.1",
"v5.0.10",
"v5.0.11",
"v5.0.12",
"v5.0.13",
"v5.0.2",
"v5.0.3",
"v5.0.4",
"v5.0.5",
"v5.0.6",
"v5.0.7",
"v5.0.8",
"v5.0.9",
"v6.0.0",
"v6.0.1",
"v6.0.10",
"v6.0.11",
"v6.0.12",
"v6.0.2",
"v6.0.3",
"v6.0.4",
"v6.0.5",
"v6.0.6",
"v6.0.7",
"v6.0.8",
"v6.0.9",
"v6.1.0",
"v6.1.1",
"v6.1.10",
"v6.1.11",
"v6.1.12",
"v6.1.2",
"v6.1.3",
"v6.1.4",
"v6.1.5",
"v6.1.6",
"v6.1.7",
"v6.1.8",
"v6.1.9",
"v7.0.0",
"v7.0.1",
"v7.1.0",
"v7.1.1",
"v7.1.10",
"v7.1.11",
"v7.1.12",
"v7.1.13",
"v7.1.14",
"v7.1.2",
"v7.1.3",
"v7.1.4",
"v7.1.5",
"v7.1.6",
"v7.1.7",
"v7.1.8",
"v7.1.9",
"v7.2.0",
"v7.2.1",
"v7.2.2",
"v7.2.3",
"v7.2.4",
"v7.3.0",
"v7.3.1",
"v7.3.2",
"v7.3.3",
"v8.0.0",
"v8.0.1",
"v8.0.2",
"v8.0.3",
"v8.1.0",
"v8.1.1",
"v8.2.0",
"v8.2.1",
"v8.2.2",
"v8.2.3",
"v8.2.4",
"v8.2.5",
"v8.3.0",
"v8.3.1",
"v8.3.2",
"v8.3.3",
"v8.3.4",
"v8.4.0",
"v8.4.1",
"v8.5.0",
"v8.5.1",
"v8.5.2",
"v8.5.3",
"v8.5.4",
"v8.5.5",
"v9.0.0",
"v9.0.1",
"v9.0.2",
"v9.0.3",
"v9.0.4",
"v9.0.5",
"v9.0.6",
"v9.1.0",
"v9.1.1",
"v9.1.2",
"v9.2.0",
"v9.2.1",
"v9.3.0",
"v9.3.1",
"v9.3.2",
"v9.3.3",
"v9.3.4",
"v9.3.5",
"v9.4.0",
"v9.4.1",
"v9.4.2",
"v9.4.3",
"v9.4.4"
]
}