UNPKG

@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
"use strict"; 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;