Skip to content
This repository was archived by the owner on Jul 20, 2023. It is now read-only.

Commit 2af2d46

Browse files
authored
Add support for latest graphql-js (#108)
- graphql-js 16.x updates two collection of constants to ts enums which affect this library. - Changes needed to update the use the exported Kind & OperationTypeNode enums are backward incompatible so remove support for lower versions of graphql-js
1 parent e31ecb6 commit 2af2d46

File tree

7 files changed

+1161
-483
lines changed

7 files changed

+1161
-483
lines changed

codegen/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"dependencies": {
2727
"ast-types": "^0.14.2",
2828
"fs-extra": "^9.0.1",
29-
"graphql": "^15.3.0",
29+
"graphql": "^16.3.0",
3030
"jssha": "^3.2.0",
3131
"node-fetch": "^2.6.1",
3232
"outvariant": "^1.2.1",

codegen/src/render.ts

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { parse, buildSchema, visit, GraphQLEnumType } from "graphql";
1+
import { parse, buildSchema, visit, GraphQLEnumType, Kind, OperationTypeNode } from "graphql";
22
import type { Code } from "ts-poet";
33
import prettier from "prettier";
44

55
import { typeTransform, selectorInterfaceTransform } from "./transforms";
66
import { printType } from "./utils";
77

8+
interface ASTNode {
9+
kind: string
10+
}
11+
812
export const render = (sdl: string): string => {
913
const ast = parse(sdl, { noLocation: true });
1014
const schema = buildSchema(sdl);
@@ -15,9 +19,9 @@ export const render = (sdl: string): string => {
1519
];
1620

1721
// additive transforms
18-
const results: ReadonlyArray<{ definitions: Code[] }> = transforms.map(
22+
const results = transforms.map(
1923
(vistor) => visit(ast, vistor)
20-
);
24+
) as unknown as Array<{ readonly definitions: Code[] }> ;
2125

2226
const types = Object.values(schema.getTypeMap()).filter(
2327
(type) => !type.name.startsWith("__")
@@ -47,31 +51,32 @@ export const render = (sdl: string): string => {
4751

4852
const source =
4953
`
50-
import { buildASTSchema } from 'graphql'
54+
import { buildASTSchema, Kind, OperationTypeNode } from 'graphql'
5155
52-
import {
56+
import {
5357
TypeConditionError,
5458
NamedType,
5559
Field,
5660
InlineFragment,
57-
Argument,
58-
Variable,
59-
Selection,
60-
SelectionSet,
61-
SelectionBuilder,
61+
Argument,
62+
Variable,
63+
Selection,
64+
SelectionSet,
65+
SelectionBuilder,
6266
namedType,
6367
field,
6468
inlineFragment,
65-
argument,
69+
argument,
6670
selectionSet
6771
} from '@timkendall/tql'
68-
69-
export { Result, Variables, $ } from '@timkendall/tql'
70-
72+
73+
export type { Result, Variables } from '@timkendall/tql'
74+
export { $ } from '@timkendall/tql'
75+
7176
` +
7277
`
73-
export const SCHEMA = buildASTSchema(${JSON.stringify(ast)})
74-
78+
export const SCHEMA = buildASTSchema(${stringifyAST(ast)})
79+
7580
export const ENUMS = ${ENUMS}
7681
7782
${typeMap}
@@ -84,3 +89,44 @@ export const render = (sdl: string): string => {
8489

8590
return prettier.format(source, { parser: "typescript" });
8691
};
92+
93+
const stringifyAST = (ast: ASTNode) => {
94+
const acc: string[] = [];
95+
accumulateASTNode(ast, acc)
96+
return acc.join("\n")
97+
}
98+
99+
const reverseRecord = <TRecord extends Record<string, string>>(input: TRecord) => Object.fromEntries(Object.entries(input).map(([k, v]) => [v, k]))
100+
101+
const kindRevMapping = reverseRecord(Kind)
102+
const operationTypeRevMapping = reverseRecord(OperationTypeNode)
103+
104+
const accumulateASTNode = (
105+
astNode: ASTNode,
106+
acc: string[]
107+
) => {
108+
acc.push('{')
109+
for (const [k,v] of Object.entries(astNode)) {
110+
if (v === undefined) continue
111+
acc.push(`${JSON.stringify(k)}: `)
112+
if (Array.isArray(v)) {
113+
acc.push(`[`)
114+
for (const childNode of v) {
115+
accumulateASTNode(childNode, acc)
116+
acc.push(',')
117+
}
118+
acc.push(']')
119+
} else if (typeof v === "object" && typeof v.kind === "string") {
120+
accumulateASTNode(v, acc)
121+
} else if (k === "kind" && kindRevMapping[v]) {
122+
acc.push(`Kind.${kindRevMapping[v]}`)
123+
} else if (k === "operation" && operationTypeRevMapping[v]) {
124+
acc.push(`OperationTypeNode.${operationTypeRevMapping[v]}`)
125+
} else {
126+
acc.push(JSON.stringify(v))
127+
}
128+
acc.push(',')
129+
}
130+
acc.push('}')
131+
}
132+

0 commit comments

Comments
 (0)