Skip to content

Commit

Permalink
Fix ESLint setup, improve tests and small fix for more accurate HTTP …
Browse files Browse the repository at this point in the history
…status code (#2250)

* Fix ESLint setup

* Update green-yaks-shave.md

* Fix ESLint
  • Loading branch information
ardatan committed Dec 26, 2022
1 parent 290c7f7 commit 82f5893
Show file tree
Hide file tree
Showing 98 changed files with 462 additions and 322 deletions.
10 changes: 10 additions & 0 deletions .changeset/green-yaks-shave.md
@@ -0,0 +1,10 @@
---
'graphql-yoga': patch
---

More accurate HTTP status code when unsupported media type is sent as a request body.

Before it was returning `400: Bad Request` with `Request is not valid` text body in the response but now it returns `415: Unsupported Media Type` with an empty body.

Also see this unit test;
https://github.com/dotansimha/graphql-yoga/pull/2250/files#diff-78bcfa5f6d33aceeabdacd26e353641fea6fd125838ed0e1565762221568c777R380
17 changes: 16 additions & 1 deletion .eslintrc.cjs
@@ -1,5 +1,9 @@
module.exports = {
extends: ['@theguild'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
overrides: [
{
files: ['packages/graphql-yoga/src/plugins/**/*.ts'],
Expand All @@ -9,6 +13,10 @@ module.exports = {
},
{
files: ['website/**'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './website/tsconfig.json',
},
rules: { 'import/no-default-export': 'off' },
},
{
Expand Down Expand Up @@ -53,7 +61,14 @@ module.exports = {
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: ['**/*.test.ts', '**/*.spec.ts'] },
{
devDependencies: [
'**/*.test.ts',
'**/*.spec.ts',
'**/scripts/*.js',
'**/vite.config.ts',
],
},
],
'no-restricted-imports': [
'error',
Expand Down
@@ -1,10 +1,9 @@
import { ApolloClient, FetchResult, InMemoryCache } from '@apollo/client/core'
import { createYoga, createSchema } from 'graphql-yoga'
import { createServer, Server } from 'http'
import { createServer, Server } from 'node:http'
import { AddressInfo } from 'node:net'
import { parse } from 'graphql'
import { ApolloClient, FetchResult, InMemoryCache } from '@apollo/client/core'
import { YogaLink } from '@graphql-yoga/apollo-link'
import { File } from '@whatwg-node/fetch'
import { AddressInfo } from 'net'
import { createSchema, createYoga } from 'graphql-yoga'

describe.skip('Yoga Apollo Link', () => {
const endpoint = '/graphql'
Expand Down Expand Up @@ -50,7 +49,7 @@ describe.skip('Yoga Apollo Link', () => {

let server: Server
let url: string
let client: ApolloClient<any>
let client: ApolloClient<unknown>

beforeAll(async () => {
server = createServer(yoga)
Expand Down Expand Up @@ -118,7 +117,9 @@ describe.skip('Yoga Apollo Link', () => {
}
`),
variables: {
file: new File(['Hello World'], 'file.txt', { type: 'text/plain' }),
file: new yoga.fetchAPI.File(['Hello World'], 'file.txt', {
type: 'text/plain',
}),
},
})
expect(result.errors?.length).toBeFalsy()
Expand Down
3 changes: 2 additions & 1 deletion packages/client/apollo-link/package.json
Expand Up @@ -54,7 +54,8 @@
"tslib": "^2.3.1"
},
"devDependencies": {
"@apollo/client": "3.7.2"
"@apollo/client": "3.7.2",
"graphql-yoga": "3.1.2"
},
"peerDependencies": {
"graphql": "^15.2.0 || ^16.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/client/apollo-link/src/index.ts
@@ -1,13 +1,14 @@
import { ExecutorLink } from '@graphql-tools/executor-apollo-link'
import {
HTTPExecutorOptions,
buildHTTPExecutor,
HTTPExecutorOptions,
} from '@graphql-tools/executor-http'

export type YogaLinkOptions = HTTPExecutorOptions

export class YogaLink extends ExecutorLink {
constructor(options: YogaLinkOptions) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
super(buildHTTPExecutor(options as any))
}
}
@@ -1,10 +1,9 @@
import { Client, createClient } from '@urql/core'
import { createServer, Server } from 'node:http'
import { AddressInfo } from 'node:net'
import { yogaExchange } from '@graphql-yoga/urql-exchange'
import { Client, createClient } from '@urql/core'
import { createSchema, createYoga } from 'graphql-yoga'
import { pipe, toObservable } from 'wonka'
import { createYoga, createSchema } from 'graphql-yoga'
import { File } from '@whatwg-node/fetch'
import { createServer, Server } from 'http'
import { AddressInfo } from 'net'

describe.skip('URQL Yoga Exchange', () => {
const endpoint = '/graphql'
Expand Down Expand Up @@ -133,7 +132,9 @@ describe.skip('URQL Yoga Exchange', () => {
`
const result = await client
.mutation(query, {
file: new File(['Hello World'], 'file.txt', { type: 'text/plain' }),
file: new yoga.fetchAPI.File(['Hello World'], 'file.txt', {
type: 'text/plain',
}),
})
.toPromise()
expect(result.error).toBeFalsy()
Expand Down
3 changes: 2 additions & 1 deletion packages/client/urql-exchange/package.json
Expand Up @@ -55,7 +55,8 @@
},
"devDependencies": {
"@urql/core": "3.0.5",
"wonka": "6.1.2"
"wonka": "6.1.2",
"graphql-yoga": "3.1.2"
},
"peerDependencies": {
"graphql": "^15.2.0 || ^16.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/client/urql-exchange/src/index.ts
Expand Up @@ -8,5 +8,6 @@ import { Exchange } from '@urql/core'
export type YogaExchangeOptions = HTTPExecutorOptions

export function yogaExchange(options?: HTTPExecutorOptions): Exchange {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return executorExchange(buildHTTPExecutor(options as any))
}
@@ -1,6 +1,7 @@
import { CustomEvent } from '@whatwg-node/events'
import Redis from 'ioredis-mock'

import { createRedisEventTarget } from '../src'
import { CustomEvent } from '@whatwg-node/events'

describe('createRedisEventTarget', () => {
it('can listen to a simple publish', (done) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/event-target/redis-event-target/src/index.ts
@@ -1,6 +1,6 @@
import type { TypedEventTarget } from '@graphql-yoga/typed-event-target'
import { CustomEvent } from '@whatwg-node/events'
import type { Redis, Cluster } from 'ioredis'
import type { Cluster, Redis } from 'ioredis'

export type CreateRedisEventTargetArgs = {
publishClient: Redis | Cluster
Expand Down
19 changes: 10 additions & 9 deletions packages/graphiql/src/YogaGraphiQL.tsx
@@ -1,24 +1,25 @@
import 'json-bigint-patch'
import React, { useMemo, useState } from 'react'
import { DocumentNode, Kind, parse } from 'graphql'
import { useExplorerPlugin } from '@graphiql/plugin-explorer'
import { Fetcher, FetcherOpts, FetcherParams } from '@graphiql/toolkit'
import {
LoadFromUrlOptions,
SubscriptionProtocol,
UrlLoader,
} from '@graphql-tools/url-loader'
import {
GraphiQL,
GraphiQLInterface,
GraphiQLProps,
GraphiQLProvider,
} from 'graphiql'
import { Fetcher, FetcherParams, FetcherOpts } from '@graphiql/toolkit'
import {
LoadFromUrlOptions,
SubscriptionProtocol,
UrlLoader,
} from '@graphql-tools/url-loader'
import { useUrlSearchParams } from 'use-url-search-params'
import { DocumentNode, Kind, parse } from 'graphql'

import { YogaLogo } from './YogaLogo'
import 'graphiql/graphiql.css'
import '@graphiql/plugin-explorer/dist/style.css'
import './styles.css'
import 'json-bigint-patch'
import { YogaLogo } from './YogaLogo'

const getOperationWithFragments = (
document: DocumentNode,
Expand Down
1 change: 1 addition & 0 deletions packages/graphiql/src/bundle.tsx
@@ -1,5 +1,6 @@
import React from 'react'
import ReactDOM from 'react-dom'

import { YogaGraphiQL, YogaGraphiQLProps } from './YogaGraphiQL.js'

export function renderYogaGraphiQL(element: Element, opts?: YogaGraphiQLProps) {
Expand Down
4 changes: 2 additions & 2 deletions packages/graphiql/vite.config.ts
@@ -1,6 +1,6 @@
import { defineConfig } from 'vite'
import * as path from 'node:path'
import react from '@vitejs/plugin-react'
import * as path from 'path'
import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
Expand Down
44 changes: 23 additions & 21 deletions packages/graphql-yoga/__integration-tests__/browser.spec.ts
@@ -1,23 +1,24 @@
import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store'
import { GraphQLLiveDirective, useLiveQuery } from '@envelop/live-query'
import { CORSOptions, createYoga, Repeater } from '../src/index.js'
import { renderGraphiQL } from '@graphql-yoga/render-graphiql'
import puppeteer, { Browser, ElementHandle, Page } from 'puppeteer'
import { createServer, Server } from 'http'
import 'json-bigint-patch'
import { createServer, Server } from 'node:http'
import { AddressInfo } from 'node:net'
import {
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
GraphQLInt,
GraphQLBoolean,
GraphQLList,
GraphQLFloat,
GraphQLInt,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
} from 'graphql'
import { GraphQLBigInt } from 'graphql-scalars'
import 'json-bigint-patch'
import { AddressInfo } from 'net'
import { GraphQLLiveDirective, useLiveQuery } from '@envelop/live-query'
import { useDeferStream } from '@graphql-yoga/plugin-defer-stream'
import { renderGraphiQL } from '@graphql-yoga/render-graphiql'
import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store'
import { GraphQLBigInt } from 'graphql-scalars'
import puppeteer, { Browser, ElementHandle, Page } from 'puppeteer'

import { CORSOptions, createYoga, Repeater } from '../src/index.js'

let resolveOnReturn: VoidFunction
const timeouts = new Set<NodeJS.Timeout>()
Expand Down Expand Up @@ -122,13 +123,14 @@ export function createTestSchema() {
},
error: {
type: GraphQLBoolean,
// eslint-disable-next-line require-yield
// eslint-disable-next-line
async *subscribe() {
throw new Error('This is not okay')
},
},
eventEmitted: {
type: GraphQLFloat,
// eslint-disable-next-line
async *subscribe() {
yield { eventEmitted: Date.now() }
},
Expand Down Expand Up @@ -220,7 +222,7 @@ describe('browser', () => {
await page.waitForFunction(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
() => !!window.g.resultComponent.viewer.getValue(),
() => Boolean(window.g.resultComponent.viewer.getValue()),
)
const resultContents = await page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down Expand Up @@ -344,7 +346,7 @@ describe('browser', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.g.resultComponent.viewer.getValue(),
!!window.document.querySelector(stopButtonSelector),
Boolean(window.document.querySelector(stopButtonSelector)),
]
},
stopButtonSelector,
Expand Down Expand Up @@ -373,7 +375,7 @@ describe('browser', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.g.resultComponent.viewer.getValue(),
!!window.document.querySelector(stopButtonSelector),
Boolean(window.document.querySelector(stopButtonSelector)),
]
},
stopButtonSelector,
Expand All @@ -391,7 +393,7 @@ describe('browser', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.g.resultComponent.viewer.getValue(),
!!window.document.querySelector(playButtonSelector),
Boolean(window.document.querySelector(playButtonSelector)),
]
},
playButtonSelector,
Expand Down Expand Up @@ -451,7 +453,7 @@ describe('browser', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.g.resultComponent.viewer.getValue(),
!!window.document.querySelector(stopButtonSelector),
Boolean(window.document.querySelector(stopButtonSelector)),
]
}, stopButtonSelector)
const resultJson = JSON.parse(resultContents)
Expand Down Expand Up @@ -479,7 +481,7 @@ describe('browser', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.g.resultComponent.viewer.getValue(),
!!window.document.querySelector(playButtonSelector),
Boolean(window.document.querySelector(playButtonSelector)),
]
}, playButtonSelector)
const resultJson1 = JSON.parse(resultContents1)
Expand Down
15 changes: 8 additions & 7 deletions packages/graphql-yoga/__integration-tests__/file-uploads.spec.ts
@@ -1,11 +1,12 @@
import * as fs from 'fs'
import * as crypto from 'crypto'
import * as path from 'path'
import * as os from 'os'
import { createServer } from 'http'
import { createYoga, createSchema } from 'graphql-yoga'
import * as crypto from 'node:crypto'
import * as fs from 'node:fs'
import { createServer } from 'node:http'
import { AddressInfo } from 'node:net'
import * as os from 'node:os'
import * as path from 'node:path'
import { fetch, File, FormData } from '@whatwg-node/fetch'
import { AddressInfo } from 'net'

import { createSchema, createYoga } from '../src'

function md5File(path: string) {
return new Promise((resolve, reject) => {
Expand Down
@@ -1,9 +1,10 @@
import { createSchema, createYoga } from '../src/index.js'
import { specifiedScalarTypes } from 'graphql'
import {
typeDefs as scalarsTypeDefs,
resolvers as scalarsResolvers,
typeDefs as scalarsTypeDefs,
} from 'graphql-scalars'
import { specifiedScalarTypes } from 'graphql'

import { createSchema, createYoga } from '../src/index.js'

describe('graphql-scalars', () => {
const ignoredScalars = [
Expand Down Expand Up @@ -40,7 +41,8 @@ describe('graphql-scalars', () => {
scalarsResolvers,
...allScalars.map((scalar) => ({
Query: {
[`get${scalar.name}`]: (_: never, { input }: any) => input,
[`get${scalar.name}`]: (_: never, { input }: { input: unknown }) =>
input,
},
})),
],
Expand Down

0 comments on commit 82f5893

Please sign in to comment.