Skip to content

Instantly share code, notes, and snippets.

@StevenACoffman
Last active June 22, 2023 15:37
Show Gist options
  • Save StevenACoffman/2f15cd2e64f107d1a9a5f10f9748e1b0 to your computer and use it in GitHub Desktop.
Save StevenACoffman/2f15cd2e64f107d1a9a5f10f9748e1b0 to your computer and use it in GitHub Desktop.
Get latest Apollo Sandbox Playground and SRI
// Gets the latest Apollo Embedded Sandbox Playground URL from the CDN S3 bucket
//
// To get the Subresource Integrity check, `go run main.go` and take what that outputs and run like this:
// CDN_FILE=https://embeddable-sandbox.cdn.apollographql.com/58165cf7452dbad480c7cb85e7acba085b3bac1d/embeddable-sandbox.umd.production.min.js
// curl -s $CDN_FILE | openssl dgst -sha256 -binary | openssl base64 -A; echo
package main
import (
"encoding/xml"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"time"
)
type ListBucketResult struct {
XMLName xml.Name `xml:"ListBucketResult"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
Name string `xml:"Name"`
Prefix string `xml:"Prefix"`
NextContinuationToken string `xml:"NextContinuationToken"`
KeyCount string `xml:"KeyCount"`
IsTruncated bool `xml:"IsTruncated"`
Contents []struct {
Text string `xml:",chardata"`
Key string `xml:"Key"`
Generation string `xml:"Generation"`
MetaGeneration string `xml:"MetaGeneration"`
LastModified time.Time `xml:"LastModified"`
ETag string `xml:"ETag"`
Size string `xml:"Size"`
} `xml:"Contents"`
}
func main() {
var continuationToken string
var latestKey string
var latestTime time.Time
isTruncated := true
for isTruncated {
continuationToken, isTruncated, latestKey, latestTime = getPage(
latestKey,
latestTime,
continuationToken,
isTruncated,
)
}
fmt.Println("CDN_FILE=https://embeddable-sandbox.cdn.apollographql.com/" + latestKey)
fmt.Println("curl -s $CDN_FILE | openssl dgst -sha256 -binary | openssl base64 -A; echo")
}
func getPage(
latestKey string,
latestTime time.Time,
continuationToken string,
isTruncated bool,
) (string, bool, string, time.Time) {
const baseURL = "https://embeddable-sandbox.cdn.apollographql.com/?list-type=2"
reqURL := baseURL
if continuationToken != "" {
reqURL += "&continuation-token=" + continuationToken
}
var result ListBucketResult
resp, err := http.Get(reqURL)
if err != nil {
fmt.Printf("client: could not make request: %s\n", err)
os.Exit(1)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf("client: could not read response body: %s\n", err)
os.Exit(1)
}
err = xml.Unmarshal(data, &result)
if err != nil {
log.Fatalf("xml.Unmarshal failed with '%s'\n", err)
}
continuationToken = result.NextContinuationToken
isTruncated = result.IsTruncated
for _, content := range result.Contents {
if strings.Contains(content.Key, "embeddable-sandbox.umd.production.min.js") &&
!strings.Contains(content.Key, "embeddable-sandbox.umd.production.min.js.map") &&
!strings.Contains(content.Key, "_latest") {
if latestTime.IsZero() || latestTime.Before(content.LastModified) {
latestKey = content.Key
latestTime = content.LastModified
}
}
}
return continuationToken, isTruncated, latestKey, latestTime
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment