@@ -14,12 +14,12 @@ import { QueryEditor } from "./query-editor"
14
14
import { VariableEditor } from "./variable-editor"
15
15
import { ResultViewer } from "./result-viewer"
16
16
import { getVariableToType } from "./get-variable-to-type"
17
+ import { StarWarsSchema } from "./swapi-schema"
18
+ import { UsersSchema } from "./users-schema"
19
+ import { CodeBlockLabel } from "@/components/pre/code-block-label"
17
20
18
21
export type MiniGraphiQLProps = {
19
- schema : GraphQLSchema
20
- query : string
21
- variables : string
22
- rootValue ?: any
22
+ children : string
23
23
}
24
24
25
25
interface MiniGraphiQLState {
@@ -29,6 +29,19 @@ interface MiniGraphiQLState {
29
29
variableToType : Record < string , string >
30
30
}
31
31
32
+ const SCHEMA_MAP = {
33
+ StarWars : StarWarsSchema ,
34
+ Users : UsersSchema ,
35
+ } as const
36
+
37
+ type SchemaKey = keyof typeof SCHEMA_MAP
38
+
39
+ type Metadata = {
40
+ graphiql ?: boolean
41
+ variables ?: unknown
42
+ schema ?: SchemaKey
43
+ }
44
+
32
45
export default class MiniGraphiQL extends Component <
33
46
MiniGraphiQLProps ,
34
47
MiniGraphiQLState
@@ -37,46 +50,77 @@ export default class MiniGraphiQL extends Component<
37
50
38
51
_editorQueryID = 0
39
52
53
+ schema : GraphQLSchema
54
+
40
55
constructor ( props : MiniGraphiQLProps ) {
41
56
super ( props )
42
- const query = props . query . replace ( / ^ \s + / , "" )
43
57
44
- // Initialize state
58
+ const codeMatch = this . props . children . match ( / ` ` ` g r a p h q l \s * \n ( [ \s \S ] * ?) ` ` ` / )
59
+ const blockContent = codeMatch ?. [ 1 ]
60
+ const [ firstLine , ...rest ] = ( blockContent || "" ) . split ( "\n" )
61
+
62
+ const metaMatch = firstLine . match ( / ^ \s * # \s * ( { .* } ) \s * $ / ) ?. [ 1 ] ?? "{}"
63
+ const meta = JSON . parse ( metaMatch ) as Metadata
64
+
65
+ const query = rest . join ( "\n" ) . replace ( / ^ \s + / , "" )
66
+ const variables = meta . variables
67
+ ? JSON . stringify ( meta . variables , null , 2 )
68
+ : ""
69
+ this . schema = SCHEMA_MAP [ meta . schema ?? "StarWars" ]
70
+
45
71
this . state = {
46
72
query : query ,
47
- variables : props . variables ,
73
+ variables : variables ,
48
74
response : null ,
49
- variableToType : getVariableToType ( props . schema , query ) ,
75
+ variableToType : getVariableToType ( this . schema , query ) ,
50
76
}
51
77
}
52
78
53
79
render ( ) {
54
80
const editor = (
55
- < QueryEditor
56
- key = "query-editor"
57
- schema = { this . props . schema }
58
- value = { this . state . query }
59
- onEdit = { this . _handleEditQuery . bind ( this ) }
60
- runQuery = { this . _runQueryFromEditor . bind ( this ) }
61
- />
81
+ < div className = "flex flex-col" >
82
+ < CodeBlockLabel
83
+ text = "Operation"
84
+ className = "border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
85
+ />
86
+ < QueryEditor
87
+ key = "query-editor"
88
+ schema = { this . schema }
89
+ value = { this . state . query }
90
+ onEdit = { this . _handleEditQuery . bind ( this ) }
91
+ runQuery = { this . _runQueryFromEditor . bind ( this ) }
92
+ />
93
+ </ div >
62
94
)
63
95
64
96
return (
65
97
< div className = "[&:not(:first-child)]:_mt-6 grid grid-cols-2 border border-neu-200 text-sm dark:border-neu-50" >
66
98
{ Object . keys ( this . state . variableToType ) . length > 0 ? (
67
- < div className = "hasVariables" >
99
+ < div className = "hasVariables flex flex-col " >
68
100
{ editor }
69
- < VariableEditor
70
- value = { this . state . variables }
71
- variableToType = { this . state . variableToType }
72
- onEdit = { this . _handleEditVariables . bind ( this ) }
73
- onRunQuery = { this . _runQuery . bind ( this ) }
74
- />
101
+ < div className = "flex flex-col border-neu-200 dark:border-neu-50" >
102
+ < CodeBlockLabel
103
+ text = "Variables"
104
+ className = "border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
105
+ />
106
+ < VariableEditor
107
+ value = { this . state . variables }
108
+ variableToType = { this . state . variableToType }
109
+ onEdit = { this . _handleEditVariables . bind ( this ) }
110
+ onRunQuery = { ( ) => void this . _runQuery . bind ( this ) }
111
+ />
112
+ </ div >
75
113
</ div >
76
114
) : (
77
115
editor
78
116
) }
79
- < ResultViewer value = { this . state . response || undefined } />
117
+ < div className = "flex flex-col border-l border-neu-200 dark:border-neu-50" >
118
+ < CodeBlockLabel
119
+ text = "Response"
120
+ className = "border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
121
+ />
122
+ < ResultViewer value = { this . state . response || undefined } />
123
+ </ div >
80
124
</ div >
81
125
)
82
126
}
@@ -89,7 +133,7 @@ export default class MiniGraphiQL extends Component<
89
133
90
134
_runQueryFromEditor ( ) {
91
135
this . setState ( {
92
- variableToType : getVariableToType ( this . props . schema , this . state . query ) ,
136
+ variableToType : getVariableToType ( this . schema , this . state . query ) ,
93
137
} )
94
138
this . _runQuery ( { manual : true } )
95
139
}
@@ -99,10 +143,9 @@ export default class MiniGraphiQL extends Component<
99
143
const queryID = this . _editorQueryID
100
144
try {
101
145
const result = await graphql ( {
102
- schema : this . props . schema ,
146
+ schema : this . schema ,
103
147
source : this . state . query ,
104
148
variableValues : JSON . parse ( this . state . variables || "{}" ) ,
105
- rootValue : this . props . rootValue ,
106
149
} )
107
150
108
151
let resultToSerialize : any = result
0 commit comments