meabed / graphql-upload-ts

Middleware and an Upload scalar to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers.
MIT License
42 stars 2 forks source link

type-graphql usage? #322

Open FezVrasta opened 2 months ago

FezVrasta commented 2 months ago

Hi, could you please provide an example to use your package with type-graphql?

When I try to use the GraphQLUpload directly I get:

Cannot determine GraphQL input type for 'image' of 'ContentCreateInput' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper input value?

Thanks!

wolflu05 commented 2 months ago

Hi, I was having the same problem today and figured it out by the help of this blog post. For a workaround I need to wrap it in a custom Scalar:

I use nestjs/graphql which internally uses the typegraphql package. There a custom scalar can be defined the following way:

import { Scalar } from '@nestjs/graphql';
import { GraphQLUpload } from 'graphql-upload-ts';

@Scalar('Upload')
export class UploadScalar {
  name = 'Upload';
  description = 'Upload files';

  parseValue(value) {
    return GraphQLUpload.parseValue(value);
  }

  serialize(value) {
    return GraphQLUpload.serialize(value);
  }

  parseLiteral(ast) {
    return GraphQLUpload.parseLiteral(ast, ast.value);
  }
}

(Do not forget to add this to the module providers array in nestjs)

If you're using the type-graphql package directly, the following should work too:

import { GraphQLScalarType } from 'graphql';
import { GraphQLUpload } from 'graphql-upload-ts';

const UploadScalar = new GraphQLScalarType({
  name: "Upload",
  description: "Upload files",

  parseValue: (value) => GraphQLUpload.parseValue(value),
  serialize: (value) => GraphQLUpload.serialize(value),
  parseLiteral: (ast) => GraphQLUpload.parseLiteral(ast, (ast as any).value),
})

Then I am able to just use this in an input type like this:

import { FileUpload } from 'graphql-upload-ts';

@InputType()
export class CreateFileInput {
  @Field(() => UploadScalar)
  file: Promise<FileUpload>;
}