@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
125 lines (124 loc) • 4.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmartMergeContent = void 0;
const merge_content_1 = require("./merge-content");
class SmartMergeContent {
constructor() {
this.originalMerge = new merge_content_1.MergeContent();
this.SCHEMA_MARKER = '// @generated from prisma schema';
}
merge(existingText, generatedText) {
if (!existingText.trim()) {
return generatedText;
}
try {
return this.smartMerge(existingText, generatedText);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
console.warn('Smart merge failed, falling back to original merge:', errorMessage);
return this.originalMerge.merge(existingText, generatedText);
}
}
smartMerge(existingText, generatedText) {
const userFields = this.extractUserFields(existingText);
let result = this.originalMerge.merge(existingText, generatedText);
if (userFields.length > 0) {
result = this.ensureUserFieldsPreserved(result, userFields);
}
return result;
}
extractUserFields(text) {
const userFields = [];
const lines = text.split('\n');
let currentField = '';
let inUserField = false;
let braceCount = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (!inUserField &&
this.isPropertyStart(line) &&
!this.hasSchemaMarkerNearby(lines, i)) {
inUserField = true;
currentField = line;
braceCount = this.countBraces(line);
if (line.includes(';') && braceCount === 0) {
userFields.push(currentField.trim());
currentField = '';
inUserField = false;
}
}
else if (inUserField) {
currentField += '\n' + line;
braceCount += this.countBraces(line);
if (line.includes(';') && braceCount === 0) {
userFields.push(currentField.trim());
currentField = '';
inUserField = false;
}
}
}
return userFields;
}
isPropertyStart(line) {
const trimmed = line.trim();
return ((trimmed.startsWith('@') || /^\s*\w+[\?\!]?\s*:\s*/.test(trimmed)) &&
!trimmed.startsWith('//') &&
!trimmed.startsWith('/*') &&
!trimmed.includes('class ') &&
!trimmed.includes('export ') &&
!trimmed.includes('import '));
}
hasSchemaMarkerNearby(lines, index) {
for (let i = Math.max(0, index - 5); i < index; i++) {
if (lines[i].includes(this.SCHEMA_MARKER)) {
return true;
}
}
return false;
}
countBraces(line) {
return (line.match(/\{/g) || []).length - (line.match(/\}/g) || []).length;
}
ensureUserFieldsPreserved(mergedText, userFields) {
let result = mergedText;
for (const userField of userFields) {
const fieldName = this.extractFieldName(userField);
if (fieldName && !this.fieldExistsInResult(result, fieldName)) {
result = this.addUserFieldToClass(result, userField);
}
}
return result;
}
extractFieldName(field) {
const match = field.match(/(\w+)[\?\!]?\s*:/);
return match ? match[1] : null;
}
fieldExistsInResult(text, fieldName) {
const regex = new RegExp(`\\b${fieldName}[\\?\\!]?\\s*:`, 'g');
return regex.test(text);
}
addUserFieldToClass(text, userField) {
const lines = text.split('\n');
for (let i = lines.length - 1; i >= 0; i--) {
if (lines[i].trim() === '}' && this.isClassClosingBrace(lines, i)) {
lines.splice(i, 0, '', ' // @user-defined field', ' ' + userField.replace(/^\s+/, ''));
break;
}
}
return lines.join('\n');
}
isClassClosingBrace(lines, index) {
for (let i = index - 1; i >= 0; i--) {
const line = lines[i].trim();
if (line.includes('export class')) {
return true;
}
if (line.includes('class ') && !line.includes('export class')) {
return false;
}
}
return false;
}
}
exports.SmartMergeContent = SmartMergeContent;