diff options
author | Michael Muré <batolettre@gmail.com> | 2018-07-19 14:15:50 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-07-19 14:15:50 +0200 |
commit | a2a50f3de0c428c5a61e6a449191be3c4ded86ac (patch) | |
tree | 5ecf4f5f1f26933b42a606b741963fa5f66c85aa /vendor/github.com/graphql-go/handler/graphiql.go | |
parent | 25fb88d7497b00bbe3dda540efde22ffd3de6e49 (diff) | |
download | git-bug-a2a50f3de0c428c5a61e6a449191be3c4ded86ac.tar.gz |
webui: add a primitive graphql handler
Diffstat (limited to 'vendor/github.com/graphql-go/handler/graphiql.go')
-rw-r--r-- | vendor/github.com/graphql-go/handler/graphiql.go | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/github.com/graphql-go/handler/graphiql.go b/vendor/github.com/graphql-go/handler/graphiql.go new file mode 100644 index 00000000..ace949b4 --- /dev/null +++ b/vendor/github.com/graphql-go/handler/graphiql.go @@ -0,0 +1,199 @@ +package handler + +import ( + "encoding/json" + "html/template" + "net/http" + + "github.com/graphql-go/graphql" +) + +// page is the page data structure of the rendered GraphiQL page +type graphiqlPage struct { + GraphiqlVersion string + QueryString string + ResultString string + VariablesString string + OperationName string +} + +// renderGraphiQL renders the GraphiQL GUI +func renderGraphiQL(w http.ResponseWriter, params graphql.Params) { + t := template.New("GraphiQL") + t, err := t.Parse(graphiqlTemplate) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Create variables string + vars, err := json.MarshalIndent(params.VariableValues, "", " ") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + varsString := string(vars) + if varsString == "null" { + varsString = "" + } + + // Create result string + var resString string + if params.RequestString == "" { + resString = "" + } else { + result, err := json.MarshalIndent(graphql.Do(params), "", " ") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + resString = string(result) + } + + p := graphiqlPage{ + GraphiqlVersion: graphiqlVersion, + QueryString: params.RequestString, + ResultString: resString, + VariablesString: varsString, + OperationName: params.OperationName, + } + + err = t.ExecuteTemplate(w, "index", p) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + return +} + +// graphiqlVersion is the current version of GraphiQL +const graphiqlVersion = "0.11.3" + +// tmpl is the page template to render GraphiQL +const graphiqlTemplate = ` +{{ define "index" }} +<!-- +The request to this GraphQL server provided the header "Accept: text/html" +and as a result has been presented GraphiQL - an in-browser IDE for +exploring GraphQL. + +If you wish to receive JSON, provide the header "Accept: application/json" or +add "&raw" to the end of the URL within a browser. +--> +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>GraphiQL</title> + <meta name="robots" content="noindex" /> + <style> + html, body { + height: 100%; + margin: 0; + overflow: hidden; + width: 100%; + } + </style> + <link href="//cdn.jsdelivr.net/npm/graphiql@{{ .GraphiqlVersion }}/graphiql.css" rel="stylesheet" /> + <script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script> + <script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script> + <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script> + <script src="//cdn.jsdelivr.net/npm/graphiql@{{ .GraphiqlVersion }}/graphiql.min.js"></script> +</head> +<body> + <script> + // Collect the URL parameters + var parameters = {}; + window.location.search.substr(1).split('&').forEach(function (entry) { + var eq = entry.indexOf('='); + if (eq >= 0) { + parameters[decodeURIComponent(entry.slice(0, eq))] = + decodeURIComponent(entry.slice(eq + 1)); + } + }); + + // Produce a Location query string from a parameter object. + function locationQuery(params) { + return '?' + Object.keys(params).filter(function (key) { + return Boolean(params[key]); + }).map(function (key) { + return encodeURIComponent(key) + '=' + + encodeURIComponent(params[key]); + }).join('&'); + } + + // Derive a fetch URL from the current URL, sans the GraphQL parameters. + var graphqlParamNames = { + query: true, + variables: true, + operationName: true + }; + + var otherParams = {}; + for (var k in parameters) { + if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) { + otherParams[k] = parameters[k]; + } + } + var fetchURL = locationQuery(otherParams); + + // Defines a GraphQL fetcher using the fetch API. + function graphQLFetcher(graphQLParams) { + return fetch(fetchURL, { + method: 'post', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(graphQLParams), + credentials: 'include', + }).then(function (response) { + return response.text(); + }).then(function (responseBody) { + try { + return JSON.parse(responseBody); + } catch (error) { + return responseBody; + } + }); + } + + // When the query and variables string is edited, update the URL bar so + // that it can be easily shared. + function onEditQuery(newQuery) { + parameters.query = newQuery; + updateURL(); + } + + function onEditVariables(newVariables) { + parameters.variables = newVariables; + updateURL(); + } + + function onEditOperationName(newOperationName) { + parameters.operationName = newOperationName; + updateURL(); + } + + function updateURL() { + history.replaceState(null, null, locationQuery(parameters)); + } + + // Render <GraphiQL /> into the body. + ReactDOM.render( + React.createElement(GraphiQL, { + fetcher: graphQLFetcher, + onEditQuery: onEditQuery, + onEditVariables: onEditVariables, + onEditOperationName: onEditOperationName, + query: {{ .QueryString }}, + response: {{ .ResultString }}, + variables: {{ .VariablesString }}, + operationName: {{ .OperationName }}, + }), + document.body + ); + </script> +</body> +</html> +{{ end }} +` |