UNPKG

@buka/nestjs-type-helper

Version:
62 lines (61 loc) 2.69 kB
import * as R from 'ramda'; import { ModelPropertiesAccessor } from '@nestjs/swagger/dist/services/model-properties-accessor'; import { DECORATORS } from '@nestjs/swagger/dist/constants'; import { METADATA_FACTORY_NAME } from '@nestjs/swagger/dist/plugin/plugin-constants'; import { clonePluginMetadataFactory } from '@nestjs/swagger/dist/type-helpers/mapped-types.utils'; import { ApiProperty } from '@nestjs/swagger'; import { isFunction } from '@nestjs/common/utils/shared.utils'; import { isBuiltInType } from '@nestjs/swagger/dist/utils/is-built-in-type.util'; const modelPropertiesAccessor = new ModelPropertiesAccessor(); /** * 克隆 @nestjs/swagger Plugin 添加的元数据 */ export const cloneSwaggerPluginMetadataFactory = clonePluginMetadataFactory; export function cloneMetadata(target, source, keys) { cloneSwaggerPluginMetadataFactory(target, source.prototype, (metadata) => R.pick(keys, metadata)); keys.forEach((propertyKey) => { const metadata = getMetadataOfDecorator(source, propertyKey); const decoratorFactory = ApiProperty(metadata); decoratorFactory(target.prototype, propertyKey); }); } export function getMetadataOfDecorator(classRef, propertyKey) { if (propertyKey) { return Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, propertyKey); } const props = modelPropertiesAccessor .getModelProperties(classRef.prototype); return R.fromPairs(props.map((prop) => [ prop, Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES, classRef.prototype, prop), ])); } function getMetadataOfPlugin(classRef, propertyKey) { const propsInPlugin = typeof classRef[METADATA_FACTORY_NAME] === 'function' ? classRef[METADATA_FACTORY_NAME]() : {}; if (propertyKey) return propsInPlugin[propertyKey]; return propsInPlugin; } export function getMetadata(classRef, propertyKey) { const propsInDecorator = getMetadataOfDecorator(classRef); const propsInPlugin = getMetadataOfPlugin(classRef); const metadataMap = R.mergeRight(propsInPlugin, propsInDecorator); if (propertyKey) return metadataMap[propertyKey]; return metadataMap; } /** * Set @ApiProperty() to all properties of the class. */ export function overridePluginMetadata(classRef, props) { classRef[METADATA_FACTORY_NAME] = () => props; } export function getMetadataType(metadata) { if (isFunction(metadata.type) && metadata.type.name === 'type') { return getMetadataType(metadata.type()); } else if (isFunction(metadata.type) && isBuiltInType(metadata.type)) { return metadata.type.name.toLowerCase(); } return metadata.type; }