@weverson_na/prisma-generator-nestjs-dto
Version:
Advanced Prisma Generator with Smart Merge v2: Creates DTO and Entity classes with AST-based preservation, intelligent import management, and modular architecture for NestJS
142 lines (141 loc) • 4.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmartMergeContent = void 0;
class SmartMergeContent {
constructor() {
this.SCHEMA_MARKER = '// @generated from prisma schema';
}
merge(existingText, generatedText) {
if (!existingText.trim()) {
return generatedText;
}
try {
const userFields = this.extractUserFields(existingText);
if (userFields.length === 0) {
return generatedText;
}
let result = this.insertUserFieldsIntoGenerated(generatedText, userFields);
return result;
}
catch (error) {
console.warn('Smart merge failed, falling back to generated content:', error);
return generatedText;
}
}
extractUserFields(text) {
const userFields = [];
const lines = text.split('\n');
let i = 0;
while (i < lines.length) {
if (this.shouldSkipLine(lines[i])) {
i++;
continue;
}
const fieldBlock = this.extractFieldBlock(lines, i);
if (fieldBlock) {
if (!this.isSchemaGenerated(fieldBlock.code)) {
userFields.push({
name: fieldBlock.name,
code: fieldBlock.code,
});
}
i = fieldBlock.endIndex;
}
else {
i++;
}
}
return userFields;
}
shouldSkipLine(line) {
const trimmed = line.trim();
return (trimmed.startsWith('import ') ||
trimmed.startsWith('export class ') ||
trimmed.includes('@ApiExtraModels') ||
trimmed === '' ||
trimmed === '}' ||
trimmed === '{');
}
extractFieldBlock(lines, startIndex) {
let i = startIndex;
let blockLines = [];
let fieldName = '';
let foundProperty = false;
let lookAhead = i;
while (lookAhead < lines.length && lookAhead < i + 10) {
const line = lines[lookAhead];
if (this.isPropertyDeclaration(line)) {
foundProperty = true;
fieldName = this.extractFieldName(line) || '';
break;
}
if (this.isEndOfBlock(line)) {
break;
}
lookAhead++;
}
if (!foundProperty || !fieldName) {
return null;
}
while (i <= lookAhead && i < lines.length) {
const line = lines[i];
blockLines.push(line);
if (this.isPropertyDeclaration(line)) {
i++;
break;
}
i++;
}
return {
name: fieldName,
code: blockLines.join('\n').trim(),
endIndex: i,
};
}
isPropertyDeclaration(line) {
const trimmed = line.trim();
return /^\s*\w+[?!]?\s*:\s*/.test(trimmed) && trimmed.includes(';');
}
isEndOfBlock(line) {
const trimmed = line.trim();
return (trimmed === '}' ||
trimmed.startsWith('export ') ||
trimmed.startsWith('import '));
}
extractFieldName(line) {
const match = line.match(/(\w+)[?!]?\s*:/);
return match ? match[1] : null;
}
isSchemaGenerated(fieldCode) {
return fieldCode.includes(this.SCHEMA_MARKER);
}
insertUserFieldsIntoGenerated(generatedText, userFields) {
const lines = generatedText.split('\n');
let insertIndex = -1;
for (let i = lines.length - 1; i >= 0; i--) {
if (lines[i].trim() === '}') {
insertIndex = i;
break;
}
}
if (insertIndex === -1) {
return generatedText;
}
const insertLines = [];
for (const field of userFields) {
insertLines.push('');
const fieldLines = field.code.split('\n');
for (const fieldLine of fieldLines) {
if (fieldLine.trim()) {
insertLines.push(' ' + fieldLine.replace(/^\s+/, ''));
}
else {
insertLines.push(fieldLine);
}
}
}
lines.splice(insertIndex, 0, ...insertLines);
return lines.join('\n');
}
}
exports.SmartMergeContent = SmartMergeContent;