...

Source file src/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go

Documentation: github.com/99designs/gqlgen/graphql/playground

     1  package playground
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"html/template"
     7  	"net/http"
     8  )
     9  
    10  // NOTE: New version available at https://embeddable-sandbox.cdn.apollographql.com/ -->
    11  var apolloSandboxPage = template.Must(template.New("ApolloSandbox").Parse(`<!doctype html>
    12  <html>
    13  
    14  <head>
    15    <meta charset="utf-8">
    16    <title>{{.title}}</title>
    17    <meta name="viewport" content="width=device-width,initial-scale=1">
    18    <link rel="icon" href="https://embeddable-sandbox.cdn.apollographql.com/_latest/public/assets/favicon-dark.png">
    19  	<style>
    20  	body {
    21  		margin: 0;
    22  		overflow: hidden;
    23  	}
    24  </style>
    25  </head>
    26  
    27  <body>
    28    <div style="width: 100vw; height: 100vh;" id='embedded-sandbox'></div>
    29    <script rel="preload" as="script" crossorigin="anonymous" integrity="{{.mainSRI}}" type="text/javascript" src="https://embeddable-sandbox.cdn.apollographql.com/02e2da0fccbe0240ef03d2396d6c98559bab5b06/embeddable-sandbox.umd.production.min.js"></script>
    30    <script>
    31  {{- if .endpointIsAbsolute}}
    32  	const url = {{.endpoint}};
    33  {{- else}}
    34  	const url = location.protocol + '//' + location.host + {{.endpoint}};
    35  {{- end}}
    36  	const options = JSON.parse({{.options}})
    37  	new window.EmbeddedSandbox({
    38  		target: '#embedded-sandbox',
    39  		initialEndpoint: url,
    40  		persistExplorerState: true,
    41  		...options,
    42  	});
    43    </script>
    44  </body>
    45  </html>`))
    46  
    47  // ApolloSandboxHandler responsible for setting up the apollo sandbox playground
    48  func ApolloSandboxHandler(title, endpoint string, opts ...ApolloSandboxOption) http.HandlerFunc {
    49  	options := &apolloSandboxOptions{
    50  		HideCookieToggle: true,
    51  		InitialState: apolloSandboxInitialState{
    52  			IncludeCookies:       true,
    53  			PollForSchemaUpdates: false,
    54  		},
    55  	}
    56  
    57  	for _, opt := range opts {
    58  		opt(options)
    59  	}
    60  
    61  	optionsBytes, err := json.Marshal(options)
    62  	if err != nil {
    63  		panic(fmt.Errorf("failed to marshal apollo sandbox options: %w", err))
    64  	}
    65  
    66  	return func(w http.ResponseWriter, r *http.Request) {
    67  		err := apolloSandboxPage.Execute(w, map[string]interface{}{
    68  			"title":              title,
    69  			"endpoint":           endpoint,
    70  			"endpointIsAbsolute": endpointHasScheme(endpoint),
    71  			"mainSRI":            "sha256-pYhw/8TGkZxk960PMMpDtjhw9YtKXUzGv6XQQaMJSh8=",
    72  			"options":            string(optionsBytes),
    73  		})
    74  		if err != nil {
    75  			panic(err)
    76  		}
    77  	}
    78  }
    79  
    80  // See https://www.apollographql.com/docs/graphos/explorer/sandbox/#options -->
    81  type apolloSandboxOptions struct {
    82  	HideCookieToggle   bool                      `json:"hideCookieToggle"`
    83  	EndpointIsEditable bool                      `json:"endpointIsEditable"`
    84  	InitialState       apolloSandboxInitialState `json:"initialState,omitempty"`
    85  }
    86  
    87  type apolloSandboxInitialState struct {
    88  	IncludeCookies       bool           `json:"includeCookies"`
    89  	Document             string         `json:"document,omitempty"`
    90  	Variables            map[string]any `json:"variables,omitempty"`
    91  	Headers              map[string]any `json:"headers,omitempty"`
    92  	CollectionId         string         `json:"collectionId,omitempty"`
    93  	OperationId          string         `json:"operationId,omitempty"`
    94  	PollForSchemaUpdates bool           `json:"pollForSchemaUpdates"`
    95  	SharedHeaders        map[string]any `json:"sharedHeaders,omitempty"`
    96  }
    97  
    98  type ApolloSandboxOption func(options *apolloSandboxOptions)
    99  
   100  // WithApolloSandboxHideCookieToggle By default, the embedded Sandbox does not show the Include cookies toggle in its connection settings.
   101  //
   102  // Set hideCookieToggle to false to enable users of your embedded Sandbox instance to toggle the Include cookies setting.
   103  func WithApolloSandboxHideCookieToggle(hideCookieToggle bool) ApolloSandboxOption {
   104  	return func(options *apolloSandboxOptions) {
   105  		options.HideCookieToggle = hideCookieToggle
   106  	}
   107  }
   108  
   109  // WithApolloSandboxEndpointIsEditable By default, the embedded Sandbox has a URL input box that is editable by users.
   110  //
   111  // Set endpointIsEditable to false to prevent users of your embedded Sandbox instance from changing the endpoint URL.
   112  func WithApolloSandboxEndpointIsEditable(endpointIsEditable bool) ApolloSandboxOption {
   113  	return func(options *apolloSandboxOptions) {
   114  		options.EndpointIsEditable = endpointIsEditable
   115  	}
   116  }
   117  
   118  // WithApolloSandboxInitialStateIncludeCookies Set this value to true if you want the Sandbox to pass { credentials: 'include' } for its requests by default.
   119  //
   120  // If you set hideCookieToggle to false, users can override this default setting with the Include cookies toggle. (By default, the embedded Sandbox does not show the Include cookies toggle in its connection settings.)
   121  //
   122  // If you also pass the handleRequest option, this option is ignored.
   123  //
   124  // Read more about the fetch API and credentials here https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials
   125  func WithApolloSandboxInitialStateIncludeCookies(includeCookies bool) ApolloSandboxOption {
   126  	return func(options *apolloSandboxOptions) {
   127  		options.InitialState.IncludeCookies = includeCookies
   128  	}
   129  }
   130  
   131  // WithApolloSandboxInitialStateDocument Document operation to populate in the Sandbox's editor on load.
   132  //
   133  // If you omit this, the Sandbox initially loads an example query based on your schema.
   134  func WithApolloSandboxInitialStateDocument(document string) ApolloSandboxOption {
   135  	return func(options *apolloSandboxOptions) {
   136  		options.InitialState.Document = document
   137  	}
   138  }
   139  
   140  // WithApolloSandboxInitialStateVariables Variables containing initial variable values to populate in the Sandbox on load.
   141  //
   142  // If provided, these variables should apply to the initial query you provide for document.
   143  func WithApolloSandboxInitialStateVariables(variables map[string]any) ApolloSandboxOption {
   144  	return func(options *apolloSandboxOptions) {
   145  		options.InitialState.Variables = variables
   146  	}
   147  }
   148  
   149  // WithApolloSandboxInitialStateHeaders Headers containing initial variable values to populate in the Sandbox on load.
   150  //
   151  // If provided, these variables should apply to the initial query you provide for document.
   152  func WithApolloSandboxInitialStateHeaders(headers map[string]any) ApolloSandboxOption {
   153  	return func(options *apolloSandboxOptions) {
   154  		options.InitialState.Headers = headers
   155  	}
   156  }
   157  
   158  // WithApolloSandboxInitialStateCollectionIdAndOperationId The ID of a collection, paired with an operation ID to populate in the Sandbox on load.
   159  //
   160  // You can find these values from a registered graph in Studio by clicking the ... menu next to an operation in the Explorer of that graph and selecting View operation details.
   161  func WithApolloSandboxInitialStateCollectionIdAndOperationId(collectionId, operationId string) ApolloSandboxOption {
   162  	return func(options *apolloSandboxOptions) {
   163  		options.InitialState.CollectionId = collectionId
   164  		options.InitialState.OperationId = operationId
   165  	}
   166  }
   167  
   168  // WithApolloSandboxInitialStatePollForSchemaUpdates If true, the embedded Sandbox periodically polls your initialEndpoint for schema updates.
   169  //
   170  // The default value is false.
   171  func WithApolloSandboxInitialStatePollForSchemaUpdates(pollForSchemaUpdates bool) ApolloSandboxOption {
   172  	return func(options *apolloSandboxOptions) {
   173  		options.InitialState.PollForSchemaUpdates = pollForSchemaUpdates
   174  	}
   175  }
   176  
   177  // WithApolloSandboxInitialStateSharedHeaders Headers that are applied by default to every operation executed by the embedded Sandbox.
   178  //
   179  // Users can disable the application of these headers, but they can't modify their values.
   180  //
   181  // The embedded Sandbox always includes these headers in its introspection queries to your initialEndpoint.
   182  func WithApolloSandboxInitialStateSharedHeaders(sharedHeaders map[string]any) ApolloSandboxOption {
   183  	return func(options *apolloSandboxOptions) {
   184  		options.InitialState.SharedHeaders = sharedHeaders
   185  	}
   186  }
   187  

View as plain text