UNPKG

@rodbe/nsl

Version:

List, fuzzy search and run scripts from any type of project

175 lines (165 loc) 5.31 kB
import { join, parse, dirname } from 'node:path'; import { execSync } from 'node:child_process'; import chalk from 'chalk'; import { tryCatch } from '@rodbe/fn-utils'; import { fsCache } from '@rodbe/lru-cache-fs'; import { fileURLToPath } from 'node:url'; import { readFileSync } from 'node:fs'; import { homedir } from 'node:os'; import process$1 from 'node:process'; const PAGE_SIZE = 20; const BASE_CACHE_KEY = "nsl"; const RERUN_CACHE_NAME = `${BASE_CACHE_KEY}-rerun-cache`; const SHORT_CONFIG_CACHE_NAME = `${BASE_CACHE_KEY}-short-config-cache`; const LONG_CONFIG_CACHE_NAME = `${BASE_CACHE_KEY}-long-config-cache`; const MINUTE_IN_MS = 60 * 1e3; const HOUR_IN_MS = 60 * MINUTE_IN_MS; const DAY_IN_MS = 24 * HOUR_IN_MS; const WEEK_IN_MS = 7 * DAY_IN_MS; const MONTH_IN_MS = 30 * DAY_IN_MS; const QUATER_IN_MS = 3 * MONTH_IN_MS; const NPM_SCRIPTS_TO_IGNORE = [ "dependencies", "install", "postinstall", "postpack", "postprepare", "postpublish", "postrestart", "poststart", "poststop", "posttest", "postversion", "preinstall", "prepack", "prepare", "preprepare", "prepublish", "prepublishOnly", "prerestart", "prestart,", "prestop", "pretest", "preversion", "publish", "restart" ]; const nslCachePath = join(homedir(), ".nsl"); const getCacheFilePath = (cacheName) => join(nslCachePath, cacheName); const getNSLDistPath = () => { const filename = fileURLToPath(import.meta.url); return dirname(filename); }; const getMainPkgJsonPath = () => { let currentFolderPath = getNSLDistPath(); let pkgJsonPath = ""; while (true) { const { base, dir } = parse(currentFolderPath); if (base === "dist") { pkgJsonPath = dir; break; } currentFolderPath = join(currentFolderPath, ".."); } return join(pkgJsonPath, "package.json"); }; const getNslPkgJson = () => { return JSON.parse(readFileSync(getMainPkgJsonPath(), "utf8")); }; const rerunCache = () => { return fsCache({ cacheName: RERUN_CACHE_NAME, cachePath: nslCachePath, max: 200, ttl: QUATER_IN_MS }); }; const DEFAULT_RUNNER = "npm"; const getPackageManager = (packageManager) => { if (!packageManager) { return DEFAULT_RUNNER; } const regex = /npm|pnpm|yarn|bun/; const match = regex.exec(packageManager); if (match) { return match[0]; } return DEFAULT_RUNNER; }; const voltaExists = () => { const [err] = tryCatch(() => { execSync("volta --version", { stdio: "ignore" }); return true; }); return !err; }; const getCommandToRunFromRoot = (answerSelected, rootPackageManager) => { const { folderContainer, packageManager, scriptName, packageName } = answerSelected; const runner = getPackageManager(packageManager ?? rootPackageManager); if (folderContainer === "Root") { return `${runner} run ${scriptName}`; } if (runner === "pnpm") { return `pnpm -F ${packageName} ${scriptName}`; } if (runner === "yarn") { return `yarn workspace ${packageName} ${scriptName}`; } return `npm run ${scriptName} -w ${folderContainer}`; }; const getCommandToRunFromFolder = (answerSelected, rootPackageManager) => { const { packageManager, scriptName } = answerSelected; const runner = getPackageManager(packageManager ?? rootPackageManager); const commandToRun = `${runner} run ${scriptName}`; if (voltaExists()) { return `volta run npm run ${scriptName}`; } return commandToRun; }; const getCommandToRun = (answerSelected, rootPackageManager) => { const commandToRunFromRoot = getCommandToRunFromRoot(answerSelected, rootPackageManager); const commandToRunFromFolder = getCommandToRunFromFolder(answerSelected, rootPackageManager); return { root: commandToRunFromRoot, folder: commandToRunFromFolder }; }; const execScript = ({ answer, cwd, debug, print, rootPkgManager }) => { const { syncFs } = rerunCache(); const commandToRun = getCommandToRun(answer, rootPkgManager); syncFs.setItem(cwd, { answer, rootPkgManager, debug, print, commandToRun }); const scriptPath = answer.folderContainer === "Root" ? cwd : join(cwd, answer.folderContainer); console.log(chalk.black.bold.bgGreenBright(commandToRun.root)); if (debug) { console.log({ commandToRun, scriptPath }); } if (print) { process.exit(0); } const [err] = tryCatch(() => { execSync(commandToRun.folder, { cwd: scriptPath, stdio: [process.stdin, process.stdout, process.stderr] }); }); if (err) { console.log(chalk.white.bold.bgMagenta(`Ups, try to run the script manually `)); console.log(commandToRun); } }; const initEvents = () => { process$1.stdin.on("keypress", (_, key) => { if (key && key.name === "escape") { console.log("\u{1F44B} until next time!"); process$1.exit(0); } }); process$1.on("uncaughtException", (error) => { if (error instanceof Error && error.name === "ExitPromptError") { console.log("\u{1F44B} until next time!"); } else { throw error; } }); }; export { DAY_IN_MS as D, LONG_CONFIG_CACHE_NAME as L, NPM_SCRIPTS_TO_IGNORE as N, PAGE_SIZE as P, RERUN_CACHE_NAME as R, SHORT_CONFIG_CACHE_NAME as S, WEEK_IN_MS as W, getNslPkgJson as a, getNSLDistPath as b, getMainPkgJsonPath as c, execScript as e, getCacheFilePath as g, initEvents as i, rerunCache as r };