generator-begcode
Version:
Spring Boot + Angular/React/Vue in one handy generator
509 lines (508 loc) • 19.1 kB
JavaScript
import chalk from 'chalk';
import { includes, intersection } from 'lodash-es';
import { applicationOptions, applicationTypes, authenticationTypes, databaseTypes, cacheTypes, testFrameworkTypes, } from '../../jdl/jhipster/index.js';
import { MESSAGE_BROKER } from '../server/options/index.js';
import { R2DBC_DB_OPTIONS, SQL_DB_OPTIONS } from '../server/support/database.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 { CACHE_PROVIDER, DATABASE_TYPE, DEV_DATABASE_TYPE, PROD_DATABASE_TYPE, SERVICE_DISCOVERY_TYPE, WEBSOCKET, SEARCH_ENGINE, ENABLE_SWAGGER_CODEGEN, } = OptionNames;
const NO_DATABASE = databaseTypes.NO;
const NO_CACHE_PROVIDER = cacheTypes.NO;
const { GATLING, CUCUMBER } = testFrameworkTypes;
const getOptionFromArray = (array, option) => {
let optionValue = false;
array.forEach(value => {
if (includes(value, option)) {
optionValue = value.split(':')[1];
}
});
optionValue = optionValue === 'true' ? true : optionValue;
return optionValue;
};
export async function askForServerSideOpts({ control }) {
if (control.existingProject && !this.options.askAnswered)
return;
const { applicationType } = this.jhipsterConfigWithDefaults;
const prompts = [
{
type: 'list',
name: DATABASE_TYPE,
message: `Which ${chalk.yellow('*type*')} of database would you like to use?`,
choices: answers => {
const opts = [];
if (!answers.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 (answers.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: PROD_DATABASE_TYPE,
message: `Which ${chalk.yellow('*production*')} database would you like to use?`,
choices: answers => (answers.reactive ? R2DBC_DB_OPTIONS : SQL_DB_OPTIONS),
default: this.jhipsterConfigWithDefaults.prodDatabaseType,
},
{
when: response => response.databaseType === SQL,
type: 'list',
name: DEV_DATABASE_TYPE,
message: `Which ${chalk.yellow('*development*')} database would you like to use?`,
choices: response => [SQL_DB_OPTIONS.find(it => it.value === response.prodDatabaseType)].concat([
{
value: H2_DISK,
name: 'H2 with disk-based persistence',
},
{
value: H2_MEMORY,
name: 'H2 with in-memory persistence',
},
]),
default: this.jhipsterConfigWithDefaults.devDatabaseType,
},
{
when: answers => !answers.reactive,
type: 'list',
name: CACHE_PROVIDER,
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, supports rate-limiting for gateway applications)',
},
{
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 &&
!answers.reactive,
type: 'confirm',
name: 'enableHibernateCache',
message: 'Do you want to use Hibernate 2nd level cache?',
default: this.jhipsterConfigWithDefaults.enableHibernateCache,
},
];
await this.prompt(prompts, this.config);
}
export async function askForOptionalItems({ control }) {
if (control.existingProject && !this.options.askAnswered)
return;
const { applicationType, reactive, databaseType, serverSideOptions = [] } = this.jhipsterConfigWithDefaults;
const choices = [];
const defaultChoice = [...serverSideOptions];
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',
});
const PROMPTS = {
type: 'checkbox',
name: 'serverSideOptions',
message: 'Which other technologies would you like to use?',
choices,
default: defaultChoice,
};
if (choices.length > 0) {
await this.prompt(PROMPTS).then(answers => {
this.jhipsterConfig.serverSideOptions = answers.serverSideOptions;
this.jhipsterConfig.websocket = getOptionFromArray(answers.serverSideOptions, WEBSOCKET);
this.jhipsterConfig.searchEngine = getOptionFromArray(answers.serverSideOptions, SEARCH_ENGINE);
this.jhipsterConfig.messageBroker = getOptionFromArray(answers.serverSideOptions, MESSAGE_BROKER);
this.jhipsterConfig.enableSwaggerCodegen = getOptionFromArray(answers.serverSideOptions, ENABLE_SWAGGER_CODEGEN);
if (!this.jhipsterConfig.serviceDiscoveryType) {
this.jhipsterConfig.serviceDiscoveryType = getOptionFromArray(answers.serverSideOptions, SERVICE_DISCOVERY_TYPE);
}
});
}
}
export async function askForServerTestOpts({ control }) {
if (control.existingProject && this.options.askAnswered !== true)
return;
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 },
{ name: 'Cucumber', value: 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 prompts = [
{
type: 'list',
name: 'ormTool',
message: `Which ${chalk.yellow('OrmTools')} would you like to use for your application?`,
choices,
default: 'mybatis',
},
];
const answers = await this.prompt(prompts);
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 prompts = [
{
type: 'list',
name: 'userIdType',
message: `Which ${chalk.yellow('*type*')} of user id type would you like to use?`,
choices,
default: 'long',
},
];
const answers = await this.prompt(prompts);
this.jhipsterConfig.userIdType = answers.userIdType;
}
export async function askJavaVersion({ control }) {
if (control.existingProject && !this.options.askAnswered) {
return;
}
const choices = [
{
value: '17',
name: 'Java 17',
},
{
value: '8',
name: 'Java 1.8',
},
];
const prompts = [
{
type: 'list',
name: 'javaVersion',
message: `Which ${chalk.yellow('JavaVersion')} would you like to use for your application?`,
choices,
default: '17',
},
];
const answers = await this.prompt(prompts);
this.jhipsterConfig.javaVersion = answers.javaVersion;
}
export async function askJobScheduler() {
this.jobScheduler = this.jhipsterConfig.jobScheduler = 'quartz';
}
export async function askUseLombok({ control }) {
if (control.existingProject && !this.options.askAnswered) {
return;
}
const prompts = [
{
type: 'confirm',
name: 'useLombok',
message: `Would you like to use the ${chalk.yellow('Lombok')} for your application?`,
default: true,
},
];
const answers = await this.prompt(prompts);
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 prompts = [
{
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),
},
];
const answers = await this.prompt(prompts);
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.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.frontOrBack = this.jhipsterConfig.frontOrBack = answer.frontOrBack;
}
else {
this.frontOrBack = this.jhipsterConfig.frontOrBack = choices;
}
if (!this.frontOrBack.includes('front')) {
this.skipClient = this.jhipsterConfig.skipClient = true;
this.clientFramework = this.jhipsterConfig.clientFramework = 'no';
}
if (!this.frontOrBack.includes('mobile')) {
this.skipMobile = this.jhipsterConfig.skipMobile = true;
this.mobileTheme = this.jhipsterConfig.mobileTheme = 'no';
}
if (!this.frontOrBack.includes('back')) {
this.skipServer = 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.useMultiTenant = 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.useMultiTenant = 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.builtInServices = 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 = [];
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.mobileThemes = this.jhipsterConfig.mobileThemes = answer.mobileThemes;
}