merge-tsconfigs
Version:
Merge-tsconfigs is a CLI and node tool for merging tsconfig files into the exact tsconfig file you want 🛣️
300 lines (293 loc) • 10.9 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
default: () => src_default,
logger: () => logger,
mergeConfigContent: () => mergeConfigContent,
mergeConfigObjects: () => mergeConfigObjects,
mergeTsConfigs: () => mergeTsConfigs,
parsePath: () => parsePath,
resolveJSON: () => resolveJSON,
script: () => script,
updateCompilerOptions: () => updateCompilerOptions,
writeTsconfig: () => writeTsconfig
});
module.exports = __toCommonJS(src_exports);
// src/scripts.ts
var import_fs = require("fs");
var import_path = require("path");
var import_json5 = __toESM(require("json5"), 1);
var logger = ({ isDebugging = false, emoji = `\u{1F6E3}\uFE0F`, gap = ` => `, name = "merge-tsconfigs" }) => (type) => (section) => (message) => (err) => {
const debugMsg = isDebugging ? "debugging:" : "";
const sectionMsg = section.length ? `${section}:` : "";
const firstLine = `${name}:${debugMsg}${sectionMsg}`;
const secondLine = message ? `${emoji}${gap}${message}` : "";
if (type === "error") {
console.error(firstLine);
if (secondLine)
console.error(secondLine);
if (err)
console.error(err);
} else if (type === "debug") {
console.debug(firstLine);
if (secondLine)
console.debug(secondLine);
} else if (type === "info") {
console.info(firstLine);
if (secondLine)
console.info(secondLine);
} else {
console.log(firstLine);
if (secondLine)
console.log(secondLine);
}
};
function resolveJSON(path, debug = false) {
try {
const json = import_json5.default.parse((0, import_fs.readFileSync)(path, "utf8"));
return json;
} catch (err) {
if (debug)
logger({ isDebugging: debug })("error")("resolveJSON")("There was an error:")(err);
return {};
}
}
var mergeConfigObjects = (tsconfig1, tsconfig2) => ({
...tsconfig1,
...tsconfig2,
compilerOptions: {
...tsconfig1?.compilerOptions,
...tsconfig2?.compilerOptions
},
...tsconfig1?.exclude || tsconfig2?.exclude ? {
exclude: [
...tsconfig1?.exclude || [],
...tsconfig2?.exclude || []
]
} : {},
...tsconfig1?.include || tsconfig2?.include ? {
include: [
...tsconfig1?.include || [],
...tsconfig2?.include || []
]
} : {}
});
var mergeConfigContent = (tsconfigs, cwd, debug = false) => tsconfigs.reduce((acc = {}, tsconfig) => {
const path = `${cwd}/${tsconfig}`;
let tsconfigJSON = resolveJSON(path, debug);
const parentPath = tsconfigJSON?.extends;
if (parentPath) {
const relativeParentPath = (0, import_path.join)((0, import_path.dirname)(path), parentPath);
const parentTsconfig = resolveJSON(relativeParentPath, debug);
if (parentTsconfig?.extends) {
logger({ isDebugging: debug })("error")("mergeConfigContent")("Parent tsconfig:merge-tsconfigs only handles extending from a parent, consider extending tsconfigs less.")(parentTsconfig);
}
const { extends: _, ...tsconfigWithoutExtends } = tsconfigJSON;
tsconfigJSON = mergeConfigObjects(parentTsconfig, tsconfigWithoutExtends);
}
if (!tsconfigJSON) {
if (debug)
logger({ isDebugging: debug })("error")("mergeConfigContent")("There was an error:")(tsconfigJSON);
return acc;
}
return mergeConfigObjects(acc, tsconfigJSON);
}, {});
var writeTsconfig = (tsconfig, cwd, out, isTesting) => {
if (isTesting)
return tsconfig;
const path = `${cwd}/${out}`;
(0, import_fs.mkdirSync)((0, import_path.dirname)(path), { recursive: true });
(0, import_fs.writeFileSync)(path, JSON.stringify(tsconfig, null, 2));
return tsconfig;
};
var updateCompilerOptions = (compilerOptions2 = {}, currentCompilerOptions, updatedPath) => {
const compilerOptionKeys = compilerOptions2 ? Object.keys(compilerOptions2) : [];
const hasCompilerOptions = compilerOptionKeys.length > 0;
if (!hasCompilerOptions)
return {};
return compilerOptionKeys.reduce((acc = {}, key) => {
const updatedOptions = { ...acc, ...currentCompilerOptions };
const value = compilerOptions2?.[key];
if (updatedOptions?.[key] === "delete") {
delete updatedOptions[key];
return updatedOptions || {};
}
const paths = {
...updatedOptions.paths || {},
...key === "paths" ? { value } : {},
...updatedPath ? { ...updatedPath } : {}
};
return { ...updatedOptions, [key]: value, ...Object.keys(paths).length > 0 ? { paths } : {} };
}, {});
};
var parsePath = (path = "", debug = false) => {
if (!path)
return {};
try {
const json = import_json5.default.parse(path);
return json;
} catch (err) {
if (debug)
logger({ isDebugging: debug })("error")("parsePath")("There was an error:")(err);
return {};
}
};
var mergeTsConfigs = ({
tsconfigs = [],
exclude,
include,
compilerOptions: compilerOptions2,
debug = false,
out = "tsconfig.merged.json",
path,
isTesting = false
}) => {
if (tsconfigs.length === 0) {
if (debug)
logger({ isDebugging: debug })("error")("mergeTsConfig")("No tsconfig files were provided.")(null);
return;
}
const cwd = process.cwd();
const updatedTsconfig = mergeConfigContent(tsconfigs, cwd, debug);
if (debug)
logger({ isDebugging: debug })("debug")("mergeTsConfig")("Updated tsconfig:")(updatedTsconfig);
const updatedPath = parsePath(path, debug);
const updatedCompilerOptions = updateCompilerOptions(
compilerOptions2,
updatedTsconfig?.compilerOptions || {},
updatedPath
);
const updatedExclude = exclude ? { exclude: [...updatedTsconfig?.exclude || [], ...exclude] } : {};
const updatedInclude = include ? { include: [...updatedTsconfig.include || [], ...include] } : {};
const tsconfig = {
...updatedTsconfig,
...updatedExclude,
...updatedInclude,
...Object.keys(updatedCompilerOptions).length > 0 ? { compilerOptions: updatedCompilerOptions } : {}
};
return writeTsconfig(tsconfig, cwd, out, isTesting);
};
var script = mergeTsConfigs;
var scripts_default = mergeTsConfigs;
// src/program.ts
var import_commander = require("commander");
// src/config.ts
var compilerOptions = {
target: "string",
module: "string",
lib: "array",
allowJs: "boolean",
checkJs: "boolean",
jsx: "string",
declaration: "boolean",
sourceMap: "boolean",
outFile: "string",
outDir: "string",
rootDir: "string",
removeComments: "boolean",
noEmit: "boolean",
importHelpers: "boolean",
downlevelIteration: "boolean",
isolatedModules: "boolean",
strict: "boolean",
noImplicitAny: "boolean",
strictNullChecks: "boolean",
noImplicitThis: "boolean",
alwaysStrict: "boolean",
noUnusedLocals: "boolean",
noUnusedParameters: "boolean",
noImplicitReturns: "boolean",
noFallthroughCasesInSwitch: "boolean",
moduleResolution: "string",
baseUrl: "string",
paths: "object",
rootDirs: "array",
typeRoots: "array",
types: "array",
allowSyntheticDefaultImports: "boolean",
sourceRoot: "string",
mapRoot: "string",
inlineSourceMap: "boolean",
inlineSources: "boolean",
experimentalDecorators: "boolean",
emitDecoratorMetadata: "boolean"
};
// src/program.ts
function action(files, options = {}) {
try {
const {
debug = false,
exclude,
include,
isTesting = false,
isTestingCLI = false,
out,
path,
...compilerOptions2
} = options;
if (isTestingCLI) {
console.info({ files, options });
return;
}
script({ debug, exclude, include, isTesting, path, out, tsconfigs: files, compilerOptions: compilerOptions2 });
} catch (err) {
logger({ isDebugging: options.debug })("error")("action")("There was an error:")(err);
}
}
import_commander.program.name("merge-tsconfigs").description(
"Merge-tsconfigs is a CLI and node tool for merging tsconfig files into the exact tsconfig file you want \u{1F6E3}\uFE0F"
).argument("[files...]", "files to check, matches an array pattern").option("-d, --debug", "enable debugging").option("-e, --exclude [exclude...]", "files to exclude, matches a glob or array pattern").option("-i, --include [include...]", "files to include, matches a glob or array pattern").option("--isTesting", "enable testing").option("-o, --out <file>", "output file, otherwise, the file will be written to tsconfig.merged.json").option("--isTesting", "enable testing").option("-t, --isTestingCLI", "enable CLI only testing").option("-p, --path <path>", 'a json parseable string wrapped object, e.g. {"item/*": ["foo": "bar"]}');
Object.keys(compilerOptions).map((name) => ({ name, value: compilerOptions[name] })).forEach(({ name, value }) => {
if (value === "boolean") {
import_commander.program.option(`--${name}`, `tsconfig.compilerOptions.${name}`);
} else if (value === "string") {
import_commander.program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
} else if (value === "array") {
import_commander.program.option(`--${name} [${value}...]`, `tsconfig.compilerOptions.${name}`);
} else if (value === "object") {
import_commander.program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
}
});
import_commander.program.action(action).parse(process.argv);
// src/index.ts
var src_default = scripts_default;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
logger,
mergeConfigContent,
mergeConfigObjects,
mergeTsConfigs,
parsePath,
resolveJSON,
script,
updateCompilerOptions,
writeTsconfig
});