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

220 lines (219 loc) 9.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DecoratorStrategy = void 0; const fs_1 = require("fs"); const annotations_1 = require("./annotations"); class DecoratorStrategy { constructor(customDecoratorConfigsPath) { var _a; this.omitDecorators = [ ...annotations_1.DTO_RELATION_MODIFIERS, ...annotations_1.DTO_RELATION_MODIFIERS_ON_CREATE, ...annotations_1.DTO_RELATION_MODIFIERS_ON_UPDATE, ]; this.decoratorCategories = [ { importPath: '@nestjs/swagger', names: [/ApiProperty/, /ApiExtraModels/], }, { importPath: 'class-transformer', names: [/Exclude/, /Expose/, /Transform/, /Type/], }, { importPath: 'class-validator', names: [ /Allow/, /IsDefined/, /IsOptional/, /Validate/, /ValidateBy/, /ValidateIf/, /ValidateNested/, /ValidatePromise/, /IsLatLong/, /IsLatitude/, /IsLongitude/, /Equals/, /NotEquals/, /IsEmpty/, /IsNotEmpty/, /IsIn/, /IsNotIn/, /IsDivisibleBy/, /IsPositive/, /IsNegative/, /Max/, /Min/, /MinDate/, /MaxDate/, /Contains/, /NotContains/, /IsAlpha/, /IsAlphanumeric/, /IsDecimal/, /IsAscii/, /IsBase64/, /IsByteLength/, /IsCreditCard/, /IsCurrency/, /IsEmail/, /IsFQDN/, /IsFullWidth/, /IsHalfWidth/, /IsVariableWidth/, /IsHexColor/, /IsHexadecimal/, /IsMacAddress/, /IsIP/, /IsPort/, /IsISBN/, /IsISIN/, /IsISO8601/, /IsJSON/, /IsJWT/, /IsLowercase/, /IsMobilePhone/, /IsISO31661Alpha2/, /IsISO31661Alpha3/, /IsMongoId/, /IsMultibyte/, /IsSurrogatePair/, /IsUrl/, /IsUUID/, /IsFirebasePushId/, /IsUppercase/, /Length/, /MaxLength/, /MinLength/, /Matches/, /IsPhoneNumber/, /IsMilitaryTime/, /IsHash/, /IsISSN/, /IsDateString/, /IsBooleanString/, /IsNumberString/, /IsBase32/, /IsBIC/, /IsBtcAddress/, /IsDataURI/, /IsEAN/, /IsEthereumAddress/, /IsHSL/, /IsIBAN/, /IsIdentityCard/, /IsISRC/, /IsLocale/, /IsMagnetURI/, /IsMimeType/, /IsOctal/, /IsPassportNumber/, /IsPostalCode/, /IsRFC3339/, /IsRgbColor/, /IsSemVer/, /IsStrongPassword/, /IsTimeZone/, /IsBase58/, /is-tax-id/, /is-iso4217-currency-code/, /IsBoolean/, /IsDate/, /IsNumber/, /IsEnum/, /IsInt/, /IsString/, /IsArray/, /IsObject/, /ArrayContains/, /ArrayNotContains/, /ArrayNotEmpty/, /ArrayMinSize/, /ArrayMaxSize/, /ArrayUnique/, /IsNotEmptyObject/, /IsInstance/, ], }, ]; console.log(`[DecoratorStrategy] Constructor called with path: ${customDecoratorConfigsPath}`); if (!customDecoratorConfigsPath) { console.log('[DecoratorStrategy] WARNING: No config path provided! Stack trace:'); console.log((_a = new Error().stack) === null || _a === void 0 ? void 0 : _a.split('\n').slice(1, 5).join('\n')); } let combinedCategories = this.decoratorCategories; let customConfigs = []; if (customDecoratorConfigsPath) { console.log(`Using custom decorator configs from ${customDecoratorConfigsPath}`); try { const customDecoratorConfigs = (0, fs_1.readFileSync)(customDecoratorConfigsPath, 'utf8'); customConfigs = JSON.parse(customDecoratorConfigs); console.log(`Custom decorator configs loaded: ${JSON.stringify(customConfigs)}`); } catch (err) { console.error('Error loading custom decorator configs:', err); throw new Error('Invalid JSON for customDecoratorConfigs'); } } if (customConfigs.length) { console.log(`Found ${customConfigs.length} custom decorator configs: ${JSON.stringify(customConfigs)}`); const processedCustomConfigs = customConfigs.map((category) => ({ ...category, names: category.names.map((name) => typeof name === 'string' ? new RegExp(name) : name), })); console.log(`Processed custom decorator configs: ${JSON.stringify(processedCustomConfigs.map((category) => ({ ...category, names: category.names.map((name) => name instanceof RegExp ? name.toString() : name), })), null, 2)}`); combinedCategories = [...combinedCategories, ...processedCustomConfigs]; } console.log('[DecoratorStrategy] Final combined categories:', combinedCategories.map(cat => ({ importPath: cat.importPath, nameCount: cat.names.length }))); this.decoratorImportMap = combinedCategories.flatMap(({ importPath, names }) => names.map((name) => ({ name, importPath }))); console.log('[DecoratorStrategy] Import map created with', this.decoratorImportMap.length, 'entries'); } getValidDecorators(doc) { const decorators = this.decoratorsStringToArray(doc); return decorators.filter((decorator) => this.verifyIfDecoratorIsValid(decorator) && !this.omitDecorators.find((omitDecorator) => omitDecorator.test(decorator))); } decoratorsStringToArray(doc) { const decorators = doc .split('\n') .map((line) => line.trim()) .filter((line) => line.startsWith('@')); return decorators; } verifyIfDecoratorIsValid(decoratorName) { return this.decoratorImportMap.some(({ name }) => name.test(decoratorName)); } getValidDecoratorAndImportsByDoc(doc) { if (!doc) return []; const decorators = this.decoratorsStringToArray(doc); console.log(`Found decorators in doc: ${decorators.join(', ')}`); return decorators .map((decorator) => this.getValidDecoratorAndImports(decorator)) .filter((result) => !!result); } formatValidDecoratorResultToFromDestruct(validDecoratorResult) { return Array.from(validDecoratorResult.reduce((map, { importPath, decoratorName }) => { var _a; return map.set(importPath, [...((_a = map.get(importPath)) !== null && _a !== void 0 ? _a : []), decoratorName]); }, new Map())).map(([from, destruct]) => ({ from, destruct })); } getValidDecoratorAndImports(decoratorName) { const hasCustomDecorators = this.decoratorImportMap.some(({ importPath }) => importPath === '@angular/core'); if (!hasCustomDecorators) { console.log(`[DecoratorStrategy] WARNING: No @angular/core decorators in import map for decorator: ${decoratorName}`); } console.log('Checking decorator imports:', this.decoratorImportMap.filter(({ importPath }) => importPath !== 'class-validator')); const match = this.decoratorImportMap.find(({ name }) => name.test(decoratorName)); if (!match) { console.log(`[DecoratorStrategy] No match found for decorator: ${decoratorName}`); return undefined; } return { importPath: match.importPath, decoratorName: match.name.source }; } } exports.DecoratorStrategy = DecoratorStrategy;