UNPKG

generator-begcode

Version:

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

128 lines (127 loc) 5.86 kB
import assert from 'assert'; import { escapeRegExp, kebabCase } from 'lodash-es'; import { joinCallbacks } from './write-files.js'; export const convertToPrettierExpressions = (str) => str.replace(/\s+/g, '([\\s\n]*)').replace(/>+/g, '(\n?[\\s]*)>'); export const checkContentIn = (contentToCheck, content, ignoreWhitespaces = true) => { assert(content, 'content is required'); assert(contentToCheck, 'contentToCheck is required'); let re; if (typeof contentToCheck === 'string') { const pattern = ignoreWhitespaces ? convertToPrettierExpressions(escapeRegExp(contentToCheck)) : contentToCheck .split('\n') .map(line => `\\s*${escapeRegExp(line)}`) .join('\n'); re = new RegExp(pattern); } else { re = contentToCheck; } return re.test(content); }; export const insertContentBeforeNeedle = ({ content, contentToAdd, needle, autoIndent = true }) => { assert(needle, 'needle is required'); assert(content, 'content is required'); assert(contentToAdd, 'contentToAdd is required'); needle = needle.includes('jhipster-needle-') ? needle : `jhipster-needle-${needle}`; let regexp = new RegExp(`(?://|<!--|/*|#) ${needle}(?:$|\n| )`, 'g'); let firstMatch = regexp.exec(content); if (!firstMatch) { regexp = new RegExp(`"${needle}": `, 'g'); firstMatch = regexp.exec(content); if (!firstMatch) { return null; } } if (typeof contentToAdd !== 'function' && regexp.exec(content)) { throw new Error(`Multiple needles found for ${needle}`); } const needleIndex = firstMatch.index; const needleLineIndex = content.lastIndexOf('\n', needleIndex); const beforeContent = content.substring(0, needleLineIndex + 1); const afterContent = content.substring(needleLineIndex + 1); const needleLine = afterContent.split('\n', 2)[0]; const needleIndent = needleLine.length - needleLine.trimStart().length; if (typeof contentToAdd === 'function') { return contentToAdd(content, { needleIndent, indentPrefix: ' '.repeat(needleIndent) }); } contentToAdd = Array.isArray(contentToAdd) ? contentToAdd : [contentToAdd]; if (autoIndent) { contentToAdd = contentToAdd.map(eachContentToAdd => eachContentToAdd.split('\n')).flat(); } const firstContent = contentToAdd.find(line => line.trim()); if (!firstContent) { return null; } const contentIndent = firstContent.length - firstContent.trimStart().length; if (needleIndent > contentIndent) { const identToApply = ' '.repeat(needleIndent - contentIndent); contentToAdd = contentToAdd.map(line => (line ? identToApply + line : line)); } else if (needleIndent < contentIndent) { let identToRemove = contentIndent - needleIndent; contentToAdd .filter(line => line.trimStart()) .forEach(line => { const trimmedLine = line.trimStart(); const lineIndent = line.length - trimmedLine.length; if (lineIndent < identToRemove) { identToRemove = lineIndent; } }); contentToAdd = contentToAdd.map(line => (line.length > identToRemove ? line.substring(identToRemove) : '')); } return `${beforeContent}${contentToAdd.join('\n')}\n${afterContent}`; }; export const createNeedleCallback = ({ needle, contentToAdd, contentToCheck, optional = false, ignoreWhitespaces = true, autoIndent, }) => { assert(needle, 'needle is required'); assert(contentToAdd, 'contentToAdd is required'); return function (content, filePath) { if (contentToCheck && checkContentIn(contentToCheck, content, ignoreWhitespaces)) { return content; } if (typeof contentToAdd !== 'function') { if (typeof contentToAdd === 'string' && contentToAdd.startsWith('\n')) { contentToAdd = contentToAdd.slice(1); } contentToAdd = (Array.isArray(contentToAdd) ? contentToAdd : [contentToAdd]).filter(eachContent => !checkContentIn(eachContent, content, ignoreWhitespaces)); if (contentToAdd.length === 0) { return content; } } const newContent = insertContentBeforeNeedle({ needle, content, contentToAdd, autoIndent, }); if (newContent) { return newContent; } const message = `Missing ${optional ? 'optional' : 'required'} jhipster-needle ${needle} not found at '${filePath}'`; if (optional && this) { this.log.warn(message); return content; } throw new Error(message); }; }; export function createBaseNeedle(options, needles) { const actualNeedles = needles === undefined ? options : needles; const actualOptions = needles === undefined ? {} : options; assert(actualNeedles, 'needles is required'); const { needlesPrefix, filePath, ...needleOptions } = actualOptions; needleOptions.optional = needleOptions.optional ?? false; needleOptions.ignoreWhitespaces = needleOptions.ignoreWhitespaces ?? true; const callbacks = Object.entries(actualNeedles) .filter(([_key, contentToAdd]) => contentToAdd) .map(([key, contentToAdd]) => createNeedleCallback({ ...needleOptions, needle: `${needlesPrefix ? `${needlesPrefix}-` : ''}${kebabCase(key)}`, contentToAdd })); assert(callbacks.length > 0, 'At least 1 needle is required'); const callback = callbacks.length === 1 ? callbacks[0] : joinCallbacks(...callbacks); if (filePath) { assert(this?.editFile, 'when passing filePath, the generator is required'); return this.editFile(filePath, callback); } return callback; }