1
- import { parse , buildSchema , visit , GraphQLEnumType } from "graphql" ;
1
+ import { parse , buildSchema , visit , GraphQLEnumType , Kind , OperationTypeNode } from "graphql" ;
2
2
import type { Code } from "ts-poet" ;
3
3
import prettier from "prettier" ;
4
4
5
5
import { typeTransform , selectorInterfaceTransform } from "./transforms" ;
6
6
import { printType } from "./utils" ;
7
7
8
+ interface ASTNode {
9
+ kind : string
10
+ }
11
+
8
12
export const render = ( sdl : string ) : string => {
9
13
const ast = parse ( sdl , { noLocation : true } ) ;
10
14
const schema = buildSchema ( sdl ) ;
@@ -15,9 +19,9 @@ export const render = (sdl: string): string => {
15
19
] ;
16
20
17
21
// additive transforms
18
- const results : ReadonlyArray < { definitions : Code [ ] } > = transforms . map (
22
+ const results = transforms . map (
19
23
( vistor ) => visit ( ast , vistor )
20
- ) ;
24
+ ) as unknown as Array < { readonly definitions : Code [ ] } > ;
21
25
22
26
const types = Object . values ( schema . getTypeMap ( ) ) . filter (
23
27
( type ) => ! type . name . startsWith ( "__" )
@@ -47,31 +51,32 @@ export const render = (sdl: string): string => {
47
51
48
52
const source =
49
53
`
50
- import { buildASTSchema } from 'graphql'
54
+ import { buildASTSchema, Kind, OperationTypeNode } from 'graphql'
51
55
52
- import {
56
+ import {
53
57
TypeConditionError,
54
58
NamedType,
55
59
Field,
56
60
InlineFragment,
57
- Argument,
58
- Variable,
59
- Selection,
60
- SelectionSet,
61
- SelectionBuilder,
61
+ Argument,
62
+ Variable,
63
+ Selection,
64
+ SelectionSet,
65
+ SelectionBuilder,
62
66
namedType,
63
67
field,
64
68
inlineFragment,
65
- argument,
69
+ argument,
66
70
selectionSet
67
71
} 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
+
71
76
` +
72
77
`
73
- export const SCHEMA = buildASTSchema(${ JSON . stringify ( ast ) } )
74
-
78
+ export const SCHEMA = buildASTSchema(${ stringifyAST ( ast ) } )
79
+
75
80
export const ENUMS = ${ ENUMS }
76
81
77
82
${ typeMap }
@@ -84,3 +89,44 @@ export const render = (sdl: string): string => {
84
89
85
90
return prettier . format ( source , { parser : "typescript" } ) ;
86
91
} ;
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