diff --git a/.eslintrc.yml b/.eslintrc.yml index 21c50fcb..d31b2ae2 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -51,7 +51,7 @@ rules: node/no-unpublished-import: error node/no-unpublished-require: error node/no-unsupported-features/es-builtins: error - node/no-unsupported-features/es-syntax: off # TODO enable + node/no-unsupported-features/es-syntax: error node/no-unsupported-features/node-builtins: error node/process-exit-as-throw: error node/shebang: error @@ -444,6 +444,8 @@ overrides: extends: - plugin:import/typescript rules: + node/no-unsupported-features/es-syntax: off + ########################################################################## # `@typescript-eslint/eslint-plugin` rule list based on `v3.5.x` ########################################################################## diff --git a/src/index.ts b/src/index.ts index 47d232e1..23b4d930 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ import type { GraphQLFormattedError, } from 'graphql'; import accepts from 'accepts'; -import httpError, { HttpError } from 'http-errors'; +import httpError from 'http-errors'; import { Source, parse, @@ -31,7 +31,9 @@ import type { GraphiQLOptions, GraphiQLData } from './renderGraphiQL'; import { parseBody } from './parseBody'; import { renderGraphiQL } from './renderGraphiQL'; -type Request = IncomingMessage; +// `url` is always defined for IncomingMessage coming from http.Server +type Request = IncomingMessage & { url: string }; + type Response = ServerResponse & { json?: (data: unknown) => void }; type MaybePromise = Promise | T; @@ -361,11 +363,10 @@ export function graphqlHTTP(options: Options): Middleware { // If an error was caught, report the httpError status, or 500. response.statusCode = error.status ?? 500; - if (error.headers) { - const err = error as HttpError; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - for (const [key, value] of Object.entries(err.headers!)) { - response.setHeader(key, value); + const { headers } = error; + if (headers != null) { + for (const [key, value] of Object.entries(headers)) { + response.setHeader(key, String(value)); } } @@ -465,9 +466,7 @@ export interface GraphQLParams { export async function getGraphQLParams( request: Request, ): Promise { - // `url` is always defined for IncomingMessage coming from http.Server - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const urlData = new URLSearchParams(request.url!.split('?')[1]); + const urlData = new URLSearchParams(request.url.split('?')[1]); const bodyData = await parseBody(request); // GraphQL Query string. diff --git a/src/parseBody.ts b/src/parseBody.ts index adbf63b4..32b1f968 100644 --- a/src/parseBody.ts +++ b/src/parseBody.ts @@ -6,12 +6,9 @@ import querystring from 'querystring'; import getBody from 'raw-body'; import httpError from 'http-errors'; import contentType from 'content-type'; +import type { ParsedMediaType } from 'content-type'; type Request = IncomingMessage & { body?: unknown }; -interface ParsedMediaType { - type: string; - parameters: { [key: string]: string | undefined }; -} /** * Provided a "Request" provided by express or connect (typically a node style @@ -106,7 +103,7 @@ async function readBody( } catch (err) { throw err.type === 'encoding.unsupported' ? httpError(415, `Unsupported charset "${charset.toUpperCase()}".`) - : httpError(400, `Invalid body: ${err.message as string}.`); + : httpError(400, `Invalid body: ${String(err.message)}.`); } }