x

Programs, configuration and documentation that don't fit anywhere else
Log | Files | Refs | README | LICENSE

gql.go (2283B)


      1 package main
      2 
      3 import (
      4 	"bytes"
      5 	"encoding/json"
      6 	"flag"
      7 	"fmt"
      8 	"io"
      9 	"log"
     10 	"net/http"
     11 	"os"
     12 	"strings"
     13 )
     14 
     15 const usage string = "gql [-k file] [-r file] [-v var=value ] url [file]"
     16 
     17 // Firefox ESR (Extended Support Release).
     18 const firefox = "Mozilla/5.0 (X11; Intel Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0"
     19 
     20 type Query struct {
     21 	Query     string `json:"query"`
     22 	Variables any `json:"variables,omitempty"`
     23 }
     24 
     25 var tokenFlag = flag.String("k", "", "file containing api key")
     26 var varFlag = flag.String("v", "", "variable in key=value format")
     27 var rFlag = flag.String("r", "", "file containing variables in json format")
     28 
     29 var token string
     30 
     31 func init() {
     32 	flag.Parse()
     33 }
     34 
     35 func main() {
     36 	if len(flag.Args()) == 0 {
     37 		fmt.Println("usage:", usage)
     38 		os.Exit(2)
     39 	}
     40 
     41 	if *tokenFlag != "" {
     42 		b, err := os.ReadFile(*tokenFlag)
     43 		if err != nil {
     44 			log.Fatalf("read key file: %v", err)
     45 		}
     46 		token = string(bytes.TrimSpace(b))
     47 	}
     48 
     49 	var query Query
     50 	if *varFlag != "" {
     51 		k, v, ok := strings.Cut(*varFlag, "=")
     52 		if !ok {
     53 			log.Fatalf("missing = separator in variable spec %q", *varFlag)
     54 		}
     55 		query.Variables = map[string]string{k: v}
     56 	} else if *rFlag != "" {
     57 		f, err := os.Open(*rFlag)
     58 		if err != nil {
     59 			log.Fatalf("open variables file: %v", err)
     60 		}
     61 		defer f.Close()
     62 		if err := json.NewDecoder(f).Decode(&query.Variables); err != nil {
     63 			log.Fatalf("parse variables from %s: %v", *rFlag, err)
     64 		}
     65 	}
     66 
     67 	url := flag.Arg(0)
     68 
     69 	rd := os.Stdin
     70 	if len(flag.Args()) == 2 {
     71 		f, err := os.Open(flag.Arg(1))
     72 		if err != nil {
     73 			log.Fatal(err)
     74 		}
     75 		defer f.Close()
     76 		rd = f
     77 	}
     78 	b, err := io.ReadAll(rd)
     79 	if err != nil {
     80 		log.Fatalf("read query: %v", err)
     81 	}
     82 	query.Query = string(bytes.TrimSpace(b))
     83 
     84 	buf := &bytes.Buffer{}
     85 	if err := json.NewEncoder(buf).Encode(&query); err != nil {
     86 		log.Fatalf("encode graphql query: %v", err)
     87 	}
     88 	println(buf.String())
     89 	os.Exit(1)
     90 
     91 	req, err := http.NewRequest(http.MethodPost, url, buf)
     92 	if err != nil {
     93 		log.Fatal(err)
     94 	}
     95 	if token != "" {
     96 		req.Header.Set("Authorization", "Bearer "+token)
     97 	}
     98 	req.Header.Set("User-Agent", firefox)
     99 	req.Header.Set("Content-Type", "application/json")
    100 
    101 	resp, err := http.DefaultClient.Do(req)
    102 	if err != nil {
    103 		log.Fatal(err)
    104 	}
    105 	fmt.Fprintln(os.Stderr, resp.Status)
    106 	io.Copy(os.Stdout, resp.Body)
    107 }