UNPKG

generator-jhipster

Version:

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

289 lines (288 loc) 11.6 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 { lowerFirst, upperFirst } from 'lodash-es'; import { asJdlRelationshipType } from "../core/basic-types/relationship-types.js"; import { binaryOptions, relationshipOptions, unaryOptions } from "../core/built-in-options/index.js"; import { JDLEntity, JDLEnum } from "../core/models/index.js"; import JDLBinaryOption from "../core/models/jdl-binary-option.js"; import JDLField from "../core/models/jdl-field.js"; import JDLObject from "../core/models/jdl-object.js"; import JDLRelationship, {} from "../core/models/jdl-relationship.js"; import JDLUnaryOption from "../core/models/jdl-unary-option.js"; import JDLValidation from "../core/models/jdl-validation.js"; const { BUILT_IN_ENTITY } = relationshipOptions; const { FILTER, NO_FLUENT_METHOD, READ_ONLY, EMBEDDED } = unaryOptions; const { ANGULAR_SUFFIX, CLIENT_ROOT_FOLDER, DTO, MICROSERVICE, PAGINATION, SEARCH, SERVICE } = binaryOptions.Options; export default { convertEntitiesToJDL, }; let entities; let jdlObject; /** * Convert the passed entities (parsed from JSON files) to a JDL object. * @param entities - a Map having for keys the entity names and values the JSON entity files. * @return the parsed entities in the JDL form. */ export function convertEntitiesToJDL(entities) { if (!entities) { throw new Error('Entities have to be passed to be converted.'); } init(entities); addEntities(); addRelationshipsToJDL(); return jdlObject; } function init(ents) { entities = ents; jdlObject = new JDLObject(); } function addEntities() { entities.forEach((entity, entityName) => { addEntity(entity, entityName); }); } function addEntity(entity, entityName) { jdlObject.addEntity(convertJSONToJDLEntity(entity, entityName)); addEnumsToJDL(entity); addEntityOptionsToJDL(entity, entityName); } function convertJSONToJDLEntity(entity, entityName) { const jdlEntity = new JDLEntity({ name: entityName, tableName: entity.entityTableName, comment: entity.documentation, annotations: entity.annotations, }); addFields(jdlEntity, entity); return jdlEntity; } function addFields(jdlEntity, entity) { entity?.fields?.forEach(field => { jdlEntity.addField(convertJSONToJDLField(field)); }); } function convertJSONToJDLField(field) { const jdlField = new JDLField({ name: lowerFirst(field.fieldName), type: field.fieldType, comment: field.documentation, options: field.options, }); addValidations(jdlField, field); return jdlField; } function addValidations(jdlField, field) { if (field.fieldValidateRules) { field.fieldValidateRules.forEach((rule) => { jdlField.addValidation(convertJSONToJDLValidation(rule, field)); }); } } function convertJSONToJDLValidation(rule, field) { return new JDLValidation({ name: rule, value: field[`fieldValidateRules${upperFirst(rule)}`], }); } function addEnumsToJDL(entity) { entity?.fields?.forEach((field) => { if (field.fieldValues !== undefined) { jdlObject.addEnum(new JDLEnum({ name: field.fieldType, values: getEnumValuesFromString(field.fieldValues), comment: field.fieldTypeDocumentation, })); } }); } function getEnumValuesFromString(valuesAsString) { return valuesAsString.split(',').map(fieldValue => { // if fieldValue looks like ENUM_VALUE (something) if (fieldValue.includes('(')) { const [key, value] = fieldValue .replace(/^(\w+)\s\((\w+)\)$/, (_match, matchedKey, matchedValue) => `${matchedKey},${matchedValue}`) .split(','); return { key, value, }; } return { key: fieldValue }; }); } /* * Adds relationships for entities to JDL. * The jdl passed must contain the jdl entities concerned by the relationships */ function addRelationshipsToJDL() { entities.forEach((entity, entityName) => { dealWithRelationships(entity.relationships, entityName); }); } function dealWithRelationships(relationships, entityName) { if (!relationships) { return; } relationships.forEach(relationship => { if (relationship.relationshipSide === 'right') { // Right side will be merged into the left side. return; } const jdlRelationship = getRelationship(relationship, entityName); if (jdlRelationship) { jdlObject.addRelationship(jdlRelationship); } }); } function getRelationship(relationship, entityName) { const type = asJdlRelationshipType(relationship.relationshipType); const options = getRelationshipOptions(relationship); const sourceEntitySideAttributes = getSourceEntitySideAttributes(entityName, relationship); const destinationEntityName = upperFirst(relationship.otherEntityName); const destinationJDLEntity = jdlObject.getEntity(destinationEntityName); const destinationEntity = entities.get(destinationEntityName); let relationshipConfiguration = { side: relationship.relationshipSide, from: entityName, to: destinationJDLEntity?.name ?? destinationEntityName, type, options, injectedFieldInFrom: sourceEntitySideAttributes.injectedFieldInSourceEntity, isInjectedFieldInFromRequired: sourceEntitySideAttributes.injectedFieldInSourceIsRequired, commentInFrom: sourceEntitySideAttributes.commentForSourceEntity, isInjectedFieldInToRequired: false, injectedFieldInTo: null, commentInTo: null, }; relationshipConfiguration = { ...relationshipConfiguration, ...sourceEntitySideAttributes, }; if (!destinationJDLEntity || !destinationEntity) { if (relationshipConfiguration.options.global[BUILT_IN_ENTITY]) { return new JDLRelationship(relationshipConfiguration); } return undefined; } const isEntityTheDestinationSideEntity = (otherEntityName, otherEntityRelationshipName) => otherEntityName === entityName && otherEntityRelationshipName === relationship.relationshipName; const destinationSideAttributes = getDestinationEntitySideAttributes(isEntityTheDestinationSideEntity, destinationEntity.relationships); relationshipConfiguration = { ...relationshipConfiguration, injectedFieldInTo: destinationSideAttributes.injectedFieldInDestinationEntity, isInjectedFieldInToRequired: destinationSideAttributes.injectedFieldInDestinationIsRequired ?? false, commentInTo: destinationSideAttributes.commentForDestinationEntity, }; if (destinationSideAttributes.optionsForDestinationEntity) { relationshipConfiguration.options = { ...relationshipConfiguration.options, destination: destinationSideAttributes.optionsForDestinationEntity, }; } return new JDLRelationship(relationshipConfiguration); } function getSourceEntitySideAttributes(entityName, relationship) { return { sourceEntity: entityName, injectedFieldInSourceEntity: getInjectedFieldInSourceEntity(relationship), injectedFieldInSourceIsRequired: relationship.relationshipValidateRules, commentForSourceEntity: relationship.documentation, }; } function getDestinationEntitySideAttributes(isEntityTheDestinationSideEntity, destinationEntityRelationships) { const foundDestinationSideEntity = destinationEntityRelationships?.find(destinationEntityFromRelationship => { return isEntityTheDestinationSideEntity(upperFirst(destinationEntityFromRelationship.otherEntityName), destinationEntityFromRelationship.otherEntityRelationshipName); }); if (!foundDestinationSideEntity) { return {}; } // Bidirectional relationship let injectedFieldInDestinationEntity = foundDestinationSideEntity.relationshipName; if (!!foundDestinationSideEntity.otherEntityField && foundDestinationSideEntity.otherEntityField !== 'id') { injectedFieldInDestinationEntity += `(${foundDestinationSideEntity.otherEntityField})`; } const injectedFieldInDestinationIsRequired = !!foundDestinationSideEntity.relationshipValidateRules; const commentForDestinationEntity = foundDestinationSideEntity.documentation; return { injectedFieldInDestinationEntity, injectedFieldInDestinationIsRequired, commentForDestinationEntity, optionsForDestinationEntity: foundDestinationSideEntity.options, }; } function getRelationshipOptions(relationship) { const options = { global: {}, source: relationship.options ?? {}, destination: {}, }; if (relationship.relationshipWithBuiltInEntity) { options.global[BUILT_IN_ENTITY] = true; } return options; } function getInjectedFieldInSourceEntity(relationship) { return (relationship.relationshipName + (relationship.otherEntityField && relationship.otherEntityField !== 'id' ? `(${relationship.otherEntityField})` : '')); } function addEntityOptionsToJDL(entity, entityName) { if (entity.fluentMethods === false) { addUnaryOptionToJDL(NO_FLUENT_METHOD, entityName); } [DTO, PAGINATION, SERVICE].forEach(option => { if (entity[option] && entity[option] !== 'no') { addBinaryOptionToJDL(option, entity[option], entityName); } }); if (entity.searchEngine) { addBinaryOptionToJDL(SEARCH, entity.searchEngine, entityName); } // angularSuffix in BinaryOptions, angularJSSuffix in Json if (entity.angularJSSuffix) { addBinaryOptionToJDL(ANGULAR_SUFFIX, entity.angularJSSuffix, entityName); } // microservice in BinaryOptions, microserviceName in Json if (entity.microserviceName !== undefined) { addBinaryOptionToJDL(MICROSERVICE, entity.microserviceName, entityName); } if (entity.jpaMetamodelFiltering) { addUnaryOptionToJDL(FILTER, entityName); } if (entity.readOnly) { addUnaryOptionToJDL(READ_ONLY, entityName); } if (entity.embedded) { addUnaryOptionToJDL(EMBEDDED, entityName); } if (entity.clientRootFolder) { addBinaryOptionToJDL(CLIENT_ROOT_FOLDER, entity.clientRootFolder, entityName); } } function addUnaryOptionToJDL(unaryOption, entityName) { jdlObject.addOption(new JDLUnaryOption({ name: unaryOption, entityNames: new Set([entityName]), })); } function addBinaryOptionToJDL(binaryOption, value, entityName) { jdlObject.addOption(new JDLBinaryOption({ name: binaryOption, value, entityNames: new Set([entityName]), })); }