graphqlUploadKoa.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // @ts-check
  2. "use strict";
  3. const defaultProcessRequest = require("./processRequest.js");
  4. /**
  5. * Creates [Koa](https://koajs.com) middleware that processes incoming
  6. * [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec)
  7. * using {@linkcode processRequest}, ignoring non multipart requests. It sets
  8. * the request `body` to be similar to a conventional GraphQL POST request for
  9. * following GraphQL middleware to consume.
  10. * @param {import("./processRequest.js").ProcessRequestOptions & {
  11. * processRequest?: import("./processRequest.js").ProcessRequestFunction
  12. * }} options Options.
  13. * @returns Koa middleware.
  14. * @example
  15. * Basic [`graphql-api-koa`](https://npm.im/graphql-api-koa) setup:
  16. *
  17. * ```js
  18. * const Koa = require("koa");
  19. * const bodyParser = require("koa-bodyparser");
  20. * const { errorHandler, execute } = require("graphql-api-koa");
  21. * const graphqlUploadKoa = require("graphql-upload/graphqlUploadKoa.js");
  22. * const schema = require("./schema.js");
  23. *
  24. * new Koa()
  25. * .use(errorHandler())
  26. * .use(bodyParser())
  27. * .use(graphqlUploadKoa({ maxFileSize: 10000000, maxFiles: 10 }))
  28. * .use(execute({ schema }))
  29. * .listen(3000);
  30. * ```
  31. */
  32. function graphqlUploadKoa({
  33. processRequest = defaultProcessRequest,
  34. ...processRequestOptions
  35. } = {}) {
  36. /**
  37. * [Koa](https://koajs.com) middleware that processes incoming
  38. * [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec)
  39. * using {@linkcode processRequest}, ignoring non multipart requests. It sets
  40. * the request `body` to be similar to a conventional GraphQL POST request for
  41. * following GraphQL middleware to consume.
  42. * @param {import("koa").ParameterizedContext} ctx
  43. * @param {() => Promise<unknown>} next
  44. */
  45. async function graphqlUploadKoaMiddleware(ctx, next) {
  46. if (!ctx.request.is("multipart/form-data")) return next();
  47. const requestEnd = new Promise((resolve) => ctx.req.on("end", resolve));
  48. try {
  49. // @ts-ignore This is conventional.
  50. ctx.request.body = await processRequest(
  51. ctx.req,
  52. ctx.res,
  53. processRequestOptions
  54. );
  55. await next();
  56. } finally {
  57. await requestEnd;
  58. }
  59. }
  60. return graphqlUploadKoaMiddleware;
  61. }
  62. module.exports = graphqlUploadKoa;