121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
|
package graphiql
|
||
|
|
||
|
import (
|
||
|
"html/template"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
)
|
||
|
|
||
|
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>{{.title}}</title>
|
||
|
<style>
|
||
|
body {
|
||
|
height: 100%;
|
||
|
margin: 0;
|
||
|
width: 100%;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
|
||
|
#graphiql {
|
||
|
height: 100vh;
|
||
|
}
|
||
|
</style>
|
||
|
<script
|
||
|
src="https://cdn.jsdelivr.net/npm/react@{{.reactVersion}}/umd/react.production.min.js"
|
||
|
integrity="{{.reactSRI}}"
|
||
|
crossorigin="anonymous"
|
||
|
></script>
|
||
|
<script
|
||
|
src="https://cdn.jsdelivr.net/npm/react-dom@{{.reactVersion}}/umd/react-dom.production.min.js"
|
||
|
integrity="{{.reactDOMSRI}}"
|
||
|
crossorigin="anonymous"
|
||
|
></script>
|
||
|
<link
|
||
|
rel="stylesheet"
|
||
|
href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
|
||
|
x-integrity="{{.cssSRI}}"
|
||
|
crossorigin="anonymous"
|
||
|
/>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="graphiql">Loading...</div>
|
||
|
|
||
|
<script
|
||
|
src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
|
||
|
x-integrity="{{.jsSRI}}"
|
||
|
crossorigin="anonymous"
|
||
|
></script>
|
||
|
|
||
|
<script>
|
||
|
{{- if .endpointIsAbsolute}}
|
||
|
const url = {{.endpoint}};
|
||
|
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||
|
{{- else}}
|
||
|
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||
|
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||
|
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||
|
{{- end}}
|
||
|
|
||
|
const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl });
|
||
|
ReactDOM.render(
|
||
|
React.createElement(GraphiQL, {
|
||
|
fetcher: fetcher,
|
||
|
isHeadersEditorEnabled: true,
|
||
|
shouldPersistHeaders: true
|
||
|
}),
|
||
|
document.getElementById('graphiql'),
|
||
|
);
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|
||
|
`))
|
||
|
|
||
|
// Handler responsible for setting up the playground
|
||
|
func Handler(title string, endpoint string) http.HandlerFunc {
|
||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
|
||
|
err := page.Execute(w, map[string]interface{}{
|
||
|
"title": title,
|
||
|
"endpoint": endpoint,
|
||
|
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||
|
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||
|
"version": "2.4.1",
|
||
|
"reactVersion": "17.0.2",
|
||
|
"cssSRI": "sha256-bGeEsMhcAqeXBjh2w0eQzBTFAxwlxhM0PKIKqMshlnk=",
|
||
|
"jsSRI": "sha256-s+f7CFAPSUIygFnRC2nfoiEKd3liCUy+snSdYFAoLUc=",
|
||
|
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||
|
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||
|
})
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// endpointHasScheme checks if the endpoint has a scheme.
|
||
|
func endpointHasScheme(endpoint string) bool {
|
||
|
u, err := url.Parse(endpoint)
|
||
|
return err == nil && u.Scheme != ""
|
||
|
}
|
||
|
|
||
|
// getSubscriptionEndpoint returns the subscription endpoint for the given
|
||
|
// endpoint if it is parsable as a URL, or an empty string.
|
||
|
func getSubscriptionEndpoint(endpoint string) string {
|
||
|
u, err := url.Parse(endpoint)
|
||
|
if err != nil {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
switch u.Scheme {
|
||
|
case "https":
|
||
|
u.Scheme = "wss"
|
||
|
default:
|
||
|
u.Scheme = "ws"
|
||
|
}
|
||
|
|
||
|
return u.String()
|
||
|
}
|