UNPKG

react-native-test-app

Version:

react-native-test-app provides a test app for all supported platforms as a package

106 lines (96 loc) 2.79 kB
// @ts-check import cliui from "cliui"; import * as fs from "node:fs"; import * as path from "node:path"; import { URL, fileURLToPath } from "node:url"; import * as util from "node:util"; /** @import { Args, Options } from "../types.js"; */ /** * @template {Options} O * @param {NonNullable<unknown>} values * @param {O} _options (Unused; only present for type inference) * @returns {values is Args<O>} */ function coerce(values, _options) { return Boolean(typeof values === "object" && "help" in values); } /** * Generates help message. * @param {string} description * @param {Record<string, { short?: string; description: string; }>} options * @returns {string} */ function formatHelp(description, options) { const flags = Object.entries(options); const indent = " "; const minWidth = Math.max(...flags.map(([flag]) => flag.length)) + indent.length * 2; const padding = [0, 0, 0, 0]; const ui = cliui({ width: process.stdout.columns ?? 80 }); for (const [flag, config] of flags) { ui.div( { text: "", width: 2, padding }, { text: config.short ? `-${config.short},` : "", width: 4, padding }, { text: `--${flag}`, width: minWidth + 2, padding }, { text: config.description, padding } ); } const script = path.basename(process.argv[1]); return [ `usage: ${script} [options]`, "", description, "", "Options:", ui.toString(), "", ].join("\n"); } /** * Parses command line arguments. * * @see {@link https://nodejs.org/api/util.html#utilparseargsconfig} * * @template {Options} O * @param {string} description * @param {O} options * @param {(args: Args<O>) => void} callback */ export function parseArgs(description, options, callback) { const mergedOptions = { help: { description: "Show this help message", type: "boolean", short: "h", default: false, }, version: { description: "Show version number", type: "boolean", short: "v", default: false, }, ...options, }; const { values, positionals } = util.parseArgs({ args: process.argv.slice(2), options: mergedOptions, strict: true, allowPositionals: true, tokens: false, }); if (!coerce(values, mergedOptions)) { throw new Error("Failed to parse command-line arguments"); } if (values.help) { console.log(formatHelp(description, mergedOptions)); } else if (typeof values.version === "boolean" && values.version) { const file = fileURLToPath(new URL("../../package.json", import.meta.url)); const manifest = fs.readFileSync(file, { encoding: "utf-8" }); const { name, version } = JSON.parse(manifest); console.log(`${name} ${version}`); } else { values._ = positionals; callback(values); } }