UNPKG

@solid-nestjs/rest-api

Version:

solid-nestjs Rest-API utilities

206 lines 7.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SwaggerDecoratorAdapter = void 0; //Base: 081d3ec version que funciona para DTOs + lógica de relaciones const common_1 = require("@solid-nestjs/common"); // Dynamic imports to avoid dependency issues when Swagger is not available let ApiProperty; let ApiPropertyOptional; let ApiHideProperty; let ApiExtraModels; // Relation adapter helper for Swagger class SwaggerRelationAdapterHelper { getRelationAdapterOptions(type, targetFn, inverseSide, options) { return { type: () => { const targetClass = targetFn(); // For array relations, return array type if (type === 'one-to-many' || type === 'many-to-many') { return [targetClass]; } // For single relations, return single type return targetClass; }, description: options.description || `Related ${targetFn().name} entities`, }; } } class SwaggerDecoratorAdapter { constructor() { this.name = 'swagger'; this.swaggerLoaded = false; } isAvailable() { try { require.resolve('@nestjs/swagger'); return true; } catch { return false; } } loadSwagger() { if (this.swaggerLoaded) return; try { const swagger = require('@nestjs/swagger'); ApiProperty = swagger.ApiProperty; ApiPropertyOptional = swagger.ApiPropertyOptional; ApiHideProperty = swagger.ApiHideProperty; ApiExtraModels = swagger.ApiExtraModels; this.swaggerLoaded = true; } catch (error) { console.warn('[SolidNestJS] Failed to load Swagger decorators:', error); } } apply(target, propertyKey, metadata) { if (!this.swaggerLoaded) { this.loadSwagger(); if (!this.swaggerLoaded) return; } const { type, options, isOptional, adapterOptions } = metadata; // Skip hidden fields if (options.hidden) { if (ApiHideProperty) { ApiHideProperty()(target, propertyKey); } return; } // Build Swagger property options const swaggerOptions = this.buildSwaggerOptions(type, options, adapterOptions); // Apply appropriate decorator const decorator = (options.nullable ?? isOptional) ? ApiPropertyOptional : ApiProperty; if (decorator) { decorator(swaggerOptions)(target, propertyKey); } } applyClassDecorator(target, type, options) { // No class decorators needed for this adapter // Schema registration is handled at the controller level } buildSwaggerOptions(type, options, adapterOptions) { const swaggerOptions = { description: options.description, example: options.example, default: options.defaultValue, deprecated: options.deprecated, minimum: options.min, maximum: options.max, minLength: options.minLength, maxLength: options.maxLength, pattern: options.pattern?.source, readOnly: options.readOnly, writeOnly: options.writeOnly, }; // NUEVO: Detectar relaciones PRIMERO if (adapterOptions?.type) { const explicitType = typeof adapterOptions.type === 'function' ? adapterOptions.type() : adapterOptions.type; // Si es [TargetClass] de relaciones if (Array.isArray(explicitType) && explicitType.length > 0) { swaggerOptions.isArray = true; swaggerOptions.type = this.mapPrimitiveType(explicitType[0]); } else { // Single relation swaggerOptions.type = this.mapPrimitiveType(explicitType); } } // ORIGINAL: Lógica de 081d3ec para arrays de DTOs else if (options.array) { swaggerOptions.isArray = true; // Get array item type let itemType = options.arrayType; if (typeof itemType === 'function') { itemType = itemType(); } if (itemType) { // For custom classes, use the class directly if (typeof itemType === 'function' && itemType.prototype) { swaggerOptions.type = itemType; } else { // For primitives, map them swaggerOptions.type = this.mapPrimitiveType(itemType); } } else { swaggerOptions.type = this.mapPrimitiveType(type); } // Array-specific options if (options.minSize !== undefined) swaggerOptions.minItems = options.minSize; if (options.maxSize !== undefined) swaggerOptions.maxItems = options.maxSize; if (options.uniqueItems) swaggerOptions.uniqueItems = true; } // ORIGINAL: Single value type else { swaggerOptions.type = this.mapPrimitiveType(type); } // Handle enums if (options.enum) { swaggerOptions.enum = options.enum; if (options.enumName) { swaggerOptions.enumName = options.enumName; } } // Handle special string formats if (type === String) { if (options.email) swaggerOptions.format = 'email'; if (options.url) swaggerOptions.format = 'url'; if (options.uuid) swaggerOptions.format = 'uuid'; if (options.password) swaggerOptions.format = 'password'; } // Handle date format if (type === Date) { swaggerOptions.format = 'date-time'; } // Handle number formats if (type === Number) { if (options.integer) { swaggerOptions.type = 'integer'; } if (options.float || options.precision) { swaggerOptions.format = 'float'; } if (options.double) { swaggerOptions.format = 'double'; } } // Remove undefined values Object.keys(swaggerOptions).forEach(key => { if (swaggerOptions[key] === undefined) { delete swaggerOptions[key]; } }); return swaggerOptions; } mapPrimitiveType(type) { // For custom classes, return the class directly if (typeof type === 'function' && type.prototype && type.name) { return type; } // Map primitive types to Swagger types const typeMap = new Map([ [String, 'string'], [Number, 'number'], [Boolean, 'boolean'], [Date, 'string'], [Object, 'object'], ]); return typeMap.get(type) || type; } } exports.SwaggerDecoratorAdapter = SwaggerDecoratorAdapter; // Register the Swagger relation adapter common_1.RelationAdapterRegistry.registerAdapter('swagger', new SwaggerRelationAdapterHelper()); //# sourceMappingURL=swagger.adapter.js.map