@bleed-believer/path-alias
Version:
Assign path alias using tsconfig.json file
104 lines (103 loc) • 4.04 kB
JavaScript
import { basename, resolve, dirname, normalize, join } from "path";
import { normalizeTsConfig } from "./normalize-ts-config.js";
import { toSWCConfig } from "./to-swc-config.js";
import { getTsConfig } from "../get-ts-config/index.js";
import { logger } from "../../logger.js";
export class TsConfig {
#cwd;
get cwd() {
return this.#cwd;
}
#path;
get path() {
return this.#path;
}
#config;
get config() {
return structuredClone(this.#config);
}
get outDir() {
return this.#config?.compilerOptions?.outDir ?? '.';
}
get rootDir() {
return this.#config?.compilerOptions?.rootDir ?? '.';
}
get baseUrl() {
return this.#config?.compilerOptions?.baseUrl ?? '.';
}
// Nuevo diccionario para almacenar los patrones precompilados
#pathRegexMap;
static load(searchPath, filename) {
if (!searchPath) {
searchPath = process.cwd();
}
if (!filename) {
filename = 'tsconfig.json';
}
const fullPath = normalize(join(searchPath, filename));
const result = getTsConfig(fullPath);
result.config?.exclude?.pop();
return new TsConfig(result);
}
constructor(result){
this.#config = normalizeTsConfig(result.config);
this.#path = resolve(result.path);
this.#cwd = dirname(this.#path);
if (!this.#config.compilerOptions?.verbatimModuleSyntax) {
logger.warn(`In "${basename(this.#path)}", the option ` + `"compilerOptions.verbatimModuleSyntax"` + ` must be true to work properly.`);
}
// Precompilar los patrones de paths en el constructor
const compilerOptions = this.#config.compilerOptions ?? {};
const paths = compilerOptions.paths ?? {};
this.#pathRegexMap = [];
for(const pattern in paths){
const regex = this.#patternToRegex(pattern);
const targetPaths = paths[pattern];
this.#pathRegexMap.push({
regex,
targetPaths
});
}
}
#patternToRegex(pattern) {
// Escapar caracteres especiales de regex excepto '*'
let regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&');
// Reemplazar '*' por '(.+?)'
regexPattern = regexPattern.replace(/\*/g, '(.+?)');
return new RegExp('^' + regexPattern + '$');
}
#substituteWildcards(targetPath, matches) {
let index = 0;
return targetPath.replace(/\*/g, ()=>matches[index++] || '');
}
toSwcConfig() {
return toSWCConfig(this);
}
resolveAll(moduleName, dist) {
const compilerOptions = this.#config.compilerOptions ?? {};
const baseUrl = compilerOptions.baseUrl ?? '.';
const rootDir = resolve(this.cwd, this.rootDir);
const outDir = resolve(this.cwd, this.outDir);
const results = [];
for (const { regex, targetPaths } of this.#pathRegexMap){
const match = regex.exec(moduleName);
if (match) {
// Extraer los grupos coincidentes, excluyendo la coincidencia completa
const matchedGroups = match.slice(1);
for (const targetPath of targetPaths){
// Sustituir comodines en targetPath
const substitutedPath = this.#substituteWildcards(targetPath, matchedGroups);
// Resolver la ruta relativa a baseUrl
let fullPath = resolve(this.cwd, baseUrl, substitutedPath);
if (!dist && fullPath.startsWith(rootDir)) {
fullPath = fullPath.replace(/(?<=\.m?)j(?=(sx?)$)/gi, 't');
} else if (dist && fullPath.startsWith(rootDir)) {
fullPath = fullPath.replace(rootDir, outDir).replace(/(?<=\.m?)t(?=(sx?)$)/gi, 'j');
}
results.push(fullPath);
}
}
}
return results;
}
}