@nestjs/graphql
Version:
Nest - modern, fast, powerful node.js web framework (@graphql)
65 lines (64 loc) • 2.99 kB
JavaScript
/**
* The API surface of this module has been heavily inspired by the "type-graphql" library (https://github.com/MichalLytek/type-graphql), originally designed & released by Michal Lytek.
* In the v6 major release of NestJS, we introduced the code-first approach as a compatibility layer between this package and the `@nestjs/graphql` module.
* Eventually, our team decided to reimplement all the features from scratch due to a lack of flexibility.
* To avoid numerous breaking changes, the public API is backward-compatible and may resemble "type-graphql".
*/
import { isFunction } from '@nestjs/common/utils/shared.utils.js';
import { LazyMetadataStorage } from '../schema-builder/storages/lazy-metadata.storage.js';
import { TypeMetadataStorage } from '../schema-builder/storages/type-metadata.storage.js';
import { reflectTypeFromMetadata } from '../utils/reflection.utilts.js';
/**
* @Field() decorator is used to mark a specific class property as a GraphQL field.
* Only properties decorated with this decorator will be defined in the schema.
*
* @publicApi
*/
export function Field(typeOrOptions, fieldOptions) {
return (prototype, propertyKey, descriptor) => {
addFieldMetadata(typeOrOptions, fieldOptions, prototype, propertyKey, descriptor);
};
}
export function addFieldMetadata(typeOrOptions, fieldOptions, prototype, propertyKey, descriptor, loadEagerly) {
const [typeFunc, options = {}] = isFunction(typeOrOptions)
? [typeOrOptions, fieldOptions]
: [undefined, typeOrOptions];
const applyMetadataFn = () => {
const isResolver = !!descriptor;
const isResolverMethod = !!(descriptor && descriptor.value);
const { typeFn: getType, options: typeOptions } = reflectTypeFromMetadata({
metadataKey: isResolverMethod ? 'design:returntype' : 'design:type',
prototype,
propertyKey,
explicitTypeFn: typeFunc,
typeOptions: options,
ignoreOnUndefinedType: loadEagerly,
});
TypeMetadataStorage.addClassFieldMetadata({
name: propertyKey,
schemaName: options.name || propertyKey,
typeFn: getType,
options: typeOptions,
target: prototype.constructor,
description: options.description,
deprecationReason: options.deprecationReason,
complexity: options.complexity,
middleware: options.middleware,
});
if (isResolver) {
TypeMetadataStorage.addResolverPropertyMetadata({
kind: 'internal',
methodName: propertyKey,
schemaName: options.name || propertyKey,
target: prototype.constructor,
complexity: options.complexity,
});
}
};
if (loadEagerly) {
applyMetadataFn();
}
else {
LazyMetadataStorage.store(prototype.constructor, applyMetadataFn, { isField: true });
}
}