crapifyme
Version:
Ultra-fast developer productivity CLI tools - remove comments, logs, and more
203 lines • 7.81 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PathResolver = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
class PathResolver {
constructor(projectRoot = process.cwd()) {
this.aliases = [];
this.tsConfigPaths = {};
this.projectRoot = projectRoot;
this.loadTsConfigPaths();
}
addAlias(pattern, replacement) {
const alias = {
pattern,
replacement,
regex: this.createAliasRegex(pattern)
};
this.aliases.push(alias);
}
addAliases(aliases) {
for (const alias of aliases) {
this.addAlias(alias.pattern, alias.replacement);
}
}
parseAliasString(aliasString) {
const pairs = aliasString.split(',');
for (const pair of pairs) {
const [pattern, replacement] = pair.split(':').map(s => s.trim());
if (pattern && replacement) {
this.addAlias(pattern, replacement);
}
}
}
resolveImportPath(importPath, currentFile) {
if (this.isExternalModule(importPath)) {
return importPath;
}
for (const alias of this.aliases) {
if (alias.regex.test(importPath)) {
return importPath.replace(alias.regex, alias.replacement);
}
}
for (const [aliasPattern, paths] of Object.entries(this.tsConfigPaths)) {
const match = this.matchTsConfigPath(importPath, aliasPattern);
if (match && paths.length > 0) {
const resolvedPath = this.resolveTsConfigPath(match, paths[0]);
if (resolvedPath) {
return resolvedPath;
}
}
}
return this.resolveRelativePath(importPath, currentFile);
}
convertToAbsolute(importPath, currentFile) {
if (this.isExternalModule(importPath)) {
return importPath;
}
if (importPath.startsWith('./') || importPath.startsWith('../')) {
const currentDir = path_1.default.dirname(currentFile);
const absolutePath = path_1.default.resolve(currentDir, importPath);
const relativePath = path_1.default.relative(this.projectRoot, absolutePath);
return `@/${relativePath}`.replace(/\\/g, '/');
}
return importPath;
}
convertToRelative(importPath, currentFile) {
if (this.isExternalModule(importPath)) {
return importPath;
}
if (importPath.startsWith('@/') || importPath.startsWith('~/')) {
const targetPath = importPath.replace(/^[@~]\//, '');
const currentDir = path_1.default.dirname(currentFile);
const targetAbsolute = path_1.default.resolve(this.projectRoot, targetPath);
const relativePath = path_1.default.relative(currentDir, targetAbsolute);
if (relativePath.startsWith('.')) {
return relativePath.replace(/\\/g, '/');
}
else {
return `./${relativePath}`.replace(/\\/g, '/');
}
}
return importPath;
}
normalizeImportPath(importPath) {
return importPath.replace(/\\/g, '/').replace(/\/+/g, '/').replace(/\/$/, '');
}
getFileExtensions() {
return ['.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte'];
}
resolveModulePath(importPath, currentFile) {
const basePath = this.resolveImportPath(importPath, currentFile);
if (this.isExternalModule(basePath)) {
return basePath;
}
const possiblePaths = this.generatePossiblePaths(basePath, currentFile);
for (const possiblePath of possiblePaths) {
if (fs_1.default.existsSync(possiblePath)) {
return possiblePath;
}
}
return null;
}
createAliasRegex(pattern) {
const escapedPattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '(.*)');
return new RegExp(`^${escapedPattern}`);
}
loadTsConfigPaths() {
const tsConfigPath = path_1.default.join(this.projectRoot, 'tsconfig.json');
if (fs_1.default.existsSync(tsConfigPath)) {
try {
const tsConfig = JSON.parse(fs_1.default.readFileSync(tsConfigPath, 'utf-8'));
const compilerOptions = tsConfig.compilerOptions;
if (compilerOptions?.paths) {
this.tsConfigPaths = compilerOptions.paths;
}
if (compilerOptions?.baseUrl) {
const baseUrl = path_1.default.resolve(this.projectRoot, compilerOptions.baseUrl);
this.addAlias('*', baseUrl + '/*');
}
}
catch (error) {
console.warn(`Warning: Could not parse tsconfig.json: ${error.message}`);
}
}
}
matchTsConfigPath(importPath, pattern) {
if (pattern === '*') {
return importPath;
}
if (pattern.endsWith('/*')) {
const prefix = pattern.slice(0, -2);
if (importPath.startsWith(prefix)) {
return importPath.slice(prefix.length);
}
}
if (pattern === importPath) {
return '';
}
return null;
}
resolveTsConfigPath(match, pathPattern) {
if (pathPattern.endsWith('/*')) {
const basePath = pathPattern.slice(0, -2);
return path_1.default.join(basePath, match).replace(/\\/g, '/');
}
return pathPattern.replace(/\\/g, '/');
}
isExternalModule(importPath) {
return (!importPath.startsWith('.') &&
!importPath.startsWith('/') &&
!importPath.startsWith('@/') &&
!importPath.startsWith('~/'));
}
resolveRelativePath(importPath, currentFile) {
if (importPath.startsWith('./') || importPath.startsWith('../')) {
const currentDir = path_1.default.dirname(currentFile);
const resolved = path_1.default.resolve(currentDir, importPath);
return path_1.default.relative(this.projectRoot, resolved).replace(/\\/g, '/');
}
return importPath;
}
generatePossiblePaths(basePath, currentFile) {
const paths = [];
const currentDir = path_1.default.dirname(currentFile);
let resolvedBase;
if (path_1.default.isAbsolute(basePath)) {
resolvedBase = basePath;
}
else {
resolvedBase = path_1.default.resolve(currentDir, basePath);
}
paths.push(resolvedBase);
for (const ext of this.getFileExtensions()) {
paths.push(resolvedBase + ext);
}
const indexPath = path_1.default.join(resolvedBase, 'index');
for (const ext of this.getFileExtensions()) {
paths.push(indexPath + ext);
}
return paths;
}
static parseCliAliases(aliasString) {
const aliases = [];
const pairs = aliasString.split(',');
for (const pair of pairs) {
const [pattern, replacement] = pair.split(':').map(s => s.trim());
if (pattern && replacement) {
aliases.push({
pattern,
replacement,
regex: new RegExp(`^${pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '(.*)')}`)
});
}
}
return aliases;
}
}
exports.PathResolver = PathResolver;
//# sourceMappingURL=path-resolver.js.map