diff options
Diffstat (limited to 'node_modules/sucrase/dist/esm/cli.js')
| -rw-r--r-- | node_modules/sucrase/dist/esm/cli.js | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/node_modules/sucrase/dist/esm/cli.js b/node_modules/sucrase/dist/esm/cli.js new file mode 100644 index 0000000..93fbb6e --- /dev/null +++ b/node_modules/sucrase/dist/esm/cli.js @@ -0,0 +1,320 @@ +/* eslint-disable no-console */ +import commander from "commander"; +import globCb from "glob"; +import {exists, mkdir, readdir, readFile, stat, writeFile} from "mz/fs"; +import {dirname, join, relative} from "path"; +import {promisify} from "util"; + +import { transform} from "./index"; + + + + + + + + + + + +const glob = promisify(globCb); + +export default function run() { + commander + .description(`Sucrase: super-fast Babel alternative.`) + .usage("[options] <srcDir>") + .option( + "-d, --out-dir <out>", + "Compile an input directory of modules into an output directory.", + ) + .option( + "-p, --project <dir>", + "Compile a TypeScript project, will read from tsconfig.json in <dir>", + ) + .option("--out-extension <extension>", "File extension to use for all output files.", "js") + .option("--exclude-dirs <paths>", "Names of directories that should not be traversed.") + .option("-q, --quiet", "Don't print the names of converted files.") + .option("-t, --transforms <transforms>", "Comma-separated list of transforms to run.") + .option("--disable-es-transforms", "Opt out of all ES syntax transforms.") + .option("--jsx-runtime <string>", "Transformation mode for the JSX transform.") + .option("--production", "Disable debugging information from JSX in output.") + .option( + "--jsx-import-source <string>", + "Automatic JSX transform import path prefix, defaults to `React.Fragment`.", + ) + .option( + "--jsx-pragma <string>", + "Classic JSX transform element creation function, defaults to `React.createElement`.", + ) + .option( + "--jsx-fragment-pragma <string>", + "Classic JSX transform fragment component, defaults to `React.Fragment`.", + ) + .option("--keep-unused-imports", "Disable automatic removal of type-only imports/exports.") + .option("--preserve-dynamic-import", "Don't transpile dynamic import() to require.") + .option( + "--inject-create-require-for-import-require", + "Use `createRequire` when transpiling TS `import = require` to ESM.", + ) + .option( + "--enable-legacy-typescript-module-interop", + "Use default TypeScript ESM/CJS interop strategy.", + ) + .option("--enable-legacy-babel5-module-interop", "Use Babel 5 ESM/CJS interop strategy.") + .parse(process.argv); + + if (commander.project) { + if ( + commander.outDir || + commander.transforms || + commander.args[0] || + commander.enableLegacyTypescriptModuleInterop + ) { + console.error( + "If TypeScript project is specified, out directory, transforms, source " + + "directory, and --enable-legacy-typescript-module-interop may not be specified.", + ); + process.exit(1); + } + } else { + if (!commander.outDir) { + console.error("Out directory is required"); + process.exit(1); + } + + if (!commander.transforms) { + console.error("Transforms option is required."); + process.exit(1); + } + + if (!commander.args[0]) { + console.error("Source directory is required."); + process.exit(1); + } + } + + const options = { + outDirPath: commander.outDir, + srcDirPath: commander.args[0], + project: commander.project, + outExtension: commander.outExtension, + excludeDirs: commander.excludeDirs ? commander.excludeDirs.split(",") : [], + quiet: commander.quiet, + sucraseOptions: { + transforms: commander.transforms ? commander.transforms.split(",") : [], + disableESTransforms: commander.disableEsTransforms, + jsxRuntime: commander.jsxRuntime, + production: commander.production, + jsxImportSource: commander.jsxImportSource, + jsxPragma: commander.jsxPragma || "React.createElement", + jsxFragmentPragma: commander.jsxFragmentPragma || "React.Fragment", + keepUnusedImports: commander.keepUnusedImports, + preserveDynamicImport: commander.preserveDynamicImport, + injectCreateRequireForImportRequire: commander.injectCreateRequireForImportRequire, + enableLegacyTypeScriptModuleInterop: commander.enableLegacyTypescriptModuleInterop, + enableLegacyBabel5ModuleInterop: commander.enableLegacyBabel5ModuleInterop, + }, + }; + + buildDirectory(options).catch((e) => { + process.exitCode = 1; + console.error(e); + }); +} + + + + + + +async function findFiles(options) { + const outDirPath = options.outDirPath; + const srcDirPath = options.srcDirPath; + + const extensions = options.sucraseOptions.transforms.includes("typescript") + ? [".ts", ".tsx"] + : [".js", ".jsx"]; + + if (!(await exists(outDirPath))) { + await mkdir(outDirPath); + } + + const outArr = []; + for (const child of await readdir(srcDirPath)) { + if (["node_modules", ".git"].includes(child) || options.excludeDirs.includes(child)) { + continue; + } + const srcChildPath = join(srcDirPath, child); + const outChildPath = join(outDirPath, child); + if ((await stat(srcChildPath)).isDirectory()) { + const innerOptions = {...options}; + innerOptions.srcDirPath = srcChildPath; + innerOptions.outDirPath = outChildPath; + const innerFiles = await findFiles(innerOptions); + outArr.push(...innerFiles); + } else if (extensions.some((ext) => srcChildPath.endsWith(ext))) { + const outPath = outChildPath.replace(/\.\w+$/, `.${options.outExtension}`); + outArr.push({ + srcPath: srcChildPath, + outPath, + }); + } + } + + return outArr; +} + +async function runGlob(options) { + const tsConfigPath = join(options.project, "tsconfig.json"); + + let str; + try { + str = await readFile(tsConfigPath, "utf8"); + } catch (err) { + console.error("Could not find project tsconfig.json"); + console.error(` --project=${options.project}`); + console.error(err); + process.exit(1); + } + const json = JSON.parse(str); + + const foundFiles = []; + + const files = json.files; + const include = json.include; + + const absProject = join(process.cwd(), options.project); + const outDirs = []; + + if (!(await exists(options.outDirPath))) { + await mkdir(options.outDirPath); + } + + if (files) { + for (const file of files) { + if (file.endsWith(".d.ts")) { + continue; + } + if (!file.endsWith(".ts") && !file.endsWith(".js")) { + continue; + } + + const srcFile = join(absProject, file); + const outFile = join(options.outDirPath, file); + const outPath = outFile.replace(/\.\w+$/, `.${options.outExtension}`); + + const outDir = dirname(outPath); + if (!outDirs.includes(outDir)) { + outDirs.push(outDir); + } + + foundFiles.push({ + srcPath: srcFile, + outPath, + }); + } + } + if (include) { + for (const pattern of include) { + const globFiles = await glob(join(absProject, pattern)); + for (const file of globFiles) { + if (!file.endsWith(".ts") && !file.endsWith(".js")) { + continue; + } + if (file.endsWith(".d.ts")) { + continue; + } + + const relativeFile = relative(absProject, file); + const outFile = join(options.outDirPath, relativeFile); + const outPath = outFile.replace(/\.\w+$/, `.${options.outExtension}`); + + const outDir = dirname(outPath); + if (!outDirs.includes(outDir)) { + outDirs.push(outDir); + } + + foundFiles.push({ + srcPath: file, + outPath, + }); + } + } + } + + for (const outDirPath of outDirs) { + if (!(await exists(outDirPath))) { + await mkdir(outDirPath); + } + } + + // TODO: read exclude + + return foundFiles; +} + +async function updateOptionsFromProject(options) { + /** + * Read the project information and assign the following. + * - outDirPath + * - transform: imports + * - transform: typescript + * - enableLegacyTypescriptModuleInterop: true/false. + */ + + const tsConfigPath = join(options.project, "tsconfig.json"); + + let str; + try { + str = await readFile(tsConfigPath, "utf8"); + } catch (err) { + console.error("Could not find project tsconfig.json"); + console.error(` --project=${options.project}`); + console.error(err); + process.exit(1); + } + const json = JSON.parse(str); + const sucraseOpts = options.sucraseOptions; + if (!sucraseOpts.transforms.includes("typescript")) { + sucraseOpts.transforms.push("typescript"); + } + + const compilerOpts = json.compilerOptions; + if (compilerOpts.outDir) { + options.outDirPath = join(process.cwd(), options.project, compilerOpts.outDir); + } + if (compilerOpts.esModuleInterop !== true) { + sucraseOpts.enableLegacyTypeScriptModuleInterop = true; + } + if (compilerOpts.module === "commonjs") { + if (!sucraseOpts.transforms.includes("imports")) { + sucraseOpts.transforms.push("imports"); + } + } +} + +async function buildDirectory(options) { + let files; + if (options.outDirPath && options.srcDirPath) { + files = await findFiles(options); + } else if (options.project) { + await updateOptionsFromProject(options); + files = await runGlob(options); + } else { + console.error("Project or Source directory required."); + process.exit(1); + } + + for (const file of files) { + await buildFile(file.srcPath, file.outPath, options); + } +} + +async function buildFile(srcPath, outPath, options) { + if (!options.quiet) { + console.log(`${srcPath} -> ${outPath}`); + } + const code = (await readFile(srcPath)).toString(); + const transformedCode = transform(code, {...options.sucraseOptions, filePath: srcPath}).code; + await writeFile(outPath, transformedCode); +} |