mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 22:32:46 +01:00
* Add gql client generation files * Update dependencies * Add stash-box client generation to the makefile * Move scraped scene object matchers to models * Add stash-box to scrape with dropdown * Add scrape scene from fingerprint in UI
123 lines
3 KiB
Go
123 lines
3 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/99designs/gqlgen/codegen/config"
|
|
"github.com/Yamashou/gqlgenc/client"
|
|
"github.com/Yamashou/gqlgenc/introspection"
|
|
"github.com/vektah/gqlparser/v2/ast"
|
|
"github.com/vektah/gqlparser/v2/validator"
|
|
"golang.org/x/xerrors"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type Config struct {
|
|
Model config.PackageConfig `yaml:"model,omitempty"`
|
|
Client config.PackageConfig `yaml:"client,omitempty"`
|
|
Models config.TypeMap `yaml:"models,omitempty"`
|
|
Endpoint EndPointConfig `yaml:"endpoint"`
|
|
Query []string `yaml:"query"`
|
|
|
|
// gqlgen config struct
|
|
GQLConfig *config.Config `yaml:"-"`
|
|
}
|
|
|
|
type EndPointConfig struct {
|
|
URL string `yaml:"url"`
|
|
Headers map[string]string `yaml:"headers,omitempty"`
|
|
}
|
|
|
|
func findCfg(fileName string) (string, error) {
|
|
dir, err := os.Getwd()
|
|
if err != nil {
|
|
return "", xerrors.Errorf("unable to get working dir to findCfg: %w", err)
|
|
}
|
|
|
|
cfg := findCfgInDir(dir, fileName)
|
|
|
|
if cfg == "" {
|
|
return "", os.ErrNotExist
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func findCfgInDir(dir, fileName string) string {
|
|
path := filepath.Join(dir, fileName)
|
|
|
|
return path
|
|
}
|
|
|
|
func LoadConfig(filename string) (*Config, error) {
|
|
var cfg Config
|
|
file, err := findCfg(filename)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("unable to get file path: %w", err)
|
|
}
|
|
b, err := ioutil.ReadFile(file)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("unable to read config: %w", err)
|
|
}
|
|
|
|
confContent := []byte(os.ExpandEnv(string(b)))
|
|
if err := yaml.UnmarshalStrict(confContent, &cfg); err != nil {
|
|
return nil, xerrors.Errorf("unable to parse config: %w", err)
|
|
}
|
|
|
|
cfg.GQLConfig = &config.Config{
|
|
Model: cfg.Model,
|
|
Models: cfg.Models,
|
|
// TODO: gqlgen must be set exec but client not used
|
|
Exec: config.PackageConfig{Filename: "generated.go"},
|
|
Directives: map[string]config.DirectiveConfig{},
|
|
}
|
|
|
|
if err := cfg.Client.Check(); err != nil {
|
|
return nil, xerrors.Errorf("config.exec: %w", err)
|
|
}
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
func (c *Config) LoadSchema(ctx context.Context) error {
|
|
addHeader := func(req *http.Request) {
|
|
for key, value := range c.Endpoint.Headers {
|
|
req.Header.Set(key, value)
|
|
}
|
|
}
|
|
gqlclient := client.NewClient(http.DefaultClient, c.Endpoint.URL, addHeader)
|
|
schema, err := LoadRemoteSchema(ctx, gqlclient)
|
|
if err != nil {
|
|
return xerrors.Errorf("load remote schema failed: %w", err)
|
|
}
|
|
if schema.Query == nil {
|
|
schema.Query = &ast.Definition{
|
|
Kind: ast.Object,
|
|
Name: "Query",
|
|
}
|
|
schema.Types["Query"] = schema.Query
|
|
}
|
|
|
|
c.GQLConfig.Schema = schema
|
|
|
|
return nil
|
|
}
|
|
|
|
func LoadRemoteSchema(ctx context.Context, gqlclient *client.Client) (*ast.Schema, error) {
|
|
var res introspection.Query
|
|
if err := gqlclient.Post(ctx, introspection.Introspection, &res, nil); err != nil {
|
|
return nil, xerrors.Errorf("introspection query failed: %w", err)
|
|
}
|
|
|
|
schema, err := validator.ValidateSchemaDocument(introspection.ParseIntrospectionQuery(res))
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("validation error: %w", err)
|
|
}
|
|
|
|
return schema, nil
|
|
}
|