Предоставить поддержку для проверки по необязательному параметру с использованием класса-валидатора в Nest JS и GraphQL? - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть input для обновления блока. Я хочу, чтобы пользователи могли обновлять имя или контент или и то, и другое. Теперь проблема в том, что если я передаю только имя GrapQL, выдается ошибка типа Variable \"$updateBlockInput\" got invalid value { name: \"Updated again\" }; Field content of required type String! was not provided. и Vice Varsa.

Что я делаю не так?


update-block.input.ts

import { InputType, Field } from '@nestjs/graphql';
import { IsOptional, IsNotEmpty } from 'class-validator';

@InputType()
export class UpdateBlockInput {
  @IsOptional()
  @IsNotEmpty()
  @Field()
  name?: string;

  @IsOptional()
  @IsNotEmpty()
  @Field()
  content?: string;
}

block.resolver.ts

...
@Mutation(returns => BlockType)
updateBlock(
  @Args('id') id: string,
  @Args('updateBlockInput') updateBlockInput: UpdateBlockInput,
) {
  return this.blockService.update(id, updateBlockInput);
}
...

Мутация

mutation(
  $id: String!
  $updateBlockInput: UpdateBlockInput!
) {
  updateBlock(
    id: $id
    updateBlockInput: $updateBlockInput
  ) {
    name
    content
  }
}

Переменные

{
  "id": "087e7c12-b48f-4ac4-ae76-1b9a96bbcbdc",
  "updateBlockInput": {
    "name": "Updated again"
  }
}

1 Ответ

1 голос
/ 08 апреля 2020

если они являются необязательными, вам нужно избегать IsNotEmpty и заменить на IsString, чтобы сказать, что если значение присутствует, оно должно быть только строкового типа.

Если вы хотите принять либо и сбой при отправке non, вам нужно написать собственный пользовательский валидатор, потому что этот случай не поддерживается "из коробки".

пример:

import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
@ValidatorConstraint({async: false})
export class IsInPast implements ValidatorConstraintInterface {
    public validate(value: unknown): boolean {
        if (typeof value !== 'string' && typeof value !== 'number') {
            return false;
        }
        const now = new Date();
        now.setHours(23);
        now.setMinutes(59);
        now.setSeconds(59);
        now.setMilliseconds(999);
        return `${value}`.match(/^\d+$/) !== null && `${value}` <= `${now.getTime()}`;
    }

    public defaultMessage(): string {
        return 'Should be in past';
    }
}

и позже где-нибудь в коде :

@Validate(IsInPast)
public dateField: string;
...