Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22dee96f51 | ||
|
|
0c614b7097 | ||
|
|
f0a5869c53 | ||
|
|
5cd1668e0d | ||
|
|
0b061d68cc | ||
|
|
ffa4a2d054 | ||
|
|
f8072a8004 | ||
|
|
4306b3563a | ||
|
|
c4de88af6f | ||
|
|
9486185ceb | ||
|
|
261eb04e97 | ||
|
|
832bd6c908 | ||
|
|
05844caf85 | ||
|
|
f7e82fcb46 | ||
|
|
27b3af0a7b | ||
|
|
f733fac875 | ||
|
|
1097a1b020 | ||
|
|
ea422d63b3 | ||
|
|
a3821f6c4b | ||
|
|
de8a717b4c | ||
|
|
86e0269a86 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
.package_node_modules/
|
||||
obsolete/
|
||||
.DS_Store
|
||||
.tmp/
|
||||
|
||||
@@ -3,6 +3,13 @@ Changelog
|
||||
|
||||
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
|
||||
|
||||
ethers/v5.0.15 (2020-09-26 03:22)
|
||||
---------------------------------
|
||||
|
||||
- Add more accurate intrinsic gas cost to ABI calls with specified gas property. ([#1058](https://github.com/ethers-io/ethers.js/issues/1058); [f0a5869](https://github.com/ethers-io/ethers.js/commit/f0a5869c53475e55a5f47d8651f609fff45dc9a7))
|
||||
- Better errors for unconfigured ENS names. ([#1066](https://github.com/ethers-io/ethers.js/issues/1066); [5cd1668](https://github.com/ethers-io/ethers.js/commit/5cd1668e0d29099c5b7ce1fdc1d0e8a41af1a249))
|
||||
- Updated CLI solc to versin 0.7.1. ([4306b35](https://github.com/ethers-io/ethers.js/commit/4306b3563a171baa9d7bf4872475a13c3434f834))
|
||||
|
||||
ethers/v5.0.14 (2020-09-16 02:39)
|
||||
---------------------------------
|
||||
|
||||
@@ -122,4 +129,3 @@ ethers/v5.0.0 (2020-06-12 19:58)
|
||||
|
||||
- Preserve config canary string. ([7157816](https://github.com/ethers-io/ethers.js/commit/7157816fa53f660d750811b293e3b1d5a2f70bd4))
|
||||
- Updated docs. ([9e4c7e6](https://github.com/ethers-io/ethers.js/commit/9e4c7e609d9eeb5f2a11d6a90bfa9d32ee696431))
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const { setupBuild } = require("../build");
|
||||
|
||||
setupBuild(false);
|
||||
@@ -1,37 +0,0 @@
|
||||
const { setupBuild } = require("../build");
|
||||
const { loadPackage, savePackage } = require("../local");
|
||||
|
||||
const arg = process.argv[2];
|
||||
|
||||
(async function() {
|
||||
process.argv.slice(2).forEach((arg) => {
|
||||
console.log("Setting Option:", arg);
|
||||
switch(arg) {
|
||||
case "esm":
|
||||
setupBuild(true);
|
||||
break;
|
||||
|
||||
case "cjs":
|
||||
setupBuild(false);
|
||||
break;
|
||||
|
||||
// This will remove the browser field entirely, so make sure
|
||||
// to set esm of cjs first as they will restore the browser
|
||||
// field
|
||||
case "browser-lang-all": {
|
||||
const info = loadPackage("wordlists");
|
||||
delete info.browser;
|
||||
savePackage("wordlists", info);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
console.log("Unknown option:", arg);
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
|
||||
})().then((result) => {
|
||||
process.exit(result);
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
"use stricT";
|
||||
|
||||
const depgraph = require("../depgraph");
|
||||
const { log } = require("../log");
|
||||
const { loadJson, resolve, saveJson } = require("../utils");
|
||||
|
||||
(async function() {
|
||||
log(`<bold:Updating dependency-graph build order (tsconfig.project.json)...>`);
|
||||
let ordered = depgraph.getOrdered(true);
|
||||
|
||||
let path = resolve("tsconfig.project.json")
|
||||
|
||||
let projectConfig = loadJson(path);
|
||||
projectConfig.references = ordered.map((name) => ({ path: ("./packages/" + name) }));
|
||||
saveJson(path, projectConfig);
|
||||
})();
|
||||
@@ -1,30 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const { resolve } = require("path");
|
||||
|
||||
const sourceEthers = fs.readFileSync(resolve(__dirname, "../../packages/ethers/src.ts/ethers.ts")).toString();
|
||||
const targets = sourceEthers.match(/export\s*{\s*((.|\s)*)}/)[1].trim();
|
||||
|
||||
const output = `"use strict";
|
||||
|
||||
// To modify this file, you must update ./admin/cmds/update-exports.js
|
||||
|
||||
import * as ethers from "./ethers";
|
||||
|
||||
try {
|
||||
const anyGlobal = (window as any);
|
||||
|
||||
if (anyGlobal._ethers == null) {
|
||||
anyGlobal._ethers = ethers;
|
||||
}
|
||||
} catch (error) { }
|
||||
|
||||
export { ethers };
|
||||
|
||||
export {
|
||||
${ targets }
|
||||
} from "./ethers";
|
||||
`;
|
||||
|
||||
fs.writeFileSync(resolve(__dirname, "../../packages/ethers/src.ts/index.ts"), output);
|
||||
@@ -9,7 +9,7 @@ The [Cryptographic Hash Functions](link-wiki-cryptographichash)
|
||||
are a specific family of hash functions.
|
||||
|
||||
_property: ethers.utils.id(text) => string<[[DataHexString]]<32>> @<utils-id> @SRC<hash>
|
||||
The Ethereum Identity function computs the [KECCAK256](link-wiki-sha3) hash of the //text// bytes.
|
||||
The Ethereum Identity function computes the [KECCAK256](link-wiki-sha3) hash of the //text// bytes.
|
||||
|
||||
_property: ethers.utils.keccak256(aBytesLike) => string<[[DataHexString]]<32>> @<utils-keccak256> @SRC<keccak256>
|
||||
Returns the [KECCAK256](link-wiki-sha3) digest //aBytesLike//.
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = function(config) {
|
||||
{ pattern: "./packages/ethers/dist/ethers-all.esm.min.js", type: "module" },
|
||||
{ pattern: "./packages/tests/dist/tests.esm.js", type: "module" }
|
||||
],
|
||||
reporters: ['karma'],
|
||||
reporters: [ 'karma' ],
|
||||
plugins: [
|
||||
'karma-mocha',
|
||||
'karma-chrome-launcher',
|
||||
@@ -18,7 +18,7 @@ module.exports = function(config) {
|
||||
browsers: [ 'ChromeHeadless', "HeadlessLittleLiar" ],
|
||||
autoWatch: false,
|
||||
singleRun: true,
|
||||
browserNoActivityTimeout: 60000,
|
||||
browserNoActivityTimeout: 3600000,
|
||||
customLaunchers: {
|
||||
HeadlessLittleLiar: {
|
||||
base: 'ChromeHeadless',
|
||||
|
||||
@@ -18,24 +18,24 @@ module.exports = function(config) {
|
||||
browsers: [ 'ChromeHeadless', "HeadlessLittleLiar" ],
|
||||
autoWatch: false,
|
||||
singleRun: true,
|
||||
browserNoActivityTimeout: 600000,
|
||||
browserNoActivityTimeout: 3600000,
|
||||
|
||||
customLaunchers: {
|
||||
HeadlessLittleLiar: {
|
||||
base: 'ChromeHeadless',
|
||||
// https://peter.sh/experiments/chromium-command-line-switches/
|
||||
flags: [
|
||||
'--disable-extensions',
|
||||
'--disable-extensions',
|
||||
|
||||
// Enable this to help debug CORS issues (otherwise fetch throws a useless TypeError)
|
||||
//'--disable-web-security',
|
||||
// Enable this to help debug CORS issues (otherwise fetch throws a useless TypeError)
|
||||
//'--disable-web-security',
|
||||
|
||||
'--enable-automation',
|
||||
'--enable-automation',
|
||||
|
||||
// Cloudflare will block (on the testnet endpoints) any traffic
|
||||
// from a headless chome (based on the user agent), so we lie
|
||||
// This was take from Safari, because that is what I had on-hand
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
|
||||
// Cloudflare will block (on the testnet endpoints) any traffic
|
||||
// from a headless chome (based on the user agent), so we lie
|
||||
// This was take from Safari, because that is what I had on-hand
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
|
||||
}
|
||||
},
|
||||
/*
|
||||
|
||||
1
misc/ReactNativeTestApp/libs/.gitignore
vendored
Normal file
1
misc/ReactNativeTestApp/libs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.js
|
||||
3
misc/admin/auto-build.sh
Executable file
3
misc/admin/auto-build.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
npx tsc -w
|
||||
1
misc/admin/lib/build.d.ts
vendored
Normal file
1
misc/admin/lib/build.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function setupBuild(buildModule: boolean): void;
|
||||
48
misc/admin/lib/build.js
Normal file
48
misc/admin/lib/build.js
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path_1 = require("./path");
|
||||
const utils_1 = require("./utils");
|
||||
function setupConfig(outDir, moduleType, targetType) {
|
||||
// Configure the tsconfit.package.json...
|
||||
const path = path_1.resolve("tsconfig.package.json");
|
||||
const content = utils_1.loadJson(path);
|
||||
content.compilerOptions.module = moduleType;
|
||||
content.compilerOptions.target = targetType;
|
||||
utils_1.saveJson(path, content, true);
|
||||
// Configure the browser field for every pacakge, copying the
|
||||
// browser.umd filed for UMD and browser.esm for ESM
|
||||
path_1.dirnames.forEach((dirname) => {
|
||||
const filename = path_1.getPackageJsonPath(dirname);
|
||||
const info = utils_1.loadJson(filename);
|
||||
if (info._ethers_nobuild) {
|
||||
return;
|
||||
}
|
||||
if (targetType === "es2015") {
|
||||
if (info["browser.esm"]) {
|
||||
info.browser = info["browser.esm"];
|
||||
}
|
||||
}
|
||||
else if (targetType === "es5") {
|
||||
if (info["browser.umd"]) {
|
||||
info.browser = info["browser.umd"];
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("unsupported target");
|
||||
}
|
||||
utils_1.saveJson(filename, info, true);
|
||||
let path = path_1.resolve("packages", dirname, "tsconfig.json");
|
||||
let content = utils_1.loadJson(path);
|
||||
content.compilerOptions.outDir = outDir;
|
||||
utils_1.saveJson(path, content, true);
|
||||
});
|
||||
}
|
||||
function setupBuild(buildModule) {
|
||||
if (buildModule) {
|
||||
setupConfig("./lib.esm/", "es2015", "es2015");
|
||||
}
|
||||
else {
|
||||
setupConfig("./lib/", "commonjs", "es5");
|
||||
}
|
||||
}
|
||||
exports.setupBuild = setupBuild;
|
||||
1
misc/admin/lib/changelog.d.ts
vendored
Normal file
1
misc/admin/lib/changelog.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function generate(): Promise<string>;
|
||||
106
misc/admin/lib/changelog.js
Normal file
106
misc/admin/lib/changelog.js
Normal file
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const local = __importStar(require("./local"));
|
||||
const log_1 = require("./log");
|
||||
const npm = __importStar(require("./npm"));
|
||||
const path_1 = require("./path");
|
||||
const run_1 = require("./run");
|
||||
const utils_1 = require("./utils");
|
||||
const changelogPath = path_1.resolve("CHANGELOG.md");
|
||||
function generate() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const lines = fs_1.default.readFileSync(changelogPath).toString().trim().split("\n");
|
||||
let firstLine = null;
|
||||
const versions = Object.keys(lines.reduce((accum, line, index) => {
|
||||
const match = line.match(/^ethers\/v([^ ]*)/);
|
||||
if (match) {
|
||||
if (firstLine == null) {
|
||||
firstLine = index;
|
||||
}
|
||||
accum[match[1]] = true;
|
||||
}
|
||||
return accum;
|
||||
}, {}));
|
||||
const version = local.getPackage("ethers").version;
|
||||
;
|
||||
const published = yield npm.getPackage("ethers");
|
||||
if (versions.indexOf(version) >= 0) {
|
||||
const line = `Version ${version} already in CHANGELOG. Please edit before committing.`;
|
||||
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
|
||||
console.log(log_1.colorify.red(line));
|
||||
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
|
||||
}
|
||||
const gitResult = yield run_1.run("git", ["log", (published.gitHead + "..")]);
|
||||
if (!gitResult.ok) {
|
||||
console.log(gitResult);
|
||||
throw new Error("Error running git log");
|
||||
}
|
||||
let changes = [];
|
||||
gitResult.stdout.split("\n").forEach((line) => {
|
||||
if (line.toLowerCase().substring(0, 6) === "commit") {
|
||||
changes.push({
|
||||
commit: line.substring(6).trim(),
|
||||
date: null,
|
||||
body: ""
|
||||
});
|
||||
}
|
||||
else if (line.toLowerCase().substring(0, 5) === "date:") {
|
||||
changes[changes.length - 1].date = utils_1.getDateTime(new Date(line.substring(5).trim()));
|
||||
}
|
||||
else if (line.substring(0, 1) === " ") {
|
||||
line = line.trim();
|
||||
if (line === "") {
|
||||
return;
|
||||
}
|
||||
changes[changes.length - 1].body += line + " ";
|
||||
}
|
||||
});
|
||||
const output = [];
|
||||
for (let i = 0; i < firstLine; i++) {
|
||||
output.push(lines[i]);
|
||||
}
|
||||
const newTitle = `ethers/v${version} (${utils_1.getDateTime(new Date())})`;
|
||||
output.push(newTitle);
|
||||
output.push(utils_1.repeat("-", newTitle.length));
|
||||
output.push("");
|
||||
changes.forEach((change) => {
|
||||
let body = change.body.trim();
|
||||
let linkMatch = body.match(/(\((.*#.*)\))/);
|
||||
let commit = `[${change.commit.substring(0, 7)}](https://github.com/ethers-io/ethers.js/commit/${change.commit})`;
|
||||
let link = commit;
|
||||
if (linkMatch) {
|
||||
body = body.replace(/ *(\(.*#.*)\) */, "");
|
||||
link = linkMatch[2].replace(/#([0-9]+)/g, (all, issue) => {
|
||||
return `[#${issue}](https://github.com/ethers-io/ethers.js/issues/${issue})`;
|
||||
}) + "; " + commit;
|
||||
}
|
||||
output.push(` - ${body} (${link})`);
|
||||
});
|
||||
output.push("");
|
||||
for (let i = firstLine; i < lines.length; i++) {
|
||||
output.push(lines[i]);
|
||||
}
|
||||
return output.join("\n");
|
||||
});
|
||||
}
|
||||
exports.generate = generate;
|
||||
1
misc/admin/lib/cmds/bump-versions.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/bump-versions.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
81
misc/admin/lib/cmds/bump-versions.js
Normal file
81
misc/admin/lib/cmds/bump-versions.js
Normal file
@@ -0,0 +1,81 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const semver_1 = __importDefault(require("semver"));
|
||||
const path_1 = require("../path");
|
||||
const local = __importStar(require("../local"));
|
||||
const log_1 = require("../log");
|
||||
const npm = __importStar(require("../npm"));
|
||||
const utils_1 = require("../utils");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const progress = log_1.getProgressBar(log_1.colorify.bold("Bumping package.json versions"));
|
||||
const latestVersions = {};
|
||||
let updated = false;
|
||||
const output = [];
|
||||
// For each package, detect diff between tarball and remote
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
progress(i / path_1.dirnames.length);
|
||||
const dirname = path_1.dirnames[i];
|
||||
const pLocal = local.getPackage(dirname);
|
||||
const pNpm = yield npm.getPackage(dirname);
|
||||
const tarballHash = local.computeTarballHash(dirname);
|
||||
let version = pNpm.version;
|
||||
if (tarballHash !== pNpm.tarballHash) {
|
||||
version = semver_1.default.inc(version, "patch");
|
||||
output.push([
|
||||
" ",
|
||||
log_1.colorify.blue(pLocal.name),
|
||||
utils_1.repeat(" ", 47 - pLocal.name.length - pNpm.version.length),
|
||||
pNpm.version,
|
||||
log_1.colorify.bold(" => "),
|
||||
log_1.colorify.green(version)
|
||||
].join(""));
|
||||
local.updateJson(path_1.getPackageJsonPath(dirname), { gitHead: undefined, tarballHash, version }, true);
|
||||
updated = true;
|
||||
}
|
||||
latestVersions[pLocal.name] = version;
|
||||
// Write out the _version.ts
|
||||
if (!pLocal._ethers_nobuild) {
|
||||
const code = "export const version = " + JSON.stringify(dirname + "/" + pLocal.version) + ";\n";
|
||||
fs_1.default.writeFileSync(path_1.resolve(path_1.getPackagePath(dirname), "src.ts/_version.ts"), code);
|
||||
}
|
||||
}
|
||||
progress(1);
|
||||
if (updated) {
|
||||
const filename = path_1.resolve("packages/ethers/package.json");
|
||||
const info = utils_1.loadJson(filename);
|
||||
Object.keys(info.dependencies).forEach((name) => {
|
||||
const version = latestVersions[name];
|
||||
if (name == null) {
|
||||
return;
|
||||
}
|
||||
info.dependencies[name] = version;
|
||||
});
|
||||
utils_1.saveJson(filename, info);
|
||||
}
|
||||
output.forEach((line) => { console.log(line); });
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/echo.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/echo.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
4
misc/admin/lib/cmds/echo.js
Normal file
4
misc/admin/lib/cmds/echo.js
Normal file
@@ -0,0 +1,4 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const log_1 = require("../log");
|
||||
console.log(log_1.colorify.bold(process.argv[2] || "no message"));
|
||||
1
misc/admin/lib/cmds/hoist.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/hoist.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
26
misc/admin/lib/cmds/hoist.js
Normal file
26
misc/admin/lib/cmds/hoist.js
Normal file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path_1 = require("../path");
|
||||
const local_1 = require("../local");
|
||||
const log_1 = require("../log");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const dependencies = local_1.getDependencies(null, (name) => {
|
||||
return !path_1.isEthers(name);
|
||||
});
|
||||
console.log(log_1.colorify.bold(`Hoisting ${Object.keys(dependencies).length} dependencies into root package...`));
|
||||
local_1.updateJson(path_1.dirs.rootPackageJsonPath, { dependencies });
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/link.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/link.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
65
misc/admin/lib/cmds/link.js
Normal file
65
misc/admin/lib/cmds/link.js
Normal file
@@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("path");
|
||||
const local_1 = require("../local");
|
||||
const log_1 = require("../log");
|
||||
const path_2 = require("../path");
|
||||
const utils_1 = require("../utils");
|
||||
function link(existing, path) {
|
||||
try {
|
||||
const current = fs_1.default.readlinkSync(path);
|
||||
// Alerady linked
|
||||
if (current === existing) {
|
||||
return;
|
||||
}
|
||||
fs_1.default.unlinkSync(path);
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code !== "ENOENT") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
// Link
|
||||
const dir = path_1.dirname(path);
|
||||
utils_1.mkdir(dir);
|
||||
fs_1.default.symlinkSync(existing, path);
|
||||
}
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold(`Linking ${path_2.packages.length} package node_modules rat nests...`));
|
||||
const nodeModulesBase = path_1.resolve(path_2.dirs.root, ".package_node_modules");
|
||||
// Make a symlink in the ROOT/node_mpdules to each package in this repo
|
||||
path_2.packages.forEach((name) => {
|
||||
// e.g. /node_modules/@ethersproject/abi => /packages/abi
|
||||
link(path_2.getPackagePath(name), path_1.resolve(path_2.dirs.root, "node_modules", name));
|
||||
// e.g. /packages/abi/node_modules => /.package_node_modules/abi/
|
||||
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
|
||||
utils_1.mkdir(nodeModules);
|
||||
link(nodeModules, path_1.resolve(path_2.getPackagePath(name), "node_modules"));
|
||||
});
|
||||
path_2.packages.forEach((name) => {
|
||||
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
|
||||
const deps = local_1.getDependencies(name);
|
||||
Object.keys(deps).forEach((name) => {
|
||||
link(path_1.resolve(path_2.dirs.root, "node_modules", name), path_1.resolve(nodeModules, name));
|
||||
});
|
||||
});
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
;
|
||||
1
misc/admin/lib/cmds/npm-skip-node8.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/npm-skip-node8.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare const major: any;
|
||||
@@ -1,15 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
const { major } = require("semver");
|
||||
|
||||
// This should be used like `node npm-skip-node8 || COMMAND`.
|
||||
// - If node 8, this script returns true, skipping COMMAND
|
||||
// - Otherwise, return false, running COMMAND
|
||||
|
||||
if (major(process.version) > 8) {
|
||||
// Node >8; return "false" (wrt to shell scripting)
|
||||
process.exit(1);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Node 8; return "true" (wrt to shell scripting)
|
||||
process.exit(0);
|
||||
}
|
||||
8
misc/admin/lib/cmds/serve-docs.d.ts
vendored
Normal file
8
misc/admin/lib/cmds/serve-docs.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/// <reference types="node" />
|
||||
import { Server } from "http";
|
||||
export declare function getMime(filename: string): string;
|
||||
export declare type Options = {
|
||||
port?: number;
|
||||
redirects?: Record<string, string>;
|
||||
};
|
||||
export declare function start(root: string, options: Options): Server;
|
||||
96
misc/admin/lib/cmds/serve-docs.js
Normal file
96
misc/admin/lib/cmds/serve-docs.js
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const http_1 = require("http");
|
||||
const path_1 = require("path");
|
||||
function getMime(filename) {
|
||||
switch (filename.split('.').pop().toLowerCase()) {
|
||||
case 'css': return 'text/css';
|
||||
case 'doctree': return 'application/x-doctree';
|
||||
case 'eot': return 'application/vnd.ms-fontobject';
|
||||
case 'gif': return 'image/gif';
|
||||
case 'html': return 'text/html';
|
||||
case 'js': return 'application/javascript';
|
||||
case 'jpg': return 'image/jpeg';
|
||||
case 'jpeg': return 'image/jpeg';
|
||||
case 'md': return 'text/markdown';
|
||||
case 'pickle': return 'application/x-pickle';
|
||||
case 'png': return 'image/png';
|
||||
case 'svg': return 'image/svg+xml';
|
||||
case 'ttf': return 'application/x-font-ttf';
|
||||
case 'txt': return 'text/plain';
|
||||
case 'woff': return 'application/font-woff';
|
||||
}
|
||||
console.log('NO MIME', filename);
|
||||
return "application/octet-stream";
|
||||
}
|
||||
exports.getMime = getMime;
|
||||
function start(root, options) {
|
||||
if (root == null) {
|
||||
throw new Error("root required");
|
||||
}
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
if (options.port == null) {
|
||||
options.port = 8000;
|
||||
}
|
||||
root = path_1.resolve(root);
|
||||
const server = http_1.createServer((req, resp) => {
|
||||
// Follow redirects in options
|
||||
if (options.redirects && options.redirects[req.url]) {
|
||||
resp.writeHead(301, { Location: options.redirects[req.url] });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
let filename = path_1.resolve(root, "." + req.url);
|
||||
// Make sure we aren't crawling out of our sandbox
|
||||
if (req.url[0] !== "/" || filename.substring(0, filename.length) !== filename) {
|
||||
resp.writeHead(403);
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stat = fs_1.default.statSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
// Redirect bare directory to its path (i.e. "/foo" => "/foo/")
|
||||
if (req.url[req.url.length - 1] !== "/") {
|
||||
resp.writeHead(301, { Location: req.url + "/" });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
filename += "/index.html";
|
||||
}
|
||||
const content = fs_1.default.readFileSync(filename);
|
||||
resp.writeHead(200, {
|
||||
"Content-Length": content.length,
|
||||
"Content-Type": getMime(filename)
|
||||
});
|
||||
resp.end(content);
|
||||
return;
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
resp.writeHead(404, {});
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
resp.writeHead(500, {});
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
server.listen(options.port, () => {
|
||||
console.log(`Server running on: http://localhost:${options.port}`);
|
||||
});
|
||||
return server;
|
||||
}
|
||||
exports.start = start;
|
||||
start(path_1.resolve(__dirname, "../../docs"), {
|
||||
redirects: {
|
||||
"/": "/v5/"
|
||||
}
|
||||
});
|
||||
1
misc/admin/lib/cmds/set-build-option.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/set-build-option.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
45
misc/admin/lib/cmds/set-build-option.js
Normal file
45
misc/admin/lib/cmds/set-build-option.js
Normal file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const build_1 = require("../build");
|
||||
const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
const utils_1 = require("../utils");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
process.argv.slice(2).forEach((arg) => {
|
||||
console.log(log_1.colorify.bold("Setting Option:"), arg);
|
||||
switch (arg) {
|
||||
case "esm":
|
||||
build_1.setupBuild(true);
|
||||
break;
|
||||
case "cjs":
|
||||
build_1.setupBuild(false);
|
||||
break;
|
||||
// This will remove the browser field entirely, so make sure
|
||||
// to set esm of cjs first as they will restore the browser
|
||||
// field
|
||||
case "browser-lang-all": {
|
||||
const filename = path_1.getPackageJsonPath("wordlists");
|
||||
const info = utils_1.loadJson(filename);
|
||||
delete info.browser;
|
||||
utils_1.saveJson(filename, info, true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown option: ${JSON.stringify(arg)}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/set-config.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/set-config.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
27
misc/admin/lib/cmds/set-config.js
Normal file
27
misc/admin/lib/cmds/set-config.js
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const config_1 = require("../config");
|
||||
const log_1 = require("../log");
|
||||
if (process.argv.length !== 3) {
|
||||
console.log("Usage: set-config KEY");
|
||||
process.exit(1);
|
||||
}
|
||||
const key = process.argv[2];
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const value = yield log_1.getPassword("Value: ");
|
||||
yield config_1.config.set(key, value);
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/spell-check.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/spell-check.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
227
misc/admin/lib/cmds/spell-check.js
Normal file
227
misc/admin/lib/cmds/spell-check.js
Normal file
@@ -0,0 +1,227 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("path");
|
||||
const typescript_1 = __importDefault(require("typescript"));
|
||||
const log_1 = require("../log");
|
||||
const Words = fs_1.default.readFileSync("/usr/share/dict/words").toString().split("\n").reduce((accum, word) => {
|
||||
accum[word.toLowerCase()] = true;
|
||||
return accum;
|
||||
}, {});
|
||||
`
|
||||
// Words missing from the dictionary
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email enabled encoded encoding encrypt
|
||||
encrypted encrypting entries euro exceeded existing expected
|
||||
expired failed fetches formatted formatting funding generated
|
||||
hardened has highly ignoring implemented implementer imported including instantiate
|
||||
joined keyword labelled larger lookup matches mined modified modifies multi
|
||||
named needed nested neutered numeric offline optimizer overriding owned packed
|
||||
padded parsed parsing passed placeholder processing properties prototyping reached
|
||||
recommended recovered redacted remaining replaced required
|
||||
serializes shared signed signing skipped stored supported tagging targetted
|
||||
throttled transactions uninstall unstake unsubscribe using verifies website
|
||||
|
||||
// Overly Specific Words
|
||||
bech BIP BIP39 BIP44 btc bzz crypto eip etc hashes hmac icap
|
||||
keccak ltc namehash ripemd RLP scrypt secp sha xdai
|
||||
|
||||
blockhash
|
||||
|
||||
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
|
||||
|
||||
crowdsale hexlify hd hdnode underpriced
|
||||
|
||||
boolean int struct tuple uint
|
||||
nonpayable
|
||||
jumpdest mstore shr shl xor
|
||||
|
||||
// Classes
|
||||
ABIEncoder testcase numberish Wordlist
|
||||
|
||||
// Common Code Strings
|
||||
abi addr api app arg arrayify asm basex bigint bignumber bn byte
|
||||
bytecode callback calldata checksum ciphertext cli codepoint commify config
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof ethaddr
|
||||
ethseed ethers eval exec filename func gz hid http https hw iv
|
||||
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
||||
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||
pragma pre prf repl rpc sighash topichash solc stdin stdout subclasses
|
||||
subnode timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||
wikipedia wx xe xpriv xpub xx yyyy zlib
|
||||
|
||||
// AbiV2
|
||||
abiv
|
||||
|
||||
// Query parameters
|
||||
apikey asc endblock startblock
|
||||
|
||||
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby
|
||||
ropsten testnet
|
||||
|
||||
// Demo words
|
||||
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
|
||||
|
||||
// nameprep tags
|
||||
ALCat BiDi LCat nameprep
|
||||
|
||||
// Lanauge Codes (and short binary data)
|
||||
cn cz en es fr it ja tw zh zh_cn zh_tw
|
||||
OYAa IJBEJqXZJ
|
||||
|
||||
`.split("\n").filter((l) => (l.substring(0, 2) != "/\/")).join("\n").split(/\s+/g).forEach((word) => {
|
||||
word = word.trim();
|
||||
if (word === "") {
|
||||
return;
|
||||
}
|
||||
Words[word.toLowerCase()] = true;
|
||||
});
|
||||
function getStrings(source) {
|
||||
const sourceFile = typescript_1.default.createSourceFile("filename.ts", source, typescript_1.default.ScriptTarget.Latest);
|
||||
const result = [];
|
||||
function add(value, pos) {
|
||||
const lineNo = sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
|
||||
result.push({ value, lineNo });
|
||||
}
|
||||
//let lastClass = null, lastEnum = null;
|
||||
function visit(node, depth) {
|
||||
switch (node.kind) {
|
||||
//case ts.SyntaxKind.TemplateExpression:
|
||||
// if (node.head) { visit(node.head); }
|
||||
// console.dir(node, { depth: null });
|
||||
// break;
|
||||
case typescript_1.default.SyntaxKind.TemplateHead:
|
||||
case typescript_1.default.SyntaxKind.TemplateMiddle:
|
||||
case typescript_1.default.SyntaxKind.TemplateTail:
|
||||
case typescript_1.default.SyntaxKind.StringLiteral:
|
||||
case typescript_1.default.SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
add(node.text, node.pos);
|
||||
break;
|
||||
}
|
||||
typescript_1.default.forEachChild(node, (node) => { return visit(node, depth + 1); });
|
||||
}
|
||||
visit(sourceFile, 0);
|
||||
return result;
|
||||
}
|
||||
const Include = new RegExp("packages/.*/src.ts/.*\.ts$");
|
||||
const Exclude = new RegExp("/node_modules/|src.ts/.*browser.*");
|
||||
function getAllStrings(path) {
|
||||
const Root = path_1.resolve(__dirname, path);
|
||||
const readdir = function (path) {
|
||||
if (path.match(Exclude)) {
|
||||
return [];
|
||||
}
|
||||
const stat = fs_1.default.statSync(path);
|
||||
if (stat.isDirectory()) {
|
||||
return fs_1.default.readdirSync(path).reduce((result, filename) => {
|
||||
readdir(path_1.resolve(path, filename)).forEach((file) => {
|
||||
result.push(file);
|
||||
});
|
||||
return result;
|
||||
}, []);
|
||||
}
|
||||
if (path.match(Include)) {
|
||||
const source = fs_1.default.readFileSync(path).toString();
|
||||
return [{ filename: path.substring(Root.length), values: getStrings(source) }];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
return readdir(Root);
|
||||
}
|
||||
function checkWord(word) {
|
||||
word = word.toLowerCase();
|
||||
// A word
|
||||
if (Words[word]) {
|
||||
return true;
|
||||
}
|
||||
// Simple Plural
|
||||
if (word.match(/.*s$/) && Words[word.substring(0, word.length - 1)]) {
|
||||
return true;
|
||||
}
|
||||
// Hex string
|
||||
if (word.match(/^(0x)?[0-9a-f]*$/i)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function starts(text, prefix) {
|
||||
return (text.substring(0, prefix.length) === prefix);
|
||||
}
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold("Spell checking source code strings..."));
|
||||
let count = 0;
|
||||
getAllStrings(path_1.resolve(__dirname, "../../../../packages")).forEach((file) => {
|
||||
if (starts(file.filename, "/testcases/src.ts/generation-scripts")) {
|
||||
return;
|
||||
}
|
||||
if (starts(file.filename, "/asm/src.ts/opcodes.ts")) {
|
||||
return;
|
||||
}
|
||||
file.values.forEach((entry) => {
|
||||
function problem(word) {
|
||||
count++;
|
||||
console.log({
|
||||
filename: file.filename,
|
||||
word: JSON.stringify(word),
|
||||
sentence: JSON.stringify(entry.value.substring(0, 80)),
|
||||
line: entry.lineNo
|
||||
});
|
||||
}
|
||||
const value = entry.value.trim();
|
||||
// Emptry space
|
||||
if (value === "") {
|
||||
return;
|
||||
}
|
||||
// Prolly a require
|
||||
if (value.match(/^@ethersproject\/[a-z0-9-]+$/)) {
|
||||
return;
|
||||
}
|
||||
if (value.substring(0, 2) === "./") {
|
||||
return;
|
||||
}
|
||||
// Prolly encoded binary data
|
||||
if (value.indexOf(" ") === -1 && value.length > 20) {
|
||||
return;
|
||||
}
|
||||
if (checkWord(value)) {
|
||||
return;
|
||||
}
|
||||
value.replace(/([a-z+])([A-Z])/g, (all, first, secondLetter) => {
|
||||
return first + " " + secondLetter;
|
||||
}).replace(/((?:0x)?[A-Za-z]+)/gi, (all, word) => {
|
||||
if (checkWord(word)) {
|
||||
return "";
|
||||
}
|
||||
problem(word);
|
||||
return "";
|
||||
});
|
||||
;
|
||||
});
|
||||
});
|
||||
if (count) {
|
||||
console.log(`Found ${count} typos.`);
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/update-changelog.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/update-changelog.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
24
misc/admin/lib/cmds/update-changelog.js
Normal file
24
misc/admin/lib/cmds/update-changelog.js
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const changelog_1 = require("../changelog");
|
||||
const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold("Updating CHANGELOG.md..."));
|
||||
fs_1.default.writeFileSync(path_1.resolve("CHANGELOG.md"), yield changelog_1.generate());
|
||||
});
|
||||
})();
|
||||
1
misc/admin/lib/cmds/update-depgraph.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/update-depgraph.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
25
misc/admin/lib/cmds/update-depgraph.js
Normal file
25
misc/admin/lib/cmds/update-depgraph.js
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const depgraph_1 = require("../depgraph");
|
||||
const path_1 = require("../path");
|
||||
const local_1 = require("../local");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const ordered = depgraph_1.getOrdered(true);
|
||||
local_1.updateJson(path_1.resolve("tsconfig.project.json"), {
|
||||
references: ordered.map((name) => ({ path: ("./packages/" + name) }))
|
||||
});
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
1
misc/admin/lib/cmds/update-exports.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/update-exports.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
38
misc/admin/lib/cmds/update-exports.js
Normal file
38
misc/admin/lib/cmds/update-exports.js
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
const sourceEthers = fs_1.default.readFileSync(path_1.resolve("packages/ethers/src.ts/ethers.ts")).toString();
|
||||
const targets = sourceEthers.match(/export\s*{\s*((.|\s)*)}/)[1].trim();
|
||||
////////////////////
|
||||
// Begin template
|
||||
////////////////////
|
||||
const output = `"use strict";
|
||||
|
||||
// To modify this file, you must update ./misc/admin/lib/cmds/update-exports.js
|
||||
|
||||
import * as ethers from "./ethers";
|
||||
|
||||
try {
|
||||
const anyGlobal = (window as any);
|
||||
|
||||
if (anyGlobal._ethers == null) {
|
||||
anyGlobal._ethers = ethers;
|
||||
}
|
||||
} catch (error) { }
|
||||
|
||||
export { ethers };
|
||||
|
||||
export {
|
||||
${targets}
|
||||
} from "./ethers";
|
||||
`;
|
||||
////////////////////
|
||||
// End template
|
||||
////////////////////
|
||||
console.log(log_1.colorify.bold(`Flattening exports...`));
|
||||
fs_1.default.writeFileSync(path_1.resolve("packages/ethers/src.ts/index.ts"), output);
|
||||
1
misc/admin/lib/cmds/update-hashes.d.ts
vendored
Normal file
1
misc/admin/lib/cmds/update-hashes.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
33
misc/admin/lib/cmds/update-hashes.js
Normal file
33
misc/admin/lib/cmds/update-hashes.js
Normal file
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//import { getGitTag } from "../git";
|
||||
const local_1 = require("../local");
|
||||
const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const progress = log_1.getProgressBar(log_1.colorify.bold("Updating package.json hashes"));
|
||||
// Updating all tarball hashes now that versions have been updated
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
progress(i / path_1.dirnames.length);
|
||||
const dirname = path_1.dirnames[i];
|
||||
//const gitHead = await getGitTag(resolve("packages", dirname));
|
||||
const tarballHash = local_1.computeTarballHash(dirname);
|
||||
local_1.updateJson(path_1.getPackageJsonPath(dirname), { tarballHash }, true);
|
||||
}
|
||||
progress(1);
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
;
|
||||
6
misc/admin/lib/config.d.ts
vendored
Normal file
6
misc/admin/lib/config.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export declare const config: {
|
||||
get: (key: string) => Promise<string>;
|
||||
set: (key: string, value: string) => void;
|
||||
keys: () => Promise<string[]>;
|
||||
lock: () => void;
|
||||
};
|
||||
129
misc/admin/lib/config.js
Normal file
129
misc/admin/lib/config.js
Normal file
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const crypto_1 = require("crypto");
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const os_1 = __importDefault(require("os"));
|
||||
const path_1 = require("path");
|
||||
const aes_js_1 = __importDefault(require("aes-js"));
|
||||
const scrypt_js_1 = __importDefault(require("scrypt-js"));
|
||||
const log_1 = require("./log");
|
||||
function getRandomBytes(length) {
|
||||
const result = new Uint8Array(length);
|
||||
result.set(crypto_1.randomBytes(length));
|
||||
return result;
|
||||
}
|
||||
function computeHmac(key, data) {
|
||||
return "0x" + crypto_1.createHmac("sha512", key).update(data).digest("hex");
|
||||
}
|
||||
function getScrypt(message, password, salt) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const progress = log_1.getProgressBar(message);
|
||||
return yield scrypt_js_1.default.scrypt(Buffer.from(password), Buffer.from(salt), (1 << 17), 8, 1, 64, progress);
|
||||
});
|
||||
}
|
||||
class Config {
|
||||
constructor(filename) {
|
||||
this.salt = null;
|
||||
this.dkey = null;
|
||||
this.values = {};
|
||||
this.canary = "";
|
||||
this.filename = filename;
|
||||
}
|
||||
load() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.dkey) {
|
||||
return;
|
||||
}
|
||||
let data = null;
|
||||
if (fs_1.default.existsSync(this.filename)) {
|
||||
data = JSON.parse(fs_1.default.readFileSync(this.filename).toString());
|
||||
}
|
||||
else {
|
||||
data = {
|
||||
salt: Buffer.from(getRandomBytes(32)).toString("hex")
|
||||
};
|
||||
}
|
||||
this.canary = data.canary || "";
|
||||
this.salt = data.salt;
|
||||
const password = yield log_1.getPassword(log_1.colorify.bold("Password (config-store): "));
|
||||
this.dkey = yield getScrypt(log_1.colorify.bold("Unlocking config"), password, this.salt);
|
||||
if (data.ciphertext) {
|
||||
const ciphertext = Buffer.from(data.ciphertext, "base64");
|
||||
const iv = Buffer.from(data.iv, "base64");
|
||||
const aes = new aes_js_1.default.ModeOfOperation.ctr(this.dkey.slice(0, 32), new aes_js_1.default.Counter(iv));
|
||||
const plaintext = aes.decrypt(ciphertext);
|
||||
const hmac = computeHmac(this.dkey.slice(32, 64), plaintext);
|
||||
if (hmac !== data.hmac) {
|
||||
console.log(log_1.colorify.red("Incorrect password."));
|
||||
throw new Error("wrong password");
|
||||
}
|
||||
this.values = JSON.parse(Buffer.from(plaintext).toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
keys() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.load();
|
||||
return Object.keys(this.values);
|
||||
});
|
||||
}
|
||||
save() {
|
||||
this.values._junk = Buffer.from(getRandomBytes(16 + Math.floor(Math.random() * 48))).toString("base64");
|
||||
const plaintext = Buffer.from(JSON.stringify(this.values));
|
||||
const iv = Buffer.from(getRandomBytes(16));
|
||||
const hmac = computeHmac(this.dkey.slice(32, 64), plaintext);
|
||||
const aes = new aes_js_1.default.ModeOfOperation.ctr(this.dkey.slice(0, 32), new aes_js_1.default.Counter(iv));
|
||||
const ciphertext = Buffer.from(aes.encrypt(plaintext));
|
||||
const data = {
|
||||
ciphertext: ciphertext.toString("base64"),
|
||||
iv: iv.toString("base64"),
|
||||
salt: this.salt,
|
||||
hmac: hmac,
|
||||
canary: this.canary
|
||||
};
|
||||
fs_1.default.writeFileSync(this.filename, JSON.stringify(data, null, 2));
|
||||
}
|
||||
get(key) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.load();
|
||||
return this.values[key];
|
||||
});
|
||||
}
|
||||
set(key, value) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.load();
|
||||
this.values[key] = value;
|
||||
this.save();
|
||||
});
|
||||
}
|
||||
lock() {
|
||||
this.salt = this.dkey = null;
|
||||
}
|
||||
}
|
||||
const _config = new Config(path_1.resolve(os_1.default.homedir(), ".ethers-dist"));
|
||||
exports.config = {
|
||||
get: function (key) {
|
||||
return _config.get(key);
|
||||
},
|
||||
set: function (key, value) {
|
||||
_config.set(key, value);
|
||||
},
|
||||
keys: function () {
|
||||
return _config.keys();
|
||||
},
|
||||
lock: function () {
|
||||
_config.lock();
|
||||
}
|
||||
};
|
||||
2
misc/admin/lib/depgraph.d.ts
vendored
Normal file
2
misc/admin/lib/depgraph.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export declare function getOrdered(skipNobuild?: boolean): Array<string>;
|
||||
export declare function sort(dirnames: Array<string>): void;
|
||||
101
misc/admin/lib/depgraph.js
Normal file
101
misc/admin/lib/depgraph.js
Normal file
@@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path_1 = require("./path");
|
||||
const local_1 = require("./local");
|
||||
class OrderedSet {
|
||||
constructor() {
|
||||
this._keys = [];
|
||||
this._values = {};
|
||||
}
|
||||
add(key) {
|
||||
this._values[key] = true;
|
||||
this._keys = null;
|
||||
}
|
||||
contains(key) {
|
||||
return !!this._values[key];
|
||||
}
|
||||
_sort() {
|
||||
if (this._keys != null) {
|
||||
return;
|
||||
}
|
||||
this._keys = Object.keys(this._values);
|
||||
this._keys.sort();
|
||||
}
|
||||
get length() {
|
||||
this._sort();
|
||||
return this._keys.length;
|
||||
}
|
||||
get(index) {
|
||||
this._sort();
|
||||
return this._keys[index];
|
||||
}
|
||||
}
|
||||
function getOrdered(skipNobuild) {
|
||||
const packages = {};
|
||||
const filenames = {};
|
||||
// Maps packages to names to list of dependencies; { [ name:string]: Array<name: string> }
|
||||
const deps = {};
|
||||
let addDeps = (name, depends) => {
|
||||
Object.keys(depends).forEach((dep) => {
|
||||
// Not a package we manage
|
||||
if (packages[dep] == null) {
|
||||
return;
|
||||
}
|
||||
deps[name].add(dep);
|
||||
});
|
||||
};
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
let dirname = path_1.dirnames[i];
|
||||
let info = local_1.getPackage(dirname);
|
||||
if (skipNobuild && info._ethers_nobuild) {
|
||||
continue;
|
||||
}
|
||||
packages[info.name] = info;
|
||||
filenames[info.name] = dirname;
|
||||
}
|
||||
Object.keys(packages).forEach((name) => {
|
||||
let info = packages[name];
|
||||
deps[info.name] = new OrderedSet();
|
||||
addDeps(info.name, info.dependencies || {});
|
||||
addDeps(info.name, info.devDependencies || {});
|
||||
});
|
||||
let ordered = [];
|
||||
let remaining = Object.keys(deps);
|
||||
let isSatisfied = (name) => {
|
||||
for (let i = 0; i < deps[name].length; i++) {
|
||||
if (ordered.indexOf(deps[name].get(i)) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
while (remaining.length) {
|
||||
let bail = true;
|
||||
for (let i = 0; i < remaining.length; i++) {
|
||||
if (!isSatisfied(remaining[i])) {
|
||||
continue;
|
||||
}
|
||||
bail = false;
|
||||
ordered.push(remaining[i]);
|
||||
remaining.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
if (bail) {
|
||||
throw new Error("Nothing processed; circular dependencies...");
|
||||
}
|
||||
}
|
||||
return ordered.map((name) => filenames[name]);
|
||||
}
|
||||
exports.getOrdered = getOrdered;
|
||||
function sort(dirnames) {
|
||||
let ordered = getOrdered();
|
||||
dirnames.sort((a, b) => {
|
||||
let ai = ordered.indexOf(local_1.getPackage(a).name);
|
||||
let bi = ordered.indexOf(local_1.getPackage(b).name);
|
||||
if (ai === -1 || bi === -1) {
|
||||
throw new Error("unknown dirname - " + [a, b].join(", "));
|
||||
}
|
||||
return ai - bi;
|
||||
});
|
||||
}
|
||||
exports.sort = sort;
|
||||
16
misc/admin/lib/geturl.d.ts
vendored
Normal file
16
misc/admin/lib/geturl.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export declare type GetUrlResponse = {
|
||||
statusCode: number;
|
||||
statusMessage: string;
|
||||
headers: {
|
||||
[key: string]: string;
|
||||
};
|
||||
body: Uint8Array;
|
||||
};
|
||||
export declare type Options = {
|
||||
method?: string;
|
||||
body?: Uint8Array;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
export declare function getUrl(href: string, options?: Options): Promise<GetUrlResponse>;
|
||||
100
misc/admin/lib/geturl.js
Normal file
100
misc/admin/lib/geturl.js
Normal file
@@ -0,0 +1,100 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http_1 = __importDefault(require("http"));
|
||||
const https_1 = __importDefault(require("https"));
|
||||
const url_1 = require("url");
|
||||
function getResponse(request) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.once("response", (resp) => {
|
||||
const response = {
|
||||
statusCode: resp.statusCode,
|
||||
statusMessage: resp.statusMessage,
|
||||
headers: Object.keys(resp.headers).reduce((accum, name) => {
|
||||
let value = resp.headers[name];
|
||||
if (Array.isArray(value)) {
|
||||
value = value.join(", ");
|
||||
}
|
||||
accum[name] = value;
|
||||
return accum;
|
||||
}, {}),
|
||||
body: null
|
||||
};
|
||||
//resp.setEncoding("utf8");
|
||||
resp.on("data", (chunk) => {
|
||||
if (response.body == null) {
|
||||
response.body = new Uint8Array(0);
|
||||
}
|
||||
const body = new Uint8Array(response.body.length + chunk.length);
|
||||
body.set(response.body, 0);
|
||||
body.set(chunk, response.body.length);
|
||||
response.body = body;
|
||||
});
|
||||
resp.on("end", () => {
|
||||
resolve(response);
|
||||
});
|
||||
resp.on("error", (error) => {
|
||||
/* istanbul ignore next */
|
||||
error.response = response;
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
request.on("error", (error) => { reject(error); });
|
||||
});
|
||||
}
|
||||
// The URL.parse uses null instead of the empty string
|
||||
function nonnull(value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getUrl(href, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = url_1.parse(href);
|
||||
const request = {
|
||||
protocol: nonnull(url.protocol),
|
||||
hostname: nonnull(url.hostname),
|
||||
port: nonnull(url.port),
|
||||
path: (nonnull(url.pathname) + nonnull(url.search)),
|
||||
method: (options.method || "GET"),
|
||||
headers: (options.headers || {}),
|
||||
};
|
||||
let req = null;
|
||||
switch (nonnull(url.protocol)) {
|
||||
case "http:":
|
||||
req = http_1.default.request(request);
|
||||
break;
|
||||
case "https:":
|
||||
req = https_1.default.request(request);
|
||||
break;
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`unsupported protocol ${url.protocol}`);
|
||||
}
|
||||
if (options.body) {
|
||||
req.write(Buffer.from(options.body));
|
||||
}
|
||||
req.end();
|
||||
const response = yield getResponse(req);
|
||||
return response;
|
||||
});
|
||||
}
|
||||
exports.getUrl = getUrl;
|
||||
1
misc/admin/lib/git.d.ts
vendored
Normal file
1
misc/admin/lib/git.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function getGitTag(filename: string): Promise<string>;
|
||||
32
misc/admin/lib/git.js
Normal file
32
misc/admin/lib/git.js
Normal file
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const run_1 = require("./run");
|
||||
// Returns the most recent git commit hash for a given filename
|
||||
function getGitTag(filename) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = yield run_1.run("git", ["log", "-n", "1", "--", filename]);
|
||||
if (!result.ok) {
|
||||
throw new Error(`git log error`);
|
||||
}
|
||||
let log = result.stdout.trim();
|
||||
if (!log) {
|
||||
return null;
|
||||
}
|
||||
const hashMatch = log.match(/^commit\s+([0-9a-f]{40})\n/i);
|
||||
if (!hashMatch) {
|
||||
return null;
|
||||
}
|
||||
return hashMatch[1];
|
||||
});
|
||||
}
|
||||
exports.getGitTag = getGitTag;
|
||||
//getGitTag("/Users/ricmoo/Development/ethers/ethers.js/packages/abi").then(console.log);
|
||||
19
misc/admin/lib/local.d.ts
vendored
Normal file
19
misc/admin/lib/local.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
export declare type Package = {
|
||||
dependencies: {
|
||||
[name: string]: string;
|
||||
};
|
||||
devDependencies: {
|
||||
[name: string]: string;
|
||||
};
|
||||
gitHead: string;
|
||||
name: string;
|
||||
version: string;
|
||||
tarballHash: string;
|
||||
location: "remote" | "local";
|
||||
_ethers_nobuild: boolean;
|
||||
};
|
||||
export declare function getPackage(name: string): Package;
|
||||
export declare function updateJson(path: string, replace: Record<string, any>, sort?: boolean): void;
|
||||
export declare function getDependencies(name?: string, filter?: (name: string) => boolean): Record<string, string>;
|
||||
export declare function getPackList(name: string): Array<string>;
|
||||
export declare function computeTarballHash(name: string): string;
|
||||
137
misc/admin/lib/local.js
Normal file
137
misc/admin/lib/local.js
Normal file
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("./path");
|
||||
const run_1 = require("./run");
|
||||
const utils_1 = require("./utils");
|
||||
function getPackage(name) {
|
||||
const value = utils_1.loadJson(path_1.getPackageJsonPath(name));
|
||||
return {
|
||||
name: value.name,
|
||||
version: value.version,
|
||||
dependencies: (value.dependencies || {}),
|
||||
devDependencies: (value.dependencies || {}),
|
||||
location: "local",
|
||||
tarballHash: (value.tarballHash || null),
|
||||
gitHead: (value.gitHead || null),
|
||||
_ethers_nobuild: !!value._ethers_nobuild,
|
||||
};
|
||||
}
|
||||
exports.getPackage = getPackage;
|
||||
function updateJson(path, replace, sort) {
|
||||
const values = utils_1.loadJson(path);
|
||||
Object.keys(replace).forEach((key) => {
|
||||
const value = replace[key];
|
||||
if (value === undefined) {
|
||||
delete values[key];
|
||||
}
|
||||
else {
|
||||
values[key] = replace[key];
|
||||
}
|
||||
});
|
||||
utils_1.saveJson(path, values, !!sort);
|
||||
}
|
||||
exports.updateJson = updateJson;
|
||||
function getDependencies(name, filter) {
|
||||
if (name) {
|
||||
return utils_1.sortRecords(getPackage(name).dependencies);
|
||||
}
|
||||
// Find all versions for each package dependency
|
||||
const deps = path_1.dirnames.reduce((accum, dirname) => {
|
||||
const deps = getPackage(dirname).dependencies;
|
||||
Object.keys(deps).forEach((name) => {
|
||||
if (filter && !filter(name)) {
|
||||
return;
|
||||
}
|
||||
if (!accum[name]) {
|
||||
accum[name] = {};
|
||||
}
|
||||
accum[name][deps[name]] = true;
|
||||
});
|
||||
return accum;
|
||||
}, {});
|
||||
// Make sure each package dependency only has 1 version
|
||||
return utils_1.sortRecords(Object.keys(deps).reduce((accum, name) => {
|
||||
const versions = Object.keys(deps[name]);
|
||||
if (versions.length > 1) {
|
||||
throw new Error(`cannot depend on multiple versions for ${JSON.stringify(name)}: ${versions.map(v => JSON.stringify(v)).join(", ")}`);
|
||||
}
|
||||
accum[name] = versions[0];
|
||||
return accum;
|
||||
}, {}));
|
||||
}
|
||||
exports.getDependencies = getDependencies;
|
||||
function getPackList(name) {
|
||||
const result = run_1.run("npm", ["pack", "--json", path_1.getPackagePath(name), "--dry-run"]);
|
||||
if (!result.ok) {
|
||||
const error = new Error(`failed to run npm pack: ${name}`);
|
||||
error.result = result;
|
||||
throw error;
|
||||
}
|
||||
return JSON.parse(result.stdout)[0].files.map((info) => info.path);
|
||||
}
|
||||
exports.getPackList = getPackList;
|
||||
/*
|
||||
export function getTarball(name: string): Buffer {
|
||||
const files = getPackList(name).map((name) => `./${ name }`);
|
||||
files.sort((a, b) => {
|
||||
|
||||
const compsA = a.split("/"), compsB = b.split("/");
|
||||
while (true) {
|
||||
const a = compsA.shift(), b = compsB.shift();
|
||||
if (a === b) { continue; }
|
||||
|
||||
if (compsA.length === 0 && compsB.length === 0) {
|
||||
if (a < b) { return -1; }
|
||||
if (a > b) { return 1; }
|
||||
break;
|
||||
}
|
||||
|
||||
if (compsA.length === 0) { return -1; }
|
||||
if (compsB.length === 0) { return 1; }
|
||||
|
||||
if (a < b) { return -1; }
|
||||
if (a > b) { return 1; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return tar.create({
|
||||
sync: true,
|
||||
cwd: getPackagePath(name),
|
||||
prefix: "package/",
|
||||
gzip: true,
|
||||
portable: true,
|
||||
// Provide a specific date in the 1980s for the benefit of zip,
|
||||
// which is confounded by files dated at the Unix epoch 0.
|
||||
mtime: new Date('1985-10-26T08:15:00.000Z'),
|
||||
}, files).read();
|
||||
}
|
||||
*/
|
||||
function computeTarballHash(name) {
|
||||
// Sort the files to get a consistent hash
|
||||
const files = getPackList(name);
|
||||
files.sort();
|
||||
// Compute the hash for each file
|
||||
const packageRoot = path_1.getPackagePath(name);
|
||||
const hashes = files.reduce((accum, filename) => {
|
||||
let content = fs_1.default.readFileSync(path_1.resolve(packageRoot, filename));
|
||||
// The package.json includes the hash, so we need to nix it to get a consistent hash
|
||||
if (filename === "package.json") {
|
||||
const info = JSON.parse(content.toString());
|
||||
delete info.gitHead;
|
||||
delete info.tarballHash;
|
||||
content = Buffer.from(JSON.stringify(info, null, 2));
|
||||
}
|
||||
accum[filename] = utils_1.sha256(content);
|
||||
return accum;
|
||||
}, {});
|
||||
return utils_1.sha256(Buffer.from("{" + files.map((filename) => {
|
||||
return `${JSON.stringify(filename)}:"${hashes[filename]}"`;
|
||||
}).join(",") + "}"));
|
||||
}
|
||||
exports.computeTarballHash = computeTarballHash;
|
||||
12
misc/admin/lib/log.d.ts
vendored
Normal file
12
misc/admin/lib/log.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export declare function getProgressBar(action: string): (percent: number) => void;
|
||||
export declare type ColorifyFunc = (text: string) => string;
|
||||
export declare const colorify: {
|
||||
[format: string]: ColorifyFunc;
|
||||
};
|
||||
export declare type PromptOptions = {
|
||||
choice?: Array<string>;
|
||||
defaultChoice?: string;
|
||||
mask?: string;
|
||||
};
|
||||
export declare function getPrompt(prompt: string, options: PromptOptions): Promise<string>;
|
||||
export declare function getPassword(prompt: string): Promise<string>;
|
||||
149
misc/admin/lib/log.js
Normal file
149
misc/admin/lib/log.js
Normal file
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("./utils");
|
||||
// See: https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
|
||||
let disableColor = !(process.stdout.isTTY);
|
||||
function getProgressBar(action) {
|
||||
let lastProgress = -1;
|
||||
return function (percent) {
|
||||
const progress = Math.trunc(percent * 100);
|
||||
if (disableColor) {
|
||||
if (lastProgress === -1) {
|
||||
console.log(action + "...");
|
||||
}
|
||||
lastProgress = progress;
|
||||
return;
|
||||
}
|
||||
//process.stdin.setRawMode(false);
|
||||
//process.stdin.pause();
|
||||
if (progress === lastProgress || lastProgress === 100) {
|
||||
return;
|
||||
}
|
||||
lastProgress = progress;
|
||||
(process.stdout).clearLine();
|
||||
(process.stdout).cursorTo(0);
|
||||
process.stdout.write(action + "... " + progress + "%");
|
||||
if (percent === 1) {
|
||||
process.stdout.write('\n');
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
exports.getProgressBar = getProgressBar;
|
||||
const colorSequences = {
|
||||
blue: "\x1b[34m",
|
||||
cyan: "\x1b[36m",
|
||||
green: "\x1b[32m",
|
||||
magenta: "\x1b[35m",
|
||||
red: "\x1b[31m",
|
||||
yellow: "\x1b[33m",
|
||||
bold: ""
|
||||
};
|
||||
function getColor(color) {
|
||||
if (!color || color === "normal") {
|
||||
return "\x1b[0m";
|
||||
}
|
||||
return "\x1b[1m" + colorSequences[color];
|
||||
}
|
||||
function _colorify(format) {
|
||||
return function (text) {
|
||||
if (disableColor) {
|
||||
return text;
|
||||
}
|
||||
return getColor(format) + text.replace(/[^ -~]+/g, "") + getColor();
|
||||
};
|
||||
}
|
||||
exports.colorify = Object.freeze({
|
||||
bold: _colorify("bold"),
|
||||
blue: _colorify("blue"),
|
||||
green: _colorify("green"),
|
||||
red: _colorify("red"),
|
||||
});
|
||||
function _getPrompt(prompt, options, callback) {
|
||||
process.stdout.write(prompt);
|
||||
let stdin = process.stdin;
|
||||
stdin.resume();
|
||||
stdin.setRawMode(true);
|
||||
stdin.resume();
|
||||
stdin.setEncoding('utf8');
|
||||
let message = '';
|
||||
let respond = (ctrlC, message) => {
|
||||
process.stdout.write('\n');
|
||||
stdin.setRawMode(false);
|
||||
stdin.pause();
|
||||
stdin.removeListener('data', handler);
|
||||
callback(ctrlC, message);
|
||||
};
|
||||
function handler(chr) {
|
||||
chr = String(chr);
|
||||
switch (chr) {
|
||||
// Enter (ish)
|
||||
case "\n":
|
||||
case "\r":
|
||||
case "\u0004":
|
||||
if (options.choice) {
|
||||
if (options.defaultChoice) {
|
||||
respond(null, options.defaultChoice);
|
||||
}
|
||||
}
|
||||
else {
|
||||
respond(null, message);
|
||||
}
|
||||
break;
|
||||
// Backspace
|
||||
case "\u007f":
|
||||
if (message.length > 0 && options.choice == null) {
|
||||
message = message.substring(0, message.length - 1);
|
||||
(process.stdout).clearLine();
|
||||
(process.stdout).cursorTo(0);
|
||||
if (options.mask) {
|
||||
process.stdout.write(prompt + utils_1.repeat(options.mask, message.length));
|
||||
}
|
||||
else {
|
||||
process.stdout.write(prompt + message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Ctrl-C
|
||||
case "\u0003":
|
||||
process.stdout.write('\n[ CTRL-C ]');
|
||||
respond(true, null);
|
||||
break;
|
||||
// Any other character
|
||||
default:
|
||||
if (options.choice) {
|
||||
if (options.choice.indexOf(chr) >= 0) {
|
||||
process.stdout.write(chr);
|
||||
respond(null, chr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// More passsword characters
|
||||
if (options.mask) {
|
||||
process.stdout.write('*');
|
||||
}
|
||||
else {
|
||||
process.stdout.write(chr);
|
||||
}
|
||||
message += chr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
stdin.on('data', handler);
|
||||
}
|
||||
function getPrompt(prompt, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
_getPrompt(prompt, options, (ctrlC, password) => {
|
||||
if (ctrlC) {
|
||||
return reject(new Error("cancelled"));
|
||||
}
|
||||
resolve(password);
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getPrompt = getPrompt;
|
||||
function getPassword(prompt) {
|
||||
return getPrompt(prompt, { mask: "*" });
|
||||
}
|
||||
exports.getPassword = getPassword;
|
||||
2
misc/admin/lib/npm.d.ts
vendored
Normal file
2
misc/admin/lib/npm.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { Package } from "./local";
|
||||
export declare function getPackage(name: string, version?: string): Promise<Package>;
|
||||
62
misc/admin/lib/npm.js
Normal file
62
misc/admin/lib/npm.js
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const semver_1 = __importDefault(require("semver"));
|
||||
const geturl_1 = require("./geturl");
|
||||
const local_1 = require("./local");
|
||||
const cache = {};
|
||||
function getPackageInfo(name) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Convert dirname to package if needed
|
||||
name = local_1.getPackage(name).name;
|
||||
if (!cache[name]) {
|
||||
try {
|
||||
const result = yield geturl_1.getUrl("http:/" + "/registry.npmjs.org/" + name);
|
||||
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
|
||||
}
|
||||
catch (error) {
|
||||
if (error.status === 404) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return cache[name] || null;
|
||||
});
|
||||
}
|
||||
function getPackage(name, version) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const infos = yield getPackageInfo(name);
|
||||
if (infos == null) {
|
||||
return null;
|
||||
}
|
||||
if (version == null) {
|
||||
const versions = Object.keys(infos.versions);
|
||||
versions.sort(semver_1.default.compare);
|
||||
version = versions.pop();
|
||||
}
|
||||
const info = infos.versions[version];
|
||||
return {
|
||||
dependencies: (info.dependencies || {}),
|
||||
devDependencies: (info.devDependencies || {}),
|
||||
gitHead: info.gitHead,
|
||||
location: "remote",
|
||||
name: info.name,
|
||||
tarballHash: info.tarballHash,
|
||||
version: info.version,
|
||||
_ethers_nobuild: !!info._ethers_nobuild,
|
||||
};
|
||||
});
|
||||
}
|
||||
exports.getPackage = getPackage;
|
||||
13
misc/admin/lib/path.d.ts
vendored
Normal file
13
misc/admin/lib/path.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export declare const root: string;
|
||||
export declare function resolve(...args: Array<string>): string;
|
||||
export declare const dirs: Readonly<{
|
||||
rootPackageJsonPath: string;
|
||||
packages: string;
|
||||
root: string;
|
||||
}>;
|
||||
export declare const dirnames: ReadonlyArray<string>;
|
||||
export declare const packages: ReadonlyArray<string>;
|
||||
export declare function getPackagePath(name: string): string;
|
||||
export declare function getDirname(name: string): string;
|
||||
export declare function getPackageJsonPath(name: string): string;
|
||||
export declare function isEthers(name: string): boolean;
|
||||
58
misc/admin/lib/path.js
Normal file
58
misc/admin/lib/path.js
Normal file
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("path");
|
||||
exports.root = path_1.resolve(__dirname, "../../../");
|
||||
function resolve(...args) {
|
||||
args.unshift(exports.root);
|
||||
return path_1.resolve.apply(null, args);
|
||||
}
|
||||
exports.resolve = resolve;
|
||||
const pathRootPackageJsonPath = resolve("package.json");
|
||||
const pathPackages = resolve("packages");
|
||||
exports.dirs = Object.freeze({
|
||||
rootPackageJsonPath: pathRootPackageJsonPath,
|
||||
packages: pathPackages,
|
||||
root: exports.root,
|
||||
});
|
||||
exports.dirnames = Object.freeze(fs_1.default.readdirSync(exports.dirs.packages).filter((dirname) => {
|
||||
return (dirname[0] !== ".");
|
||||
}));
|
||||
const packageLookup = exports.dirnames.reduce((accum, dirname) => {
|
||||
const packagePath = path_1.resolve(exports.dirs.packages, dirname);
|
||||
const packageJsonPath = path_1.resolve(packagePath, "package.json");
|
||||
const info = JSON.parse(fs_1.default.readFileSync(packageJsonPath).toString());
|
||||
const packageName = info.name;
|
||||
const version = info.version;
|
||||
accum[packageName] = accum[dirname] = {
|
||||
dirname, packageName, packagePath, packageJsonPath, version
|
||||
};
|
||||
return accum;
|
||||
}, {});
|
||||
exports.packages = Object.freeze(exports.dirnames.map((dirname) => packageLookup[dirname].packageName));
|
||||
function getPackageInfo(name) {
|
||||
const value = packageLookup[name];
|
||||
if (!value) {
|
||||
throw new Error(`unknown package: ${name}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getPackagePath(name) {
|
||||
return getPackageInfo(name).packagePath;
|
||||
}
|
||||
exports.getPackagePath = getPackagePath;
|
||||
function getDirname(name) {
|
||||
return getPackageInfo(name).dirname;
|
||||
}
|
||||
exports.getDirname = getDirname;
|
||||
function getPackageJsonPath(name) {
|
||||
return getPackageInfo(name).packageJsonPath;
|
||||
}
|
||||
exports.getPackageJsonPath = getPackageJsonPath;
|
||||
function isEthers(name) {
|
||||
return !!packageLookup[name];
|
||||
}
|
||||
exports.isEthers = isEthers;
|
||||
10
misc/admin/lib/run.d.ts
vendored
Normal file
10
misc/admin/lib/run.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/// <reference types="node" />
|
||||
export declare type RunResult = {
|
||||
stderr: string | null;
|
||||
_stderr: string | Buffer;
|
||||
stdout: string;
|
||||
_stdout: string | Buffer;
|
||||
status: number;
|
||||
ok: boolean;
|
||||
};
|
||||
export declare function run(progname: string, args?: Array<string>, currentWorkingDirectory?: string): RunResult;
|
||||
64
misc/admin/lib/run.js
Normal file
64
misc/admin/lib/run.js
Normal file
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const child_process_1 = require("child_process");
|
||||
function run(progname, args, currentWorkingDirectory) {
|
||||
if (args == null) {
|
||||
args = [];
|
||||
}
|
||||
const options = {};
|
||||
if (currentWorkingDirectory) {
|
||||
options.cwd = currentWorkingDirectory;
|
||||
}
|
||||
const child = child_process_1.spawnSync(progname, args, options);
|
||||
const result = {
|
||||
_stderr: child.stderr,
|
||||
stderr: (child.stderr.toString() || null),
|
||||
_stdout: child.stdout,
|
||||
stdout: child.stdout.toString(),
|
||||
status: child.status,
|
||||
ok: (child.stderr.length === 0 && child.status === 0)
|
||||
};
|
||||
if (child.error) {
|
||||
(child.error).result = result;
|
||||
throw child.error;
|
||||
}
|
||||
return result;
|
||||
/*
|
||||
const result: RunResult = {
|
||||
stderr: null,
|
||||
_stderr: Buffer.from([]),
|
||||
stdout: null,
|
||||
_stdout: Buffer.from([]),
|
||||
status: null,
|
||||
ok: false,
|
||||
};
|
||||
|
||||
proc.stderr.on("data", (data) => {
|
||||
result._stderr = Buffer.concat([ result._stderr, data ]);
|
||||
});
|
||||
|
||||
proc.stdout.on("data", (data) => {
|
||||
result._stdout = Buffer.concat([ result._stdout, data ]);
|
||||
});
|
||||
|
||||
proc.on("error", (error) => {
|
||||
result.stderr = result._stderr.toString("utf8");
|
||||
result.stdout = result._stdout.toString("utf8");
|
||||
(<any>error).result = result;
|
||||
|
||||
console.log("Error:", error);
|
||||
|
||||
reject(error);
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
result.stderr = result._stderr.toString("utf8");
|
||||
result.stdout = result._stdout.toString("utf8");
|
||||
result.status = code;
|
||||
result.ok = (result._stderr.length === 0 && code === 0);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
*/
|
||||
}
|
||||
exports.run = run;
|
||||
10
misc/admin/lib/utils.d.ts
vendored
Normal file
10
misc/admin/lib/utils.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/// <reference types="node" />
|
||||
export declare function repeat(char: string, length: number): string;
|
||||
export declare function sha256(content: Buffer): string;
|
||||
export declare function sortRecords(record: Record<string, any>): Record<string, any>;
|
||||
export declare function atomicWrite(path: string, value: string | Uint8Array): void;
|
||||
export declare function loadJson(path: string): any;
|
||||
export declare function saveJson(filename: string, data: any, sort?: boolean): any;
|
||||
export declare function resolveProperties(props: Record<string, Promise<any>>): Promise<Record<string, any>>;
|
||||
export declare function mkdir(path: string): void;
|
||||
export declare function getDateTime(date: Date): string;
|
||||
125
misc/admin/lib/utils.js
Normal file
125
misc/admin/lib/utils.js
Normal file
@@ -0,0 +1,125 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("path");
|
||||
const crypto_1 = require("crypto");
|
||||
function repeat(char, length) {
|
||||
if (char.length === 0) {
|
||||
return "";
|
||||
}
|
||||
let output = char;
|
||||
while (output.length < length) {
|
||||
output = output + output;
|
||||
}
|
||||
return output.substring(0, length);
|
||||
}
|
||||
exports.repeat = repeat;
|
||||
function sha256(content) {
|
||||
const hasher = crypto_1.createHash("sha256");
|
||||
hasher.update(content);
|
||||
return "0x" + hasher.digest("hex");
|
||||
}
|
||||
exports.sha256 = sha256;
|
||||
function sortRecords(record) {
|
||||
const keys = Object.keys(record);
|
||||
keys.sort();
|
||||
return keys.reduce((accum, name) => {
|
||||
accum[name] = record[name];
|
||||
return accum;
|
||||
}, {});
|
||||
}
|
||||
exports.sortRecords = sortRecords;
|
||||
function atomicWrite(path, value) {
|
||||
const tmp = path_1.resolve(__dirname, "../../../.atomic-tmp");
|
||||
fs_1.default.writeFileSync(tmp, value);
|
||||
fs_1.default.renameSync(tmp, path);
|
||||
}
|
||||
exports.atomicWrite = atomicWrite;
|
||||
function loadJson(path) {
|
||||
return JSON.parse(fs_1.default.readFileSync(path).toString());
|
||||
}
|
||||
exports.loadJson = loadJson;
|
||||
function saveJson(filename, data, sort) {
|
||||
let replacer = undefined;
|
||||
if (sort) {
|
||||
replacer = (key, value) => {
|
||||
if (Array.isArray(value)) {
|
||||
// pass
|
||||
}
|
||||
else if (value && typeof (value) === "object") {
|
||||
const keys = Object.keys(value);
|
||||
keys.sort();
|
||||
return keys.reduce((accum, key) => {
|
||||
accum[key] = value[key];
|
||||
return accum;
|
||||
}, {});
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
atomicWrite(filename, JSON.stringify(data, replacer, 2) + "\n");
|
||||
}
|
||||
exports.saveJson = saveJson;
|
||||
function resolveProperties(props) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const keys = Object.keys(props);
|
||||
const promises = yield Promise.all(keys.map((k) => props[k]));
|
||||
return keys.reduce((accum, key, index) => {
|
||||
accum[key] = promises[index];
|
||||
return accum;
|
||||
}, {});
|
||||
});
|
||||
}
|
||||
exports.resolveProperties = resolveProperties;
|
||||
// Node 8 does not support recursive mkdir... Remove this in v6.
|
||||
function mkdir(path) {
|
||||
let bail = 0;
|
||||
const dirs = [];
|
||||
while (path !== "/") {
|
||||
if (bail++ > 50) {
|
||||
throw new Error("something bad happened...");
|
||||
}
|
||||
if (fs_1.default.existsSync(path)) {
|
||||
break;
|
||||
}
|
||||
dirs.push(path);
|
||||
path = path_1.dirname(path);
|
||||
}
|
||||
while (dirs.length) {
|
||||
fs_1.default.mkdirSync(dirs.pop());
|
||||
}
|
||||
}
|
||||
exports.mkdir = mkdir;
|
||||
function zpad(value, length) {
|
||||
if (length == null) {
|
||||
length = 2;
|
||||
}
|
||||
const str = String(value);
|
||||
return repeat("0", length - str.length) + str;
|
||||
}
|
||||
function getDate(date) {
|
||||
return [
|
||||
date.getFullYear(),
|
||||
zpad(date.getMonth() + 1),
|
||||
zpad(date.getDate())
|
||||
].join("-");
|
||||
}
|
||||
function getDateTime(date) {
|
||||
return getDate(date) + " " + [
|
||||
zpad(date.getHours()),
|
||||
zpad(date.getMinutes() + 1)
|
||||
].join(":");
|
||||
}
|
||||
exports.getDateTime = getDateTime;
|
||||
47
misc/admin/src.ts/build.ts
Normal file
47
misc/admin/src.ts/build.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { dirnames, getPackageJsonPath, resolve } from "./path";
|
||||
import { loadJson, saveJson } from "./utils";
|
||||
|
||||
function setupConfig(outDir: string, moduleType: string, targetType: string) {
|
||||
|
||||
// Configure the tsconfit.package.json...
|
||||
const path = resolve("tsconfig.package.json");
|
||||
const content = loadJson(path);
|
||||
content.compilerOptions.module = moduleType;
|
||||
content.compilerOptions.target = targetType;
|
||||
saveJson(path, content, true);
|
||||
|
||||
// Configure the browser field for every pacakge, copying the
|
||||
// browser.umd filed for UMD and browser.esm for ESM
|
||||
dirnames.forEach((dirname) => {
|
||||
const filename = getPackageJsonPath(dirname)
|
||||
const info = loadJson(filename);
|
||||
|
||||
if (info._ethers_nobuild) { return; }
|
||||
|
||||
if (targetType === "es2015") {
|
||||
if (info["browser.esm"]) {
|
||||
info.browser = info["browser.esm"];
|
||||
}
|
||||
} else if (targetType === "es5") {
|
||||
if (info["browser.umd"]) {
|
||||
info.browser = info["browser.umd"];
|
||||
}
|
||||
} else {
|
||||
throw new Error("unsupported target");
|
||||
}
|
||||
saveJson(filename, info, true);
|
||||
|
||||
let path = resolve("packages", dirname, "tsconfig.json");
|
||||
let content = loadJson(path);
|
||||
content.compilerOptions.outDir = outDir;
|
||||
saveJson(path, content, true);
|
||||
});
|
||||
}
|
||||
|
||||
export function setupBuild(buildModule: boolean): void {
|
||||
if (buildModule) {
|
||||
setupConfig("./lib.esm/", "es2015", "es2015");
|
||||
} else {
|
||||
setupConfig("./lib/", "commonjs", "es5");
|
||||
}
|
||||
}
|
||||
90
misc/admin/src.ts/changelog.ts
Normal file
90
misc/admin/src.ts/changelog.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import fs from "fs";
|
||||
|
||||
import * as local from "./local";
|
||||
import { colorify } from "./log";
|
||||
import * as npm from "./npm";
|
||||
import { resolve } from "./path";
|
||||
import { run } from "./run";
|
||||
import { getDateTime, repeat } from "./utils";
|
||||
|
||||
const changelogPath = resolve("CHANGELOG.md");
|
||||
|
||||
export async function generate(): Promise<string> {
|
||||
const lines = fs.readFileSync(changelogPath).toString().trim().split("\n");
|
||||
|
||||
let firstLine: number = null;
|
||||
const versions: Array<string> = Object.keys(lines.reduce((accum, line, index) => {
|
||||
const match = line.match(/^ethers\/v([^ ]*)/);
|
||||
if (match) {
|
||||
if (firstLine == null) { firstLine = index; }
|
||||
accum[match[1]] = true;
|
||||
}
|
||||
return accum;
|
||||
}, <Record<string, boolean>>{ }));
|
||||
|
||||
const version = local.getPackage("ethers").version;;
|
||||
const published = await npm.getPackage("ethers");
|
||||
|
||||
if (versions.indexOf(version) >= 0) {
|
||||
const line = `Version ${ version } already in CHANGELOG. Please edit before committing.`;
|
||||
console.log(colorify.red(repeat("=", line.length)));
|
||||
console.log(colorify.red(line));
|
||||
console.log(colorify.red(repeat("=", line.length)));
|
||||
}
|
||||
|
||||
const gitResult = await run("git", [ "log", (published.gitHead + "..") ]);
|
||||
if (!gitResult.ok) {
|
||||
console.log(gitResult);
|
||||
throw new Error("Error running git log");
|
||||
}
|
||||
|
||||
let changes: Array<{ body: string, commit: string, date: string }> = [ ];
|
||||
gitResult.stdout.split("\n").forEach((line) => {
|
||||
if (line.toLowerCase().substring(0, 6) === "commit") {
|
||||
changes.push({
|
||||
commit: line.substring(6).trim(),
|
||||
date: null,
|
||||
body: ""
|
||||
});
|
||||
} else if (line.toLowerCase().substring(0, 5) === "date:") {
|
||||
changes[changes.length - 1].date = getDateTime(new Date(line.substring(5).trim()));
|
||||
} else if (line.substring(0, 1) === " ") {
|
||||
line = line.trim();
|
||||
if (line === "") { return; }
|
||||
changes[changes.length - 1].body += line + " ";
|
||||
}
|
||||
});
|
||||
|
||||
const output: Array<string> = [ ];
|
||||
for (let i = 0; i < firstLine; i++) {
|
||||
output.push(lines[i]);
|
||||
}
|
||||
|
||||
const newTitle = `ethers/v${ version } (${ getDateTime(new Date()) })`;
|
||||
output.push(newTitle);
|
||||
output.push(repeat("-", newTitle.length));
|
||||
output.push("");
|
||||
|
||||
changes.forEach((change) => {
|
||||
let body = change.body.trim();
|
||||
let linkMatch = body.match(/(\((.*#.*)\))/)
|
||||
let commit = `[${ change.commit.substring(0, 7) }](https://github.com/ethers-io/ethers.js/commit/${ change.commit })`;
|
||||
let link = commit;
|
||||
if (linkMatch) {
|
||||
body = body.replace(/ *(\(.*#.*)\) */, "");
|
||||
link = linkMatch[2].replace(/#([0-9]+)/g, (all, issue) => {
|
||||
return `[#${ issue }](https://github.com/ethers-io/ethers.js/issues/${ issue })`;
|
||||
}) + "; " + commit;
|
||||
}
|
||||
output.push(` - ${ body } (${ link })`);
|
||||
});
|
||||
|
||||
output.push("");
|
||||
|
||||
for (let i = firstLine; i < lines.length; i++) {
|
||||
output.push(lines[i]);
|
||||
}
|
||||
|
||||
return output.join("\n");
|
||||
}
|
||||
|
||||
75
misc/admin/src.ts/cmds/bump-versions.ts
Normal file
75
misc/admin/src.ts/cmds/bump-versions.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import fs from "fs";
|
||||
|
||||
import semver from "semver";
|
||||
|
||||
import { dirnames, getPackageJsonPath, getPackagePath, resolve } from "../path";
|
||||
import * as local from "../local";
|
||||
import { colorify, getProgressBar } from "../log";
|
||||
import * as npm from "../npm";
|
||||
import { loadJson, repeat, saveJson } from "../utils";
|
||||
|
||||
(async function() {
|
||||
const progress = getProgressBar(colorify.bold("Bumping package.json versions"));
|
||||
|
||||
const latestVersions: Record<string, string> = { };
|
||||
let updated = false;
|
||||
|
||||
const output: Array<string> = [ ];
|
||||
|
||||
// For each package, detect diff between tarball and remote
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
|
||||
const dirname = dirnames[i];
|
||||
|
||||
const pLocal = local.getPackage(dirname);
|
||||
const pNpm = await npm.getPackage(dirname);
|
||||
|
||||
const tarballHash = local.computeTarballHash(dirname);
|
||||
|
||||
let version = pNpm.version;
|
||||
|
||||
if (tarballHash !== pNpm.tarballHash) {
|
||||
version = semver.inc(version, "patch");
|
||||
|
||||
output.push([
|
||||
" ",
|
||||
colorify.blue(pLocal.name),
|
||||
repeat(" ", 47 - pLocal.name.length - pNpm.version.length),
|
||||
pNpm.version,
|
||||
colorify.bold(" => "),
|
||||
colorify.green(version)
|
||||
].join(""));
|
||||
|
||||
local.updateJson(getPackageJsonPath(dirname), { gitHead: undefined, tarballHash, version }, true);
|
||||
|
||||
updated = true;
|
||||
}
|
||||
|
||||
latestVersions[pLocal.name] = version;
|
||||
|
||||
// Write out the _version.ts
|
||||
if (!pLocal._ethers_nobuild) {
|
||||
const code = "export const version = " + JSON.stringify(dirname + "/" + pLocal.version) + ";\n";
|
||||
fs.writeFileSync(resolve(getPackagePath(dirname), "src.ts/_version.ts"), code);
|
||||
}
|
||||
}
|
||||
progress(1);
|
||||
|
||||
if (updated) {
|
||||
const filename = resolve("packages/ethers/package.json")
|
||||
const info = loadJson(filename);
|
||||
Object.keys(info.dependencies).forEach((name) => {
|
||||
const version = latestVersions[name];
|
||||
if (name == null) { return; }
|
||||
info.dependencies[name] = version;
|
||||
});
|
||||
saveJson(filename, info);
|
||||
}
|
||||
|
||||
output.forEach((line) => { console.log(line); });
|
||||
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${ process.argv[0] }: ${ error.message }`);
|
||||
process.exit(1);
|
||||
});
|
||||
3
misc/admin/src.ts/cmds/echo.ts
Normal file
3
misc/admin/src.ts/cmds/echo.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { colorify } from "../log";
|
||||
|
||||
console.log(colorify.bold(process.argv[2] || "no message"));
|
||||
17
misc/admin/src.ts/cmds/hoist.ts
Normal file
17
misc/admin/src.ts/cmds/hoist.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
import { dirs, isEthers } from "../path";
|
||||
import { getDependencies, updateJson } from "../local";
|
||||
import { colorify } from "../log";
|
||||
|
||||
(async function() {
|
||||
const dependencies = getDependencies(null, (name: string) => {
|
||||
return !isEthers(name);
|
||||
});
|
||||
|
||||
console.log(colorify.bold(`Hoisting ${ Object.keys(dependencies).length } dependencies into root package...`));
|
||||
|
||||
updateJson(dirs.rootPackageJsonPath, { dependencies });
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${ process.argv[0] }: ${ error.message }`);
|
||||
process.exit(1);
|
||||
});
|
||||
56
misc/admin/src.ts/cmds/link.ts
Normal file
56
misc/admin/src.ts/cmds/link.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import fs from "fs";
|
||||
import { dirname, resolve } from "path";
|
||||
|
||||
import { getDependencies } from "../local";
|
||||
import { colorify } from "../log";
|
||||
import { dirs, getDirname, getPackagePath, packages } from "../path";
|
||||
import { mkdir } from "../utils";
|
||||
|
||||
function link(existing: string, path: string): void {
|
||||
try {
|
||||
const current = fs.readlinkSync(path);
|
||||
|
||||
// Alerady linked
|
||||
if (current === existing) { return; }
|
||||
|
||||
fs.unlinkSync(path);
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") { throw error; }
|
||||
}
|
||||
|
||||
// Link
|
||||
const dir = dirname(path);
|
||||
mkdir(dir);
|
||||
fs.symlinkSync(existing, path);
|
||||
}
|
||||
|
||||
(async function() {
|
||||
console.log(colorify.bold(`Linking ${ packages.length } package node_modules rat nests...`));
|
||||
|
||||
const nodeModulesBase = resolve(dirs.root, ".package_node_modules");
|
||||
|
||||
// Make a symlink in the ROOT/node_mpdules to each package in this repo
|
||||
packages.forEach((name) => {
|
||||
|
||||
// e.g. /node_modules/@ethersproject/abi => /packages/abi
|
||||
link(getPackagePath(name), resolve(dirs.root, "node_modules", name));
|
||||
|
||||
// e.g. /packages/abi/node_modules => /.package_node_modules/abi/
|
||||
const nodeModules = resolve(nodeModulesBase, getDirname(name));
|
||||
mkdir(nodeModules);
|
||||
link(nodeModules, resolve(getPackagePath(name), "node_modules"));
|
||||
});
|
||||
|
||||
packages.forEach((name) => {
|
||||
const nodeModules = resolve(nodeModulesBase, getDirname(name));
|
||||
|
||||
const deps = getDependencies(name);
|
||||
Object.keys(deps).forEach((name) => {
|
||||
link(resolve(dirs.root, "node_modules", name), resolve(nodeModules, name));
|
||||
});
|
||||
});
|
||||
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${ process.argv[0] }: ${ error.message }`);
|
||||
process.exit(1);
|
||||
});;
|
||||
16
misc/admin/src.ts/cmds/npm-skip-node8.ts
Normal file
16
misc/admin/src.ts/cmds/npm-skip-node8.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
const { major } = require("semver");
|
||||
|
||||
// This should be used like `node npm-skip-node8 || COMMAND`.
|
||||
// - If node 8, this script returns true, skipping COMMAND
|
||||
// - Otherwise, return false, running COMMAND
|
||||
|
||||
if (major(process.version) > 8) {
|
||||
// Node >8; return "false" (wrt to shell scripting)
|
||||
process.exit(1);
|
||||
} else {
|
||||
// Node 8; return "true" (wrt to shell scripting)
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
105
misc/admin/src.ts/cmds/serve-docs.ts
Normal file
105
misc/admin/src.ts/cmds/serve-docs.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import fs from "fs";
|
||||
import { createServer, Server } from "http";
|
||||
import { resolve } from "path";
|
||||
|
||||
export function getMime(filename: string): string {
|
||||
switch (filename.split('.').pop().toLowerCase()) {
|
||||
case 'css': return 'text/css';
|
||||
case 'doctree': return 'application/x-doctree';
|
||||
case 'eot': return 'application/vnd.ms-fontobject';
|
||||
case 'gif': return 'image/gif';
|
||||
case 'html': return 'text/html';
|
||||
case 'js': return 'application/javascript';
|
||||
case 'jpg': return 'image/jpeg';
|
||||
case 'jpeg': return 'image/jpeg';
|
||||
case 'md': return 'text/markdown';
|
||||
case 'pickle': return 'application/x-pickle';
|
||||
case 'png': return 'image/png';
|
||||
case 'svg': return 'image/svg+xml';
|
||||
case 'ttf': return 'application/x-font-ttf';
|
||||
case 'txt': return 'text/plain';
|
||||
case 'woff': return 'application/font-woff';
|
||||
}
|
||||
console.log('NO MIME', filename);
|
||||
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
export type Options = {
|
||||
port?: number;
|
||||
redirects?: Record<string, string>;
|
||||
};
|
||||
|
||||
export function start(root: string, options: Options): Server {
|
||||
if (root == null) { throw new Error("root required"); }
|
||||
if (options == null) { options = { }; }
|
||||
if (options.port == null) { options.port = 8000; }
|
||||
root = resolve(root);
|
||||
|
||||
const server = createServer((req, resp) => {
|
||||
|
||||
// Follow redirects in options
|
||||
if (options.redirects && options.redirects[req.url]) {
|
||||
resp.writeHead(301, { Location: options.redirects[req.url] });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
let filename = resolve(root, "." + req.url);
|
||||
|
||||
// Make sure we aren't crawling out of our sandbox
|
||||
if (req.url[0] !== "/" || filename.substring(0, filename.length) !== filename) {
|
||||
resp.writeHead(403);
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const stat = fs.statSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
|
||||
// Redirect bare directory to its path (i.e. "/foo" => "/foo/")
|
||||
if (req.url[req.url.length - 1] !== "/") {
|
||||
resp.writeHead(301, { Location: req.url + "/" });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
filename += "/index.html";
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(filename);
|
||||
|
||||
resp.writeHead(200, {
|
||||
"Content-Length": content.length,
|
||||
"Content-Type": getMime(filename)
|
||||
});
|
||||
resp.end(content);
|
||||
return;
|
||||
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
resp.writeHead(404, { });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
resp.writeHead(500, { });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(options.port, () => {
|
||||
console.log(`Server running on: http://localhost:${ options.port }`);
|
||||
});
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
start(resolve(__dirname, "../../docs"), {
|
||||
redirects: {
|
||||
"/": "/v5/"
|
||||
}
|
||||
});
|
||||
|
||||
36
misc/admin/src.ts/cmds/set-build-option.ts
Normal file
36
misc/admin/src.ts/cmds/set-build-option.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { setupBuild } from "../build";
|
||||
import { colorify } from "../log";
|
||||
import { getPackageJsonPath } from "../path";
|
||||
import { loadJson, saveJson } from "../utils";
|
||||
|
||||
(async function() {
|
||||
process.argv.slice(2).forEach((arg) => {
|
||||
console.log(colorify.bold("Setting Option:"), arg);
|
||||
switch(arg) {
|
||||
case "esm":
|
||||
setupBuild(true);
|
||||
break;
|
||||
|
||||
case "cjs":
|
||||
setupBuild(false);
|
||||
break;
|
||||
|
||||
// This will remove the browser field entirely, so make sure
|
||||
// to set esm of cjs first as they will restore the browser
|
||||
// field
|
||||
case "browser-lang-all": {
|
||||
const filename = getPackageJsonPath("wordlists");
|
||||
const info = loadJson(filename);
|
||||
delete info.browser;
|
||||
saveJson(filename, info, true);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown option: ${ JSON.stringify(arg) }`);
|
||||
}
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${ process.argv[0] }: ${ error.message }`);
|
||||
process.exit(1);
|
||||
});
|
||||
18
misc/admin/src.ts/cmds/set-config.ts
Normal file
18
misc/admin/src.ts/cmds/set-config.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { config } from "../config";
|
||||
import { getPassword } from "../log";
|
||||
|
||||
if (process.argv.length !== 3) {
|
||||
console.log("Usage: set-config KEY");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const key = process.argv[2];
|
||||
|
||||
(async function() {
|
||||
const value = await getPassword("Value: ");
|
||||
await config.set(key, value);
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${ process.argv[0] }: ${ error.message }`);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
const { resolve } = require("path");
|
||||
const fs = require("fs");
|
||||
import fs from "fs";
|
||||
import { resolve } from "path";
|
||||
import ts from "typescript";
|
||||
|
||||
import { colorify } from "../log";
|
||||
|
||||
const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").reduce((accum, word) => {
|
||||
accum[word.toLowerCase()] = true;
|
||||
return accum;
|
||||
}, { });
|
||||
}, <Record<string, boolean>>{ });
|
||||
|
||||
`
|
||||
// Words missing from the dictionary
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email enabled encoded encoding encrypt
|
||||
encrypted encrypting entries euro exceeded existing expected
|
||||
expired failed fetches formatted formatting funding generated
|
||||
@@ -47,9 +50,9 @@ bytecode callback calldata checksum ciphertext cli codepoint commify config
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof ethaddr
|
||||
ethseed ethers eval exec filename func gz hid http https hw iv
|
||||
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
||||
nfkc nfd nfkd nodehash notok nullish oob opcode pbkdf pc plugin pragma pre prf
|
||||
repl rpc sighash topichash solc stdin stdout subclasses subnode
|
||||
timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||
pragma pre prf repl rpc sighash topichash solc stdin stdout subclasses
|
||||
subnode timeout todo txt ufixed utc utf util url uuid vm vs websocket
|
||||
wikipedia wx xe xpriv xpub xx yyyy zlib
|
||||
|
||||
// AbiV2
|
||||
@@ -79,20 +82,28 @@ OYAa IJBEJqXZJ
|
||||
Words[word.toLowerCase()] = true;
|
||||
});
|
||||
|
||||
const ts = require("typescript");
|
||||
type Bar = {
|
||||
value: string;
|
||||
lineNo: number;
|
||||
}
|
||||
|
||||
function getStrings(source) {
|
||||
const sourceFile = ts.createSourceFile("filename.ts", source);
|
||||
type Foo = {
|
||||
filename: string;
|
||||
values: Array<Bar>;
|
||||
};
|
||||
|
||||
const result = [ ];
|
||||
function getStrings(source: string): Array<Bar> {
|
||||
const sourceFile = ts.createSourceFile("filename.ts", source, ts.ScriptTarget.Latest);
|
||||
|
||||
function add(value, pos) {
|
||||
const result: Array<Bar> = [ ];
|
||||
|
||||
function add(value: string, pos: number): void {
|
||||
const lineNo = sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
|
||||
result.push({ value, lineNo });
|
||||
}
|
||||
|
||||
let lastClass = null, lastEnum = null;
|
||||
function visit(node, depth) {
|
||||
//let lastClass = null, lastEnum = null;
|
||||
function visit(node: ts.Node, depth: number): void {
|
||||
switch (node.kind) {
|
||||
//case ts.SyntaxKind.TemplateExpression:
|
||||
// if (node.head) { visit(node.head); }
|
||||
@@ -103,7 +114,7 @@ function getStrings(source) {
|
||||
case ts.SyntaxKind.TemplateTail:
|
||||
case ts.SyntaxKind.StringLiteral:
|
||||
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
add(node.text, node.pos);
|
||||
add((<ts.LiteralLikeNode>node).text, node.pos);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,10 +129,11 @@ function getStrings(source) {
|
||||
const Include = new RegExp("packages/.*/src.ts/.*\.ts$");
|
||||
const Exclude = new RegExp("/node_modules/|src.ts/.*browser.*");
|
||||
|
||||
function getAllStrings(path) {
|
||||
|
||||
function getAllStrings(path: string): Array<Foo> {
|
||||
const Root = resolve(__dirname, path);
|
||||
|
||||
const readdir = function(path) {
|
||||
const readdir = function(path: string): Array<Foo> {
|
||||
if (path.match(Exclude)) { return [ ]; }
|
||||
|
||||
const stat = fs.statSync(path);
|
||||
@@ -145,7 +157,7 @@ function getAllStrings(path) {
|
||||
return readdir(Root);
|
||||
}
|
||||
|
||||
function checkWord(word) {
|
||||
function checkWord(word: string): boolean {
|
||||
word = word.toLowerCase();
|
||||
|
||||
// A word
|
||||
@@ -156,20 +168,24 @@ function checkWord(word) {
|
||||
|
||||
// Hex string
|
||||
if (word.match(/^(0x)?[0-9a-f]*$/i)) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function starts(text, prefix) {
|
||||
function starts(text: string, prefix: string): boolean {
|
||||
return (text.substring(0, prefix.length) === prefix);
|
||||
}
|
||||
|
||||
(async function() {
|
||||
console.log(colorify.bold("Spell checking source code strings..."));
|
||||
|
||||
let count = 0;
|
||||
getAllStrings(resolve(__dirname, "../../packages")).forEach((file) => {
|
||||
getAllStrings(resolve(__dirname, "../../../../packages")).forEach((file: Foo) => {
|
||||
if (starts(file.filename, "/testcases/src.ts/generation-scripts")) { return; }
|
||||
if (starts(file.filename, "/asm/src.ts/opcodes.ts")) { return; }
|
||||
|
||||
file.values.forEach((entry) => {
|
||||
function problem(word) {
|
||||
function problem(word: string): void {
|
||||
count++;
|
||||
console.log({
|
||||
filename: file.filename,
|
||||
@@ -196,16 +212,23 @@ function starts(text, prefix) {
|
||||
value.replace(/([a-z+])([A-Z])/g, (all, first, secondLetter) => {
|
||||
return first + " " + secondLetter;
|
||||
}).replace(/((?:0x)?[A-Za-z]+)/gi, (all, word) => {
|
||||
if (checkWord(word)) { return; }
|
||||
if (checkWord(word)) { return ""; }
|
||||
problem(word);
|
||||
return "";
|
||||
});;
|
||||
});
|
||||
});
|
||||
|
||||
if (count) {
|
||||
console.log(`Found ${ count } typos.`);
|
||||
process.exit(1)
|
||||
}
|
||||
process.exit(0)
|
||||
})();
|
||||
|
||||
|
||||
process.exit(0)
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
10
misc/admin/src.ts/cmds/update-changelog.ts
Normal file
10
misc/admin/src.ts/cmds/update-changelog.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import fs from "fs";
|
||||
|
||||
import { generate } from "../changelog";
|
||||
import { colorify } from "../log";
|
||||
import { resolve } from "../path";
|
||||
|
||||
(async function() {
|
||||
console.log(colorify.bold("Updating CHANGELOG.md..."));
|
||||
fs.writeFileSync(resolve("CHANGELOG.md"), await generate());
|
||||
})();
|
||||
15
misc/admin/src.ts/cmds/update-depgraph.ts
Normal file
15
misc/admin/src.ts/cmds/update-depgraph.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { getOrdered } from "../depgraph";
|
||||
import { resolve } from "../path";
|
||||
import { updateJson } from "../local";
|
||||
|
||||
(async function() {
|
||||
const ordered = getOrdered(true);
|
||||
|
||||
updateJson(resolve("tsconfig.project.json"), {
|
||||
references: ordered.map((name) => ({ path: ("./packages/" + name) }))
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
42
misc/admin/src.ts/cmds/update-exports.ts
Normal file
42
misc/admin/src.ts/cmds/update-exports.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
import fs from "fs";
|
||||
|
||||
import { colorify } from "../log";
|
||||
import { resolve } from "../path";
|
||||
|
||||
const sourceEthers = fs.readFileSync(resolve("packages/ethers/src.ts/ethers.ts")).toString();
|
||||
const targets = sourceEthers.match(/export\s*{\s*((.|\s)*)}/)[1].trim();
|
||||
|
||||
////////////////////
|
||||
// Begin template
|
||||
////////////////////
|
||||
|
||||
const output = `"use strict";
|
||||
|
||||
// To modify this file, you must update ./misc/admin/lib/cmds/update-exports.js
|
||||
|
||||
import * as ethers from "./ethers";
|
||||
|
||||
try {
|
||||
const anyGlobal = (window as any);
|
||||
|
||||
if (anyGlobal._ethers == null) {
|
||||
anyGlobal._ethers = ethers;
|
||||
}
|
||||
} catch (error) { }
|
||||
|
||||
export { ethers };
|
||||
|
||||
export {
|
||||
${ targets }
|
||||
} from "./ethers";
|
||||
`;
|
||||
|
||||
////////////////////
|
||||
// End template
|
||||
////////////////////
|
||||
|
||||
console.log(colorify.bold(`Flattening exports...`))
|
||||
|
||||
fs.writeFileSync(resolve("packages/ethers/src.ts/index.ts"), output);
|
||||
27
misc/admin/src.ts/cmds/update-hashes.ts
Normal file
27
misc/admin/src.ts/cmds/update-hashes.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
//import { getGitTag } from "../git";
|
||||
import { computeTarballHash, updateJson } from "../local";
|
||||
import { colorify, getProgressBar } from "../log";
|
||||
import { dirnames, getPackageJsonPath } from "../path";
|
||||
|
||||
(async function() {
|
||||
const progress = getProgressBar(colorify.bold("Updating package.json hashes"));
|
||||
|
||||
// Updating all tarball hashes now that versions have been updated
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
|
||||
const dirname = dirnames[i];
|
||||
|
||||
//const gitHead = await getGitTag(resolve("packages", dirname));
|
||||
const tarballHash = computeTarballHash(dirname);
|
||||
|
||||
updateJson(getPackageJsonPath(dirname), { tarballHash }, true);
|
||||
}
|
||||
|
||||
progress(1);
|
||||
|
||||
})().catch((error) => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});;
|
||||
|
||||
134
misc/admin/src.ts/config.ts
Normal file
134
misc/admin/src.ts/config.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { createHmac, randomBytes } from "crypto";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import { resolve } from "path";
|
||||
|
||||
import AES from "aes-js";
|
||||
import scrypt from "scrypt-js";
|
||||
|
||||
import { colorify, getPassword, getProgressBar } from "./log";
|
||||
|
||||
function getRandomBytes(length: number): Uint8Array {
|
||||
const result = new Uint8Array(length);
|
||||
result.set(randomBytes(length));
|
||||
return result;
|
||||
}
|
||||
|
||||
function computeHmac(key: Uint8Array, data: Uint8Array): string {
|
||||
return "0x" + createHmac("sha512", key, ).update(data).digest("hex");
|
||||
}
|
||||
|
||||
async function getScrypt(message: string, password: string, salt: Uint8Array): Promise<Uint8Array> {
|
||||
const progress = getProgressBar(message);
|
||||
return await scrypt.scrypt(Buffer.from(password), Buffer.from(salt), (1 << 17), 8, 1, 64, progress);
|
||||
}
|
||||
|
||||
class Config {
|
||||
private salt: Uint8Array;
|
||||
private dkey: Uint8Array;
|
||||
private values: Record<string, string>;
|
||||
private canary: string;
|
||||
private filename: string;
|
||||
|
||||
constructor(filename: string) {
|
||||
this.salt = null;
|
||||
this.dkey = null;
|
||||
this.values = { };
|
||||
this.canary = "";
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
async load(): Promise<void> {
|
||||
if (this.dkey) { return; }
|
||||
|
||||
let data: any = null;
|
||||
if (fs.existsSync(this.filename)) {
|
||||
data = JSON.parse(fs.readFileSync(this.filename).toString());
|
||||
} else {
|
||||
data = {
|
||||
salt: Buffer.from(getRandomBytes(32)).toString("hex")
|
||||
};
|
||||
}
|
||||
|
||||
this.canary = data.canary || "";
|
||||
|
||||
this.salt = data.salt;
|
||||
|
||||
const password = await getPassword(colorify.bold("Password (config-store): "));
|
||||
|
||||
this.dkey = await getScrypt(colorify.bold("Unlocking config"), password, this.salt);
|
||||
|
||||
if (data.ciphertext) {
|
||||
const ciphertext = Buffer.from(data.ciphertext, "base64");
|
||||
const iv = Buffer.from(data.iv, "base64");
|
||||
const aes = new AES.ModeOfOperation.ctr(this.dkey.slice(0, 32), new AES.Counter(iv));
|
||||
const plaintext = aes.decrypt(ciphertext);
|
||||
const hmac = computeHmac(this.dkey.slice(32, 64), plaintext);
|
||||
if (hmac !== data.hmac) {
|
||||
console.log(colorify.red("Incorrect password."));
|
||||
throw new Error("wrong password");
|
||||
}
|
||||
|
||||
this.values = JSON.parse(Buffer.from(plaintext).toString());
|
||||
}
|
||||
}
|
||||
|
||||
async keys(): Promise<Array<string>> {
|
||||
await this.load();
|
||||
return Object.keys(this.values);
|
||||
}
|
||||
|
||||
save(): void {
|
||||
this.values._junk = Buffer.from(getRandomBytes(16 + Math.floor(Math.random() * 48))).toString("base64")
|
||||
|
||||
const plaintext = Buffer.from(JSON.stringify(this.values));
|
||||
|
||||
const iv = Buffer.from(getRandomBytes(16));
|
||||
const hmac = computeHmac(this.dkey.slice(32, 64), plaintext);
|
||||
|
||||
const aes = new AES.ModeOfOperation.ctr(this.dkey.slice(0, 32), new AES.Counter(iv));
|
||||
const ciphertext = Buffer.from(aes.encrypt(plaintext));
|
||||
|
||||
const data = {
|
||||
ciphertext: ciphertext.toString("base64"),
|
||||
iv: iv.toString("base64"),
|
||||
salt: this.salt,
|
||||
hmac: hmac,
|
||||
canary: this.canary
|
||||
};
|
||||
|
||||
fs.writeFileSync(this.filename, JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
||||
async get(key: string): Promise<string> {
|
||||
await this.load();
|
||||
return this.values[key];
|
||||
}
|
||||
|
||||
async set(key: string, value: string): Promise<void> {
|
||||
await this.load();
|
||||
this.values[key] = value;
|
||||
this.save();
|
||||
}
|
||||
|
||||
lock(): void {
|
||||
this.salt = this.dkey = null;
|
||||
}
|
||||
}
|
||||
|
||||
const _config = new Config(resolve(os.homedir(), ".ethers-dist"));
|
||||
|
||||
export const config = {
|
||||
get: function(key: string) {
|
||||
return _config.get(key);
|
||||
},
|
||||
set: function(key: string, value: string) {
|
||||
_config.set(key, value);
|
||||
},
|
||||
keys: function() {
|
||||
return _config.keys();
|
||||
},
|
||||
lock: function() {
|
||||
_config.lock();
|
||||
}
|
||||
};
|
||||
110
misc/admin/src.ts/depgraph.ts
Normal file
110
misc/admin/src.ts/depgraph.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
import { dirnames } from "./path";
|
||||
import { getPackage, Package } from "./local";
|
||||
|
||||
class OrderedSet {
|
||||
_keys: Array<string>;
|
||||
_values: Record<string, boolean>
|
||||
|
||||
constructor() {
|
||||
this._keys = [ ];
|
||||
this._values = { };
|
||||
}
|
||||
|
||||
add(key: string): void {
|
||||
this._values[key] = true;
|
||||
this._keys = null;
|
||||
}
|
||||
|
||||
contains(key: string): boolean {
|
||||
return !!this._values[key];
|
||||
}
|
||||
|
||||
_sort(): void {
|
||||
if (this._keys != null) { return; }
|
||||
this._keys = Object.keys(this._values);
|
||||
this._keys.sort();
|
||||
}
|
||||
|
||||
get length(): number {
|
||||
this._sort();
|
||||
return this._keys.length;
|
||||
}
|
||||
|
||||
get(index: number): string {
|
||||
this._sort();
|
||||
return this._keys[index];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export function getOrdered(skipNobuild?: boolean): Array<string> {
|
||||
const packages: Record<string, Package > = { };
|
||||
const filenames: Record<string, string> = { };
|
||||
|
||||
// Maps packages to names to list of dependencies; { [ name:string]: Array<name: string> }
|
||||
const deps: Record<string, OrderedSet> = { };
|
||||
|
||||
let addDeps = (name: string, depends: Record<string, string>) => {
|
||||
Object.keys(depends).forEach((dep) => {
|
||||
// Not a package we manage
|
||||
if (packages[dep] == null) { return; }
|
||||
deps[name].add(dep);
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
let info = getPackage(dirname);
|
||||
if (skipNobuild && info._ethers_nobuild) { continue; }
|
||||
packages[info.name] = info;
|
||||
filenames[info.name] = dirname;
|
||||
}
|
||||
|
||||
Object.keys(packages).forEach((name) => {
|
||||
let info = packages[name];
|
||||
deps[info.name] = new OrderedSet();
|
||||
addDeps(info.name, info.dependencies || { });
|
||||
addDeps(info.name, info.devDependencies || { });
|
||||
});
|
||||
|
||||
let ordered: Array<string> = [ ];
|
||||
let remaining = Object.keys(deps);
|
||||
|
||||
let isSatisfied = (name: string) => {
|
||||
for (let i = 0; i < deps[name].length; i++) {
|
||||
if (ordered.indexOf(deps[name].get(i)) === -1) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
while (remaining.length) {
|
||||
let bail = true;
|
||||
for (let i = 0; i < remaining.length; i++) {
|
||||
if (!isSatisfied(remaining[i])) { continue; }
|
||||
bail = false;
|
||||
ordered.push(remaining[i]);
|
||||
remaining.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bail) {
|
||||
throw new Error("Nothing processed; circular dependencies...");
|
||||
}
|
||||
}
|
||||
|
||||
return ordered.map((name) => filenames[name]);
|
||||
}
|
||||
|
||||
export function sort(dirnames: Array<string>): void {
|
||||
let ordered = getOrdered();
|
||||
dirnames.sort((a, b) => {
|
||||
let ai = ordered.indexOf(getPackage(a).name);
|
||||
let bi = ordered.indexOf(getPackage(b).name);
|
||||
if (ai === -1 || bi === -1) {
|
||||
throw new Error("unknown dirname - " + [a, b].join(", "));
|
||||
}
|
||||
return ai - bi;
|
||||
});
|
||||
}
|
||||
|
||||
106
misc/admin/src.ts/geturl.ts
Normal file
106
misc/admin/src.ts/geturl.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
import { parse } from "url"
|
||||
|
||||
export type GetUrlResponse = {
|
||||
statusCode: number,
|
||||
statusMessage: string;
|
||||
headers: { [ key: string] : string };
|
||||
body: Uint8Array;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
method?: string,
|
||||
body?: Uint8Array
|
||||
headers?: { [ key: string] : string },
|
||||
};
|
||||
|
||||
function getResponse(request: http.ClientRequest): Promise<GetUrlResponse> {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.once("response", (resp: http.IncomingMessage) => {
|
||||
const response: GetUrlResponse = {
|
||||
statusCode: resp.statusCode,
|
||||
statusMessage: resp.statusMessage,
|
||||
headers: Object.keys(resp.headers).reduce((accum, name) => {
|
||||
let value = resp.headers[name];
|
||||
if (Array.isArray(value)) {
|
||||
value = value.join(", ");
|
||||
}
|
||||
accum[name] = value;
|
||||
return accum;
|
||||
}, <{ [ name: string ]: string }>{ }),
|
||||
body: null
|
||||
};
|
||||
//resp.setEncoding("utf8");
|
||||
|
||||
resp.on("data", (chunk: Uint8Array) => {
|
||||
if (response.body == null) { response.body = new Uint8Array(0); }
|
||||
|
||||
const body = new Uint8Array(response.body.length + chunk.length);
|
||||
body.set(response.body, 0);
|
||||
body.set(chunk, response.body.length);
|
||||
|
||||
response.body = body;
|
||||
});
|
||||
|
||||
resp.on("end", () => {
|
||||
resolve(response);
|
||||
});
|
||||
|
||||
resp.on("error", (error) => {
|
||||
/* istanbul ignore next */
|
||||
(<any>error).response = response;
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
request.on("error", (error) => { reject(error); });
|
||||
});
|
||||
}
|
||||
|
||||
// The URL.parse uses null instead of the empty string
|
||||
function nonnull(value: string): string {
|
||||
if (value == null) { return ""; }
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function getUrl(href: string, options?: Options): Promise<GetUrlResponse> {
|
||||
if (options == null) { options = { }; }
|
||||
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = parse(href);
|
||||
|
||||
const request = {
|
||||
protocol: nonnull(url.protocol),
|
||||
hostname: nonnull(url.hostname),
|
||||
port: nonnull(url.port),
|
||||
path: (nonnull(url.pathname) + nonnull(url.search)),
|
||||
|
||||
method: (options.method || "GET"),
|
||||
headers: (options.headers || { }),
|
||||
};
|
||||
|
||||
let req: http.ClientRequest = null;
|
||||
switch (nonnull(url.protocol)) {
|
||||
case "http:":
|
||||
req = http.request(request);
|
||||
break;
|
||||
case "https:":
|
||||
req = https.request(request);
|
||||
break;
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`unsupported protocol ${ url.protocol }`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
req.write(Buffer.from(options.body));
|
||||
}
|
||||
req.end();
|
||||
|
||||
const response = await getResponse(req);
|
||||
return response;
|
||||
}
|
||||
|
||||
16
misc/admin/src.ts/git.ts
Normal file
16
misc/admin/src.ts/git.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { run } from "./run";
|
||||
|
||||
// Returns the most recent git commit hash for a given filename
|
||||
export async function getGitTag(filename: string): Promise<string> {
|
||||
const result = await run("git", [ "log", "-n", "1", "--", filename ]);
|
||||
if (!result.ok) { throw new Error(`git log error`); }
|
||||
|
||||
let log = result.stdout.trim();
|
||||
if (!log) { return null; }
|
||||
|
||||
const hashMatch = log.match(/^commit\s+([0-9a-f]{40})\n/i);
|
||||
if (!hashMatch) { return null; }
|
||||
return hashMatch[1];
|
||||
}
|
||||
|
||||
//getGitTag("/Users/ricmoo/Development/ethers/ethers.js/packages/abi").then(console.log);
|
||||
148
misc/admin/src.ts/local.ts
Normal file
148
misc/admin/src.ts/local.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import fs from "fs";
|
||||
|
||||
import { dirnames, getPackageJsonPath, getPackagePath, resolve } from "./path";
|
||||
import { run } from "./run";
|
||||
import { loadJson, saveJson, sha256, sortRecords } from "./utils";
|
||||
|
||||
export type Package = {
|
||||
dependencies: { [ name: string ]: string };
|
||||
devDependencies: { [ name: string ]: string };
|
||||
gitHead: string;
|
||||
name: string;
|
||||
version: string;
|
||||
tarballHash: string;
|
||||
location: "remote" | "local";
|
||||
_ethers_nobuild: boolean;
|
||||
};
|
||||
|
||||
export function getPackage(name: string): Package {
|
||||
const value = loadJson(getPackageJsonPath(name));
|
||||
return {
|
||||
name: value.name,
|
||||
version: value.version,
|
||||
dependencies: (value.dependencies || { }),
|
||||
devDependencies: (value.dependencies || { }),
|
||||
location: "local",
|
||||
tarballHash: (value.tarballHash || null),
|
||||
gitHead: (value.gitHead || null),
|
||||
_ethers_nobuild: !!value._ethers_nobuild,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateJson(path: string, replace: Record<string, any>, sort?: boolean): void {
|
||||
const values = loadJson(path);
|
||||
|
||||
Object.keys(replace).forEach((key) => {
|
||||
const value = replace[key];
|
||||
if (value === undefined) {
|
||||
delete values[key];
|
||||
} else {
|
||||
values[key] = replace[key];
|
||||
}
|
||||
});
|
||||
|
||||
saveJson(path, values, !!sort);
|
||||
}
|
||||
|
||||
export function getDependencies(name?: string, filter?: (name: string) => boolean): Record<string, string> {
|
||||
if (name) {
|
||||
return sortRecords(getPackage(name).dependencies);
|
||||
}
|
||||
|
||||
// Find all versions for each package dependency
|
||||
const deps = dirnames.reduce((accum, dirname) => {
|
||||
const deps = getPackage(dirname).dependencies;
|
||||
Object.keys(deps).forEach((name) => {
|
||||
if (filter && !filter(name)) { return; }
|
||||
if (!accum[name]) { accum[name] = { }; }
|
||||
accum[name][deps[name]] = true;
|
||||
});
|
||||
return accum;
|
||||
}, <Record<string, Record<string, boolean>>>{});
|
||||
|
||||
// Make sure each package dependency only has 1 version
|
||||
return sortRecords(Object.keys(deps).reduce((accum, name) => {
|
||||
const versions = Object.keys(deps[name]);
|
||||
if (versions.length > 1) {
|
||||
throw new Error(`cannot depend on multiple versions for ${ JSON.stringify(name) }: ${ versions.map(v => JSON.stringify(v)).join(", ") }`);
|
||||
}
|
||||
accum[name] = versions[0];
|
||||
return accum;
|
||||
}, <Record<string, string>>{ }));
|
||||
}
|
||||
|
||||
export function getPackList(name: string): Array<string> {
|
||||
const result = run("npm", [ "pack", "--json", getPackagePath(name), "--dry-run" ]);
|
||||
if (!result.ok) {
|
||||
const error = new Error(`failed to run npm pack: ${ name }`);
|
||||
(<any>error).result = result;
|
||||
throw error;
|
||||
}
|
||||
return JSON.parse(result.stdout)[0].files.map((info: { path: string }) => info.path);
|
||||
}
|
||||
|
||||
/*
|
||||
export function getTarball(name: string): Buffer {
|
||||
const files = getPackList(name).map((name) => `./${ name }`);
|
||||
files.sort((a, b) => {
|
||||
|
||||
const compsA = a.split("/"), compsB = b.split("/");
|
||||
while (true) {
|
||||
const a = compsA.shift(), b = compsB.shift();
|
||||
if (a === b) { continue; }
|
||||
|
||||
if (compsA.length === 0 && compsB.length === 0) {
|
||||
if (a < b) { return -1; }
|
||||
if (a > b) { return 1; }
|
||||
break;
|
||||
}
|
||||
|
||||
if (compsA.length === 0) { return -1; }
|
||||
if (compsB.length === 0) { return 1; }
|
||||
|
||||
if (a < b) { return -1; }
|
||||
if (a > b) { return 1; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return tar.create({
|
||||
sync: true,
|
||||
cwd: getPackagePath(name),
|
||||
prefix: "package/",
|
||||
gzip: true,
|
||||
portable: true,
|
||||
// Provide a specific date in the 1980s for the benefit of zip,
|
||||
// which is confounded by files dated at the Unix epoch 0.
|
||||
mtime: new Date('1985-10-26T08:15:00.000Z'),
|
||||
}, files).read();
|
||||
}
|
||||
*/
|
||||
export function computeTarballHash(name: string): string {
|
||||
|
||||
// Sort the files to get a consistent hash
|
||||
const files = getPackList(name);
|
||||
files.sort();
|
||||
|
||||
// Compute the hash for each file
|
||||
const packageRoot = getPackagePath(name);
|
||||
const hashes = files.reduce((accum, filename) => {
|
||||
let content = fs.readFileSync(resolve(packageRoot, filename));
|
||||
|
||||
// The package.json includes the hash, so we need to nix it to get a consistent hash
|
||||
if (filename === "package.json") {
|
||||
const info = JSON.parse(content.toString());
|
||||
delete info.gitHead;
|
||||
delete info.tarballHash;
|
||||
content = Buffer.from(JSON.stringify(info, null, 2));
|
||||
}
|
||||
|
||||
accum[filename] = sha256(content);
|
||||
return accum;
|
||||
}, <Record<string, string>>{ });
|
||||
|
||||
return sha256(Buffer.from("{" + files.map((filename) => {
|
||||
return `${ JSON.stringify(filename) }:"${ hashes[filename] }"`
|
||||
}).join(",") + "}"));
|
||||
}
|
||||
167
misc/admin/src.ts/log.ts
Normal file
167
misc/admin/src.ts/log.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { repeat } from "./utils";
|
||||
|
||||
// See: https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
|
||||
let disableColor = !(process.stdout.isTTY);
|
||||
|
||||
export function getProgressBar(action: string): (percent: number) => void {
|
||||
let lastProgress = -1;
|
||||
|
||||
return function(percent: number): void {
|
||||
const progress = Math.trunc(percent * 100);
|
||||
|
||||
if (disableColor) {
|
||||
if (lastProgress === -1) {
|
||||
console.log(action + "...");
|
||||
}
|
||||
lastProgress = progress;
|
||||
return;
|
||||
}
|
||||
|
||||
//process.stdin.setRawMode(false);
|
||||
//process.stdin.pause();
|
||||
|
||||
if (progress === lastProgress || lastProgress === 100) { return; }
|
||||
lastProgress = progress;
|
||||
|
||||
(<any>(process.stdout)).clearLine();
|
||||
(<any>(process.stdout)).cursorTo(0);
|
||||
process.stdout.write(action + "... " + progress + "%");
|
||||
|
||||
if (percent === 1) {
|
||||
process.stdout.write('\n');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const colorSequences: Record<string, string> = {
|
||||
blue: "\x1b[34m",
|
||||
cyan: "\x1b[36m",
|
||||
green: "\x1b[32m",
|
||||
magenta: "\x1b[35m",
|
||||
red: "\x1b[31m",
|
||||
yellow: "\x1b[33m",
|
||||
bold: ""
|
||||
};
|
||||
|
||||
function getColor(color?: string): string {
|
||||
if (!color || color === "normal") { return "\x1b[0m"; }
|
||||
return "\x1b[1m" + colorSequences[color];
|
||||
}
|
||||
|
||||
export type ColorifyFunc = (text: string) => string;
|
||||
|
||||
function _colorify(format: string): ColorifyFunc {
|
||||
return function (text: string): string {
|
||||
if (disableColor) { return text; }
|
||||
return getColor(format) + text.replace(/[^ -~]+/g, "") + getColor();
|
||||
}
|
||||
}
|
||||
|
||||
export const colorify: { [ format: string ]: ColorifyFunc } = Object.freeze({
|
||||
bold: _colorify("bold"),
|
||||
|
||||
blue: _colorify("blue"),
|
||||
green: _colorify("green"),
|
||||
red: _colorify("red"),
|
||||
});
|
||||
|
||||
export type PromptOptions = {
|
||||
choice?: Array<string>;
|
||||
defaultChoice?: string;
|
||||
mask?: string;
|
||||
};
|
||||
|
||||
function _getPrompt(prompt: string, options: PromptOptions, callback: (ctrlC: boolean, message: string) => void) {
|
||||
process.stdout.write(prompt);
|
||||
|
||||
let stdin = process.stdin;
|
||||
stdin.resume();
|
||||
stdin.setRawMode(true);
|
||||
stdin.resume();
|
||||
stdin.setEncoding('utf8');
|
||||
|
||||
let message = '';
|
||||
|
||||
let respond = (ctrlC: boolean, message: string) => {
|
||||
process.stdout.write('\n');
|
||||
stdin.setRawMode(false);
|
||||
stdin.pause();
|
||||
stdin.removeListener('data', handler);
|
||||
callback(ctrlC, message);
|
||||
}
|
||||
|
||||
function handler(chr: string): void {
|
||||
chr = String(chr);
|
||||
|
||||
switch (chr) {
|
||||
// Enter (ish)
|
||||
case "\n":
|
||||
case "\r":
|
||||
case "\u0004":
|
||||
if (options.choice) {
|
||||
if (options.defaultChoice) {
|
||||
respond(null, options.defaultChoice);
|
||||
}
|
||||
} else {
|
||||
respond(null, message);
|
||||
}
|
||||
break;
|
||||
|
||||
// Backspace
|
||||
case "\u007f":
|
||||
if (message.length > 0 && options.choice == null) {
|
||||
message = message.substring(0, message.length - 1);
|
||||
(<any>(process.stdout)).clearLine();
|
||||
(<any>(process.stdout)).cursorTo(0);
|
||||
if (options.mask) {
|
||||
process.stdout.write(prompt + repeat(options.mask, message.length));
|
||||
} else {
|
||||
process.stdout.write(prompt + message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Ctrl-C
|
||||
case "\u0003":
|
||||
process.stdout.write('\n[ CTRL-C ]');
|
||||
respond(true, null);
|
||||
break;
|
||||
|
||||
// Any other character
|
||||
default:
|
||||
if (options.choice) {
|
||||
if (options.choice.indexOf(chr) >= 0) {
|
||||
process.stdout.write(chr);
|
||||
respond(null, chr);
|
||||
}
|
||||
} else {
|
||||
// More passsword characters
|
||||
if (options.mask) {
|
||||
process.stdout.write('*');
|
||||
} else {
|
||||
process.stdout.write(chr);
|
||||
}
|
||||
message += chr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
stdin.on('data', handler);
|
||||
}
|
||||
|
||||
export function getPrompt(prompt: string, options: PromptOptions): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
_getPrompt(prompt, options, (ctrlC, password) => {
|
||||
if (ctrlC) {
|
||||
return reject(new Error("cancelled"));
|
||||
}
|
||||
resolve(password);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getPassword(prompt: string): Promise<string> {
|
||||
return getPrompt(prompt, { mask: "*" });
|
||||
}
|
||||
48
misc/admin/src.ts/npm.ts
Normal file
48
misc/admin/src.ts/npm.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
import semver from "semver";
|
||||
|
||||
import { getUrl } from "./geturl";
|
||||
import { Package, getPackage as _getPackage } from "./local";
|
||||
|
||||
|
||||
const cache: Record<string, any> = { };
|
||||
|
||||
async function getPackageInfo(name: string): Promise<any> {
|
||||
// Convert dirname to package if needed
|
||||
name = _getPackage(name).name;
|
||||
|
||||
if (!cache[name]) {
|
||||
try {
|
||||
const result = await getUrl("http:/" + "/registry.npmjs.org/" + name);
|
||||
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
|
||||
} catch (error) {
|
||||
if (error.status === 404) { return null; }
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return cache[name] || null;
|
||||
}
|
||||
|
||||
export async function getPackage(name: string, version?: string): Promise<Package> {
|
||||
const infos = await getPackageInfo(name);
|
||||
if (infos == null) { return null; }
|
||||
|
||||
if (version == null) {
|
||||
const versions = Object.keys(infos.versions);
|
||||
versions.sort(semver.compare);
|
||||
version = versions.pop();
|
||||
}
|
||||
|
||||
const info = infos.versions[version];
|
||||
|
||||
return {
|
||||
dependencies: (info.dependencies || {}),
|
||||
devDependencies: (info.devDependencies || {}),
|
||||
gitHead: info.gitHead,
|
||||
location: "remote",
|
||||
name: info.name,
|
||||
tarballHash: info.tarballHash,
|
||||
version : info.version,
|
||||
_ethers_nobuild: !!info._ethers_nobuild,
|
||||
};
|
||||
}
|
||||
70
misc/admin/src.ts/path.ts
Normal file
70
misc/admin/src.ts/path.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import fs from "fs";
|
||||
import { resolve as _resolve } from "path";
|
||||
|
||||
export const root: string = _resolve(__dirname, "../../../");
|
||||
|
||||
export function resolve(...args: Array<string>): string {
|
||||
args.unshift(root);
|
||||
return _resolve.apply(null, args);
|
||||
}
|
||||
|
||||
const pathRootPackageJsonPath: string = resolve("package.json");
|
||||
const pathPackages: string = resolve("packages");
|
||||
|
||||
export const dirs = Object.freeze({
|
||||
rootPackageJsonPath: pathRootPackageJsonPath,
|
||||
packages: pathPackages,
|
||||
root,
|
||||
});
|
||||
|
||||
|
||||
type PackageInfo = {
|
||||
dirname: string;
|
||||
packageName: string;
|
||||
packagePath: string;
|
||||
packageJsonPath: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export const dirnames: ReadonlyArray<string> = Object.freeze(fs.readdirSync(dirs.packages).filter((dirname) => {
|
||||
return (dirname[0] !== ".");
|
||||
}));
|
||||
|
||||
const packageLookup = dirnames.reduce((accum, dirname) => {
|
||||
const packagePath = _resolve(dirs.packages, dirname);
|
||||
const packageJsonPath = _resolve(packagePath, "package.json");
|
||||
|
||||
const info = JSON.parse(fs.readFileSync(packageJsonPath).toString());
|
||||
const packageName = info.name;
|
||||
const version = info.version;
|
||||
|
||||
accum[packageName] = accum[dirname] = {
|
||||
dirname, packageName, packagePath, packageJsonPath, version
|
||||
};
|
||||
|
||||
return accum;
|
||||
}, <{ [ name: string ]: PackageInfo }>{ });
|
||||
|
||||
export const packages: ReadonlyArray<string> = Object.freeze(dirnames.map((dirname) => packageLookup[dirname].packageName));
|
||||
|
||||
function getPackageInfo(name: string): PackageInfo {
|
||||
const value = packageLookup[name];
|
||||
if (!value) { throw new Error(`unknown package: ${ name }`); }
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getPackagePath(name: string): string {
|
||||
return getPackageInfo(name).packagePath;
|
||||
}
|
||||
|
||||
export function getDirname(name: string): string {
|
||||
return getPackageInfo(name).dirname;
|
||||
}
|
||||
|
||||
export function getPackageJsonPath(name: string): string {
|
||||
return getPackageInfo(name).packageJsonPath;
|
||||
}
|
||||
|
||||
export function isEthers(name: string) {
|
||||
return !!packageLookup[name];
|
||||
}
|
||||
74
misc/admin/src.ts/run.ts
Normal file
74
misc/admin/src.ts/run.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { spawnSync } from "child_process";
|
||||
|
||||
export type RunResult = {
|
||||
stderr: string | null;
|
||||
_stderr: string | Buffer;
|
||||
|
||||
stdout: string;
|
||||
_stdout: string | Buffer;
|
||||
|
||||
status: number;
|
||||
ok: boolean;
|
||||
};
|
||||
|
||||
export function run(progname: string, args?: Array<string>, currentWorkingDirectory?: string): RunResult {
|
||||
if (args == null) { args = [ ]; }
|
||||
|
||||
const options: any = { };
|
||||
if (currentWorkingDirectory) { options.cwd = currentWorkingDirectory; }
|
||||
const child = spawnSync(progname, args, options);
|
||||
|
||||
const result = {
|
||||
_stderr: child.stderr,
|
||||
stderr: (child.stderr.toString() || null),
|
||||
_stdout: child.stdout,
|
||||
stdout: child.stdout.toString(),
|
||||
status: child.status,
|
||||
ok: (child.stderr.length === 0 && child.status === 0)
|
||||
};
|
||||
|
||||
if (child.error) {
|
||||
(<any>(child.error)).result = result;
|
||||
throw child.error;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
/*
|
||||
const result: RunResult = {
|
||||
stderr: null,
|
||||
_stderr: Buffer.from([]),
|
||||
stdout: null,
|
||||
_stdout: Buffer.from([]),
|
||||
status: null,
|
||||
ok: false,
|
||||
};
|
||||
|
||||
proc.stderr.on("data", (data) => {
|
||||
result._stderr = Buffer.concat([ result._stderr, data ]);
|
||||
});
|
||||
|
||||
proc.stdout.on("data", (data) => {
|
||||
result._stdout = Buffer.concat([ result._stdout, data ]);
|
||||
});
|
||||
|
||||
proc.on("error", (error) => {
|
||||
result.stderr = result._stderr.toString("utf8");
|
||||
result.stdout = result._stdout.toString("utf8");
|
||||
(<any>error).result = result;
|
||||
|
||||
console.log("Error:", error);
|
||||
|
||||
reject(error);
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
result.stderr = result._stderr.toString("utf8");
|
||||
result.stdout = result._stdout.toString("utf8");
|
||||
result.status = code;
|
||||
result.ok = (result._stderr.length === 0 && code === 0);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
*/
|
||||
}
|
||||
106
misc/admin/src.ts/utils.ts
Normal file
106
misc/admin/src.ts/utils.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import fs from "fs";
|
||||
import { dirname, resolve } from "path";
|
||||
|
||||
import { createHash } from "crypto";
|
||||
|
||||
export function repeat(char: string, length: number): string {
|
||||
if (char.length === 0) { return ""; }
|
||||
let output = char;
|
||||
while (output.length < length) { output = output + output; }
|
||||
return output.substring(0, length);
|
||||
}
|
||||
|
||||
export function sha256(content: Buffer): string {
|
||||
const hasher = createHash("sha256");
|
||||
hasher.update(content);
|
||||
return "0x" + hasher.digest("hex");
|
||||
}
|
||||
|
||||
export function sortRecords(record: Record<string, any>): Record<string, any> {
|
||||
const keys = Object.keys(record);
|
||||
keys.sort();
|
||||
|
||||
return keys.reduce((accum, name) => {
|
||||
accum[name] = record[name];
|
||||
return accum;
|
||||
}, <Record<string, any>>{ });
|
||||
}
|
||||
|
||||
export function atomicWrite(path: string, value: string | Uint8Array): void {
|
||||
const tmp = resolve(__dirname, "../../../.atomic-tmp");
|
||||
fs.writeFileSync(tmp, value);
|
||||
fs.renameSync(tmp, path);
|
||||
}
|
||||
|
||||
export function loadJson(path: string): any {
|
||||
return JSON.parse(fs.readFileSync(path).toString());
|
||||
}
|
||||
|
||||
export function saveJson(filename: string, data: any, sort?: boolean): any {
|
||||
|
||||
let replacer: (key: string, value: any) => any = undefined;
|
||||
if (sort) {
|
||||
replacer = (key, value) => {
|
||||
if (Array.isArray(value)) {
|
||||
// pass
|
||||
} else if (value && typeof(value) === "object") {
|
||||
const keys = Object.keys(value);
|
||||
keys.sort();
|
||||
return keys.reduce((accum, key) => {
|
||||
accum[key] = value[key];
|
||||
return accum;
|
||||
}, <Record<string, any>>{});
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
atomicWrite(filename, JSON.stringify(data, replacer, 2) + "\n");
|
||||
}
|
||||
|
||||
export async function resolveProperties(props: Record<string, Promise<any>>): Promise<Record<string, any>> {
|
||||
const keys = Object.keys(props);
|
||||
const promises = await Promise.all(keys.map((k) => props[k]));
|
||||
return keys.reduce((accum, key, index) => {
|
||||
accum[key] = promises[index];
|
||||
return accum;
|
||||
}, <Record<string, any>>{});
|
||||
}
|
||||
|
||||
// Node 8 does not support recursive mkdir... Remove this in v6.
|
||||
export function mkdir(path: string): void {
|
||||
let bail = 0;
|
||||
const dirs = [ ];
|
||||
while (path !== "/") {
|
||||
if (bail++ > 50) { throw new Error("something bad happened..."); }
|
||||
|
||||
if (fs.existsSync(path)) { break; }
|
||||
dirs.push(path);
|
||||
path = dirname(path);
|
||||
}
|
||||
|
||||
while (dirs.length) {
|
||||
fs.mkdirSync(dirs.pop());
|
||||
}
|
||||
}
|
||||
|
||||
function zpad(value: number, length?: number): string {
|
||||
if (length == null) { length = 2; }
|
||||
const str = String(value);
|
||||
return repeat("0", length - str.length) + str;
|
||||
}
|
||||
|
||||
function getDate(date: Date): string {
|
||||
return [
|
||||
date.getFullYear(),
|
||||
zpad(date.getMonth() + 1),
|
||||
zpad(date.getDate())
|
||||
].join("-");
|
||||
}
|
||||
|
||||
export function getDateTime(date: Date): string {
|
||||
return getDate(date) + " " + [
|
||||
zpad(date.getHours()) ,
|
||||
zpad(date.getMinutes() + 1)
|
||||
].join(":");
|
||||
}
|
||||
39
misc/admin/thirdparty.d.ts
vendored
Normal file
39
misc/admin/thirdparty.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
declare module "aes-js" {
|
||||
export class Counter {
|
||||
constructor(iv: Uint8Array);
|
||||
}
|
||||
export namespace ModeOfOperation {
|
||||
class cbc{
|
||||
constructor(key: Uint8Array, iv: Uint8Array);
|
||||
decrypt(data: Uint8Array): Uint8Array;
|
||||
encrypt(data: Uint8Array): Uint8Array;
|
||||
}
|
||||
class ctr{
|
||||
constructor(key: Uint8Array, counter: Counter);
|
||||
decrypt(data: Uint8Array): Uint8Array;
|
||||
encrypt(data: Uint8Array): Uint8Array;
|
||||
}
|
||||
}
|
||||
export namespace padding {
|
||||
export namespace pkcs7 {
|
||||
export function strip(data: Uint8Array): Uint8Array;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare module "tar" {
|
||||
export type CreateOptions = {
|
||||
sync?: boolean,
|
||||
cwd?: string,
|
||||
prefix?: string,
|
||||
gzip?: boolean,
|
||||
portable?: boolean,
|
||||
mtime?: Date
|
||||
};
|
||||
|
||||
export interface Readable {
|
||||
read(): Buffer;
|
||||
}
|
||||
|
||||
export function create(options: CreateOptions, files: Array<string>): Readable;
|
||||
}
|
||||
31
misc/admin/tsconfig.json
Normal file
31
misc/admin/tsconfig.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"lib": ["es2015", "es5", "dom"],
|
||||
"module": "commonjs",
|
||||
"target": "es2015",
|
||||
"moduleResolution": "node",
|
||||
|
||||
"outDir": "./lib/",
|
||||
|
||||
"declaration": true,
|
||||
|
||||
"preserveSymlinks": true,
|
||||
|
||||
"preserveWatchOutput": true,
|
||||
"pretty": false,
|
||||
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true
|
||||
},
|
||||
"include": [
|
||||
"./thirdparty.d.ts",
|
||||
"./src.ts/*.ts",
|
||||
"./src.ts/cmds/*.ts"
|
||||
],
|
||||
"exclude": [ ]
|
||||
}
|
||||
19521
package-lock.json
generated
19521
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
90
package.json
90
package.json
@@ -6,58 +6,60 @@
|
||||
"url": "git://github.com/ethers-io/ethers.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "npm run bootstrap",
|
||||
"auto-build": "node ./admin/cmds/reset-build.js && npm run build -- -w",
|
||||
"auto-build-esm": "node ./admin/cmds/set-option esm && npm run build -- -w",
|
||||
"bootstrap": "node ./admin/cmds/reset-build.js && node ./admin/cmds/update-depgraph && lerna bootstrap --hoist",
|
||||
"preinstall": "npm run bootstrap-hoist",
|
||||
"postinstall": "node ./misc/admin/lib/cmds/update-depgraph && npm run bootstrap-link",
|
||||
"bootstrap-hoist": "node ./misc/admin/lib/cmds/hoist",
|
||||
"bootstrap-link": "node ./misc/admin/lib/cmds/link",
|
||||
"auto-build": "node ./misc/admin/lib/cmds/set-build-option cjs && npm run build -- -w",
|
||||
"auto-build-esm": "node ./misc/admin/lib/cmds/set-build-option esm && npm run build -- -w",
|
||||
"build": "tsc --build ./tsconfig.project.json",
|
||||
"_build-cjs": "node ./admin/cmds/set-option cjs && npm run build",
|
||||
"_build-esm": "node ./admin/cmds/set-option esm && npm run build",
|
||||
"build-all": "node ./admin/cmds/update-exports.js && npm run _build-esm && npm run _build-cjs && npm run _dist",
|
||||
"_dist-ancillary": "node ./admin/cmds/set-option esm && rollup -c rollup-ancillary.config.js",
|
||||
"_dist-umd": "node ./admin/cmds/set-option cjs browser-lang-all && rollup -c && mv ./packages/ethers/dist/ethers.umd.min.js ./packages/ethers/dist/ethers-all.umd.min.js && node ./admin/cmds/set-option cjs && rollup -c",
|
||||
"_dist-esm": "node ./admin/cmds/set-option esm browser-lang-all && rollup -c --configModule && mv ./packages/ethers/dist/ethers.esm.min.js ./packages/ethers/dist/ethers-all.esm.min.js && node ./admin/cmds/set-option esm && rollup -c --configModule",
|
||||
"_dist-all": "npm run _dist-esm && npm run _dist-ancillary && npm run _dist-umd",
|
||||
"_dist": "node admin/cmds/npm-skip-node8.js || npm run _dist-all",
|
||||
"clean": "node ./admin/cmds/reset-build.js && tsc --build --clean ./tsconfig.project.json",
|
||||
"dist-shims": "cd packages/shims && npm run dist",
|
||||
"_dist-test-esm": "rollup -c rollup-tests.config.js --configModule",
|
||||
"_dist-test-umd": "rollup -c rollup-tests.config.js",
|
||||
"_build-cjs": "node ./misc/admin/lib/cmds/echo 'Building CommonJS libraries...' && node ./misc/admin/lib/cmds/set-build-option cjs && npm run build",
|
||||
"_build-esm": "node ./misc/admin/lib/cmds/echo 'Building ES modules libraries...' && node ./misc/admin/lib/cmds/set-build-option esm && npm run build",
|
||||
"clean": "node ./misc/admin/lib/cmds/echo 'Cleaning all build files...' && rm -rf packages/*/lib packages/*/lib.esm packages/*/node_modules packages/*/dist/*.js packages/*/tsconfig.tsbuildinfo node_modules .package_node_modules package-lock.json",
|
||||
"_test-esm-dist": "rollup -c rollup-tests.config.js --configModule",
|
||||
"_test-umd-dist": "rollup -c rollup-tests.config.js",
|
||||
"_test-browser-umd": "karma start --single-run --browsers HeadlessLittleLiar karma-umd.conf.js",
|
||||
"_test-browser-esm": "karma start --single-run --browsers HeadlessLittleLiar karma-esm.conf.js",
|
||||
"test-browser-umd": "npm run _dist-test-umd && npm run _test-browser-umd",
|
||||
"test-browser-esm": "npm run _dist-test-esm && npm run _test-browser-esm",
|
||||
"test-node": "mocha --no-colors --reporter ./packages/tests/reporter ./packages/tests/lib/test-*.js",
|
||||
"test-react": "npm run _dist-test-umd && npm run dist-shims && pushd misc/ReactNativeTestApp && ./run-tests.sh && popd",
|
||||
"test": "npm run build-all && npm run test-node",
|
||||
"test-browser-umd": "npm run _test-umd-dist && npm run _test-browser-umd",
|
||||
"test-browser-esm": "npm run _test-esm-dist && npm run _test-browser-esm",
|
||||
"test-coverage": "nyc --report-dir=output --reporter=lcov --reporter=text mocha --reporter ./packages/tests/reporter-keepalive ./packages/tests/lib/test-*.js | tee output/summary.txt",
|
||||
"lock-versions": "node ./admin/cmds/lock-versions",
|
||||
"test-node": "mocha --no-colors --reporter ./packages/tests/reporter ./packages/tests/lib/test-*.js",
|
||||
"test-react": "npm run _test-umd-dist && npm run build-dist-shims && pushd misc/ReactNativeTestApp && ./run-tests.sh && popd",
|
||||
"test": "npm run build-all && npm run test-node",
|
||||
"build-docs": "flatworm docs.wrm docs",
|
||||
"serve-docs": "node ./admin/cmds/serve-docs.js",
|
||||
"serve-docs": "node ./misc/admin/lib/cmds/serve-docs.js",
|
||||
"test-docs": "npm run build-docs && npm run serve-docs",
|
||||
"upload-docs": " node ./admin/cmds/upload-docs.js",
|
||||
"spell-check": "node admin/cmds/spell-check.js",
|
||||
"_admin_prepare": "npm run clean && npm run bootstrap && npm run build && node ./admin/cmds/update-exports.js",
|
||||
"update-versions": "npm run spell-check && npm run _admin_prepare && node ./admin/cmds/update-versions",
|
||||
"publish-all": "node ./admin/cmds/publish",
|
||||
"sync-github": "node ./admin/cmds/cache-github"
|
||||
"TODO-upload-docs": " node ./admin/cmds/upload-docs.js",
|
||||
"spell-check": "node ./misc/admin/lib/cmds/spell-check.js",
|
||||
"build-dist-ancillary": "node ./misc/admin/lib/cmds/set-build-option esm && rollup -c rollup-ancillary.config.js",
|
||||
"build-dist-shims": "browserify ./packages/shims/src/index.js -o ./packages/shims/dist/index.js && uglifyjs --compress --mangle --output ./packages/shims/dist/index.min.js -- ./packages/shims/dist/index.js",
|
||||
"build-dist-umd": "node ./misc/admin/lib/cmds/set-build-option cjs browser-lang-all && rollup -c && mv ./packages/ethers/dist/ethers.umd.min.js ./packages/ethers/dist/ethers-all.umd.min.js && node ./misc/admin/lib/cmds/set-build-option cjs && rollup -c",
|
||||
"build-dist-esm": "node ./misc/admin/lib/cmds/set-build-option esm browser-lang-all && rollup -c --configModule && mv ./packages/ethers/dist/ethers.esm.min.js ./packages/ethers/dist/ethers-all.esm.min.js && node ./misc/admin/lib/cmds/set-build-option esm && rollup -c --configModule",
|
||||
"_build-dist": "node ./misc/admin/lib/cmds/echo 'Building dist files...' && npm run build-dist-shims && npm run build-dist-esm && npm run build-dist-ancillary && npm run build-dist-umd",
|
||||
"build-dist": "node ./misc/admin/lib/cmds/npm-skip-node8.js || npm run _build-dist",
|
||||
"build-libs": "node ./misc/admin/lib/cmds/update-exports.js && npm run _build-cjs && npm run _build-esm && node ./misc/admin/lib/cmds/set-build-option cjs && node packages/asm/generate.js && chmod 755 packages/*/lib/bin/*.js",
|
||||
"build-all": "npm run build-libs && npm run build-dist",
|
||||
"update-versions": "npm run clean && npm install && npm run spell-check && npm run build-all && node ./misc/admin/lib/cmds/bump-versions && npm run build-all && node ./misc/admin/lib/cmds/update-hashes && node ./misc/admin/lib/cmds/update-changelog",
|
||||
"TODO-publish-all": "node ./admin/cmds/publish",
|
||||
"TODO-sync-github": "node ./admin/cmds/cache-github"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@erquhart/rollup-plugin-node-builtins": "2.1.5",
|
||||
"@types/assert": "^1.4.1",
|
||||
"@types/mocha": "^5.2.0",
|
||||
"@types/node": "^12.7.4",
|
||||
"@types/semver": "^7.3.4",
|
||||
"aes-js": "3.0.0",
|
||||
"aws-sdk": "2.137.0",
|
||||
"browserify": "16.2.3",
|
||||
"diff": "4.0.1",
|
||||
"flatworm": "0.0.2-beta.4",
|
||||
"jison": "^0.4.18",
|
||||
"karma": "5.1.0",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-mocha": "2.0.1",
|
||||
"lerna": "3.22.1",
|
||||
"libnpmpublish": "1.1.3",
|
||||
"libnpmpublish": "3.0.1",
|
||||
"mocha": "^7.1.1",
|
||||
"npm-packlist": "1.4.1",
|
||||
"nyc": "15.1.0",
|
||||
"rollup": "1.20.1",
|
||||
"rollup-plugin-commonjs": "10.0.2",
|
||||
@@ -68,7 +70,27 @@
|
||||
"rollup-pluginutils": "2.8.1",
|
||||
"scrypt-js": "3.0.1",
|
||||
"semver": "^5.6.0",
|
||||
"tar": "4.4.8",
|
||||
"typescript": "3.8.3"
|
||||
"typescript": "3.8.3",
|
||||
"uglify-es": "3.3.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": "7.8.4",
|
||||
"@babel/types": "7.8.3",
|
||||
"@ledgerhq/hw-app-eth": "5.3.0",
|
||||
"@ledgerhq/hw-transport": "5.3.0",
|
||||
"@ledgerhq/hw-transport-u2f": "5.3.0",
|
||||
"@types/mocha": "^5.2.0",
|
||||
"aes-js": "3.0.0",
|
||||
"bech32": "1.1.4",
|
||||
"bn.js": "^4.4.0",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"elliptic": "6.5.3",
|
||||
"hash.js": "1.1.3",
|
||||
"js-sha3": "0.5.7",
|
||||
"mime-types": "2.1.11",
|
||||
"scrypt-js": "3.0.1",
|
||||
"solc": "0.7.1",
|
||||
"solidity-parser-antlr": "^0.3.2",
|
||||
"ws": "7.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
tsconfig.json
|
||||
src.ts/
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
2
packages/abi/lib.esm/_version.d.ts
vendored
2
packages/abi/lib.esm/_version.d.ts
vendored
@@ -1 +1 @@
|
||||
export declare const version = "abi/5.0.5";
|
||||
export declare const version = "abi/5.0.6";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export const version = "abi/5.0.5";
|
||||
export const version = "abi/5.0.6";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
2
packages/abi/lib/_version.d.ts
vendored
2
packages/abi/lib/_version.d.ts
vendored
@@ -1 +1 @@
|
||||
export declare const version = "abi/5.0.5";
|
||||
export declare const version = "abi/5.0.6";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = "abi/5.0.5";
|
||||
exports.version = "abi/5.0.6";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
@@ -31,7 +31,7 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"tarballHash": "0x72e2d79207141b5d847504c349b75add9d423a8bd4408eda0a14933e6ea4d803",
|
||||
"tarballHash": "0x5b932b3bf61ca5d2e09dcadec286bd2d06023608801f8e01bba2fb8c86d8b54b",
|
||||
"types": "./lib/index.d.ts",
|
||||
"version": "5.0.5"
|
||||
"version": "5.0.6"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const version = "abi/5.0.5";
|
||||
export const version = "abi/5.0.6";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.package.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src.ts",
|
||||
"outDir": "./lib/"
|
||||
"outDir": "./lib/",
|
||||
"rootDir": "./src.ts"
|
||||
},
|
||||
"exclude": [],
|
||||
"extends": "../../tsconfig.package.json",
|
||||
"include": [
|
||||
"./src.ts/*.ts",
|
||||
"./src.ts/coders/*.ts"
|
||||
],
|
||||
"exclude": []
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
tsconfig.json
|
||||
src.ts/
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
@@ -1 +1 @@
|
||||
export declare const version = "abstract-provider/5.0.4";
|
||||
export declare const version = "abstract-provider/5.0.5";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user