UNPKG

@odata2ts/odata2ts

Version:

Flexible generator to produce various TypeScript artefacts (from simple model interfaces to complete odata clients) from OData metadata files

200 lines 8.86 kB
import { __awaiter } from "tslib"; import * as path from "path"; import { mkdirp } from "mkdirp"; import { Project } from "ts-morph"; import { firstCharLowerCase } from "xml2js/lib/processors.js"; import { ImportContainer } from "../generator/ImportContainer.js"; import { FileHandler } from "./FileHandler.js"; import { createFormatter } from "./formatter/index.js"; import { loadTsMorphCompilerOptions } from "./TsMorphHelper.js"; export function createProjectManager(outputDir, emitMode, namingHelper, dataModel, options) { return __awaiter(this, void 0, void 0, function* () { const { usePrettier = false, tsConfigPath = "tsconfig.json" } = options; const formatter = usePrettier ? yield createFormatter(outputDir, usePrettier) : undefined; const compilerOpts = yield loadTsMorphCompilerOptions(tsConfigPath, emitMode, outputDir); const pm = new ProjectManager(outputDir, emitMode, namingHelper, dataModel, formatter, compilerOpts, Object.assign({ usePrettier, tsConfigPath }, options)); yield pm.init(); return pm; }); } export class ProjectManager { constructor(outputDir, emitMode, namingHelper, dataModel, formatter, compilerOptions, options) { this.outputDir = outputDir; this.emitMode = emitMode; this.namingHelper = namingHelper; this.dataModel = dataModel; this.formatter = formatter; this.options = options; // Create ts-morph project this.project = new Project({ // manipulationSettings: this.formatter.getSettings(), skipAddingFilesFromTsConfig: true, compilerOptions, }); if (options.noOutput) { this.cachedFiles = new Map(); } } getDataModel() { return this.dataModel; } /** * Only filled when noOutput=true */ getCachedFiles() { return this.cachedFiles; } writeFile(fileHandler) { return __awaiter(this, void 0, void 0, function* () { if (this.options.noOutput) { yield fileHandler.write(this.emitMode, true); this.cachedFiles.set(fileHandler.getFullFilePath(), fileHandler.getFile()); return; } return fileHandler.write(this.emitMode); }); } createFile(name, reservedNames, additionalPath = "", forceTypeChecking = false) { const fileName = path.join(this.outputDir, additionalPath, `${name}.ts`); const imports = new ImportContainer(additionalPath, name, this.dataModel, this.namingHelper.getFileNames(), !!this.options.bundledFileGeneration, reservedNames); return new FileHandler(additionalPath, name, this.project.createSourceFile(fileName), imports, this.formatter, forceTypeChecking || !!this.options.allowTypeChecking); } init() { return __awaiter(this, void 0, void 0, function* () { if (!this.options.bundledFileGeneration) { // ensure folder for each model: we do this at this point for performance reasons yield Promise.all(this.dataModel.getModelTypes().map((mt) => mkdirp(path.join(this.outputDir, mt.folderPath)))); } }); } initModels() { if (this.options.bundledFileGeneration) { // collect reserved names, that is names of classes we're going to create => imports must take them into account const reservedWords = this.dataModel.getModelTypes().reduce((collector, model) => { var _a; const asEntityType = model; collector.push(model.modelName); if (asEntityType.editableName) { collector.push(asEntityType.editableName); } if ((_a = asEntityType.id) === null || _a === void 0 ? void 0 : _a.modelName) { collector.push(asEntityType.id.modelName); } this.dataModel.getAllEntityOperations(model.fqName).forEach((op) => { if (op.parameters.length) { collector.push(op.paramsModelName); } }); return collector; }, []); this.dataModel.getUnboundOperationTypes().forEach((op) => { if (op.parameters.length) { reservedWords.push(op.paramsModelName); } }); this.mainModelFile = this.createFile(this.namingHelper.getFileNames().model, reservedWords); } } finalizeModels() { return __awaiter(this, void 0, void 0, function* () { if (this.mainModelFile && (this.options.bundledFileGeneration || this.mainModelFile.getFile().getFullText().length)) { yield this.writeFile(this.mainModelFile); } }); } initQObjects() { if (this.options.bundledFileGeneration) { // collect reserved names, that is names of classes we're going to create => imports must take them into account const reservedWords = this.dataModel.getModelTypes().reduce((collector, model) => { var _a; const asEntityType = model; if (asEntityType.qName) { collector.push(asEntityType.qName, firstCharLowerCase(asEntityType.qName)); } if ((_a = asEntityType.id) === null || _a === void 0 ? void 0 : _a.qName) { collector.push(asEntityType.id.qName); } this.dataModel.getAllEntityOperations(model.fqName).forEach((op) => { collector.push(op.qName); }); return collector; }, []); this.dataModel.getUnboundOperationTypes().forEach((op) => { reservedWords.push(op.qName); }); this.mainQFile = this.createFile(this.namingHelper.getFileNames().qObject, reservedWords); } } finalizeQObjects() { return __awaiter(this, void 0, void 0, function* () { if (this.mainQFile && (this.options.bundledFileGeneration || this.mainQFile.getFile().getFullText().length)) { yield this.writeFile(this.mainQFile); } }); } initServices() { const mainServiceName = this.namingHelper.getMainServiceName(); const reservedNames = [mainServiceName]; if (this.options.bundledFileGeneration) { [...this.dataModel.getEntityTypes(), ...this.dataModel.getComplexTypes()].reduce((collector, model) => { collector.push(model.serviceName, model.serviceCollectionName); return collector; }, reservedNames); } this.mainServiceFile = this.createFile(mainServiceName, reservedNames); } finalizeServices() { return __awaiter(this, void 0, void 0, function* () { if (this.mainServiceFile) { yield this.writeFile(this.mainServiceFile); } }); } getMainServiceFile() { return this.mainServiceFile; } createOrGetMainModelFile(reservedNames) { if (!this.mainModelFile) { this.mainModelFile = this.createFile(this.namingHelper.getFileNames().model, reservedNames, "", true); } return this.mainModelFile; } createOrGetMainQObjectFile(reservedNames) { if (!this.mainQFile) { this.mainQFile = this.createFile(this.namingHelper.getFileNames().qObject, reservedNames); } return this.mainQFile; } createOrGetModelFile(folderPath, name, reservedNames) { if (this.mainModelFile) { return this.mainModelFile; } // model files always allow for type checking return this.createFile(name, reservedNames, folderPath, true); } createOrGetQObjectFile(folderPath, name, reservedNames) { if (this.mainQFile) { return this.mainQFile; } return this.createFile(name, reservedNames, folderPath); } createOrGetServiceFile(folderPath, name, reservedNames) { if (this.options.bundledFileGeneration) { return this.mainServiceFile; } return this.createFile(name, reservedNames, folderPath); } finalizeFile(file) { return __awaiter(this, void 0, void 0, function* () { // write individual files in unbundled mode & if this is not one of the main files on root level if (!this.options.bundledFileGeneration && file.path !== "" && !Object.values(this.namingHelper.getFileNames()).includes(file.fileName)) { yield this.writeFile(file); } }); } } //# sourceMappingURL=ProjectManager.js.map