@@ -14,12 +14,12 @@ import { QueryEditor } from "./query-editor"
1414import { VariableEditor } from "./variable-editor"
1515import { ResultViewer } from "./result-viewer"
1616import { 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"
1720
1821export type MiniGraphiQLProps = {
19- schema : GraphQLSchema
20- query : string
21- variables : string
22- rootValue ?: any
22+ children : string
2323}
2424
2525interface MiniGraphiQLState {
@@ -29,6 +29,19 @@ interface MiniGraphiQLState {
2929 variableToType : Record < string , string >
3030}
3131
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+
3245export default class MiniGraphiQL extends Component <
3346 MiniGraphiQLProps ,
3447 MiniGraphiQLState
@@ -37,46 +50,77 @@ export default class MiniGraphiQL extends Component<
3750
3851 _editorQueryID = 0
3952
53+ schema : GraphQLSchema
54+
4055 constructor ( props : MiniGraphiQLProps ) {
4156 super ( props )
42- const query = props . query . replace ( / ^ \s + / , "" )
4357
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+
4571 this . state = {
4672 query : query ,
47- variables : props . variables ,
73+ variables : variables ,
4874 response : null ,
49- variableToType : getVariableToType ( props . schema , query ) ,
75+ variableToType : getVariableToType ( this . schema , query ) ,
5076 }
5177 }
5278
5379 render ( ) {
5480 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 >
6294 )
6395
6496 return (
6597 < div className = "[&:not(:first-child)]:_mt-6 grid grid-cols-2 border border-neu-200 text-sm dark:border-neu-50" >
6698 { Object . keys ( this . state . variableToType ) . length > 0 ? (
67- < div className = "hasVariables" >
99+ < div className = "hasVariables flex flex-col " >
68100 { 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 >
75113 </ div >
76114 ) : (
77115 editor
78116 ) }
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 >
80124 </ div >
81125 )
82126 }
@@ -89,7 +133,7 @@ export default class MiniGraphiQL extends Component<
89133
90134 _runQueryFromEditor ( ) {
91135 this . setState ( {
92- variableToType : getVariableToType ( this . props . schema , this . state . query ) ,
136+ variableToType : getVariableToType ( this . schema , this . state . query ) ,
93137 } )
94138 this . _runQuery ( { manual : true } )
95139 }
@@ -99,10 +143,9 @@ export default class MiniGraphiQL extends Component<
99143 const queryID = this . _editorQueryID
100144 try {
101145 const result = await graphql ( {
102- schema : this . props . schema ,
146+ schema : this . schema ,
103147 source : this . state . query ,
104148 variableValues : JSON . parse ( this . state . variables || "{}" ) ,
105- rootValue : this . props . rootValue ,
106149 } )
107150
108151 let resultToSerialize : any = result
0 commit comments