// @ts-check "use strict"; const defaultProcessRequest = require("./processRequest.js"); /** * Creates [Express](https://expressjs.com) middleware that processes incoming * [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec) * using {@linkcode processRequest}, ignoring non multipart requests. It sets * the request `body` to be similar to a conventional GraphQL POST request for * following GraphQL middleware to consume. * @param {import("./processRequest.js").ProcessRequestOptions & { * processRequest?: import("./processRequest.js").ProcessRequestFunction * }} options Options. * @returns Express middleware. * @example * Basic [`express-graphql`](https://npm.im/express-graphql) setup: * * ```js * const express = require("express"); * const graphqlHTTP = require("express-graphql"); * const graphqlUploadExpress = require("graphql-upload/graphqlUploadExpress.js"); * const schema = require("./schema.js"); * * express() * .use( * "/graphql", * graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }), * graphqlHTTP({ schema }) * ) * .listen(3000); * ``` */ function graphqlUploadExpress({ processRequest = defaultProcessRequest, ...processRequestOptions } = {}) { /** * [Express](https://expressjs.com) middleware that processes incoming * [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec) * using {@linkcode processRequest}, ignoring non multipart requests. It sets * the request `body` to be similar to a conventional GraphQL POST request for * following GraphQL middleware to consume. * @param {import("express").Request} request * @param {import("express").Response} response * @param {import("express").NextFunction} next */ function graphqlUploadExpressMiddleware(request, response, next) { if (!request.is("multipart/form-data")) return next(); const requestEnd = new Promise((resolve) => request.on("end", resolve)); const { send } = response; // @ts-ignore Todo: Find a less hacky way to prevent sending a response // before the request has ended. response.send = /** @param {Array} args */ (...args) => { requestEnd.then(() => { response.send = send; response.send(...args); }); }; processRequest(request, response, processRequestOptions) .then((body) => { request.body = body; next(); }) .catch((error) => { if (error.status && error.expose) response.status(error.status); next(error); }); } return graphqlUploadExpressMiddleware; } module.exports = graphqlUploadExpress;