UNPKG

@wessberg/cjs-to-esm-transformer

Version:

A Custom Transformer for Typescript that transforms Node-style CommonJS to tree-shakeable ES Modules

264 lines (253 loc) 7.26 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var commander = _interopDefault(require('commander')); var fs = require('fs'); var fs__default = _interopDefault(fs); var TS = require('typescript'); var chalk = _interopDefault(require('chalk')); // tslint:disable:no-any /** * Coerces the given option value into an acceptable data type * * @param type * @param value */ function coerceOptionValue(type, value) { switch (type) { case "string": if (value === null) return "null"; else if (value === undefined) return "undefined"; return String(value); case "number": if (typeof value === "number") return value; else if (value === true) return 1; else if (value === false) return 0; return parseFloat(value); case "boolean": if (value === "true" || value === "" || value === "1" || value === 1) return true; else if (value === "false" || value === "0" || value === 0) return false; return Boolean(value); } } /** * Formats the given option flags * * @param shortHand * @param longHand * @returns */ function formatOptionFlags(shortHand, longHand) { const formattedLongHand = `${longHand} [arg]`; return shortHand != null ? `-${shortHand}, --${formattedLongHand}` : `--${formattedLongHand}`; } /** * Formats the given command name, along with its arguments * * @param options * @returns */ function formatCommandNameWithArgs(options) { const formattedArgs = Object.entries(options.args) .map(([argName, { type, required }]) => { const left = required ? `<` : `[`; const right = required ? ">" : `]`; if (type === "string[]") { return `${left}${argName}...${right}`; } else { return `${left}${argName}${right}`; } }) .join(" "); return `${options.name} ${formattedArgs}`; } /** * Creates a new command * * @param options * @param action */ function createCommand(options, action) { // Add the command to the program const result = commander .command(formatCommandNameWithArgs(options), { isDefault: options.isDefault }) .description(options.description); // Add options to the command Object.entries(options.options).forEach(([longhand, { shortHand, description, type, defaultValue }]) => { result.option(formatOptionFlags(shortHand, longhand), description, coerceOptionValue.bind(null, type), defaultValue); }); // Add the action to the command result.action((...args) => { const argKeys = Object.keys(options.args); const optionKeys = Object.keys(options.options); const actionOptions = {}; for (let i = 0; i < args.length; i++) { if (argKeys[i] == null) continue; // eslint-disable-next-line @typescript-eslint/no-explicit-any actionOptions[argKeys[i]] = args[i]; } // Take the last argument const lastArg = args[args.length - 1]; // Apply all option values for (const key of optionKeys) { // eslint-disable-next-line @typescript-eslint/no-explicit-any actionOptions[key] = lastArg[key]; } // Invoke the action action(actionOptions); }); } const TRANSFORM_COMMAND_OPTIONS = {}; /** * Selects a LogLevel based on the given options * * @param options * @returns */ function selectLogLevel(options) { if (options.debug) { return 3 /* DEBUG */; } else if (options.verbose) { return 2 /* VERBOSE */; } else if (options.silent) { return 0 /* NONE */; } else { return 1 /* INFO */; } } /** * A logger that can print to the console */ class Logger { constructor(logLevel) { this.logLevel = logLevel; this.INFO_COLOR = "white"; this.VERBOSE_COLOR = "gray"; this.WARNING_COLOR = "yellow"; this.DEBUG_COLOR = "cyan"; } /** * Logs info-related messages */ info(...messages) { if (this.logLevel < 1 /* INFO */) return; console.log(chalk[this.INFO_COLOR](...messages)); } /** * Logs verbose-related messages */ verbose(...messages) { if (this.logLevel < 2 /* VERBOSE */) return; console.log(chalk[this.VERBOSE_COLOR](...messages)); } /** * Logs debug-related messages */ debug(...messages) { if (this.logLevel < 3 /* DEBUG */) return; console.log(chalk[this.DEBUG_COLOR](...messages)); } /** * Logs warning-related messages */ warn(...messages) { console.warn(chalk[this.WARNING_COLOR](`(!)`, ...messages)); } } /** * Generates the task options that are shared across all commands * * @param options * @returns */ async function generateTaskOptions(options) { // Prepare a logger const logLevel = selectLogLevel(options); const logger = new Logger(logLevel); // Inform about the log level (if applicable) if (logLevel === 2 /* VERBOSE */) { logger.verbose(`Logging mode: VERBOSE`); } else if (logLevel === 3 /* DEBUG */) logger.debug(`Logging mode: DEBUG`); return { fs: fs__default, logger, root: process.cwd(), typescript: TS }; } const SHARED_OPTIONS = { debug: { shortHand: "d", type: "boolean", description: "Whether to print debug information" }, verbose: { shortHand: "v", type: "boolean", description: "Whether to print verbose information" }, silent: { shortHand: "s", type: "boolean", description: "Whether to not print anything" } }; createCommand({ name: "transform", description: `Transforms CJS to ESM modules based on the input glob`, isDefault: true, args: { input: { type: "string", required: true, description: "A glob for all the files that should be transformed" }, outDir: { type: "string", required: true, description: `The directory to write the transformed files to.` } }, options: { ...SHARED_OPTIONS, ...TRANSFORM_COMMAND_OPTIONS } }, async (args) => { // Load the task const { transformTask } = await Promise.resolve().then(function () { return require('./transform-task-5c7b7086.js'); }); const taskOptions = await generateTaskOptions(args); // Execute it await transformTask({ ...taskOptions, input: args.input, outDir: args.outDir }); }); const args = [...process.argv]; if (args[2] !== "transform") { args.splice(2, 0, "transform"); } commander.parse(args); // Show help if no arguments are given if (commander.args.length === 0) { commander.help(text => `Welcome to the CJS to ESM CLI!\n\n` + text); } //# sourceMappingURL=index.js.map