tsconfig-utils
Version:
A collection of utilities for working with `tsconfig.json` files
79 lines (78 loc) • 2.56 kB
JavaScript
import { readFile } from 'fs/promises';
import { resolve } from 'path';
import { alias, boolean } from './types.js';
import { fork } from 'child_process';
import { createRequire } from 'module';
import json5 from 'json5';
export class TsConfig {
cwd;
args;
extends;
files;
references;
compilerOptions = {};
constructor(cwd, args) {
this.cwd = cwd;
this.args = args;
}
index(key) {
const names = [key, ...alias[key] || []].map(word => word.length > 1 ? `--${word}` : `-${word}`);
return this.args.findIndex(arg => names.some(name => arg === name));
}
get(key, fallback) {
const index = this.index(key);
if (index < 0)
return fallback ?? this.compilerOptions[key];
if (boolean.includes(key)) {
return this.args[index + 1] !== 'false';
}
else {
return this.args[index + 1];
}
}
set(key, value, override = true) {
const index = this.index(key);
if (index < 0) {
this.args.push(`--${key}`, value);
}
else if (override) {
this.args.splice(index + 1, 1, value);
}
}
}
export class TsConfigError extends Error {
}
export async function read(filename) {
const source = await readFile(filename, 'utf8');
return json5.parse(source);
}
function makeArray(value) {
return Array.isArray(value) ? value : value ? [value] : [];
}
export async function load(cwd, args = []) {
const config = new TsConfig(cwd, args);
const filename = resolve(cwd, config.get('project', 'tsconfig.json'));
Object.assign(config, await read(filename));
const queue = makeArray(config.extends).map(path => createRequire(filename).resolve(path));
while (queue.length) {
const filename = queue.pop();
const parent = await read(filename);
config.compilerOptions = {
...parent.compilerOptions,
...config.compilerOptions,
types: [
...parent.compilerOptions.types ?? [],
...config.compilerOptions.types ?? [],
],
};
queue.push(...makeArray(parent.extends).map(path => createRequire(filename).resolve(path)));
}
return config;
}
export async function compile(args, options) {
const path = createRequire(import.meta.url).resolve('typescript/bin/tsc');
const child = fork(path, args, { stdio: 'inherit', ...options });
return new Promise((resolve) => {
child.on('close', resolve);
});
}