UNPKG

@moonsong-labs/moonwall-cli

Version:

Testing framework for the Moon family of projects

425 lines (412 loc) 13.2 kB
import { fetchArtifact } from "./chunk-UKF5VW3F.js"; import { generateConfig } from "./chunk-FN5ZWO77.js"; import { runNetwork } from "./chunk-4KPQVQED.js"; import { testCmd } from "./chunk-NWVZXZ7E.js"; import { importJsonConfig } from "./chunk-3P647NU6.js"; // src/cmds/main.ts import chalk from "chalk"; import inquirer from "inquirer"; import PressToContinuePrompt from "inquirer-press-to-continue"; import colors from "colors"; import clear from "clear"; // package.json var package_default = { name: "@moonsong-labs/moonwall-cli", type: "module", version: "0.3.1", description: "Testing framework for the Moon family of projects", author: "timbrinded", license: "ISC", homepage: "https://github.com/Moonsong-Labs/moonwall#readme", repository: { type: "git", url: "git+https://github.com/Moonsong-Labs/moonwall.git", directory: "packages/moonwall" }, bugs: { url: "https://github.com/Moonsong-Labs/moonwall/issues" }, keywords: [ "moonwall", "moonbeam", "moondance", "polkadot", "kusama", "substrate" ], exports: "./dist/index.js", module: "./dist/index.mjs", types: "./dist/index.d.ts", bin: { moonwall: "./moonwall.mjs" }, engines: { node: ">=14.16.0", pnpm: ">=7" }, files: [ "dist", "bin", "*.d.ts", "*.d.cts", "*.mjs", "*.cjs" ], scripts: { build: "pnpm exec rimraf dist && tsup src --format cjs,esm --dts ", watch: "tsup src --format cjs,esm --dts --watch", typecheck: "pnpm exec tsc --noEmit", prepublish: "pnpm run build", prepare: "pnpm build", schema: "typescript-json-schema ./src/types/config.ts MoonwallConfig > config_schema.json", compile: "pnpm build ", lint: "tsc" }, dependencies: { "@acala-network/chopsticks": "^0.5.10", "@moonbeam-network/api-augment": "^0.2201.0", "@moonsong-labs/moonwall-util": "workspace:*", "@polkadot/api": "^10.2.1", "@polkadot/api-augment": "^10.2.1", "@polkadot/api-derive": "^10.2.1", "@polkadot/keyring": "^11.1.2", "@polkadot/types": "^10.2.1", "@polkadot/types-codec": "^10.2.1", "@polkadot/util": "^11.1.2", "@types/cli-progress": "^3.11.0", "@types/node": "^18.15.10", "@types/yargs": "^17.0.23", bottleneck: "^2.19.5", chalk: "^5.2.0", clear: "^0.1.0", "cli-progress": "^3.12.0", colors: "^1.4.0", debug: "^4.3.4", dotenv: "^16.0.3", ethers: "^6.2.3", inquirer: "^8.2.5", "inquirer-press-to-continue": "^1.1.4", "moonbeam-types-bundle": "^2.0.10", "node-fetch": "^3.3.1", prettier: "^2.8.7", "pretty-bytes": "^6.1.0", "request-progress": "^3.0.0", semver: "^7.3.8", superagent: "^8.0.9", "ts-node": "^10.9.1", tsup: "^6.7.0", vitest: "^0.29.7", web3: "4.0.1-rc.0", "web3-providers-ws": "4.0.1-rc.0", ws: "^8.13.0", yaml: "^2.2.1", yargs: "^17.7.1" }, devDependencies: { "@types/debug": "^4.1.7", "@vitest/ui": "^0.28.5", "regenerator-runtime": "^0.13.11", typescript: "^4.9.5", "typescript-json-schema": "^0.55.0" }, pnpm: { overrides: { "@moonsong-labs/moonwall-util": "workspace:*", "@polkadot/rpc-provider": "$@polkadot/rpc-provider", "@polkadot/util": "$@polkadot/rpc-provider", "@polkadot/keyring": "$@polkadot/rpc-provider", "@polkadot/api": "$@polkadot/api", "@polkadot/types": "$@polkadot/api" } }, publishConfig: { access: "public" } }; // src/cmds/main.ts import { SemVer, lt } from "semver"; import fetch from "node-fetch"; inquirer.registerPrompt("press-to-continue", PressToContinuePrompt); async function main() { while (true) { let globalConfig; try { globalConfig = await importJsonConfig(); } catch (e) { console.log(e); } clear(); await printIntro(); if (await mainMenu(globalConfig)) { break; } else { continue; } } process.stdout.write(`Goodbye! \u{1F44B} `); process.exit(0); } async function mainMenu(config) { const configPresent = config !== void 0; const questionList = { name: "MenuChoice", type: "list", message: `Main Menu - Please select one of the following:`, default: 0, pageSize: 12, choices: [ { name: !configPresent ? "1) Initialise: Generate a new Moonwall Config File." : chalk.dim("1) Initialise: \u2705 CONFIG ALREADY GENERATED"), value: "init", disabled: configPresent }, { name: configPresent ? `2) Network Launcher & Toolbox: Launch network, access tools: tail logs, interactive tests etc.` : chalk.dim("2) Network Launcher & Toolbox NO CONFIG FOUND"), value: "run", disabled: !configPresent }, { name: configPresent ? "3) Test Suite Execution: Run automated tests, start network if needed." : chalk.dim("3) Test Suite Execution: NO CONFIG FOUND"), value: "test", disabled: !configPresent }, { name: chalk.dim("4) Batch-Run Tests: \u{1F3D7}\uFE0F NOT YET IMPLEMENTED "), value: "batch", disabled: true }, { name: "5) Artifact Downloader: Fetch artifacts from GitHub repos.", value: "download", disabled: false }, { name: `6) Quit Application`, value: "quit" } ], filter(val) { return val; } }; const answers = await inquirer.prompt(questionList); switch (answers.MenuChoice) { case "init": await generateConfig(); return false; case "run": const chosenRunEnv = await chooseRunEnv(config); if (chosenRunEnv.envName !== "back") { await runNetwork(chosenRunEnv); } return false; case "test": const chosenTestEnv = await chooseTestEnv(config); if (chosenTestEnv.envName !== "back") { await testCmd(chosenTestEnv.envName); await inquirer.prompt({ name: "test complete", type: "press-to-continue", anyKey: true, pressToContinueMessage: `\u2139\uFE0F Test run for ${chalk.bgWhiteBright.black( chosenTestEnv.envName )} has been completed. Press any key to continue... ` }); } return false; case "download": await resolveDownloadChoice(); return false; case "quit": return await resolveQuitChoice(); } } async function resolveDownloadChoice() { while (true) { const firstChoice = await inquirer.prompt({ name: "artifact", type: "list", message: `Download - which artifact?`, choices: [ "moonbeam", "polkadot", "moonbase-runtime", "moonriver-runtime", "moonbeam-runtime", new inquirer.Separator(), "Back", new inquirer.Separator() ] }); if (firstChoice.artifact === "Back") { return; } const otherChoices = await inquirer.prompt([ { name: "binVersion", type: "input", default: "latest", message: `Download - which version?` }, { name: "path", type: "input", message: `Download - where would you like it placed?`, default: "./tmp" } ]); const result = await inquirer.prompt({ name: "continue", type: "confirm", message: `You are about to download ${chalk.bgWhite.blackBright( firstChoice.artifact )} v-${chalk.bgWhite.blackBright(otherChoices.binVersion)} to: ${chalk.bgWhite.blackBright( otherChoices.path )}. Would you like to continue? `, default: true }); if (result.continue === false) { continue; } await fetchArtifact({ artifact: firstChoice.artifact, binVersion: otherChoices.binVersion, path: otherChoices.path }); await inquirer.prompt({ name: "NetworkStarted", type: "press-to-continue", anyKey: true, pressToContinueMessage: `\u2705 Artifact has been downloaded. Press any key to continue... ` }); return; } } var chooseTestEnv = async (config) => { const envs = config.environments.map((a) => ({ name: `Env: ${a.name} (${a.foundation.type})`, value: a.name, disabled: false })).sort((a, b) => a.name > b.name ? -1 : 1); envs.push( ...[ new inquirer.Separator(), { name: "Back", value: "back" }, new inquirer.Separator() ] ); const result = await inquirer.prompt({ name: "envName", message: "Select a environment to run", type: "list", pageSize: 12, choices: envs }); return result; }; var chooseRunEnv = async (config) => { const envs = config.environments.map((a) => { const result2 = { name: "", value: a.name, disabled: false }; if (a.foundation.type === "dev" || a.foundation.type === "chopsticks") { result2.name = `Env: ${a.name} (${a.foundation.type})`; } else { result2.name = chalk.dim(`Env: ${a.name} (${a.foundation.type}) NO NETWORK TO RUN`); result2.disabled = true; } return result2; }); const choices = [ ...envs.filter(({ disabled }) => disabled === false).sort((a, b) => a.name > b.name ? 1 : -1), new inquirer.Separator(), ...envs.filter(({ disabled }) => disabled === true).sort((a, b) => a.name > b.name ? 1 : -1), new inquirer.Separator(), { name: "Back", value: "back" }, new inquirer.Separator() ]; const result = await inquirer.prompt({ name: "envName", message: "Select a environment to run", type: "list", pageSize: 12, choices }); return result; }; var resolveQuitChoice = async () => { const result = await inquirer.prompt({ name: "Quit", type: "confirm", message: "Are you sure you want to Quit?", default: false }); return result.Quit; }; var printIntro = async () => { const currentVersion = new SemVer(package_default.version); const resp = await fetch("https://registry.npmjs.org/@moonsong-labs/moonwall-cli/latest"); const json = await resp.json(); const npmVersion = new SemVer(json["version"]); const logo = chalk.cyan(` #################### ############################ ################################### ######################################## ########################################### ############################################## ################################################ .################################################# ################################################## ################################################## `) + chalk.magenta(` *** ************************************************************ **** ********************************************* *** ****************************************************** ** *********************** ********************************************* ** *********************** ******************************************** *** ****************************** **** ***************************** `); process.stdout.write(logo); process.stdout.write( colors.rainbow( "================================================================================\n" ) ); if (lt(currentVersion, npmVersion)) { process.stdout.write( chalk.bgCyan.white( ` MOONWALL V${currentVersion.version} (New version ${npmVersion.version} available!) ` ) ); } else { process.stdout.write( chalk.bgCyan.white( ` MOONWALL V${currentVersion.version} ` ) ); } process.stdout.write( colors.rainbow( "================================================================================\n" ) ); }; export { main };