From f509fc0f9077a82d8f73853e035b49982802b7b3 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 11:42:01 -0700 Subject: [PATCH 01/13] Add graphql-react --- types/graphql-react/graphql-react-tests.ts | 0 types/graphql-react/index.d.ts | 134 +++++++++++++++++++++ types/graphql-react/tsconfig.json | 22 ++++ types/graphql-react/tslint.json | 1 + 4 files changed, 157 insertions(+) create mode 100644 types/graphql-react/graphql-react-tests.ts create mode 100644 types/graphql-react/index.d.ts create mode 100644 types/graphql-react/tsconfig.json create mode 100644 types/graphql-react/tslint.json diff --git a/types/graphql-react/graphql-react-tests.ts b/types/graphql-react/graphql-react-tests.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts new file mode 100644 index 0000000000..13ee68b33b --- /dev/null +++ b/types/graphql-react/index.d.ts @@ -0,0 +1,134 @@ +// Type definitions for graphql-react 8.1 +// Project: https://github.com/jaydenseric/graphql-react#readme +// Definitions by: Mike Marcacci +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +import { ReactNode, Context } from "react"; + +export const GraphQLContext: Context; + +export interface HttpError { + status: number; + statusText: string; +} + +export type GraphQLCacheKey = string; +export interface GraphQLCacheValue { + fetchError: null | string; + httpError: null | HttpError; + parseError: null | string; + graphQLErrors: + | null + | { + message: string; + path: string[]; + locations: { column: number; line: number }[]; + }[]; + data: T; +} + +export interface GraphQLCache { + [key: string]: GraphQLCacheValue; +} + +export interface GraphQLFetchOptions { + url: string; + body: string | FormData; + headers: Headers; + credentials: null | string; +} + +export type GraphQLFetchOptionsOverride = ( + options: GraphQLFetchOptions +) => void; + +export type GraphQLOperation = { + query: string; +} & (V extends void ? {} : { variables: V }); + +export interface GraphQLOperationLoading { + cacheKey: GraphQLCacheKey; + cacheValue: undefined | GraphQLCacheValue; + cacheValuePromise: Promise>; +} + +export interface GraphQLOperationStatus { + load: () => void; + loading: boolean; + cacheKey: GraphQLCacheKey; + cacheValue?: GraphQLCacheValue; +} + +export class GraphQL { + public constructor(options?: { cache?: GraphQLCache }); + + public on( + type: "reset", + handler: (event: { exceptCacheKey: GraphQLCacheKey }) => void + ): void; + + public on( + type: "cache", + handler: (event: { + cacheKey: GraphQLCacheKey; + cacheValue: GraphQLCacheValue; + }) => void + ): void; + + public on( + type: "fetch", + handler: (event: { + cacheKey: GraphQLCacheKey; + cacheValuePromise: Promise>; + }) => void + ): void; + + public off( + type: "reset", + handler: (event: { exceptCacheKey: GraphQLCacheKey }) => void + ): void; + + public off( + type: "cache", + handler: (event: { + cacheKey: GraphQLCacheKey; + cacheValue: GraphQLCacheValue; + }) => void + ): void; + + public off( + type: "fetch", + handler: (event: { + cacheKey: GraphQLCacheKey; + cacheValuePromise: Promise>; + }) => void + ): void; + + public reset(exceptCacheKey?: string): void; + public operate(options: { + operation: GraphQLOperation; + fetchOptionsOverride?: GraphQLFetchOptionsOverride; + reloadOnLoad?: boolean; + resetOnLoad?: boolean; + }): GraphQLOperationLoading; + + public cache: GraphQLCache; +} + +export function reportCacheErrors(event: any): void; + +export function ssr( + grapphql: GraphQL, + node: ReactNode, + render?: (element: ReactNode) => string +): void; + +export function useGraphQL(options: { + fetchOptionsOverride?: GraphQLFetchOptionsOverride; + loadOnMount?: boolean; + loadOnReload?: boolean; + loadOnReset?: boolean; + reloadOnLoad?: boolean; + resetOnLoad?: boolean; + operation: GraphQLOperation; +}): GraphQLOperationStatus; diff --git a/types/graphql-react/tsconfig.json b/types/graphql-react/tsconfig.json new file mode 100644 index 0000000000..674f11617e --- /dev/null +++ b/types/graphql-react/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "graphql-react-tests.ts" + ] +} diff --git a/types/graphql-react/tslint.json b/types/graphql-react/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/graphql-react/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } From 41ff754fef1145d225b955aee47c31067c36f6bd Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 11:46:55 -0700 Subject: [PATCH 02/13] Add config to appease linter --- types/graphql-react/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/types/graphql-react/tsconfig.json b/types/graphql-react/tsconfig.json index 674f11617e..e7edb0b605 100644 --- a/types/graphql-react/tsconfig.json +++ b/types/graphql-react/tsconfig.json @@ -7,6 +7,7 @@ "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, + "strictFunctionTypes": true, "baseUrl": "../", "typeRoots": [ "../" From d802c72f4367036730395fdbed10fcd2108c9355 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 11:55:37 -0700 Subject: [PATCH 03/13] Add minimum TypeScript version --- types/graphql-react/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index 13ee68b33b..1b27bc9014 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -2,6 +2,7 @@ // Project: https://github.com/jaydenseric/graphql-react#readme // Definitions by: Mike Marcacci // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.6 import { ReactNode, Context } from "react"; From e737956aba3cc33a4d4d52f43d83a4b29f545b8a Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 12:03:46 -0700 Subject: [PATCH 04/13] Bump TS version to match react --- types/graphql-react/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index 1b27bc9014..1e80e31d23 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/jaydenseric/graphql-react#readme // Definitions by: Mike Marcacci // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.6 +// TypeScript Version: 2.8 import { ReactNode, Context } from "react"; From ae114479a87f7edaeba3e03cdd65e93d0358d963 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 12:05:03 -0700 Subject: [PATCH 05/13] Well, this seems to keep failing, so I'll bump to the latest --- types/graphql-react/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index 1e80e31d23..cc0babeee5 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/jaydenseric/graphql-react#readme // Definitions by: Mike Marcacci // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.8 +// TypeScript Version: 3.4 import { ReactNode, Context } from "react"; From 511a0d169e50e1f36379da8748a71a909d493023 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 12:11:41 -0700 Subject: [PATCH 06/13] I guess 3.4 isnt supported in DT? --- types/graphql-react/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index cc0babeee5..7e1a7ce214 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/jaydenseric/graphql-react#readme // Definitions by: Mike Marcacci // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 3.4 +// TypeScript Version: 3.3 import { ReactNode, Context } from "react"; From 6c7213110ab21787b8da3ba2fa2f96f9720158a9 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 12:21:04 -0700 Subject: [PATCH 07/13] The linter only works in CI... --- types/graphql-react/graphql-react-tests.ts | 0 types/graphql-react/index.d.ts | 28 +++++++++++----------- types/graphql-react/tsconfig.json | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) delete mode 100644 types/graphql-react/graphql-react-tests.ts diff --git a/types/graphql-react/graphql-react-tests.ts b/types/graphql-react/graphql-react-tests.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index 7e1a7ce214..dbd29a495c 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -20,11 +20,11 @@ export interface GraphQLCacheValue { parseError: null | string; graphQLErrors: | null - | { + | Array<{ message: string; path: string[]; - locations: { column: number; line: number }[]; - }[]; + locations: Array<{ column: number; line: number }>; + }>; data: T; } @@ -45,7 +45,7 @@ export type GraphQLFetchOptionsOverride = ( export type GraphQLOperation = { query: string; -} & (V extends void ? {} : { variables: V }); +} & (V extends undefined ? {} : { variables: V }); export interface GraphQLOperationLoading { cacheKey: GraphQLCacheKey; @@ -61,14 +61,14 @@ export interface GraphQLOperationStatus { } export class GraphQL { - public constructor(options?: { cache?: GraphQLCache }); + constructor(options?: { cache?: GraphQLCache }); - public on( + on( type: "reset", handler: (event: { exceptCacheKey: GraphQLCacheKey }) => void ): void; - public on( + on( type: "cache", handler: (event: { cacheKey: GraphQLCacheKey; @@ -76,7 +76,7 @@ export class GraphQL { }) => void ): void; - public on( + on( type: "fetch", handler: (event: { cacheKey: GraphQLCacheKey; @@ -84,12 +84,12 @@ export class GraphQL { }) => void ): void; - public off( + off( type: "reset", handler: (event: { exceptCacheKey: GraphQLCacheKey }) => void ): void; - public off( + off( type: "cache", handler: (event: { cacheKey: GraphQLCacheKey; @@ -97,7 +97,7 @@ export class GraphQL { }) => void ): void; - public off( + off( type: "fetch", handler: (event: { cacheKey: GraphQLCacheKey; @@ -105,15 +105,15 @@ export class GraphQL { }) => void ): void; - public reset(exceptCacheKey?: string): void; - public operate(options: { + reset(exceptCacheKey?: string): void; + operate(options: { operation: GraphQLOperation; fetchOptionsOverride?: GraphQLFetchOptionsOverride; reloadOnLoad?: boolean; resetOnLoad?: boolean; }): GraphQLOperationLoading; - public cache: GraphQLCache; + cache: GraphQLCache; } export function reportCacheErrors(event: any): void; diff --git a/types/graphql-react/tsconfig.json b/types/graphql-react/tsconfig.json index e7edb0b605..50cc7d19bc 100644 --- a/types/graphql-react/tsconfig.json +++ b/types/graphql-react/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "module": "commonjs", "lib": [ - "es6" + "es6", + "dom" ], "noImplicitAny": true, "noImplicitThis": true, From 2a005627d98078bb101eec54fb55fd5ff0e4371f Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 12:54:08 -0700 Subject: [PATCH 08/13] Add tests --- types/graphql-react/graphql-react-tests.tsx | 47 +++++++++++++++++++++ types/graphql-react/tsconfig.json | 3 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 types/graphql-react/graphql-react-tests.tsx diff --git a/types/graphql-react/graphql-react-tests.tsx b/types/graphql-react/graphql-react-tests.tsx new file mode 100644 index 0000000000..2ebd250332 --- /dev/null +++ b/types/graphql-react/graphql-react-tests.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; + +const graphql = new GraphQL(); + +function App() { + const { loading, cacheValue } = useGraphQL< + {node: null | {id: string}}, + {id: string} + >({ + fetchOptionsOverride(options) { + options.url = "/graphql"; + }, + variables: { + id: "123456" + }, + operation: { + query: ` + query($id: !String) { + node(id: $id) { + id + } + } + ` + } + }); + + if (loading) { + return
Loading...
; + } + + return ( +
{ + cacheValue && cacheValue.data && cacheValue.data.node + ? "exists" + : "does not exist" + }
+ ); +} + +function Root() { + return ( + + + + ); +} diff --git a/types/graphql-react/tsconfig.json b/types/graphql-react/tsconfig.json index 50cc7d19bc..d4b3672f9c 100644 --- a/types/graphql-react/tsconfig.json +++ b/types/graphql-react/tsconfig.json @@ -15,7 +15,8 @@ ], "types": [], "noEmit": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "jsx": "react" }, "files": [ "index.d.ts", From 3b5708639b3ead10e1c65eb3b15b5d577f049dbb Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 13:08:33 -0700 Subject: [PATCH 09/13] Looks like the extension is important --- types/graphql-react/graphql-react-tests.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 types/graphql-react/graphql-react-tests.ts diff --git a/types/graphql-react/graphql-react-tests.ts b/types/graphql-react/graphql-react-tests.ts new file mode 100644 index 0000000000..ebe4706d8f --- /dev/null +++ b/types/graphql-react/graphql-react-tests.ts @@ -0,0 +1 @@ +import * as tests from "./graphql-react-tests.tsx"; From f1734f5d9df78c3b09604a4b9d79f61585a9ebdf Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 13:23:34 -0700 Subject: [PATCH 10/13] So frustrating... --- types/graphql-react/graphql-react-tests.ts | 80 +++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/types/graphql-react/graphql-react-tests.ts b/types/graphql-react/graphql-react-tests.ts index ebe4706d8f..d1a35ffa94 100644 --- a/types/graphql-react/graphql-react-tests.ts +++ b/types/graphql-react/graphql-react-tests.ts @@ -1 +1,79 @@ -import * as tests from "./graphql-react-tests.tsx"; +import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; + +const { loading, cacheValue } = useGraphQL< + {node: null | {id: string}}, + {id: string} +>({ + fetchOptionsOverride(options) { + options.url = "/graphql"; + }, + operation: { + variables: { + id: "123456" + }, + query: ` + query($id: !String) { + node(id: $id) { + id + } + } + ` + } +}); + +/* This SHOULD be the test, but the DefinitelyTyped tooling is so difficult to + work with that I've spent all my time, and can't figure out how to use JSX + here, since it won't recognize the test if it ends with .tsx, it complains + about an extra file if I simply have the test import an additional .tsx file, + and I have to change, push, and wait for CI because neither the lint nor test + scripts run locally, because I depend on `react` which has some error that + breaks before it runs my code. What a frustrating several hours. + +import React from "react"; +import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; + +const graphql = new GraphQL(); + +function App() { + const { loading, cacheValue } = useGraphQL< + {node: null | {id: string}}, + {id: string} + >({ + fetchOptionsOverride(options) { + options.url = "/graphql"; + }, + operation: { + variables: { + id: "123456" + }, + query: ` + query($id: !String) { + node(id: $id) { + id + } + } + ` + } + }); + + if (loading) { + return
Loading...
; + } + + return ( +
{ + cacheValue && cacheValue.data && cacheValue.data.node + ? "exists" + : "does not exist" + }
+ ); +} + +function Root() { + return ( + + + + ); +} +*/ From 8333b417231090fd14c9c8218e568dd88572c8c7 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 13:29:54 -0700 Subject: [PATCH 11/13] remove file --- types/graphql-react/graphql-react-tests.tsx | 47 --------------------- 1 file changed, 47 deletions(-) delete mode 100644 types/graphql-react/graphql-react-tests.tsx diff --git a/types/graphql-react/graphql-react-tests.tsx b/types/graphql-react/graphql-react-tests.tsx deleted file mode 100644 index 2ebd250332..0000000000 --- a/types/graphql-react/graphql-react-tests.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from "react"; -import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; - -const graphql = new GraphQL(); - -function App() { - const { loading, cacheValue } = useGraphQL< - {node: null | {id: string}}, - {id: string} - >({ - fetchOptionsOverride(options) { - options.url = "/graphql"; - }, - variables: { - id: "123456" - }, - operation: { - query: ` - query($id: !String) { - node(id: $id) { - id - } - } - ` - } - }); - - if (loading) { - return
Loading...
; - } - - return ( -
{ - cacheValue && cacheValue.data && cacheValue.data.node - ? "exists" - : "does not exist" - }
- ); -} - -function Root() { - return ( - - - - ); -} From c70042f4523d34a2173f518581c605ae52349072 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Wed, 27 Mar 2019 13:43:24 -0700 Subject: [PATCH 12/13] Disable no-unnecessary-generics --- types/graphql-react/index.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/types/graphql-react/index.d.ts b/types/graphql-react/index.d.ts index dbd29a495c..9ee919bd16 100644 --- a/types/graphql-react/index.d.ts +++ b/types/graphql-react/index.d.ts @@ -4,6 +4,10 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 3.3 +// The no-unnecessary-generics rule is stupid and overrestrictive. It is a +// perfectly valid and often useful to type-constrain a wrapping object. +/* tslint:disable:no-unnecessary-generics */ + import { ReactNode, Context } from "react"; export const GraphQLContext: Context; From de753676c59dc5415e86801efb668389d208306a Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Tue, 2 Apr 2019 23:33:12 -0700 Subject: [PATCH 13/13] Attempt to use tsx again --- types/graphql-react/graphql-react-tests.ts | 79 --------------------- types/graphql-react/graphql-react-tests.tsx | 47 ++++++++++++ types/graphql-react/tsconfig.json | 5 +- 3 files changed, 50 insertions(+), 81 deletions(-) delete mode 100644 types/graphql-react/graphql-react-tests.ts create mode 100644 types/graphql-react/graphql-react-tests.tsx diff --git a/types/graphql-react/graphql-react-tests.ts b/types/graphql-react/graphql-react-tests.ts deleted file mode 100644 index d1a35ffa94..0000000000 --- a/types/graphql-react/graphql-react-tests.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; - -const { loading, cacheValue } = useGraphQL< - {node: null | {id: string}}, - {id: string} ->({ - fetchOptionsOverride(options) { - options.url = "/graphql"; - }, - operation: { - variables: { - id: "123456" - }, - query: ` - query($id: !String) { - node(id: $id) { - id - } - } - ` - } -}); - -/* This SHOULD be the test, but the DefinitelyTyped tooling is so difficult to - work with that I've spent all my time, and can't figure out how to use JSX - here, since it won't recognize the test if it ends with .tsx, it complains - about an extra file if I simply have the test import an additional .tsx file, - and I have to change, push, and wait for CI because neither the lint nor test - scripts run locally, because I depend on `react` which has some error that - breaks before it runs my code. What a frustrating several hours. - -import React from "react"; -import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; - -const graphql = new GraphQL(); - -function App() { - const { loading, cacheValue } = useGraphQL< - {node: null | {id: string}}, - {id: string} - >({ - fetchOptionsOverride(options) { - options.url = "/graphql"; - }, - operation: { - variables: { - id: "123456" - }, - query: ` - query($id: !String) { - node(id: $id) { - id - } - } - ` - } - }); - - if (loading) { - return
Loading...
; - } - - return ( -
{ - cacheValue && cacheValue.data && cacheValue.data.node - ? "exists" - : "does not exist" - }
- ); -} - -function Root() { - return ( - - - - ); -} -*/ diff --git a/types/graphql-react/graphql-react-tests.tsx b/types/graphql-react/graphql-react-tests.tsx new file mode 100644 index 0000000000..a1c80d7995 --- /dev/null +++ b/types/graphql-react/graphql-react-tests.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { GraphQL, GraphQLContext, useGraphQL } from "graphql-react"; + +const graphql = new GraphQL(); + +function App() { + const { loading, cacheValue } = useGraphQL< + {node: null | {id: string}}, + {id: string} + >({ + fetchOptionsOverride(options) { + options.url = "/graphql"; + }, + operation: { + variables: { + id: "123456" + }, + query: ` + query($id: !String) { + node(id: $id) { + id + } + } + ` + } + }); + + if (loading) { + return
Loading...
; + } + + return ( +
{ + cacheValue && cacheValue.data && cacheValue.data.node + ? "exists" + : "does not exist" + }
+ ); +} + +function Root() { + return ( + + + + ); +} diff --git a/types/graphql-react/tsconfig.json b/types/graphql-react/tsconfig.json index d4b3672f9c..16a784d5cc 100644 --- a/types/graphql-react/tsconfig.json +++ b/types/graphql-react/tsconfig.json @@ -16,10 +16,11 @@ "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true, - "jsx": "react" + "jsx": "react", + "esModuleInterop": true }, "files": [ "index.d.ts", - "graphql-react-tests.ts" + "graphql-react-tests.tsx" ] }