@@ -10,7 +10,9 @@ import {
10
10
ValueNode ,
11
11
buildClientSchema ,
12
12
getNamedType ,
13
+ isEnumType ,
13
14
isInputObjectType ,
15
+ isListType ,
14
16
print ,
15
17
} from "graphql" ;
16
18
import { upsertFile } from "./file-utils" ;
@@ -34,9 +36,7 @@ export function registerAdHoc(
34
36
ast : ObjectTypeDefinitionNode ,
35
37
documentPath : string ,
36
38
) {
37
- // TODO(rrousselGit) - this is a temporary solution due to the lack of a "schema".
38
- // As such, we hardcoded the list of allowed primitives.
39
- // We should ideally refactor this to allow any scalar type.
39
+ // TODO(hlshen): Revamp makeQuery to utilize live schema, and built out an AST instead of construction the query through string builder
40
40
const primitiveTypes = new Set ( [
41
41
"String" ,
42
42
"Int" ,
@@ -67,9 +67,12 @@ export function registerAdHoc(
67
67
var hasField = false ;
68
68
let query = "{\n" ;
69
69
for ( const field of ast . fields ! ) {
70
- // We unwrap NonNullType to obtain the actual type
70
+ // We unwrap NonNullType and ListType to obtain the actual type
71
71
let fieldType = field . type ;
72
- if ( fieldType . kind === Kind . NON_NULL_TYPE ) {
72
+ while (
73
+ fieldType . kind === Kind . LIST_TYPE ||
74
+ fieldType . kind === Kind . NON_NULL_TYPE
75
+ ) {
73
76
fieldType = fieldType . type ;
74
77
}
75
78
@@ -83,6 +86,17 @@ export function registerAdHoc(
83
86
continue ;
84
87
}
85
88
89
+ const isEnum = document . definitions . some (
90
+ ( def ) =>
91
+ def . kind === Kind . ENUM_TYPE_DEFINITION &&
92
+ def . name . value === targetType . name . value ,
93
+ ) ;
94
+ if ( isEnum ) {
95
+ query += ` ${ indent } ${ field . name . value } \n` ;
96
+ hasField = true ;
97
+ continue ;
98
+ }
99
+
86
100
// Check relational types.
87
101
// Since we lack a schema, we can only build queries for types that are defined in the same document.
88
102
const targetTypeDefinition = document . definitions . find (
@@ -106,18 +120,16 @@ export function registerAdHoc(
106
120
}
107
121
108
122
query += `${ indent } }` ;
123
+ if ( ! hasField ) {
124
+ return undefined ;
125
+ }
109
126
return query ;
110
127
}
111
128
112
129
await upsertFile ( filePath , ( ) => {
113
130
const queryName = `${ ast . name . value . charAt ( 0 ) . toLowerCase ( ) } ${ ast . name . value . slice ( 1 ) } s` ;
114
131
115
- return `
116
- # This is a file for you to write an un-named query.
117
- # Only one un-named query is allowed per file.
118
- query {
119
- ${ queryName } ${ buildRecursiveObjectQuery ( ast ) ! }
120
- }` ;
132
+ return `\n# This is a file for you to write an un-named query.\n# Only one un-named query is allowed per file.\nquery {\n ${ queryName } ${ buildRecursiveObjectQuery ( ast ) ! } \n}` ;
121
133
} ) ;
122
134
}
123
135
@@ -164,82 +176,6 @@ query {
164
176
} ) ;
165
177
}
166
178
167
- function makeAdHocMutation (
168
- fields : GraphQLInputField [ ] ,
169
- singularName : string ,
170
- ) : OperationDefinitionNode {
171
- const argumentFields : ObjectFieldNode [ ] = [ ] ;
172
-
173
- for ( const field of fields ) {
174
- const type = getNamedType ( field . type ) ;
175
- const defaultValue = getDefaultScalarValueNode ( type . name ) ;
176
- if ( ! defaultValue ) {
177
- continue ;
178
- }
179
-
180
- argumentFields . push ( {
181
- kind : Kind . OBJECT_FIELD ,
182
- name : { kind : Kind . NAME , value : field . name } ,
183
- value : defaultValue ,
184
- } ) ;
185
- }
186
-
187
- return {
188
- kind : Kind . OPERATION_DEFINITION ,
189
- operation : OperationTypeNode . MUTATION ,
190
- selectionSet : {
191
- kind : Kind . SELECTION_SET ,
192
- selections : [
193
- {
194
- kind : Kind . FIELD ,
195
- name : {
196
- kind : Kind . NAME ,
197
- value : `${ singularName . charAt ( 0 ) . toLowerCase ( ) } ${ singularName . slice ( 1 ) } _insert` ,
198
- } ,
199
- arguments : [
200
- {
201
- kind : Kind . ARGUMENT ,
202
- name : { kind : Kind . NAME , value : "data" } ,
203
- value : {
204
- kind : Kind . OBJECT ,
205
- fields : argumentFields ,
206
- } ,
207
- } ,
208
- ] ,
209
- } ,
210
- ] ,
211
- } ,
212
- } ;
213
- }
214
- function getDefaultScalarValueNode ( type : string ) : ValueNode | undefined {
215
- switch ( type ) {
216
- case "Any" :
217
- return { kind : Kind . OBJECT , fields : [ ] } ;
218
- case "Boolean" :
219
- return { kind : Kind . BOOLEAN , value : false } ;
220
- case "Date" :
221
- return {
222
- kind : Kind . STRING ,
223
- value : new Date ( ) . toISOString ( ) . substring ( 0 , 10 ) ,
224
- } ;
225
- case "Float" :
226
- return { kind : Kind . FLOAT , value : "0" } ;
227
- case "Int" :
228
- return { kind : Kind . INT , value : "0" } ;
229
- case "Int64" :
230
- return { kind : Kind . INT , value : "0" } ;
231
- case "String" :
232
- return { kind : Kind . STRING , value : "" } ;
233
- case "Timestamp" :
234
- return { kind : Kind . STRING , value : new Date ( ) . toISOString ( ) } ;
235
- case "UUID" :
236
- return { kind : Kind . STRING , value : "11111111222233334444555555555555" } ;
237
- case "Vector" :
238
- return { kind : Kind . LIST , values : [ ] } ;
239
- default :
240
- return undefined ;
241
- }
242
- }
243
179
return Disposable . from (
244
180
vscode . commands . registerCommand (
245
181
"firebase.dataConnect.schemaAddData" ,
@@ -258,6 +194,95 @@ query {
258
194
) ;
259
195
}
260
196
197
+ export function makeAdHocMutation (
198
+ fields : GraphQLInputField [ ] ,
199
+ singularName : string ,
200
+ ) : OperationDefinitionNode {
201
+ const argumentFields : ObjectFieldNode [ ] = [ ] ;
202
+
203
+ for ( const field of fields ) {
204
+ const type = getNamedType ( field . type ) ;
205
+ let defaultValue : ValueNode | undefined ;
206
+ if ( isEnumType ( type ) ) {
207
+ const enumValues = type . getValues ( ) ;
208
+ if ( enumValues . length > 0 ) {
209
+ defaultValue = { kind : Kind . ENUM , value : enumValues [ 0 ] . name } ;
210
+ }
211
+ } else {
212
+ defaultValue = getDefaultScalarValueNode ( type . name ) ;
213
+ }
214
+ if ( ! defaultValue ) {
215
+ continue ;
216
+ }
217
+
218
+ // convert it back to a list
219
+ if ( isListType ( field . type ) ) {
220
+ defaultValue = { kind : Kind . LIST , values : [ defaultValue ] } ;
221
+ }
222
+
223
+ argumentFields . push ( {
224
+ kind : Kind . OBJECT_FIELD ,
225
+ name : { kind : Kind . NAME , value : field . name } ,
226
+ value : defaultValue ,
227
+ } ) ;
228
+ }
229
+
230
+ return {
231
+ kind : Kind . OPERATION_DEFINITION ,
232
+ operation : OperationTypeNode . MUTATION ,
233
+ selectionSet : {
234
+ kind : Kind . SELECTION_SET ,
235
+ selections : [
236
+ {
237
+ kind : Kind . FIELD ,
238
+ name : {
239
+ kind : Kind . NAME ,
240
+ value : `${ singularName . charAt ( 0 ) . toLowerCase ( ) } ${ singularName . slice ( 1 ) } _insert` ,
241
+ } ,
242
+ arguments : [
243
+ {
244
+ kind : Kind . ARGUMENT ,
245
+ name : { kind : Kind . NAME , value : "data" } ,
246
+ value : {
247
+ kind : Kind . OBJECT ,
248
+ fields : argumentFields ,
249
+ } ,
250
+ } ,
251
+ ] ,
252
+ } ,
253
+ ] ,
254
+ } ,
255
+ } ;
256
+ }
257
+ function getDefaultScalarValueNode ( type : string ) : ValueNode | undefined {
258
+ switch ( type ) {
259
+ case "Any" :
260
+ return { kind : Kind . OBJECT , fields : [ ] } ;
261
+ case "Boolean" :
262
+ return { kind : Kind . BOOLEAN , value : false } ;
263
+ case "Date" :
264
+ return {
265
+ kind : Kind . STRING ,
266
+ value : new Date ( ) . toISOString ( ) . substring ( 0 , 10 ) ,
267
+ } ;
268
+ case "Float" :
269
+ return { kind : Kind . FLOAT , value : "0" } ;
270
+ case "Int" :
271
+ return { kind : Kind . INT , value : "0" } ;
272
+ case "Int64" :
273
+ return { kind : Kind . INT , value : "0" } ;
274
+ case "String" :
275
+ return { kind : Kind . STRING , value : "" } ;
276
+ case "Timestamp" :
277
+ return { kind : Kind . STRING , value : new Date ( ) . toISOString ( ) } ;
278
+ case "UUID" :
279
+ return { kind : Kind . STRING , value : "11111111222233334444555555555555" } ;
280
+ case "Vector" :
281
+ return { kind : Kind . LIST , values : [ ] } ;
282
+ default :
283
+ return undefined ;
284
+ }
285
+ }
261
286
262
287
export function getDefaultScalarValue ( type : string ) : string {
263
288
switch ( type ) {
0 commit comments