From c9dab6a663de3e4a81359a0dc58e3fa745a9c54c Mon Sep 17 00:00:00 2001 From: Rikki Date: Mon, 18 Jan 2021 19:37:35 -0500 Subject: [PATCH 1/8] feat: new encapsulation for transport spec --- .../graphiql-create-react-app/package.json | 2 - examples/graphiql-parcel/package.json | 2 - package.json | 8 +- packages/graphiql-build-fetcher/README.md | 146 +++++ .../graphiql-build-fetcher/jest.config.js | 5 + packages/graphiql-build-fetcher/package.json | 33 + .../src/__tests__/buildFetcher.spec.ts | 91 +++ .../src/__tests__/lib.spec.ts | 57 ++ .../src/buildFetcher.ts | 87 +++ packages/graphiql-build-fetcher/src/index.ts | 2 + packages/graphiql-build-fetcher/src/lib.ts | 144 +++++ packages/graphiql-build-fetcher/src/types.ts | 38 ++ .../graphiql-build-fetcher/test/server.ts | 80 +++ .../graphiql-build-fetcher/tsconfig.esm.json | 27 + packages/graphiql-build-fetcher/tsconfig.json | 30 + packages/graphiql-toolkit/package.json | 21 + packages/graphiql-toolkit/src/index.ts | 3 + packages/graphiql-toolkit/src/types.ts | 61 ++ packages/graphiql-toolkit/tsconfig.esm.json | 22 + packages/graphiql-toolkit/tsconfig.json | 23 + packages/graphiql/package.json | 11 +- packages/graphiql/src/components/GraphiQL.tsx | 71 +- .../graphiql/src/components/ImagePreview.tsx | 5 - .../graphiql/src/components/ToolbarSelect.tsx | 8 - packages/graphiql/src/index.ts | 10 +- packages/graphiql/tsconfig.esm.json | 13 +- packages/graphiql/tsconfig.json | 9 + .../src/MessageProcessor.ts | 4 +- resources/tsconfig.build.cjs.json | 6 + resources/tsconfig.build.esm.json | 6 + yarn.lock | 607 ++++++++++-------- 31 files changed, 1278 insertions(+), 354 deletions(-) create mode 100644 packages/graphiql-build-fetcher/README.md create mode 100644 packages/graphiql-build-fetcher/jest.config.js create mode 100644 packages/graphiql-build-fetcher/package.json create mode 100644 packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts create mode 100644 packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts create mode 100644 packages/graphiql-build-fetcher/src/buildFetcher.ts create mode 100644 packages/graphiql-build-fetcher/src/index.ts create mode 100644 packages/graphiql-build-fetcher/src/lib.ts create mode 100644 packages/graphiql-build-fetcher/src/types.ts create mode 100644 packages/graphiql-build-fetcher/test/server.ts create mode 100644 packages/graphiql-build-fetcher/tsconfig.esm.json create mode 100644 packages/graphiql-build-fetcher/tsconfig.json create mode 100644 packages/graphiql-toolkit/package.json create mode 100644 packages/graphiql-toolkit/src/index.ts create mode 100644 packages/graphiql-toolkit/src/types.ts create mode 100644 packages/graphiql-toolkit/tsconfig.esm.json create mode 100644 packages/graphiql-toolkit/tsconfig.json diff --git a/examples/graphiql-create-react-app/package.json b/examples/graphiql-create-react-app/package.json index 33d8ef66f29..61ea4f0b5d4 100644 --- a/examples/graphiql-create-react-app/package.json +++ b/examples/graphiql-create-react-app/package.json @@ -3,8 +3,6 @@ "version": "0.1.11-alpha.8", "private": true, "dependencies": { - "@types/react": "^16.9.34", - "@types/react-dom": "^16.9.6", "graphiql": "file:../../packages/graphiql", "graphql": "^15.0.0", "react": "^16.13.1", diff --git a/examples/graphiql-parcel/package.json b/examples/graphiql-parcel/package.json index 9b91431019a..29e0b2ba82d 100644 --- a/examples/graphiql-parcel/package.json +++ b/examples/graphiql-parcel/package.json @@ -22,8 +22,6 @@ ] }, "dependencies": { - "@types/react": "^16.9.34", - "@types/react-dom": "^16.9.6", "graphiql": "file:../../packages/graphiql", "graphql": "15.0.0", "react": "^16.13.1", diff --git a/package.json b/package.json index e8d0824fb5f..3294665a2f0 100644 --- a/package.json +++ b/package.json @@ -81,11 +81,13 @@ "@strictsoftware/typedoc-plugin-monorepo": "^0.3.1", "@testing-library/jest-dom": "^5.4.0", "@types/codemirror": "^0.0.90", + "@types/express": "^4.17.11", "@types/fetch-mock": "^7.3.2", - "@types/jest": "^26.0.8", + "@types/jest": "^26.0.20", "@types/node": "^13.11.1", "@types/prettier": "^2.0.0", "@types/theme-ui": "^0.3.1", + "@types/ws": "^7.4.0", "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "babel-eslint": "^10.1.0", @@ -93,7 +95,7 @@ "conventional-changelog-conventionalcommits": "^4.2.3", "copy": "^0.3.2", "cross-env": "^7.0.2", - "cypress": "^4.3.0", + "cypress": "^4.7.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-plugin-babel": "^5.3.0", @@ -119,7 +121,7 @@ "rimraf": "^3.0.2", "ts-jest": "^25.3.1", "typedoc": "^0.19.2", - "typescript": "^3.9.5", + "typescript": "^4.1.3", "whatwg-url": "^8.4.0" } } diff --git a/packages/graphiql-build-fetcher/README.md b/packages/graphiql-build-fetcher/README.md new file mode 100644 index 00000000000..78b768555a6 --- /dev/null +++ b/packages/graphiql-build-fetcher/README.md @@ -0,0 +1,146 @@ +## `@graphiql/build-fetcher` + +a utility for generating a full-featured fetcher for GraphiQL. + +under the hood, it uses [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) and [`fetch-multipart-graphql`](https://www.npmjs.com/package/fetch-multipart-graphql) to follow the [GraphQL over HTTP Working Group Spec](https://github.com/graphql/graphql-over-http) both accepted and advanced proposals. + +### Setup + +[`graphiql`](https://npmjs.com/package/graphiql) and thus `react` and `react-dom` should already be installed. + +you'll need to install `@graphiql/build-fetcher` + +npm +```bash +npm install --save @graphiql/build-fetcher +``` + +yarn +```bash +yarn add @graphiql/build-fetcher +``` + +### Getting Started + +We have a few flexible options to get you started with the client. It's meant to cover the majority of common use cases with a simple encapsulation. + +#### HTTP/Multipart Usage + +Here's a simple example. In this case, a websocket client isn't even initialized, only http (with multipart `@stream` and `@defer` support of course!). + +```ts +import * as React from "react" +import ReactDOM from "react-dom" +import { GraphiQL } from "graphiql" +import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" + +const url = 'https://myschema.com/graphql' + +const fetcher = buildGraphiQLFetcher({ url }); + +export const App = () => ; + +ReactDOM.render(document.getElementByID('graphiql'), ) +``` +#### HTTP/Multipart & Websockets + +Just by providing the `subscriptionsUrl`, you can generate a `graphql-ws` client + +```ts +import * as React from "react" +import ReactDOM from "react-dom" +import { GraphiQL } from "graphiql" +import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" + +const url = 'https://myschema.com/graphql' + +const subscriptionsUrl = "wss://myschema.com/graphql" + +const fetcher = buildGraphiQLFetcher({ + url, + subscriptionsUrl +}); + +export const App = () => ; + +ReactDOM.render(document.getElementByID('graphiql'), ) +``` + +You can further customize the `wsClient` implementation below + +### Options + +#### `url` (*required*) + +This is url used for all `HTTP` requests, and for schema introspection. + +#### `subscriptionsUrl` + +This generates a `graphql-ws` client. + +#### `wsClient` + +provide your own subscriptions client. bypasses `subscriptionsUrl`. In theory, this could be any client using any transport, as long as it matches `graphql-ws` `Client` signature. + +#### `headers` + +Pass headers to any and all requests + +#### `fetch` + +Pass a custom fetch implementation such as `isomorphic-feth` + +### Customization Examples + + + +#### Custom `wsClient` Example +Just by providing the `subscriptionsUrl` + +```ts +import * as React from "react" +import ReactDOM from "react-dom" +import { GraphiQL } from "graphiql" +import { createClient } from "graphql-ws" +import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" + +const url = 'https://myschema.com/graphql' + +const subscriptionsUrl = "wss://myschema.com/graphql" + +const fetcher = buildGraphiQLFetcher({ + url, + wsClient: createClient({ + url: subscriptionsUrl , + keepAlive: 2000 + }) +}); + +export const App = () => ; + +ReactDOM.render(document.getElementByID('graphiql'), ) +``` + + +#### Custom `fetcher` Example +For SSR, we might want to use something like `isomorphic-fetch` + +```ts +import * as React from "react" +import ReactDOM from "react-dom" +import { GraphiQL } from "graphiql" +import { fetch } from "isomorphic-fetch" +import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" + +const url = 'https://myschema.com/graphql' + + +const fetcher = buildGraphiQLFetcher({ + url, + fetch +}); + +export const App = () => ; + +ReactDOM.render(document.getElementByID('graphiql'), ) +``` diff --git a/packages/graphiql-build-fetcher/jest.config.js b/packages/graphiql-build-fetcher/jest.config.js new file mode 100644 index 00000000000..d5f2ae82f35 --- /dev/null +++ b/packages/graphiql-build-fetcher/jest.config.js @@ -0,0 +1,5 @@ +const base = require('../../jest.config.base')(__dirname); + +module.exports = { + ...base, +}; diff --git a/packages/graphiql-build-fetcher/package.json b/packages/graphiql-build-fetcher/package.json new file mode 100644 index 00000000000..3b2d0b34752 --- /dev/null +++ b/packages/graphiql-build-fetcher/package.json @@ -0,0 +1,33 @@ +{ + "name": "@graphiql/build-fetcher", + "version": "0.0.1", + "description": "Utility to build a fetcher for GraphiQL", + "contributors": [ + "Rikki Schulte (http://rikki.dev/" + ], + "repository": "http://github.com/graphql/graphiql", + "homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql#readme", + "bugs": { + "url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql" + }, + "license": "MIT", + "main": "dist/index.js", + "module": "esm/index.js", + "scripts": { + "server": "ts-node test/server.ts" + }, + "dependencies": { + "graphql-ws": "^4.1.0", + "graphql-transport-ws": "^1.9.0", + "fetch-multipart-graphql": "^3.0.0", + "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", + "@graphiql/toolkit": "^0.0.1" + }, + "devDependencies": { + "isomorphic-fetch": "^3.0.0", + "express": "^4.17.1", + "express-graphql": "experimental-stream-defer", + "ws": "^7.4.2", + "ts-node": "^9.1.1" + } +} diff --git a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts new file mode 100644 index 00000000000..194d3db2b5a --- /dev/null +++ b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts @@ -0,0 +1,91 @@ +import { parse, getIntrospectionQuery } from 'graphql'; +import { buildGraphiQLFetcher } from '../buildFetcher'; + +import 'isomorphic-fetch'; + +jest.mock('../lib'); + +jest.mock('graphql-ws'); + +jest.mock('graphql-transport-ws'); + +import { + createWebsocketsClient, + createWebsocketsFetcher, + createMultipartFetcher, + createSimpleFetcher, +} from '../lib'; +import { createClient } from 'graphql-ws'; + +const exampleWithSubscripton = /* GraphQL */ ` +subscription Example { + example +} +query SomethingElse { + example +} +`; + +const exampleWithSubscriptonNode = parse(exampleWithSubscripton); + +const serverURL = 'http://localhost:3000/graphql'; +const wssURL = 'ws://localhost:3000/graphql'; + +const exampleIntrospectionJson = parse(getIntrospectionQuery()); + +describe('buildGraphiQLFetcher', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + it('returns fetcher without websocket client by default', async () => { + createWebsocketsClient.mockReturnValue(true); + const fetcher = buildGraphiQLFetcher({ url: serverURL }); + expect(createWebsocketsClient.mock.calls).toEqual([]); + expect(createMultipartFetcher.mock.calls).toEqual([ + [{ enableMultipart: true, url: serverURL }], + ]); + + }); + it('returns fetcher without websocket client or multipart', () => { + createWebsocketsClient.mockReturnValue(true); + buildGraphiQLFetcher({ url: serverURL, enableMultipart: false }); + expect(createWebsocketsClient.mock.calls).toEqual([]); + expect(createMultipartFetcher.mock.calls).toEqual([]); + expect(createSimpleFetcher.mock.calls).toEqual([ + [{ enableMultipart: false, url: serverURL }, fetch], + ]); + }); + it('returns fetcher with websocket client', () => { + createWebsocketsClient.mockReturnValue('Client1'); + + const args = { + url: serverURL, + subscriptionsUrl: wssURL, + enableMultipart: true, + }; + + buildGraphiQLFetcher(args); + + expect(createMultipartFetcher.mock.calls).toEqual([[args]]); + expect(createWebsocketsClient.mock.calls).toEqual([[args]]); + expect(createWebsocketsFetcher.mock.calls).toEqual([['Client1']]); + }); + + it('returns fetcher with custom wsClient', () => { + createClient.mockReturnValue('WSClient'); + createWebsocketsFetcher.mockReturnValue('CustomWSSFetcher'); + + const wsClient = createClient({ url: wssURL }); + const args = { + url: serverURL, + wsClient, + enableMultipart: true, + }; + + buildGraphiQLFetcher(args); + + expect(createMultipartFetcher.mock.calls).toEqual([[args]]); + expect(createWebsocketsClient.mock.calls).toEqual([]); + expect(createWebsocketsFetcher.mock.calls).toEqual([['WSClient']]); + }); +}); diff --git a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts new file mode 100644 index 00000000000..ad436694c68 --- /dev/null +++ b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts @@ -0,0 +1,57 @@ +import { parse } from 'graphql'; +import { isSubcriptionWithName, createWebsocketsClient } from '../lib'; + +import "isomorphic-fetch" + + +jest.mock('graphql-ws') + +jest.mock("graphql-transport-ws") + + + +import { createClient } from "graphql-ws" + +import { createClient as createLegacyClient } from "graphql-transport-ws" + +const exampleWithSubscripton = /* GraphQL */ parse(` + subscription Example { + example + } + query SomethingElse { + example + } +`); + +describe('isSubcriptionWithName', () => { + it('detects when the subscription is present', () => { + expect( + isSubcriptionWithName(exampleWithSubscripton, 'Example'), + ).toBeTruthy(); + }); + it('detects when the specified operation is not a subscription', () => { + expect( + isSubcriptionWithName(exampleWithSubscripton, 'SomethingElse'), + ).toBeFalsy(); + }); + it('detects when the operation is not present', () => { + expect( + isSubcriptionWithName(exampleWithSubscripton, 'NotPresent'), + ).toBeFalsy(); + }); +}); + +describe('createWebsocketsClient', () => { + afterEach(() => { + // @ts-ignore + createClient.mockRestore() + }) + it('creates a websockets client using provided url', () => { + createWebsocketsClient({ + url: 'https://example.com', + subscriptionsUrl: 'wss://example.com', + }); + // @ts-ignore + expect(createClient.mock.calls[0][0]).toEqual({"url": "wss://example.com"}) + }); +}); diff --git a/packages/graphiql-build-fetcher/src/buildFetcher.ts b/packages/graphiql-build-fetcher/src/buildFetcher.ts new file mode 100644 index 00000000000..13c328df784 --- /dev/null +++ b/packages/graphiql-build-fetcher/src/buildFetcher.ts @@ -0,0 +1,87 @@ +import type { Client } from 'graphql-ws' +import type { Fetcher } from '@graphiql/toolkit'; +import type { BuildFetcherOptions } from './types'; + +import { + createMultipartFetcher, + createSimpleFetcher, + isSubcriptionWithName, + createWebsocketsClient, + createWebsocketsFetcher, +} from './lib'; + + + + +/** + * build a GraphiQL fetcher that is: + * - backwards compatible + * - optionally supports graphql-ws or ` + * + * @param options {BuildFetcherOptions} + * @returns {Fetcher} + */ +export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { + // hoist the wsClient to global scope, so that we can unsubscribe/re-subscribe +// even when the function is re-invoked. + let wsClient: Client | null = null; + + let httpFetch; + if (typeof window !== null && window?.fetch) { + httpFetch = window.fetch; + } + if (options?.enableMultipart === null || options.enableMultipart !== false) { + options.enableMultipart = true; + } + if (options.fetch) { + httpFetch = options.fetch; + } + if (!httpFetch) { + throw Error('No valid fetcher implementation available'); + } + + + let wsFetcher: Fetcher | null = null; + + // user provided wsClient + if (options.wsClient) { + wsClient = options.wsClient; + } + + // if there's no user provided wsClient, + // and a subscriptionsUrl us present, then generate one + if (!wsClient && options.subscriptionsUrl) { + wsClient = createWebsocketsClient(options); + } + + if (wsClient) { + wsFetcher = createWebsocketsFetcher(wsClient); + } else if (options.subscriptionsUrl) { + throw Error("subscriptions client failed to initialize") + } + + const simpleFetcher = createSimpleFetcher(options, httpFetch); + + const httpFetcher = options.enableMultipart + ? createMultipartFetcher(options) + : simpleFetcher; + + return (graphQLParams, opts) => { + if (graphQLParams.operationName === 'IntrospectionQuery') { + return simpleFetcher(graphQLParams, opts); + } + const isSubscription = isSubcriptionWithName( + opts?.documentAST!, + graphQLParams.operationName, + ); + if (isSubscription) { + if (!wsFetcher) { + throw Error( + 'GraphiQL buildFetcher did not successfully build a wsFetcher', + ); + } + return wsFetcher(graphQLParams, opts); + } + return httpFetcher(graphQLParams, opts); + }; +} diff --git a/packages/graphiql-build-fetcher/src/index.ts b/packages/graphiql-build-fetcher/src/index.ts new file mode 100644 index 00000000000..d11e5722d6c --- /dev/null +++ b/packages/graphiql-build-fetcher/src/index.ts @@ -0,0 +1,2 @@ +export type { BuildFetcherOptions} from './types' +export { buildGraphiQLFetcher } from './buildFetcher' diff --git a/packages/graphiql-build-fetcher/src/lib.ts b/packages/graphiql-build-fetcher/src/lib.ts new file mode 100644 index 00000000000..792d4a250a0 --- /dev/null +++ b/packages/graphiql-build-fetcher/src/lib.ts @@ -0,0 +1,144 @@ +import { DocumentNode, visit } from 'graphql'; +import fetchMultipart from 'fetch-multipart-graphql'; +import { createClient, Client } from 'graphql-ws'; +import { createClient as createLegacyClient } from 'graphql-transport-ws'; +import { makeAsyncIterableIteratorFromSink } from '@n1ru4l/push-pull-async-iterable-iterator'; + +import type { BuildFetcherOptions } from './'; +import type { + Fetcher, + FetcherResult, + FetcherParams, + FetcherOpts, +} from '@graphiql/toolkit'; + +/** + * Returns true if the name matches a subscription in the AST + * + * @param document {DocumentNode} + * @param name the operation name to lookup + * @returns {boolean} + */ +export const isSubcriptionWithName = ( + document: DocumentNode, + name: string, +): boolean => { + let isSubcription = false; + visit(document, { + OperationDefinition(node) { + if (name === node.name?.value) { + if (node.operation === 'subscription') { + isSubcription = true; + } + } + }, + }); + return isSubcription; +}; + +/** + * create a websockets client, following + * `graphql-ws` Client signature + * + * @param options + * @returns {Client | null} + */ +export const createWebsocketsClient = ( + options: BuildFetcherOptions, +): Client | null => { + let wsClient: Client | null = null; + try { + try { + // TODO: defaults? + wsClient = createClient({ + url: options.subscriptionsUrl!, + }); + if (!wsClient) { + wsClient = createLegacyClient({ + url: options.subscriptionsUrl!, + }); + } + } catch (err) { + wsClient = createLegacyClient({ + url: options.subscriptionsUrl!, + }); + } + } catch (err) { + throw Error( + `Error creating websocket client for:\n${options.subscriptionsUrl}`, + ); + } + return wsClient; +}; + +/** + * create a simple HTTP/S fetcher using a fetch implementation where + * multipart is not needed + * + * @param options {BuildFetcherOptions} + * @param httpFetch {typeof fetch} + * @returns {Fetcher} + */ +export const createSimpleFetcher = ( + options: BuildFetcherOptions, + httpFetch: typeof fetch, +): Fetcher => async ( + graphQLParams: FetcherParams, + fetcherOpts?: FetcherOpts, +) => { + const data = await httpFetch(options.url, { + method: 'POST', + body: JSON.stringify(graphQLParams), + headers: { + 'content-type': 'application/json', + ...options.headers, + ...fetcherOpts?.headers, + }, + }); + return data.json(); +}; + +/** + * Create ws/s fetcher using provided wsClient implementation + * + * @param wsClient {Client} + * @returns {Fetcher} + */ +export const createWebsocketsFetcher = (wsClient: Client) => ( + graphQLParams: FetcherParams, +) => + makeAsyncIterableIteratorFromSink(sink => + wsClient!.subscribe(graphQLParams, sink), + ); + +/** + * create a fetcher with the `IncrementalDelivery` HTTP/S spec for + * `@stream` and `@defer` support using `fetch-multipart-graphql` + * + * @param options {BuildFetcherOptions} + * @returns {Fetcher} + */ +export const createMultipartFetcher = ( + options: BuildFetcherOptions, +): Fetcher => async (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) => + makeAsyncIterableIteratorFromSink(sink => { + fetchMultipart(options.url, { + method: 'POST', + body: JSON.stringify(graphQLParams), + headers: { + 'content-type': 'application/json', + ...options.headers, + // allow user-defined headers to override + // the static provided headers + ...fetcherOpts?.headers, + }, + onNext: parts => { + // Introspection is broken if we return a array instead of a single item. + // TODO: This should be addressed inside GraphiQL + sink.next(parts[0]); + }, + onError: sink.error, + onComplete: sink.complete, + }); + return () => undefined; + }); diff --git a/packages/graphiql-build-fetcher/src/types.ts b/packages/graphiql-build-fetcher/src/types.ts new file mode 100644 index 00000000000..382bf263b5b --- /dev/null +++ b/packages/graphiql-build-fetcher/src/types.ts @@ -0,0 +1,38 @@ +import type { Client } from "graphql-ws" + +/** + * Options for creating a sinple, spec-compliant GraphiQL fetcher + */ +export interface BuildFetcherOptions { + /** + * url for HTTP(S) requests. required! + */ + url: string; + /** + * url for websocket subscription requests + */ + subscriptionsUrl?: string; + /** + * wsClient implementation that matches `ws-graphql` signature, + * whether via `createClient()` itself or another client. + */ + wsClient?: Client; + /** + * Headers you can provide statically. + * + * If you enable the headers editor and the user provides + * A header you set statically here, it will be overriden by their value. + */ + headers?: Record; + /** + * You can disable the usage of the `fetch-multipart-graphql` library + * entirely, defaulting to a simple fetch POST implementation. + */ + enableMultipart?: boolean; + /** + * The fetch implementation, in case the user needs to override this for SSR + * or other purposes. this does not override the `fetch-multipart-graphql` + * default fetch behavior yet. + */ + fetch?: typeof fetch; +} diff --git a/packages/graphiql-build-fetcher/test/server.ts b/packages/graphiql-build-fetcher/test/server.ts new file mode 100644 index 00000000000..da426930e57 --- /dev/null +++ b/packages/graphiql-build-fetcher/test/server.ts @@ -0,0 +1,80 @@ +import https from 'https'; +import ws from 'ws'; // yarn add ws +import express from 'express'; +import { graphqlHTTP } from 'express-graphql'; +import { useServer } from 'graphql-ws/lib/use/ws'; +import { + execute, + GraphQLObjectType, + GraphQLString, + subscribe, + GraphQLSchema, +} from 'graphql'; + +const wait = (timeout: number = 200) => + new Promise(res => setTimeout(res, timeout)); + +const Query = new GraphQLObjectType({ + name: 'Query', + fields: { + streamExample: { + type: GraphQLString, + resolve: async function* sayHiInFiveLanguages() { + for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { + yield { greetings: hi }; + await wait(500); + } + }, + }, + }, +}); + +const Subscription = new GraphQLObjectType({ + name: 'Subscription', + fields: { + subscriptionExample: { + type: GraphQLString, + subscribe: async function* sayHiInFiveLanguages() { + for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { + yield { greetings: hi }; + await wait(500); + } + }, + }, + }, +}); + +try { + const schema = new GraphQLSchema({ + subscription: Subscription, + query: Query, + }); + + // create express and middleware + const app = express(); + app.use('/graphql', graphqlHTTP({ schema, graphiql: true })); + + // create a http server using express + const server = https.createServer(app); + + // create websocket server + const wsServer = new ws.Server({ + server, + path: '/graphql', + }); + const port = process.env.PORT || 3000 + server.listen(port, () => { + useServer( + { + schema, + execute, + subscribe, + connectionInitWaitTimeout: 2000 + }, + wsServer, + ); + console.log(`listening on ${port}`) + }); +} catch (err) { + console.error(err); +} diff --git a/packages/graphiql-build-fetcher/tsconfig.esm.json b/packages/graphiql-build-fetcher/tsconfig.esm.json new file mode 100644 index 00000000000..04b6f62e0a2 --- /dev/null +++ b/packages/graphiql-build-fetcher/tsconfig.esm.json @@ -0,0 +1,27 @@ +{ + "extends": "../../resources/tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "composite": true, + "jsx": "react", + "strictPropertyInitialization": false, + "module": "ESNext", + "target": "ESNext" + }, + "include": ["src"], + "exclude": [ + "**/__tests__/**", + "**/dist/**.*", + "**/*.spec.ts", + "**/*.spec.js", + "**/*-test.ts", + "**/*-test.js", + "**/*.stories.js", + "**/*.stories.ts", + "**/*.stories.tsx" + ], + "references": [{ + "path": "../graphiql-toolkit" + }] +} diff --git a/packages/graphiql-build-fetcher/tsconfig.json b/packages/graphiql-build-fetcher/tsconfig.json new file mode 100644 index 00000000000..d2dff622688 --- /dev/null +++ b/packages/graphiql-build-fetcher/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../resources/tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./esm", + "composite": false, + "jsx": "react", + "baseUrl": ".", + "target": "ES5", + "module": "CommonJS", + "lib": ["DOM", "ESNext"] + }, + "include": ["src"], + "exclude": [ + "node_modules", + "**/__tests__/**", + "**/dist/**.*", + "**/*.spec.ts", + "**/*.spec.js", + "**/*-test.ts", + "**/*-test.js", + "**/*.stories.js", + "**/*.stories.ts" + ], + "references": [ + { + "path": "../graphiql-toolkit" + } + ] +} diff --git a/packages/graphiql-toolkit/package.json b/packages/graphiql-toolkit/package.json new file mode 100644 index 00000000000..56fc8a8c49f --- /dev/null +++ b/packages/graphiql-toolkit/package.json @@ -0,0 +1,21 @@ +{ + "name": "@graphiql/toolkit", + "version": "0.0.1", + "description": "Utility to build a fetcher for GraphiQL", + "contributors": [ + "Rikki Schulte (http://rikki.dev/" + ], + "repository": "http://github.com/graphql/graphiql", + "homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql#readme", + "bugs": { + "url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql" + }, + "license": "MIT", + "main": "dist/index.js", + "module": "esm/index.js", + "scripts": { + }, + "peerDependencies": { + "graphql": "^15.0.0" + } +} diff --git a/packages/graphiql-toolkit/src/index.ts b/packages/graphiql-toolkit/src/index.ts new file mode 100644 index 00000000000..7089d010187 --- /dev/null +++ b/packages/graphiql-toolkit/src/index.ts @@ -0,0 +1,3 @@ +export * from './types' + +// TODO: move the most useful utilities from graphiql to here diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts new file mode 100644 index 00000000000..23375643985 --- /dev/null +++ b/packages/graphiql-toolkit/src/types.ts @@ -0,0 +1,61 @@ +import type { + DocumentNode, + IntrospectionQuery +} from 'graphql' + +export type Observable = { + subscribe(opts: { + next: (value: T) => void; + error: (error: any) => void; + complete: () => void; + }): Unsubscribable; + subscribe( + next: (value: T) => void, + error: null | undefined, + complete: () => void, + ): Unsubscribable; + subscribe( + next?: (value: T) => void, + error?: (error: any) => void, + complete?: () => void, + ): Unsubscribable; +}; + +// These type just taken from https://github.com/ReactiveX/rxjs/blob/master/src/internal/types.ts#L41 +export type Unsubscribable = { + unsubscribe: () => void; +}; + + +export type FetcherParams = { + query: string; + operationName: string; + variables?: any; +}; + +export type FetcherOpts = { + headers?: { [key: string]: any }; + shouldPersistHeaders: boolean; + documentAST?: DocumentNode; +}; + +export type FetcherResult = + | { + data: IntrospectionQuery; + } + | string + | { data: any }; + +export type MaybePromise = T | Promise; + +export type SyncFetcherResult = + | FetcherResult + | Observable + | AsyncIterable; + +export type FetcherReturnType = MaybePromise; + +export type Fetcher = ( + graphQLParams: FetcherParams, + opts?: FetcherOpts, +) => FetcherReturnType; diff --git a/packages/graphiql-toolkit/tsconfig.esm.json b/packages/graphiql-toolkit/tsconfig.esm.json new file mode 100644 index 00000000000..a21ff9aece2 --- /dev/null +++ b/packages/graphiql-toolkit/tsconfig.esm.json @@ -0,0 +1,22 @@ +{ + "extends": "../../resources/tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "composite": true, + "jsx": "react", + "strictPropertyInitialization": false + }, + "include": ["src"], + "exclude": [ + "**/__tests__/**", + "**/dist/**.*", + "**/*.spec.ts", + "**/*.spec.js", + "**/*-test.ts", + "**/*-test.js", + "**/*.stories.js", + "**/*.stories.ts", + "**/*.stories.tsx" + ] +} diff --git a/packages/graphiql-toolkit/tsconfig.json b/packages/graphiql-toolkit/tsconfig.json new file mode 100644 index 00000000000..458ba460e72 --- /dev/null +++ b/packages/graphiql-toolkit/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../resources/tsconfig.base.cjs.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "composite": true, + "jsx": "react", + "target": "es5", + "strictPropertyInitialization": false + }, + "include": ["src"], + "exclude": [ + "**/__tests__/**", + "**/dist/**.*", + "**/*.spec.ts", + "**/*.spec.js", + "**/*-test.ts", + "**/*-test.js", + "**/*.stories.js", + "**/*.stories.ts", + "**/*.stories.tsx" + ] +} diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index b6badbcf4c5..ee336a21042 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -47,7 +47,8 @@ "copy-to-clipboard": "^3.2.0", "entities": "^2.0.0", "graphql-language-service": "^3.1.2", - "markdown-it": "^10.0.0" + "markdown-it": "^10.0.0", + "@graphiql/toolkit": "^0.0.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0", @@ -62,15 +63,19 @@ "@types/markdown-it": "^0.0.9", "@types/node": "^13.7.1", "@types/testing-library__jest-dom": "^5.0.1", + "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", "babel-loader": "^8.1.0", "babel-plugin-macros": "^2.8.0", "cross-env": "^7.0.0", "css-loader": "3.4.2", "cssnano": "^4.1.10", "express": "4.17.1", - "express-graphql": "0.9.0", + "express-graphql": "experimental-stream-defer", "fork-ts-checker-webpack-plugin": "4.1.3", "graphql": "15.4.0", + "graphql-ws": "^4.1.0", + "graphql-transport-ws": "^1.9.0", + "fetch-multipart-graphql": "^3.0.0", "html-webpack-plugin": "^4.0.4", "identity-obj-proxy": "^3.0.0", "jest": "^24.8.0", @@ -90,7 +95,7 @@ "start-server-and-test": "^1.10.11", "style-loader": "^1.1.3", "ts-loader": "^6.2.2", - "typescript": "3.8.3", + "typescript": "^4.1.3", "webpack": "4.42.1", "webpack-bundle-analyzer": "^3.6.1", "webpack-cli": "^3.3.11", diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx index 5e2823a1813..f223abbff01 100644 --- a/packages/graphiql/src/components/GraphiQL.tsx +++ b/packages/graphiql/src/components/GraphiQL.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 GraphQL Contributors. + * Copyright (c) 2020 GraphQL Contributors. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -19,14 +19,13 @@ import { print, visit, OperationDefinitionNode, - IntrospectionQuery, GraphQLType, ValidationRule, FragmentDefinitionNode, DocumentNode, } from 'graphql'; import copyToClipboard from 'copy-to-clipboard'; -import { getFragmentDependenciesForAST } from 'graphql-language-service'; +import { getFragmentDependenciesForAST } from 'graphql-language-service-utils'; import { ExecuteButton } from './ExecuteButton'; import { ImagePreview } from './ImagePreview'; @@ -54,6 +53,16 @@ import { introspectionQuerySansSubscriptions, } from '../utility/introspectionQueries'; +import type { + Fetcher, + FetcherResult, + FetcherReturnType, + FetcherOpts, + SyncFetcherResult, + Observable, + Unsubscribable, +} from '@graphiql/toolkit'; + const DEFAULT_DOC_EXPLORER_WIDTH = 350; const majorVersion = parseInt(React.version.slice(0, 2), 10); @@ -74,39 +83,6 @@ declare namespace global { export type Maybe = T | null | undefined; -export type FetcherParams = { - query: string; - operationName: string; - variables?: any; -}; - -export type FetcherOpts = { - headers?: { [key: string]: any }; - shouldPersistHeaders: boolean; - documentAST?: DocumentNode; -}; - -export type FetcherResult = - | { - data: IntrospectionQuery; - } - | string - | { data: any }; - -export type MaybePromise = T | Promise; - -export type SyncFetcherResult = - | FetcherResult - | Observable - | AsyncIterable; - -export type FetcherReturnType = MaybePromise; - -export type Fetcher = ( - graphQLParams: FetcherParams, - opts?: FetcherOpts, -) => FetcherReturnType; - type OnMouseMoveFn = Maybe< (moveEvent: MouseEvent | React.MouseEvent) => void >; @@ -1681,29 +1657,6 @@ function isPromise(value: Promise | any): value is Promise { return typeof value === 'object' && typeof value.then === 'function'; } -// These type just taken from https://github.com/ReactiveX/rxjs/blob/master/src/internal/types.ts#L41 -type Unsubscribable = { - unsubscribe: () => void; -}; - -type Observable = { - subscribe(opts: { - next: (value: T) => void; - error: (error: any) => void; - complete: () => void; - }): Unsubscribable; - subscribe( - next: (value: T) => void, - error: null | undefined, - complete: () => void, - ): Unsubscribable; - subscribe( - next?: (value: T) => void, - error?: (error: any) => void, - complete?: () => void, - ): Unsubscribable; -}; - // Duck-type Observable.take(1).toPromise() function observableToPromise(observable: Observable): Promise { return new Promise((resolve, reject) => { diff --git a/packages/graphiql/src/components/ImagePreview.tsx b/packages/graphiql/src/components/ImagePreview.tsx index d26f91017c5..c55042ae34b 100644 --- a/packages/graphiql/src/components/ImagePreview.tsx +++ b/packages/graphiql/src/components/ImagePreview.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; function tokenToURL(token: any) { if (token.type !== 'string') { @@ -49,10 +48,6 @@ export class ImagePreview extends React.Component< return url ? isImageURL(url) : false; } - static propTypes = { - token: PropTypes.any, - }; - state = { width: null, height: null, diff --git a/packages/graphiql/src/components/ToolbarSelect.tsx b/packages/graphiql/src/components/ToolbarSelect.tsx index 26ad23ffd0b..ee4b9361612 100644 --- a/packages/graphiql/src/components/ToolbarSelect.tsx +++ b/packages/graphiql/src/components/ToolbarSelect.tsx @@ -6,7 +6,6 @@ */ import React, { MouseEventHandler } from 'react'; -import PropTypes from 'prop-types'; type ToolbarSelectProps = { title?: string; @@ -157,13 +156,6 @@ export function ToolbarSelectOption({ ); } -ToolbarSelectOption.propTypes = { - onSelect: PropTypes.func, - selected: PropTypes.bool, - label: PropTypes.string, - value: PropTypes.any, -}; - function preventDefault(e: any) { e.preventDefault(); } diff --git a/packages/graphiql/src/index.ts b/packages/graphiql/src/index.ts index cf3f33a1feb..a41c6ec0766 100644 --- a/packages/graphiql/src/index.ts +++ b/packages/graphiql/src/index.ts @@ -16,16 +16,20 @@ export default GraphiQL; /** * Definitions */ +export type { + + GraphiQLProps, +} from './components/GraphiQL'; + export type { Fetcher, FetcherOpts, FetcherParams, FetcherResult, FetcherReturnType, - GraphiQLProps, SyncFetcherResult, -} from './components/GraphiQL'; - + Observable, +} from '@graphiql/toolkit' /** * Components */ diff --git a/packages/graphiql/tsconfig.esm.json b/packages/graphiql/tsconfig.esm.json index a041dec59dc..b37cf5405e6 100644 --- a/packages/graphiql/tsconfig.esm.json +++ b/packages/graphiql/tsconfig.esm.json @@ -21,10 +21,19 @@ ], "references": [ { - "path": "../graphql-language-service" + "path": "../graphql-language-service/tsconfig.esm.json" }, { - "path": "../graphql-language-service-utils" + "path": "../graphql-language-service-interface/tsconfig.esm.json" + }, + { + "path": "../graphql-language-service-parser/tsconfig.esm.json" + }, + { + "path": "../graphql-language-service-utils/tsconfig.esm.json" + }, + { + "path": "../graphiql-toolkit/tsconfig.esm.json" } ] } diff --git a/packages/graphiql/tsconfig.json b/packages/graphiql/tsconfig.json index 5974e5e74ea..cf9915b9538 100644 --- a/packages/graphiql/tsconfig.json +++ b/packages/graphiql/tsconfig.json @@ -26,6 +26,15 @@ }, { "path": "../graphql-language-service-utils" + }, + { + "path": "../graphql-language-service-parser" + }, + { + "path": "../graphql-language-service-interface" + }, + { + "path": "../graphiql-toolkit" } ] } diff --git a/packages/graphql-language-service-server/src/MessageProcessor.ts b/packages/graphql-language-service-server/src/MessageProcessor.ts index 0e5e5cb9f55..8c3eaf821c8 100644 --- a/packages/graphql-language-service-server/src/MessageProcessor.ts +++ b/packages/graphql-language-service-server/src/MessageProcessor.ts @@ -215,8 +215,8 @@ export class MessageProcessor { const rootDir = this._settings?.load?.rootDir || this._rootPath; this._rootPath = rootDir; this._loadConfigOptions = { - ...Object.keys(this._settings.load || []).reduce((agg, key) => { - const value = this._settings.load[key]; + ...Object.keys(this._settings?.load || []).reduce((agg, key) => { + const value = this._settings?.load[key]; if (value === undefined || value === null) { delete agg[key]; } diff --git a/resources/tsconfig.build.cjs.json b/resources/tsconfig.build.cjs.json index 21e707c0f6e..c949964496b 100644 --- a/resources/tsconfig.build.cjs.json +++ b/resources/tsconfig.build.cjs.json @@ -5,6 +5,12 @@ "files": [], "include": [], "references": [ + { + "path": "../packages/graphiql-build-fetcher" + }, + { + "path": "../packages/graphiql-toolkit" + }, { "path": "../packages/graphiql" }, diff --git a/resources/tsconfig.build.esm.json b/resources/tsconfig.build.esm.json index e39c8ea8876..40794dee009 100644 --- a/resources/tsconfig.build.esm.json +++ b/resources/tsconfig.build.esm.json @@ -5,6 +5,12 @@ "files": [], "include": [], "references": [ + { + "path": "../packages/graphiql-build-fetcher/tsconfig.esm.json" + }, + { + "path": "../packages/graphiql-toolkit/tsconfig.esm.json" + }, { "path": "../packages/graphiql/tsconfig.esm.json" }, diff --git a/yarn.lock b/yarn.lock index 83f6cfbdb44..d919b31a1fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2946,7 +2946,7 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== -"@cypress/listr-verbose-renderer@0.4.1": +"@cypress/listr-verbose-renderer@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a" integrity sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo= @@ -2956,7 +2956,7 @@ date-fns "^1.27.2" figures "^1.7.0" -"@cypress/request@2.88.5": +"@cypress/request@^2.88.5": version "2.88.5" resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.5.tgz#8d7ecd17b53a849cfd5ab06d5abe7d84976375d7" integrity sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA== @@ -2991,7 +2991,7 @@ debug "^4.1.1" lodash "^4.17.20" -"@cypress/xvfb@1.2.4": +"@cypress/xvfb@^1.2.4": version "1.2.4" resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== @@ -3700,6 +3700,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@lerna/add@3.20.0": version "3.20.0" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.20.0.tgz#bea7edf36fc93fb72ec34cb9ba854c48d4abf309" @@ -4407,6 +4418,11 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@n1ru4l/push-pull-async-iterable-iterator@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-2.0.1.tgz#8fc68e0e9e8bd3826d727b96ddd2afba2a7f26c7" + integrity sha512-3nDfpI/4WZgdocw75cxG4Qwmi3yp5zOleaT23EpVUhwVwlYzb4kDojl0nCZKB5lCGcTqT5wFlKepShs4Q+hymw== + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -5444,33 +5460,13 @@ resolved "https://registry.yarnpkg.com/@types/benchmark/-/benchmark-1.0.33.tgz#437641cb977db0267b8146f963763aafd0f02fef" integrity sha512-rG7Ieasa9UfZJnL72qiFvY9ivhEIYjCGgfcLLb5tJ/EL9+Mcxernj6W3HVCv/cOfJYuwNUwvVVhnrKl8iT8aqA== -"@types/blob-util@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a" - integrity sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w== - -"@types/bluebird@3.5.29": - version "3.5.29" - resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.29.tgz#7cd933c902c4fc83046517a1bef973886d00bdb6" - integrity sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw== - -"@types/chai-jquery@1.1.40": - version "1.1.40" - resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.40.tgz#445bedcbbb2ae4e3027f46fa2c1733c43481ffa1" - integrity sha512-mCNEZ3GKP7T7kftKeIs7QmfZZQM7hslGSpYzKbOlR2a2HCFf9ph4nlMRA9UnuOETeOQYJVhJQK7MwGqNZVyUtQ== +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== dependencies: - "@types/chai" "*" - "@types/jquery" "*" - -"@types/chai@*": - version "4.2.11" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50" - integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw== - -"@types/chai@4.2.7": - version "4.2.7" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.7.tgz#1c8c25cbf6e59ffa7d6b9652c78e547d9a41692d" - integrity sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g== + "@types/connect" "*" + "@types/node" "*" "@types/codemirror@0.0.82": version "0.0.82" @@ -5491,6 +5487,13 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/connect@*": + version "3.4.34" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" + integrity sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ== + dependencies: + "@types/node" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -5506,6 +5509,25 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/express-serve-static-core@^4.17.18": + version "4.17.18" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" + integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.11": + version "4.17.11" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545" + integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/fetch-mock@^7.3.2": version "7.3.2" resolved "https://registry.yarnpkg.com/@types/fetch-mock/-/fetch-mock-7.3.2.tgz#58805ba36a9357be92cc8c008dbfda937e9f7d8f" @@ -5584,27 +5606,13 @@ dependencies: jest-diff "^24.3.0" -"@types/jest@^26.0.8": - version "26.0.8" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.8.tgz#f5c5559cf25911ce227f7ce30f1f160f24966369" - integrity sha512-eo3VX9jGASSuv680D4VQ89UmuLZneNxv2MCZjfwlInav05zXVJTzfc//lavdV0GPwSxsXJTy2jALscB7Acqg0g== - dependencies: - jest-diff "^25.2.1" - pretty-format "^25.2.1" - -"@types/jquery@*": - version "3.3.34" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.34.tgz#0d3b94057063d3854adaeb579652048fec07ba6c" - integrity sha512-lW9vsVL53Xu/Nj4gi2hNmHGc4u3KKghjqTkAlO0kF5GIOPxbqqnQpgqJBzmn3yXLrPqHb6cmNJ6URnS23Vtvbg== +"@types/jest@^26.0.20": + version "26.0.20" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307" + integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA== dependencies: - "@types/sizzle" "*" - -"@types/jquery@3.3.31": - version "3.3.31" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b" - integrity sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg== - dependencies: - "@types/sizzle" "*" + jest-diff "^26.0.0" + pretty-format "^26.0.0" "@types/json-schema@^7.0.3": version "7.0.4" @@ -5621,11 +5629,6 @@ resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" integrity sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw== -"@types/lodash@4.14.149": - version "4.14.149" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" - integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== - "@types/markdown-it@^0.0.9": version "0.0.9" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.9.tgz#a5d552f95216c478e0a27a5acc1b28dcffd989ce" @@ -5633,7 +5636,12 @@ dependencies: "@types/linkify-it" "*" -"@types/minimatch@*", "@types/minimatch@3.0.3": +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== @@ -5645,11 +5653,6 @@ dependencies: "@types/node" "*" -"@types/mocha@5.2.7": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - "@types/node@*", "@types/node@>= 8", "@types/node@^13.11.1": version "13.11.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" @@ -5695,6 +5698,16 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/qs@*": + version "6.9.5" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" + integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + "@types/reach__router@^1.2.3": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.5.tgz#14e1e981cccd3a5e50dc9e969a72de0b9d472f6d" @@ -5710,13 +5723,6 @@ dependencies: "@types/react" "*" -"@types/react-dom@^16.9.6": - version "16.9.10" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.10.tgz#4485b0bec3d41f856181b717f45fd7831101156f" - integrity sha512-ItatOrnXDMAYpv6G8UCk2VhbYVTjZT9aorLtA/OzDN9XJ2GKcfam68jutoAcILdRjsRUO8qb7AmyObF77Q8QFw== - dependencies: - "@types/react" "^16" - "@types/react-syntax-highlighter@11.0.4": version "11.0.4" resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" @@ -5739,40 +5745,20 @@ "@types/prop-types" "*" csstype "^2.2.0" -"@types/react@^16", "@types/react@^16.9.34": - version "16.14.2" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.2.tgz#85dcc0947d0645349923c04ccef6018a1ab7538c" - integrity sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/sinon-chai@3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.3.tgz#afe392303dda95cc8069685d1e537ff434fa506e" - integrity sha512-TOUFS6vqS0PVL1I8NGVSNcFaNJtFoyZPXZ5zur+qlhDfOmQECZZM4H4kKgca6O8L+QceX/ymODZASfUfn+y4yQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.0.tgz#5b70a360f55645dd64f205defd2a31b749a59799" - integrity sha512-v2TkYHkts4VXshMkcmot/H+ERZ2SevKa10saGaJPGCJ8vh3lKrC4u663zYEeRZxep+VbG6YRDtQ6gVqw9dYzPA== +"@types/serve-static@*": + version "1.13.9" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.9.tgz#aacf28a85a05ee29a11fb7c3ead935ac56f33e4e" + integrity sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA== dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinon@7.5.1": - version "7.5.1" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.1.tgz#d27b81af0d1cfe1f9b24eebe7a24f74ae40f5b7c" - integrity sha512-EZQUP3hSZQyTQRfiLqelC9NMWd1kqLcmQE0dMiklxBkgi84T+cHOhnKpgk4NnOWpGX863yE6+IaGnOXUNFqDnQ== + "@types/mime" "^1" + "@types/node" "*" -"@types/sinonjs__fake-timers@*": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" - integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== +"@types/sinonjs__fake-timers@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae" + integrity sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg== -"@types/sizzle@*", "@types/sizzle@2.3.2": +"@types/sizzle@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== @@ -5913,6 +5899,13 @@ dependencies: "@types/node" "*" +"@types/ws@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.0.tgz#499690ea08736e05a8186113dac37769ab251a0e" + integrity sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -6682,16 +6675,16 @@ aproba@^2.0.0: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" - integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== - arch@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf" integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ== +arch@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" @@ -6949,7 +6942,7 @@ async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.1.0: +async@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== @@ -7583,7 +7576,7 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.4.1, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.1: +bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.4.1, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.1, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -8007,7 +8000,7 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cachedir@2.3.0: +cachedir@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== @@ -8206,7 +8199,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -check-more-types@2.24.0: +check-more-types@2.24.0, check-more-types@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= @@ -8353,7 +8346,7 @@ cli-spinners@^1.1.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" integrity sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg== -cli-table3@0.5.1: +cli-table3@0.5.1, cli-table3@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== @@ -8567,11 +8560,6 @@ command-exists@^1.2.6: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== -commander@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" - integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== - commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -8587,7 +8575,7 @@ commander@^5.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -common-tags@1.8.0, common-tags@^1.8.0: +common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== @@ -9019,6 +9007,11 @@ create-react-context@0.3.0, create-react-context@^0.3.0: gud "^1.0.0" warning "^4.0.3" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-env@^7.0.0, cross-env@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" @@ -9372,11 +9365,6 @@ csstype@^2.2.0, csstype@^2.5.7, csstype@^2.6.6, csstype@^2.6.9: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== -csstype@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8" - integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ== - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -9389,57 +9377,48 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -cypress@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.3.0.tgz#74694c2407846119368a6aecc456b3ee1a8ee32b" - integrity sha512-xO1oef4ns4koDAkQROGJIhKKhGHDOKfOmlirwP1QAk9w/no+YJpN7HZ6IUPiXwWw3C7xVLjScoI8Dad0z5uTTg== - dependencies: - "@cypress/listr-verbose-renderer" "0.4.1" - "@cypress/request" "2.88.5" - "@cypress/xvfb" "1.2.4" - "@types/blob-util" "1.3.3" - "@types/bluebird" "3.5.29" - "@types/chai" "4.2.7" - "@types/chai-jquery" "1.1.40" - "@types/jquery" "3.3.31" - "@types/lodash" "4.14.149" - "@types/minimatch" "3.0.3" - "@types/mocha" "5.2.7" - "@types/sinon" "7.5.1" - "@types/sinon-chai" "3.2.3" - "@types/sizzle" "2.3.2" - arch "2.1.1" - bluebird "3.7.2" - cachedir "2.3.0" - chalk "2.4.2" - check-more-types "2.24.0" - cli-table3 "0.5.1" - commander "4.1.0" - common-tags "1.8.0" - debug "4.1.1" - eventemitter2 "4.1.2" - execa "1.0.0" - executable "4.1.1" - extract-zip "1.7.0" - fs-extra "8.1.0" - getos "3.1.4" - is-ci "2.0.0" - is-installed-globally "0.1.0" - lazy-ass "1.6.0" - listr "0.14.3" - lodash "4.17.15" - log-symbols "3.0.0" - minimist "1.2.5" - moment "2.24.0" - ospath "1.2.2" - pretty-bytes "5.3.0" - ramda "0.26.1" - request-progress "3.0.0" - supports-color "7.1.0" - tmp "0.1.0" - untildify "4.0.0" - url "0.11.0" - yauzl "2.10.0" +cypress@^4.7.0: + version "4.12.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.12.1.tgz#0ead1b9f4c0917d69d8b57f996b6e01fe693b6ec" + integrity sha512-9SGIPEmqU8vuRA6xst2CMTYd9sCFCxKSzrHt0wr+w2iAQMCIIsXsQ5Gplns1sT6LDbZcmLv6uehabAOl3fhc9Q== + dependencies: + "@cypress/listr-verbose-renderer" "^0.4.1" + "@cypress/request" "^2.88.5" + "@cypress/xvfb" "^1.2.4" + "@types/sinonjs__fake-timers" "^6.0.1" + "@types/sizzle" "^2.3.2" + arch "^2.1.2" + bluebird "^3.7.2" + cachedir "^2.3.0" + chalk "^2.4.2" + check-more-types "^2.24.0" + cli-table3 "~0.5.1" + commander "^4.1.1" + common-tags "^1.8.0" + debug "^4.1.1" + eventemitter2 "^6.4.2" + execa "^1.0.0" + executable "^4.1.1" + extract-zip "^1.7.0" + fs-extra "^8.1.0" + getos "^3.2.1" + is-ci "^2.0.0" + is-installed-globally "^0.3.2" + lazy-ass "^1.6.0" + listr "^0.14.3" + lodash "^4.17.19" + log-symbols "^3.0.0" + minimist "^1.2.5" + moment "^2.27.0" + ospath "^1.2.2" + pretty-bytes "^5.3.0" + ramda "~0.26.1" + request-progress "^3.0.0" + supports-color "^7.1.0" + tmp "~0.1.0" + untildify "^4.0.0" + url "^0.11.0" + yauzl "^2.10.0" d@1, d@^1.0.1: version "1.0.1" @@ -9761,6 +9740,11 @@ diff-sequences@^25.2.6: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -10664,10 +10648,10 @@ event-stream@=3.3.4: stream-combiner "~0.0.4" through "~2.3.1" -eventemitter2@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-4.1.2.tgz#0e1a8477af821a6ef3995b311bf74c23a5247f15" - integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU= +eventemitter2@^6.4.2: + version "6.4.3" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820" + integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ== eventemitter3@^3.1.0: version "3.1.2" @@ -10711,19 +10695,6 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== -execa@1.0.0, execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@3.4.0, execa@^3.2.0, execa@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" @@ -10766,7 +10737,20 @@ execa@^0.8.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -executable@4.1.1: +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== @@ -10858,6 +10842,16 @@ express-graphql@0.9.0: http-errors "^1.7.3" raw-body "^2.4.1" +express-graphql@experimental-stream-defer: + version "0.12.0-experimental-stream-defer.1" + resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.12.0-experimental-stream-defer.1.tgz#1723f400cd94065e9a584ad4677a0d2ce4a7e7d1" + integrity sha512-VqSOUgN00Sbs+OO7sYWvZVtGwkLbWK6D71N07Q8iuM9NcJOSQH/g0UvODd1eXLq/nEOQTWLyd7W1s9n1UWxZsA== + dependencies: + accepts "^1.3.7" + content-type "^1.0.4" + http-errors "1.8.0" + raw-body "^2.4.1" + express@4.17.1, express@^4.16.3, express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -10951,7 +10945,7 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-zip@1.7.0: +extract-zip@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== @@ -11088,6 +11082,11 @@ fetch-mock@6.5.2: glob-to-regexp "^0.4.0" path-to-regexp "^2.2.1" +fetch-multipart-graphql@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/fetch-multipart-graphql/-/fetch-multipart-graphql-3.0.0.tgz#61c9c1623beb4a7330e86ee72e6906148cd20acf" + integrity sha512-asrZG9CMaRUJmzqU+jqyBp52IB3MEzO38bhrPVB73BNAZ8ShBYgQUPOR9d/kYO4dfIrJIki/sTjeNYbUGuqOzQ== + figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" @@ -11503,15 +11502,6 @@ fs-exists-sync@^0.1.0: resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0= -fs-extra@8.1.0, fs-extra@^8.0.1, fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@9.0.1, fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -11551,6 +11541,15 @@ fs-extra@^7.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^8.0.1, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" @@ -11739,12 +11738,12 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getos@3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.4.tgz#29cdf240ed10a70c049add7b6f8cb08c81876faf" - integrity sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw== +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== dependencies: - async "^3.1.0" + async "^3.2.0" getpass@^0.1.1: version "0.1.7" @@ -11865,13 +11864,20 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, gl once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0, global-dirs@^0.1.1: +global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= dependencies: ini "^1.3.4" +global-dirs@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" + integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== + dependencies: + ini "1.3.7" + global-modules@2.0.0, global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -12031,6 +12037,7 @@ grapheme-breaker@^0.3.2: "graphiql@file:packages/graphiql": version "1.3.2" dependencies: + "@graphiql/toolkit" "^0.0.1" codemirror "^5.54.0" codemirror-graphql "^0.15.2" copy-to-clipboard "^3.2.0" @@ -12054,6 +12061,18 @@ graphql-config@^3.0.2, graphql-config@^3.0.3: string-env-interpolation "1.0.1" tslib "^2.0.0" +graphql-transport-ws@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/graphql-transport-ws/-/graphql-transport-ws-1.9.0.tgz#81891de870619d4e39242954a9e0f832dd980179" + integrity sha512-yrw7nIR4V+lWWRCVCa5ogagHWjlPLDO/Ld1177V4S4fqcMO4qVJyTgMKbTcAUXBhlEATqN7Scb5Oy8Ly+zKFwg== + dependencies: + ws "^7.3.1" + +graphql-ws@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.1.0.tgz#cebe281474b5501d7be66210fb5711633b27fd78" + integrity sha512-DxJP1y2YzCqVLy7DrQN0iuR2l48vMOBWukX2d/J9aN2o5x9un5psIIq/2UFRh91UGARmfvPH86y1p4qbC1dITg== + graphql@14.6.0: version "14.6.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.6.0.tgz#57822297111e874ea12f5cd4419616930cd83e49" @@ -12472,7 +12491,7 @@ http-errors@1.7.3, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@^1.7.3: +http-errors@1.8.0, http-errors@^1.7.3: version "1.8.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== @@ -12760,6 +12779,11 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +ini@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -13003,7 +13027,7 @@ is-callable@^1.2.0: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== -is-ci@2.0.0, is-ci@^2.0.0: +is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== @@ -13180,13 +13204,13 @@ is-html@^1.1.0: dependencies: html-tags "^1.0.0" -is-installed-globally@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= +is-installed-globally@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" + integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" + global-dirs "^2.0.1" + is-path-inside "^3.0.1" is-map@^2.0.1: version "2.0.1" @@ -13246,13 +13270,6 @@ is-path-in-cwd@^2.0.0: dependencies: is-path-inside "^2.1.0" -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= - dependencies: - path-is-inside "^1.0.1" - is-path-inside@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" @@ -13260,6 +13277,11 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.0.2" +is-path-inside@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" + integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== + is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -13472,6 +13494,14 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== + dependencies: + node-fetch "^2.6.1" + whatwg-fetch "^3.4.1" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -13707,6 +13737,16 @@ jest-diff@^25.1.0, jest-diff@^25.2.1, jest-diff@^25.3.0: jest-get-type "^25.2.6" pretty-format "^25.3.0" +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -13817,6 +13857,11 @@ jest-get-type@^25.2.6: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -14708,7 +14753,7 @@ last-call-webpack-plugin@^3.0.0: lodash "^4.17.5" webpack-sources "^1.1.0" -lazy-ass@1.6.0: +lazy-ass@1.6.0, lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= @@ -14857,7 +14902,7 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr@0.14.3, listr@^0.14.3: +listr@^0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== @@ -15070,13 +15115,6 @@ log-ok@^0.1.1: ansi-green "^0.1.1" success-symbol "^0.1.0" -log-symbols@3.0.0, log-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -15091,6 +15129,13 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -15657,7 +15702,7 @@ minimist-options@^3.0.1: arrify "^1.0.1" is-plain-obj "^1.1.0" -minimist@1.2.5, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -15761,10 +15806,10 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -moment@2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== +moment@^2.27.0: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== monaco-editor-webpack-plugin@^1.9.0: version "1.9.0" @@ -16521,7 +16566,7 @@ osenv@^0.1.4, osenv@^0.1.5: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -ospath@1.2.2: +ospath@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= @@ -16910,7 +16955,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@1.0.2, path-is-inside@^1.0.1, path-is-inside@^1.0.2: +path-is-inside@1.0.2, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -17940,16 +17985,16 @@ prettier@^2.0.4: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== -pretty-bytes@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" - integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== - pretty-bytes@^5.1.0: version "5.4.1" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.4.1.tgz#cd89f79bbcef21e3d21eb0da68ffe93f803e884b" integrity sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA== +pretty-bytes@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" + integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== + pretty-error@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" @@ -17988,6 +18033,16 @@ pretty-format@^25.2.1, pretty-format@^25.3.0: ansi-styles "^4.0.0" react-is "^16.12.0" +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + pretty-format@^26.4.2: version "26.4.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.4.2.tgz#d081d032b398e801e2012af2df1214ef75a81237" @@ -18281,16 +18336,16 @@ raf@^3.4.1: dependencies: performance-now "^2.1.0" -ramda@0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" - integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== - ramda@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= +ramda@~0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" + integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== + randomatic@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" @@ -18557,6 +18612,11 @@ react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-i resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" + integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -19116,7 +19176,7 @@ replace-ext@0.0.1: resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= -request-progress@3.0.0: +request-progress@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= @@ -20677,13 +20737,6 @@ success-symbol@^0.1.0: resolved "https://registry.yarnpkg.com/success-symbol/-/success-symbol-0.1.0.tgz#24022e486f3bf1cdca094283b769c472d3b72897" integrity sha1-JAIuSG878c3KCUKDt2nEctO3KJc= -supports-color@7.1.0, supports-color@^7.0.0, supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== - dependencies: - has-flag "^4.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -20710,6 +20763,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" @@ -21024,13 +21084,6 @@ tiny-inflate@^1.0.0: resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -21038,6 +21091,13 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -21220,6 +21280,18 @@ ts-node@^8.10.2: source-map-support "^0.5.17" yn "3.1.1" +ts-node@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + ts-pnp@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" @@ -21373,7 +21445,7 @@ typescript@^3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== -typescript@^4.0.3: +typescript@^4.0.3, typescript@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== @@ -21545,7 +21617,7 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -untildify@4.0.0: +untildify@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== @@ -21592,7 +21664,7 @@ url-parse@^1.4.3, url-parse@^1.4.7: querystringify "^2.1.1" requires-port "^1.0.0" -url@0.11.0, url@^0.11.0: +url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= @@ -22237,7 +22309,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" -whatwg-fetch@^3.0.0: +whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: version "3.5.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868" integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A== @@ -22632,6 +22704,11 @@ ws@^7.2.1, ws@^7.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== +ws@^7.3.1, ws@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" + integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -22798,7 +22875,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.1" -yauzl@2.10.0, yauzl@^2.10.0: +yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= From 27081f1abaa58fedd0ad366fb9b10ccf6f846c47 Mon Sep 17 00:00:00 2001 From: Rikki Date: Wed, 20 Jan 2021 14:44:59 -0500 Subject: [PATCH 2/8] chore: format/eslint fixes --- .eslintrc.js | 32 +- package.json | 18 +- .../components/__tests__/GraphiQL.spec.tsx | 7 +- .../src/utility/__tests__/mergeAst.spec.ts | 2 +- packages/graphiql-build-fetcher/README.md | 103 ++-- .../src/__tests__/buildFetcher.spec.ts | 15 +- .../src/__tests__/lib.spec.ts | 19 +- .../src/buildFetcher.ts | 10 +- packages/graphiql-build-fetcher/src/index.ts | 4 +- packages/graphiql-build-fetcher/src/types.ts | 4 +- .../graphiql-build-fetcher/test/server.ts | 6 +- .../graphiql-build-fetcher/tsconfig.esm.json | 8 +- packages/graphiql-toolkit/package.json | 3 +- packages/graphiql-toolkit/src/index.ts | 2 +- packages/graphiql-toolkit/src/types.ts | 6 +- packages/graphiql-toolkit/tsconfig.esm.json | 3 +- packages/graphiql-toolkit/tsconfig.json | 1 + .../components/__tests__/GraphiQL.spec.tsx | 4 +- packages/graphiql/src/index.ts | 7 +- .../src/utility/__tests__/mergeAst.spec.ts | 2 +- packages/graphiql/test/e2e-server.js | 2 +- .../src/__tests__/OnlineParserUtils.ts | 3 +- .../src/__tests__/GraphQLCache-test.ts | 4 +- yarn.lock | 543 ++++++++++++++++-- 24 files changed, 599 insertions(+), 209 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index feba88576d6..7239f96493a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,6 +30,7 @@ module.exports = { node: true, browser: true, jest: true, + 'jest/globals': true, }, extends: [ @@ -294,6 +295,9 @@ module.exports = { 'react/prefer-stateless-function': 'error', 'react/react-in-jsx-scope': 'error', 'react/self-closing-comp': 'error', + 'react/display-name': 'warn', + // Jest rules + 'jest/no-conditional-expect': 0, }, plugins: ['import', 'prefer-object-spread', '@typescript-eslint'], @@ -310,14 +314,18 @@ module.exports = { }, }, { + excludedFiles: ['**/cypress/**/*.{js,ts}'], files: [ - 'packages/{*graphql-*,graphiql}/src/**', '**/__{tests,mocks}__/*.{js,jsx,ts,tsx}', + '**/*.spec.{ts,js.jsx.tsx}', ], extends: ['plugin:jest/recommended'], env: { 'jest/globals': true, }, + rules: { + 'jest/no-conditional-expect': 0, + }, }, // Rules for TypeScript only { @@ -326,28 +334,6 @@ module.exports = { 'no-unused-vars': 'off', }, }, - // Rules for Babel & Flow only - { - files: ['packages/codemirror-graphql/src/**/*.js'], - parser: 'babel-eslint', - plugins: ['flowtype', 'babel'], - rules: { - // flowtype (https://github.com/gajus/eslint-plugin-flowtype) - 'flowtype/boolean-style': 1, - 'flowtype/define-flow-type': 1, - 'flowtype/no-dupe-keys': 0, - 'flowtype/no-primitive-constructor-types': 1, - 'flowtype/no-weak-types': 0, - 'flowtype/require-parameter-type': 0, - 'flowtype/require-return-type': 0, - 'flowtype/require-valid-file-annotation': 0, - 'flowtype/require-variable-type': 0, - 'flowtype/sort-keys': 0, - 'flowtype/type-id-match': 0, - 'flowtype/use-flow-type': 1, - 'flowtype/valid-syntax': 0, - }, - }, { // Converted from 'dependencies' options in ancient config files: ['**/spec/**', '**/sample-*/**'], diff --git a/package.json b/package.json index 3294665a2f0..42805a2556d 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "eslint": "eslint --ext=ts,js,jsx,tsx .", "lint": "yarn eslint && yarn lint-check && yarn pretty-check", "lint-fix": "yarn eslint --fix", - "lint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check", + "lint-check": "eslint-config-prettier .eslintrc.js", "check": "flow check --show-all-errors && yarn tsc --dry", "pretty": "node resources/pretty.js", "pretty-check": "node resources/pretty.js --check", @@ -88,24 +88,24 @@ "@types/prettier": "^2.0.0", "@types/theme-ui": "^0.3.1", "@types/ws": "^7.4.0", - "@typescript-eslint/eslint-plugin": "^2.27.0", - "@typescript-eslint/parser": "^2.27.0", + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0", "babel-eslint": "^10.1.0", "babel-jest": "^25.3.0", "conventional-changelog-conventionalcommits": "^4.2.3", "copy": "^0.3.2", "cross-env": "^7.0.2", "cypress": "^4.7.0", - "eslint": "^6.8.0", - "eslint-config-prettier": "^6.10.1", + "eslint": "^7.18.0", + "eslint-config-prettier": "^7.2.0", "eslint-plugin-babel": "^5.3.0", "eslint-plugin-cypress": "^2.10.3", "eslint-plugin-flowtype": "4.7.0", "eslint-plugin-import": "^2.20.2", - "eslint-plugin-jest": "^23.8.2", - "eslint-plugin-prefer-object-spread": "1.2.1", - "eslint-plugin-react": "7.19.0", - "eslint-plugin-react-hooks": "^3.0.0", + "eslint-plugin-jest": "^24.1.3", + "eslint-plugin-prefer-object-spread": "^1.2.1", + "eslint-plugin-react": "^7.22.0", + "eslint-plugin-react-hooks": "^4.2.0", "fetch-mock": "6.5.2", "flow-bin": "^0.119.1", "graphql": "^15.4.0", diff --git a/packages/graphiql-2-rfc-context/src/components/__tests__/GraphiQL.spec.tsx b/packages/graphiql-2-rfc-context/src/components/__tests__/GraphiQL.spec.tsx index 4723d5adf42..6168b150c34 100644 --- a/packages/graphiql-2-rfc-context/src/components/__tests__/GraphiQL.spec.tsx +++ b/packages/graphiql-2-rfc-context/src/components/__tests__/GraphiQL.spec.tsx @@ -251,7 +251,7 @@ describe('GraphiQL', () => { expect(container.querySelectorAll('.history-label')).toHaveLength(2); }); - it('will save query if variables are different ', () => { + it('will save query if variables are different', () => { const { getByTitle, container } = render( { expect(container.querySelectorAll('.history-label')).toHaveLength(2); }); - it('will save query if headers are different ', () => { + it('will save query if headers are different', () => { const { getByTitle, getByText, container } = render( { const MyFunctionalComponent = () => { return null; }; - const wrap = component => () => ( -
{component}
- ); it('properly ignores fragments', () => { const myFragment = ( diff --git a/packages/graphiql-2-rfc-context/src/utility/__tests__/mergeAst.spec.ts b/packages/graphiql-2-rfc-context/src/utility/__tests__/mergeAst.spec.ts index f6cd0bb605d..866a3561ba4 100644 --- a/packages/graphiql-2-rfc-context/src/utility/__tests__/mergeAst.spec.ts +++ b/packages/graphiql-2-rfc-context/src/utility/__tests__/mergeAst.spec.ts @@ -30,7 +30,7 @@ const schema = new GraphQLSchema({ describe('MergeAst', () => { fixtures.forEach(fixture => { - it(fixture.desc, () => { + it(`${fixture.desc}`, () => { const result = print(mergeAst(parse(fixture.query))).replace(/\s/g, ''); const result2 = print(mergeAst(parse(fixture.query), schema)).replace( /\s/g, diff --git a/packages/graphiql-build-fetcher/README.md b/packages/graphiql-build-fetcher/README.md index 78b768555a6..a5cd7b16ceb 100644 --- a/packages/graphiql-build-fetcher/README.md +++ b/packages/graphiql-build-fetcher/README.md @@ -6,71 +6,74 @@ under the hood, it uses [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) ### Setup -[`graphiql`](https://npmjs.com/package/graphiql) and thus `react` and `react-dom` should already be installed. +[`graphiql`](https://npmjs.com/package/graphiql) and thus `react` and `react-dom` should already be installed. you'll need to install `@graphiql/build-fetcher` npm + ```bash npm install --save @graphiql/build-fetcher ``` yarn + ```bash yarn add @graphiql/build-fetcher ``` ### Getting Started -We have a few flexible options to get you started with the client. It's meant to cover the majority of common use cases with a simple encapsulation. +We have a few flexible options to get you started with the client. It's meant to cover the majority of common use cases with a simple encapsulation. #### HTTP/Multipart Usage Here's a simple example. In this case, a websocket client isn't even initialized, only http (with multipart `@stream` and `@defer` support of course!). ```ts -import * as React from "react" -import ReactDOM from "react-dom" -import { GraphiQL } from "graphiql" -import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" +import * as React from 'react'; +import ReactDOM from 'react-dom'; +import { GraphiQL } from 'graphiql'; +import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; -const url = 'https://myschema.com/graphql' +const url = 'https://myschema.com/graphql'; const fetcher = buildGraphiQLFetcher({ url }); export const App = () => ; -ReactDOM.render(document.getElementByID('graphiql'), ) +ReactDOM.render(document.getElementByID('graphiql'), ); ``` -#### HTTP/Multipart & Websockets + +#### HTTP/Multipart & Websockets Just by providing the `subscriptionsUrl`, you can generate a `graphql-ws` client ```ts -import * as React from "react" -import ReactDOM from "react-dom" -import { GraphiQL } from "graphiql" -import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" +import * as React from 'react'; +import ReactDOM from 'react-dom'; +import { GraphiQL } from 'graphiql'; +import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; -const url = 'https://myschema.com/graphql' +const url = 'https://myschema.com/graphql'; -const subscriptionsUrl = "wss://myschema.com/graphql" +const subscriptionsUrl = 'wss://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ - url, - subscriptionsUrl +const fetcher = buildGraphiQLFetcher({ + url, + subscriptionsUrl, }); export const App = () => ; -ReactDOM.render(document.getElementByID('graphiql'), ) +ReactDOM.render(document.getElementByID('graphiql'), ); ``` You can further customize the `wsClient` implementation below ### Options -#### `url` (*required*) +#### `url` (_required_) This is url used for all `HTTP` requests, and for schema introspection. @@ -92,55 +95,53 @@ Pass a custom fetch implementation such as `isomorphic-feth` ### Customization Examples - - #### Custom `wsClient` Example + Just by providing the `subscriptionsUrl` ```ts -import * as React from "react" -import ReactDOM from "react-dom" -import { GraphiQL } from "graphiql" -import { createClient } from "graphql-ws" -import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" - -const url = 'https://myschema.com/graphql' - -const subscriptionsUrl = "wss://myschema.com/graphql" - -const fetcher = buildGraphiQLFetcher({ - url, - wsClient: createClient({ - url: subscriptionsUrl , - keepAlive: 2000 - }) +import * as React from 'react'; +import ReactDOM from 'react-dom'; +import { GraphiQL } from 'graphiql'; +import { createClient } from 'graphql-ws'; +import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; + +const url = 'https://myschema.com/graphql'; + +const subscriptionsUrl = 'wss://myschema.com/graphql'; + +const fetcher = buildGraphiQLFetcher({ + url, + wsClient: createClient({ + url: subscriptionsUrl, + keepAlive: 2000, + }), }); export const App = () => ; -ReactDOM.render(document.getElementByID('graphiql'), ) +ReactDOM.render(document.getElementByID('graphiql'), ); ``` - #### Custom `fetcher` Example + For SSR, we might want to use something like `isomorphic-fetch` ```ts -import * as React from "react" -import ReactDOM from "react-dom" -import { GraphiQL } from "graphiql" -import { fetch } from "isomorphic-fetch" -import { buildGraphiQLFetcher } from "@graphiql/build-fetcher" - -const url = 'https://myschema.com/graphql' +import * as React from 'react'; +import ReactDOM from 'react-dom'; +import { GraphiQL } from 'graphiql'; +import { fetch } from 'isomorphic-fetch'; +import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +const url = 'https://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ - url, - fetch +const fetcher = buildGraphiQLFetcher({ + url, + fetch, }); export const App = () => ; -ReactDOM.render(document.getElementByID('graphiql'), ) +ReactDOM.render(document.getElementByID('graphiql'), ); ``` diff --git a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts index 194d3db2b5a..957ca137737 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts +++ b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts @@ -17,13 +17,13 @@ import { } from '../lib'; import { createClient } from 'graphql-ws'; -const exampleWithSubscripton = /* GraphQL */ ` -subscription Example { - example -} -query SomethingElse { - example -} +const exampleWithSubscripton = /* GraphQL */ ` + subscription Example { + example + } + query SomethingElse { + example + } `; const exampleWithSubscriptonNode = parse(exampleWithSubscripton); @@ -44,7 +44,6 @@ describe('buildGraphiQLFetcher', () => { expect(createMultipartFetcher.mock.calls).toEqual([ [{ enableMultipart: true, url: serverURL }], ]); - }); it('returns fetcher without websocket client or multipart', () => { createWebsocketsClient.mockReturnValue(true); diff --git a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts index ad436694c68..a397830b794 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts +++ b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts @@ -1,18 +1,15 @@ import { parse } from 'graphql'; import { isSubcriptionWithName, createWebsocketsClient } from '../lib'; -import "isomorphic-fetch" +import 'isomorphic-fetch'; +jest.mock('graphql-ws'); -jest.mock('graphql-ws') +jest.mock('graphql-transport-ws'); -jest.mock("graphql-transport-ws") +import { createClient } from 'graphql-ws'; - - -import { createClient } from "graphql-ws" - -import { createClient as createLegacyClient } from "graphql-transport-ws" +import { createClient as createLegacyClient } from 'graphql-transport-ws'; const exampleWithSubscripton = /* GraphQL */ parse(` subscription Example { @@ -44,14 +41,14 @@ describe('isSubcriptionWithName', () => { describe('createWebsocketsClient', () => { afterEach(() => { // @ts-ignore - createClient.mockRestore() - }) + createClient.mockRestore(); + }); it('creates a websockets client using provided url', () => { createWebsocketsClient({ url: 'https://example.com', subscriptionsUrl: 'wss://example.com', }); // @ts-ignore - expect(createClient.mock.calls[0][0]).toEqual({"url": "wss://example.com"}) + expect(createClient.mock.calls[0][0]).toEqual({ url: 'wss://example.com' }); }); }); diff --git a/packages/graphiql-build-fetcher/src/buildFetcher.ts b/packages/graphiql-build-fetcher/src/buildFetcher.ts index 13c328df784..ca9b4a4c9b9 100644 --- a/packages/graphiql-build-fetcher/src/buildFetcher.ts +++ b/packages/graphiql-build-fetcher/src/buildFetcher.ts @@ -1,4 +1,4 @@ -import type { Client } from 'graphql-ws' +import type { Client } from 'graphql-ws'; import type { Fetcher } from '@graphiql/toolkit'; import type { BuildFetcherOptions } from './types'; @@ -10,9 +10,6 @@ import { createWebsocketsFetcher, } from './lib'; - - - /** * build a GraphiQL fetcher that is: * - backwards compatible @@ -23,7 +20,7 @@ import { */ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { // hoist the wsClient to global scope, so that we can unsubscribe/re-subscribe -// even when the function is re-invoked. + // even when the function is re-invoked. let wsClient: Client | null = null; let httpFetch; @@ -40,7 +37,6 @@ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { throw Error('No valid fetcher implementation available'); } - let wsFetcher: Fetcher | null = null; // user provided wsClient @@ -57,7 +53,7 @@ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { if (wsClient) { wsFetcher = createWebsocketsFetcher(wsClient); } else if (options.subscriptionsUrl) { - throw Error("subscriptions client failed to initialize") + throw Error('subscriptions client failed to initialize'); } const simpleFetcher = createSimpleFetcher(options, httpFetch); diff --git a/packages/graphiql-build-fetcher/src/index.ts b/packages/graphiql-build-fetcher/src/index.ts index d11e5722d6c..5ccb2a018aa 100644 --- a/packages/graphiql-build-fetcher/src/index.ts +++ b/packages/graphiql-build-fetcher/src/index.ts @@ -1,2 +1,2 @@ -export type { BuildFetcherOptions} from './types' -export { buildGraphiQLFetcher } from './buildFetcher' +export type { BuildFetcherOptions } from './types'; +export { buildGraphiQLFetcher } from './buildFetcher'; diff --git a/packages/graphiql-build-fetcher/src/types.ts b/packages/graphiql-build-fetcher/src/types.ts index 382bf263b5b..f794c7d55a7 100644 --- a/packages/graphiql-build-fetcher/src/types.ts +++ b/packages/graphiql-build-fetcher/src/types.ts @@ -1,4 +1,4 @@ -import type { Client } from "graphql-ws" +import type { Client } from 'graphql-ws'; /** * Options for creating a sinple, spec-compliant GraphiQL fetcher @@ -19,7 +19,7 @@ export interface BuildFetcherOptions { wsClient?: Client; /** * Headers you can provide statically. - * + * * If you enable the headers editor and the user provides * A header you set statically here, it will be overriden by their value. */ diff --git a/packages/graphiql-build-fetcher/test/server.ts b/packages/graphiql-build-fetcher/test/server.ts index da426930e57..41b6ee15dcc 100644 --- a/packages/graphiql-build-fetcher/test/server.ts +++ b/packages/graphiql-build-fetcher/test/server.ts @@ -62,18 +62,18 @@ try { server, path: '/graphql', }); - const port = process.env.PORT || 3000 + const port = process.env.PORT || 3000; server.listen(port, () => { useServer( { schema, execute, subscribe, - connectionInitWaitTimeout: 2000 + connectionInitWaitTimeout: 2000, }, wsServer, ); - console.log(`listening on ${port}`) + console.log(`listening on ${port}`); }); } catch (err) { console.error(err); diff --git a/packages/graphiql-build-fetcher/tsconfig.esm.json b/packages/graphiql-build-fetcher/tsconfig.esm.json index 04b6f62e0a2..f5615d848f6 100644 --- a/packages/graphiql-build-fetcher/tsconfig.esm.json +++ b/packages/graphiql-build-fetcher/tsconfig.esm.json @@ -21,7 +21,9 @@ "**/*.stories.ts", "**/*.stories.tsx" ], - "references": [{ - "path": "../graphiql-toolkit" - }] + "references": [ + { + "path": "../graphiql-toolkit" + } + ] } diff --git a/packages/graphiql-toolkit/package.json b/packages/graphiql-toolkit/package.json index 56fc8a8c49f..b22c51ecb51 100644 --- a/packages/graphiql-toolkit/package.json +++ b/packages/graphiql-toolkit/package.json @@ -13,8 +13,7 @@ "license": "MIT", "main": "dist/index.js", "module": "esm/index.js", - "scripts": { - }, + "scripts": {}, "peerDependencies": { "graphql": "^15.0.0" } diff --git a/packages/graphiql-toolkit/src/index.ts b/packages/graphiql-toolkit/src/index.ts index 7089d010187..9690aedea3c 100644 --- a/packages/graphiql-toolkit/src/index.ts +++ b/packages/graphiql-toolkit/src/index.ts @@ -1,3 +1,3 @@ -export * from './types' +export * from './types'; // TODO: move the most useful utilities from graphiql to here diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts index 23375643985..be2fc0dbae8 100644 --- a/packages/graphiql-toolkit/src/types.ts +++ b/packages/graphiql-toolkit/src/types.ts @@ -1,7 +1,4 @@ -import type { - DocumentNode, - IntrospectionQuery -} from 'graphql' +import type { DocumentNode, IntrospectionQuery } from 'graphql'; export type Observable = { subscribe(opts: { @@ -26,7 +23,6 @@ export type Unsubscribable = { unsubscribe: () => void; }; - export type FetcherParams = { query: string; operationName: string; diff --git a/packages/graphiql-toolkit/tsconfig.esm.json b/packages/graphiql-toolkit/tsconfig.esm.json index a21ff9aece2..e0624bdc43f 100644 --- a/packages/graphiql-toolkit/tsconfig.esm.json +++ b/packages/graphiql-toolkit/tsconfig.esm.json @@ -5,7 +5,8 @@ "outDir": "./dist", "composite": true, "jsx": "react", - "strictPropertyInitialization": false + "strictPropertyInitialization": false, + "baseUrl": "." }, "include": ["src"], "exclude": [ diff --git a/packages/graphiql-toolkit/tsconfig.json b/packages/graphiql-toolkit/tsconfig.json index 458ba460e72..570b9c49c77 100644 --- a/packages/graphiql-toolkit/tsconfig.json +++ b/packages/graphiql-toolkit/tsconfig.json @@ -6,6 +6,7 @@ "composite": true, "jsx": "react", "target": "es5", + "baseUrl": ".", "strictPropertyInitialization": false }, "include": ["src"], diff --git a/packages/graphiql/src/components/__tests__/GraphiQL.spec.tsx b/packages/graphiql/src/components/__tests__/GraphiQL.spec.tsx index 92b537ed92e..fcc58ee164a 100644 --- a/packages/graphiql/src/components/__tests__/GraphiQL.spec.tsx +++ b/packages/graphiql/src/components/__tests__/GraphiQL.spec.tsx @@ -250,7 +250,7 @@ describe('GraphiQL', () => { expect(container.querySelectorAll('.history-label')).toHaveLength(2); }); - it('will save query if variables are different ', () => { + it('will save query if variables are different', () => { const { getByTitle, container } = render( { expect(container.querySelectorAll('.history-label')).toHaveLength(2); }); - it('will save query if headers are different ', () => { + it('will save query if headers are different', () => { const { getByTitle, getByText, container } = render( { fixtures.forEach(fixture => { - it(fixture.desc, () => { + it(`${fixture.desc}`, () => { const result = print(mergeAst(parse(fixture.query))).replace(/\s/g, ''); const result2 = print(mergeAst(parse(fixture.query), schema)).replace( /\s/g, diff --git a/packages/graphiql/test/e2e-server.js b/packages/graphiql/test/e2e-server.js index 39444bc926d..878d3c053f2 100644 --- a/packages/graphiql/test/e2e-server.js +++ b/packages/graphiql/test/e2e-server.js @@ -8,7 +8,7 @@ /* eslint-disable no-console */ const express = require('express'); const path = require('path'); -const graphqlHTTP = require('express-graphql'); +const { graphqlHTTP } = require('express-graphql'); const schema = require('./schema'); const app = express(); diff --git a/packages/graphql-language-service-parser/src/__tests__/OnlineParserUtils.ts b/packages/graphql-language-service-parser/src/__tests__/OnlineParserUtils.ts index a09c047a793..652179161a2 100644 --- a/packages/graphql-language-service-parser/src/__tests__/OnlineParserUtils.ts +++ b/packages/graphql-language-service-parser/src/__tests__/OnlineParserUtils.ts @@ -133,8 +133,7 @@ export const performForEachType = (source, test) => { const utils = getUtils( source.replace(/__VALUE__/g, value).replace(/__TYPE__/g, type), ); - - test(utils, { type, value, kind, valueType }); + test(utils, { type, value, kind, valueType }); // eslint-disable-line }); }; diff --git a/packages/graphql-language-service-server/src/__tests__/GraphQLCache-test.ts b/packages/graphql-language-service-server/src/__tests__/GraphQLCache-test.ts index 4ee95a3ab8b..a5669170623 100644 --- a/packages/graphql-language-service-server/src/__tests__/GraphQLCache-test.ts +++ b/packages/graphql-language-service-server/src/__tests__/GraphQLCache-test.ts @@ -192,13 +192,13 @@ describe('GraphQLCache', () => { }); describe('getFragmentDefinitions', () => { - it('it caches fragments found through single glob in `documents`', async () => { + it('caches fragments found through single glob in `documents`', async () => { const config = graphQLRC.getProject('testSingularIncludesGlob'); const fragmentDefinitions = await cache.getFragmentDefinitions(config); expect(fragmentDefinitions.get('testFragment')).not.toBeUndefined(); }); - it('it caches fragments found through multiple globs in `documents`', async () => { + it('caches fragments found through multiple globs in `documents`', async () => { const config = graphQLRC.getProject('testMultipleIncludes'); const fragmentDefinitions = await cache.getFragmentDefinitions(config); expect(fragmentDefinitions.get('testFragment')).not.toBeUndefined(); diff --git a/yarn.lock b/yarn.lock index d919b31a1fc..d03dbd61999 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3113,6 +3113,22 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@eslint/eslintrc@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" + integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + lodash "^4.17.20" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@evocateur/libnpmaccess@^3.1.2": version "3.1.2" resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845" @@ -5935,26 +5951,20 @@ regexpp "^3.0.0" tsutils "^3.17.1" -"@typescript-eslint/eslint-plugin@^2.27.0": - version "2.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.27.0.tgz#e479cdc4c9cf46f96b4c287755733311b0d0ba4b" - integrity sha512-/my+vVHRN7zYgcp0n4z5A6HAK7bvKGBiswaM5zIlOQczsxj/aiD7RcgD+dvVFuwFaGh5+kM7XA6Q6PN0bvb1tw== +"@typescript-eslint/eslint-plugin@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.0.tgz#92db8e7c357ed7d69632d6843ca70b71be3a721d" + integrity sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww== dependencies: - "@typescript-eslint/experimental-utils" "2.27.0" + "@typescript-eslint/experimental-utils" "4.14.0" + "@typescript-eslint/scope-manager" "4.14.0" + debug "^4.1.1" functional-red-black-tree "^1.0.1" + lodash "^4.17.15" regexpp "^3.0.0" + semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.27.0", "@typescript-eslint/experimental-utils@^2.5.0": - version "2.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.27.0.tgz#801a952c10b58e486c9a0b36cf21e2aab1e9e01a" - integrity sha512-vOsYzjwJlY6E0NJRXPTeCGqjv5OHgRU1kzxHKWJVPjDYGbPgLudBXjIlc+OD1hDBZ4l1DLbOc5VjofKahsu9Jw== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.27.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - "@typescript-eslint/experimental-utils@2.34.0": version "2.34.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" @@ -5965,6 +5975,18 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/experimental-utils@4.14.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.0.tgz#5aa7b006736634f588a69ee343ca959cd09988df" + integrity sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.14.0" + "@typescript-eslint/types" "4.14.0" + "@typescript-eslint/typescript-estree" "4.14.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/parser@^2.10.0": version "2.34.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" @@ -5975,28 +5997,28 @@ "@typescript-eslint/typescript-estree" "2.34.0" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/parser@^2.27.0": - version "2.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.27.0.tgz#d91664335b2c46584294e42eb4ff35838c427287" - integrity sha512-HFUXZY+EdwrJXZo31DW4IS1ujQW3krzlRjBrFRrJcMDh0zCu107/nRfhk/uBasO8m0NVDbBF5WZKcIUMRO7vPg== +"@typescript-eslint/parser@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.14.0.tgz#62d4cd2079d5c06683e9bfb200c758f292c4dee7" + integrity sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg== dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.27.0" - "@typescript-eslint/typescript-estree" "2.27.0" - eslint-visitor-keys "^1.1.0" + "@typescript-eslint/scope-manager" "4.14.0" + "@typescript-eslint/types" "4.14.0" + "@typescript-eslint/typescript-estree" "4.14.0" + debug "^4.1.1" -"@typescript-eslint/typescript-estree@2.27.0": - version "2.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.27.0.tgz#a288e54605412da8b81f1660b56c8b2e42966ce8" - integrity sha512-t2miCCJIb/FU8yArjAvxllxbTiyNqaXJag7UOpB5DVoM3+xnjeOngtqlJkLRnMtzaRcJhe3CIR9RmL40omubhg== +"@typescript-eslint/scope-manager@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.14.0.tgz#55a4743095d684e1f7b7180c4bac2a0a3727f517" + integrity sha512-/J+LlRMdbPh4RdL4hfP1eCwHN5bAhFAGOTsvE6SxsrM/47XQiPSgF5MDgLyp/i9kbZV9Lx80DW0OpPkzL+uf8Q== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^6.3.0" - tsutils "^3.17.1" + "@typescript-eslint/types" "4.14.0" + "@typescript-eslint/visitor-keys" "4.14.0" + +"@typescript-eslint/types@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.14.0.tgz#d8a8202d9b58831d6fd9cee2ba12f8a5a5dd44b6" + integrity sha512-VsQE4VvpldHrTFuVPY1ZnHn/Txw6cZGjL48e+iBxTi2ksa9DmebKjAeFmTVAYoSkTk7gjA7UqJ7pIsyifTsI4A== "@typescript-eslint/typescript-estree@2.34.0": version "2.34.0" @@ -6011,6 +6033,28 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.0.tgz#4bcd67486e9acafc3d0c982b23a9ab8ac8911ed7" + integrity sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag== + dependencies: + "@typescript-eslint/types" "4.14.0" + "@typescript-eslint/visitor-keys" "4.14.0" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.0.tgz#b1090d9d2955b044b2ea2904a22496849acbdf54" + integrity sha512-MeHHzUyRI50DuiPgV9+LxcM52FCJFYjJiWHtXlbyC27b80mfOwKeiKI+MHOTEpcpfmoPFm/vvQS88bYIx6PZTA== + dependencies: + "@typescript-eslint/types" "4.14.0" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -6378,6 +6422,11 @@ acorn-jsx@^5.2.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + acorn-walk@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" @@ -6408,6 +6457,11 @@ acorn@^7.1.0, acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -6526,6 +6580,16 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.0.3.tgz#13ae747eff125cafb230ac504b2406cf371eece2" + integrity sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -6550,6 +6614,11 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -6792,6 +6861,17 @@ array-includes@^3.0.3, array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" +array-includes@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" + integrity sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + get-intrinsic "^1.0.1" + is-string "^1.0.5" + array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -6836,6 +6916,16 @@ array.prototype.flatmap@^1.2.1: es-abstract "^1.17.0-next.1" function-bind "^1.1.1" +array.prototype.flatmap@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + function-bind "^1.1.1" + array.prototype.map@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" @@ -6920,6 +7010,11 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-array-reduce@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/async-array-reduce/-/async-array-reduce-0.2.1.tgz#c8be010a2b5cd00dea96c81116034693dfdd82d1" @@ -8005,6 +8100,14 @@ cachedir@^2.3.0: resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -9064,6 +9167,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -9566,7 +9678,7 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -10120,6 +10232,13 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1, enhan memory-fs "^0.5.0" tapable "^1.0.0" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^1.1.1, entities@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -10203,6 +10322,26 @@ es-abstract@^1.17.0-next.0, es-abstract@^1.17.2, es-abstract@^1.17.4: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" +es-abstract@^1.18.0-next.1: + version "1.18.0-next.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" + integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-negative-zero "^2.0.1" + is-regex "^1.1.1" + object-inspect "^1.9.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.3" + string.prototype.trimstart "^1.0.3" + es-array-method-boxes-properly@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" @@ -10339,12 +10478,10 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.10.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a" - integrity sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ== - dependencies: - get-stdin "^6.0.0" +eslint-config-prettier@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" + integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== eslint-config-react-app@^5.2.1: version "5.2.1" @@ -10444,12 +10581,12 @@ eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" -eslint-plugin-jest@^23.8.2: - version "23.8.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz#6f28b41c67ef635f803ebd9e168f6b73858eb8d4" - integrity sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg== +eslint-plugin-jest@^24.1.3: + version "24.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c" + integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg== dependencies: - "@typescript-eslint/experimental-utils" "^2.5.0" + "@typescript-eslint/experimental-utils" "^4.0.1" eslint-plugin-jsx-a11y@6.2.3: version "6.2.3" @@ -10466,7 +10603,7 @@ eslint-plugin-jsx-a11y@6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-prefer-object-spread@1.2.1: +eslint-plugin-prefer-object-spread@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c" integrity sha1-J/uRhTaQzOs65hAdnIrsxqZ6QCw= @@ -10476,10 +10613,10 @@ eslint-plugin-react-hooks@^1.6.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== -eslint-plugin-react-hooks@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz#9e80c71846eb68dd29c3b21d832728aa66e5bd35" - integrity sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw== +eslint-plugin-react-hooks@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" + integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== eslint-plugin-react@7.19.0: version "7.19.0" @@ -10499,6 +10636,23 @@ eslint-plugin-react@7.19.0: string.prototype.matchall "^4.0.2" xregexp "^4.3.0" +eslint-plugin-react@^7.22.0: + version "7.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" + integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA== + dependencies: + array-includes "^3.1.1" + array.prototype.flatmap "^1.2.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.4.1 || ^3.0.0" + object.entries "^1.1.2" + object.fromentries "^2.0.2" + object.values "^1.1.1" + prop-types "^15.7.2" + resolve "^1.18.1" + string.prototype.matchall "^4.0.2" + eslint-rule-composer@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" @@ -10520,6 +10674,14 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" @@ -10534,12 +10696,29 @@ eslint-utils@^2.0.0: dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.6.0, eslint@^6.8.0: +eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + +eslint@^6.6.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== @@ -10582,6 +10761,49 @@ eslint@^6.6.0, eslint@^6.8.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@^7.18.0: + version "7.18.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" + integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^0.3.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.2.0" + esutils "^2.0.2" + file-entry-cache "^6.0.0" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash "^4.17.20" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.4" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + espree@^6.1.2: version "6.2.1" resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" @@ -10591,6 +10813,15 @@ espree@^6.1.2: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -10608,6 +10839,13 @@ esquery@^1.0.1: dependencies: estraverse "^5.0.0" +esquery@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" @@ -10615,6 +10853,13 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" @@ -10625,6 +10870,11 @@ estraverse@^5.0.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -11152,6 +11402,13 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" +file-entry-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" + integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== + dependencies: + flat-cache "^3.0.4" + file-loader@4.3.0, file-loader@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" @@ -11345,11 +11602,24 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + flatten@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" @@ -11673,6 +11943,15 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -11709,11 +11988,6 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== - get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -11984,6 +12258,18 @@ globby@8.0.2: pify "^3.0.0" slash "^1.0.0" +globby@^11.0.1: + version "11.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83" + integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -12694,6 +12980,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0: parent-module "^1.0.0" resolve-from "^4.0.0" +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-from@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" @@ -13027,6 +13321,11 @@ is-callable@^1.2.0: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== +is-callable@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" + integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -13217,6 +13516,11 @@ is-map@^2.0.1: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -13331,7 +13635,7 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-regex@^1.0.4, is-regex@^1.1.0: +is-regex@^1.0.4, is-regex@^1.1.0, is-regex@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== @@ -14597,6 +14901,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -14697,6 +15006,14 @@ jsx-ast-utils@^2.2.3: array-includes "^3.0.3" object.assign "^4.1.0" +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" + integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== + dependencies: + array-includes "^3.1.2" + object.assign "^4.1.2" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -14842,6 +15159,14 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -16297,6 +16622,11 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + object-inspect@~1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.4.1.tgz#37ffb10e71adaf3748d05f713b4c9452f402cbc4" @@ -16337,6 +16667,16 @@ object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + object.entries@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" @@ -16356,6 +16696,16 @@ object.entries@^1.1.1: function-bind "^1.1.1" has "^1.0.3" +object.entries@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" + integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + has "^1.0.3" + "object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" @@ -16507,6 +16857,18 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + ora@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ora/-/ora-2.1.0.tgz#6caf2830eb924941861ec53a173799e008b51e5b" @@ -17960,6 +18322,11 @@ posthtml@^0.13.4: posthtml-parser "^0.5.0" posthtml-render "^1.2.3" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -19077,7 +19444,7 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.0.0: +regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -19253,6 +19620,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -19372,7 +19744,7 @@ resolve@1.x, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, dependencies: path-parse "^1.0.6" -resolve@^1.1.5, resolve@^1.4.0, resolve@^1.8.1: +resolve@^1.1.5, resolve@^1.18.1, resolve@^1.4.0, resolve@^1.8.1: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -19710,7 +20082,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^7.3.2: +semver@^7.2.1, semver@^7.3.2: version "7.3.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== @@ -20015,6 +20387,15 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + slide@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -20514,6 +20895,14 @@ string.prototype.trimend@^1.0.0, string.prototype.trimend@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" +string.prototype.trimend@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" + integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + string.prototype.trimleft@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" @@ -20540,6 +20929,14 @@ string.prototype.trimstart@^1.0.0, string.prototype.trimstart@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" +string.prototype.trimstart@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" + integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -20663,6 +21060,11 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -20830,6 +21232,16 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +table@^6.0.4: + version "6.0.7" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" + integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + dependencies: + ajv "^7.0.2" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" + tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -21341,6 +21753,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -22407,7 +22826,7 @@ windows-release@^3.1.0: dependencies: execa "^1.0.0" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From ba7e7c033e8070ec773727f5cec9fbaf2098e286 Mon Sep 17 00:00:00 2001 From: Rikki Date: Sun, 24 Jan 2021 14:49:19 -0500 Subject: [PATCH 3/8] feat: iterate over increments in GraphiQL, stream fetcher in netlify! --- .../graphiql-create-react-app/package.json | 2 +- examples/graphiql-parcel/package.json | 2 +- examples/graphiql-webpack/package.json | 2 +- examples/monaco-graphql-webpack/package.json | 2 +- package.json | 23 +- packages/codemirror-graphql/package.json | 2 +- packages/graphiql-2-rfc-context/package.json | 2 +- packages/graphiql-build-fetcher/README.md | 16 +- packages/graphiql-build-fetcher/package.json | 13 +- .../src/__tests__/buildFetcher.spec.ts | 59 ++- .../src/__tests__/lib.spec.ts | 27 +- .../src/buildFetcher.ts | 49 +- packages/graphiql-build-fetcher/src/lib.ts | 85 ++-- packages/graphiql-build-fetcher/src/types.ts | 9 +- .../graphiql-build-fetcher/test/server.ts | 24 +- packages/graphiql-toolkit/README.md | 0 packages/graphiql-toolkit/package.json | 2 +- packages/graphiql-toolkit/src/types.ts | 5 +- packages/graphiql/package.json | 6 +- packages/graphiql/resources/renderExample.js | 48 +- packages/graphiql/src/cdn.ts | 9 +- packages/graphiql/src/components/GraphiQL.tsx | 35 +- packages/graphiql/test/beforeDevServer.js | 2 +- packages/graphiql/test/schema.js | 20 + .../getAutocompleteSuggestions-test.ts | 9 +- resources/tsconfig.base.esm.json | 3 +- yarn.lock | 458 ++---------------- 27 files changed, 300 insertions(+), 614 deletions(-) create mode 100644 packages/graphiql-toolkit/README.md diff --git a/examples/graphiql-create-react-app/package.json b/examples/graphiql-create-react-app/package.json index 61ea4f0b5d4..9f72bd1db3a 100644 --- a/examples/graphiql-create-react-app/package.json +++ b/examples/graphiql-create-react-app/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "graphiql": "file:../../packages/graphiql", - "graphql": "^15.0.0", + "graphql": "experimental-stream-defer", "react": "^16.13.1", "react-dom": "^16.13.1", "react-scripts": "3.4.1" diff --git a/examples/graphiql-parcel/package.json b/examples/graphiql-parcel/package.json index 29e0b2ba82d..0a8dd31bed0 100644 --- a/examples/graphiql-parcel/package.json +++ b/examples/graphiql-parcel/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "graphiql": "file:../../packages/graphiql", - "graphql": "15.0.0", + "graphql": "experimental-stream-defer", "react": "^16.13.1", "react-dom": "^16.13.1", "typescript": "^3.4.4" diff --git a/examples/graphiql-webpack/package.json b/examples/graphiql-webpack/package.json index f192b08dfac..ea0fe5d9220 100644 --- a/examples/graphiql-webpack/package.json +++ b/examples/graphiql-webpack/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "graphiql": "file:../../packages/graphiql", - "graphql": "15.0.0", + "graphql": "experimental-stream-defer", "react": "16.13.1" }, "devDependencies": { diff --git a/examples/monaco-graphql-webpack/package.json b/examples/monaco-graphql-webpack/package.json index 3edb6773020..1adae3b91f4 100644 --- a/examples/monaco-graphql-webpack/package.json +++ b/examples/monaco-graphql-webpack/package.json @@ -11,7 +11,7 @@ "start": "cross-env NODE_ENV=development webpack-dev-server" }, "dependencies": { - "graphql": "14.6.0", + "graphql": "experimental-stream-defer", "monaco-graphql": "file:../../packages/monaco-graphql", "prettier": "^2.0.2" }, diff --git a/package.json b/package.json index 42805a2556d..375648d07ff 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,12 @@ { "private": true, "license": "MIT", - "workspaces": [ - "packages/*", - "examples/*" - ], + "workspaces": { + "packages": [ + "packages/*", + "examples/*" + ] + }, "lint-staged": { "*.{js,ts,jsx,tsx}": [ "eslint --fix", @@ -96,19 +98,18 @@ "copy": "^0.3.2", "cross-env": "^7.0.2", "cypress": "^4.7.0", - "eslint": "^7.18.0", - "eslint-config-prettier": "^7.2.0", + "eslint": "^6.8.0", + "eslint-config-prettier": "^6.10.1", "eslint-plugin-babel": "^5.3.0", "eslint-plugin-cypress": "^2.10.3", "eslint-plugin-flowtype": "4.7.0", "eslint-plugin-import": "^2.20.2", - "eslint-plugin-jest": "^24.1.3", - "eslint-plugin-prefer-object-spread": "^1.2.1", - "eslint-plugin-react": "^7.22.0", - "eslint-plugin-react-hooks": "^4.2.0", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-prefer-object-spread": "1.2.1", + "eslint-plugin-react": "7.19.0", + "eslint-plugin-react-hooks": "^3.0.0", "fetch-mock": "6.5.2", "flow-bin": "^0.119.1", - "graphql": "^15.4.0", "husky": "^4.2.3", "jest": "^25.3.0", "jest-environment-jsdom": "^25.3.0", diff --git a/packages/codemirror-graphql/package.json b/packages/codemirror-graphql/package.json index 213442855b7..c7b00c0c514 100644 --- a/packages/codemirror-graphql/package.json +++ b/packages/codemirror-graphql/package.json @@ -53,7 +53,7 @@ "devDependencies": { "codemirror": "^5.52.2", "cross-env": "^7.0.2", - "graphql": "15.4.0", + "graphql": "experimental-stream-defer", "jsdom": "^16.1.0", "rimraf": "^3.0.0", "sane": "2.0.0" diff --git a/packages/graphiql-2-rfc-context/package.json b/packages/graphiql-2-rfc-context/package.json index da354473e5f..b335d4ca0d8 100644 --- a/packages/graphiql-2-rfc-context/package.json +++ b/packages/graphiql-2-rfc-context/package.json @@ -80,7 +80,7 @@ "express-graphql": "0.9.0", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "4.1.3", - "graphql": "^15.4.0", + "graphql": "experimental-stream-defer", "html-webpack-plugin": "^4.0.4", "identity-obj-proxy": "^3.0.0", "jest": "^24.8.0", diff --git a/packages/graphiql-build-fetcher/README.md b/packages/graphiql-build-fetcher/README.md index a5cd7b16ceb..50ca39d9e01 100644 --- a/packages/graphiql-build-fetcher/README.md +++ b/packages/graphiql-build-fetcher/README.md @@ -47,7 +47,7 @@ ReactDOM.render(document.getElementByID('graphiql'), ); #### HTTP/Multipart & Websockets -Just by providing the `subscriptionsUrl`, you can generate a `graphql-ws` client +Just by providing the `subscriptionUrl`, you can generate a `graphql-ws` client ```ts import * as React from 'react'; @@ -57,11 +57,11 @@ import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; const url = 'https://myschema.com/graphql'; -const subscriptionsUrl = 'wss://myschema.com/graphql'; +const subscriptionUrl = 'wss://myschema.com/graphql'; const fetcher = buildGraphiQLFetcher({ url, - subscriptionsUrl, + subscriptionUrl, }); export const App = () => ; @@ -77,13 +77,13 @@ You can further customize the `wsClient` implementation below This is url used for all `HTTP` requests, and for schema introspection. -#### `subscriptionsUrl` +#### `subscriptionUrl` This generates a `graphql-ws` client. #### `wsClient` -provide your own subscriptions client. bypasses `subscriptionsUrl`. In theory, this could be any client using any transport, as long as it matches `graphql-ws` `Client` signature. +provide your own subscriptions client. bypasses `subscriptionUrl`. In theory, this could be any client using any transport, as long as it matches `graphql-ws` `Client` signature. #### `headers` @@ -97,7 +97,7 @@ Pass a custom fetch implementation such as `isomorphic-feth` #### Custom `wsClient` Example -Just by providing the `subscriptionsUrl` +Just by providing the `subscriptionUrl` ```ts import * as React from 'react'; @@ -108,12 +108,12 @@ import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; const url = 'https://myschema.com/graphql'; -const subscriptionsUrl = 'wss://myschema.com/graphql'; +const subscriptionUrl = 'wss://myschema.com/graphql'; const fetcher = buildGraphiQLFetcher({ url, wsClient: createClient({ - url: subscriptionsUrl, + url: subscriptionUrl, keepAlive: 2000, }), }); diff --git a/packages/graphiql-build-fetcher/package.json b/packages/graphiql-build-fetcher/package.json index 3b2d0b34752..d955e7f709f 100644 --- a/packages/graphiql-build-fetcher/package.json +++ b/packages/graphiql-build-fetcher/package.json @@ -16,9 +16,14 @@ "scripts": { "server": "ts-node test/server.ts" }, + "workspaces": { + "nohoist": [ + "graphql" + ] + }, "dependencies": { "graphql-ws": "^4.1.0", - "graphql-transport-ws": "^1.9.0", + "subscriptions-transport-ws": "^0.9.18", "fetch-multipart-graphql": "^3.0.0", "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", "@graphiql/toolkit": "^0.0.1" @@ -28,6 +33,10 @@ "express": "^4.17.1", "express-graphql": "experimental-stream-defer", "ws": "^7.4.2", - "ts-node": "^9.1.1" + "ts-node": "^9.1.1", + "graphql": "experimental-stream-defer" + }, + "resolutions": { + "graphql": "experimental-stream-defer" } } diff --git a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts index 957ca137737..022e23ec41a 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts +++ b/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts @@ -7,11 +7,10 @@ jest.mock('../lib'); jest.mock('graphql-ws'); -jest.mock('graphql-transport-ws'); +jest.mock('subscriptions-transport-ws'); import { - createWebsocketsClient, - createWebsocketsFetcher, + createWebsocketsFetcherFromUrl, createMultipartFetcher, createSimpleFetcher, } from '../lib'; @@ -31,60 +30,80 @@ const exampleWithSubscriptonNode = parse(exampleWithSubscripton); const serverURL = 'http://localhost:3000/graphql'; const wssURL = 'ws://localhost:3000/graphql'; -const exampleIntrospectionJson = parse(getIntrospectionQuery()); +const exampleIntrospectionDocument = parse(getIntrospectionQuery()); describe('buildGraphiQLFetcher', () => { afterEach(() => { jest.resetAllMocks(); }); it('returns fetcher without websocket client by default', async () => { - createWebsocketsClient.mockReturnValue(true); + createWebsocketsFetcherFromUrl.mockReturnValue(true); const fetcher = buildGraphiQLFetcher({ url: serverURL }); - expect(createWebsocketsClient.mock.calls).toEqual([]); + expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([ - [{ enableMultipart: true, url: serverURL }], + [{ enableIncrementalDelivery: true, url: serverURL }], ]); }); + + it('returns simple fetcher for introspection', async () => { + createSimpleFetcher.mockReturnValue(async () => 'hey!'); + const fetcher = buildGraphiQLFetcher({ url: serverURL }); + expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); + expect(createMultipartFetcher.mock.calls).toEqual([ + [{ enableIncrementalDelivery: true, url: serverURL }], + ]); + expect(createSimpleFetcher.mock.calls).toEqual([ + [{ enableIncrementalDelivery: true, url: serverURL }, fetch], + ]); + const res = await fetcher( + { query: getIntrospectionQuery(), operationName: 'IntrospectionQuery' }, + { + documentAST: exampleIntrospectionDocument, + shouldPersistHeaders: false, + }, + ); + expect(res).toEqual('hey!'); + }); it('returns fetcher without websocket client or multipart', () => { - createWebsocketsClient.mockReturnValue(true); - buildGraphiQLFetcher({ url: serverURL, enableMultipart: false }); - expect(createWebsocketsClient.mock.calls).toEqual([]); + createWebsocketsFetcherFromUrl.mockReturnValue(true); + buildGraphiQLFetcher({ url: serverURL, enableIncrementalDelivery: false }); + expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([]); expect(createSimpleFetcher.mock.calls).toEqual([ - [{ enableMultipart: false, url: serverURL }, fetch], + [{ enableIncrementalDelivery: false, url: serverURL }, fetch], ]); }); it('returns fetcher with websocket client', () => { - createWebsocketsClient.mockReturnValue('Client1'); + createWebsocketsFetcherFromUrl.mockReturnValue('Client1'); const args = { url: serverURL, - subscriptionsUrl: wssURL, - enableMultipart: true, + subscriptionUrl: wssURL, + enableIncrementalDelivery: true, }; buildGraphiQLFetcher(args); expect(createMultipartFetcher.mock.calls).toEqual([[args]]); - expect(createWebsocketsClient.mock.calls).toEqual([[args]]); - expect(createWebsocketsFetcher.mock.calls).toEqual([['Client1']]); + expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([ + [args.subscriptionUrl], + ]); }); it('returns fetcher with custom wsClient', () => { createClient.mockReturnValue('WSClient'); - createWebsocketsFetcher.mockReturnValue('CustomWSSFetcher'); + createWebsocketsFetcherFromUrl.mockReturnValue('CustomWSSFetcher'); const wsClient = createClient({ url: wssURL }); const args = { url: serverURL, wsClient, - enableMultipart: true, + enableIncrementalDelivery: true, }; buildGraphiQLFetcher(args); expect(createMultipartFetcher.mock.calls).toEqual([[args]]); - expect(createWebsocketsClient.mock.calls).toEqual([]); - expect(createWebsocketsFetcher.mock.calls).toEqual([['WSClient']]); + expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); }); }); diff --git a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts index a397830b794..748fc14ae31 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts +++ b/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts @@ -1,15 +1,15 @@ import { parse } from 'graphql'; -import { isSubcriptionWithName, createWebsocketsClient } from '../lib'; +import { isSubcriptionWithName, createWebsocketsFetcherFromUrl } from '../lib'; import 'isomorphic-fetch'; jest.mock('graphql-ws'); -jest.mock('graphql-transport-ws'); +jest.mock('subscriptions-transport-ws'); import { createClient } from 'graphql-ws'; -import { createClient as createLegacyClient } from 'graphql-transport-ws'; +import { SubscriptionClient } from 'subscriptions-transport-ws'; const exampleWithSubscripton = /* GraphQL */ parse(` subscription Example { @@ -38,17 +38,24 @@ describe('isSubcriptionWithName', () => { }); }); -describe('createWebsocketsClient', () => { +describe('createWebsocketsFetcherFromUrl', () => { afterEach(() => { - // @ts-ignore - createClient.mockRestore(); + jest.resetAllMocks(); }); + it('creates a websockets client using provided url', () => { - createWebsocketsClient({ - url: 'https://example.com', - subscriptionsUrl: 'wss://example.com', - }); + createClient.mockReturnValue(true); + createWebsocketsFetcherFromUrl('wss://example.com'); + // @ts-ignore + expect(createClient.mock.calls[0][0]).toEqual({ url: 'wss://example.com' }); + expect(SubscriptionClient.mock.calls).toEqual([]); + }); + + it('creates a websockets client using provided url that fails to legacy client', async () => { + createClient.mockReturnValue(false); + await createWebsocketsFetcherFromUrl('wss://example.com'); // @ts-ignore expect(createClient.mock.calls[0][0]).toEqual({ url: 'wss://example.com' }); + expect(SubscriptionClient.mock.calls[0][0]).toEqual('wss://example.com'); }); }); diff --git a/packages/graphiql-build-fetcher/src/buildFetcher.ts b/packages/graphiql-build-fetcher/src/buildFetcher.ts index ca9b4a4c9b9..776359e8a2b 100644 --- a/packages/graphiql-build-fetcher/src/buildFetcher.ts +++ b/packages/graphiql-build-fetcher/src/buildFetcher.ts @@ -1,4 +1,3 @@ -import type { Client } from 'graphql-ws'; import type { Fetcher } from '@graphiql/toolkit'; import type { BuildFetcherOptions } from './types'; @@ -6,8 +5,8 @@ import { createMultipartFetcher, createSimpleFetcher, isSubcriptionWithName, - createWebsocketsClient, - createWebsocketsFetcher, + createWebsocketsFetcherFromUrl, + createWebsocketsFetcherFromClient, } from './lib'; /** @@ -19,16 +18,16 @@ import { * @returns {Fetcher} */ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { - // hoist the wsClient to global scope, so that we can unsubscribe/re-subscribe - // even when the function is re-invoked. - let wsClient: Client | null = null; - let httpFetch; + let wsFetcher: null | Fetcher | void = null; if (typeof window !== null && window?.fetch) { httpFetch = window.fetch; } - if (options?.enableMultipart === null || options.enableMultipart !== false) { - options.enableMultipart = true; + if ( + options?.enableIncrementalDelivery === null || + options.enableIncrementalDelivery !== false + ) { + options.enableIncrementalDelivery = true; } if (options.fetch) { httpFetch = options.fetch; @@ -37,28 +36,16 @@ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { throw Error('No valid fetcher implementation available'); } - let wsFetcher: Fetcher | null = null; - - // user provided wsClient - if (options.wsClient) { - wsClient = options.wsClient; - } + const simpleFetcher = createSimpleFetcher(options, httpFetch); - // if there's no user provided wsClient, - // and a subscriptionsUrl us present, then generate one - if (!wsClient && options.subscriptionsUrl) { - wsClient = createWebsocketsClient(options); + if (options.subscriptionUrl) { + wsFetcher = createWebsocketsFetcherFromUrl(options.subscriptionUrl); } - - if (wsClient) { - wsFetcher = createWebsocketsFetcher(wsClient); - } else if (options.subscriptionsUrl) { - throw Error('subscriptions client failed to initialize'); + if (options.wsClient) { + wsFetcher = createWebsocketsFetcherFromClient(options.wsClient); } - const simpleFetcher = createSimpleFetcher(options, httpFetch); - - const httpFetcher = options.enableMultipart + const httpFetcher = options.enableIncrementalDelivery ? createMultipartFetcher(options) : simpleFetcher; @@ -73,10 +60,14 @@ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { if (isSubscription) { if (!wsFetcher) { throw Error( - 'GraphiQL buildFetcher did not successfully build a wsFetcher', + `Your GraphiQL buildFetcher is not properly configured for websocket subscriptions yet. ${ + options.subscriptionUrl + ? `Provided URL ${options.subscriptionUrl} failed` + : `Try providing options.subscriptionUrl or options.wsClient first.` + }`, ); } - return wsFetcher(graphQLParams, opts); + return wsFetcher(graphQLParams); } return httpFetcher(graphQLParams, opts); }; diff --git a/packages/graphiql-build-fetcher/src/lib.ts b/packages/graphiql-build-fetcher/src/lib.ts index 792d4a250a0..17984d50787 100644 --- a/packages/graphiql-build-fetcher/src/lib.ts +++ b/packages/graphiql-build-fetcher/src/lib.ts @@ -1,16 +1,16 @@ import { DocumentNode, visit } from 'graphql'; import fetchMultipart from 'fetch-multipart-graphql'; import { createClient, Client } from 'graphql-ws'; -import { createClient as createLegacyClient } from 'graphql-transport-ws'; +import { SubscriptionClient } from 'subscriptions-transport-ws'; import { makeAsyncIterableIteratorFromSink } from '@n1ru4l/push-pull-async-iterable-iterator'; -import type { BuildFetcherOptions } from './'; import type { Fetcher, FetcherResult, FetcherParams, FetcherOpts, } from '@graphiql/toolkit'; +import type { BuildFetcherOptions } from './types'; /** * Returns true if the name matches a subscription in the AST @@ -36,41 +36,6 @@ export const isSubcriptionWithName = ( return isSubcription; }; -/** - * create a websockets client, following - * `graphql-ws` Client signature - * - * @param options - * @returns {Client | null} - */ -export const createWebsocketsClient = ( - options: BuildFetcherOptions, -): Client | null => { - let wsClient: Client | null = null; - try { - try { - // TODO: defaults? - wsClient = createClient({ - url: options.subscriptionsUrl!, - }); - if (!wsClient) { - wsClient = createLegacyClient({ - url: options.subscriptionsUrl!, - }); - } - } catch (err) { - wsClient = createLegacyClient({ - url: options.subscriptionsUrl!, - }); - } - } catch (err) { - throw Error( - `Error creating websocket client for:\n${options.subscriptionsUrl}`, - ); - } - return wsClient; -}; - /** * create a simple HTTP/S fetcher using a fetch implementation where * multipart is not needed @@ -98,19 +63,58 @@ export const createSimpleFetcher = ( return data.json(); }; +export const createWebsocketsFetcherFromUrl = (url: string) => { + let wsClient: Client | null = null; + let legacyClient: SubscriptionClient | null = null; + if (url) { + try { + try { + // TODO: defaults? + wsClient = createClient({ + url, + }); + if (!wsClient) { + legacyClient = new SubscriptionClient(url); + } + } catch (err) { + legacyClient = new SubscriptionClient(url); + } + } catch (err) { + console.error(`Error creating websocket client for:\n${url}\n\n${err}`); + } + } + + if (wsClient) { + return createWebsocketsFetcherFromClient(wsClient); + } else if (legacyClient) { + return createLegacyWebsocketsFetcher(legacyClient); + } else if (url) { + throw Error('subscriptions client failed to initialize'); + } +}; + /** * Create ws/s fetcher using provided wsClient implementation * * @param wsClient {Client} * @returns {Fetcher} */ -export const createWebsocketsFetcher = (wsClient: Client) => ( +export const createWebsocketsFetcherFromClient = (wsClient: Client) => ( graphQLParams: FetcherParams, ) => makeAsyncIterableIteratorFromSink(sink => wsClient!.subscribe(graphQLParams, sink), ); +export const createLegacyWebsocketsFetcher = ( + legacyWsClient: SubscriptionClient, +) => (graphQLParams: FetcherParams) => { + const observable = legacyWsClient.request(graphQLParams); + return makeAsyncIterableIteratorFromSink( + // @ts-ignore + sink => observable.subscribe(sink).unsubscribe, + ); +}; /** * create a fetcher with the `IncrementalDelivery` HTTP/S spec for * `@stream` and `@defer` support using `fetch-multipart-graphql` @@ -133,9 +137,8 @@ export const createMultipartFetcher = ( ...fetcherOpts?.headers, }, onNext: parts => { - // Introspection is broken if we return a array instead of a single item. - // TODO: This should be addressed inside GraphiQL - sink.next(parts[0]); + // @ts-ignore + sink.next(parts); }, onError: sink.error, onComplete: sink.complete, diff --git a/packages/graphiql-build-fetcher/src/types.ts b/packages/graphiql-build-fetcher/src/types.ts index f794c7d55a7..79eea3c40b5 100644 --- a/packages/graphiql-build-fetcher/src/types.ts +++ b/packages/graphiql-build-fetcher/src/types.ts @@ -1,4 +1,7 @@ import type { Client } from 'graphql-ws'; +import type { SubscriptionClient } from 'subscriptions-transport-ws'; + +export type WebsocketsClient = Client | SubscriptionClient; /** * Options for creating a sinple, spec-compliant GraphiQL fetcher @@ -11,9 +14,9 @@ export interface BuildFetcherOptions { /** * url for websocket subscription requests */ - subscriptionsUrl?: string; + subscriptionUrl?: string; /** - * wsClient implementation that matches `ws-graphql` signature, + * `wsClient` implementation that matches `ws-graphql` signature, * whether via `createClient()` itself or another client. */ wsClient?: Client; @@ -28,7 +31,7 @@ export interface BuildFetcherOptions { * You can disable the usage of the `fetch-multipart-graphql` library * entirely, defaulting to a simple fetch POST implementation. */ - enableMultipart?: boolean; + enableIncrementalDelivery?: boolean; /** * The fetch implementation, in case the user needs to override this for SSR * or other purposes. this does not override the `fetch-multipart-graphql` diff --git a/packages/graphiql-build-fetcher/test/server.ts b/packages/graphiql-build-fetcher/test/server.ts index 41b6ee15dcc..18b621b9ec8 100644 --- a/packages/graphiql-build-fetcher/test/server.ts +++ b/packages/graphiql-build-fetcher/test/server.ts @@ -9,20 +9,29 @@ import { GraphQLString, subscribe, GraphQLSchema, + GraphQLList, } from 'graphql'; const wait = (timeout: number = 200) => new Promise(res => setTimeout(res, timeout)); +const Greeting = new GraphQLObjectType({ + name: 'Greeting', + fields: { + name: { + type: GraphQLString, + }, + }, +}); + const Query = new GraphQLObjectType({ name: 'Query', fields: { streamExample: { - type: GraphQLString, + type: new GraphQLList(Greeting), resolve: async function* sayHiInFiveLanguages() { for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { - yield { greetings: hi }; - await wait(500); + yield { name: hi }; } }, }, @@ -36,7 +45,7 @@ const Subscription = new GraphQLObjectType({ type: GraphQLString, subscribe: async function* sayHiInFiveLanguages() { for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { - yield { greetings: hi }; + yield hi; await wait(500); } }, @@ -62,14 +71,15 @@ try { server, path: '/graphql', }); - const port = process.env.PORT || 3000; - server.listen(port, () => { + + const port = process.env.PORT || 3005; + + app.listen(port, () => { useServer( { schema, execute, subscribe, - connectionInitWaitTimeout: 2000, }, wsServer, ); diff --git a/packages/graphiql-toolkit/README.md b/packages/graphiql-toolkit/README.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/graphiql-toolkit/package.json b/packages/graphiql-toolkit/package.json index b22c51ecb51..bc9ecc7c59a 100644 --- a/packages/graphiql-toolkit/package.json +++ b/packages/graphiql-toolkit/package.json @@ -15,6 +15,6 @@ "module": "esm/index.js", "scripts": {}, "peerDependencies": { - "graphql": "^15.0.0" + "graphql": "experimental-stream-defer" } } diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts index be2fc0dbae8..7486954ff8d 100644 --- a/packages/graphiql-toolkit/src/types.ts +++ b/packages/graphiql-toolkit/src/types.ts @@ -31,16 +31,17 @@ export type FetcherParams = { export type FetcherOpts = { headers?: { [key: string]: any }; - shouldPersistHeaders: boolean; + shouldPersistHeaders?: boolean; documentAST?: DocumentNode; }; export type FetcherResult = | { data: IntrospectionQuery; + errors?: Array; } | string - | { data: any }; + | { data?: any; errors?: Array }; export type MaybePromise = T | Promise; diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index ee336a21042..eb87d1fc375 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -54,7 +54,8 @@ "graphql": "^14.0.0 || ^15.0.0", "prop-types": ">=15.5.0", "react": "^16.8.0", - "react-dom": "^16.8.0" + "react-dom": "^16.8.0", + "@graphiql/build-fetcher": "^0.0.1" }, "devDependencies": { "@testing-library/jest-dom": "5.1.1", @@ -64,6 +65,7 @@ "@types/node": "^13.7.1", "@types/testing-library__jest-dom": "^5.0.1", "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", + "@graphiql/build-fetcher": "^0.0.1", "babel-loader": "^8.1.0", "babel-plugin-macros": "^2.8.0", "cross-env": "^7.0.0", @@ -72,7 +74,7 @@ "express": "4.17.1", "express-graphql": "experimental-stream-defer", "fork-ts-checker-webpack-plugin": "4.1.3", - "graphql": "15.4.0", + "graphql": "experimental-stream-defer", "graphql-ws": "^4.1.0", "graphql-transport-ws": "^1.9.0", "fetch-multipart-graphql": "^3.0.0", diff --git a/packages/graphiql/resources/renderExample.js b/packages/graphiql/resources/renderExample.js index 4755a02afc6..fa4732b12c2 100644 --- a/packages/graphiql/resources/renderExample.js +++ b/packages/graphiql/resources/renderExample.js @@ -88,47 +88,10 @@ function updateURL() { history.replaceState(null, null, newSearch); } -// Defines a GraphQL fetcher using the fetch API. You're not required to -// use fetch, and could instead implement graphQLFetcher however you like, -// as long as it returns a Promise or Observable. -function graphQLFetcher(graphQLParams, opts = { headers: {} }) { - // When working locally, the example expects a GraphQL server at the path /graphql. - // In a PR preview, it connects to the Star Wars API externally. - // Change this to point wherever you host your GraphQL server. - const isDev = window.location.hostname.match(/localhost$/); - const api = isDev - ? '/graphql' - : 'https://swapi-graphql.netlify.app/.netlify/functions/index'; - - let headers = opts.headers; - // Convert headers to an object. - if (typeof headers === 'string') { - headers = JSON.parse(opts.headers); - } - - return fetch(api, { - method: 'post', - headers: Object.assign( - { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - headers, - ), - body: JSON.stringify(graphQLParams), - credentials: 'omit', - }) - .then(function (response) { - return response.text(); - }) - .then(function (responseBody) { - try { - return JSON.parse(responseBody); - } catch (error) { - return responseBody; - } - }); -} +const isDev = window.location.hostname.match(/localhost$/); +const api = isDev + ? '/graphql' + : 'https://swapi-graphql.netlify.app/.netlify/functions/index'; // Render into the body. // See the README in the top level of this module to learn more about @@ -136,7 +99,7 @@ function graphQLFetcher(graphQLParams, opts = { headers: {} }) { // additional child elements. ReactDOM.render( React.createElement(GraphiQL, { - fetcher: graphQLFetcher, + fetcher: GraphiQL.buildFetcher({ url: api }), query: parameters.query, variables: parameters.variables, headers: parameters.headers, @@ -147,6 +110,7 @@ ReactDOM.render( defaultSecondaryEditorOpen: true, onEditOperationName: onEditOperationName, headerEditorEnabled: true, + shouldPersistHeaders: true, }), document.getElementById('graphiql'), ); diff --git a/packages/graphiql/src/cdn.ts b/packages/graphiql/src/cdn.ts index 90221789642..c1dd63b000b 100644 --- a/packages/graphiql/src/cdn.ts +++ b/packages/graphiql/src/cdn.ts @@ -6,6 +6,8 @@ */ import 'regenerator-runtime/runtime'; +import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; + import './css/app.css'; import './css/codemirror.css'; import './css/foldgutter.css'; @@ -18,5 +20,10 @@ import './css/show-hint.css'; import './css/doc-explorer.css'; import './css/history.css'; -export default GraphiQL; import { GraphiQL } from './components/GraphiQL'; +// add the static function here for CDN only. otherwise, doing this in the component could +// add unwanted dependencies to the bundle. +// @ts-ignore +GraphiQL.buildFetcher = buildGraphiQLFetcher; + +export default GraphiQL; diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx index f223abbff01..5bd26e6ca14 100644 --- a/packages/graphiql/src/components/GraphiQL.tsx +++ b/packages/graphiql/src/components/GraphiQL.tsx @@ -1066,6 +1066,8 @@ export class GraphiQL extends React.Component { ); } + const totalResponse = { data: {} }; + // _fetchQuery may return a subscription. const subscription = await this._fetchQuery( editedQuery as string, @@ -1075,10 +1077,34 @@ export class GraphiQL extends React.Component { shouldPersistHeaders as boolean, (result: FetcherResult) => { if (queryID === this._editorQueryID) { - this.setState({ - isWaitingForResponse: false, - response: GraphiQL.formatResult(result), - }); + if (Array.isArray(result)) { + // for `IncrementalDelivery` + // https://github.com/graphql/graphql-over-http/blob/master/rfcs/IncrementalDelivery.md + // TODO: types + const response = result.reduce((result, increment) => { + if (increment.errors) { + result.errors = [...result?.errors, ...increment?.errors]; + } + if (increment.path) { + const [path, index] = increment.path; + const data = result?.data[path] || []; + data[index] = increment.data; + result.data = { ...result?.data, [path]: data }; + } else { + result.data = { ...result?.data, ...increment.data }; + } + return result; + }, totalResponse); + this.setState({ + isWaitingForResponse: false, + response: GraphiQL.formatResult(response), + }); + } else { + this.setState({ + isWaitingForResponse: false, + response: GraphiQL.formatResult(result), + }); + } } }, ); @@ -1711,6 +1737,7 @@ function asyncIterableToPromise( iteratorNext() .then(result => { + console.log(result.value); resolve(result.value); // ensure cleanup iteratorReturn?.(); diff --git a/packages/graphiql/test/beforeDevServer.js b/packages/graphiql/test/beforeDevServer.js index b08de9cf655..97fd298b258 100644 --- a/packages/graphiql/test/beforeDevServer.js +++ b/packages/graphiql/test/beforeDevServer.js @@ -7,7 +7,7 @@ const express = require('express'); const path = require('path'); -const graphqlHTTP = require('express-graphql'); +const { graphqlHTTP } = require('express-graphql'); const schema = require('./schema'); module.exports = function beforeDevServer(app, _server, _compiler) { diff --git a/packages/graphiql/test/schema.js b/packages/graphiql/test/schema.js index 568a7c89f84..38c777ca7b5 100644 --- a/packages/graphiql/test/schema.js +++ b/packages/graphiql/test/schema.js @@ -128,6 +128,17 @@ const TestUnion = new GraphQLUnionType({ }, }); +const Greeting = new GraphQLObjectType({ + name: 'Greeting', + fields: { + text: { + type: GraphQLString, + }, + }, +}); + +const sleep = async timeout => new Promise(res => setTimeout(res, timeout)); + const TestType = new GraphQLObjectType({ name: 'Test', fields: () => ({ @@ -136,6 +147,15 @@ const TestType = new GraphQLObjectType({ description: '`test` field from `Test` type.', resolve: () => ({}), }, + streamable: { + type: new GraphQLList(Greeting), + resolve: async function* sayHiInFiveLanguages() { + for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { + await sleep(800); + yield { text: hi }; + } + }, + }, longDescriptionType: { type: TestType, description: diff --git a/packages/graphql-language-service-interface/src/__tests__/getAutocompleteSuggestions-test.ts b/packages/graphql-language-service-interface/src/__tests__/getAutocompleteSuggestions-test.ts index 134d9a29007..56418d82d9f 100644 --- a/packages/graphql-language-service-interface/src/__tests__/getAutocompleteSuggestions-test.ts +++ b/packages/graphql-language-service-interface/src/__tests__/getAutocompleteSuggestions-test.ts @@ -352,18 +352,25 @@ query name { expect(testSuggestions('{ test @ }', new Position(0, 8))).toEqual([ { label: 'include' }, { label: 'skip' }, + { label: 'stream' }, { label: 'test' }, ]); expect(testSuggestions('{ test @', new Position(0, 8))).toEqual([ { label: 'include' }, { label: 'skip' }, + { label: 'stream' }, { label: 'test' }, ]); expect( testSuggestions('{ aliasTest: test @ }', new Position(0, 19)), - ).toEqual([{ label: 'include' }, { label: 'skip' }, { label: 'test' }]); + ).toEqual([ + { label: 'include' }, + { label: 'skip' }, + { label: 'stream' }, + { label: 'test' }, + ]); expect(testSuggestions('query @', new Position(0, 7))).toEqual([]); }); diff --git a/resources/tsconfig.base.esm.json b/resources/tsconfig.base.esm.json index 54a6df14473..3be2083b0ae 100644 --- a/resources/tsconfig.base.esm.json +++ b/resources/tsconfig.base.esm.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.base.cjs.json", "compilerOptions": { - "module": "ESNext" + "module": "ESNext", + "target": "ESNext" } } diff --git a/yarn.lock b/yarn.lock index d03dbd61999..502d3df7997 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3113,22 +3113,6 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@eslint/eslintrc@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" - integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - lodash "^4.17.20" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - "@evocateur/libnpmaccess@^3.1.2": version "3.1.2" resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845" @@ -5965,7 +5949,7 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.34.0": +"@typescript-eslint/experimental-utils@2.34.0", "@typescript-eslint/experimental-utils@^2.5.0": version "2.34.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== @@ -5975,7 +5959,7 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/experimental-utils@4.14.0", "@typescript-eslint/experimental-utils@^4.0.1": +"@typescript-eslint/experimental-utils@4.14.0": version "4.14.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.0.tgz#5aa7b006736634f588a69ee343ca959cd09988df" integrity sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ== @@ -6422,11 +6406,6 @@ acorn-jsx@^5.2.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== -acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - acorn-walk@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" @@ -6457,11 +6436,6 @@ acorn@^7.1.0, acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -6580,16 +6554,6 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.0.3.tgz#13ae747eff125cafb230ac504b2406cf371eece2" - integrity sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -6614,11 +6578,6 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -6861,17 +6820,6 @@ array-includes@^3.0.3, array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" -array-includes@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" - integrity sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - get-intrinsic "^1.0.1" - is-string "^1.0.5" - array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -6916,16 +6864,6 @@ array.prototype.flatmap@^1.2.1: es-abstract "^1.17.0-next.1" function-bind "^1.1.1" -array.prototype.flatmap@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" - integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - function-bind "^1.1.1" - array.prototype.map@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" @@ -7010,11 +6948,6 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - async-array-reduce@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/async-array-reduce/-/async-array-reduce-0.2.1.tgz#c8be010a2b5cd00dea96c81116034693dfdd82d1" @@ -8100,14 +8033,6 @@ cachedir@^2.3.0: resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -9167,15 +9092,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -9678,7 +9594,7 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -10232,13 +10148,6 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1, enhan memory-fs "^0.5.0" tapable "^1.0.0" -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^1.1.1, entities@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -10322,26 +10231,6 @@ es-abstract@^1.17.0-next.0, es-abstract@^1.17.2, es-abstract@^1.17.4: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" -es-abstract@^1.18.0-next.1: - version "1.18.0-next.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" - integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" - is-negative-zero "^2.0.1" - is-regex "^1.1.1" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.3" - string.prototype.trimstart "^1.0.3" - es-array-method-boxes-properly@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" @@ -10478,10 +10367,12 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" - integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== +eslint-config-prettier@^6.10.1: + version "6.15.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" + integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== + dependencies: + get-stdin "^6.0.0" eslint-config-react-app@^5.2.1: version "5.2.1" @@ -10581,12 +10472,12 @@ eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" -eslint-plugin-jest@^24.1.3: - version "24.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c" - integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg== +eslint-plugin-jest@^23.8.2: + version "23.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz#e1d69c75f639e99d836642453c4e75ed22da4099" + integrity sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw== dependencies: - "@typescript-eslint/experimental-utils" "^4.0.1" + "@typescript-eslint/experimental-utils" "^2.5.0" eslint-plugin-jsx-a11y@6.2.3: version "6.2.3" @@ -10603,7 +10494,7 @@ eslint-plugin-jsx-a11y@6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-prefer-object-spread@^1.2.1: +eslint-plugin-prefer-object-spread@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c" integrity sha1-J/uRhTaQzOs65hAdnIrsxqZ6QCw= @@ -10613,10 +10504,10 @@ eslint-plugin-react-hooks@^1.6.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== -eslint-plugin-react-hooks@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" - integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== +eslint-plugin-react-hooks@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz#9e80c71846eb68dd29c3b21d832728aa66e5bd35" + integrity sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw== eslint-plugin-react@7.19.0: version "7.19.0" @@ -10636,23 +10527,6 @@ eslint-plugin-react@7.19.0: string.prototype.matchall "^4.0.2" xregexp "^4.3.0" -eslint-plugin-react@^7.22.0: - version "7.22.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" - integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA== - dependencies: - array-includes "^3.1.1" - array.prototype.flatmap "^1.2.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.4.1 || ^3.0.0" - object.entries "^1.1.2" - object.fromentries "^2.0.2" - object.values "^1.1.1" - prop-types "^15.7.2" - resolve "^1.18.1" - string.prototype.matchall "^4.0.2" - eslint-rule-composer@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" @@ -10674,14 +10548,6 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" @@ -10696,29 +10562,17 @@ eslint-utils@^2.0.0: dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - eslint-visitor-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^6.6.0: +eslint@^6.6.0, eslint@^6.8.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== @@ -10761,49 +10615,6 @@ eslint@^6.6.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -eslint@^7.18.0: - version "7.18.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" - integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.3.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.2.0" - esutils "^2.0.2" - file-entry-cache "^6.0.0" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.20" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.4" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - espree@^6.1.2: version "6.2.1" resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" @@ -10813,15 +10624,6 @@ espree@^6.1.2: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -10839,13 +10641,6 @@ esquery@^1.0.1: dependencies: estraverse "^5.0.0" -esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== - dependencies: - estraverse "^5.1.0" - esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" @@ -10853,13 +10648,6 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" @@ -10870,11 +10658,6 @@ estraverse@^5.0.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -11402,13 +11185,6 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" -file-entry-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" - integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== - dependencies: - flat-cache "^3.0.4" - file-loader@4.3.0, file-loader@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" @@ -11602,24 +11378,11 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== -flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== - flatten@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" @@ -11943,15 +11706,6 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" - integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -11988,6 +11742,11 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -12359,22 +12118,10 @@ graphql-ws@^4.1.0: resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.1.0.tgz#cebe281474b5501d7be66210fb5711633b27fd78" integrity sha512-DxJP1y2YzCqVLy7DrQN0iuR2l48vMOBWukX2d/J9aN2o5x9un5psIIq/2UFRh91UGARmfvPH86y1p4qbC1dITg== -graphql@14.6.0: - version "14.6.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.6.0.tgz#57822297111e874ea12f5cd4419616930cd83e49" - integrity sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg== - dependencies: - iterall "^1.2.2" - -graphql@15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.0.0.tgz#042a5eb5e2506a2e2111ce41eb446a8e570b8be9" - integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ== - -graphql@15.4.0, graphql@^15.0.0, graphql@^15.4.0: - version "15.4.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347" - integrity sha512-EB3zgGchcabbsU9cFe1j+yxdzKQKAbGUWRb13DsrsMN1yyfmmIq+2+L5MqVWcDCE4V89R5AyUOi7sMOGxdsYtA== +graphql@experimental-stream-defer: + version "15.4.0-experimental-stream-defer.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0-experimental-stream-defer.1.tgz#46ae3fd2b532284575e7ddcf6c4f08aa7fe53fa3" + integrity sha512-zlGgY7aLlIofjO0CfTpCYK/tMccnj+5jvjnkTnW5qOxYhgEltuCvpMNYOJ67gz6L1flTIigt5BVEM8JExgtW3w== growly@^1.3.0: version "1.3.0" @@ -12980,14 +12727,6 @@ import-fresh@^3.0.0, import-fresh@^3.1.0: parent-module "^1.0.0" resolve-from "^4.0.0" -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - import-from@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" @@ -13321,11 +13060,6 @@ is-callable@^1.2.0: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== -is-callable@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" - integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -13516,11 +13250,6 @@ is-map@^2.0.1: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -13635,7 +13364,7 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-regex@^1.0.4, is-regex@^1.1.0, is-regex@^1.1.1: +is-regex@^1.0.4, is-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== @@ -13900,7 +13629,7 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterall@^1.2.1, iterall@^1.2.2: +iterall@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== @@ -14901,11 +14630,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -15006,14 +14730,6 @@ jsx-ast-utils@^2.2.3: array-includes "^3.0.3" object.assign "^4.1.0" -"jsx-ast-utils@^2.4.1 || ^3.0.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" - integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== - dependencies: - array-includes "^3.1.2" - object.assign "^4.1.2" - killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -15159,14 +14875,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -16622,11 +16330,6 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== -object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== - object-inspect@~1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.4.1.tgz#37ffb10e71adaf3748d05f713b4c9452f402cbc4" @@ -16667,16 +16370,6 @@ object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - object.entries@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" @@ -16696,16 +16389,6 @@ object.entries@^1.1.1: function-bind "^1.1.1" has "^1.0.3" -object.entries@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" - integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has "^1.0.3" - "object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" @@ -16857,18 +16540,6 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - ora@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ora/-/ora-2.1.0.tgz#6caf2830eb924941861ec53a173799e008b51e5b" @@ -18322,11 +17993,6 @@ posthtml@^0.13.4: posthtml-parser "^0.5.0" posthtml-render "^1.2.3" -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -19444,7 +19110,7 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -19620,11 +19286,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -19744,7 +19405,7 @@ resolve@1.x, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, dependencies: path-parse "^1.0.6" -resolve@^1.1.5, resolve@^1.18.1, resolve@^1.4.0, resolve@^1.8.1: +resolve@^1.1.5, resolve@^1.4.0, resolve@^1.8.1: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -20082,7 +19743,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^7.2.1, semver@^7.3.2: +semver@^7.3.2: version "7.3.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== @@ -20387,15 +20048,6 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - slide@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -20895,14 +20547,6 @@ string.prototype.trimend@^1.0.0, string.prototype.trimend@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" -string.prototype.trimend@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" - integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - string.prototype.trimleft@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" @@ -20929,14 +20573,6 @@ string.prototype.trimstart@^1.0.0, string.prototype.trimstart@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" -string.prototype.trimstart@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -21060,11 +20696,6 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -21123,7 +20754,7 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -subscriptions-transport-ws@0.9.18: +subscriptions-transport-ws@0.9.18, subscriptions-transport-ws@^0.9.18: version "0.9.18" resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97" integrity sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA== @@ -21232,16 +20863,6 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" -table@^6.0.4: - version "6.0.7" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" - integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== - dependencies: - ajv "^7.0.2" - lodash "^4.17.20" - slice-ansi "^4.0.0" - string-width "^4.2.0" - tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -21753,13 +21374,6 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -22826,7 +22440,7 @@ windows-release@^3.1.0: dependencies: execa "^1.0.0" -word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From 3876b5f7093cf5680784a39e6e9863d5bb5ca391 Mon Sep 17 00:00:00 2001 From: Rikki Date: Mon, 25 Jan 2021 13:53:57 -0500 Subject: [PATCH 4/8] chore: types, cleanup, rename it, end to end tests --- .npmrc | 1 + package.json | 2 +- packages/graphiql-build-fetcher/src/index.ts | 2 - .../graphiql-build-fetcher/test/server.ts | 90 ------------------- .../README.md | 24 ++--- .../jest.config.js | 0 .../package.json | 32 +++---- .../src/__tests__/buildFetcher.spec.ts | 14 +-- .../src/__tests__/lib.spec.ts | 8 +- .../src/createFetcher.ts} | 12 +-- packages/graphiql-create-fetcher/src/index.ts | 2 + .../src/lib.ts | 18 ++-- .../src/types.ts | 2 +- .../tsconfig.esm.json | 6 +- .../tsconfig.json | 16 ++-- packages/graphiql-toolkit/README.md | 15 ++++ packages/graphiql-toolkit/package.json | 15 ++-- packages/graphiql-toolkit/src/types.ts | 9 +- packages/graphiql-toolkit/tsconfig.esm.json | 2 +- .../integration/incrementalDelivery.spec.ts | 48 ++++++++++ packages/graphiql/cypress/support/commands.ts | 15 ++-- packages/graphiql/package.json | 8 +- packages/graphiql/resources/renderExample.js | 2 +- packages/graphiql/src/cdn.ts | 4 +- .../components/DocExplorer/SearchResults.tsx | 2 +- .../src/components/DocExplorer/TypeDoc.tsx | 2 +- packages/graphiql/src/components/GraphiQL.tsx | 10 ++- packages/graphiql/test/schema.js | 18 +++- packages/graphiql/tsconfig.esm.json | 9 +- packages/graphiql/tsconfig.json | 6 +- resources/tsconfig.build.cjs.json | 2 +- resources/tsconfig.build.esm.json | 2 +- yarn.lock | 20 +---- 33 files changed, 199 insertions(+), 219 deletions(-) delete mode 100644 packages/graphiql-build-fetcher/src/index.ts delete mode 100644 packages/graphiql-build-fetcher/test/server.ts rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/README.md (84%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/jest.config.js (100%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/package.json (52%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/src/__tests__/buildFetcher.spec.ts (89%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/src/__tests__/lib.spec.ts (84%) rename packages/{graphiql-build-fetcher/src/buildFetcher.ts => graphiql-create-fetcher/src/createFetcher.ts} (83%) create mode 100644 packages/graphiql-create-fetcher/src/index.ts rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/src/lib.ts (91%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/src/types.ts (96%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/tsconfig.esm.json (80%) rename packages/{graphiql-build-fetcher => graphiql-create-fetcher}/tsconfig.json (58%) create mode 100644 packages/graphiql/cypress/integration/incrementalDelivery.spec.ts diff --git a/.npmrc b/.npmrc index b6f27f13595..d38f53c764a 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ engine-strict=true +access=public diff --git a/package.json b/package.json index 375648d07ff..e3cd581fb8b 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "eslint": "eslint --ext=ts,js,jsx,tsx .", "lint": "yarn eslint && yarn lint-check && yarn pretty-check", "lint-fix": "yarn eslint --fix", - "lint-check": "eslint-config-prettier .eslintrc.js", + "lint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check", "check": "flow check --show-all-errors && yarn tsc --dry", "pretty": "node resources/pretty.js", "pretty-check": "node resources/pretty.js --check", diff --git a/packages/graphiql-build-fetcher/src/index.ts b/packages/graphiql-build-fetcher/src/index.ts deleted file mode 100644 index 5ccb2a018aa..00000000000 --- a/packages/graphiql-build-fetcher/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { BuildFetcherOptions } from './types'; -export { buildGraphiQLFetcher } from './buildFetcher'; diff --git a/packages/graphiql-build-fetcher/test/server.ts b/packages/graphiql-build-fetcher/test/server.ts deleted file mode 100644 index 18b621b9ec8..00000000000 --- a/packages/graphiql-build-fetcher/test/server.ts +++ /dev/null @@ -1,90 +0,0 @@ -import https from 'https'; -import ws from 'ws'; // yarn add ws -import express from 'express'; -import { graphqlHTTP } from 'express-graphql'; -import { useServer } from 'graphql-ws/lib/use/ws'; -import { - execute, - GraphQLObjectType, - GraphQLString, - subscribe, - GraphQLSchema, - GraphQLList, -} from 'graphql'; - -const wait = (timeout: number = 200) => - new Promise(res => setTimeout(res, timeout)); - -const Greeting = new GraphQLObjectType({ - name: 'Greeting', - fields: { - name: { - type: GraphQLString, - }, - }, -}); - -const Query = new GraphQLObjectType({ - name: 'Query', - fields: { - streamExample: { - type: new GraphQLList(Greeting), - resolve: async function* sayHiInFiveLanguages() { - for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { - yield { name: hi }; - } - }, - }, - }, -}); - -const Subscription = new GraphQLObjectType({ - name: 'Subscription', - fields: { - subscriptionExample: { - type: GraphQLString, - subscribe: async function* sayHiInFiveLanguages() { - for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { - yield hi; - await wait(500); - } - }, - }, - }, -}); - -try { - const schema = new GraphQLSchema({ - subscription: Subscription, - query: Query, - }); - - // create express and middleware - const app = express(); - app.use('/graphql', graphqlHTTP({ schema, graphiql: true })); - - // create a http server using express - const server = https.createServer(app); - - // create websocket server - const wsServer = new ws.Server({ - server, - path: '/graphql', - }); - - const port = process.env.PORT || 3005; - - app.listen(port, () => { - useServer( - { - schema, - execute, - subscribe, - }, - wsServer, - ); - console.log(`listening on ${port}`); - }); -} catch (err) { - console.error(err); -} diff --git a/packages/graphiql-build-fetcher/README.md b/packages/graphiql-create-fetcher/README.md similarity index 84% rename from packages/graphiql-build-fetcher/README.md rename to packages/graphiql-create-fetcher/README.md index 50ca39d9e01..0854f76c192 100644 --- a/packages/graphiql-build-fetcher/README.md +++ b/packages/graphiql-create-fetcher/README.md @@ -1,4 +1,4 @@ -## `@graphiql/build-fetcher` +## `@graphiql/create-fetcher` a utility for generating a full-featured fetcher for GraphiQL. @@ -8,18 +8,18 @@ under the hood, it uses [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) [`graphiql`](https://npmjs.com/package/graphiql) and thus `react` and `react-dom` should already be installed. -you'll need to install `@graphiql/build-fetcher` +you'll need to install `@graphiql/create-fetcher` npm ```bash -npm install --save @graphiql/build-fetcher +npm install --save @graphiql/create-fetcher ``` yarn ```bash -yarn add @graphiql/build-fetcher +yarn add @graphiql/create-fetcher ``` ### Getting Started @@ -34,11 +34,11 @@ Here's a simple example. In this case, a websocket client isn't even initialized import * as React from 'react'; import ReactDOM from 'react-dom'; import { GraphiQL } from 'graphiql'; -import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; const url = 'https://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ url }); +const fetcher = createGraphiQLFetcher({ url }); export const App = () => ; @@ -53,13 +53,13 @@ Just by providing the `subscriptionUrl`, you can generate a `graphql-ws` client import * as React from 'react'; import ReactDOM from 'react-dom'; import { GraphiQL } from 'graphiql'; -import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; const url = 'https://myschema.com/graphql'; const subscriptionUrl = 'wss://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ +const fetcher = createGraphiQLFetcher({ url, subscriptionUrl, }); @@ -104,13 +104,13 @@ import * as React from 'react'; import ReactDOM from 'react-dom'; import { GraphiQL } from 'graphiql'; import { createClient } from 'graphql-ws'; -import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; const url = 'https://myschema.com/graphql'; const subscriptionUrl = 'wss://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ +const fetcher = createGraphiQLFetcher({ url, wsClient: createClient({ url: subscriptionUrl, @@ -132,11 +132,11 @@ import * as React from 'react'; import ReactDOM from 'react-dom'; import { GraphiQL } from 'graphiql'; import { fetch } from 'isomorphic-fetch'; -import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; const url = 'https://myschema.com/graphql'; -const fetcher = buildGraphiQLFetcher({ +const fetcher = createGraphiQLFetcher({ url, fetch, }); diff --git a/packages/graphiql-build-fetcher/jest.config.js b/packages/graphiql-create-fetcher/jest.config.js similarity index 100% rename from packages/graphiql-build-fetcher/jest.config.js rename to packages/graphiql-create-fetcher/jest.config.js diff --git a/packages/graphiql-build-fetcher/package.json b/packages/graphiql-create-fetcher/package.json similarity index 52% rename from packages/graphiql-build-fetcher/package.json rename to packages/graphiql-create-fetcher/package.json index d955e7f709f..ddc3d690330 100644 --- a/packages/graphiql-build-fetcher/package.json +++ b/packages/graphiql-create-fetcher/package.json @@ -1,26 +1,23 @@ { - "name": "@graphiql/build-fetcher", + "name": "@graphiql/create-fetcher", "version": "0.0.1", - "description": "Utility to build a fetcher for GraphiQL", + "description": "A GraphiQL fetcher with `IncrementalDelivery` and `graphql-ws` support", "contributors": [ - "Rikki Schulte (http://rikki.dev/" + "Rikki Schulte (https://rikki.dev)" ], - "repository": "http://github.com/graphql/graphiql", - "homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql#readme", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/graphql/graphiql.git" + }, + "homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql-create-fetcher#readme", "bugs": { - "url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql" + "url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql-create-fetcher" }, "license": "MIT", "main": "dist/index.js", "module": "esm/index.js", - "scripts": { - "server": "ts-node test/server.ts" - }, - "workspaces": { - "nohoist": [ - "graphql" - ] - }, + "types": "dist/index.d.ts", + "scripts": {}, "dependencies": { "graphql-ws": "^4.1.0", "subscriptions-transport-ws": "^0.9.18", @@ -30,13 +27,6 @@ }, "devDependencies": { "isomorphic-fetch": "^3.0.0", - "express": "^4.17.1", - "express-graphql": "experimental-stream-defer", - "ws": "^7.4.2", - "ts-node": "^9.1.1", - "graphql": "experimental-stream-defer" - }, - "resolutions": { "graphql": "experimental-stream-defer" } } diff --git a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts b/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts similarity index 89% rename from packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts rename to packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts index 022e23ec41a..c078a62ce08 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/buildFetcher.spec.ts +++ b/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts @@ -1,5 +1,5 @@ import { parse, getIntrospectionQuery } from 'graphql'; -import { buildGraphiQLFetcher } from '../buildFetcher'; +import { createGraphiQLFetcher } from '../createFetcher'; import 'isomorphic-fetch'; @@ -32,13 +32,13 @@ const wssURL = 'ws://localhost:3000/graphql'; const exampleIntrospectionDocument = parse(getIntrospectionQuery()); -describe('buildGraphiQLFetcher', () => { +describe('createGraphiQLFetcher', () => { afterEach(() => { jest.resetAllMocks(); }); it('returns fetcher without websocket client by default', async () => { createWebsocketsFetcherFromUrl.mockReturnValue(true); - const fetcher = buildGraphiQLFetcher({ url: serverURL }); + const fetcher = createGraphiQLFetcher({ url: serverURL }); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([ [{ enableIncrementalDelivery: true, url: serverURL }], @@ -47,7 +47,7 @@ describe('buildGraphiQLFetcher', () => { it('returns simple fetcher for introspection', async () => { createSimpleFetcher.mockReturnValue(async () => 'hey!'); - const fetcher = buildGraphiQLFetcher({ url: serverURL }); + const fetcher = createGraphiQLFetcher({ url: serverURL }); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([ [{ enableIncrementalDelivery: true, url: serverURL }], @@ -66,7 +66,7 @@ describe('buildGraphiQLFetcher', () => { }); it('returns fetcher without websocket client or multipart', () => { createWebsocketsFetcherFromUrl.mockReturnValue(true); - buildGraphiQLFetcher({ url: serverURL, enableIncrementalDelivery: false }); + createGraphiQLFetcher({ url: serverURL, enableIncrementalDelivery: false }); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([]); expect(createSimpleFetcher.mock.calls).toEqual([ @@ -82,7 +82,7 @@ describe('buildGraphiQLFetcher', () => { enableIncrementalDelivery: true, }; - buildGraphiQLFetcher(args); + createGraphiQLFetcher(args); expect(createMultipartFetcher.mock.calls).toEqual([[args]]); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([ @@ -101,7 +101,7 @@ describe('buildGraphiQLFetcher', () => { enableIncrementalDelivery: true, }; - buildGraphiQLFetcher(args); + createGraphiQLFetcher(args); expect(createMultipartFetcher.mock.calls).toEqual([[args]]); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); diff --git a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts b/packages/graphiql-create-fetcher/src/__tests__/lib.spec.ts similarity index 84% rename from packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts rename to packages/graphiql-create-fetcher/src/__tests__/lib.spec.ts index 748fc14ae31..77367bb0dd1 100644 --- a/packages/graphiql-build-fetcher/src/__tests__/lib.spec.ts +++ b/packages/graphiql-create-fetcher/src/__tests__/lib.spec.ts @@ -1,5 +1,5 @@ import { parse } from 'graphql'; -import { isSubcriptionWithName, createWebsocketsFetcherFromUrl } from '../lib'; +import { isSubscriptionWithName, createWebsocketsFetcherFromUrl } from '../lib'; import 'isomorphic-fetch'; @@ -23,17 +23,17 @@ const exampleWithSubscripton = /* GraphQL */ parse(` describe('isSubcriptionWithName', () => { it('detects when the subscription is present', () => { expect( - isSubcriptionWithName(exampleWithSubscripton, 'Example'), + isSubscriptionWithName(exampleWithSubscripton, 'Example'), ).toBeTruthy(); }); it('detects when the specified operation is not a subscription', () => { expect( - isSubcriptionWithName(exampleWithSubscripton, 'SomethingElse'), + isSubscriptionWithName(exampleWithSubscripton, 'SomethingElse'), ).toBeFalsy(); }); it('detects when the operation is not present', () => { expect( - isSubcriptionWithName(exampleWithSubscripton, 'NotPresent'), + isSubscriptionWithName(exampleWithSubscripton, 'NotPresent'), ).toBeFalsy(); }); }); diff --git a/packages/graphiql-build-fetcher/src/buildFetcher.ts b/packages/graphiql-create-fetcher/src/createFetcher.ts similarity index 83% rename from packages/graphiql-build-fetcher/src/buildFetcher.ts rename to packages/graphiql-create-fetcher/src/createFetcher.ts index 776359e8a2b..ef2ee015e4e 100644 --- a/packages/graphiql-build-fetcher/src/buildFetcher.ts +++ b/packages/graphiql-create-fetcher/src/createFetcher.ts @@ -1,10 +1,10 @@ import type { Fetcher } from '@graphiql/toolkit'; -import type { BuildFetcherOptions } from './types'; +import type { CreateFetcherOptions } from './types'; import { createMultipartFetcher, createSimpleFetcher, - isSubcriptionWithName, + isSubscriptionWithName, createWebsocketsFetcherFromUrl, createWebsocketsFetcherFromClient, } from './lib'; @@ -14,10 +14,10 @@ import { * - backwards compatible * - optionally supports graphql-ws or ` * - * @param options {BuildFetcherOptions} + * @param options {CreateFetcherOptions} * @returns {Fetcher} */ -export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { +export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { let httpFetch; let wsFetcher: null | Fetcher | void = null; if (typeof window !== null && window?.fetch) { @@ -53,14 +53,14 @@ export function buildGraphiQLFetcher(options: BuildFetcherOptions): Fetcher { if (graphQLParams.operationName === 'IntrospectionQuery') { return simpleFetcher(graphQLParams, opts); } - const isSubscription = isSubcriptionWithName( + const isSubscription = isSubscriptionWithName( opts?.documentAST!, graphQLParams.operationName, ); if (isSubscription) { if (!wsFetcher) { throw Error( - `Your GraphiQL buildFetcher is not properly configured for websocket subscriptions yet. ${ + `Your GraphiQL createFetcher is not properly configured for websocket subscriptions yet. ${ options.subscriptionUrl ? `Provided URL ${options.subscriptionUrl} failed` : `Try providing options.subscriptionUrl or options.wsClient first.` diff --git a/packages/graphiql-create-fetcher/src/index.ts b/packages/graphiql-create-fetcher/src/index.ts new file mode 100644 index 00000000000..cd0cc758484 --- /dev/null +++ b/packages/graphiql-create-fetcher/src/index.ts @@ -0,0 +1,2 @@ +export type { CreateFetcherOptions } from './types'; +export { createGraphiQLFetcher } from './createFetcher'; diff --git a/packages/graphiql-build-fetcher/src/lib.ts b/packages/graphiql-create-fetcher/src/lib.ts similarity index 91% rename from packages/graphiql-build-fetcher/src/lib.ts rename to packages/graphiql-create-fetcher/src/lib.ts index 17984d50787..a44c3bc92cd 100644 --- a/packages/graphiql-build-fetcher/src/lib.ts +++ b/packages/graphiql-create-fetcher/src/lib.ts @@ -10,7 +10,7 @@ import type { FetcherParams, FetcherOpts, } from '@graphiql/toolkit'; -import type { BuildFetcherOptions } from './types'; +import type { CreateFetcherOptions } from './types'; /** * Returns true if the name matches a subscription in the AST @@ -19,33 +19,33 @@ import type { BuildFetcherOptions } from './types'; * @param name the operation name to lookup * @returns {boolean} */ -export const isSubcriptionWithName = ( +export const isSubscriptionWithName = ( document: DocumentNode, name: string, ): boolean => { - let isSubcription = false; + let isSubscription = false; visit(document, { OperationDefinition(node) { if (name === node.name?.value) { if (node.operation === 'subscription') { - isSubcription = true; + isSubscription = true; } } }, }); - return isSubcription; + return isSubscription; }; /** * create a simple HTTP/S fetcher using a fetch implementation where * multipart is not needed * - * @param options {BuildFetcherOptions} + * @param options {CreateFetcherOptions} * @param httpFetch {typeof fetch} * @returns {Fetcher} */ export const createSimpleFetcher = ( - options: BuildFetcherOptions, + options: CreateFetcherOptions, httpFetch: typeof fetch, ): Fetcher => async ( graphQLParams: FetcherParams, @@ -119,11 +119,11 @@ export const createLegacyWebsocketsFetcher = ( * create a fetcher with the `IncrementalDelivery` HTTP/S spec for * `@stream` and `@defer` support using `fetch-multipart-graphql` * - * @param options {BuildFetcherOptions} + * @param options {CreateFetcherOptions} * @returns {Fetcher} */ export const createMultipartFetcher = ( - options: BuildFetcherOptions, + options: CreateFetcherOptions, ): Fetcher => async (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) => makeAsyncIterableIteratorFromSink(sink => { fetchMultipart(options.url, { diff --git a/packages/graphiql-build-fetcher/src/types.ts b/packages/graphiql-create-fetcher/src/types.ts similarity index 96% rename from packages/graphiql-build-fetcher/src/types.ts rename to packages/graphiql-create-fetcher/src/types.ts index 79eea3c40b5..c35514fa9fc 100644 --- a/packages/graphiql-build-fetcher/src/types.ts +++ b/packages/graphiql-create-fetcher/src/types.ts @@ -6,7 +6,7 @@ export type WebsocketsClient = Client | SubscriptionClient; /** * Options for creating a sinple, spec-compliant GraphiQL fetcher */ -export interface BuildFetcherOptions { +export interface CreateFetcherOptions { /** * url for HTTP(S) requests. required! */ diff --git a/packages/graphiql-build-fetcher/tsconfig.esm.json b/packages/graphiql-create-fetcher/tsconfig.esm.json similarity index 80% rename from packages/graphiql-build-fetcher/tsconfig.esm.json rename to packages/graphiql-create-fetcher/tsconfig.esm.json index f5615d848f6..658a1a5af19 100644 --- a/packages/graphiql-build-fetcher/tsconfig.esm.json +++ b/packages/graphiql-create-fetcher/tsconfig.esm.json @@ -2,12 +2,10 @@ "extends": "../../resources/tsconfig.base.esm.json", "compilerOptions": { "rootDir": "./src", - "outDir": "./dist", + "outDir": "./esm", "composite": true, "jsx": "react", - "strictPropertyInitialization": false, - "module": "ESNext", - "target": "ESNext" + "baseUrl": "." }, "include": ["src"], "exclude": [ diff --git a/packages/graphiql-build-fetcher/tsconfig.json b/packages/graphiql-create-fetcher/tsconfig.json similarity index 58% rename from packages/graphiql-build-fetcher/tsconfig.json rename to packages/graphiql-create-fetcher/tsconfig.json index d2dff622688..d6e80b99433 100644 --- a/packages/graphiql-build-fetcher/tsconfig.json +++ b/packages/graphiql-create-fetcher/tsconfig.json @@ -1,18 +1,15 @@ { - "extends": "../../resources/tsconfig.base.esm.json", + "extends": "../../resources/tsconfig.base.cjs.json", "compilerOptions": { "rootDir": "./src", - "outDir": "./esm", - "composite": false, + "outDir": "./dist", + "composite": true, "jsx": "react", - "baseUrl": ".", - "target": "ES5", - "module": "CommonJS", - "lib": ["DOM", "ESNext"] + "target": "es5", + "baseUrl": "." }, "include": ["src"], "exclude": [ - "node_modules", "**/__tests__/**", "**/dist/**.*", "**/*.spec.ts", @@ -20,7 +17,8 @@ "**/*-test.ts", "**/*-test.js", "**/*.stories.js", - "**/*.stories.ts" + "**/*.stories.ts", + "**/*.stories.tsx" ], "references": [ { diff --git a/packages/graphiql-toolkit/README.md b/packages/graphiql-toolkit/README.md index e69de29bb2d..15bd97f0dae 100644 --- a/packages/graphiql-toolkit/README.md +++ b/packages/graphiql-toolkit/README.md @@ -0,0 +1,15 @@ +# `@graphiql/toolkit` + +General purpose library as a dependency of GraphiQL. + +The goal is to make this and related packages a set of general purpose tools used to build an end implementation like GraphiQL + +It also allows us to share utilities, libraries and components that can be used by + +## Todo + +- [x] Begin porting common type definitions used by GraphiQL and it's dependencies +- [ ] Port over the GraphiQL components library created by @walaura and designed by @orta +- [ ] Migrate over general purpose `graphiql/src/utilities` +- [ ] Frontend framework agnostic state implementation +- [ ] React components and hooks? Or should react specifics live seperately? diff --git a/packages/graphiql-toolkit/package.json b/packages/graphiql-toolkit/package.json index bc9ecc7c59a..ad96577a051 100644 --- a/packages/graphiql-toolkit/package.json +++ b/packages/graphiql-toolkit/package.json @@ -3,9 +3,12 @@ "version": "0.0.1", "description": "Utility to build a fetcher for GraphiQL", "contributors": [ - "Rikki Schulte (http://rikki.dev/" + "Rikki Schulte (https://rikki.dev)" ], - "repository": "http://github.com/graphql/graphiql", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/graphql/graphiql.git" + }, "homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql#readme", "bugs": { "url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql" @@ -13,8 +16,10 @@ "license": "MIT", "main": "dist/index.js", "module": "esm/index.js", + "types": "dist/index.d.ts", "scripts": {}, - "peerDependencies": { - "graphql": "experimental-stream-defer" - } + "keywords": [ + "graphql", + "graphiql" + ] } diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts index 7486954ff8d..a192b88f670 100644 --- a/packages/graphiql-toolkit/src/types.ts +++ b/packages/graphiql-toolkit/src/types.ts @@ -41,7 +41,14 @@ export type FetcherResult = errors?: Array; } | string - | { data?: any; errors?: Array }; + | { data?: any; errors?: Array; hasNext?: boolean } + // for IncrementalDelivery + | Array<{ + data?: any; + errors?: any[]; + path?: [string, number]; + hasNext: boolean; + }>; export type MaybePromise = T | Promise; diff --git a/packages/graphiql-toolkit/tsconfig.esm.json b/packages/graphiql-toolkit/tsconfig.esm.json index e0624bdc43f..fbdc6deed6c 100644 --- a/packages/graphiql-toolkit/tsconfig.esm.json +++ b/packages/graphiql-toolkit/tsconfig.esm.json @@ -2,7 +2,7 @@ "extends": "../../resources/tsconfig.base.esm.json", "compilerOptions": { "rootDir": "./src", - "outDir": "./dist", + "outDir": "./esm", "composite": true, "jsx": "react", "strictPropertyInitialization": false, diff --git a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts new file mode 100644 index 00000000000..81da2a67d36 --- /dev/null +++ b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts @@ -0,0 +1,48 @@ +const testStreamQuery = /* GraphQL */ ` + { + streamable @stream(initialCount: 2) { + text + } + } +`; + +const mockStreamSuccess = { + data: { + streamable: [ + { + text: 'Hi', + }, + { + text: '你好', + }, + { + text: 'Hola', + }, + { + text: 'سلام', + }, + { + text: 'Bonjour', + }, + { + text: '안녕', + }, + { + text: 'Ciao', + }, + { + text: 'हेलो', + }, + { + text: 'Здорово', + }, + ], + }, +}; + +describe('IncrementalDelivery support via fetcher', () => { + it('Executes a GraphQL query over HTTP that has the expected result', () => { + cy.visit(`/?query=${testStreamQuery}`); + cy.assertQueryResult({ query: testStreamQuery }, mockStreamSuccess, 3000); + }); +}); diff --git a/packages/graphiql/cypress/support/commands.ts b/packages/graphiql/cypress/support/commands.ts index 140f96a7c93..7ed93321fb5 100644 --- a/packages/graphiql/cypress/support/commands.ts +++ b/packages/graphiql/cypress/support/commands.ts @@ -31,7 +31,11 @@ declare namespace Cypress { visitWithOp(op: Op): Chainable; clickPrettify(): Chainable; assertHasValues(op: Op): Chainable; - assertQueryResult(op: Op, expectedResult: MockResult): Chainable; + assertQueryResult( + op: Op, + expectedResult: MockResult, + timeout?: number, + ): Chainable; } } @@ -66,14 +70,13 @@ Cypress.Commands.add('assertHasValues', ({ query, variables }) => { }); }); -Cypress.Commands.add('assertQueryResult', (op, mockSuccess) => { +Cypress.Commands.add('assertQueryResult', (op, mockSuccess, timeout = 200) => { cy.visitWithOp(op); cy.clickExecuteQuery(); - cy.wait(200); + cy.wait(timeout); cy.window().then(w => { // @ts-ignore - expect(JSON.parse(w.g.resultComponent.viewer.getValue())).to.deep.equal( - mockSuccess, - ); + const value = w.g.resultComponent.viewer.getValue(); + expect(value).to.deep.equal(JSON.stringify(mockSuccess, null, 2)); }); }); diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index eb87d1fc375..f4a61927731 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -14,6 +14,7 @@ "license": "MIT", "main": "dist/index.js", "module": "esm/index.js", + "types": "dist/index.d.ts", "files": [ "dist", "esm", @@ -48,14 +49,14 @@ "entities": "^2.0.0", "graphql-language-service": "^3.1.2", "markdown-it": "^10.0.0", - "@graphiql/toolkit": "^0.0.1" + "@graphiql/toolkit": "^0.0.1", + "@graphiql/create-fetcher": "^0.0.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0", "prop-types": ">=15.5.0", "react": "^16.8.0", - "react-dom": "^16.8.0", - "@graphiql/build-fetcher": "^0.0.1" + "react-dom": "^16.8.0" }, "devDependencies": { "@testing-library/jest-dom": "5.1.1", @@ -65,7 +66,6 @@ "@types/node": "^13.7.1", "@types/testing-library__jest-dom": "^5.0.1", "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", - "@graphiql/build-fetcher": "^0.0.1", "babel-loader": "^8.1.0", "babel-plugin-macros": "^2.8.0", "cross-env": "^7.0.0", diff --git a/packages/graphiql/resources/renderExample.js b/packages/graphiql/resources/renderExample.js index fa4732b12c2..52fd0bdcd6e 100644 --- a/packages/graphiql/resources/renderExample.js +++ b/packages/graphiql/resources/renderExample.js @@ -99,7 +99,7 @@ const api = isDev // additional child elements. ReactDOM.render( React.createElement(GraphiQL, { - fetcher: GraphiQL.buildFetcher({ url: api }), + fetcher: GraphiQL.createFetcher({ url: api }), query: parameters.query, variables: parameters.variables, headers: parameters.headers, diff --git a/packages/graphiql/src/cdn.ts b/packages/graphiql/src/cdn.ts index c1dd63b000b..72f5d2d082c 100644 --- a/packages/graphiql/src/cdn.ts +++ b/packages/graphiql/src/cdn.ts @@ -6,7 +6,7 @@ */ import 'regenerator-runtime/runtime'; -import { buildGraphiQLFetcher } from '@graphiql/build-fetcher'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; import './css/app.css'; import './css/codemirror.css'; @@ -24,6 +24,6 @@ import { GraphiQL } from './components/GraphiQL'; // add the static function here for CDN only. otherwise, doing this in the component could // add unwanted dependencies to the bundle. // @ts-ignore -GraphiQL.buildFetcher = buildGraphiQLFetcher; +GraphiQL.createFetcher = createGraphiQLFetcher; export default GraphiQL; diff --git a/packages/graphiql/src/components/DocExplorer/SearchResults.tsx b/packages/graphiql/src/components/DocExplorer/SearchResults.tsx index 06f8aa69b23..d8bd30c3142 100644 --- a/packages/graphiql/src/components/DocExplorer/SearchResults.tsx +++ b/packages/graphiql/src/components/DocExplorer/SearchResults.tsx @@ -68,7 +68,7 @@ export default class SearchResults extends React.Component< ); } - if ('getFields' in type) { + if (type && 'getFields' in type) { const fields = type.getFields(); Object.keys(fields).forEach(fieldName => { const field = fields[fieldName]; diff --git a/packages/graphiql/src/components/DocExplorer/TypeDoc.tsx b/packages/graphiql/src/components/DocExplorer/TypeDoc.tsx index e881f2e5a14..e7bb87b0f7f 100644 --- a/packages/graphiql/src/components/DocExplorer/TypeDoc.tsx +++ b/packages/graphiql/src/components/DocExplorer/TypeDoc.tsx @@ -86,7 +86,7 @@ export default class TypeDoc extends React.Component< // InputObject and Object let fieldsDef; let deprecatedFieldsDef; - if ('getFields' in type) { + if (type && 'getFields' in type) { const fieldMap = type.getFields(); const fields = Object.keys(fieldMap).map(name => fieldMap[name]); fieldsDef = ( diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx index 5bd26e6ca14..b21127c5139 100644 --- a/packages/graphiql/src/components/GraphiQL.tsx +++ b/packages/graphiql/src/components/GraphiQL.tsx @@ -1066,7 +1066,7 @@ export class GraphiQL extends React.Component { ); } - const totalResponse = { data: {} }; + const totalResponse: FetcherResult = { data: {} }; // _fetchQuery may return a subscription. const subscription = await this._fetchQuery( @@ -1080,14 +1080,18 @@ export class GraphiQL extends React.Component { if (Array.isArray(result)) { // for `IncrementalDelivery` // https://github.com/graphql/graphql-over-http/blob/master/rfcs/IncrementalDelivery.md - // TODO: types + // TODO: typescript types const response = result.reduce((result, increment) => { if (increment.errors) { - result.errors = [...result?.errors, ...increment?.errors]; + result.errors = [ + ...(result?.errors || []), + ...increment?.errors, + ]; } if (increment.path) { const [path, index] = increment.path; const data = result?.data[path] || []; + // place them at the exact index. this matters a lot data[index] = increment.data; result.data = { ...result?.data, [path]: data }; } else { diff --git a/packages/graphiql/test/schema.js b/packages/graphiql/test/schema.js index 38c777ca7b5..65d109158d7 100644 --- a/packages/graphiql/test/schema.js +++ b/packages/graphiql/test/schema.js @@ -150,8 +150,22 @@ const TestType = new GraphQLObjectType({ streamable: { type: new GraphQLList(Greeting), resolve: async function* sayHiInFiveLanguages() { - for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) { - await sleep(800); + let i = 0; + for (const hi of [ + 'Hi', + '你好', + 'Hola', + 'سلام', + 'Bonjour', + '안녕', + 'Ciao', + 'हेलो', + 'Здорово', + ]) { + if (i > 2) { + await sleep(400); + } + i++; yield { text: hi }; } }, diff --git a/packages/graphiql/tsconfig.esm.json b/packages/graphiql/tsconfig.esm.json index b37cf5405e6..b41ed514246 100644 --- a/packages/graphiql/tsconfig.esm.json +++ b/packages/graphiql/tsconfig.esm.json @@ -20,6 +20,12 @@ "**/*.stories.ts" ], "references": [ + { + "path": "../graphiql-toolkit/tsconfig.esm.json" + }, + { + "path": "../graphiql-create-fetcher" + }, { "path": "../graphql-language-service/tsconfig.esm.json" }, @@ -31,9 +37,6 @@ }, { "path": "../graphql-language-service-utils/tsconfig.esm.json" - }, - { - "path": "../graphiql-toolkit/tsconfig.esm.json" } ] } diff --git a/packages/graphiql/tsconfig.json b/packages/graphiql/tsconfig.json index cf9915b9538..1a23cf8d7bf 100644 --- a/packages/graphiql/tsconfig.json +++ b/packages/graphiql/tsconfig.json @@ -21,6 +21,9 @@ "**/*.stories.tsx" ], "references": [ + { + "path": "../graphiql-create-fetcher" + }, { "path": "../graphql-language-service" }, @@ -32,9 +35,6 @@ }, { "path": "../graphql-language-service-interface" - }, - { - "path": "../graphiql-toolkit" } ] } diff --git a/resources/tsconfig.build.cjs.json b/resources/tsconfig.build.cjs.json index c949964496b..d4300443803 100644 --- a/resources/tsconfig.build.cjs.json +++ b/resources/tsconfig.build.cjs.json @@ -6,7 +6,7 @@ "include": [], "references": [ { - "path": "../packages/graphiql-build-fetcher" + "path": "../packages/graphiql-create-fetcher" }, { "path": "../packages/graphiql-toolkit" diff --git a/resources/tsconfig.build.esm.json b/resources/tsconfig.build.esm.json index 40794dee009..656c6d281d1 100644 --- a/resources/tsconfig.build.esm.json +++ b/resources/tsconfig.build.esm.json @@ -6,7 +6,7 @@ "include": [], "references": [ { - "path": "../packages/graphiql-build-fetcher/tsconfig.esm.json" + "path": "../packages/graphiql-create-fetcher/tsconfig.esm.json" }, { "path": "../packages/graphiql-toolkit/tsconfig.esm.json" diff --git a/yarn.lock b/yarn.lock index 502d3df7997..0fc1e6d0826 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9035,11 +9035,6 @@ create-react-context@0.3.0, create-react-context@^0.3.0: gud "^1.0.0" warning "^4.0.3" -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - cross-env@^7.0.0, cross-env@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" @@ -12082,6 +12077,7 @@ grapheme-breaker@^0.3.2: "graphiql@file:packages/graphiql": version "1.3.2" dependencies: + "@graphiql/create-fetcher" "^0.0.1" "@graphiql/toolkit" "^0.0.1" codemirror "^5.54.0" codemirror-graphql "^0.15.2" @@ -21313,18 +21309,6 @@ ts-node@^8.10.2: source-map-support "^0.5.17" yn "3.1.1" -ts-node@^9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== - dependencies: - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - ts-pnp@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" @@ -22737,7 +22721,7 @@ ws@^7.2.1, ws@^7.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== -ws@^7.3.1, ws@^7.4.2: +ws@^7.3.1: version "7.4.2" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== From 532779135661b562cede82e8734a6e20bb72c1db Mon Sep 17 00:00:00 2001 From: Rikki Date: Mon, 25 Jan 2021 20:43:41 -0500 Subject: [PATCH 5/8] chore: improve/stabilize e2e tests --- .../graphiql/cypress/integration/docs.spec.ts | 1 + .../integration/incrementalDelivery.spec.ts | 27 ++++++++++--- .../cypress/integration/prettify.spec.ts | 21 +++++----- packages/graphiql/cypress/support/commands.ts | 38 ++++++++++++------- packages/graphiql/test/schema.js | 17 +++++++-- 5 files changed, 73 insertions(+), 31 deletions(-) diff --git a/packages/graphiql/cypress/integration/docs.spec.ts b/packages/graphiql/cypress/integration/docs.spec.ts index 21d08288183..ddc85cc87cc 100644 --- a/packages/graphiql/cypress/integration/docs.spec.ts +++ b/packages/graphiql/cypress/integration/docs.spec.ts @@ -51,6 +51,7 @@ describe('GraphiQL DocExplorer - search', () => { it('Type fields link to their own docs entry', () => { cy.get('label.search-box input').type('test'); + cy.pause(); cy.get('.doc-search-items>.doc-category-item') .last() .find('a:nth-child(2)') diff --git a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts index 81da2a67d36..ad618a072e4 100644 --- a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts +++ b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts @@ -1,6 +1,6 @@ const testStreamQuery = /* GraphQL */ ` - { - streamable @stream(initialCount: 2) { + query StreamQuery($delay: Int) { + streamable(delay: $delay) @stream(initialCount: 2) { text } } @@ -19,11 +19,14 @@ const mockStreamSuccess = { text: 'Hola', }, { - text: 'سلام', + text: 'أهلاً', }, { text: 'Bonjour', }, + { + text: 'سلام', + }, { text: '안녕', }, @@ -41,8 +44,22 @@ const mockStreamSuccess = { }; describe('IncrementalDelivery support via fetcher', () => { - it('Executes a GraphQL query over HTTP that has the expected result', () => { + it('Expects slower streams to resolve in several increments', () => { + const delay = 100; + const timeout = mockStreamSuccess.data.streamable.length * (delay * 1.5); + + cy.visit(`/?query=${testStreamQuery}`); + cy.assertQueryResult( + { query: testStreamQuery, variables: { delay } }, + mockStreamSuccess, + timeout, + ); + }); + it('Expects a quick stream to resolve in a single increment', () => { cy.visit(`/?query=${testStreamQuery}`); - cy.assertQueryResult({ query: testStreamQuery }, mockStreamSuccess, 3000); + cy.assertQueryResult( + { query: testStreamQuery, variables: { delay: 0 } }, + mockStreamSuccess, + ); }); }); diff --git a/packages/graphiql/cypress/integration/prettify.spec.ts b/packages/graphiql/cypress/integration/prettify.spec.ts index 1c1e7a7c54f..8472c8f4f76 100644 --- a/packages/graphiql/cypress/integration/prettify.spec.ts +++ b/packages/graphiql/cypress/integration/prettify.spec.ts @@ -19,53 +19,56 @@ const brokenVariables = `"a": 1}`; describe('GraphiQL Prettify', () => { it('Regular prettification', () => { - cy.visitWithOp({ query: uglyQuery, variables: uglyVariables }); + cy.visitWithOp({ query: uglyQuery, variablesString: uglyVariables }); cy.clickPrettify(); cy.window().then(w => { cy.assertHasValues({ query: prettifiedQuery, - variables: prettifiedVariables, + variablesString: prettifiedVariables, }); }); }); it('Noop prettification', () => { - cy.visitWithOp({ query: prettifiedQuery, variables: prettifiedVariables }); + cy.visitWithOp({ + query: prettifiedQuery, + variablesString: prettifiedVariables, + }); cy.clickPrettify(); cy.window().then(w => { cy.assertHasValues({ query: prettifiedQuery, - variables: prettifiedVariables, + variablesString: prettifiedVariables, }); }); }); it('No crash on bad query', () => { - cy.visitWithOp({ query: brokenQuery, variables: uglyVariables }); + cy.visitWithOp({ query: brokenQuery, variablesString: uglyVariables }); cy.clickPrettify(); cy.window().then(w => { cy.assertHasValues({ query: brokenQuery, - variables: prettifiedVariables, + variablesString: prettifiedVariables, }); }); }); - it('No crash on bad variables', () => { - cy.visitWithOp({ query: uglyQuery, variables: brokenVariables }); + it('No crash on bad variablesString', () => { + cy.visitWithOp({ query: uglyQuery, variablesString: brokenVariables }); cy.clickPrettify(); cy.window().then(w => { cy.assertHasValues({ query: prettifiedQuery, - variables: brokenVariables, + variablesString: brokenVariables, }); }); }); diff --git a/packages/graphiql/cypress/support/commands.ts b/packages/graphiql/cypress/support/commands.ts index 7ed93321fb5..38d7db2ac5d 100644 --- a/packages/graphiql/cypress/support/commands.ts +++ b/packages/graphiql/cypress/support/commands.ts @@ -13,7 +13,8 @@ declare namespace Cypress { type Op = { query: string; - variables?: string; + variables?: Record; + variablesString?: string; }; type MockResult = | { @@ -51,24 +52,35 @@ Cypress.Commands.add('clickPrettify', () => { return cy.get('[title="Prettify Query (Shift-Ctrl-P)"]').click(); }); -Cypress.Commands.add('visitWithOp', ({ query, variables }) => { +Cypress.Commands.add('visitWithOp', ({ query, variables, variablesString }) => { let url = `/?query=${encodeURIComponent(query)}`; - if (variables) { - url += `&variables=${encodeURIComponent(variables)}`; + if (variables || variablesString) { + url += `&variables=${encodeURIComponent( + JSON.stringify(variables, null, 2) || variablesString, + )}`; } return cy.visit(url); }); -Cypress.Commands.add('assertHasValues', ({ query, variables }) => { - cy.window().then(w => { - // @ts-ignore - expect(w.g.getQueryEditor().getValue()).to.equal(query); - if (variables) { +Cypress.Commands.add( + 'assertHasValues', + ({ query, variables, variablesString }) => { + cy.window().then(w => { // @ts-ignore - expect(w.g.getVariableEditor().getValue()).to.equal(variables); - } - }); -}); + expect(w.g.getQueryEditor().getValue()).to.equal(query); + if (variables) { + // @ts-ignore + expect(w.g.getVariableEditor().getValue()).to.equal( + JSON.stringify(variables, null, 2), + ); + } + if (variablesString) { + // @ts-ignore + expect(w.g.getVariableEditor().getValue()).to.equal(variablesString); + } + }); + }, +); Cypress.Commands.add('assertQueryResult', (op, mockSuccess, timeout = 200) => { cy.visitWithOp(op); diff --git a/packages/graphiql/test/schema.js b/packages/graphiql/test/schema.js index 65d109158d7..182da92e072 100644 --- a/packages/graphiql/test/schema.js +++ b/packages/graphiql/test/schema.js @@ -149,21 +149,30 @@ const TestType = new GraphQLObjectType({ }, streamable: { type: new GraphQLList(Greeting), - resolve: async function* sayHiInFiveLanguages() { + args: { + delay: { + description: + 'delay in milleseconds for subsequent results, for demonstration purposes', + type: GraphQLInt, + defaultValue: 400, + }, + }, + resolve: async function* sayHiInSomeLanguages(_value, args) { let i = 0; for (const hi of [ 'Hi', '你好', 'Hola', - 'سلام', + 'أهلاً', 'Bonjour', + 'سلام', '안녕', 'Ciao', 'हेलो', 'Здорово', ]) { if (i > 2) { - await sleep(400); + await sleep(args.delay); } i++; yield { text: hi }; @@ -206,7 +215,7 @@ const TestType = new GraphQLObjectType({ }, hasArgs: { type: GraphQLString, - resolve(value, args) { + resolve(_value, args) { return JSON.stringify(args); }, args: { From 26feeeba83dc213fc430f193f469dffd6b3c2671 Mon Sep 17 00:00:00 2001 From: Rikki Date: Mon, 25 Jan 2021 22:18:52 -0500 Subject: [PATCH 6/8] chore: attempt netlify function --- .gitignore | 3 + functions/schema-demo.js | 49 ++++++++++++ package.json | 7 +- packages/graphiql-2-rfc-context/package.json | 2 +- packages/graphiql/package.json | 2 +- packages/graphiql/resources/renderExample.js | 17 +++-- yarn.lock | 78 ++++++++++++++++---- 7 files changed, 131 insertions(+), 27 deletions(-) create mode 100644 functions/schema-demo.js diff --git a/.gitignore b/.gitignore index 13cdf2ebf45..08aee99fa65 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ lerna-debug.log .yarnrc yarn-1.18.0.js *.orig + +# Local Netlify folder +.netlify \ No newline at end of file diff --git a/functions/schema-demo.js b/functions/schema-demo.js new file mode 100644 index 00000000000..71dcfcc6cce --- /dev/null +++ b/functions/schema-demo.js @@ -0,0 +1,49 @@ +/* example using https://github.com/awslabs/aws-serverless-express */ +const express = require('express'); +const { graphqlHTTP } = require('express-graphql'); +const awsServerlessExpress = require('aws-serverless-express'); +const schema = require('../packages/graphiql/test/schema'); +const cors = require('cors'); + +const binaryMimeTypes = [ + 'application/javascript', + 'application/json', + 'font/eot', + 'font/opentype', + 'font/otf', + 'image/jpeg', + 'image/png', + 'image/svg+xml', + 'text/css', + 'text/html', + 'text/javascript', + 'multipart/mixed', +]; + +const app = express(); + +app.use(cors({ origin: '*' })); + +// Requests to /graphql redirect to / +app.all('/graphql', (req, res) => res.redirect('/')); + +// Finally, serve up the GraphQL Schema itself +app.use( + '/', + graphqlHTTP(() => ({ schema })), +); + +const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes); + +exports.handler = (event, context) => + awsServerlessExpress.proxy(server, event, context); + +// // Server +// app.post('/graphql', graphqlHTTP({ schema })); + +// // app.get('/graphql', graphQLMiddleware); +// // Export Lambda handler + +// exports.handler = serverless(app, { +// httpMethod: 'POST' +// }) diff --git a/package.json b/package.json index e3cd581fb8b..3b3dfcba74b 100644 --- a/package.json +++ b/package.json @@ -82,20 +82,23 @@ "@octokit/rest": "^18.0.12", "@strictsoftware/typedoc-plugin-monorepo": "^0.3.1", "@testing-library/jest-dom": "^5.4.0", + "@types/aws-serverless-express": "^3.3.3", "@types/codemirror": "^0.0.90", "@types/express": "^4.17.11", "@types/fetch-mock": "^7.3.2", "@types/jest": "^26.0.20", - "@types/node": "^13.11.1", + "@types/node": "^14.14.22", "@types/prettier": "^2.0.0", "@types/theme-ui": "^0.3.1", "@types/ws": "^7.4.0", "@typescript-eslint/eslint-plugin": "^4.14.0", "@typescript-eslint/parser": "^4.14.0", + "aws-serverless-express": "^3.4.0", "babel-eslint": "^10.1.0", "babel-jest": "^25.3.0", "conventional-changelog-conventionalcommits": "^4.2.3", "copy": "^0.3.2", + "cors": "^2.8.5", "cross-env": "^7.0.2", "cypress": "^4.7.0", "eslint": "^6.8.0", @@ -108,6 +111,7 @@ "eslint-plugin-prefer-object-spread": "1.2.1", "eslint-plugin-react": "7.19.0", "eslint-plugin-react-hooks": "^3.0.0", + "express": "^4.17.1", "fetch-mock": "6.5.2", "flow-bin": "^0.119.1", "husky": "^4.2.3", @@ -120,6 +124,7 @@ "mkdirp": "^1.0.4", "prettier": "^2.0.4", "rimraf": "^3.0.2", + "serverless-http": "^2.7.0", "ts-jest": "^25.3.1", "typedoc": "^0.19.2", "typescript": "^4.1.3", diff --git a/packages/graphiql-2-rfc-context/package.json b/packages/graphiql-2-rfc-context/package.json index b335d4ca0d8..8cc222dd936 100644 --- a/packages/graphiql-2-rfc-context/package.json +++ b/packages/graphiql-2-rfc-context/package.json @@ -77,7 +77,7 @@ "cssnano": "^4.1.10", "error-overlay-webpack-plugin": "^0.4.1", "express": "4.17.1", - "express-graphql": "0.9.0", + "express-graphql": "experimental-stream-defer", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "4.1.3", "graphql": "experimental-stream-defer", diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index f4a61927731..3af1d2746ed 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -71,7 +71,7 @@ "cross-env": "^7.0.0", "css-loader": "3.4.2", "cssnano": "^4.1.10", - "express": "4.17.1", + "express": "^4.17.1", "express-graphql": "experimental-stream-defer", "fork-ts-checker-webpack-plugin": "4.1.3", "graphql": "experimental-stream-defer", diff --git a/packages/graphiql/resources/renderExample.js b/packages/graphiql/resources/renderExample.js index 52fd0bdcd6e..1f18f8d0c78 100644 --- a/packages/graphiql/resources/renderExample.js +++ b/packages/graphiql/resources/renderExample.js @@ -1,10 +1,13 @@ /** - * This GraphiQL example illustrates how to use some of GraphiQL's props - * in order to enable reading and updating the URL parameters, making - * link sharing of queries a little bit easier. + * UMD GraphiQL Example * - * This is only one example of this kind of feature, GraphiQL exposes - * various React params to enable interesting integrations. + * This is a simple example that provides a primitive query string parser on top of GraphiQL props + * It assumes a global umd GraphiQL, which would be provided by an index.html in the default example + * + * It is used by: + * - the netlify demo + * - end to end tests + * - webpack dev server */ // Parse the search string to get url parameters. @@ -89,9 +92,7 @@ function updateURL() { } const isDev = window.location.hostname.match(/localhost$/); -const api = isDev - ? '/graphql' - : 'https://swapi-graphql.netlify.app/.netlify/functions/index'; +const api = isDev ? '/graphql' : '/.netlify/functions/schema-demo'; // Render into the body. // See the README in the top level of this module to learn more about diff --git a/yarn.lock b/yarn.lock index 0fc1e6d0826..229e151768f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5411,6 +5411,20 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== +"@types/aws-lambda@*", "@types/aws-lambda@^8.10.56": + version "8.10.71" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.71.tgz#ab3084038411ce42f63b975e67aafb163f3aa353" + integrity sha512-l0Lag6qq06AlKllprAJ3pbgVUbXCjRGRb7VpHow8IMn2BMHTPR0t5OD97/w8CR1+wA5XZuWQoXLjYvdlk2kQrQ== + +"@types/aws-serverless-express@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@types/aws-serverless-express/-/aws-serverless-express-3.3.3.tgz#8af184bf16e1ba0269de318ac7b7fd638c7df70c" + integrity sha512-gIPinyiEsda2Z6Dx6GdQs47/GXaBGEGOMkYWtmqFDsVSDHzWtnIKBBBVQKyMdcK/0ZXa31zzlT+CobFnwNbsTQ== + dependencies: + "@types/aws-lambda" "*" + "@types/express" "*" + "@types/node" "*" + "@types/babel__core@^7.1.0": version "7.1.9" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d" @@ -5518,7 +5532,7 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@^4.17.11": +"@types/express@*", "@types/express@^4.17.11": version "4.17.11" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545" integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg== @@ -5653,7 +5667,7 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>= 8", "@types/node@^13.11.1": +"@types/node@*", "@types/node@>= 8": version "13.11.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== @@ -5663,6 +5677,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.18.tgz#e932b06eb33294f5b97a67de3b820fc6f456ad1c" integrity sha512-nru5D2PxzwzWyo3ocADAkzbc5H1KxVJMmX8oco9Fe5c+4vv6+MMp93wPq6ADqwHAwDtNH55eTCNGVaIZHZsAFQ== +"@types/node@^14.14.22": + version "14.14.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18" + integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -6039,6 +6058,14 @@ "@typescript-eslint/types" "4.14.0" eslint-visitor-keys "^2.0.0" +"@vendia/serverless-express@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@vendia/serverless-express/-/serverless-express-3.4.0.tgz#156f47d364b067ae6fa678a914c51887f494321a" + integrity sha512-/UAAbi9qRjUtjRISt5MJ1sfhtrHb26hqQ0nvE5qhMLsAdR5H7ErBwPD8Q/v2OENKm0iWsGwErIZEg7ebUeFDjQ== + dependencies: + binary-case "^1.0.0" + type-is "^1.6.16" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -7008,6 +7035,15 @@ autoprefixer@^9.6.1, autoprefixer@^9.7.2: postcss "^7.0.32" postcss-value-parser "^4.1.0" +aws-serverless-express@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/aws-serverless-express/-/aws-serverless-express-3.4.0.tgz#74153b8cc80dbd2c6a32a51e6d353a325c2710d7" + integrity sha512-YG9ZjAOI9OpwqDDWzkRc3kKJYJuR7gTMjLa3kAWopO17myoprxskCUyCEee+RKe34tcR4UNrVtgAwW5yDe74bw== + dependencies: + "@vendia/serverless-express" "^3.4.0" + binary-case "^1.0.0" + type-is "^1.6.16" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -7587,6 +7623,11 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +binary-case@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/binary-case/-/binary-case-1.1.4.tgz#d687104d59e38f2b9e658d3a58936963c59ab931" + integrity sha512-9Kq8m6NZTAgy05Ryuh7U3Qc4/ujLQU1AZ5vMw4cr3igTdi5itZC6kCNrRr2X8NzPiDn2oUIFTfa71DKMnue/Zg== + binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -8975,6 +9016,14 @@ corejs-upgrade-webpack-plugin@^2.2.0: resolve-from "^5.0.0" webpack "^4.38.0" +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@6.0.0, cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -10860,16 +10909,6 @@ expect@^25.3.0: jest-message-util "^25.3.0" jest-regex-util "^25.2.6" -express-graphql@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.9.0.tgz#00fd8552f866bac5c9a4612b2c4c82076107b3c2" - integrity sha512-wccd9Lb6oeJ8yHpUs/8LcnGjFUUQYmOG9A5BNLybRdCzGw0PeUrtBxsIR8bfiur6uSW4OvPkVDoYH06z6/N9+w== - dependencies: - accepts "^1.3.7" - content-type "^1.0.4" - http-errors "^1.7.3" - raw-body "^2.4.1" - express-graphql@experimental-stream-defer: version "0.12.0-experimental-stream-defer.1" resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.12.0-experimental-stream-defer.1.tgz#1723f400cd94065e9a584ad4677a0d2ce4a7e7d1" @@ -12520,7 +12559,7 @@ http-errors@1.7.3, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@1.8.0, http-errors@^1.7.3: +http-errors@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== @@ -16302,7 +16341,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -19845,6 +19884,13 @@ serve@^11.3.0: serve-handler "6.1.3" update-check "1.5.2" +serverless-http@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/serverless-http/-/serverless-http-2.7.0.tgz#352ca38cbbba58dc71dcfb11bb27c92c3c81fe69" + integrity sha512-iWq0z1X2Xkuvz6wL305uCux/SypbojHlYsB5bzmF5TqoLYsdvMNIoCsgtWjwqWoo3AR2cjw3zAmHN2+U6mF99Q== + optionalDependencies: + "@types/aws-lambda" "^8.10.56" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -21390,7 +21436,7 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-is@~1.6.17, type-is@~1.6.18: +type-is@^1.6.16, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -21824,7 +21870,7 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= From 3292e854630f753cf3ac18ea589080c71a2dc781 Mon Sep 17 00:00:00 2001 From: Marais Rossouw Date: Sat, 30 Jan 2021 07:02:44 +1000 Subject: [PATCH 7/8] improvement: move incremental client from fmg to meros (#1774) --- packages/graphiql-create-fetcher/README.md | 2 +- packages/graphiql-create-fetcher/package.json | 2 +- .../src/__tests__/buildFetcher.spec.ts | 8 +-- .../src/createFetcher.ts | 2 +- packages/graphiql-create-fetcher/src/lib.ts | 43 ++++++++++----- packages/graphiql-toolkit/src/types.ts | 12 ++-- .../integration/incrementalDelivery.spec.ts | 1 + packages/graphiql/package.json | 5 +- packages/graphiql/src/components/GraphiQL.tsx | 55 +++++++++++-------- yarn.lock | 16 ++++-- 10 files changed, 88 insertions(+), 58 deletions(-) diff --git a/packages/graphiql-create-fetcher/README.md b/packages/graphiql-create-fetcher/README.md index 0854f76c192..8df848552df 100644 --- a/packages/graphiql-create-fetcher/README.md +++ b/packages/graphiql-create-fetcher/README.md @@ -2,7 +2,7 @@ a utility for generating a full-featured fetcher for GraphiQL. -under the hood, it uses [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) and [`fetch-multipart-graphql`](https://www.npmjs.com/package/fetch-multipart-graphql) to follow the [GraphQL over HTTP Working Group Spec](https://github.com/graphql/graphql-over-http) both accepted and advanced proposals. +under the hood, it uses [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) and [`meros`](https://www.npmjs.com/package/meros) to follow the [GraphQL over HTTP Working Group Spec](https://github.com/graphql/graphql-over-http) both accepted and advanced proposals. ### Setup diff --git a/packages/graphiql-create-fetcher/package.json b/packages/graphiql-create-fetcher/package.json index ddc3d690330..06863ad9500 100644 --- a/packages/graphiql-create-fetcher/package.json +++ b/packages/graphiql-create-fetcher/package.json @@ -21,7 +21,7 @@ "dependencies": { "graphql-ws": "^4.1.0", "subscriptions-transport-ws": "^0.9.18", - "fetch-multipart-graphql": "^3.0.0", + "meros": "^1.0.0", "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", "@graphiql/toolkit": "^0.0.1" }, diff --git a/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts b/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts index c078a62ce08..2fd6de568bd 100644 --- a/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts +++ b/packages/graphiql-create-fetcher/src/__tests__/buildFetcher.spec.ts @@ -41,7 +41,7 @@ describe('createGraphiQLFetcher', () => { const fetcher = createGraphiQLFetcher({ url: serverURL }); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([ - [{ enableIncrementalDelivery: true, url: serverURL }], + [{ enableIncrementalDelivery: true, url: serverURL }, fetch], ]); }); @@ -50,7 +50,7 @@ describe('createGraphiQLFetcher', () => { const fetcher = createGraphiQLFetcher({ url: serverURL }); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); expect(createMultipartFetcher.mock.calls).toEqual([ - [{ enableIncrementalDelivery: true, url: serverURL }], + [{ enableIncrementalDelivery: true, url: serverURL }, fetch], ]); expect(createSimpleFetcher.mock.calls).toEqual([ [{ enableIncrementalDelivery: true, url: serverURL }, fetch], @@ -84,7 +84,7 @@ describe('createGraphiQLFetcher', () => { createGraphiQLFetcher(args); - expect(createMultipartFetcher.mock.calls).toEqual([[args]]); + expect(createMultipartFetcher.mock.calls).toEqual([[args, fetch]]); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([ [args.subscriptionUrl], ]); @@ -103,7 +103,7 @@ describe('createGraphiQLFetcher', () => { createGraphiQLFetcher(args); - expect(createMultipartFetcher.mock.calls).toEqual([[args]]); + expect(createMultipartFetcher.mock.calls).toEqual([[args, fetch]]); expect(createWebsocketsFetcherFromUrl.mock.calls).toEqual([]); }); }); diff --git a/packages/graphiql-create-fetcher/src/createFetcher.ts b/packages/graphiql-create-fetcher/src/createFetcher.ts index ef2ee015e4e..e0897787584 100644 --- a/packages/graphiql-create-fetcher/src/createFetcher.ts +++ b/packages/graphiql-create-fetcher/src/createFetcher.ts @@ -46,7 +46,7 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { } const httpFetcher = options.enableIncrementalDelivery - ? createMultipartFetcher(options) + ? createMultipartFetcher(options, httpFetch) : simpleFetcher; return (graphQLParams, opts) => { diff --git a/packages/graphiql-create-fetcher/src/lib.ts b/packages/graphiql-create-fetcher/src/lib.ts index a44c3bc92cd..4a8cc689510 100644 --- a/packages/graphiql-create-fetcher/src/lib.ts +++ b/packages/graphiql-create-fetcher/src/lib.ts @@ -1,14 +1,18 @@ import { DocumentNode, visit } from 'graphql'; -import fetchMultipart from 'fetch-multipart-graphql'; +import { meros } from 'meros'; import { createClient, Client } from 'graphql-ws'; import { SubscriptionClient } from 'subscriptions-transport-ws'; -import { makeAsyncIterableIteratorFromSink } from '@n1ru4l/push-pull-async-iterable-iterator'; +import { + isAsyncIterable, + makeAsyncIterableIteratorFromSink, +} from '@n1ru4l/push-pull-async-iterable-iterator'; import type { Fetcher, FetcherResult, FetcherParams, FetcherOpts, + FetcherResultPayload, } from '@graphiql/toolkit'; import type { CreateFetcherOptions } from './types'; @@ -124,24 +128,35 @@ export const createLegacyWebsocketsFetcher = ( */ export const createMultipartFetcher = ( options: CreateFetcherOptions, -): Fetcher => async (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) => - makeAsyncIterableIteratorFromSink(sink => { - fetchMultipart(options.url, { + httpFetch: typeof fetch, +): Fetcher => + async function* (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) { + const response = await httpFetch(options.url, { method: 'POST', body: JSON.stringify(graphQLParams), headers: { 'content-type': 'application/json', + accept: 'application/json, multipart/mixed', ...options.headers, // allow user-defined headers to override // the static provided headers ...fetcherOpts?.headers, }, - onNext: parts => { - // @ts-ignore - sink.next(parts); - }, - onError: sink.error, - onComplete: sink.complete, - }); - return () => undefined; - }); + }).then(response => + meros>(response), + ); + + // Follows the same as createSimpleFetcher above, in that we simply return it as json. + if (!isAsyncIterable(response)) { + return yield response.json(); + } + + for await (const part of response) { + if (!part.json) { + throw new Error( + `Expected multipart to be of json type, but got\n\nHeaders: ${part.headers}\n\nBody:${part.body}`, + ); + } + yield part.body; + } + }; diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts index a192b88f670..72bf741e969 100644 --- a/packages/graphiql-toolkit/src/types.ts +++ b/packages/graphiql-toolkit/src/types.ts @@ -35,20 +35,22 @@ export type FetcherOpts = { documentAST?: DocumentNode; }; -export type FetcherResult = +export type FetcherResultPayload = | { data: IntrospectionQuery; errors?: Array; + hasNext?: boolean; } - | string | { data?: any; errors?: Array; hasNext?: boolean } // for IncrementalDelivery - | Array<{ + | { data?: any; errors?: any[]; - path?: [string, number]; + path?: (string | number)[]; hasNext: boolean; - }>; + }; + +export type FetcherResult = FetcherResultPayload | string; export type MaybePromise = T | Promise; diff --git a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts index ad618a072e4..c2ae01a07b4 100644 --- a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts +++ b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts @@ -41,6 +41,7 @@ const mockStreamSuccess = { }, ], }, + hasNext: false, }; describe('IncrementalDelivery support via fetcher', () => { diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index 3af1d2746ed..3529585502e 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -50,7 +50,8 @@ "graphql-language-service": "^3.1.2", "markdown-it": "^10.0.0", "@graphiql/toolkit": "^0.0.1", - "@graphiql/create-fetcher": "^0.0.1" + "@graphiql/create-fetcher": "^0.0.1", + "dset": "^3.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0", @@ -65,7 +66,6 @@ "@types/markdown-it": "^0.0.9", "@types/node": "^13.7.1", "@types/testing-library__jest-dom": "^5.0.1", - "@n1ru4l/push-pull-async-iterable-iterator": "^2.0.1", "babel-loader": "^8.1.0", "babel-plugin-macros": "^2.8.0", "cross-env": "^7.0.0", @@ -77,7 +77,6 @@ "graphql": "experimental-stream-defer", "graphql-ws": "^4.1.0", "graphql-transport-ws": "^1.9.0", - "fetch-multipart-graphql": "^3.0.0", "html-webpack-plugin": "^4.0.4", "identity-obj-proxy": "^3.0.0", "jest": "^24.8.0", diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx index b21127c5139..00ae5d7f023 100644 --- a/packages/graphiql/src/components/GraphiQL.tsx +++ b/packages/graphiql/src/components/GraphiQL.tsx @@ -26,6 +26,7 @@ import { } from 'graphql'; import copyToClipboard from 'copy-to-clipboard'; import { getFragmentDependenciesForAST } from 'graphql-language-service-utils'; +import { dset } from 'dset'; import { ExecuteButton } from './ExecuteButton'; import { ImagePreview } from './ImagePreview'; @@ -61,6 +62,7 @@ import type { SyncFetcherResult, Observable, Unsubscribable, + FetcherResultPayload, } from '@graphiql/toolkit'; const DEFAULT_DOC_EXPLORER_WIDTH = 350; @@ -1066,7 +1068,7 @@ export class GraphiQL extends React.Component { ); } - const totalResponse: FetcherResult = { data: {} }; + const totalResponse: FetcherResultPayload = { data: {} }; // _fetchQuery may return a subscription. const subscription = await this._fetchQuery( @@ -1077,31 +1079,37 @@ export class GraphiQL extends React.Component { shouldPersistHeaders as boolean, (result: FetcherResult) => { if (queryID === this._editorQueryID) { - if (Array.isArray(result)) { - // for `IncrementalDelivery` - // https://github.com/graphql/graphql-over-http/blob/master/rfcs/IncrementalDelivery.md - // TODO: typescript types - const response = result.reduce((result, increment) => { - if (increment.errors) { - result.errors = [ - ...(result?.errors || []), - ...increment?.errors, - ]; - } - if (increment.path) { - const [path, index] = increment.path; - const data = result?.data[path] || []; - // place them at the exact index. this matters a lot - data[index] = increment.data; - result.data = { ...result?.data, [path]: data }; - } else { - result.data = { ...result?.data, ...increment.data }; + if ( + typeof result === 'object' && + result !== null && + 'hasNext' in result + ) { + if (result.errors) { + // We dont care about "index" here, just concat. + totalResponse.errors = [ + ...(totalResponse?.errors || []), + ...result?.errors, + ]; + } + + totalResponse.hasNext = result.hasNext; + + if ('path' in result) { + if (!('data' in result)) { + throw new Error( + `Expected part to contain a data property, but got ${result}`, + ); } - return result; - }, totalResponse); + dset(totalResponse.data, result.path!.map(String), result.data); + } else if ('data' in result) { + // If there is no path, we don't know what to do with the payload, + // so we just set it. + totalResponse.data = result.data; + } + this.setState({ isWaitingForResponse: false, - response: GraphiQL.formatResult(response), + response: GraphiQL.formatResult(totalResponse), }); } else { this.setState({ @@ -1741,7 +1749,6 @@ function asyncIterableToPromise( iteratorNext() .then(result => { - console.log(result.value); resolve(result.value); // ensure cleanup iteratorReturn?.(); diff --git a/yarn.lock b/yarn.lock index 229e151768f..c987bb6935f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10040,6 +10040,11 @@ dotenv@^6.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== +dset@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dset/-/dset-3.0.0.tgz#b49ef4a6a092c2c5328618eca2ccf6885fafb431" + integrity sha512-pp0B9VgLwMem6bfSDJujcXa41swmXkhWICL1jwC7WbD/NaxXPCXO0Z1sOrVshIQaD4D/pi5lDS7NCt6qIytWaA== + duplexer2@~0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -11149,11 +11154,6 @@ fetch-mock@6.5.2: glob-to-regexp "^0.4.0" path-to-regexp "^2.2.1" -fetch-multipart-graphql@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fetch-multipart-graphql/-/fetch-multipart-graphql-3.0.0.tgz#61c9c1623beb4a7330e86ee72e6906148cd20acf" - integrity sha512-asrZG9CMaRUJmzqU+jqyBp52IB3MEzO38bhrPVB73BNAZ8ShBYgQUPOR9d/kYO4dfIrJIki/sTjeNYbUGuqOzQ== - figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" @@ -12121,6 +12121,7 @@ grapheme-breaker@^0.3.2: codemirror "^5.54.0" codemirror-graphql "^0.15.2" copy-to-clipboard "^3.2.0" + dset "^3.0.0" entities "^2.0.0" graphql-language-service "^3.1.2" markdown-it "^10.0.0" @@ -15593,6 +15594,11 @@ merge@^1.2.0: resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== +meros@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/meros/-/meros-1.0.0.tgz#cb1fc818a60afc56bd86c577a9758b4510b3f027" + integrity sha512-gGhudbEI/7Z/5Mc3Mh2VsxWTm0byUB7O34azwchvvDRZ3oaxt5RaN80tF9mwN+plfi2JKDeIQQfJJWwuWmgqBQ== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" From 03d28b147e7fb721d9fe88ef305acbb3dcdac165 Mon Sep 17 00:00:00 2001 From: Rikki Date: Sun, 31 Jan 2021 08:46:44 -0500 Subject: [PATCH 8/8] chore: documentation cleanup --- .../src/createFetcher.ts | 13 +- packages/graphiql-create-fetcher/src/lib.ts | 12 +- packages/graphiql-create-fetcher/src/types.ts | 12 +- packages/graphiql-toolkit/src/types.ts | 10 +- packages/graphiql/README.md | 403 +++++------------- .../integration/incrementalDelivery.spec.ts | 10 +- packages/graphiql/src/components/GraphiQL.tsx | 17 +- packages/graphiql/test/schema.js | 39 +- 8 files changed, 183 insertions(+), 333 deletions(-) diff --git a/packages/graphiql-create-fetcher/src/createFetcher.ts b/packages/graphiql-create-fetcher/src/createFetcher.ts index e0897787584..730138c4b77 100644 --- a/packages/graphiql-create-fetcher/src/createFetcher.ts +++ b/packages/graphiql-create-fetcher/src/createFetcher.ts @@ -35,7 +35,7 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { if (!httpFetch) { throw Error('No valid fetcher implementation available'); } - + // simpler fetcher for schema requests const simpleFetcher = createSimpleFetcher(options, httpFetch); if (options.subscriptionUrl) { @@ -49,12 +49,15 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { ? createMultipartFetcher(options, httpFetch) : simpleFetcher; - return (graphQLParams, opts) => { + return (graphQLParams, fetcherOpts) => { if (graphQLParams.operationName === 'IntrospectionQuery') { - return simpleFetcher(graphQLParams, opts); + return (options.schemaFetcher || simpleFetcher)( + graphQLParams, + fetcherOpts, + ); } const isSubscription = isSubscriptionWithName( - opts?.documentAST!, + fetcherOpts?.documentAST!, graphQLParams.operationName, ); if (isSubscription) { @@ -69,6 +72,6 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { } return wsFetcher(graphQLParams); } - return httpFetcher(graphQLParams, opts); + return httpFetcher(graphQLParams, fetcherOpts); }; } diff --git a/packages/graphiql-create-fetcher/src/lib.ts b/packages/graphiql-create-fetcher/src/lib.ts index 4a8cc689510..e42ecfe84ad 100644 --- a/packages/graphiql-create-fetcher/src/lib.ts +++ b/packages/graphiql-create-fetcher/src/lib.ts @@ -1,6 +1,6 @@ import { DocumentNode, visit } from 'graphql'; import { meros } from 'meros'; -import { createClient, Client } from 'graphql-ws'; +import { createClient, Client, ClientOptions } from 'graphql-ws'; import { SubscriptionClient } from 'subscriptions-transport-ws'; import { isAsyncIterable, @@ -67,7 +67,10 @@ export const createSimpleFetcher = ( return data.json(); }; -export const createWebsocketsFetcherFromUrl = (url: string) => { +export const createWebsocketsFetcherFromUrl = ( + url: string, + connectionParams?: ClientOptions['connectionParams'], +) => { let wsClient: Client | null = null; let legacyClient: SubscriptionClient | null = null; if (url) { @@ -76,12 +79,13 @@ export const createWebsocketsFetcherFromUrl = (url: string) => { // TODO: defaults? wsClient = createClient({ url, + connectionParams, }); if (!wsClient) { - legacyClient = new SubscriptionClient(url); + legacyClient = new SubscriptionClient(url, { connectionParams }); } } catch (err) { - legacyClient = new SubscriptionClient(url); + legacyClient = new SubscriptionClient(url, { connectionParams }); } } catch (err) { console.error(`Error creating websocket client for:\n${url}\n\n${err}`); diff --git a/packages/graphiql-create-fetcher/src/types.ts b/packages/graphiql-create-fetcher/src/types.ts index c35514fa9fc..f7609763fa4 100644 --- a/packages/graphiql-create-fetcher/src/types.ts +++ b/packages/graphiql-create-fetcher/src/types.ts @@ -1,5 +1,6 @@ -import type { Client } from 'graphql-ws'; +import type { Client, ClientOptions } from 'graphql-ws'; import type { SubscriptionClient } from 'subscriptions-transport-ws'; +import type { Fetcher } from '@graphiql/toolkit'; export type WebsocketsClient = Client | SubscriptionClient; @@ -27,6 +28,10 @@ export interface CreateFetcherOptions { * A header you set statically here, it will be overriden by their value. */ headers?: Record; + /** + * Websockets connection params used when you provide subscriptionUrl. graphql-ws `ClientOptions.connectionParams` + */ + wsConnectionParams?: ClientOptions['connectionParams']; /** * You can disable the usage of the `fetch-multipart-graphql` library * entirely, defaulting to a simple fetch POST implementation. @@ -38,4 +43,9 @@ export interface CreateFetcherOptions { * default fetch behavior yet. */ fetch?: typeof fetch; + /** + * An optional custom fetcher specifically for your schema. For most cases + * the `url` and `headers` property should have you covered. + */ + schemaFetcher?: Fetcher; } diff --git a/packages/graphiql-toolkit/src/types.ts b/packages/graphiql-toolkit/src/types.ts index 72bf741e969..191218ca7ec 100644 --- a/packages/graphiql-toolkit/src/types.ts +++ b/packages/graphiql-toolkit/src/types.ts @@ -39,14 +39,16 @@ export type FetcherResultPayload = | { data: IntrospectionQuery; errors?: Array; - hasNext?: boolean; } - | { data?: any; errors?: Array; hasNext?: boolean } - // for IncrementalDelivery + // normal result payloads + | { data?: any; errors?: Array } + // for the initial Stream/Defer payload + | { data?: any; errors?: Array; hasNext: boolean } + // for successive Stream/Defer payloads | { data?: any; errors?: any[]; - path?: (string | number)[]; + path: (string | number)[]; hasNext: boolean; }; diff --git a/packages/graphiql/README.md b/packages/graphiql/README.md index 0737c8dcb48..aa1411a394e 100644 --- a/packages/graphiql/README.md +++ b/packages/graphiql/README.md @@ -1,6 +1,6 @@ # GraphiQL -> **Breaking Changes & Improvements:** several interfaces are being dropped for new ones for GraphiQL 1.0.0! Read more in [this issue](https://github.com/graphql/graphiql/issues/1165) +> **Breaking Changes & Improvements:** several interfaces are being dropped for new ones for GraphiQL 2.0.0! Read more in [this issue](https://github.com/graphql/graphiql/issues/1165) > **[`graphiql@1.0.0`](https://github.com/graphql/graphiql/milestone/3)** is coming soon & will provide a stable release with react 16, graphql 15 support, fixes, and a headers tab @@ -49,27 +49,63 @@ We have a few demos of `master` branch via the default netlify build (the same U ## Getting started +With `npm`: + +``` +npm install --save graphiql +``` + +Alternatively, if you are using [`yarn`](https://yarnpkg.com/): + +``` +yarn add graphiql +``` + +With `unpkg`/`jsdelivr`, etc: + +```html + + +``` + +(see: Usage UMD Bundle below for more required script tags) + +## Usage + Build for the web with [webpack](https://webpack.js.org/) or [browserify](http://browserify.org/), or use the pre-bundled `graphiql.js` file. See the [cdn example](../examples/graphiql-cdn/) in the git repository to see how to use the pre-bundled file, or see the [webpack example](../examples/graphiql-webpack) to see how to bundle an application using the `GraphiQL` component. -### GraphiQL for my GraphQL Service/HTTP Server/Etc +### Usage: NPM module -You may be using a runtime that already provides graphiql, or that provides it via a middleware. For example, we support [`express-graphql`](https://github.com/graphql/express-graphql)! +**Note**: If you are having webpack issues or questions about webpack, make sure you've cross-referenced your webpack configuration with our own [webpack example](../examples/graphiql-webpack) first. f you are having webpack issues or questions about webpack, make sure you've cross-referenced your webpack configuration with our own [webpack example](../examples/graphiql-webpack) first. We now have tests in CI that ensure this always builds, and we ensure it works end-to-end with every publish. -I would suggest a search for "graphiql " such as "graphiql express", "graphiql absinthe", etc to learn a potentially simpler route to setup for your environment. There are many npm packages, ruby gems, java utilities for deploying graphiql. +Using another GraphQL service? Here's how to get GraphiQL set up: -Here are some example searches: +GraphiQL provides a React component responsible for rendering the UI, which should be provided with a required `fetcher function for executing GraphQL operations against your schema. -- https://www.npmjs.com/search?q=graphiql - ~117 hits -- https://pypi.org/search/?q=graphiql - ~33 hits -- https://search.maven.org/search?q=graphiql - ~15 hits -- https://rubygems.org/search?utf8=%E2%9C%93&query=graphiql - ~6 hits -- https://godoc.org/?q=graphiql - ~12 hits -- https://packagist.org/?query=%22graphiql%22 - ~5 hits -- https://crates.io/search?q=graphiql - ~2 hits +For HTTP transport implementations, we recommend using the [fetch](https://fetch.spec.whatwg.org/) standard API, but you can use anything that matches [the type signature](https://graphiql-test.netlify.app/typedoc/modules/graphiql-toolkit.html#fetcher), including async iterables and observables. -This doesn't include runtimes or libraries where GraphiQL is used but isn't referenced in the package registry search entry. +You can also install `@graphiql/create-fetcher` to make it easier to create a simple fetcher for conventional http and websockets transports. + +```js +import React from 'react'; +import ReactDOM from 'react-dom'; + +import GraphiQL from 'graphiql'; +import { createGraphiQLFetcher } from '@graphiql/create-fetcher'; + +const fetcher = createGraphiQLFetcher({ + url: window.location.origin + '/graphql', +}); + +ReactDOM.render( + , + document.body, +); +``` -### CDN Bundle +Read more about using [`@graphiql/create-fetcher`](https://github.com/graphql/graphiql/packages/tree/main/packages/graphiql-create-fetcher) in the readme to learn how to add headers and more. + +### Usage: UMD Bundle over CDN (Unpkg, JSDelivr, etc) Don't forget to include the CSS file on the page! If you're using `npm` or `yarn`, you can find it in `node_modules/graphiql/graphiql.css`, or you can download it from the [releases page](https://github.com/graphql/graphiql/releases). @@ -100,16 +136,10 @@ The most minimal way to set up GraphiQL is a single index.html file: > @@ -120,46 +150,28 @@ The most minimal way to set up GraphiQL is a single index.html file: **Notes**: - the inlined styles are important for ensuring GraphiQL is visible and fills the canvas. -- using `React.createElement` directly is belaborous, so follow the webpack instructions below for more highly customized implementation - -### Webpack/Bundler - -**Note**: If you are having webpack issues or questions about webpack, make sure you've cross-referenced your webpack configuration with our own [webpack example](../examples/graphiql-webpack) first. f you are having webpack issues or questions about webpack, make sure you've cross-referenced your webpack configuration with our own [webpack example](../examples/graphiql-webpack) first. We now have tests in CI that ensure this always builds, and we ensure it works end-to-end with every publish. - -Using another GraphQL service? Here's how to get GraphiQL set up: - -With `npm`: - -``` -npm install --save graphiql -``` +- using `React.createElement` directly is belaborous, so follow the webpack instructions above for more highly customized implementation +- we can use `GraphiQL.createFetcher` in the UMD bundle only, so that it can be tree shaken out for modules -Alternatively, if you are using [`yarn`](https://yarnpkg.com/): +### GraphiQL for my GraphQL Service/HTTP Server/Etc -``` -yarn add graphiql -``` +You may be using a runtime that already provides graphiql, or that provides it via a middleware. For example, we support [`express-graphql`](https://github.com/graphql/express-graphql)! -GraphiQL provides a React component responsible for rendering the UI, which should be provided with a function for fetching from GraphQL, we recommend using the [fetch](https://fetch.spec.whatwg.org/) standard API. +I would suggest a search for "graphiql " such as "graphiql express", "graphiql absinthe", etc to learn a potentially simpler route to setup for your environment. There are many npm packages, ruby gems, java utilities for deploying graphiql. -```js -import React from 'react'; -import ReactDOM from 'react-dom'; -import GraphiQL from 'graphiql'; -import fetch from 'isomorphic-fetch'; +Here are some example searches: -function graphQLFetcher(graphQLParams) { - return fetch(window.location.origin + '/graphql', { - method: 'post', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(graphQLParams), - }).then(response => response.json()); -} +- https://www.npmjs.com/search?q=graphiql - ~117 hits +- https://pypi.org/search/?q=graphiql - ~33 hits +- https://search.maven.org/search?q=graphiql - ~15 hits +- https://rubygems.org/search?utf8=%E2%9C%93&query=graphiql - ~6 hits +- https://godoc.org/?q=graphiql - ~12 hits +- https://packagist.org/?query=%22graphiql%22 - ~5 hits +- https://crates.io/search?q=graphiql - ~2 hits -ReactDOM.render(, document.body); -``` +This doesn't include runtimes or libraries where GraphiQL is used but isn't referenced in the package registry search entry. -## Options +## Customize GraphiQL supports customization in UI and behavior by accepting React props and children. @@ -171,35 +183,35 @@ GraphiQL supports customization in UI and behavior by accepting React props and For more details on props, see the [API Docs](https://graphiql-test.netlify.app/typedoc/modules/graphiql.html#graphiqlprops) -| Prop | Type | Description | -| ---------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `fetcher` | [`Fetcher function`](https://graphiql-test.netlify.app/typedoc/modules/graphiql.html#fetcher) | **Required.** a function which accepts GraphQL-HTTP parameters and returns a Promise, Observable or AsyncIterable which resolves to the GraphQL parsed JSON response. | | -| `schema` | [`GraphQLSchema`](https://graphql.org/graphql-js/type/#graphqlschema) | a GraphQLSchema instance or `null` if one is not to be used. If `undefined` is provided, GraphiQL will send an introspection query using the fetcher to produce a schema. | -| `query` | `string` (GraphQL) | initial displayed query, if `undefined` is provided, the stored query or `defaultQuery` will be used. You can also set this value at runtime to override the current operation editor state. | -| `validationRules` | `ValidationRule[]` | A array of validation rules that will be used for validating the GraphQL operations. If `undefined` is provided, the default rules (exported as `specifiedRules` from `graphql`) will be used. | -| `variables` | `string` (JSON) | initial displayed query variables, if `undefined` is provided, the stored variables will be used. | -| `headers` | `string` | initial displayed request headers. if not defined, it will default to the stored headers if `shouldPersistHeaders` is enabled. | -| `externalFragments` | `string | FragmentDefinitionNode[]` | provide fragments external to the operation for completion, validation, and for selective use when executing operations. | -| `operationName` | `string` | an optional name of which GraphQL operation should be executed. | -| `response` | `string` (JSON) | an optional JSON string to use as the initial displayed response. If not provided, no response will be initially shown. You might provide this if illustrating the result of the initial query. | -| `storage` | [`Storage`](https://graphiql-test.netlify.app/typedoc/interfaces/graphiql.storage.html) | **Default:** `window.localStorage`. an interface that matches `window.localStorage` signature that GraphiQL will use to persist state. | -| `defaultQuery` | `string` | **Default:** graphiql help text. Provides default query if no user state is present. | default graphiql help text | -| `defaultVariableEditorOpen` | `boolean` | sets whether or not to show the variables pane on startup. overridden by user state (**deprecated** in favor of `defaultSecondaryEditorOpen`) | -| `defaultSecondaryEditorOpen` | `boolean` | sets whether or not to show the variables/headers pane on startup. If not defined, it will be based off whether or not variables and/or headers are present. | -| `getDefaultFieldNames` | `Function` | **Default:** `defaultGetDefaultFieldNames`. provides default field values for incomplete queries | `defaultGetDefaultFieldNames` | -| `editorTheme` | `string` | **Default:** `graphiql`. names a CodeMirror theme to be applied to the `QueryEditor`, `ResultViewer`, and `Variables` panes. See below for full usage. | -| `readOnly` | `boolean` | when `true` will make the `QueryEditor` and `Variables` panes readOnly. | -| `docExplorerOpen` | `boolean` | when `true` will ensure the `DocExplorer` is open by default when the user first renders the component. Overridden by user's toggle state | -| `headerEditorEnabled` | `boolean` | **Default:** `false`. enables the header editor when `true`. | -| `shouldPersistHeaders` | `boolean` | **Default:** `false`. o persist headers to storage when `true` | -| `toolbar.additionalContent` | `React.Component[]` | pass additional toolbar react components inside a fragment | `null` | -| `onEditQuery` | `Function` | called when the Query editor changes. The argument to the function will be the query string. | -| `onEditVariables` | `Function` | called when the Query variable editor changes. The argument to the function will be the variables string. | -| `onEditHeaders` | `Function` | called when the request headers editor changes. The argument to the function will be the headers string. | -| `onEditOperationName` | `Function` | called when the operation name to be executed changes. | -| `onToggleDocs` | `Function` | called when the docs will be toggled. The argument to the function will be a boolean whether the docs are now open or closed. | - -### Children (dropped as of 1.0.0-rc.2) +| Prop | Type | Description | +| ---------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fetcher` | [`Fetcher function`](https://graphiql-test.netlify.app/typedoc/modules/graphiql-toolkit.html#fetcher) | **Required.** a function which accepts GraphQL-HTTP parameters and returns a Promise, Observable or AsyncIterable which resolves to the GraphQL parsed JSON response. | | +| `schema` | [`GraphQLSchema`](https://graphql.org/graphql-js/type/#graphqlschema) | a GraphQLSchema instance or `null` if one is not to be used. If `undefined` is provided, GraphiQL will send an introspection query using the fetcher to produce a schema. | +| `query` | `string` (GraphQL) | initial displayed query, if `undefined` is provided, the stored query or `defaultQuery` will be used. You can also set this value at runtime to override the current operation editor state. | +| `validationRules` | `ValidationRule[]` | A array of validation rules that will be used for validating the GraphQL operations. If `undefined` is provided, the default rules (exported as `specifiedRules` from `graphql`) will be used. | +| `variables` | `string` (JSON) | initial displayed query variables, if `undefined` is provided, the stored variables will be used. | +| `headers` | `string` | initial displayed request headers. if not defined, it will default to the stored headers if `shouldPersistHeaders` is enabled. | +| `externalFragments` | `string | FragmentDefinitionNode[]` | provide fragments external to the operation for completion, validation, and for selective use when executing operations. | +| `operationName` | `string` | an optional name of which GraphQL operation should be executed. | +| `response` | `string` (JSON) | an optional JSON string to use as the initial displayed response. If not provided, no response will be initially shown. You might provide this if illustrating the result of the initial query. | +| `storage` | [`Storage`](https://graphiql-test.netlify.app/typedoc/interfaces/graphiql.storage.html) | **Default:** `window.localStorage`. an interface that matches `window.localStorage` signature that GraphiQL will use to persist state. | +| `defaultQuery` | `string` | **Default:** graphiql help text. Provides default query if no user state is present. | default graphiql help text | +| `defaultVariableEditorOpen` | `boolean` | sets whether or not to show the variables pane on startup. overridden by user state (**deprecated** in favor of `defaultSecondaryEditorOpen`) | +| `defaultSecondaryEditorOpen` | `boolean` | sets whether or not to show the variables/headers pane on startup. If not defined, it will be based off whether or not variables and/or headers are present. | +| `getDefaultFieldNames` | `Function` | **Default:** `defaultGetDefaultFieldNames`. provides default field values for incomplete queries | `defaultGetDefaultFieldNames` | +| `editorTheme` | `string` | **Default:** `graphiql`. names a CodeMirror theme to be applied to the `QueryEditor`, `ResultViewer`, and `Variables` panes. See below for full usage. | +| `readOnly` | `boolean` | when `true` will make the `QueryEditor` and `Variables` panes readOnly. | +| `docExplorerOpen` | `boolean` | when `true` will ensure the `DocExplorer` is open by default when the user first renders the component. Overridden by user's toggle state | +| `headerEditorEnabled` | `boolean` | **Default:** `false`. enables the header editor when `true`. | +| `shouldPersistHeaders` | `boolean` | **Default:** `false`. o persist headers to storage when `true` | +| `toolbar.additionalContent` | `React.Component[]` | pass additional toolbar react components inside a fragment | `null` | +| `onEditQuery` | `Function` | called when the Query editor changes. The argument to the function will be the query string. | +| `onEditVariables` | `Function` | called when the Query variable editor changes. The argument to the function will be the variables string. | +| `onEditHeaders` | `Function` | called when the request headers editor changes. The argument to the function will be the headers string. | +| `onEditOperationName` | `Function` | called when the operation name to be executed changes. | +| `onToggleDocs` | `Function` | called when the docs will be toggled. The argument to the function will be a boolean whether the docs are now open or closed. | + +### Children (this pattern will be dropped in 2.0.0) - ``: Replace the GraphiQL logo with your own. @@ -225,92 +237,7 @@ For more details on props, see the [API Docs](https://graphiql-test.netlify.app/ ## Full Usage Example -> **Breaking Changes & Improvements:** using `window.GraphiQL.state` will no longer be possible in `1.0.0-rc.2` Read more in [this issue](#1165) - -Here's a more complex react implementation. This would require webpack or a bundler. - -```js -class CustomGraphiQL extends React.Component { - constructor(props) { - super(props); - this.state = { - // REQUIRED: - // `fetcher` must be provided in order for GraphiQL to operate - fetcher: this.props.fetcher, - - // OPTIONAL PARAMETERS - // GraphQL artifacts - query: '', - variables: '', - headers: '', - response: '', - - // GraphQL Schema - // If `undefined` is provided, an introspection query is executed - // using the fetcher. - schema: undefined, - - // Useful to determine which operation to run - // when there are multiple of them. - operationName: null, - storage: null, - defaultQuery: null, - - // Custom Event Handlers - onEditQuery: null, - onEditVariables: null, - onEditHeaders: null, - onEditOperationName: null, - - // GraphiQL automatically fills in leaf nodes when the query - // does not provide them. Change this if your GraphQL Definitions - // should behave differently than what's defined here: - // (https://github.com/graphql/graphiql/blob/master/src/utility/fillLeafs.js#L75) - getDefaultFieldNames: null - }; - } - - // Example of using the GraphiQL Component API via a toolbar button. - handleClickPrettifyButton(event) { - const editor = this.graphiql.getQueryEditor(); - const currentText = editor.getValue(); - const { parse, print } = require('graphql'); - const prettyText = print(parse(currentText)); - editor.setValue(prettyText); - } - - render() { - return ( - { this.graphiql = c; }} {...this.state}> - - Custom Logo - - - - // GraphiQL.Button usage - - - // Some other possible toolbar items - - - - - - - - - // Footer works the same as Toolbar - // add items by appending child components - - - ); - } -} -``` +TODO: kitchen sink example project or codesandbox ### Applying an Editor Theme @@ -326,136 +253,4 @@ In order to theme the editor portions of the interface, you can supply a `editor /> ``` -### Query Samples - -**Query** - -GraphQL queries declaratively describe what data the issuer wishes to fetch from whoever is fulfilling the GraphQL query. - -```graphql -query FetchSomeIDQuery($someId: String!) { - human(id: $someId) { - name - } -} -``` - -More examples available from: [GraphQL Queries](http://graphql.org/docs/queries/). - -**Mutation** - -Given this schema, - -```js -const schema = new GraphQLSchema({ - query: new GraphQLObjectType({ - fields: { - numberHolder: { type: numberHolderType }, - }, - name: 'Query', - }), - mutation: new GraphQLObjectType({ - fields: { - immediatelyChangeTheNumber: { - type: numberHolderType, - args: { newNumber: { type: GraphQLInt } }, - resolve: function (obj, { newNumber }) { - return obj.immediatelyChangeTheNumber(newNumber); - }, - }, - }, - name: 'Mutation', - }), -}); -``` - -then the following mutation queries are possible: - -```graphql -mutation TestMutation { - first: immediatelyChangeTheNumber(newNumber: 1) { - theNumber - } -} -``` - -Read more in [this mutation test in `graphql-js`](https://github.com/graphql/graphql-js/blob/master/src/execution/__tests__/mutations-test.js). - -[Relay](https://relay.dev/) has another good example using a common pattern for composing mutations. Given the following GraphQL Type Definitions, - -```graphql -input IntroduceShipInput { - factionId: ID! - shipName: String! - clientMutationId: String! -} - -type IntroduceShipPayload { - faction: Faction - ship: Ship - clientMutationId: String! -} -``` - -mutation calls are composed as such: - -```graphql -mutation AddBWingQuery($input: IntroduceShipInput!) { - introduceShip(input: $input) { - ship { - id - name - } - faction { - name - } - clientMutationId - } -} -{ - "input": { - "shipName": "B-Wing", - "factionId": "1", - "clientMutationId": "abcde" - } -} -``` - -Read more from [Relay Mutation Documentation](https://relay.dev/docs/en/graphql-server-specification.html#mutations). - -**Fragment** - -Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document. Inline Fragments can be used directly within a selection to condition upon a type condition when querying against an interface or union. Therefore, instead of the following query: - -```graphql -{ - luke: human(id: "1000") { - name - homePlanet - } - leia: human(id: "1003") { - name - homePlanet - } -} -``` - -using fragments, the following query is possible. - -```graphql -{ - luke: human(id: "1000") { - ...HumanFragment - } - leia: human(id: "1003") { - ...HumanFragment - } -} - -fragment HumanFragment on Human { - name - homePlanet -} -``` - -Read more from [GraphQL Fragment Specification](https://graphql.github.io/graphql-spec/draft/#sec-Language.Fragments). +### Running Operations diff --git a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts index c2ae01a07b4..a2a1947c656 100644 --- a/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts +++ b/packages/graphiql/cypress/integration/incrementalDelivery.spec.ts @@ -44,8 +44,16 @@ const mockStreamSuccess = { hasNext: false, }; +const testDeferQuery = /* GraphQL */ ` + query DeferQuery($delay: Int) { + streamable(delay: $delay) @stream(initialCount: 2) { + text + } + } +`; + describe('IncrementalDelivery support via fetcher', () => { - it('Expects slower streams to resolve in several increments', () => { + it('Expects slower streams to resolve in several increments, and the payloads to patch properly', () => { const delay = 100; const timeout = mockStreamSuccess.data.streamable.length * (delay * 1.5); diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx index 00ae5d7f023..0912f8b810f 100644 --- a/packages/graphiql/src/components/GraphiQL.tsx +++ b/packages/graphiql/src/components/GraphiQL.tsx @@ -1068,7 +1068,8 @@ export class GraphiQL extends React.Component { ); } - const totalResponse: FetcherResultPayload = { data: {} }; + // when dealing with defer or stream, we need to aggregate results + const fullResponse: FetcherResultPayload = { data: {}, hasNext: false }; // _fetchQuery may return a subscription. const subscription = await this._fetchQuery( @@ -1080,19 +1081,19 @@ export class GraphiQL extends React.Component { (result: FetcherResult) => { if (queryID === this._editorQueryID) { if ( - typeof result === 'object' && + typeof result !== 'string' && result !== null && 'hasNext' in result ) { if (result.errors) { // We dont care about "index" here, just concat. - totalResponse.errors = [ - ...(totalResponse?.errors || []), + fullResponse.errors = [ + ...(fullResponse?.errors || []), ...result?.errors, ]; } - totalResponse.hasNext = result.hasNext; + fullResponse.hasNext = result.hasNext; if ('path' in result) { if (!('data' in result)) { @@ -1100,16 +1101,16 @@ export class GraphiQL extends React.Component { `Expected part to contain a data property, but got ${result}`, ); } - dset(totalResponse.data, result.path!.map(String), result.data); + dset(fullResponse.data, result.path, result.data); } else if ('data' in result) { // If there is no path, we don't know what to do with the payload, // so we just set it. - totalResponse.data = result.data; + fullResponse.data = result.data; } this.setState({ isWaitingForResponse: false, - response: GraphiQL.formatResult(totalResponse), + response: GraphiQL.formatResult(fullResponse), }); } else { this.setState({ diff --git a/packages/graphiql/test/schema.js b/packages/graphiql/test/schema.js index 182da92e072..3e881fe847a 100644 --- a/packages/graphiql/test/schema.js +++ b/packages/graphiql/test/schema.js @@ -137,6 +137,34 @@ const Greeting = new GraphQLObjectType({ }, }); +const delayArgument = (defaultValue = 400) => ({ + description: + 'delay in milleseconds for subsequent results, for demonstration purposes', + type: GraphQLInt, + defaultValue, +}); + +const DeferrableObject = new GraphQLObjectType({ + name: 'Deferrable', + fields: { + normalString: { + type: GraphQLString, + resolve: () => `Nice`, + }, + deferredString: { + args: { + delay: delayArgument(600), + }, + type: GraphQLString, + resolve: async function lazilyReturnValue(_value, args) { + const seconds = args.delay / 1000; + await sleep(args.delay); + return `Oops, this took ${seconds} seconds longer than I thought it would!`; + }, + }, + }, +}); + const sleep = async timeout => new Promise(res => setTimeout(res, timeout)); const TestType = new GraphQLObjectType({ @@ -147,15 +175,14 @@ const TestType = new GraphQLObjectType({ description: '`test` field from `Test` type.', resolve: () => ({}), }, + deferrable: { + type: DeferrableObject, + resolve: () => ({}), + }, streamable: { type: new GraphQLList(Greeting), args: { - delay: { - description: - 'delay in milleseconds for subsequent results, for demonstration purposes', - type: GraphQLInt, - defaultValue: 400, - }, + delay: delayArgument(300), }, resolve: async function* sayHiInSomeLanguages(_value, args) { let i = 0;