@nestjs/graphql
Version:
Nest - modern, fast, powerful node.js web framework (@graphql)
56 lines (55 loc) • 2.62 kB
JavaScript
import { isFunction } from '@nestjs/common/utils/shared.utils.js';
import { inheritPropertyInitializers, inheritTransformationMetadata, inheritValidationMetadata, } from '@nestjs/mapped-types';
import { Field } from '../decorators/index.js';
import { MetadataLoader } from '../plugin/metadata-loader.js';
import { getFieldsAndDecoratorForType } from '../schema-builder/utils/get-fields-and-decorator.util.js';
import { applyFieldDecorators } from './type-helpers.utils.js';
export function IntersectionType(classARef, classBRef, decorator) {
const { decoratorFactory, fields: fieldsA } = getFieldsAndDecoratorForType(classARef);
const { fields: fieldsB } = getFieldsAndDecoratorForType(classBRef);
const fields = [...fieldsA, ...fieldsB];
class IntersectionObjectType {
constructor() {
inheritPropertyInitializers(this, classARef);
inheritPropertyInitializers(this, classBRef);
}
}
if (decorator) {
decorator({ isAbstract: true })(IntersectionObjectType);
}
else {
decoratorFactory({ isAbstract: true })(IntersectionObjectType);
}
inheritValidationMetadata(classARef, IntersectionObjectType);
inheritTransformationMetadata(classARef, IntersectionObjectType);
inheritValidationMetadata(classBRef, IntersectionObjectType);
inheritTransformationMetadata(classBRef, IntersectionObjectType);
function applyFields(fields) {
fields.forEach((item) => {
if (isFunction(item.typeFn)) {
// Execute type function eagerly to update the type options object (before "clone" operation)
// when the passed function (e.g., @Field(() => Type)) lazily returns an array.
item.typeFn();
}
Field(item.typeFn, { ...item.options })(IntersectionObjectType.prototype, item.name);
applyFieldDecorators(IntersectionObjectType, item);
});
}
applyFields(fields);
// Register a refresh hook to update the fields when the serialized metadata
// is loaded from file.
MetadataLoader.addRefreshHook(() => {
const { fields: fieldsA } = getFieldsAndDecoratorForType(classARef, {
overrideFields: true,
});
const { fields: fieldsB } = getFieldsAndDecoratorForType(classBRef, {
overrideFields: true,
});
const fields = [...fieldsA, ...fieldsB];
applyFields(fields);
});
Object.defineProperty(IntersectionObjectType, 'name', {
value: `Intersection${classARef.name}${classBRef.name}`,
});
return IntersectionObjectType;
}