Comparing version 1.1.0 to 1.1.1
@@ -6,2 +6,3 @@ import chalk from 'chalk'; | ||
import { fileURLToPath } from 'url'; | ||
import { UsageError } from './errors.js'; | ||
import { findFiles } from './findFiles.js'; | ||
@@ -32,3 +33,4 @@ import { processFiles } from './processFiles.js'; | ||
} | ||
export async function app(program = defaultCommand) { | ||
export async function app(program = defaultCommand, logger) { | ||
const con = logger || console; | ||
program | ||
@@ -41,4 +43,5 @@ .name((await getName()) || 'ts2mjs') | ||
.option('--root <dir>', 'The root directory.') | ||
.option('--dry-run', 'Dry Run do not update files.') | ||
.option('--no-must-find-files', 'No error if files are not found.') | ||
.option('--dry-run', 'Dry Run do not update files.') | ||
.option('--no-enforce-root', 'Do not fail if relative `.js` files outside of the root are imported.') | ||
.option('--color', 'Force color.') | ||
@@ -59,7 +62,10 @@ .option('--no-color', 'Do not use color.') | ||
} | ||
function logger(msg) { | ||
function log(msg) { | ||
if (optionsCli.dryRun || optionsCli.verbose) { | ||
console.log(msg); | ||
con.log(msg); | ||
} | ||
} | ||
function warning(msg) { | ||
con.error(chalk.yellowBright('Warning: ') + msg); | ||
} | ||
const processOptions = { | ||
@@ -69,7 +75,9 @@ cwd: optionsCli.cwd, | ||
output: optionsCli.output, | ||
progress: logger, | ||
progress: log, | ||
warning, | ||
root: optionsCli.root, | ||
allowJsOutsideOfRoot: !(optionsCli.enforceRoot ?? true), | ||
}; | ||
await processFiles(files, processOptions); | ||
logger(chalk.green('done.')); | ||
log(chalk.green('done.')); | ||
}); | ||
@@ -79,5 +87,16 @@ program.showHelpAfterError(); | ||
} | ||
export async function run(argv, program) { | ||
const prog = await app(program); | ||
await prog.parseAsync(argv); | ||
export async function run(argv, program, logger) { | ||
const con = logger || console; | ||
const prog = await app(program, logger); | ||
try { | ||
await prog.parseAsync(argv); | ||
} | ||
catch (e) { | ||
if (e instanceof UsageError) { | ||
con.error(chalk.red('Error: ') + e.message); | ||
process.exitCode = process.exitCode || 1; | ||
return; | ||
} | ||
throw e; | ||
} | ||
} |
@@ -7,8 +7,10 @@ import { basename, dirname, join as pathJoin, normalize, relative, sep as pathSep } from 'path'; | ||
import { readSourceFile, SOURCE_MAP_URL_MARKER } from './readSourceFile.js'; | ||
import { UsageError } from './errors.js'; | ||
const isSupportedFile = /\.(m?js|d\.m?ts)$/; | ||
const regExpImportExport = /(import|export).*? from ('|")(?<file>\..*?)\2;/g; | ||
export function processSourceFile(src, srcRoot, targetRoot) { | ||
export function processSourceFile(src, options) { | ||
const { srcFilename, content, map: mappings } = src; | ||
const { root: srcRoot, target: targetRoot, allowJsOutsideOfRoot } = options; | ||
assert(doesContain(srcRoot, srcFilename), 'Must be under root.'); | ||
assert(isSupportedFile.test(srcFilename), 'Must be a supported file type.'); | ||
assert(isSupportedFile.test(srcFilename), 'Must be a supported file type (.js, .mjs, .d.ts, .d.mts).'); | ||
const exp = new RegExp(regExpImportExport); | ||
@@ -25,3 +27,12 @@ const magicString = createMagicString(content, { filename: src.srcFilename }); | ||
const end = start + reference.length; | ||
const newRef = rebaseImport(reference, srcFilename, srcRoot, targetRoot); | ||
if (!doesContain(srcRoot, pathJoin(dirname(srcFilename), reference))) { | ||
const message = `Import of a file outside of the root. Import: (${reference}) Source: (${relative(srcRoot, srcFilename)})`; | ||
if (!allowJsOutsideOfRoot) { | ||
throw new UsageError(message); | ||
} | ||
else { | ||
options.warning(message); | ||
} | ||
} | ||
const newRef = calcRelativeImportFilename(reference, srcFilename, srcRoot, targetRoot); | ||
magicString.update(start, end, newRef); | ||
@@ -52,5 +63,5 @@ linesChanged += 1; | ||
} | ||
export async function processFile(filename, root, target) { | ||
export async function processFile(filename, options) { | ||
const src = await readSourceFile(filename); | ||
const r = processSourceFile(src, root, target); | ||
const r = processSourceFile(src, options); | ||
if (!r.mappings) | ||
@@ -64,5 +75,2 @@ return [r]; | ||
} | ||
export const __testing__ = { | ||
calcNewFilename, | ||
}; | ||
function processSourceMap(sourceMap) { | ||
@@ -100,4 +108,7 @@ const pr = { | ||
} | ||
function rebaseImport(importFile, currentFile, root, target) { | ||
const newImportFile = rebaseRelFileReference(importFile, currentFile, root, target).replace(/\.js$/, '.mjs'); | ||
function calcRelativeImportFilename(importFile, currentFile, root, target) { | ||
const newImportFile = rebaseRelFileReference(importFile, currentFile, root, target); | ||
if (doesContain(root, pathJoin(dirname(currentFile), importFile))) { | ||
return newImportFile.replace(/\.js$/, '.mjs'); | ||
} | ||
return newImportFile; | ||
@@ -111,1 +122,5 @@ } | ||
} | ||
export const __testing__ = { | ||
calcNewFilename, | ||
calcRelativeImportFilename, | ||
}; |
@@ -6,3 +6,3 @@ import chalk from 'chalk'; | ||
export async function processFiles(files, options) { | ||
const { output, root = process.cwd(), cwd = process.cwd(), dryRun, progress: logProgress } = options; | ||
const { output, root = process.cwd(), cwd = process.cwd(), dryRun, progress: logProgress, allowJsOutsideOfRoot = false, warning = console.warn, } = options; | ||
const filesWritten = new Map(); | ||
@@ -54,3 +54,3 @@ const result = { | ||
const src = path.resolve(fromDir, filename); | ||
const filesToWrite = await processFile(src, fromDir, toDir); | ||
const filesToWrite = await processFile(src, { root: fromDir, target: toDir, allowJsOutsideOfRoot, warning }); | ||
for (const fileToWrite of filesToWrite) { | ||
@@ -57,0 +57,0 @@ const { filename, oldFilename, content } = fileToWrite; |
{ | ||
"name": "ts2mjs", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "Rename TypeScript Created ESM .js files to .mjs", | ||
@@ -50,2 +50,3 @@ "bin": { | ||
"prettier": "^2.8.1", | ||
"shx": "^0.3.4", | ||
"typescript": "^4.9.4", | ||
@@ -69,2 +70,3 @@ "vite": "^4.0.3", | ||
"build": "tsc -p .", | ||
"build:all": "pnpm build && pnpm build:fixtures && pnpm build:readme", | ||
"build:fixtures": "tsc -p fixtures/sample && ./bin.mjs . --root fixtures/sample/lib --output fixtures/sample/out ", | ||
@@ -75,2 +77,4 @@ "build:readme": "pnpm build:readme:help && pnpm build:readme:inject && prettier -w README.md", | ||
"watch": "tsc -p . --watch", | ||
"clean": "shx rm -rf dist temp coverage", | ||
"clean-build": "pnpm clean && shx rm -rf fixtures/sample/lib fixtures/sample/out && pnpm build:all", | ||
"coverage": "vitest run --coverage", | ||
@@ -77,0 +81,0 @@ "lint": "pnpm eslint && pnpm prettier", |
@@ -107,4 +107,6 @@ # ts2mjs | ||
--root <dir> The root directory. | ||
--dry-run Dry Run do not update files. | ||
--no-must-find-files No error if files are not found. | ||
--dry-run Dry Run do not update files. | ||
--no-enforce-root Do not fail if relative `.js` files outside of the root | ||
are imported. | ||
--color Force color. | ||
@@ -111,0 +113,0 @@ --no-color Do not use color. |
22612
14
410
133
20