mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
425 lines
14 KiB
JavaScript
Executable File
425 lines
14 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const colors = require("../cli/util/colors");
|
|
const version = require("../package.json").version;
|
|
const options = require("../cli/util/options");
|
|
|
|
const npmDefaultTest = "echo \"Error: no test specified\" && exit 1";
|
|
|
|
const commands = {
|
|
"npm": {
|
|
install: "npm install",
|
|
run: "npm run",
|
|
test: "npm test"
|
|
},
|
|
"yarn": {
|
|
install: "yarn install",
|
|
run: "yarn",
|
|
test: "yarn test"
|
|
},
|
|
"pnpm": {
|
|
install: "pnpm install",
|
|
run: "pnpm run",
|
|
test: "pnpm test"
|
|
}
|
|
};
|
|
|
|
let pm = "npm";
|
|
if (typeof process.env.npm_config_user_agent === "string") {
|
|
if (/\byarn\//.test(process.env.npm_config_user_agent)) {
|
|
pm = "yarn";
|
|
} else if (/\bpnpm\//.test(process.env.npm_config_user_agent)) {
|
|
pm = "pnpm";
|
|
}
|
|
}
|
|
|
|
const asinitOptions = {
|
|
"help": {
|
|
"category": "General",
|
|
"description": "Prints a help message.",
|
|
"type": "b",
|
|
"alias": "h"
|
|
},
|
|
"yes": {
|
|
"category": "General",
|
|
"description": "Answers all questions with their default option for non-interactive usage.",
|
|
"type": "b",
|
|
"alias": "y"
|
|
}
|
|
};
|
|
|
|
const cliOptions = options.parse(process.argv.slice(2), asinitOptions);
|
|
|
|
if (cliOptions.options.help || cliOptions.arguments.length === 0) printHelp();
|
|
|
|
function printHelp() {
|
|
console.log([
|
|
"Sets up a new AssemblyScript project or updates an existing one.",
|
|
"For example, to create a new project in the current directory:",
|
|
"",
|
|
" " + colors.cyan("asinit") + " .",
|
|
].join("\n"));
|
|
process.exit(0);
|
|
}
|
|
|
|
const projectDir = path.resolve(cliOptions.arguments[0]);
|
|
const compilerDir = path.join(__dirname, "..");
|
|
const compilerVersion = require(path.join(compilerDir, "package.json")).version;
|
|
const assemblyDir = path.join(projectDir, "assembly");
|
|
const tsconfigFile = path.join(assemblyDir, "tsconfig.json");
|
|
const asconfigFile = path.join(projectDir, "asconfig.json");
|
|
let tsconfigBase = path.relative(assemblyDir, path.join(compilerDir, "std", "assembly.json"));
|
|
if (/^(\.\.[/\\])*node_modules[/\\]assemblyscript[/\\]/.test(tsconfigBase)) {
|
|
// Use node resolution if the compiler is a normal dependency
|
|
tsconfigBase = "assemblyscript/std/assembly.json";
|
|
}
|
|
const entryFile = path.join(assemblyDir, "index.ts");
|
|
const buildDir = path.join(projectDir, "build");
|
|
const testsDir = path.join(projectDir, "tests");
|
|
const gitignoreFile = path.join(buildDir, ".gitignore");
|
|
const packageFile = path.join(projectDir, "package.json");
|
|
const indexFile = path.join(projectDir, "index.js");
|
|
const testsIndexFile = path.join(testsDir, "index.js");
|
|
|
|
console.log([
|
|
"Version: " + version,
|
|
"",
|
|
colors.white([
|
|
"This command will make sure that the following files exist in the project",
|
|
"directory '" + projectDir + "':"
|
|
].join("\n")),
|
|
"",
|
|
colors.cyan(" ./assembly"),
|
|
" Directory holding the AssemblyScript sources being compiled to WebAssembly.",
|
|
"",
|
|
colors.cyan(" ./assembly/tsconfig.json"),
|
|
" TypeScript configuration inheriting recommended AssemblyScript settings.",
|
|
"",
|
|
colors.cyan(" ./assembly/index.ts"),
|
|
" Example entry file being compiled to WebAssembly to get you started.",
|
|
"",
|
|
colors.cyan(" ./build"),
|
|
" Build artifact directory where compiled WebAssembly files are stored.",
|
|
"",
|
|
colors.cyan(" ./build/.gitignore"),
|
|
" Git configuration that excludes compiled binaries from source control.",
|
|
"",
|
|
colors.cyan(" ./index.js"),
|
|
" Main file loading the WebAssembly module and exporting its exports.",
|
|
"",
|
|
colors.cyan(" ./tests/index.js"),
|
|
" Example test to check that your module is indeed working.",
|
|
"",
|
|
colors.cyan(" ./asconfig.json"),
|
|
" Configuration file defining both a 'debug' and a 'release' target.",
|
|
"",
|
|
colors.cyan(" ./package.json"),
|
|
" Package info containing the necessary commands to compile to WebAssembly.",
|
|
"",
|
|
"The command will try to update existing files to match the correct settings",
|
|
"for this instance of the compiler in '" + compilerDir + "'.",
|
|
""
|
|
].join("\n"));
|
|
|
|
function createProject(answer) {
|
|
if (!/^y?$/i.test(answer)) {
|
|
process.exit(1);
|
|
return;
|
|
}
|
|
console.log();
|
|
ensureProjectDirectory();
|
|
ensureAssemblyDirectory();
|
|
ensureTsconfigJson();
|
|
ensureEntryFile();
|
|
ensureBuildDirectory();
|
|
ensureGitignore();
|
|
ensurePackageJson();
|
|
ensureIndexJs();
|
|
ensureTestsDirectory();
|
|
ensureTestsIndexJs();
|
|
ensureAsconfigJson();
|
|
console.log([
|
|
colors.green("Done!"),
|
|
"",
|
|
"Don't forget to install dependencies before you start:",
|
|
"",
|
|
colors.white(" " + commands[pm].install),
|
|
"",
|
|
"To edit the entry file, open '" + colors.cyan("assembly/index.ts") + "' in your editor of choice.",
|
|
"Create as many additional files as necessary and use them as imports.",
|
|
"",
|
|
"To build the entry file to WebAssembly when you are ready, run:",
|
|
"",
|
|
colors.white(" " + commands[pm].run + " asbuild"),
|
|
"",
|
|
"Running the command above creates the following binaries incl. their respective",
|
|
"text format representations and source maps:",
|
|
"",
|
|
colors.cyan(" ./build/untouched.wasm"),
|
|
colors.cyan(" ./build/untouched.wasm.map"),
|
|
colors.cyan(" ./build/untouched.wat"),
|
|
"",
|
|
" ^ The untouched WebAssembly module as generated by the compiler.",
|
|
" This one matches your sources exactly, without any optimizations.",
|
|
"",
|
|
colors.cyan(" ./build/optimized.wasm"),
|
|
colors.cyan(" ./build/optimized.wasm.map"),
|
|
colors.cyan(" ./build/optimized.wat"),
|
|
"",
|
|
" ^ The optimized WebAssembly module using default optimization settings.",
|
|
" You can change the optimization settings in '" + colors.cyan("package.json")+ "'.",
|
|
"",
|
|
"To run the tests, do:",
|
|
"",
|
|
colors.white(" " + commands[pm].test),
|
|
"",
|
|
"The AssemblyScript documentation covers all the details:",
|
|
"",
|
|
" https://docs.assemblyscript.org",
|
|
"",
|
|
"Have a nice day!"
|
|
].join("\n"));
|
|
}
|
|
|
|
if (cliOptions.options.yes) {
|
|
createProject("y");
|
|
} else {
|
|
const rl = require("readline").createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
rl.question(colors.white("Do you want to proceed?") + " [Y/n] ", result => {
|
|
rl.close();
|
|
createProject(result);
|
|
});
|
|
}
|
|
|
|
function ensureProjectDirectory() {
|
|
console.log("- Making sure that the project directory exists...");
|
|
if (!fs.existsSync(projectDir)) {
|
|
fs.mkdirSync(projectDir);
|
|
console.log(colors.green(" Created: ") + projectDir);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + projectDir);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureAssemblyDirectory() {
|
|
console.log("- Making sure that the 'assembly' directory exists...");
|
|
if (!fs.existsSync(assemblyDir)) {
|
|
fs.mkdirSync(assemblyDir);
|
|
console.log(colors.green(" Created: ") + assemblyDir);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + assemblyDir);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureTsconfigJson() {
|
|
console.log("- Making sure that 'assembly/tsconfig.json' is set up...");
|
|
const base = tsconfigBase.replace(/\\/g, "/");
|
|
if (!fs.existsSync(tsconfigFile)) {
|
|
fs.writeFileSync(tsconfigFile, JSON.stringify({
|
|
"extends": base,
|
|
"include": [
|
|
"./**/*.ts"
|
|
]
|
|
}, null, 2));
|
|
console.log(colors.green(" Created: ") + tsconfigFile);
|
|
|
|
} else {
|
|
let tsconfig = JSON.parse(fs.readFileSync(tsconfigFile, "utf8"));
|
|
tsconfig["extends"] = base;
|
|
fs.writeFileSync(tsconfigFile, JSON.stringify(tsconfig, null, 2));
|
|
console.log(colors.green(" Updated: ") + tsconfigFile);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureAsconfigJson() {
|
|
console.log("- Making sure that 'asconfig.json' is set up...");
|
|
if (!fs.existsSync(asconfigFile)) {
|
|
fs.writeFileSync(asconfigFile, JSON.stringify({
|
|
targets: {
|
|
debug: {
|
|
// -b build/untouched.wasm -t build/untouched.wat --sourceMap --debug
|
|
binaryFile: "build/untouched.wasm",
|
|
textFile: "build/untouched.wat",
|
|
sourceMap: true,
|
|
debug: true
|
|
},
|
|
release: {
|
|
// -b build/optimized.wasm -t build/optimized.wat --sourceMap --optimize
|
|
binaryFile: "build/optimized.wasm",
|
|
textFile: "build/optimized.wat",
|
|
sourceMap: true,
|
|
optimizeLevel: 3,
|
|
shrinkLevel: 0,
|
|
converge: false,
|
|
noAssert: false
|
|
}
|
|
},
|
|
options: {}
|
|
}, null, 2));
|
|
console.log(colors.green(" Created: ") + asconfigFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + asconfigFile);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureEntryFile() {
|
|
console.log("- Making sure that 'assembly/index.ts' exists...");
|
|
if (!fs.existsSync(entryFile)) {
|
|
fs.writeFileSync(entryFile, [
|
|
"// The entry file of your WebAssembly module.",
|
|
"",
|
|
"export function add(a: i32, b: i32): i32 {",
|
|
" return a + b;",
|
|
"}"
|
|
].join("\n") + "\n");
|
|
console.log(colors.green(" Created: ") + entryFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + entryFile);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureBuildDirectory() {
|
|
console.log("- Making sure that the 'build' directory exists...");
|
|
if (!fs.existsSync(buildDir)) {
|
|
fs.mkdirSync(buildDir);
|
|
console.log(colors.green(" Created: ") + buildDir);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + buildDir);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureGitignore() {
|
|
console.log("- Making sure that 'build/.gitignore' is set up...");
|
|
if (!fs.existsSync(gitignoreFile)) {
|
|
fs.writeFileSync(gitignoreFile, [
|
|
"*.wasm",
|
|
"*.wasm.map",
|
|
"*.asm.js"
|
|
].join("\n") + "\n");
|
|
console.log(colors.green(" Created: ") + gitignoreFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + gitignoreFile);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensurePackageJson() {
|
|
console.log("- Making sure that 'package.json' contains the build commands...");
|
|
const entryPath = path.relative(projectDir, entryFile).replace(/\\/g, "/");
|
|
const buildUntouched = "asc " + entryPath + " --target debug";
|
|
const buildOptimized = "asc " + entryPath + " --target release";
|
|
const buildAll = commands[pm].run + " asbuild:untouched && " + commands[pm].run + " asbuild:optimized";
|
|
if (!fs.existsSync(packageFile)) {
|
|
fs.writeFileSync(packageFile, JSON.stringify({
|
|
"scripts": {
|
|
"asbuild:untouched": buildUntouched,
|
|
"asbuild:optimized": buildOptimized,
|
|
"asbuild": buildAll,
|
|
"test": "node tests"
|
|
},
|
|
"dependencies": {
|
|
"@assemblyscript/loader": "^" + compilerVersion
|
|
},
|
|
"devDependencies": {
|
|
"assemblyscript": "^" + compilerVersion
|
|
}
|
|
}, null, 2));
|
|
console.log(colors.green(" Created: ") + packageFile);
|
|
} else {
|
|
let pkg = JSON.parse(fs.readFileSync(packageFile));
|
|
let scripts = pkg.scripts || {};
|
|
let updated = false;
|
|
if (!scripts["asbuild"]) {
|
|
scripts["asbuild:untouched"] = buildUntouched;
|
|
scripts["asbuild:optimized"] = buildOptimized;
|
|
scripts["asbuild"] = buildAll;
|
|
pkg["scripts"] = scripts;
|
|
updated = true;
|
|
}
|
|
if (!scripts["test"] || scripts["test"] == npmDefaultTest) {
|
|
scripts["test"] = "node tests";
|
|
pkg["scripts"] = scripts;
|
|
updated = true;
|
|
}
|
|
let dependencies = pkg["dependencies"] || {};
|
|
if (!dependencies["@assemblyscript/loader"]) {
|
|
dependencies["@assemblyscript/loader"] = "^" + compilerVersion;
|
|
pkg["dependencies"] = dependencies;
|
|
updated = true;
|
|
}
|
|
let devDependencies = pkg["devDependencies"] || {};
|
|
if (!devDependencies["assemblyscript"]) {
|
|
devDependencies["assemblyscript"] = "^" + compilerVersion;
|
|
pkg["devDependencies"] = devDependencies;
|
|
updated = true;
|
|
}
|
|
if (updated) {
|
|
fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2));
|
|
console.log(colors.green(" Updated: ") + packageFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + packageFile);
|
|
}
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureIndexJs() {
|
|
console.log("- Making sure that 'index.js' exists...");
|
|
if (!fs.existsSync(indexFile)) {
|
|
// since node.js v13.2.0 or v12.17.0 we can use ESM without flags
|
|
const ver = process.versions.node.split('.');
|
|
const maj = parseInt(ver[0]);
|
|
const min = parseInt(ver[1]);
|
|
const supportESM = maj >= 14 || (maj == 13 && min >= 2) || (maj == 12 && min >= 17);
|
|
fs.writeFileSync(indexFile, [
|
|
"const fs = require(\"fs\");",
|
|
"const loader = require(\"@assemblyscript/loader" + (supportESM ? "" : "/umd") + "\");",
|
|
"const imports = { /* imports go here */ };",
|
|
"const wasmModule = loader.instantiateSync(fs.readFileSync(__dirname + \"/build/optimized.wasm\"), imports);",
|
|
"module.exports = wasmModule.exports;"
|
|
].join("\n") + "\n");
|
|
console.log(colors.green(" Created: ") + indexFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + indexFile);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureTestsDirectory() {
|
|
console.log("- Making sure that the 'tests' directory exists...");
|
|
if (!fs.existsSync(testsDir)) {
|
|
fs.mkdirSync(testsDir);
|
|
console.log(colors.green(" Created: ") + testsDir);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + testsDir);
|
|
}
|
|
console.log();
|
|
}
|
|
|
|
function ensureTestsIndexJs() {
|
|
console.log("- Making sure that 'tests/index.js' exists...");
|
|
if (!fs.existsSync(testsIndexFile)) {
|
|
fs.writeFileSync(testsIndexFile, [
|
|
"const assert = require(\"assert\");",
|
|
"const myModule = require(\"..\");",
|
|
"assert.strictEqual(myModule.add(1, 2), 3);",
|
|
"console.log(\"ok\");"
|
|
].join("\n") + "\n");
|
|
console.log(colors.green(" Created: ") + testsIndexFile);
|
|
} else {
|
|
console.log(colors.yellow(" Exists: ") + testsIndexFile);
|
|
}
|
|
console.log();
|
|
}
|