UNPKG

generator-begcode

Version:

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

471 lines (470 loc) 17.9 kB
import chalk from 'chalk'; import { intersection } from 'lodash-es'; import { applicationOptions, applicationTypes, authenticationTypes, cacheTypes, databaseTypes, testFrameworkTypes, } from '../../lib/jhipster/index.js'; import { R2DBC_DB_OPTIONS, SQL_DB_OPTIONS } from '../server/support/database.js'; import { asPromptingTask } from '../base-application/support/index.js'; const { OptionNames } = applicationOptions; const { GATEWAY, MONOLITH } = applicationTypes; const { CAFFEINE, EHCACHE, HAZELCAST, INFINISPAN, MEMCACHED, REDIS } = cacheTypes; const { OAUTH2 } = authenticationTypes; const { CASSANDRA, H2_DISK, H2_MEMORY, MONGODB, NEO4J, SQL, COUCHBASE } = databaseTypes; const { WEBSOCKET, SEARCH_ENGINE, ENABLE_SWAGGER_CODEGEN } = OptionNames; const NO_DATABASE = databaseTypes.NO; const NO_CACHE_PROVIDER = cacheTypes.NO; const { GATLING, CUCUMBER } = testFrameworkTypes; export const askForServerSideOpts = asPromptingTask(async function ({ control }) { if (control.existingProject && !this.options.askAnswered) return; const { applicationType, authenticationType, reactive } = this.jhipsterConfigWithDefaults; await this.prompt([ { type: 'list', name: 'databaseType', message: `Which ${chalk.yellow('*type*')} of database would you like to use?`, choices: () => { const opts = []; if (!reactive) { opts.push({ value: SQL, name: 'SQL (H2, PostgreSQL, MySQL, MariaDB, Oracle, MSSQL)', }); } else { opts.push({ value: SQL, name: 'SQL (H2, PostgreSQL, MySQL, MariaDB, MSSQL)', }); } opts.push({ value: MONGODB, name: 'MongoDB', }); if (authenticationType !== OAUTH2) { opts.push({ value: CASSANDRA, name: 'Cassandra', }); } opts.push({ value: 'couchbase', name: '[BETA] Couchbase', }); opts.push({ value: NEO4J, name: '[BETA] Neo4j', }); opts.push({ value: NO_DATABASE, name: 'No database', }); return opts; }, default: this.jhipsterConfigWithDefaults.databaseType, }, { when: response => response.databaseType === SQL, type: 'list', name: 'prodDatabaseType', message: `Which ${chalk.yellow('*production*')} database would you like to use?`, choices: reactive ? R2DBC_DB_OPTIONS : SQL_DB_OPTIONS, default: this.jhipsterConfigWithDefaults.prodDatabaseType, }, { when: response => response.databaseType === SQL, type: 'list', name: 'devDatabaseType', message: `Which ${chalk.yellow('*development*')} database would you like to use?`, choices: response => { const currentDatabase = SQL_DB_OPTIONS.find(it => it.value === response.prodDatabaseType); return [ { ...currentDatabase, name: `${currentDatabase.name} (requires Docker or manually configured database)`, }, ].concat([ { value: H2_DISK, name: `H2 with disk-based persistence` }, { value: H2_MEMORY, name: `H2 with in-memory persistence` }, ]); }, default: this.jhipsterConfigWithDefaults.devDatabaseType, }, { when: !reactive, type: 'list', name: 'cacheProvider', message: 'Which cache do you want to use? (Spring cache abstraction)', choices: [ { value: EHCACHE, name: 'Ehcache (local cache, for a single node)', }, { value: CAFFEINE, name: 'Caffeine (local cache, for a single node)', }, { value: HAZELCAST, name: 'Hazelcast (distributed cache for multiple nodes)', }, { value: INFINISPAN, name: 'Infinispan (hybrid cache, for multiple nodes)', }, { value: MEMCACHED, name: 'Memcached (distributed cache) - Warning, when using an SQL database, this will disable the Hibernate 2nd level cache!', }, { value: REDIS, name: 'Redis (distributed cache)', }, { value: NO_CACHE_PROVIDER, name: 'No cache - Warning, when using an SQL database, this will disable the Hibernate 2nd level cache!', }, ], default: this.jhipsterConfigWithDefaults.cacheProvider, }, { when: answers => ((answers.cacheProvider !== NO_CACHE_PROVIDER && answers.cacheProvider !== MEMCACHED) || applicationType === GATEWAY) && answers.databaseType === SQL && !reactive, type: 'confirm', name: 'enableHibernateCache', message: 'Do you want to use Hibernate 2nd level cache?', default: this.jhipsterConfigWithDefaults.enableHibernateCache, }, ], this.config); }); export const askForOptionalItems = asPromptingTask(async function askForOptionalItems({ control }) { if (control.existingProject && !this.options.askAnswered) return; const { applicationType, reactive, databaseType, serverSideOptions = [] } = this.jhipsterConfigWithDefaults; const choices = []; if ([SQL, MONGODB, NEO4J].includes(databaseType)) { choices.push({ name: 'Elasticsearch as search engine', value: 'searchEngine:elasticsearch', }); } if (databaseType === COUCHBASE) { choices.push({ name: 'Couchbase FTS as search engine', value: 'searchEngine:couchbase', }); } if (!reactive) { if (applicationType === MONOLITH || applicationType === GATEWAY) { choices.push({ name: 'WebSockets using Spring Websocket', value: 'websocket:spring-websocket', }); } } choices.push({ name: 'Apache Kafka as asynchronous messages broker', value: 'messageBroker:kafka', }); choices.push({ name: 'Apache Pulsar as asynchronous messages broker', value: 'messageBroker:pulsar', }); choices.push({ name: 'API first development using OpenAPI-generator', value: 'enableSwaggerCodegen:true', }); if (choices.length > 0) { const selectedChoices = [WEBSOCKET, SEARCH_ENGINE, 'messageBroker', ENABLE_SWAGGER_CODEGEN] .map(property => [property, this.jhipsterConfig[property]]) .filter(([, value]) => value !== undefined) .map(([key, value]) => `${key}:${value}`) .filter(Boolean); choices.forEach(choice => { choice.checked = selectedChoices.includes(choice.value); }); const answers = await this.prompt({ type: 'checkbox', name: 'serverSideOptions', message: 'Which other technologies would you like to use?', choices, default: selectedChoices, }); Object.assign(this.jhipsterConfig, Object.fromEntries(answers.serverSideOptions .map(it => it.split(':')) .map(([key, value]) => [key, ['true', 'false'].includes(value) ? value === 'true' : value]))); } }); export const askForServerTestOpts = asPromptingTask(async function ({ control }) { if (control.existingProject && this.options.askAnswered !== true) return; const testFrameworks = this.jhipsterConfigWithDefaults.testFrameworks ?? []; const answers = await this.prompt([ { type: 'checkbox', name: 'serverTestFrameworks', message: 'Besides JUnit, which testing frameworks would you like to use?', choices: [ { name: 'Gatling', value: GATLING, checked: testFrameworks.includes(GATLING) }, { name: 'Cucumber', value: CUCUMBER, checked: testFrameworks.includes(CUCUMBER) }, ], default: intersection([GATLING, CUCUMBER], this.jhipsterConfigWithDefaults.testFrameworks), }, ]); this.jhipsterConfig.testFrameworks = [...new Set([...(this.jhipsterConfig.testFrameworks ?? []), ...answers.serverTestFrameworks])]; }); export async function askForOrmTool({ control }) { if (control.existingProject && !this.options.askAnswered) return; if (this.jhipsterConfig.databaseType !== 'sql' || this.jhipsterConfig.applicationType === 'gateway' || this.jhipsterConfig.reactive) { this.jhipsterConfig.ormTool = 'hibernate'; return; } const choices = [ { value: 'mybatis', name: 'Mybatis-Plus', }, { value: 'hibernate', name: 'Hibernate', }, ]; const answers = await this.prompt([ { type: 'list', name: 'ormTool', message: `Which ${chalk.yellow('OrmTools')} would you like to use for your application?`, choices, default: 'mybatis', }, ]); this.jhipsterConfig.ormTool = answers.ormTool; } export async function askForUserIdType({ control }) { if (control.existingProject && !this.options.askAnswered) return; if (OAUTH2 === this.jhipsterConfig.authenticationType && CASSANDRA === this.jhipsterConfig.databaseType) { this.jhipsterConfig.userIdType = 'string'; return; } const choices = [ { value: 'long', name: 'Long', }, { value: 'string', name: 'String', }, { value: 'uuid', name: 'UUID', }, ]; const answers = await this.prompt([ { type: 'list', name: 'userIdType', message: `Which ${chalk.yellow('*type*')} of user id type would you like to use?`, choices, default: 'long', }, ]); this.jhipsterConfig.userIdType = answers.userIdType; } export async function askJobScheduler({ control }) { this.jhipsterConfig.jobScheduler = this.jhipsterConfig.jobScheduler = 'quartz'; } export async function askUseLombok({ control }) { if (control.existingProject && !this.options.askAnswered) { return; } const answers = await this.prompt([ { type: 'confirm', name: 'useLombok', message: `Would you like to use the ${chalk.yellow('Lombok')} for your application?`, default: true, }, ]); this.jhipsterConfig.useLombok = answers.useLombok; } export async function askForIdmServicePath({ control }) { if ((control.existingProject && !this.options.askAnswered) || this.jhipsterConfig.applicationType !== 'microservice' || (this.jhipsterConfig.applicationType === 'microservice' && this.jhipsterConfig.builtInServices?.includes('idm'))) { if (this.jhipsterConfig.applicationType === 'microservice' && this.jhipsterConfig.builtInServices?.includes('idm')) { this.jhipsterConfig.skipUserManagement = false; } return; } const answers = await this.prompt([ { type: 'input', name: 'idmServicePath', message: `Please input ${chalk.yellow('idm service')} project path ?`, default: '../system/', validate: (input) => (input.length === 0 ? 'Please enter your idm service path' : true), }, ]); this.jhipsterConfig.skipUserManagement = true; this.jhipsterConfig.idmServicePath = answers.idmServicePath; } export async function askForSoftDelete({ control }) { if (control.existingProject && this.options.askAnswered !== true) return; await this.prompt({ type: 'confirm', name: 'softDelete', message: `Would you like to use the ${chalk.yellow('SOFT_DELETE')} for your application?`, default: false, }, this.config); } export async function askFrontOrBack({ control }) { if (control.existingProject && this.options.askAnswered !== true) return; if (control.existingProject) { this.jhipsterConfig.frontOrBack = this.config.get('frontOrBack') || ['front', 'back']; return; } const config = this.jhipsterConfigWithDefaults; const choices = ['back', 'front']; choices.push(...(config.frontOrBack || [])); if (config.applicationType === 'commonmodule' || config.applicationType === 'microservice') { choices.splice(choices.indexOf('front'), 1); } if (config.applicationType === 'monolith' && config.skipServer) { choices.splice(choices.indexOf('back'), 1); } if (config.applicationType === 'monolith' && config.skipClient) { choices.splice(choices.indexOf('front'), 1); } if (config.applicationType === 'gateway' && config.skipClient) { choices.splice(choices.indexOf('front'), 1); } if (config.applicationType === 'gateway' && config.skipServer) { choices.splice(choices.indexOf('back'), 1); } const choicesData = [ { value: 'all', name: 'All', }, { value: 'front', name: 'Front End', }, { value: 'back', name: 'Back End', }, { value: 'mobile', name: 'Mobile End', }, ]; const answer = await this.prompt([ { when: () => choices.length > 1, type: 'checkbox', name: 'frontOrBack', message: `Which ${chalk.yellow('Front Or Back End')} would you like to use for your application?`, choices: choicesData.filter(choice => choices.includes(choice.value)), default: choices, }, ]); if (choices.length > 1) { this.jhipsterConfig.frontOrBack = answer.frontOrBack; } else { this.jhipsterConfig.frontOrBack = choices; } if (!this.jhipsterConfig.frontOrBack.includes('front')) { this.jhipsterConfig.skipClient = true; this.jhipsterConfig.clientFramework = 'no'; } if (!this.jhipsterConfig.frontOrBack.includes('mobile')) { this.jhipsterConfig.skipMobile = true; this.jhipsterConfig.mobileTheme = 'no'; } if (!this.jhipsterConfig.frontOrBack.includes('back')) { this.jhipsterConfig.skipServer = true; } } export async function askUseMultiTenant({ control }) { if (control.existingProject && this.options.askAnswered !== true) return; const config = this.jhipsterConfigWithDefaults; if (config.applicationType === 'gateway') { this.jhipsterConfig.useMultiTenant = false; return; } const answers = await this.prompt([ { type: 'confirm', name: 'useMultiTenant', message: `Would you like to use the ${chalk.yellow('Use Multi-Tenant')} for your application?`, default: false, }, ]); this.jhipsterConfig.useMultiTenant = answers.useMultiTenant; } export async function askBuiltInServices({ control }) { if (control.existingProject && this.options.askAnswered !== true) return; const config = this.jhipsterConfigWithDefaults; if (config.applicationType === 'monolith' || config.applicationType === 'gateway') { return; } const choices = []; const defaultChoice = []; defaultChoice.push('idm'); choices.push({ name: 'User Center', value: 'idm', }); defaultChoice.push('oss', 'log'); choices.push({ name: 'Object Storage Service', value: 'oss', }); choices.push({ name: 'Log Service', value: 'log', }); choices.push({ name: 'Report', value: 'report', }); const answers = await this.prompt([ { type: 'checkbox', name: 'builtInServices', message: 'Which other services would you like to use?', choices, default: defaultChoice, }, ]); this.jhipsterConfig.builtInServices = answers.builtInServices; } export async function askForMobileTheme({ control }) { if (control.existingProject && !this.options.askAnswered) return; const config = this.jhipsterConfigWithDefaults; if (config.skipMobile && !config.frontOrBack.includes('mobile')) return; const mobileThemes = [...(config.mobileThemes || [])].map(theme => theme.value); const mobileThemeChoices = [...(config.mobileThemes || [])]; config.mobileThemes?.splice(0); const answer = await this.prompt([ { type: 'checkbox', name: 'mobileThemes', when: () => !this.jhipsterConfig.skipMobile && mobileThemeChoices.length > 0, message: 'Would you like to use a Mobile App framework?', choices: () => mobileThemeChoices, default: mobileThemes, }, ]); this.jhipsterConfig.mobileThemes = answer.mobileThemes; }