UNPKG

hades-cli

Version:
196 lines (195 loc) 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeWriter = void 0; const ts_morph_1 = require("ts-morph"); const typescript_1 = require("typescript"); const import_driver_1 = require("./import.driver"); const array_driver_1 = require("./array.driver"); const path = require("path"); const fs = require("fs"); class CodeWriter { constructor(srcDirectory, appDirectory, frameworkDirectory, boundedContextName, moduleName, moduleNames) { this.srcDirectory = srcDirectory; this.appDirectory = appDirectory; this.frameworkDirectory = frameworkDirectory; this.boundedContextName = boundedContextName; this.moduleName = moduleName; this.moduleNames = moduleNames; this.project = new ts_morph_1.Project({ tsConfigFilePath: path.join(process.cwd(), 'tsconfig.json'), // these are the defaults manipulationSettings: { // TwoSpaces, FourSpaces, EightSpaces, or Tab indentationText: ts_morph_1.IndentationText.FourSpaces, // LineFeed or CarriageReturnLineFeed newLineKind: typescript_1.NewLineKind.LineFeed, // Single or Double quoteKind: ts_morph_1.QuoteKind.Single, // Whether to change shorthand property assignments to property assignments // and add aliases to import & export specifiers (see more information in // the renaming section of the documentation). usePrefixAndSuffixTextForRename: false, // Whether to use trailing commas in multi-line scenarios where trailing // commas would be used. useTrailingCommas: false } }); } generateTestingForeignReferences(properties) { // get foreign relationship const foreignRelationships = properties.getForeignRelationship(this.boundedContextName); // check that exist bounded context folder if (!fs.existsSync(path.join(process.cwd(), 'cliter', this.boundedContextName.toKebabCase()))) return; // get all yaml files to get all modules managed by cli const yamlFiles = fs.readdirSync(path.join(process.cwd(), 'cliter', this.boundedContextName.toKebabCase())); for (const foreignRelationship of foreignRelationships) { if (!foreignRelationship.relationshipModulePath) return; const foreignBoundedContextName = foreignRelationship.relationshipModulePath.split('/')[0]; for (const yamlFile of yamlFiles) { // get filename of e2e test const e2eTestFile = yamlFile.replace('.yml', '').concat('.e2e-spec.ts'); const e2eTestPath = path.join(process.cwd(), 'test', 'acceptance', this.boundedContextName.toKebabCase(), e2eTestFile); // check that exist e2e test file if (fs.existsSync(e2eTestPath)) { // get sourceFile of e2e test const sourceFile = this.project.addSourceFileAtPath(e2eTestPath); // register import in e2e test import_driver_1.ImportDriver.createImportItems(sourceFile, [ `${foreignBoundedContextName.toPascalCase()}Module` ], `./../../../src/apps/${foreignBoundedContextName.toKebabCase()}/${foreignBoundedContextName.toKebabCase()}.module`); // register import in import array array_driver_1.ArrayDriver.createArrayItem(sourceFile, `${foreignBoundedContextName.toPascalCase()}Module`, `importForeignModules`); sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.saveSync(); } } } } generateReferences(properties) { const sourceFile = this.project.addSourceFileAtPath(path.join(process.cwd(), this.srcDirectory, this.appDirectory, this.boundedContextName.toKebabCase(), 'index.ts')); // register import import_driver_1.ImportDriver.createImportItems(sourceFile, [ `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Handlers`, `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Services`, `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Model`, `I${this.moduleName.toPascalCase()}Repository`, `Sequelize${this.moduleName.toPascalCase()}Repository`, `${this.moduleName.toPascalCase()}Sagas` ], `./${this.moduleName.toKebabCase()}`); // handlers array_driver_1.ArrayDriver.createArrayItem(sourceFile, `...${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Handlers`, `${this.boundedContextName.toPascalCase()}Handlers`); // services array_driver_1.ArrayDriver.createArrayItem(sourceFile, `...${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Services`, `${this.boundedContextName.toPascalCase()}Services`); // models array_driver_1.ArrayDriver.createArrayItem(sourceFile, `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Model`, `${this.boundedContextName.toPascalCase()}Models`); // intermediate table model for (const intermediateModel of properties.withRelationshipIntermediateTable) { import_driver_1.ImportDriver.createImportItems(sourceFile, [intermediateModel.intermediateModel], `./${this.moduleName.toKebabCase()}`); array_driver_1.ArrayDriver.createArrayItem(sourceFile, intermediateModel.intermediateModel, `${this.boundedContextName.toPascalCase()}Models`); } // repositories array_driver_1.ArrayDriver.createArrayItem(sourceFile, ` { provide: I${this.moduleName.toPascalCase()}Repository, useClass: Sequelize${this.moduleName.toPascalCase()}Repository }`, `${this.boundedContextName.toPascalCase()}Repositories`); // sagas array_driver_1.ArrayDriver.createArrayItem(sourceFile, `${this.moduleName.toPascalCase()}Sagas`, `${this.boundedContextName.toPascalCase()}Sagas`); sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.saveSync(); } declareFramework() { // get decorator arguments const sourceFile = this.project.addSourceFileAtPath(path.join(process.cwd(), this.srcDirectory, this.frameworkDirectory, this.boundedContextName.toKebabCase(), `${this.boundedContextName.toKebabCase()}.module.ts`)); const moduleDecoratorArguments = this.getModuleDecoratorArguments(sourceFile, `${this.boundedContextName.toPascalCase()}Module`); const providers = moduleDecoratorArguments.getProperty('providers'); const providersArray = providers === null || providers === void 0 ? void 0 : providers.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); const controllers = moduleDecoratorArguments.getProperty('controllers'); const controllersArray = controllers === null || controllers === void 0 ? void 0 : controllers.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); // register imports from bounded context import_driver_1.ImportDriver.createImportItems(sourceFile, [ `${this.boundedContextName.toPascalCase()}Models`, `${this.boundedContextName.toPascalCase()}Handlers`, `${this.boundedContextName.toPascalCase()}Services`, `${this.boundedContextName.toPascalCase()}Repositories`, `${this.boundedContextName.toPascalCase()}Sagas`, ], `@hades/${this.boundedContextName.toKebabCase()}`); // register import for controllers and providers import_driver_1.ImportDriver.createImportItems(sourceFile, [ `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Controllers`, `${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Resolvers` ], `./${this.moduleName.toKebabCase()}`); // add model to ORM array argument const modelArrayArgument = this.getModelArrayArgument(moduleDecoratorArguments); array_driver_1.ArrayDriver.createArrayItem(sourceFile, `...${this.boundedContextName.toPascalCase()}Models`, modelArrayArgument); // add handlers to providers array_driver_1.ArrayDriver.createArrayItems(sourceFile, [ `...${this.boundedContextName.toPascalCase()}Handlers`, `...${this.boundedContextName.toPascalCase()}Services`, `...${this.boundedContextName.toPascalCase()}Repositories`, `...${this.boundedContextName.toPascalCase()}Sagas`, `...${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Resolvers`, ], providersArray); // add controller to controllers array array_driver_1.ArrayDriver.createArrayItem(sourceFile, `...${this.boundedContextName.toPascalCase()}${this.moduleName.toPascalCase()}Controllers`, controllersArray); sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.saveSync(); } declareModule() { const sourceFile = this.project.addSourceFileAtPath(path.join(process.cwd(), this.srcDirectory, 'app.module.ts')); const moduleDecoratorArguments = this.getModuleDecoratorArguments(sourceFile, 'AppModule'); const modules = this.getImportedModules(sourceFile); if (!modules.includes(`${this.boundedContextName.toPascalCase()}Module`)) { // import module import_driver_1.ImportDriver.createImportItems(sourceFile, [`${this.boundedContextName.toPascalCase()}Module`], `./apps/${this.boundedContextName.toKebabCase()}/${this.boundedContextName.toKebabCase()}.module`); // register module const importsArgument = moduleDecoratorArguments.getProperty('imports'); const importsArray = importsArgument === null || importsArgument === void 0 ? void 0 : importsArgument.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); importsArray.addElement(`${this.boundedContextName.toPascalCase()}Module`, { useNewLines: true }); } sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.saveSync(); } declareAuthModuleInShareModule() { const sourceFile = this.project.addSourceFileAtPath(path.join(process.cwd(), this.srcDirectory, path.join('apps', 'shared', 'shared.module.ts'))); const moduleDecoratorArguments = this.getModuleDecoratorArguments(sourceFile, 'SharedModule'); // register import auth module import_driver_1.ImportDriver.createImportItems(sourceFile, [ `AuthModule` ], `@hades/iam/shared/domain/modules/auth/auth.module.ts`); // register auth module const importsArgument = moduleDecoratorArguments.getProperty('imports'); const importsArray = importsArgument === null || importsArgument === void 0 ? void 0 : importsArgument.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); const importsElements = importsArray.getElements(); // check if AuthModule is imported if (!importsElements.find(el => el.getText() === 'AuthModule')) importsArray.addElement(`AuthModule`, { useNewLines: true }); // register auth module const exportsArgument = moduleDecoratorArguments.getProperty('exports'); const exportsArray = exportsArgument === null || exportsArgument === void 0 ? void 0 : exportsArgument.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); const exportsElements = exportsArray.getElements(); // check if AuthModule is imported if (!exportsElements.find(el => el.getText() === 'AuthModule')) exportsArray.addElement(`AuthModule`, { useNewLines: true }); sourceFile === null || sourceFile === void 0 ? void 0 : sourceFile.saveSync(); } getModelArrayArgument(moduleDecoratorArguments) { const importsArgument = moduleDecoratorArguments.getProperty('imports'); const importsArray = importsArgument.getInitializerIfKindOrThrow(typescript_1.SyntaxKind.ArrayLiteralExpression); const importsElements = importsArray.getElements(); const SequelizeModuleElement = importsElements.find(el => el.getText().indexOf('SequelizeModule.forFeature') === 0); return SequelizeModuleElement.getArguments()[0]; } getImportedModules(sourceFile) { const imports = sourceFile.getImportDeclarations(); let modules = []; for (const importObj of imports) { modules = modules.concat(importObj.getNamedImports().map(i => i.getName())); } return modules; } getModuleDecoratorArguments(sourceFile, className) { const moduleClass = sourceFile.getClass(className); const moduleDecorator = moduleClass === null || moduleClass === void 0 ? void 0 : moduleClass.getDecorator('Module'); return moduleDecorator.getArguments()[0]; } } exports.CodeWriter = CodeWriter;