github.com/geneva/gqlgen@v0.17.7-0.20230801155730-7b9317164836/graphql/playground/playground.go (about)

     1  package playground
     2  
     3  import (
     4  	"html/template"
     5  	"net/http"
     6  	"net/url"
     7  )
     8  
     9  var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
    10  <html>
    11    <head>
    12    	<meta charset="utf-8">
    13    	<title>{{.title}}</title>
    14  	<style>
    15  		body {
    16  			height: 100%;
    17  			margin: 0;
    18  			width: 100%;
    19  			overflow: hidden;
    20  		}
    21  
    22  		#graphiql {
    23  			height: 100vh;
    24  		}
    25  	</style>
    26  	<script
    27  		src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"
    28  		integrity="{{.reactSRI}}"
    29  		crossorigin="anonymous"
    30  	></script>
    31  	<script
    32  		src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"
    33  		integrity="{{.reactDOMSRI}}"
    34  		crossorigin="anonymous"
    35  	></script>
    36      <link
    37  		rel="stylesheet"
    38  		href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
    39  		integrity="{{.cssSRI}}"
    40  		crossorigin="anonymous"
    41  	/>
    42    </head>
    43    <body>
    44      <div id="graphiql">Loading...</div>
    45  
    46  	<script
    47  		src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
    48  		integrity="{{.jsSRI}}"
    49  		crossorigin="anonymous"
    50  	></script>
    51  
    52      <script>
    53  {{- if .endpointIsAbsolute}}
    54        const url = {{.endpoint}};
    55        const subscriptionUrl = {{.subscriptionEndpoint}};
    56  {{- else}}
    57        const url = location.protocol + '//' + location.host + {{.endpoint}};
    58        const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
    59        const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
    60  {{- end}}
    61  {{- if .headers}}
    62        const headers = {{.headers}};
    63  {{- else}}
    64        const headers = undefined;
    65  {{- end}}
    66  
    67        const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl, headers });
    68        ReactDOM.render(
    69          React.createElement(GraphiQL, {
    70            fetcher: fetcher,
    71            isHeadersEditorEnabled: true,
    72            shouldPersistHeaders: true
    73          }),
    74          document.getElementById('graphiql'),
    75        );
    76      </script>
    77    </body>
    78  </html>
    79  `))
    80  
    81  // Handler responsible for setting up the playground
    82  func Handler(title string, endpoint string) http.HandlerFunc {
    83  	return HandlerWithHeaders(title, endpoint, nil)
    84  }
    85  
    86  func HandlerWithHeaders(title string, endpoint string, headers map[string]string) http.HandlerFunc {
    87  	return func(w http.ResponseWriter, r *http.Request) {
    88  		w.Header().Add("Content-Type", "text/html; charset=UTF-8")
    89  		err := page.Execute(w, map[string]interface{}{
    90  			"title":                title,
    91  			"endpoint":             endpoint,
    92  			"headers":              headers,
    93  			"endpointIsAbsolute":   endpointHasScheme(endpoint),
    94  			"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
    95  			"version":              "3.0.1",
    96  			"cssSRI":               "sha256-wTzfn13a+pLMB5rMeysPPR1hO7x0SwSeQI+cnw7VdbE=",
    97  			"jsSRI":                "sha256-dLnxjV+d2rFUCtYKjbPy413/8O+Ahy7QqAhaPNlL8fk=",
    98  			"reactSRI":             "sha256-S0lp+k7zWUMk2ixteM6HZvu8L9Eh//OVrt+ZfbCpmgY=",
    99  			"reactDOMSRI":          "sha256-IXWO0ITNDjfnNXIu5POVfqlgYoop36bDzhodR6LW5Pc=",
   100  		})
   101  		if err != nil {
   102  			panic(err)
   103  		}
   104  	}
   105  }
   106  
   107  // endpointHasScheme checks if the endpoint has a scheme.
   108  func endpointHasScheme(endpoint string) bool {
   109  	u, err := url.Parse(endpoint)
   110  	return err == nil && u.Scheme != ""
   111  }
   112  
   113  // getSubscriptionEndpoint returns the subscription endpoint for the given
   114  // endpoint if it is parsable as a URL, or an empty string.
   115  func getSubscriptionEndpoint(endpoint string) string {
   116  	u, err := url.Parse(endpoint)
   117  	if err != nil {
   118  		return ""
   119  	}
   120  
   121  	switch u.Scheme {
   122  	case "https":
   123  		u.Scheme = "wss"
   124  	default:
   125  		u.Scheme = "ws"
   126  	}
   127  
   128  	return u.String()
   129  }