UNPKG

@next-boilerplate/cli-helpers

Version:
270 lines (262 loc) 8.96 kB
'use strict'; var fs = require('fs-extra'); var path = require('path'); var helpers = require('./helpers-m-hZApfC.cjs'); var process$1 = require('process'); var readline = require('readline'); var index$1 = require('./config/index.cjs'); var index = require('./plugins/index.cjs'); require('child_process'); require('globby'); require('tar'); require('./stores/index.cjs'); require('zod'); require('./utils/index.cjs'); let gora = null; const loadOra = async () => { if (gora) return gora; const resolvedOra = await Promise.resolve().then(function () { return require('./index-1aVq6B9v.cjs'); }).then((_ora) => _ora.default); gora = resolvedOra; return resolvedOra; }; const { addPrefixToArgs, errorText, infoText, log, successText, warnText } = helpers.logger.utils; const clearLastLines = (count) => { for (let i = 0; i < count; i++) { readline.moveCursor(process$1.stderr, 0, -1); readline.clearLine(process$1.stderr, 0); } }; const windowLog = (maxLines, opts) => { const lines = []; let numberOfLines = 0; let hasPrintedTopPrefix = false; let prefixValue = ""; const handleLine = (line, kind) => { const rows = process.stdout.rows; maxLines = Math.min(maxLines, rows - 1 - (opts?.topPrefix ? 1 : 0)); const toClear = Math.min(numberOfLines, maxLines); clearLastLines(toClear); const columns = process.stdout.columns; if (line) { lines.push({ content: line, kind }); const lineLength = Math.ceil(line.length / columns); numberOfLines += lineLength; } if (numberOfLines > maxLines) { const removedLine = lines.shift(); if (removedLine) { const removedLineLength = Math.ceil(removedLine.content.length / columns); numberOfLines -= removedLineLength; } } const printable = lines.map((l) => { const wrapper = l.kind === "error" ? errorText : l.kind === "info" ? infoText : l.kind === "success" ? successText : l.kind === "warn" ? warnText : log; const value = addPrefixToArgs(helpers.logger.prefix, wrapper(l.content)); return value.join(" "); }); if (!opts?.noPrint) { if (opts?.topPrefix) { if (hasPrintedTopPrefix) { clearLastLines(1); } if (line === null) { prefixValue = opts.topPrefix(); } process$1.stderr.write(prefixValue + "\n"); hasPrintedTopPrefix = true; } printable.forEach((l) => { process$1.stderr.write(l); }); } return printable; }; const print = (line, type = "log") => { handleLine(line, type); }; let interval = null; if (opts) { handleLine(null, "log"); const { topInterval, topPrefix } = opts; if (topInterval && topPrefix) interval = setInterval(() => { handleLine(null, "log"); }, topInterval); } const stop = ({ noClear, successMessage, endPrint } = {}) => { if (interval) { clearInterval(interval); } if (!noClear) { const toClear = Math.min(numberOfLines, maxLines) + 1; clearLastLines(toClear); } if (endPrint && endPrint?.length > 0) { endPrint.forEach((l) => { helpers.logger[l.kind](l.content); }); } if (successMessage) { helpers.logger.success(successMessage); } }; return { print, stop }; }; const isCI = () => process.env.CI !== void 0 || process.env.GITHUB_ACTIONS !== void 0; const levelOrder = { error: 1, warn: 2, log: 3, info: 4, success: 5 }; async function startTask(options) { const { maxLines = 10, name, successMessage } = options; if (isCI()) { return { log: helpers.logger.log, error: helpers.logger.error, warn: helpers.logger.warn, info: helpers.logger.info, success: helpers.logger.log, stop: (message) => { if (message) { helpers.logger.log(message); } } }; } const ora = await loadOra(); const spinner = ora({ text: name, isSilent: true, isEnabled: false }).start(); const window = windowLog(maxLines, { topPrefix: () => spinner.frame(), topInterval: 100 }); const rows = process.stdout.rows; const curMax = Math.min(maxLines, rows - 2); const endPrint = []; const registerHandlePrint = (kind) => (data) => { const lines = data.toString().split("\n").filter((l) => l.length > 0).slice(-curMax - 1); lines.forEach((line) => { window.print(line + "\n", kind); }); if (kind === "error" || kind === "warn") { endPrint.push({ content: data, kind }); } }; return { log: registerHandlePrint("log"), error: registerHandlePrint("error"), warn: registerHandlePrint("warn"), info: registerHandlePrint("info"), success: registerHandlePrint("success"), stop: (message) => { window.stop({ successMessage: message ?? successMessage, noClear: options.noClear, endPrint: endPrint.sort((a, b) => { return levelOrder[b.kind] - levelOrder[a.kind]; }) }); } }; } function stopTask(window, opts) { window.stop(opts); } loadOra(); const task = { startTask, stopTask }; const getPluginPath = ({ assetsDirectory, plugin }) => path.join( helpers.getStoreDataDirectory({ store: plugin.store, assetsDirectory }), index.pluginsFolder, plugin.name // The name in the config file is the relative path from the store ); const applyConfigurationTask = async ({ assetsDirectory, root, noTask }) => { let _applyConfigTask = null; if (!noTask) { _applyConfigTask = await task.startTask({ name: "Apply template config... \u{1F9F0}" }); } const applyConfigTask = _applyConfigTask ?? { log: (message) => helpers.logger.info(message), error: (message) => helpers.logger.error(message), stop: (message) => helpers.logger.success(message) }; applyConfigTask.log("Retrieving the config"); const configPath = !root.endsWith(index.pluginConfigFileName) ? path.join(root, index.pluginConfigFileName) : root; if (!await fs.exists(configPath)) { applyConfigTask.error(`The config file ${configPath} doesn't exist`); applyConfigTask.stop(); throw new Error(`The config file ${configPath} doesn't exist`); } const { data: config, error } = index$1.configSchema.safeParse(await fs.readJson(configPath)); if (error) { applyConfigTask.error(`The config file ${configPath} is not valid`); applyConfigTask.stop(); helpers.logger.error(error); throw error; } applyConfigTask.log("Applying plugins"); for (const plugin of config.plugins) { const pluginPath = getPluginPath({ assetsDirectory, plugin }); if (!await fs.exists(pluginPath)) { applyConfigTask.error(`The plugin ${plugin.name} doesn't exist at ${pluginPath}`); applyConfigTask.stop(); throw new Error(`The plugin ${plugin.name} doesn't exist at ${pluginPath}`); } const pluginConfigPath = path.join(pluginPath, index.pluginConfigFileName); if (!await fs.exists(pluginConfigPath)) { applyConfigTask.error(`The plugin config for ${plugin.name} doesn't exist at ${pluginConfigPath}`); applyConfigTask.stop(); throw new Error(`The plugin config for ${plugin.name} doesn't exist at ${pluginConfigPath}`); } const { data: pluginConfig, error: error2 } = index.pluginConfigSchema.safeParse(await fs.readJson(pluginConfigPath)); if (error2) { applyConfigTask.error(`The plugin config file ${pluginConfigPath} is not valid. Contact developer`); applyConfigTask.stop(); helpers.logger.error(error2); throw error2; } const relativeDestinationPaths = pluginConfig.paths.map((p) => p.to); for (const relativeDestinationPath of relativeDestinationPaths) { const destinationPath = path.join(root, relativeDestinationPath); if (await fs.exists(destinationPath)) { applyConfigTask.error(`A file/folder already exists at the destination ${destinationPath}`); applyConfigTask.stop(); throw new Error(`A file/folder already exists at the destination ${destinationPath}`); } } } applyConfigTask.log("Applying the plugins"); for (const plugin of config.plugins) { const pluginPath = getPluginPath({ assetsDirectory, plugin }); const pluginConfigPath = path.join(pluginPath, index.pluginConfigFileName); const pluginConfig = await fs.readJson(pluginConfigPath); for (const { from, to } of pluginConfig.paths) { const sourcePath = path.join(pluginPath, from); const destinationPath = path.join(root, to); applyConfigTask.log(`Copying the plugin ${plugin.name} to the destination ${destinationPath}`); await fs.copy(sourcePath, destinationPath); } } applyConfigTask.stop("The template config has been applied! \u{1F389}"); helpers.logger.info("You can now delete the config file if you want"); }; exports.applyConfigurationTask = applyConfigurationTask;