@buka/nestjs-type-helper
Version:
An easy to use nestjs config module
62 lines (61 loc) • 2.69 kB
JavaScript
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;
}