UNPKG

@nestjs/graphql

Version:

Nest - modern, fast, powerful node.js web framework (@graphql)

99 lines (98 loc) 4.15 kB
import { isFunction, isObject, isString, } from '@nestjs/common/utils/shared.utils.js'; import 'reflect-metadata'; import { GqlParamtype } from '../enums/gql-paramtype.enum.js'; import { LazyMetadataStorage } from '../schema-builder/storages/lazy-metadata.storage.js'; import { TypeMetadataStorage } from '../schema-builder/storages/type-metadata.storage.js'; import { ARGS_TYPE_METADATA } from '../graphql.constants.js'; import { isPipe } from '../utils/is-pipe.util.js'; import { reflectTypeFromMetadata } from '../utils/reflection.utilts.js'; import { addPipesMetadata } from './param.utils.js'; /** * Resolver method parameter decorator. Extracts the arguments * object from the underlying platform and populates the decorated * parameter with the value of either all arguments or a single specified argument. * * @publicApi */ export function Args(propertyOrOptionsOrPipe, optionsOrPipe, ...pipes) { const [property, argOptions, argPipes] = getArgsOptions(propertyOrOptionsOrPipe, optionsOrPipe, pipes); return (target, key, index) => { addPipesMetadata(GqlParamtype.ARGS, property, argPipes, target, key, index); // Arguments arrive keyed by their schema names. Record what each parameter // expects so that the resolvers explorer can map them back to the property // names declared by the `@ArgsType()`/`@InputType()` class before any pipe // (global ones included) gets to see the value. const argsTypes = Reflect.getOwnMetadata(ARGS_TYPE_METADATA, target.constructor, key) ?? []; Reflect.defineMetadata(ARGS_TYPE_METADATA, argsTypes.concat({ index, property: isString(property) ? property : undefined, typeFn: argOptions.type, }), target.constructor, key); LazyMetadataStorage.store(target.constructor, () => { const { typeFn: reflectedTypeFn, options } = reflectTypeFromMetadata({ metadataKey: 'design:paramtypes', prototype: target, propertyKey: key, index: index, explicitTypeFn: argOptions.type, typeOptions: argOptions, }); const metadata = { target: target.constructor, methodName: key, typeFn: reflectedTypeFn, index, options, }; if (property && isString(property)) { TypeMetadataStorage.addMethodParamMetadata({ kind: 'arg', name: property, description: argOptions.description, deprecationReason: argOptions.deprecationReason, ...metadata, }); } else { TypeMetadataStorage.addMethodParamMetadata({ kind: 'args', ...metadata, }); } }); }; } function getArgsOptions(propertyOrOptionsOrPipe, optionsOrPipe, pipes) { if (!propertyOrOptionsOrPipe || isString(propertyOrOptionsOrPipe)) { const propertyKey = propertyOrOptionsOrPipe; let options = {}; let argPipes = []; if (isPipe(optionsOrPipe)) { argPipes = [optionsOrPipe].concat(pipes); } else { options = optionsOrPipe || {}; argPipes = pipes; } return [propertyKey, options, argPipes]; } const isArgsOptionsObject = isObject(propertyOrOptionsOrPipe) && !isFunction(propertyOrOptionsOrPipe.transform); if (isArgsOptionsObject) { const argOptions = propertyOrOptionsOrPipe; const propertyKey = argOptions.name; const argPipes = optionsOrPipe ? [optionsOrPipe].concat(pipes) : pipes; return [ propertyKey, argOptions, argPipes, ]; } // concatenate all pipes let argPipes = [propertyOrOptionsOrPipe]; if (optionsOrPipe) { argPipes = argPipes.concat(optionsOrPipe); } argPipes = argPipes.concat(pipes); return [undefined, {}, argPipes]; }