UNPKG

gen-jhipster

Version:

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

153 lines (152 loc) 6.24 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 { escapeRegExp } from 'lodash-es'; const addJavaImportToContent = (content, identifier, { staticImport } = {}) => { const importStatement = `import ${staticImport ? 'static ' : ''}${identifier};`; return new RegExp(escapeRegExp(importStatement)).test(content) ? content : content.replace(/(package [\w.]+;\n\n?)/, `$1${importStatement}\n`); }; export function addJavaImport(contentOrIdentifier, identifierOrType, type) { if (typeof identifierOrType === 'string') { return addJavaImportToContent(contentOrIdentifier, identifierOrType, type); } return (content) => addJavaImportToContent(content, contentOrIdentifier, identifierOrType); } export function parseJavaAnnotation(annotation) { if (annotation === undefined) { return {}; } const params = []; let current = ''; let depth = 0; // Iterate to find top-level commas for (const char of annotation) { if (char === '(' || char === '{' || char === '[') depth++; if (char === ')' || char === '}' || char === ']') depth--; if (char === ',' && depth === 0) { params.push(current.trim()); current = ''; } else { current += char; } } params.push(current.trim()); // Convert array of strings into a key-value object return params.reduce((acc, param) => { const eqIdx = param.indexOf('='); if (eqIdx === -1) { acc.value = param.trim(); return acc; } const key = param.slice(0, eqIdx).trim(); let value = param.slice(eqIdx + 1).trim(); if (value.startsWith('{')) { // Handle Java arrays by stripping braces and splitting value = value .slice(1, -1) .split(/,\s*/) .map(v => v.replace(/^"|"$/g, '')); } else { value = value.replace(/^"|"$/g, ''); // Simple strings } acc[key] = value; return acc; }, {}); } const serializeJavaAnnotationParameters = (params) => { if (!params) { return ''; } const entries = Object.entries(params).map(([key, value]) => [key, Array.isArray(value) ? `{${value.join(', ')}}` : value]); if (entries.length === 0) { return ''; } else if (entries.length === 1 && entries[0][0] === 'value') { return entries[0][1]; } return entries.map(([key, value]) => `${key} = ${value}`).join(', '); }; const addJavaAnnotationToContent = (content, annotationDef) => { const { package: packageName, annotation, parameters } = annotationDef; if (packageName) { content = addJavaImport(content, `${packageName}.${annotation}`); } const annotationWithParametersMatches = content.match(new RegExp(String.raw `@${annotation}\((?<oldParameters>[^)]*)\)`)); let annotationToAdd; if (parameters) { const oldParameters = annotationWithParametersMatches?.groups?.oldParameters?.trim?.(); const parsedParameters = parseJavaAnnotation(oldParameters); const returnedParameters = parameters(parsedParameters, { addKeyValue: (key, value) => { const existing = parsedParameters[key]; if (existing) { if (Array.isArray(existing)) { parsedParameters[key] = Array.isArray(value) ? [...existing, ...value] : [...existing, value]; } else { parsedParameters[key] = Array.isArray(value) ? [existing, ...value] : [existing, value]; } } else { parsedParameters[key] = value; } }, setKeyValue: (key, value) => { const existing = parsedParameters[key]; if (existing) { if (Array.isArray(existing)) { parsedParameters[key] = Array.isArray(value) ? [...existing, ...value] : [...existing, value]; } else { parsedParameters[key] = Array.isArray(value) ? [existing, ...value] : [existing, value]; } } else { parsedParameters[key] = value; } }, }); const serializedParam = typeof returnedParameters === 'string' ? returnedParameters : serializeJavaAnnotationParameters(returnedParameters ?? parsedParameters); annotationToAdd = serializedParam ? `${annotation}(${serializedParam})` : annotation; } else { annotationToAdd = annotation; } if (annotationWithParametersMatches) { content = content.replace(new RegExp(String.raw `@${annotation}\((?<oldParameters>[^)]*)\)`), `@${annotationToAdd}`); } else if (!new RegExp(escapeRegExp(`\n@${annotationToAdd}\n`)).test(content)) { // add the annotation before class or interface content = content.replace(/\n([a-w ]*(class|@?interface|enum) )/, `\n@${annotationToAdd}\n$1`); } return content; }; export function addJavaAnnotation(contentOrAnnotation, annotation) { if (typeof contentOrAnnotation === 'string') { return addJavaAnnotationToContent(contentOrAnnotation, annotation); } return (content) => addJavaAnnotationToContent(content, contentOrAnnotation); }