@clawject/di
Version:
<p align="center"> <a href="https://clawject.com/" target="_blank"><img src="https://clawject.com/img/logo.svg" align="center" alt="Clawject Logo" width="120" height="120" /></a> </p>
125 lines (124 loc) • 7.63 kB
JavaScript
"use strict";
/**
* Code of this file is based on ts-morph/common and ts-morph/bootstrap packages from this repository https://github.com/dsherret/ts-morph
*
* Unfortunately, typescript package is bundled together with ts-morph, but we want it to be a peer dependency, so we can't use it directly.
* */
var _Project_instances, _Project_ts, _Project_sourceFiles, _Project_compilerOptions, _Project_normalizeFileName;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Project = void 0;
exports.createProject = createProject;
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs"));
const path = tslib_1.__importStar(require("path"));
function createProject(ts, options = {}) {
const project = new Project({ ...options, ts });
// Load files from tsconfig if provided
if (options.tsConfigFilePath && !options.skipAddingFilesFromTsConfig) {
project.addSourceFilesFromTsConfig(options.tsConfigFilePath);
}
return project;
}
class Project {
constructor(options) {
_Project_instances.add(this);
_Project_ts.set(this, void 0);
_Project_sourceFiles.set(this, new Map());
_Project_compilerOptions.set(this, void 0);
tslib_1.__classPrivateFieldSet(this, _Project_ts, options.ts, "f");
// Load compiler options from tsconfig if provided
if (options.tsConfigFilePath) {
const configPath = path.resolve(options.tsConfigFilePath);
const configFile = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").readConfigFile(configPath, tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").sys.readFile);
if (configFile.error) {
throw new Error(`Error reading tsconfig: ${configFile.error.messageText}`);
}
const parsedConfig = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").parseJsonConfigFileContent(configFile.config, tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").sys, path.dirname(configPath));
tslib_1.__classPrivateFieldSet(this, _Project_compilerOptions, {
...parsedConfig.options,
...(options.compilerOptions || {})
}, "f");
}
else {
tslib_1.__classPrivateFieldSet(this, _Project_compilerOptions, options.compilerOptions || {}, "f");
}
}
addSourceFilesFromTsConfig(tsConfigFilePath) {
const configPath = path.resolve(tsConfigFilePath);
const configFile = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").readConfigFile(configPath, tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").sys.readFile);
if (configFile.error) {
throw new Error(`Error reading tsconfig: ${configFile.error.messageText}`);
}
const parsedConfig = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").parseJsonConfigFileContent(configFile.config, tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").sys, path.dirname(configPath));
// Add all files from tsconfig
for (const fileName of parsedConfig.fileNames) {
if (fs.existsSync(fileName)) {
const sourceText = fs.readFileSync(fileName, 'utf-8');
this.updateSourceFile(fileName, sourceText);
}
}
}
getSourceFile(fileName) {
return tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").get(tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, fileName));
}
updateSourceFile(fileNameOrSourceFile, sourceText) {
let sourceFile;
if (typeof fileNameOrSourceFile === 'string') {
const normalizedFileName = tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, fileNameOrSourceFile);
sourceFile = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").createSourceFile(normalizedFileName, sourceText, tslib_1.__classPrivateFieldGet(this, _Project_compilerOptions, "f").target || tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").ScriptTarget.Latest, true);
}
else {
sourceFile = fileNameOrSourceFile;
}
const normalizedFileName = tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, sourceFile.fileName);
tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").set(normalizedFileName, sourceFile);
return sourceFile;
}
createSourceFile(fileName, sourceText = '') {
const normalizedFileName = tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, fileName);
if (tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").has(normalizedFileName)) {
throw new Error(`Source file already exists: ${fileName}`);
}
const sourceFile = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").createSourceFile(normalizedFileName, sourceText, tslib_1.__classPrivateFieldGet(this, _Project_compilerOptions, "f").target || tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").ScriptTarget.Latest, true);
tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").set(normalizedFileName, sourceFile);
return sourceFile;
}
removeSourceFile(fileNameOrSourceFile) {
const fileName = typeof fileNameOrSourceFile === 'string'
? fileNameOrSourceFile
: fileNameOrSourceFile.fileName;
tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").delete(tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, fileName));
}
resolveSourceFileDependencies() {
// Creating a program will resolve dependencies
this.createProgram();
}
createProgram(options) {
const rootNames = Array.from(tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").keys());
const compilerHost = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").createCompilerHost(tslib_1.__classPrivateFieldGet(this, _Project_compilerOptions, "f"));
// Override getSourceFile to use our cached source files
const originalGetSourceFile = compilerHost.getSourceFile;
compilerHost.getSourceFile = (fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) => {
const normalizedFileName = tslib_1.__classPrivateFieldGet(this, _Project_instances, "m", _Project_normalizeFileName).call(this, fileName);
const cachedFile = tslib_1.__classPrivateFieldGet(this, _Project_sourceFiles, "f").get(normalizedFileName);
if (cachedFile) {
return cachedFile;
}
return originalGetSourceFile.call(compilerHost, fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
};
const program = tslib_1.__classPrivateFieldGet(this, _Project_ts, "f").createProgram({
rootNames,
options: tslib_1.__classPrivateFieldGet(this, _Project_compilerOptions, "f"),
host: compilerHost,
...options,
});
//Necessary to set parent nodes
program.getTypeChecker();
return program;
}
}
exports.Project = Project;
_Project_ts = new WeakMap(), _Project_sourceFiles = new WeakMap(), _Project_compilerOptions = new WeakMap(), _Project_instances = new WeakSet(), _Project_normalizeFileName = function _Project_normalizeFileName(fileName) {
// Normalize path separators and resolve to absolute path
return path.resolve(fileName).replace(/\\/g, '/');
};