aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gulpfile.js2
-rw-r--r--lib/wallet/cryptoApi-test.ts7
-rw-r--r--node_modules/.yarn-integrity2
-rw-r--r--package.json3
-rw-r--r--testlib/node/runtime.js5
-rw-r--r--testlib/selenium/runtime.js65
-rw-r--r--testlib/selenium/testhost.html4
-rw-r--r--testlib/talertest.ts15
-rw-r--r--tsconfig.json4
-rw-r--r--yarn.lock130
10 files changed, 213 insertions, 24 deletions
diff --git a/gulpfile.js b/gulpfile.js
index b11debdc8..1cd0beaec 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -57,12 +57,14 @@ const paths = {
"popup/*.{ts,tsx}",
"pages/*.{ts,tsx}",
"!**/*.d.ts",
+ "!**/*-test*.ts",
],
decl: [
"lib/refs.d.ts",
],
dev: [
"testlib/**/.ts",
+ "**/*-test*.ts",
],
},
dist: [
diff --git a/lib/wallet/cryptoApi-test.ts b/lib/wallet/cryptoApi-test.ts
index 6399367b1..ea3045c29 100644
--- a/lib/wallet/cryptoApi-test.ts
+++ b/lib/wallet/cryptoApi-test.ts
@@ -1,6 +1,9 @@
import {CryptoApi} from "./cryptoApi";
import {test, TestLib} from "testlib/talertest";
-test("string hashing", (t: TestLib) => {
-
+test("string hashing bla", async (t: TestLib) => {
+ let crypto = new CryptoApi();
+ let s = await crypto.hashString("hello taler");
+ console.log(s);
+ t.pass();
});
diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity
index 4324f37c5..13bf7167d 100644
--- a/node_modules/.yarn-integrity
+++ b/node_modules/.yarn-integrity
@@ -1 +1 @@
-4ba2f689d57511507e94d43fc06be3ad7c3198ea985e1cb661c2eef84d2fc993 \ No newline at end of file
+b17d9b8daaa8d5ec093068da508250296323997ac6ead0747fcdc5090a390154 \ No newline at end of file
diff --git a/package.json b/package.json
index cd08e3196..c59a8e569 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"license": "GPL-3.0",
"devDependencies": {
"better-assert": "^1.0.2",
+ "connect": "^3.5.0",
"del": "^2.2.0",
"glob": "^7.0.3",
"gulp": "^3.9.1",
@@ -30,9 +31,11 @@
"gulp-zip": "^3.1.0",
"istanbul-lib-instrument": "^1.0.0-alpha.6",
"map-stream": "0.0.6",
+ "minimist": "^1.2.0",
"mocha": "^2.4.5",
"po2json": "git+https://github.com/mikeedwards/po2json",
"selenium-webdriver": "^3.0.0-beta-3",
+ "serve-static": "^1.11.1",
"systemjs": "^0.19.14",
"through2": "^2.0.1",
"typescript": "^2.0.3",
diff --git a/testlib/node/runtime.js b/testlib/node/runtime.js
index 29ee508cc..dfdada9e8 100644
--- a/testlib/node/runtime.js
+++ b/testlib/node/runtime.js
@@ -53,6 +53,11 @@ let mod = System.newModule({Module: emsc, default: emsc});
let modName = System.normalizeSync(__dirname + "/../../lib/emscripten/taler-emscripten-lib.js");
System.set(modName, mod);
+process.on('unhandledRejection', function(reason, p){
+ console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
+ process.exit(1);
+});
+
let testName = process.argv[2];
System.import("testlib/talertest")
diff --git a/testlib/selenium/runtime.js b/testlib/selenium/runtime.js
index 0cf6c6d18..2253bafbc 100644
--- a/testlib/selenium/runtime.js
+++ b/testlib/selenium/runtime.js
@@ -25,21 +25,63 @@ var webdriver = require('selenium-webdriver');
var chrome = require('selenium-webdriver/chrome');
var path = require("path");
var process = require("process");
+var fs = require("fs");
-var p = "file://" + __dirname + "/testhost.html";
+var connect = require('connect');
+var serveStatic = require('serve-static');
-if (!process.argv[2]) {
- console.log("no test script given");
+// Port of the web server used to serve the test files
+var httpPort = 8080;
+
+var p = `http://localhost:${httpPort}/testlib/selenium/testhost.html`;
+
+var argv = require('minimist')(process.argv.slice(2), {"boolean": ["keep-open"]});
+
+console.log(argv);
+
+function printUsage() {
+ console.log(`Usage: [--keep-open] TESTSCRIPT`);
+}
+
+if (argv._.length != 1) {
+ console.log("exactly one test script must be given");
+ printUsage();
process.exit(1);
}
-var testScript = path.resolve(process.argv[2]);
+var testScriptName = path.resolve(argv._[0]);
+var projectRoot = path.resolve(__dirname, "../../");
+if (!testScriptName.startsWith(projectRoot)) {
+ console.log("test file must be inside wallet project root");
+ process.exit(1);
+}
+
+var testScript = "./" + testScriptName.substring(projectRoot.length);
+console.log("test script:", testScript);
+console.log("test script name:", testScriptName);
+console.log("root:", projectRoot);
+
+try {
+ var stats = fs.lstatSync(path.resolve(projectRoot, testScript));
+ if (!stats.isFile()) {
+ throw Error("test must be a file");
+ }
+} catch (e) {
+ console.log("can't execute test");
+ console.log(e);
+ process.exit(e);
+}
+
var script = `
function f() {
+ if ("undefined" == typeof System) {
+ console.log("can't access module loader");
+ return
+ }
System.import("testlib/talertest")
.then(tt => {
- SystemJS.import("file://${testScript}")
+ SystemJS.import("http://localhost:${httpPort}/${testScript}")
.then(() => {
return tt.run();
})
@@ -69,6 +111,9 @@ function untilTestOver() {
console.log("TAP version 13");
+let srv = connect().use(serveStatic(__dirname + "/../../"));
+let l = srv.listen(8080);
+
var driver = new webdriver.Builder()
.setLoggingPrefs({browser: 'ALL'})
.forBrowser('chrome')
@@ -80,9 +125,6 @@ driver.wait(untilTestOver);
driver.manage().logs().get("browser").then((logs) => {
for (let l of logs) {
- if (l.level.name != "INFO") {
- continue;
- }
if (l.message.startsWith("{")) {
// format not understood, sometimes messages are logged
// with more structure, just pass it on
@@ -94,7 +136,10 @@ driver.manage().logs().get("browser").then((logs) => {
// Skip file url and LINE:COL
console.log(l.message.substring(s2));
}
-});
-driver.quit();
+ if (!argv["keep-open"]) {
+ driver.quit();
+ l.close();
+ }
+});
diff --git a/testlib/selenium/testhost.html b/testlib/selenium/testhost.html
index 263fe6316..62c1a4e82 100644
--- a/testlib/selenium/testhost.html
+++ b/testlib/selenium/testhost.html
@@ -2,10 +2,10 @@
<html>
<head>
<title>Browser Test Host</title>
- <script src="../../lib/vendor/system-csp-production.src.js"></script>
+ <script src="/lib/vendor/system-csp-production.src.js"></script>
<script>
System.config({
- baseURL: "../../",
+ baseURL: "/",
defaultJSExtensions: true,
meta: {
"lib/emscripten/taler-emscripten-lib": {
diff --git a/testlib/talertest.ts b/testlib/talertest.ts
index 14074620b..16d8ec14e 100644
--- a/testlib/talertest.ts
+++ b/testlib/talertest.ts
@@ -19,7 +19,7 @@
* @author Florian Dold
*/
-type TestFn = (t: TestLib) => void;
+type TestFn = (t: TestLib) => void | Promise<void>;
interface Test {
name: string;
@@ -51,9 +51,15 @@ export async function run() {
console.log(`1..${tests.length}`);
for (let i in tests) {
let t = tests[i];
+ let passed = false;
let lastMsg: string|undefined = undefined;
let p = new Promise((resolve, reject) => {
let pass = (msg?: string) => {
+ if (passed) {
+ reject(Error("called pass twice"));
+ return;
+ }
+ passed = true;
lastMsg = msg;
resolve();
};
@@ -69,7 +75,9 @@ export async function run() {
throw Error("test failed");
}
};
- t.testFn({pass,fail, assert});
+ // Test might return a promise. If so, wait for it.
+ let r = t.testFn({pass,fail, assert});
+ r.then(() => resolve(), (e) => reject(e));
});
console.log(`# ${t.name}`);
@@ -80,6 +88,9 @@ export async function run() {
try {
await p;
+ if (passed) {
+ throw Error("test did not call 'pass'");
+ }
console.log(`ok ${Number(i) + 1} ${lastMsg}`);
} catch (e) {
console.error(e);
diff --git a/tsconfig.json b/tsconfig.json
index 4692feb82..0095b8d7d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,15 +16,15 @@
"lib/components.ts",
"lib/refs.d.ts",
"lib/i18n.ts",
+ "lib/wallet/cryptoApi-test.ts",
"lib/taler-wallet-lib.ts",
+ "lib/wallet/emscriptif-test.ts",
"lib/wallet/checkable.ts",
"lib/wallet/chromeBadge.ts",
- "lib/wallet/cryptoApi-test.ts",
"lib/wallet/cryptoApi.ts",
"lib/wallet/cryptoLib.ts",
"lib/wallet/cryptoWorker.ts",
"lib/wallet/db.ts",
- "lib/wallet/emscriptif-test.ts",
"lib/wallet/emscriptif.ts",
"lib/wallet/helpers.ts",
"lib/wallet/http.ts",
diff --git a/yarn.lock b/yarn.lock
index a649925df..bb021e51c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -325,6 +325,15 @@ concat-with-sourcemaps@^1.0.0:
dependencies:
source-map "^0.5.1"
+connect:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/connect/-/connect-3.5.0.tgz#b357525a0b4c1f50599cd983e1d9efeea9677198"
+ dependencies:
+ debug "~2.2.0"
+ finalhandler "0.5.0"
+ parseurl "~1.3.1"
+ utils-merge "1.0.0"
+
convert-source-map@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67"
@@ -357,7 +366,7 @@ dateformat@^1.0.11, dateformat@^1.0.7-1.2.3:
get-stdin "^4.0.1"
meow "^3.3.0"
-debug@^2.2.0, debug@2.2.0:
+debug@^2.2.0, debug@~2.2.0, debug@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
dependencies:
@@ -385,10 +394,18 @@ del@^2.2.0:
pinkie-promise "^2.0.0"
rimraf "^2.2.8"
+depd@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
+
deprecated@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19"
+destroy@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+
detect-file@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63"
@@ -420,6 +437,14 @@ duplexify@^3.2.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+
+encodeurl@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
@@ -450,6 +475,10 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+
escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@@ -462,6 +491,10 @@ esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+etag@~1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8"
+
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
@@ -517,6 +550,16 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
+finalhandler@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7"
+ dependencies:
+ debug "~2.2.0"
+ escape-html "~1.0.3"
+ on-finished "~2.3.0"
+ statuses "~1.3.0"
+ unpipe "~1.0.0"
+
find-index@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
@@ -567,6 +610,10 @@ for-own@^0.1.4:
dependencies:
for-in "^0.1.5"
+fresh@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f"
+
fs-exists-sync@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
@@ -935,6 +982,14 @@ hosted-git-info@^2.1.4:
version "2.1.5"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b"
+http-errors@~1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.0.tgz#b1cb3d8260fd8e2386cad3189045943372d48211"
+ dependencies:
+ inherits "2.0.1"
+ setprototypeof "1.0.1"
+ statuses ">= 1.3.0 < 2"
+
iconv-lite@~0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
@@ -960,6 +1015,10 @@ inherits@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b"
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
ini@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
@@ -1480,6 +1539,10 @@ micromatch@^2.3.7:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
+mime@1.3.4:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
+
minimatch@^2.0.1:
version "2.0.10"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
@@ -1506,14 +1569,14 @@ minimatch@0.3:
lru-cache "2"
sigmund "~1.0.0"
+minimist, minimist@^1.1.0, minimist@^1.1.3:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
minimist@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce"
-minimist@^1.1.0, minimist@^1.1.3:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
-
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
@@ -1600,6 +1663,12 @@ object.omit@^2.0.0:
for-own "^0.1.4"
is-extendable "^0.1.1"
+on-finished@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+ dependencies:
+ ee-first "1.1.1"
+
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -1673,6 +1742,10 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parseurl@~1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
+
path-dirname@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
@@ -1761,6 +1834,10 @@ randomatic@^1.1.3:
is-number "^2.0.2"
kind-of "^3.0.2"
+range-parser@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@@ -1906,10 +1983,41 @@ semver@^5.3.0, "semver@2 || 3 || 4 || 5":
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+send@0.14.1:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a"
+ dependencies:
+ debug "~2.2.0"
+ depd "~1.1.0"
+ destroy "~1.0.4"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ etag "~1.7.0"
+ fresh "0.3.0"
+ http-errors "~1.5.0"
+ mime "1.3.4"
+ ms "0.7.1"
+ on-finished "~2.3.0"
+ range-parser "~1.2.0"
+ statuses "~1.3.0"
+
sequencify@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c"
+serve-static:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.1.tgz#d6cce7693505f733c759de57befc1af76c0f0805"
+ dependencies:
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ parseurl "~1.3.1"
+ send "0.14.1"
+
+setprototypeof@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.1.tgz#52009b27888c4dc48f591949c0a8275834c1ca7e"
+
sigmund@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
@@ -1940,6 +2048,10 @@ spdx-license-ids@^1.0.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+"statuses@>= 1.3.0 < 2", statuses@~1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.0.tgz#8e55758cb20e7682c1f4fce8dcab30bf01d1e07a"
+
stream-consume@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f"
@@ -2134,6 +2246,10 @@ unique-stream@^2.0.2:
json-stable-stringify "^1.0.0"
through2-filter "^2.0.0"
+unpipe@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+
user-home@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
@@ -2142,6 +2258,10 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+utils-merge@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
+
v8flags@^2.0.2:
version "2.0.11"
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881"