UNPKG

gen-jhipster

Version:

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

271 lines (270 loc) 12.5 kB
/** * Copyright 2013-2026 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 fs from 'node:fs'; import path from 'node:path'; import chalk from 'chalk'; import { upperFirst } from 'lodash-es'; import { APPLICATION_TYPE_GATEWAY, APPLICATION_TYPE_MICROSERVICE } from "../../lib/core/application-types.js"; import { reservedKeywords } from "../../lib/jhipster/index.js"; import BaseApplicationGenerator from "../base-application/index.js"; import { JHIPSTER_CONFIG_DIR } from "../generator-constants.js"; import { getDBTypeFromDBValue, hibernateSnakeCase } from "../server/support/index.js"; import { askForDTO, askForFields, askForFieldsToRemove, askForFiltering, askForMicroserviceJson, askForPagination, askForReadOnly, askForRelationsToRemove, askForRelationships, askForService, askForUpdate, } from "./prompts.js"; const { isReservedClassName } = reservedKeywords; export default class EntityGenerator extends BaseApplicationGenerator { name; application = {}; microserviceConfig; entityStorage; entityConfig; entityData; constructor(args, options, features) { super(args, options, { unique: 'argument', ...features }); } async beforeQueue() { if (!this.fromBlueprint) { await this.composeWithBlueprints(); } if (!this.delegateToBlueprint) { await this.dependsOnBootstrap('app'); } } // Public API method used by the getter and also by Blueprints get initializing() { return this.asInitializingTaskGroup({ parseOptions() { const name = upperFirst(this.name).replace('.json', ''); this.entityStorage = this.getEntityConfig(name, true); this.entityConfig = this.entityStorage.createProxy(); const configExisted = this.entityStorage.existed; const filename = path.join(JHIPSTER_CONFIG_DIR, `${name}.json`); const entityExisted = fs.existsSync(this.destinationPath(filename)); this.jhipsterConfig.entities = [...(this.jhipsterConfig.entities ?? []), name]; this.entityData = { name, filename, configExisted, entityExisted, configurationFileExists: this.fs.exists(this.destinationPath(filename)), }; this._setupEntityOptions(); }, loadOptions() { if (this.options.db) { this.entityConfig.databaseType = getDBTypeFromDBValue(this.options.db); if (this.entityConfig.databaseType === 'sql') { this.entityConfig.prodDatabaseType = this.options.db; } } if (this.options.skipServer !== undefined) { this.entityConfig.skipServer = this.options.skipServer; } if (this.options.skipDbChangelog !== undefined) { this.entityConfig.skipDbChangelog = this.options.skipDbChangelog; } if (this.options.skipClient !== undefined) { this.entityConfig.skipClient = this.options.skipClient; } }, }); } get [BaseApplicationGenerator.INITIALIZING]() { return this.delegateTasksToBlueprint(() => this.initializing); } get prompting() { return this.asPromptingTaskGroup({ /* Use need microservice path to load the entity file */ askForMicroserviceJson, }); } get [BaseApplicationGenerator.PROMPTING]() { return this.delegateTasksToBlueprint(() => this.prompting); } get postPreparing() { return this.asPostPreparingTaskGroup({ isBuiltInEntity({ application }) { if ((application.generateBuiltInUserEntity && this.entityData.name.toLowerCase() === 'user)') || (application.generateBuiltInAuthorityEntity && this.entityData.name.toLowerCase() === 'authority')) { throw new Error(`Is not possible to override built in ${this.entityData.name}`); } }, setupMicroServiceEntity({ application }) { const context = this.entityData; if (application.applicationType === APPLICATION_TYPE_MICROSERVICE) { context.microserviceName = this.entityConfig.microserviceName = this.jhipsterConfig.baseName; if (!this.entityConfig.clientRootFolder) { context.clientRootFolder = this.entityConfig.clientRootFolder = this.entityConfig.microserviceName; } } else if (application.applicationType === APPLICATION_TYPE_GATEWAY) { // If microservicePath is set we are loading the entity from the microservice side. context.useMicroserviceJson = !!this.entityConfig.microservicePath; if (context.useMicroserviceJson) { context.microserviceFileName = this.destinationPath(this.entityConfig.microservicePath, context.filename); context.useConfigurationFile = true; this.log.verboseInfo(` The entity ${context.name} is being updated. `); try { // We are generating an entity from a microservice. // Load it directly into our entity configuration. this.microserviceConfig = this.fs.readJSON(context.microserviceFileName); if (this.microserviceConfig) { this.entityStorage.set(this.microserviceConfig); } } catch (err) { this.log.debug('Error:', err); throw new Error(`The entity configuration file could not be read! ${err}`, { cause: err }); } } if (this.entityConfig.clientRootFolder === undefined) { context.clientRootFolder = this.entityConfig.clientRootFolder = context.skipUiGrouping ? '' : this.entityConfig.microserviceName; } } }, loadEntitySpecificOptions({ application }) { this.entityData.skipClient = this.entityData.skipClient || this.entityConfig.skipClient; this.entityData.databaseType = this.entityData.databaseType || this.entityConfig.databaseType || application.databaseType; }, validateEntityName() { const validation = this._validateEntityName(this.entityData.name); if (validation !== true) { throw new Error(validation); } }, bootstrapConfig({ application }) { const context = this.entityData; const entityName = context.name; if ([APPLICATION_TYPE_MICROSERVICE, APPLICATION_TYPE_GATEWAY].includes(application.applicationType)) { this.entityConfig.databaseType ??= context.databaseType; } context.useConfigurationFile = context.configurationFileExists || context.useConfigurationFile; if (context.configurationFileExists) { this.log.log(chalk.green(` Found the ${context.filename} configuration file, entity can be automatically generated! `)); } // Structure for prompts. this.entityStorage.defaults({ fields: [], relationships: [] }); if (!context.useConfigurationFile) { this.log.verboseInfo(` The entity ${entityName} is being created. `); } }, /* ask question to user if s/he wants to update entity */ askForUpdate, askForFields, askForFieldsToRemove, askForRelationships, askForRelationsToRemove, askForService, askForDTO, askForFiltering, askForReadOnly, askForPagination, async composeEntities() { if (!this.jhipsterConfig.entities) { this.jhipsterConfig.entities = []; } this.jhipsterConfig.entities = [...this.jhipsterConfig.entities, this.entityData.name]; // We need to compose with others entities to update relationships. await this.composeWithJHipster('entities', { generatorArgs: this.options.singleEntity ? [this.entityData.name] : [], }); }, }); } get [BaseApplicationGenerator.POST_PREPARING]() { return this.delegateTasksToBlueprint(() => this.postPreparing); } // Public API method used by the getter and also by Blueprints get end() { return this.asEndTaskGroup({ end() { this.log.log(chalk.bold.green(`Entity ${this.entityData.name} generated successfully.`)); }, }); } get [BaseApplicationGenerator.END]() { return this.delegateTasksToBlueprint(() => this.end); } /** * @private * Setup Entity instance level options from context. * all variables should be set to dest, * all variables should be referred from context, * all methods should be called on generator, */ _setupEntityOptions() { this.entityData.regenerate = this.options.regenerate; if (this.options.skipCheckLengthOfIdentifier !== undefined) { this.entityConfig.skipCheckLengthOfIdentifier = this.options.skipCheckLengthOfIdentifier; } if (this.options.angularSuffix !== undefined) { this.entityConfig.angularJSSuffix = this.options.angularSuffix; } if (this.options.skipUiGrouping !== undefined) { this.entityConfig.skipUiGrouping = this.options.skipUiGrouping; } if (this.options.clientRootFolder !== undefined) { if (this.entityConfig.skipUiGrouping) { this.log.warn('Ignoring client-root-folder due to skip-ui-grouping configuration'); } else { this.entityConfig.clientRootFolder = this.options.clientRootFolder; } } if (this.options.skipClient !== undefined) { this.entityConfig.skipClient = this.options.skipClient; } if (this.options.skipServer !== undefined) { this.entityConfig.skipServer = this.options.skipServer; } if (this.options.tableName) { this.entityConfig.entityTableName = hibernateSnakeCase(this.options.tableName); } } /** * @private * Validate the entityName * @return {true|string} true for a valid value or error message. */ _validateEntityName(entityName) { if (!/^([a-zA-Z0-9]*)$/.test(entityName)) { return 'The entity name must be alphanumeric only'; } if (/^\d.*$/.test(entityName)) { return 'The entity name cannot start with a number'; } if (entityName === '') { return 'The entity name cannot be empty'; } if (entityName.endsWith('Detail')) { return "The entity name cannot end with 'Detail'"; } if (!this.entityData.skipServer && isReservedClassName(entityName)) { return 'The entity name cannot contain a Java or JHipster reserved keyword'; } return true; } }