UNPKG

generator-jhipster-nodejs

Version:

A NodeJS blueprint that creates the backend using NodeJS with NestJS framework

285 lines (262 loc) 9.81 kB
import { readFile } from 'node:fs/promises'; import BaseApplicationGenerator from 'generator-jhipster/generators/base-application'; import { createNeedleCallback, mutateData } from 'generator-jhipster/generators/base/support'; import { getEnumInfo } from 'generator-jhipster/generators/base-application/support'; import { TEMPLATES_WEBAPP_SOURCES_DIR } from 'generator-jhipster'; import { SERVER_NODEJS_SRC_DIR } from '../generator-nodejs-constants.js'; import { serverFiles } from './files.js'; import { entityFiles } from './entity-files.js'; function sanitizeDbType(fieldType, dbType) { if (dbType === 'sqlite') { if (fieldType === 'timestamp') { return 'datetime'; } } return fieldType; } const fieldTypes = { Boolean: 'boolean', Integer: 'number', Long: 'number', Float: 'number', Double: 'number', BigDecimal: 'number', String: 'string', UUID: 'string', }; const dbTypes = { Boolean: 'boolean', Integer: 'integer', Long: 'long', Float: 'float', Double: 'double', BigDecimal: 'decimal', LocalDate: 'date', Instant: 'timestamp', ZonedDateTime: 'datetime', AnyBlob: 'blob', ImageBlob: 'blob', Blob: 'blob', TextBlob: 'blob', 'byte[]': 'blob', }; const databaseDrivers = { mongodb: 'mongodb', mysql: 'mysql2', postgresql: 'pg', oracle: 'oracledb', mssql: 'mssql', }; const databaseDevDrivers = { mongodb: 'mongodb-memory-server', mysql: 'sqlite3', postgresql: 'sqlite3', oracle: 'sqlite3', mssql: 'sqlite3', }; export default class extends BaseApplicationGenerator { oldNodejsVersion; nodejsPackageJson; constructor(args, opts, features) { super(args, opts, { ...features, queueCommandTasks: true }); } async beforeQueue() { await this.dependsOnJHipster('bootstrap-application'); await this.dependsOnJHipster('common'); } get [BaseApplicationGenerator.INITIALIZING]() { return this.asInitializingTaskGroup({ async initializing() { this.oldNodejsVersion = this.blueprintConfig.nodejsVersion ?? '3.0.0'; this.nodejsPackageJson = JSON.parse((await readFile(this.templatePath('../../../package.json'), 'utf-8')).toString()); this.blueprintConfig.nodejsVersion = this.nodejsPackageJson.version; }, }); } get [BaseApplicationGenerator.CONFIGURING]() { return this.asConfiguringTaskGroup({ async configuringTemplateTask() { const { prodDatabaseType, databaseType } = this.jhipsterConfigWithDefaults; const databaseTypeMongodb = (prodDatabaseType ?? databaseType) === 'mongodb'; this.jhipsterConfig.databaseType = databaseTypeMongodb ? 'mongodb' : 'sql'; if (databaseTypeMongodb) { this.jhipsterConfig.prodDatabaseType = 'mongodb'; } }, }); } get [BaseApplicationGenerator.COMPOSING]() { return this.asComposingTaskGroup({ async composingTemplateTask() { await this.composeWithJHipster('docker'); }, }); } get [BaseApplicationGenerator.LOADING]() { return this.asLoadingTaskGroup({ async loadingTemplateTask({ application }) { application.nodeServerDependencies = {}; this.loadNodeDependenciesFromPackageJson(application.nodeServerDependencies, this.templatePath('../resources/package.json')); }, }); } get [BaseApplicationGenerator.PREPARING]() { return this.asPreparingTaskGroup({ drivers({ applicationDefaults }) { applicationDefaults({ __override__: false, nodeProdDatabaseDriver: ({ databaseType, prodDatabaseType = databaseType }) => databaseDrivers[prodDatabaseType], nodeDevDatabaseDriver: ({ databaseType, prodDatabaseType = databaseType }) => databaseDevDrivers[prodDatabaseType], nodeProdDatabaseType: ({ databaseType, prodDatabaseType = databaseType }) => prodDatabaseType === 'postgresql' ? 'postgres' : prodDatabaseType, nodeDevDatabaseType: ({ databaseType, devDatabaseType = databaseType }) => devDatabaseType === 'postgresql' ? 'postgres' : devDatabaseType, }); }, async source({ source }) { source.addEntityToNodeConfig = ({ entityFileName, persistClass }) => this.editFile( `${SERVER_NODEJS_SRC_DIR}/src/orm.config.ts`, createNeedleCallback({ needle: 'add-entity-to-ormconfig-imports', contentToAdd: `import { ${persistClass} } from './domain/${entityFileName}.entity';`, }), createNeedleCallback({ needle: 'add-entity-to-ormconfig-entities', contentToAdd: `${persistClass},`, }), ); source.addEntityToAppModule = ({ entityClass, entityFileName }) => this.editFile( `${SERVER_NODEJS_SRC_DIR}/src/app.module.ts`, createNeedleCallback({ needle: 'jhipster-needle-add-entity-module-to-main-import', contentToAdd: `import { ${entityClass}Module } from './module/${entityFileName}.module';`, }), createNeedleCallback({ needle: 'jhipster-needle-add-entity-module-to-main', contentToAdd: `${entityClass}Module,`, }), ); }, async preparing({ application }) { application.typeormOrderSupport = !application.databaseTypeMongodb; application.typeormRelationsSupport = !application.databaseTypeMongodb; }, }); } get [BaseApplicationGenerator.LOADING_ENTITIES]() { return this.asLoadingEntitiesTaskGroup({ async loadingEntitiesTemplateTask({ entitiesToLoad }) { for (const entity of entitiesToLoad) { entity.entityBootstrap.dto = true; } }, }); } get [BaseApplicationGenerator.PREPARING_EACH_ENTITY_FIELD]() { return this.asPreparingEachEntityFieldTaskGroup({ async preparingEachEntityTemplateTask({ application, field }) { const { fieldType } = field; if (field.skipServer) return; if (field.fieldValues) { mutateData(field, { __override__: true, nodejsFieldType: fieldType, nodejsColumnType: application.prodDatabaseTypePostgresql ? 'varchar' : 'simple-enum', }); } else { mutateData(field, { __override__: true, nodejsFieldType: fieldTypes[fieldType] ?? 'any', nodejsColumnType: sanitizeDbType(dbTypes[fieldType], application.devDatabaseType), }); } }, }); } get [BaseApplicationGenerator.WRITING]() { return this.asWritingTaskGroup({ async cleanup({ application, control }) { if (control.existingProject) { await control.cleanupFiles(this.oldNodejsVersion, { '3.0.1': [ '.server.eslintrc.json', '.server.eslintignore', 'server/src/repository/authority.repository.ts', 'server/src/repository/user.repository.ts', [application.authenticationTypeOauth2, 'node/src/security/password-util.ts'], ], }); } }, async writingTemplateTask({ application }) { await this.writeFiles({ sections: serverFiles, context: application, }); }, }); } get [BaseApplicationGenerator.WRITING_ENTITIES]() { return this.asWritingEntitiesTaskGroup({ async cleanup({ control, entities }) { if (control.existingProject) { await control.cleanupFiles(this.oldNodejsVersion, { '3.0.1': entities.filter(e => !e.skipServer).map(e => `server/src/repository/${e.entityFileName}.repository.ts`), }); } }, async customEntityServerFiles({ application, entities }) { for (const entity of entities.filter(entity => !entity.skipServer && !entity.builtIn)) { if (application.databaseType === 'mongodb' && entity.relationships.length > 0) { throw new Error('relationships not supported in mongodb!'); } await this.writeFiles({ sections: entityFiles, context: { ...application, ...entity }, }); const webappEnumerationsDir = `${SERVER_NODEJS_SRC_DIR}/src/domain/enumeration/`; for (const field of entity.fields.filter(field => field.fieldIsEnum)) { const enumInfo = getEnumInfo(field, entity.clientRootFolder); await this.writeFile( this.fetchFromInstalledJHipster( `client/templates/${TEMPLATES_WEBAPP_SOURCES_DIR}app/entities/enumerations/enum.model.ts.ejs`, ), `${webappEnumerationsDir}${field.enumFileName}.ts`, enumInfo, ); } } }, }); } get [BaseApplicationGenerator.POST_WRITING]() { return this.asPostWritingTaskGroup({ adjustWorkspacePackageJson({ application }) { if (application.clientFrameworkAngular) { this.packageJson.merge({ overrides: { 'browser-sync': application.nodeDependencies['browser-sync'], }, }); } }, }); } get [BaseApplicationGenerator.POST_WRITING_ENTITIES]() { return this.asPostWritingEntitiesTaskGroup({ async postWritingEntitiesTemplateTask({ entities, source }) { for (const entity of entities.filter(entity => !entity.skipServer)) { const { entityFileName, persistClass, entityClass } = entity; if (!entity.builtInUserManagement) { source.addEntityToNodeConfig({ entityFileName, persistClass }); } if (!entity.builtIn) { source.addEntityToAppModule({ entityFileName, entityClass }); } } }, }); } }