UNPKG

gen-jhipster

Version:

Spring Boot + Angular/React/Vue in one handy generator

346 lines (345 loc) 15.8 kB
/** * Copyright 2013-2024 the original author or authors from the JHipster project. * * This file is part of the JHipster project, see https://www.jhipster.tech/ * for more information. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import _ from 'lodash'; import BaseApplicationGenerator from '../base-application/index.js'; import writeGrpcFilesTask from './files.js'; import writeEntitiesTasks, { cleanupEntitiesTask } from './entity-files.js'; export default class GrpcGenerator extends BaseApplicationGenerator { async beforeQueue() { if (!this.fromBlueprint) { await this.composeWithBlueprints(); } if (!this.delegateToBlueprint) { await this.dependsOnBootstrapApplication(); } } get initializing() { return this.asInitializingTaskGroup({ async loadConfig() { // Load gRPC config const config = this.jhipsterConfigWithDefaults; this.grpcConfig = { grpcEnabled: config.grpcEnabled, grpcPort: config.grpcPort, grpcSecured: config.grpcSecured, grpcUseSsl: config.grpcUseSsl, grpcCertificatePath: config.grpcCertificatePath, grpcPrivateKeyPath: config.grpcPrivateKeyPath, }; this.enableGrpc = this.jhipsterConfig.enableGrpc; }, }); } get [BaseApplicationGenerator.INITIALIZING]() { return this.delegateTasksToBlueprint(() => this.initializing); } get prompting() { return this.asPromptingTaskGroup({ async showPrompts() { if (!this.enableGrpc) { await this.prompt([ { type: 'confirm', name: 'enableGrpc', message: 'Do you want to enable gRPC integration?', default: this.jhipsterConfigWithDefaults.enableGrpc, }, { when: response => response.enableGrpc, type: 'input', name: 'grpcPort', message: 'Which port would you like gRPC to listen on?', default: this.jhipsterConfigWithDefaults.grpcPort, validate: (input) => { if (/^\d+$/.test(input)) { const port = parseInt(input, 10); if (port > 0 && port < 65536) return true; } return 'Please enter a valid port number between 1 and 65535'; }, }, ], this.config); // interface GrpcAnswers { // grpcEnabled: boolean; // grpcPort?: string; // grpcSecured?: boolean; // grpcUseSsl?: boolean; // } // // const answers: GrpcAnswers = await this.prompt([ // { // type: 'confirm', // name: 'enableGrpc', // message: 'Do you want to enable gRPC integration? (true)', // default: true, // }, // ]); // // if (answers.grpcEnabled) { // const portAnswer = await this.prompt([ // { // type: 'input', // name: 'grpcPort', // message: 'Which port would you like gRPC to listen on?', // default: (this.grpcConfig.grpcPort ?? 9090).toString(), // validate: (input: string) => { // if (/^\d+$/.test(input)) { // const port = parseInt(input, 10); // if (port > 0 && port < 65536) return true; // } // return 'Please enter a valid port number between 1 and 65535'; // }, // }, // ]); // const securityAnswers = await this.prompt([ // { // type: 'confirm', // name: 'grpcSecured', // message: 'Do you want to secure your gRPC services with JWT authentication?', // default: this.grpcConfig.grpcSecured ?? true, // }, // { // type: 'confirm', // name: 'grpcUseSsl', // message: 'Do you want to enable SSL/TLS for gRPC connections?', // default: this.grpcConfig.grpcUseSsl ?? false, // }, // ]); // Object.assign(answers, portAnswer); // } // // const newConfig = { // ...this.grpcConfig, // grpcEnabled: answers.grpcEnabled, // grpcPort: answers.grpcPort, // }; // // if (answers.grpcPort) { // newConfig.grpcPort = parseInt(answers.grpcPort, 10); // } // // this.grpcConfig = newConfig; } }, }); } get [BaseApplicationGenerator.PROMPTING]() { return this.delegateTasksToBlueprint(() => this.prompting); } get preparing() { return this.asPreparingTaskGroup({ async preparing({ application }) { const anyApp = application; }, }); } get [BaseApplicationGenerator.PREPARING]() { return this.delegateTasksToBlueprint(() => this.preparing); } get preparingEachEntity() { return this.asPreparingEachEntityTaskGroup({ prepareEntity({ application, entity }) { if (this.enableGrpc) { entity.fields.forEach(field => { if (field.fieldTypeBlobContent === 'text') { field.fieldDomainType = 'String'; } else { field.fieldDomainType = field.fieldType; } field.fieldTypeUpperUnderscored = _.snakeCase(field.fieldType).toUpperCase(); field.fieldProtobufType = getProtobufType(field.fieldDomainType); field.isProtobufCustomType = isProtobufCustomType(field.fieldProtobufType); }); this.isFilterableType = function (fieldType) { return !['byte[]', 'ByteBuffer'].includes(fieldType); }; } }, }); } get [BaseApplicationGenerator.PREPARING_EACH_ENTITY]() { return this.delegateTasksToBlueprint(() => this.preparingEachEntity); } get preparingEachEntityRelationship() { return this.asPreparingEachEntityRelationshipTaskGroup({ prepareRelationship({ application, relationship }) { if (this.enableGrpc) { relationship.relationshipNameUnderscored = _.snakeCase(relationship.relationshipName).toLowerCase(); relationship.otherEntityNameUnderscored = _.snakeCase(relationship.otherEntityName).toLowerCase(); relationship.otherEntityFieldUnderscored = _.snakeCase(relationship.otherEntityField).toLowerCase(); if (relationship.otherEntityNameCapitalized === 'User') { relationship.otherEntityProtobufType = `${application.packageName}.UserProto`; relationship.otherEntityProtoMapper = `${application.packageName}.grpc.UserProtoMapper`; relationship.otherEntityTest = `${application.packageName}.grpc.UserGrpcServiceIntTest`; relationship.otherEntityProtobufFile = `${application.packageFolder}user.proto`; } else { relationship.otherEntityProtobufType = `${application.packageName}.entity.${relationship.otherEntityNameCapitalized}Proto`; relationship.otherEntityProtoMapper = `${application.packageName}.grpc.entity.${relationship.otherEntityNameUnderscored}.${relationship.otherEntityNameCapitalized}ProtoMapper`; relationship.otherEntityTest = `${application.packageName}.grpc.entity.${relationship.otherEntityNameUnderscored}.${relationship.otherEntityNameCapitalized}GrpcServiceIntTest`; relationship.otherEntityProtobufFile = `${application.packageFolder}/entity/${relationship.otherEntityNameUnderscored}.proto`; } } }, }); } get [BaseApplicationGenerator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { return this.delegateTasksToBlueprint(() => this.preparingEachEntityRelationship); } get writing() { return { writeGrpcFilesTask, }; } get [BaseApplicationGenerator.WRITING]() { return this.delegateTasksToBlueprint(() => this.writing); } get writingEntities() { return { cleanupEntitiesTask, writeEntitiesTasks, }; } get [BaseApplicationGenerator.WRITING_ENTITIES]() { return this.delegateTasksToBlueprint(() => this.writingEntities); } get postWriting() { return this.asPostWritingTaskGroup({ addDependencies({ source, application }) { source.addJavaDependencies?.([ { groupId: 'net.devh', artifactId: 'grpc-spring-boot-starter', version: '3.1.0.RELEASE' }, { groupId: 'javax.annotation', artifactId: 'javax.annotation-api', version: '1.3.2' }, { groupId: 'build.buf', artifactId: 'protovalidate', version: '0.5.0' }, ]); if (application.reactive) { source.addJavaDependencies?.([ { groupId: 'com.salesforce.servicelibs', artifactId: 'reactor-grpc-stub', version: '1.2.4' } ]); } }, addPlugins({ source, application }) { if (this.jhipsterConfig.buildTool === 'maven') { if (application.reactive) { source.addMavenPlugin?.({ groupId: 'org.xolstice.maven.plugins', artifactId: 'protobuf-maven-plugin', version: '0.6.1', additionalContent: ` <configuration> <protocArtifact>com.google.protobuf:protoc:3.23.4:exe:\${os.detected.classifier} </protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.58.0:exe:\${os.detected.classifier} </pluginArtifact> <useArgumentFile>true</useArgumentFile> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> <configuration> <protocPlugins> <protocPlugin> <id>reactor-grpc</id> <groupId>com.salesforce.servicelibs</groupId> <artifactId>reactor-grpc</artifactId> <version>1.2.4</version> <mainClass>com.salesforce.reactorgrpc.ReactorGrpcGenerator</mainClass> </protocPlugin> </protocPlugins> </configuration> </execution> </executions>`, }); } else { source.addMavenPlugin?.({ groupId: 'org.xolstice.maven.plugins', artifactId: 'protobuf-maven-plugin', version: '0.6.1', additionalContent: ` <configuration> <protocArtifact>com.google.protobuf:protoc:3.23.4:exe:\${os.detected.classifier} </protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.58.0:exe:\${os.detected.classifier} </pluginArtifact> <useArgumentFile>true</useArgumentFile> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </configuration> </execution> </executions>`, }); } source.addMavenExtension?.({ groupId: 'kr.motd.maven', artifactId: 'os-maven-plugin', version: '1.7.0', }); } }, }); } get [BaseApplicationGenerator.POST_WRITING]() { return this.delegateTasksToBlueprint(() => this.postWriting); } } function getProtobufType(type) { switch (type) { case 'String': case 'Float': case 'Double': return type.toLowerCase(); case 'Integer': return 'int32'; case 'Long': return 'int64'; case 'Boolean': return 'bool'; case 'Instant': case 'OffsetDateTime': case 'ZonedDateTime': return 'google.protobuf.Timestamp'; case 'LocalDate': return 'util.Date'; case 'BigDecimal': return 'util.Decimal'; case 'byte[]': case 'ByteBuffer': return 'bytes'; case 'UUID': return 'string'; default: // It's an enum return `${type}Proto`; } } function isProtobufCustomType(type) { return type.startsWith('google') || type.startsWith('util'); }