UNPKG

create-ckb-js-vm-app

Version:

CLI tool to quickly bootstrap CKB on-chain script with ckb-js-vm.

260 lines ā€¢ 10.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.install = install; const commander_1 = require("commander"); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const update_check_1 = __importDefault(require("update-check")); const prompts_1 = __importDefault(require("prompts")); const picocolors_1 = require("picocolors"); const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name")); const child_process_1 = require("child_process"); const config_1 = require("./config"); const packageJson = require(path_1.default.join(__dirname, "../package.json")); let projectName = ""; const handleSigTerm = () => process.exit(0); process.on("SIGINT", handleSigTerm); process.on("SIGTERM", handleSigTerm); const onPromptState = (state) => { if (state.aborted) { // If we don't re-enable the terminal cursor before exiting // the program, the cursor will remain hidden process.stdout.write("\x1B[?25h"); process.stdout.write("\n"); process.exit(1); } }; const program = new commander_1.Command(packageJson.name) .version(packageJson.version, "-v, --version", `Output the current version of ${packageJson.name}.`) .argument("[directory]") .usage("[directory] [options]") .helpOption("-h, --help", "Display this help message.") .option("--skip-install", "Explicitly tell the CLI to skip installing packages.") .action((name) => { // Commander does not implicitly support negated options. When they are used // by the user they will be interpreted as the positional argument (name) in // the action handler. See https://github.com/tj/commander.js/pull/1355 if (name && !name.startsWith("--no-")) { projectName = name; } }) .allowUnknownOption() .parse(process.argv); const opts = program.opts(); const packageManager = getPkgManager(); function validateNpmName(name) { const nameValidation = (0, validate_npm_package_name_1.default)(name); if (nameValidation.validForNewPackages) { return { valid: true }; } return { valid: false, problems: [ ...(nameValidation.errors || []), ...(nameValidation.warnings || []), ], }; } function getPkgManager() { return "pnpm"; } function isFolderEmpty(folderPath) { const files = fs_extra_1.default.readdirSync(folderPath); return files.length === 0; } async function install(packageManager) { const args = ["install"]; return new Promise((resolve, reject) => { const child = (0, child_process_1.spawn)(packageManager, args, { stdio: "inherit", env: { ...process.env, ADBLOCK: "1", // we set NODE_ENV to development as pnpm skips dev // dependencies when production NODE_ENV: "development", DISABLE_OPENCOLLECTIVE: "1", }, }); child.on("close", (code) => { if (code !== 0) { reject({ command: `${packageManager} ${args.join(" ")}` }); return; } resolve(); }); }); } function updatePackageJson1(projectPath) { const packageJsonPath = path_1.default.join(projectPath, "packages/on-chain-script/package.json"); let json = ""; if (fs_extra_1.default.pathExistsSync(packageJsonPath)) { try { json = fs_extra_1.default.readJsonSync(packageJsonPath); json.name = projectName; json.devDependencies["ckb-testtool"] = config_1.testtoolVersion; json.dependencies["@ckb-js-std/bindings"] = config_1.bindingVersion; json.dependencies["@ckb-js-std/core"] = config_1.coreVersion; fs_extra_1.default.writeJsonSync(packageJsonPath, json, { spaces: 2 }); console.log((0, picocolors_1.green)(`Updated ${projectName}/package.json.`)); } catch (error) { console.error((0, picocolors_1.red)(`Failed to update packages/on-chain-script/package.json: ${error.message}`)); process.exit(1); } } else { console.error((0, picocolors_1.red)(`Could not find packages/on-chain-script/package.json in the template. Make sure your template includes a package.json.`)); process.exit(1); } } function updatePackageJson2(projectPath) { const packageJsonPath = path_1.default.join(projectPath, "packages/on-chain-script-tests/package.json"); let json = ""; if (fs_extra_1.default.pathExistsSync(packageJsonPath)) { try { json = fs_extra_1.default.readJsonSync(packageJsonPath); json.name = projectName; json.devDependencies["ckb-testtool"] = config_1.testtoolVersion; json.devDependencies["@ckb-ccc/core"] = config_1.cccCoreVersion; fs_extra_1.default.writeJsonSync(packageJsonPath, json, { spaces: 2 }); console.log((0, picocolors_1.green)(`Updated ${projectName}/package.json.`)); } catch (error) { console.error((0, picocolors_1.red)(`Failed to update packages/on-chain-script/package.json: ${error.message}`)); process.exit(1); } } else { console.error((0, picocolors_1.red)(`Could not find packages/on-chain-script/package.json in the template. Make sure your template includes a package.json.`)); process.exit(1); } } async function run() { var _a; console.log(); if (projectName && typeof projectName === "string") { projectName = projectName.trim(); } if (!projectName) { const res = await (0, prompts_1.default)({ onState: onPromptState, type: "text", name: "path", message: "What is your project named?", initial: "my-ckb-script", validate: (name) => { var _a; const validation = validateNpmName(path_1.default.basename(path_1.default.resolve(name))); if (validation.valid) { return true; } return ("Invalid project name: " + (((_a = validation.problems) === null || _a === void 0 ? void 0 : _a[0]) || "Unknown validation error")); }, }); if (typeof res.path === "string") { projectName = res.path.trim(); } } if (!projectName) { console.log("\nPlease specify the project directory:\n" + ` ${(0, picocolors_1.cyan)(program.name())} ${(0, picocolors_1.green)("<project-directory>")}\n` + "For example:\n" + ` ${(0, picocolors_1.cyan)(program.name())} ${(0, picocolors_1.green)("my-ckb-script")}\n\n` + `Run ${(0, picocolors_1.cyan)(`${program.name()} --help`)} to see all options.`); process.exit(1); } const appPath = path_1.default.resolve(projectName); const appName = path_1.default.basename(appPath); const validation = validateNpmName(appName); if (!validation.valid) { console.error(`Could not create a project called ${(0, picocolors_1.red)(`"${appName}"`)} because of npm naming restrictions:`); (_a = validation.problems) === null || _a === void 0 ? void 0 : _a.forEach((p) => console.error(` ${(0, picocolors_1.red)((0, picocolors_1.bold)("*"))} ${p}`)); process.exit(1); } if (fs_extra_1.default.pathExistsSync(appPath) && !isFolderEmpty(appPath)) { console.error(`Could not create a project called ${(0, picocolors_1.red)(`"${appName}"`)} because a project with the same name already exists.`); process.exit(1); } console.log((0, picocolors_1.bold)(`Using ${packageManager}.`)); const templatePath = path_1.default.join(__dirname, `../templates`); if (!fs_extra_1.default.pathExistsSync(templatePath)) { console.error(`Could not find a template`); console.error(`\n šŸ˜®ā€šŸ’Ø Project ${projectName} created failed!\n`); process.exit(1); } const originalDirectory = process.cwd(); const projectPath = path_1.default.join(originalDirectory, projectName); fs_extra_1.default.ensureDirSync(projectPath); fs_extra_1.default.copySync(templatePath, projectPath); updatePackageJson1(projectName); updatePackageJson2(projectName); console.log(`\nšŸŽ‰ Project ${projectName} created!\n`); if (opts.skipInstall) { console.log("Skip install the dependencies, we suggest that you begin by typing:"); console.log(); console.log((0, picocolors_1.cyan)(" cd"), projectName); console.log(` ${(0, picocolors_1.cyan)(`${packageManager} install`)}`); console.log(); } else { console.log("\nInstalling dependencies:"); console.log(); console.log("Installing packages. This might take a couple of minutes."); console.log(); process.chdir(appPath); await install(packageManager); console.log("Packages installed."); console.log(); } console.log(`${(0, picocolors_1.green)("Success!")} Created ${projectName} at ${projectPath}`); console.log(); } const update = (0, update_check_1.default)(packageJson).catch(() => null); async function notifyUpdate() { try { const updateInfo = await update; if (updateInfo === null || updateInfo === void 0 ? void 0 : updateInfo.latest) { const global = { pnpm: "pnpm add -g", }; const updateMessage = `${global[packageManager]} ${packageJson.name}`; console.log((0, picocolors_1.yellow)((0, picocolors_1.bold)(`A new version of \`${packageJson.name}\` is available!`)) + "\n" + "You can update by running: " + (0, picocolors_1.cyan)(updateMessage) + "\n"); } process.exit(0); } catch (_a) { // ignore error } } async function exit(reason) { console.log(); console.log("Aborting installation."); if (reason.command) { console.log(` ${(0, picocolors_1.cyan)(reason.command)} has failed.`); } else { console.log((0, picocolors_1.red)("Unexpected error. Please report it as a bug:") + "\n", reason); } console.log(); await notifyUpdate(); process.exit(1); } (async () => { try { await run(); await notifyUpdate(); } catch (error) { await exit(error); } })(); //# sourceMappingURL=index.js.map