16

I am trying to use Apollo Server's Upload scalar to send files to S3 directly. My schema:

const { gql } = require('apollo-server-express')

module.exports = gql`

extend type Mutation {
  createPicture(
    name: String!
    picture: Upload!
  ): Picture!
}

type Picture {
  name: String!
  picture: String!
}
`

Resolver:

const { combineResolvers } = require('graphql-resolvers')
const isAuthenticated = require('./auth')
const { uploadPhoto } = require('../services/picture')

module.exports = {
  Mutation: {
    createPicture: combineResolvers(
      isAuthenticated,
      async (
        parent,
        { name, picture = null },
        { models, me }
      ) => {
        const { createReadStream, filename, mimetype, encoding } = await picture
        // Does not get past this line
        const stream = createReadStream()

        uploadPhoto(stream, filename)

        const pictureModel = models.Picture.create({
           name,
           picture
        })
        return pictureModel
      }
    )
  }
}

But my code errors like this:

internal/util.js:55
  function deprecated(...args) {
                     ^

RangeError: Maximum call stack size exceeded
    at ReadStream.deprecated [as open] (internal/util.js:55:22)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:123:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
    at ReadStream.deprecated [as open] (internal/util.js:70:15)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:123:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
    at ReadStream.deprecated [as open] (internal/util.js:70:15)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:123:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
    at ReadStream.deprecated [as open] (internal/util.js:70:15)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:123:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
    at ReadStream.deprecated [as open] (internal/util.js:70:15)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:123:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
    at ReadStream.deprecated [as open] (internal/util.js:70:15)
    at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)

Note: I am sure the image was sent correctly, as filename is correct

W. Reyna
  • 594
  • 5
  • 19

7 Answers7

10

Turns out it was this bug in graphql-upload. Downgraded to node 12 and it's fixed (solution listed there did not help me)

W. Reyna
  • 594
  • 5
  • 19
10

Add this to package.json:

"resolutions": {
    "**/**/fs-capacitor":"^6.2.0",
    "**/graphql-upload": "^11.0.0"
  }

source: https://github.com/jaydenseric/graphql-upload/issues/170#issuecomment-641938198

Meursault
  • 166
  • 2
  • 7
4

This error occured to me in node version 14 too! I solved it as follows:

  1. Install latest version of graphql-upload !

  2. use graphqlUploadExpress middleware to define the maximum file limit.

    import { graphqlUploadExpress } from "graphql-upload";
    const app = express()
    app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
    
  3. Set uploads to false while initializing the ApolloServer

      const server = new ApolloServer({
        uploads: false,
        schema,
      });
    
  • could you explain why we need to set the uploads to false? why does the OP need to install a separate library for this to work now? – Johhan Santana Jan 08 '21 at 20:38
  • 1
    @JohhanSantana Apollo server bundles inside a clone of graphql-upload that is broken on Node 14. To use the newer fixed graphql-upload package you need to tell apollo not to use it's bundled one. and then use it yourself by registering the body handler with express and adding the upload schema stuff. – Tamir Daniely Feb 28 '21 at 08:14
  • This answer is really the correct one, just remember to call `app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));` before applying Apollo sever middleware. – Marek Piechut Mar 30 '21 at 11:25
  • Hi dude.I did this but now I'm getting another error: "message": "args.file.then is not a function", Here is my code: const singleUpload = (parent, args) => { return args.file.then((file) => { const { createReadStream, filename } = file const fileStream = createReadStream() fileStream.pipe(fs.createWriteStream(`../../assets/img/grid/${filename}`)) return file }) } – Juliano Costa Apr 22 '21 at 13:38
2

Add this to your package.json

 "resolutions": {
    "graphql-upload": "^11.0.0"
  }

then add this inside scripts

"scripts": {
    ....
    "preinstall": "npx npm-force-resolutions", //This one
    ....
}

then you need to do npm install. Done

Source: graphql-upload

pranav shinde
  • 352
  • 2
  • 7
2

Since it is a bug with fs-capacitor, this would help as we can see in this issue

Worked for me in node 14.16.1 with the following configuration:

"resolutions": {
    "fs-capacitor": "^6.2.0",
    "graphql-upload": "^11.0.0"
}

I needed to add force-resolutions inside "scripts"

"scripts": {
    ....
    "preinstall": "npx npm-force-resolutions"
}

Remove ./node_modules and install dependencies again with npm install.

Everton Castro
  • 119
  • 1
  • 8
0

I've been dealing with this problem multiple times

the problem is old graphql-upload more accurately version 8 uses of node open stream function which is deprecated and no longer available in 13.x and older node versions.

so the solution is you can either use nvm to set your node version to 12 or use resolutions in your package.json file. first solution(in your favorite terminal):

nvm install 12; nvm use 12

second solution(in package.json):

"resolutions": {
    "**/**/fs-capacitor":"^6.2.0",
    "**/graphql-upload": "^11.0.0"
  }

also this is a problem I've been dealing with for months and apollo team really doesn't like updating their dependencies I think.

DevAddict
  • 43
  • 2
  • 7
-2

Using:

    "apollo-server": "^2.18.2",
    "apollo-server-express": "2.18.2",
    "aws-sdk": "^2.771.0",
    "express-fileupload": "^1.2.0",
    "graphql": "^15.3.0",
    "graphql-upload": "^11.0.0",
    "fs-capacitor": "^6.2.0",

I solve this by installing the latest fs-capacitor as a dependency

yarn add fs-capacitor
msroot
  • 781
  • 10
  • 13