graphql-upload
Advanced tools
Comparing version 8.0.7 to 8.1.0
# graphql-upload changelog | ||
## 8.1.0 | ||
### Minor | ||
- `processRequest` now throws an appropriate error when a multipart field value exceeds the configured size limit, fixing [#159](https://github.com/jaydenseric/graphql-upload/issues/159). | ||
- When the file size limit is exceeded, mention how many bytes the limit is in the stream error message. | ||
- Added a new `processRequest` option to the `graphqlUploadExpress` and `graphqlUploadKoa` middleware, for improved testing without mocks or spies which are difficult to achieve with ESM. | ||
### Patch | ||
- Updated dependencies. | ||
- Due to updated dependencies: Lint fixes, removed redundant `eslint-disable-next-line` comments, and regenerated the readme. | ||
- Documented [`koa-graphql`](https://npm.im/koa-graphql) as known to be compatible, via [#156](https://github.com/jaydenseric/graphql-upload/pull/156). | ||
- Fixed a readme typo, via [#161](https://github.com/jaydenseric/graphql-upload/pull/161). | ||
- Use GitHub Actions instead of Travis for CI. | ||
- Removed `package-lock.json` from `.gitignore` and `.prettierignore`, as it’s disabled in `.npmrc` anyway. | ||
- New file structure. | ||
- Explicitly defined main exports (instead of using `export * from`) to prevent accidental public exposure of internal APIs. | ||
- Moved JSDoc typedefs into the index main entry file, alphabetically sorted. | ||
- Nicer Browserslist query syntax. | ||
- Replaced the `isObject` helper with a smarter and tested `isEnumerableObject`. | ||
- Removed the `isString` helper. | ||
- Enforced 100% code coverage for tests, and improved `processRequest` internals and tests (including a new test using vanilla Node.js HTTP), fixing [#130](https://github.com/jaydenseric/graphql-upload/issues/130) via [#162](https://github.com/jaydenseric/graphql-upload/pull/162). | ||
- Removed a workaround from the `startServer` test helper. | ||
- Added a new `ProcessRequestFunction` JSDoc type, and applied it to `processRequest`. | ||
- Renamed the `UploadOptions` JSDoc type to `ProcessRequestOptions`. | ||
- Misc. documentation improvements. | ||
## 8.0.7 | ||
@@ -4,0 +32,0 @@ |
@@ -8,3 +8,6 @@ 'use strict' | ||
const graphqlUploadExpress = options => (request, response, next) => { | ||
const graphqlUploadExpress = ({ | ||
processRequest = _processRequest.processRequest, | ||
...processRequestOptions | ||
} = {}) => (request, response, next) => { | ||
if (!request.is('multipart/form-data')) return next() | ||
@@ -21,3 +24,3 @@ const finished = new Promise(resolve => request.on('end', resolve)) | ||
;(0, _processRequest.processRequest)(request, response, options) | ||
processRequest(request, response, processRequestOptions) | ||
.then(body => { | ||
@@ -24,0 +27,0 @@ request.body = body |
@@ -8,3 +8,6 @@ 'use strict' | ||
const graphqlUploadKoa = options => async (ctx, next) => { | ||
const graphqlUploadKoa = ({ | ||
processRequest = _processRequest.processRequest, | ||
...processRequestOptions | ||
} = {}) => async (ctx, next) => { | ||
if (!ctx.request.is('multipart/form-data')) return next() | ||
@@ -14,6 +17,6 @@ const finished = new Promise(resolve => ctx.req.on('end', resolve)) | ||
try { | ||
ctx.request.body = await (0, _processRequest.processRequest)( | ||
ctx.request.body = await processRequest( | ||
ctx.req, | ||
ctx.res, | ||
options | ||
processRequestOptions | ||
) | ||
@@ -20,0 +23,0 @@ await next() |
'use strict' | ||
exports.__esModule = true | ||
exports.graphqlUploadExpress = exports.graphqlUploadKoa = exports.processRequest = exports.GraphQLUpload = void 0 | ||
var _GraphQLUpload = require('./GraphQLUpload') | ||
Object.keys(_GraphQLUpload).forEach(function(key) { | ||
if (key === 'default' || key === '__esModule') return | ||
exports[key] = _GraphQLUpload[key] | ||
}) | ||
exports.GraphQLUpload = _GraphQLUpload.GraphQLUpload | ||
var _processRequest = require('./processRequest') | ||
Object.keys(_processRequest).forEach(function(key) { | ||
if (key === 'default' || key === '__esModule') return | ||
exports[key] = _processRequest[key] | ||
}) | ||
exports.processRequest = _processRequest.processRequest | ||
var _graphqlUploadKoa = require('./graphqlUploadKoa') | ||
Object.keys(_graphqlUploadKoa).forEach(function(key) { | ||
if (key === 'default' || key === '__esModule') return | ||
exports[key] = _graphqlUploadKoa[key] | ||
}) | ||
exports.graphqlUploadKoa = _graphqlUploadKoa.graphqlUploadKoa | ||
var _graphqlUploadExpress = require('./graphqlUploadExpress') | ||
Object.keys(_graphqlUploadExpress).forEach(function(key) { | ||
if (key === 'default' || key === '__esModule') return | ||
exports[key] = _graphqlUploadExpress[key] | ||
}) | ||
exports.graphqlUploadExpress = _graphqlUploadExpress.graphqlUploadExpress |
@@ -16,15 +16,11 @@ 'use strict' | ||
function _interopRequireDefault(obj) { | ||
return obj && obj.__esModule ? obj : { default: obj } | ||
} | ||
var _constants = require('./constants') | ||
const SPEC_URL = 'https://github.com/jaydenseric/graphql-multipart-request-spec' | ||
var _ignoreStream = require('./ignoreStream') | ||
const isObject = value => value && value.constructor === Object | ||
var _isEnumerableObject = require('./isEnumerableObject') | ||
const isString = value => typeof value === 'string' || value instanceof String | ||
const ignoreStream = stream => { | ||
stream.on('error', () => {}) | ||
stream.resume() | ||
// istanbul ignore next | ||
function _interopRequireDefault(obj) { | ||
return obj && obj.__esModule ? obj : { default: obj } | ||
} | ||
@@ -52,4 +48,3 @@ | ||
new Promise((resolve, reject) => { | ||
let requestEnded = false | ||
let released = false | ||
let released | ||
let exitError | ||
@@ -86,2 +81,3 @@ let currentStream | ||
const release = () => { | ||
// istanbul ignore next | ||
if (released) return | ||
@@ -94,105 +90,127 @@ released = true | ||
parser.on('field', (fieldName, value) => { | ||
if (exitError) return | ||
const abort = () => { | ||
exit( | ||
(0, _httpErrors.default)( | ||
499, | ||
'Request disconnected during file upload stream parsing.' | ||
) | ||
) | ||
} | ||
switch (fieldName) { | ||
case 'operations': | ||
try { | ||
operations = JSON.parse(value) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid JSON in the ‘operations’ multipart field (${SPEC_URL}).` | ||
) | ||
parser.on( | ||
'field', | ||
(fieldName, value, fieldNameTruncated, valueTruncated) => { | ||
if (exitError) return | ||
if (valueTruncated) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
413, | ||
`The ‘${fieldName}’ multipart field value exceeds the ${maxFieldSize} byte size limit.` | ||
) | ||
} | ||
) | ||
if (!isObject(operations) && !Array.isArray(operations)) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘operations’ multipart field (${SPEC_URL}).` | ||
switch (fieldName) { | ||
case 'operations': | ||
try { | ||
operations = JSON.parse(value) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid JSON in the ‘operations’ multipart field (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
} | ||
if ( | ||
!(0, _isEnumerableObject.isEnumerableObject)(operations) && | ||
!Array.isArray(operations) | ||
) | ||
operationsPath = (0, _objectPath.default)(operations) | ||
break | ||
case 'map': { | ||
if (!operations) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Misordered multipart fields; ‘map’ should follow ‘operations’ (${SPEC_URL}).` | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘operations’ multipart field (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
) | ||
let parsedMap | ||
operationsPath = (0, _objectPath.default)(operations) | ||
break | ||
try { | ||
parsedMap = JSON.parse(value) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid JSON in the ‘map’ multipart field (${SPEC_URL}).` | ||
case 'map': { | ||
if (!operations) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Misordered multipart fields; ‘map’ should follow ‘operations’ (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
) | ||
} | ||
let parsedMap | ||
if (!isObject(parsedMap)) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘map’ multipart field (${SPEC_URL}).` | ||
try { | ||
parsedMap = JSON.parse(value) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid JSON in the ‘map’ multipart field (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
) | ||
const mapEntries = Object.entries(parsedMap) | ||
if (mapEntries.length > maxFiles) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
413, | ||
`${maxFiles} max file uploads exceeded.` | ||
) | ||
) | ||
map = new Map() | ||
} | ||
for (const [fieldName, paths] of mapEntries) { | ||
if (!Array.isArray(paths)) | ||
if (!(0, _isEnumerableObject.isEnumerableObject)(parsedMap)) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘map’ multipart field entry key ‘${fieldName}’ array (${SPEC_URL}).` | ||
`Invalid type for the ‘map’ multipart field (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
map.set(fieldName, new Upload()) | ||
const mapEntries = Object.entries(parsedMap) | ||
if (mapEntries.length > maxFiles) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
413, | ||
`${maxFiles} max file uploads exceeded.` | ||
) | ||
) | ||
map = new Map() | ||
for (const [index, path] of paths.entries()) { | ||
if (!isString(path)) | ||
for (const [fieldName, paths] of mapEntries) { | ||
if (!Array.isArray(paths)) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘map’ multipart field entry key ‘${fieldName}’ array index ‘${index}’ value (${SPEC_URL}).` | ||
`Invalid type for the ‘map’ multipart field entry key ‘${fieldName}’ array (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
map.set(fieldName, new Upload()) | ||
try { | ||
operationsPath.set(path, map.get(fieldName).promise) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid object path for the ‘map’ multipart field entry key ‘${fieldName}’ array index ‘${index}’ value ‘${path}’ (${SPEC_URL}).` | ||
for (const [index, path] of paths.entries()) { | ||
if (typeof path !== 'string') | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid type for the ‘map’ multipart field entry key ‘${fieldName}’ array index ‘${index}’ value (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
) | ||
try { | ||
operationsPath.set(path, map.get(fieldName).promise) | ||
} catch (error) { | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Invalid object path for the ‘map’ multipart field entry key ‘${fieldName}’ array index ‘${index}’ value ‘${path}’ (${_constants.SPEC_URL}).` | ||
) | ||
) | ||
} | ||
} | ||
} | ||
resolve(operations) | ||
} | ||
resolve(operations) | ||
} | ||
} | ||
}) | ||
) | ||
parser.on('file', (fieldName, stream, filename, encoding, mimetype) => { | ||
if (exitError) { | ||
ignoreStream(stream) | ||
;(0, _ignoreStream.ignoreStream)(stream) | ||
return | ||
@@ -202,7 +220,7 @@ } | ||
if (!map) { | ||
ignoreStream(stream) | ||
;(0, _ignoreStream.ignoreStream)(stream) | ||
return exit( | ||
(0, _httpErrors.default)( | ||
400, | ||
`Misordered multipart fields; files should follow ‘map’ (${SPEC_URL}).` | ||
`Misordered multipart fields; files should follow ‘map’ (${_constants.SPEC_URL}).` | ||
) | ||
@@ -214,3 +232,3 @@ ) | ||
stream.on('end', () => { | ||
if (currentStream === stream) currentStream = null | ||
currentStream = null | ||
}) | ||
@@ -220,3 +238,3 @@ const upload = map.get(fieldName) | ||
if (!upload) { | ||
ignoreStream(stream) | ||
;(0, _ignoreStream.ignoreStream)(stream) | ||
return | ||
@@ -231,3 +249,2 @@ } | ||
stream.on('limit', () => { | ||
if (currentStream === stream) currentStream = null | ||
stream.unpipe() | ||
@@ -237,3 +254,3 @@ capacitor.destroy( | ||
413, | ||
'File truncated as it exceeds the size limit.' | ||
`File truncated as it exceeds the ${maxFileSize} byte size limit.` | ||
) | ||
@@ -243,4 +260,4 @@ ) | ||
stream.on('error', error => { | ||
if (currentStream === stream) currentStream = null | ||
stream.unpipe() | ||
stream.unpipe() // istanbul ignore next | ||
capacitor.destroy(exitError || error) | ||
@@ -284,3 +301,3 @@ }) | ||
400, | ||
`Missing multipart field ‘operations’ (${SPEC_URL}).` | ||
`Missing multipart field ‘operations’ (${_constants.SPEC_URL}).` | ||
) | ||
@@ -292,3 +309,3 @@ ) | ||
400, | ||
`Missing multipart field ‘map’ (${SPEC_URL}).` | ||
`Missing multipart field ‘map’ (${_constants.SPEC_URL}).` | ||
) | ||
@@ -306,14 +323,6 @@ ) | ||
response.once('close', release) | ||
request.once('close', abort) | ||
request.once('end', () => { | ||
requestEnded = true | ||
request.removeListener('close', abort) | ||
}) | ||
request.once('close', () => { | ||
if (!requestEnded) | ||
exit( | ||
(0, _httpErrors.default)( | ||
499, | ||
'Request disconnected during file upload stream parsing.' | ||
) | ||
) | ||
}) | ||
request.pipe(parser) | ||
@@ -320,0 +329,0 @@ }) |
{ | ||
"name": "graphql-upload", | ||
"version": "8.0.7", | ||
"version": "8.1.0", | ||
"description": "Middleware and an Upload scalar to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers.", | ||
@@ -28,3 +28,4 @@ "license": "MIT", | ||
"lib", | ||
"!lib/test.*" | ||
"!*.test.*", | ||
"!test-helpers" | ||
], | ||
@@ -35,3 +36,3 @@ "main": "lib", | ||
}, | ||
"browserslist": "node 8.5", | ||
"browserslist": "node >= 8.5", | ||
"peerDependencies": { | ||
@@ -43,28 +44,29 @@ "graphql": "0.13.1 - 14" | ||
"fs-capacitor": "^2.0.4", | ||
"http-errors": "^1.7.2", | ||
"http-errors": "^1.7.3", | ||
"object-path": "^0.11.4" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.4.4", | ||
"@babel/core": "^7.4.5", | ||
"@babel/preset-env": "^7.4.5", | ||
"babel-eslint": "^10.0.1", | ||
"eslint": "^5.16.0", | ||
"eslint-config-env": "^6.0.0", | ||
"eslint-config-prettier": "^4.3.0", | ||
"eslint-plugin-import": "^2.17.3", | ||
"eslint-plugin-import-order-alphabetical": "^0.0.2", | ||
"eslint-plugin-node": "^9.1.0", | ||
"eslint-plugin-prettier": "^3.1.0", | ||
"@babel/cli": "^7.6.3", | ||
"@babel/core": "^7.6.3", | ||
"@babel/preset-env": "^7.6.3", | ||
"babel-eslint": "^10.0.3", | ||
"eslint": "^6.5.1", | ||
"eslint-config-env": "^9.1.0", | ||
"eslint-config-prettier": "^6.4.0", | ||
"eslint-plugin-import": "^2.18.2", | ||
"eslint-plugin-import-order-alphabetical": "^1.0.0", | ||
"eslint-plugin-jsdoc": "^15.9.10", | ||
"eslint-plugin-node": "^10.0.0", | ||
"eslint-plugin-prettier": "^3.1.1", | ||
"express": "^4.17.1", | ||
"express-async-handler": "^1.1.4", | ||
"form-data": "^2.3.3", | ||
"graphql": "^14.3.1", | ||
"husky": "^2.4.1", | ||
"jsdoc-md": "^3.0.0", | ||
"koa": "^2.7.0", | ||
"lint-staged": "^8.2.0", | ||
"form-data": "^2.5.1", | ||
"graphql": "^14.5.8", | ||
"husky": "^3.0.8", | ||
"jsdoc-md": "^4.0.1", | ||
"koa": "^2.8.2", | ||
"lint-staged": "^9.4.2", | ||
"node-fetch": "^2.6.0", | ||
"prettier": "^1.18.2", | ||
"tap": "^14.2.2" | ||
"tap": "^14.6.9" | ||
}, | ||
@@ -78,9 +80,8 @@ "scripts": { | ||
"prepare:prettier": "prettier 'lib/**/*.{mjs,js}' readme.md --write", | ||
"test": "npm run test:eslint && npm run test:prettier && npm run test:mjs && npm run test:js", | ||
"test": "npm run test:eslint && npm run test:prettier && npm run test:tap", | ||
"test:eslint": "eslint . --ext mjs,js", | ||
"test:prettier": "prettier '**/*.{json,yml,md}' -l", | ||
"test:mjs": "node --experimental-modules --no-warnings lib/test | tap-mocha-reporter classic", | ||
"test:js": "node lib/test | tap-mocha-reporter classic", | ||
"test:tap": "tap --test-ignore=src --100", | ||
"prepublishOnly": "npm test" | ||
} | ||
} |
@@ -5,3 +5,3 @@ ![graphql-upload logo](https://cdn.jsdelivr.net/gh/jaydenseric/graphql-upload@8.0.0/graphql-upload-logo.svg) | ||
[![npm version](https://badgen.net/npm/v/graphql-upload)](https://npm.im/graphql-upload) [![Build status](https://travis-ci.org/jaydenseric/graphql-upload.svg?branch=master)](https://travis-ci.org/jaydenseric/graphql-upload) | ||
[![npm version](https://badgen.net/npm/v/graphql-upload)](https://npm.im/graphql-upload) [![CI status](https://github.com/jaydenseric/graphql-upload/workflows/CI/badge.svg)](https://github.com/jaydenseric/graphql-upload/actions) | ||
@@ -21,2 +21,3 @@ Middleware and an [`Upload` scalar](#class-graphqlupload) to add support for [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec) (file uploads via queries and mutations) to various Node.js GraphQL servers. | ||
- [`graphql-api-koa`](https://npm.im/graphql-api-koa) | ||
- [`koa-graphql`](https://npm.im/koa-graphql) | ||
- [`apollo-server-koa`](https://npm.im/apollo-server-koa) (inbuilt) | ||
@@ -72,13 +73,9 @@ - [Express](https://expressjs.com) | ||
- [class GraphQLUpload](#class-graphqlupload) | ||
- [Examples](#examples) | ||
- [function graphqlUploadExpress](#function-graphqluploadexpress) | ||
- [Examples](#examples-1) | ||
- [function graphqlUploadKoa](#function-graphqluploadkoa) | ||
- [Examples](#examples-2) | ||
- [function processRequest](#function-processrequest) | ||
- [Examples](#examples-3) | ||
- [type FileUpload](#type-fileupload) | ||
- [type GraphQLOperation](#type-graphqloperation) | ||
- [See](#see) | ||
- [type UploadOptions](#type-uploadoptions) | ||
- [type ProcessRequestFunction](#type-processrequestfunction) | ||
- [type ProcessRequestOptions](#type-processrequestoptions) | ||
@@ -143,9 +140,10 @@ ### class GraphQLUpload | ||
Creates [Express](https://expressjs.com) middleware that processes GraphQL multipart requests using [`processRequest`](#function-processrequest), ignoring non-multipart requests. It sets the request body to be [similar to a conventional GraphQL POST request](#type-graphqloperation) for following GraphQL middleware to consume. | ||
Creates [Express](https://expressjs.com) middleware that processes [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec) using [`processRequest`](#function-processrequest), ignoring non-multipart requests. It sets the request body to be [similar to a conventional GraphQL POST request](#type-graphqloperation) for following GraphQL middleware to consume. | ||
| Parameter | Type | Description | | ||
| :-------- | :----------------------------------- | :---------------------- | | ||
| `options` | [UploadOptions](#type-uploadoptions) | GraphQL upload options. | | ||
| Parameter | Type | Description | | ||
| :-- | :-- | :-- | | ||
| `options` | [ProcessRequestOptions](#type-processrequestoptions) | Middleware options. Any [`ProcessRequestOptions`](#type-processrequestoptions) can be used. | | ||
| `options.processRequest` | [ProcessRequestFunction](#type-processrequestfunction)? = [processRequest](#function-processrequest) | Used to process [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec). | | ||
**Returns:** function — Express middleware. | ||
**Returns:** Function — Express middleware. | ||
@@ -175,9 +173,10 @@ #### Examples | ||
Creates [Koa](https://koajs.com) middleware that processes GraphQL multipart requests using [`processRequest`](#function-processrequest), ignoring non-multipart requests. It sets the request body to be [similar to a conventional GraphQL POST request](#type-graphqloperation) for following GraphQL middleware to consume. | ||
Creates [Koa](https://koajs.com) middleware that processes [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec) using [`processRequest`](#function-processrequest), ignoring non-multipart requests. It sets the request body to be [similar to a conventional GraphQL POST request](#type-graphqloperation) for following GraphQL middleware to consume. | ||
| Parameter | Type | Description | | ||
| :-------- | :----------------------------------- | :---------------------- | | ||
| `options` | [UploadOptions](#type-uploadoptions) | GraphQL upload options. | | ||
| Parameter | Type | Description | | ||
| :-- | :-- | :-- | | ||
| `options` | [ProcessRequestOptions](#type-processrequestoptions) | Middleware options. Any [`ProcessRequestOptions`](#type-processrequestoptions) can be used. | | ||
| `options.processRequest` | [ProcessRequestFunction](#type-processrequestfunction)? = [processRequest](#function-processrequest) | Used to process [GraphQL multipart requests](https://github.com/jaydenseric/graphql-multipart-request-spec). | | ||
**Returns:** function — Koa middleware. | ||
**Returns:** Function — Koa middleware. | ||
@@ -207,12 +206,6 @@ #### Examples | ||
Processes a [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec). Used in [`graphqlUploadKoa`](#function-graphqluploadkoa) and [`graphqlUploadExpress`](#function-graphqluploadexpress) and can be used to create custom middleware. | ||
Processes a [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec). Errors are created with [`http-errors`](https://npm.im/http-errors) to assist in sending responses with appropriate HTTP status codes. Used in [`graphqlUploadExpress`](#function-graphqluploadexpress) and [`graphqlUploadKoa`](#function-graphqluploadkoa) and can be used to create custom middleware. | ||
| Parameter | Type | Description | | ||
| :-- | :-- | :-- | | ||
| `request` | IncomingMessage | [Node.js HTTP server request instance](https://nodejs.org/api/http.html#http_class_http_incomingmessage). | | ||
| `response` | ServerResponse | [Node.js HTTP server response instance](https://nodejs.org/api/http.html#http_class_http_serverresponse). | | ||
| `options` | [UploadOptions](#type-uploadoptions)? | GraphQL upload options. | | ||
**Type:** [ProcessRequestFunction](#type-processrequestfunction) | ||
**Returns:** Promise<[GraphQLOperation](#type-graphqloperation) | Array<[GraphQLOperation](#type-graphqloperation)>> — GraphQL operation or batch of operations for a GraphQL server to consume (usually as the request body). | ||
#### Examples | ||
@@ -232,3 +225,3 @@ | ||
**Type:** Object | ||
**Type:** object | ||
@@ -240,3 +233,3 @@ | Property | Type | Description | | ||
| `encoding` | string | File stream transfer encoding. | | ||
| `createReadStream` | function | Returns a Node.js readable stream of the file contents, for processing and storing the file. Multiple calls create independent streams. Throws if called after all resolvers have resolved, or after an error has interrupted the request. | | ||
| `createReadStream` | Function | Returns a Node.js readable stream of the file contents, for processing and storing the file. Multiple calls create independent streams. Throws if called after all resolvers have resolved, or after an error has interrupted the request. | | ||
@@ -249,3 +242,3 @@ --- | ||
**Type:** Object | ||
**Type:** object | ||
@@ -255,4 +248,4 @@ | Property | Type | Description | | ||
| `query` | string | GraphQL document containing queries and fragments. | | ||
| `operationName` | string \| null? | GraphQL document operation name to execute. | | ||
| `variables` | object \| null? | GraphQL document operation variables and values map. | | ||
| `operationName` | string \| `null`? | GraphQL document operation name to execute. | | ||
| `variables` | object \| `null`? | GraphQL document operation variables and values map. | | ||
@@ -266,12 +259,28 @@ #### See | ||
### type UploadOptions | ||
### type ProcessRequestFunction | ||
GraphQL upload server options, mostly relating to security, performance and limits. | ||
Processes a [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec). | ||
**Type:** Object | ||
**Type:** Function | ||
| Parameter | Type | Description | | ||
| :-- | :-- | :-- | | ||
| `request` | IncomingMessage | [Node.js HTTP server request instance](https://nodejs.org/api/http.html#http_class_http_incomingmessage). | | ||
| `response` | ServerResponse | [Node.js HTTP server response instance](https://nodejs.org/api/http.html#http_class_http_serverresponse). | | ||
| `options` | [ProcessRequestOptions](#type-processrequestoptions)? | Options for processing the request. | | ||
**Returns:** Promise<[GraphQLOperation](#type-graphqloperation) | Array<[GraphQLOperation](#type-graphqloperation)>> — GraphQL operation or batch of operations for a GraphQL server to consume (usually as the request body). | ||
--- | ||
### type ProcessRequestOptions | ||
Options for processing a [GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec); mostly relating to security, performance and limits. | ||
**Type:** object | ||
| Property | Type | Description | | ||
| :-- | :-- | :-- | | ||
| `maxFieldSize` | number? = `1000000` | Maximum allowed non-file multipart form field size in bytes; enough for your queries. | | ||
| `maxFileSize` | number? = `Infinity` | Maximum allowed file size in bytes. | | ||
| `maxFiles` | number? = `Infinity` | Maximum allowed number of files. | | ||
| `maxFileSize` | number? = Infinity | Maximum allowed file size in bytes. | | ||
| `maxFiles` | number? = Infinity | Maximum allowed number of files. | |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
59076
19
709
276
23
Updatedhttp-errors@^1.7.3