UNPKG

@roboplay/sage

Version:
168 lines (166 loc) 6.11 kB
import path from 'node:path'; import { mkdirSync, createWriteStream } from 'node:fs'; import { pipeline, Readable } from 'node:stream'; import { promisify } from 'node:util'; import { readFile } from 'node:fs/promises'; import { logger } from './logger.js'; import { color } from './color.js'; import { FLASHCORE_KEYS } from 'robo.js/dist/core/constants.js'; import { spawn } from 'node:child_process'; import { Flashcore } from 'robo.js'; import { packageJson } from '../index.js'; import { select } from '@inquirer/prompts'; const pipelineAsync = promisify(pipeline); const IS_WINDOWS = /^win/.test(process.platform); async function checkSageUpdates(skipPrompt = false) { logger.debug(`Checking for updates...`); const response = await fetch(`https://registry.npmjs.org/${packageJson.name}/latest`); const latestVersion = (await response.json()).version; logger.debug(`Latest version on NPM Registry: ${latestVersion}`); if (packageJson.version !== latestVersion) { logger.info(color.green(`A new version of ${color.bold("@roboplay/sage")} is available! (v${latestVersion}) `)); if (skipPrompt) { logger.debug(`Skipping prompt due to flag...`); return; } const useLatest = await select({ message: "Would you like to use the latest version?", choices: [ { name: "Yes, use latest", value: true }, { name: "No, stick with v" + packageJson.version, value: false } ] }); logger.log(""); if (useLatest) { const packageExecutor = getPackageExecutor(); let cliPackage = process.argv[1] ?? packageJson.name; if (path.isAbsolute(cliPackage)) { cliPackage = path.basename(cliPackage); } await exec(`${packageExecutor} ${cliPackage}@${packageJson.version} ${process.argv.slice(2).join(" ")}`.trim()); process.exit(0); } } } async function checkUpdates(packageJson2, config, forceCheck = false) { const { updateCheckInterval = 60 * 60 } = config; logger.debug(`Checking for updates for package.json:`, packageJson2); const update = { changelogUrl: "", currentVersion: packageJson2.version, hasUpdate: false, latestVersion: "" }; if (!forceCheck && updateCheckInterval <= 0) { logger.debug(`Update check is disabled.`); return update; } const lastUpdateCheck = await Flashcore.get(FLASHCORE_KEYS.lastUpdateCheck) ?? 0; const now = Date.now(); const isDue = now - lastUpdateCheck > updateCheckInterval * 1e3; logger.debug(`Update check from ${new Date(lastUpdateCheck).toISOString()} is due:`, isDue); if (!forceCheck && !isDue) { return update; } const response = await fetch(`https://registry.npmjs.org/${packageJson2.name}/latest`); const latestVersion = (await response.json()).version; update.hasUpdate = packageJson2.version !== latestVersion; update.latestVersion = latestVersion; if (packageJson2.repository?.url) { logger.debug(`Getting changelog URL from repository URL...`, packageJson2.repository); let changelogUrl = packageJson2.repository?.url; changelogUrl = changelogUrl.replace(".git", "").replace("git+", "") + "/main"; if (packageJson2.repository.directory) { changelogUrl += `/${packageJson2.repository.directory}`; } if (changelogUrl.includes("github.com")) { changelogUrl = changelogUrl.replace("github.com", "raw.githubusercontent.com"); } changelogUrl += "/CHANGELOG.md"; const changelogResponse = await fetch(changelogUrl); if (!changelogResponse.ok) { logger.debug(`Changelog URL does not exist:`, changelogUrl); } else { update.changelogUrl = changelogUrl; } } await Flashcore.set(FLASHCORE_KEYS.lastUpdateCheck, now); return update; } function createNodeReadable(webReadable) { const reader = webReadable.getReader(); return new Readable({ async read() { const { done, value } = await reader.read(); this.push(done ? null : value); } }); } async function downloadFile(url, fileName) { const response = await fetch(url); if (!response.ok) { throw new Error("Network response was not ok " + response.statusText); } mkdirSync(path.dirname(fileName), { recursive: true }); const fileStream = createWriteStream(fileName); const nodeReadable = createNodeReadable(response.body); await pipelineAsync(nodeReadable, fileStream); } function exec(command, options) { return new Promise((resolve, reject) => { logger.debug(`> ${color.bold(command)}`); const args = command.split(" "); const childProcess = spawn(args.shift(), args, { env: { ...process.env, FORCE_COLOR: "1" }, shell: IS_WINDOWS, stdio: "inherit", ...options ?? {} }); childProcess.on("error", reject); childProcess.on("close", (code) => { if (code === 0) { resolve(); } else { reject(`Command exited with code ${code}`); } }); }); } function getPackageManager() { const userAgent = process.env.npm_config_user_agent; if (userAgent?.startsWith("bun")) { return "bun"; } else if (userAgent?.startsWith("yarn")) { return "yarn"; } else if (userAgent?.startsWith("pnpm")) { return "pnpm"; } else { return "npm"; } } function getPackageExecutor() { const packageManager = getPackageManager(); if (packageManager === "yarn") { return "yarn dlx"; } else if (packageManager === "pnpm") { return "pnpx"; } else if (packageManager === "bun") { return "bunx"; } else { return "npx"; } } async function isRoboProject(project = process.cwd()) { try { const packageJsonPath = path.join(project, "package.json"); const packageJson2 = JSON.parse(await readFile(packageJsonPath, "utf-8")); return packageJson2.dependencies["robo.js"] || packageJson2.devDependencies["robo.js"]; } catch (e) { logger.debug(`Not a Robo project:`, e); return false; } } export { IS_WINDOWS, checkSageUpdates, checkUpdates, createNodeReadable, downloadFile, exec, getPackageExecutor, getPackageManager, isRoboProject }; //# sourceMappingURL=out.js.map //# sourceMappingURL=utils.js.map