diff --git a/generators/base-core/generator.ts b/generators/base-core/generator.ts index a00e239f7b5a..6d918b519fdf 100644 --- a/generators/base-core/generator.ts +++ b/generators/base-core/generator.ts @@ -26,7 +26,7 @@ import { requireNamespace } from '@yeoman/namespace'; import { GeneratorMeta } from '@yeoman/types'; import chalk from 'chalk'; import { parse as parseYaml, stringify as stringifyYaml } from 'yaml'; -import { kebabCase, snakeCase, merge, get, set } from 'lodash-es'; +import { kebabCase, snakeCase, merge, get, set, defaults } from 'lodash-es'; import { simpleGit } from 'simple-git'; import type { CopyOptions } from 'mem-fs-editor'; import type { Data as TemplateData, Options as TemplateOptions } from 'ejs'; @@ -36,7 +36,13 @@ import type Environment from 'yeoman-environment'; import latestVersion from 'latest-version'; import SharedData from '../base/shared-data.js'; import { CUSTOM_PRIORITIES, PRIORITY_NAMES, PRIORITY_PREFIX } from '../base/priorities.js'; -import { createJHipster7Context, formatDateForChangelog, joinCallbacks, Logger } from '../base/support/index.js'; +import { + createJHipster7Context, + formatDateForChangelog, + joinCallbacks, + Logger, + removeFieldsWithNullishValues, +} from '../base/support/index.js'; import type { JHipsterGeneratorOptions, @@ -60,6 +66,7 @@ import { GENERATOR_JHIPSTER, YO_RC_FILE } from '../generator-constants.js'; import { convertConfigToOption } from '../../lib/internal/index.js'; import { getGradleLibsVersionsProperties } from '../gradle/support/dependabot-gradle.js'; import { dockerPlaceholderGenerator } from '../docker/utils.js'; +import { getConfigWithDefaults } from '../../jdl/index.js'; const { INITIALIZING, @@ -228,6 +235,20 @@ export default class CoreGenerator extends YeomanGenerator string | boolean | string[]); + /** + * Configure the generator according to the selected configuration. + */ + configure?: (gen: CoreGenerator) => void; }; export type JHipsterArguments = Record; diff --git a/generators/base/generator.ts b/generators/base/generator.ts index f62023d0ea15..3100f46cccc5 100644 --- a/generators/base/generator.ts +++ b/generators/base/generator.ts @@ -20,18 +20,16 @@ import fs from 'fs'; import path from 'path'; import chalk from 'chalk'; import semver from 'semver'; -import { defaults } from 'lodash-es'; import type { ComposeOptions } from 'yeoman-generator'; import { packageJson } from '../../lib/index.js'; -import { packageNameToNamespace, removeFieldsWithNullishValues } from './support/index.js'; +import { packageNameToNamespace } from './support/index.js'; import { mergeBlueprints, parseBluePrints, loadBlueprintsFromConfiguration, normalizeBlueprintName } from './internal/index.js'; import { PRIORITY_NAMES } from './priorities.js'; import { BaseGeneratorDefinition, GenericTaskGroup } from './tasks.js'; import type { JHipsterGeneratorFeatures, JHipsterGeneratorOptions } from './api.js'; import CoreGenerator from '../base-core/index.js'; import { LOCAL_BLUEPRINT_PACKAGE_NAMESPACE } from './support/constants.js'; -import { getConfigWithDefaults } from '../../jdl/index.js'; import { loadStoredAppOptions } from '../app/support/index.js'; /** @@ -443,20 +441,6 @@ export default class JHipsterBaseBlueprintGenerator< return taskGroup; } - /** - * JHipster config with default values fallback - */ - get jhipsterConfigWithDefaults() { - const configWithDefaults = getConfigWithDefaults(removeFieldsWithNullishValues(this.config.getAll())); - defaults(configWithDefaults, { - skipFakeData: false, - skipCheckLengthOfIdentifier: false, - enableGradleEnterprise: false, - pages: [], - }); - return configWithDefaults; - } - /** * @protected * Composes with blueprint generators, if any. diff --git a/generators/server/generator.js b/generators/server/generator.js index 2db5a9ddb89a..4f534e16b4ce 100644 --- a/generators/server/generator.js +++ b/generators/server/generator.js @@ -23,7 +23,6 @@ import { existsSync } from 'fs'; import chalk from 'chalk'; import { - getDBTypeFromDBValue, buildJavaGet as javaGetCall, javaBeanCase as javaBeanClassNameFormat, buildJavaGetter as javaGetter, @@ -52,7 +51,6 @@ import { import { applicationTypes, - authenticationTypes, buildToolTypes, databaseTypes, fieldTypes, @@ -63,7 +61,7 @@ import { clientFrameworkTypes, } from '../../jdl/jhipster/index.js'; import { stringifyApplicationData } from '../base-application/support/index.js'; -import { createBase64Secret, createSecret, createNeedleCallback, mutateData } from '../base/support/index.js'; +import { createNeedleCallback, mutateData } from '../base/support/index.js'; import { isReservedPaginationWords } from '../../jdl/jhipster/reserved-keywords.js'; import { loadStoredAppOptions } from '../app/support/index.js'; import { isReservedH2Keyword } from '../spring-data-relational/support/h2-reserved-keywords.js'; @@ -85,10 +83,9 @@ const { const { SUPPORTED_VALIDATION_RULES } = validations; const { isReservedTableName } = reservedKeywords; const { ANGULAR, REACT, VUE } = clientFrameworkTypes; -const { JWT, OAUTH2, SESSION } = authenticationTypes; const { GRADLE, MAVEN } = buildToolTypes; -const { CASSANDRA, COUCHBASE, MONGODB, NEO4J, SQL, NO: NO_DATABASE } = databaseTypes; -const { MICROSERVICE, GATEWAY } = applicationTypes; +const { CASSANDRA, SQL, NO: NO_DATABASE } = databaseTypes; +const { GATEWAY } = applicationTypes; const { NO: NO_SEARCH_ENGINE } = searchEngineTypes; const { CommonDBTypes, RelationalOnlyDBTypes } = fieldTypes; @@ -146,37 +143,6 @@ export default class JHipsterServerGenerator extends BaseApplicationGenerator { return this.delegateTasksToBlueprint(() => this.prompting); } - get configuring() { - return this.asConfiguringTaskGroup({ - configuring() { - if (process.env.JHI_WAR === '1') { - this.jhipsterConfig.defaultPackaging = 'war'; - } - }, - configServerPort() { - if (!this.jhipsterConfig.serverPort && this.jhipsterConfig.applicationIndex) { - this.jhipsterConfig.serverPort = 8080 + this.jhipsterConfig.applicationIndex; - } - }, - configure() { - this._configureServer(); - }, - syncUserWithIdp() { - if (this.jhipsterConfig.syncUserWithIdp === undefined && this.jhipsterConfig.authenticationType === OAUTH2) { - if (this.isJhipsterVersionLessThan('8.1.1')) { - this.jhipsterConfig.syncUserWithIdp = true; - } - } else if (this.jhipsterConfig.syncUserWithIdp && this.jhipsterConfig.authenticationType !== OAUTH2) { - throw new Error(`syncUserWithIdp is only supported with authenticationType ${OAUTH2}`); - } - }, - }); - } - - get [BaseApplicationGenerator.CONFIGURING]() { - return this.delegateTasksToBlueprint(() => this.configuring); - } - get composing() { return this.asComposingTaskGroup({ async composeCommand() { @@ -614,43 +580,6 @@ export default class JHipsterServerGenerator extends BaseApplicationGenerator { return this.delegateTasksToBlueprint(() => this.postWriting); } - _configureServer(config = this.jhipsterConfigWithDefaults, dest = this.jhipsterConfig) { - // Generate JWT secret key if key does not already exist in config - if ( - (config.authenticationType === JWT || config.applicationType === MICROSERVICE || config.applicationType === GATEWAY) && - config.jwtSecretKey === undefined - ) { - dest.jwtSecretKey = createBase64Secret(64, this.options.reproducibleTests); - } - // Generate remember me key if key does not already exist in config - if (config.authenticationType === SESSION && !dest.rememberMeKey) { - dest.rememberMeKey = createSecret(); - } - - if (config.authenticationType === OAUTH2) { - dest.skipUserManagement = true; - } - - if (!config.databaseType && config.prodDatabaseType) { - dest.databaseType = getDBTypeFromDBValue(config.prodDatabaseType); - } - if (!config.devDatabaseType && config.prodDatabaseType) { - dest.devDatabaseType = config.prodDatabaseType; - } - - const databaseType = config.databaseType; - if (databaseType === NO_DATABASE) { - dest.devDatabaseType = NO_DATABASE; - dest.prodDatabaseType = NO_DATABASE; - dest.enableHibernateCache = false; - dest.skipUserManagement = true; - } else if ([MONGODB, NEO4J, COUCHBASE, CASSANDRA].includes(databaseType)) { - dest.devDatabaseType = databaseType; - dest.prodDatabaseType = databaseType; - dest.enableHibernateCache = false; - } - } - /** * Validate the entityTableName * @return {true|string} true for a valid value or error message. diff --git a/generators/spring-boot/command.ts b/generators/spring-boot/command.ts index 9ce611d601a4..ff03bc54051a 100644 --- a/generators/spring-boot/command.ts +++ b/generators/spring-boot/command.ts @@ -19,6 +19,7 @@ import chalk from 'chalk'; import { JHipsterCommandDefinition } from '../base/api.js'; import { GENERATOR_JAVA, GENERATOR_LIQUIBASE, GENERATOR_SPRING_DATA_RELATIONAL } from '../generator-list.js'; +import { createBase64Secret, createSecret } from '../base/support/secret.js'; const command: JHipsterCommandDefinition = { options: { @@ -51,6 +52,11 @@ const command: JHipsterCommandDefinition = { 'As you are running in a microservice architecture, on which port would like your server to run? It should be unique to avoid port conflicts.', default: () => gen.jhipsterConfigWithDefaults.serverPort, }), + configure: gen => { + if (gen.jhipsterConfig.serverPort === undefined && gen.jhipsterConfig.applicationIndex !== undefined) { + gen.jhipsterConfig.serverPort = 8080 + gen.jhipsterConfig.applicationIndex; + } + }, }, serviceDiscoveryType: { cli: { @@ -89,6 +95,19 @@ const command: JHipsterCommandDefinition = { { value: 'oauth2', name: 'OAuth 2.0 / OIDC Authentication (stateful, works with Keycloak and Okta)' }, { value: 'session', name: 'HTTP Session Authentication (stateful, default Spring Security mechanism)' }, ], + configure: gen => { + const { jwtSecretKey, rememberMeKey, authenticationType, applicationType } = gen.jhipsterConfigWithDefaults; + if (authenticationType === 'session' && !rememberMeKey) { + gen.jhipsterConfig.rememberMeKey = createSecret(); + } else if (authenticationType === 'oauth2' && gen.jhipsterConfig.skipUserManagement === undefined) { + gen.jhipsterConfig.skipUserManagement = true; + } else if ( + jwtSecretKey === undefined && + (authenticationType === 'jwt' || applicationType === 'microservice' || applicationType === 'gateway') + ) { + gen.jhipsterConfig.jwtSecretKey = createBase64Secret(64, gen.options.reproducibleTests); + } + }, }, feignClient: { description: 'Generate a feign client', @@ -114,6 +133,15 @@ const command: JHipsterCommandDefinition = { message: 'Do you want to allow relationships with User entity?', when: ({ authenticationType }) => (authenticationType ?? gen.jhipsterConfigWithDefaults.authenticationType) === 'oauth2', }), + configure: gen => { + if (gen.jhipsterConfig.syncUserWithIdp === undefined && gen.jhipsterConfigWithDefaults.authenticationType === 'oauth2') { + if (gen.isJhipsterVersionLessThan('8.1.1')) { + gen.jhipsterConfig.syncUserWithIdp = true; + } + } else if (gen.jhipsterConfig.syncUserWithIdp && gen.jhipsterConfig.authenticationType !== 'oauth2') { + throw new Error('syncUserWithIdp is only supported with authenticationType oauth2'); + } + }, }, defaultPackaging: { description: 'Default packaging for the application', @@ -124,6 +152,11 @@ const command: JHipsterCommandDefinition = { choices: ['jar', 'war'], default: 'jar', scope: 'storage', + configure: gen => { + if (process.env.JHI_WAR === '1') { + gen.jhipsterConfig.defaultPackaging = 'war'; + } + }, }, }, import: [GENERATOR_JAVA, GENERATOR_LIQUIBASE, GENERATOR_SPRING_DATA_RELATIONAL], diff --git a/generators/spring-boot/generator.ts b/generators/spring-boot/generator.ts index 37248e3c24db..54a665b7b9d8 100644 --- a/generators/spring-boot/generator.ts +++ b/generators/spring-boot/generator.ts @@ -119,6 +119,9 @@ export default class SpringBootGenerator extends BaseApplicationGenerator { get configuring() { return this.asConfiguringTaskGroup({ + async configureCommand() { + await this.configureCurrentJHipsterCommandConfig(); + }, checks() { const config = this.jhipsterConfigWithDefaults; if (config.enableHibernateCache && [NO_CACHE, MEMCACHED].includes(config.cacheProvider)) { @@ -235,11 +238,20 @@ export default class SpringBootGenerator extends BaseApplicationGenerator { return this.delegateTasksToBlueprint(() => this.composingComponent); } - get preparing() { - return this.asPreparingTaskGroup({ + get loading() { + return this.asLoadingTaskGroup({ async loadCommand({ application }) { await this.loadCurrentJHipsterCommandConfig(application); }, + }); + } + + get [BaseApplicationGenerator.LOADING]() { + return this.delegateTasksToBlueprint(() => this.loading); + } + + get preparing() { + return this.asPreparingTaskGroup({ checksWebsocket({ application }) { const { websocket } = application as any; if (websocket && websocket !== NO_WEBSOCKET) {