bio-dts
Version:
Generate sane and clean types from JavaScript sources
144 lines (101 loc) • 2.88 kB
JavaScript
import Module from 'node:module';
import glob from 'tiny-glob';
import path from 'node:path';
import os from 'node:os';
import fs from 'node:fs';
import generateTypes from '../lib/generate-types.js';
async function run() {
const ts = getTypescript();
const args = process.argv.slice(2);
const {
options,
fileNames
} = ts.parseCommandLine(args);
const help = args.includes('--help') || args.includes('-h');
const [ _verbose, _verboseGrep ] = args.flatMap(arg => /^--verbose(?:=(.*))?$/.exec(arg) || []);
const verbose = _verbose ? _verboseGrep || true : false;
const recursive = args.includes('--recursive') || args.includes('-r');
if (help) {
console.log(`Usage: bio-dts [options] [...filesOrGlobs]
Options:
--recursive, -r recurse into directories
--verbose enable verbose logging
Additional options will be passed to the typescript generator.
Examples:
$ bio-dts --outDir dist -r lib
$ bio-dts 'lib/**/*.js'
`);
return;
}
const globPattern = recursive ? '**/*.js' : '*.js';
const files = [];
for (const fileName of fileNames) {
if (isDir(fileName)) {
const globbedFiles = await glob(globPattern, { cwd: fileName, filesOnly: true });
files.push(...globbedFiles.map(f => path.join(fileName, f)));
} else {
files.push(fileName);
}
}
console.log(`Generating types for ${files.length} files...`);
const generateOptions = {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
...options,
verbose
};
verbose && console.log('Using options ', generateOptions);
const {
diagnostics
} = generateTypes(files, generateOptions, ts);
const errors = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error);
if (errors.length) {
const formatHost = {
getNewLine() {
return os.EOL;
},
getCurrentDirectory() {
return process.cwd();
},
getCanonicalFileName(fileName) {
return fileName;
}
};
console.log('Done with errors:');
console.log();
console.log(
ts.formatDiagnosticsWithColorAndContext(errors, formatHost)
);
return 5;
}
console.log('Done.');
return 0;
}
function isDir(fileName) {
try {
return fs.statSync(fileName).isDirectory();
} catch (err) {
// ignore
return false;
}
}
function getTypescript() {
const cwd = process.cwd();
const createRequire = Module.createRequire || Module.createRequireFromPath;
const requireLocal = createRequire(
path.join(cwd, '__placeholder__.js')
);
try {
return requireLocal('typescript');
} catch (err) {
throw new Error(`failed to load <typescript> from <${ cwd }>`);
}
}
run().then(errorCode => {
process.exit(errorCode);
}, err => {
console.error(err);
process.exit(1);
});