diff --git a/client/client.go b/client/client.go deleted file mode 100644 index 0f14a383..00000000 --- a/client/client.go +++ /dev/null @@ -1,183 +0,0 @@ -package client - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - - "github.com/Yamashou/gqlgenc/graphqljson" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -// HTTPRequestOption represents the options applicable to the http client -type HTTPRequestOption func(req *http.Request) - -// Client is the http client wrapper -type Client struct { - Client *http.Client - BaseURL string - HTTPRequestOptions []HTTPRequestOption -} - -// Request represents an outgoing GraphQL request -type Request struct { - Query string `json:"query"` - Variables map[string]any `json:"variables,omitempty"` - OperationName string `json:"operationName,omitempty"` -} - -// NewClient creates a new http client wrapper -func NewClient(client *http.Client, baseURL string, options ...HTTPRequestOption) *Client { - return &Client{ - Client: client, - BaseURL: baseURL, - HTTPRequestOptions: options, - } -} - -func (c *Client) newRequest(ctx context.Context, operationName, query string, vars map[string]any, httpRequestOptions []HTTPRequestOption) (*http.Request, error) { - r := &Request{ - Query: query, - Variables: vars, - OperationName: operationName, - } - - requestBody, err := json.Marshal(r) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL, bytes.NewBuffer(requestBody)) - if err != nil { - return nil, fmt.Errorf("create request struct failed: %w", err) - } - - req.Header.Set("Content-Type", "application/json; charset=utf-8") - req.Header.Set("Accept", "application/json; charset=utf-8") - - for _, httpRequestOption := range c.HTTPRequestOptions { - httpRequestOption(req) - } - for _, httpRequestOption := range httpRequestOptions { - httpRequestOption(req) - } - - return req, nil -} - -// GqlErrorList is the struct of a standard graphql error response -type GqlErrorList struct { - Errors gqlerror.List `json:"errors"` -} - -func (e *GqlErrorList) Error() string { - return e.Errors.Error() -} - -// HTTPError is the error when a GqlErrorList cannot be parsed -type HTTPError struct { - Code int `json:"code"` - Message string `json:"message"` -} - -// ErrorResponse represent an handled error -type ErrorResponse struct { - // populated when http status code is not OK - NetworkError *HTTPError `json:"networkErrors"` - // populated when http status code is OK but the server returned at least one graphql error - GqlErrors *gqlerror.List `json:"graphqlErrors"` -} - -// HasErrors returns true when at least one error is declared -func (er *ErrorResponse) HasErrors() bool { - return er.NetworkError != nil || er.GqlErrors != nil -} - -func (er *ErrorResponse) Error() string { - content, err := json.Marshal(er) - if err != nil { - return err.Error() - } - - return string(content) -} - -// Post sends a http POST request to the graphql endpoint with the given query then unpacks -// the response into the given object. -func (c *Client) Post(ctx context.Context, operationName, query string, respData interface{}, vars map[string]interface{}, httpRequestOptions ...HTTPRequestOption) error { - req, err := c.newRequest(ctx, operationName, query, vars, httpRequestOptions) - if err != nil { - return fmt.Errorf("don't create request: %w", err) - } - - resp, err := c.Client.Do(req) - if err != nil { - return fmt.Errorf("request failed: %w", err) - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("failed to read response body: %w", err) - } - - return parseResponse(body, resp.StatusCode, respData) -} - -func parseResponse(body []byte, httpCode int, result interface{}) error { - errResponse := &ErrorResponse{} - isKOCode := httpCode < 200 || 299 < httpCode - if isKOCode { - errResponse.NetworkError = &HTTPError{ - Code: httpCode, - Message: fmt.Sprintf("Response body %s", string(body)), - } - } - - // some servers return a graphql error with a non OK http code, try anyway to parse the body - if err := unmarshal(body, result); err != nil { - if gqlErr, ok := err.(*GqlErrorList); ok { - errResponse.GqlErrors = &gqlErr.Errors - } else if !isKOCode { // if is KO code there is already the http error, this error should not be returned - return err - } - } - - if errResponse.HasErrors() { - return errResponse - } - - return nil -} - -// response is a GraphQL layer response from a handler. -type response struct { - Data json.RawMessage `json:"data"` - Errors json.RawMessage `json:"errors"` -} - -func unmarshal(data []byte, res interface{}) error { - resp := response{} - if err := json.Unmarshal(data, &resp); err != nil { - return fmt.Errorf("failed to decode data %s: %w", string(data), err) - } - - if resp.Errors != nil && len(resp.Errors) > 0 { - // try to parse standard graphql error - errors := &GqlErrorList{} - if e := json.Unmarshal(data, errors); e != nil { - return fmt.Errorf("faild to parse graphql errors. Response content %s - %w ", string(data), e) - } - - return errors - } - - if err := graphqljson.UnmarshalData(resp.Data, res); err != nil { - return fmt.Errorf("failed to decode data into response %s: %w", string(data), err) - } - - return nil -} diff --git a/client/client_test.go b/client/client_test.go deleted file mode 100644 index 1f130de8..00000000 --- a/client/client_test.go +++ /dev/null @@ -1,227 +0,0 @@ -package client - -import ( - "encoding/json" - "errors" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/gqlerror" -) - -const ( - qqlSingleErr = `{"errors":[{"path":["query GetUser","viewer","repositories","nsodes"],"extensions":{"code":"undefinedField","typeName":"RepositoryConnection","fieldName":"nsodes"},"locations":[{"line":6,"column":4}],"message":"Field 'nsodes' doesn't exist on type 'RepositoryConnection'"}]}` - gqlMultipleErr = `{"errors":[{"path":["query GetUser","viewer","repositories","nsodes"],"extensions":{"code":"undefinedField","typeName":"RepositoryConnection","fieldName":"nsodes"},"locations":[{"line":6,"column":4}],"message":"Field 'nsodes' doesn't exist on type 'RepositoryConnection'"},{"path":["query GetUser"],"extensions":{"code":"variableNotUsed","variableName":"languageFirst"},"locations":[{"line":1,"column":1}],"message":"Variable $languageFirst is declared by GetUser but not used"},{"path":["fragment LanguageFragment"],"extensions":{"code":"useAndDefineFragment","fragmentName":"LanguageFragment"},"locations":[{"line":18,"column":1}],"message":"Fragment LanguageFragment was defined, but not used"}]}` - gqlDataAndErr = `{"data": {"something": "some data"},"errors":[{"path":["query GetUser","viewer","repositories","nsodes"],"extensions":{"code":"undefinedField","typeName":"RepositoryConnection","fieldName":"nsodes"},"locations":[{"line":6,"column":4}],"message":"Field 'nsodes' doesn't exist on type 'RepositoryConnection'"}]}` - invalidJSON = "invalid" - validData = `{"data":{"something": "some data"}}` - withBadDataFormat = `{"data": "notAndObject"}` - withBadErrorsFormat = `{"errors": "bad"}` -) - -type fakeRes struct { - Something string `json:"something"` -} - -func TestUnmarshal(t *testing.T) { - t.Parallel() - t.Run("single error", func(t *testing.T) { - t.Parallel() - var path ast.Path - _ = json.Unmarshal([]byte(`["query GetUser","viewer","repositories","nsodes"]`), &path) - r := &fakeRes{} - err := unmarshal([]byte(qqlSingleErr), r) - expectedErr := &GqlErrorList{ - Errors: gqlerror.List{{ - Message: "Field 'nsodes' doesn't exist on type 'RepositoryConnection'", - Path: path, - Locations: []gqlerror.Location{{ - Line: 6, - Column: 4, - }}, - Extensions: map[string]interface{}{ - "code": "undefinedField", - "typeName": "RepositoryConnection", - "fieldName": "nsodes", - }, - }}, - } - require.Equal(t, err, expectedErr) - }) - - t.Run("multiple errors", func(t *testing.T) { - t.Parallel() - var path1 ast.Path - _ = json.Unmarshal([]byte(`["query GetUser","viewer","repositories","nsodes"]`), &path1) - var path2 ast.Path - _ = json.Unmarshal([]byte(`["query GetUser"]`), &path2) - var path3 ast.Path - _ = json.Unmarshal([]byte(`["fragment LanguageFragment"]`), &path3) - r := &fakeRes{} - err := unmarshal([]byte(gqlMultipleErr), r) - expectedErr := &GqlErrorList{ - Errors: gqlerror.List{ - { - Message: "Field 'nsodes' doesn't exist on type 'RepositoryConnection'", - Path: path1, - Locations: []gqlerror.Location{{ - Line: 6, - Column: 4, - }}, - Extensions: map[string]interface{}{ - "code": "undefinedField", - "typeName": "RepositoryConnection", - "fieldName": "nsodes", - }, - }, - { - Message: "Variable $languageFirst is declared by GetUser but not used", - Path: path2, - Locations: []gqlerror.Location{{ - Line: 1, - Column: 1, - }}, - Extensions: map[string]interface{}{ - "code": "variableNotUsed", - "variableName": "languageFirst", - }, - }, - { - Message: "Fragment LanguageFragment was defined, but not used", - Path: path3, - Locations: []gqlerror.Location{{ - Line: 18, - Column: 1, - }}, - Extensions: map[string]interface{}{ - "code": "useAndDefineFragment", - "fragmentName": "LanguageFragment", - }, - }, - }, - } - require.Equal(t, err, expectedErr) - }) - - t.Run("data and error", func(t *testing.T) { - t.Parallel() - var path ast.Path - _ = json.Unmarshal([]byte(`["query GetUser","viewer","repositories","nsodes"]`), &path) - r := &fakeRes{} - err := unmarshal([]byte(gqlDataAndErr), r) - expectedErr := &GqlErrorList{ - Errors: gqlerror.List{{ - Message: "Field 'nsodes' doesn't exist on type 'RepositoryConnection'", - Path: path, - Locations: []gqlerror.Location{{ - Line: 6, - Column: 4, - }}, - Extensions: map[string]interface{}{ - "code": "undefinedField", - "typeName": "RepositoryConnection", - "fieldName": "nsodes", - }, - }}, - } - require.Equal(t, err, expectedErr) - }) - - t.Run("invalid json", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := unmarshal([]byte(invalidJSON), r) - require.EqualError(t, err, "failed to decode data invalid: invalid character 'i' looking for beginning of value") - }) - - t.Run("valid data", func(t *testing.T) { - t.Parallel() - res := &fakeRes{} - err := unmarshal([]byte(validData), res) - require.NoError(t, err) - - expected := &fakeRes{ - Something: "some data", - } - require.Equal(t, res, expected) - }) - - t.Run("bad data format", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := unmarshal([]byte(withBadDataFormat), r) - require.EqualError(t, err, "failed to decode data into response {\"data\": \"notAndObject\"}: : : : : json: cannot unmarshal string into Go value of type client.fakeRes") - }) - - t.Run("bad data format", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := unmarshal([]byte(withBadErrorsFormat), r) - require.EqualError(t, err, "faild to parse graphql errors. Response content {\"errors\": \"bad\"} - json: cannot unmarshal string into Go struct field GqlErrorList.errors of type gqlerror.List ") - }) -} - -func TestParseResponse(t *testing.T) { - t.Parallel() - t.Run("single error", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := parseResponse([]byte(qqlSingleErr), 200, r) - - expectedType := &ErrorResponse{} - require.IsType(t, expectedType, err) - - gqlExpectedType := &gqlerror.List{} - require.IsType(t, gqlExpectedType, err.(*ErrorResponse).GqlErrors) - - require.Nil(t, err.(*ErrorResponse).NetworkError) - }) - - t.Run("bad error format", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := parseResponse([]byte(withBadErrorsFormat), 200, r) - - expectedType := fmt.Errorf("%w", errors.New("some")) - require.IsType(t, expectedType, err) - }) - - t.Run("network error with valid gql error response", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := parseResponse([]byte(qqlSingleErr), 400, r) - - expectedType := &ErrorResponse{} - require.IsType(t, expectedType, err) - - netExpectedType := &HTTPError{} - require.IsType(t, netExpectedType, err.(*ErrorResponse).NetworkError) - - gqlExpectedType := &gqlerror.List{} - require.IsType(t, gqlExpectedType, err.(*ErrorResponse).GqlErrors) - }) - - t.Run("network error with not valid gql error response", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := parseResponse([]byte(invalidJSON), 500, r) - - expectedType := &ErrorResponse{} - require.IsType(t, expectedType, err) - - netExpectedType := &HTTPError{} - require.IsType(t, netExpectedType, err.(*ErrorResponse).NetworkError) - - require.Nil(t, err.(*ErrorResponse).GqlErrors) - }) - - t.Run("no error", func(t *testing.T) { - t.Parallel() - r := &fakeRes{} - err := parseResponse([]byte(validData), 200, r) - - require.Nil(t, err) - }) -} diff --git a/clientgen/client.go b/clientgen/client.go deleted file mode 100644 index 1a73a520..00000000 --- a/clientgen/client.go +++ /dev/null @@ -1,76 +0,0 @@ -package clientgen - -import ( - "fmt" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/plugin" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -var _ plugin.ConfigMutator = &Plugin{} - -type Plugin struct { - queryFilePaths []string - Client config.PackageConfig - GenerateConfig *gqlgencConfig.GenerateConfig -} - -func New(queryFilePaths []string, client config.PackageConfig, generateConfig *gqlgencConfig.GenerateConfig) *Plugin { - return &Plugin{ - queryFilePaths: queryFilePaths, - Client: client, - GenerateConfig: generateConfig, - } -} - -func (p *Plugin) Name() string { - return "clientgen" -} - -func (p *Plugin) MutateConfig(cfg *config.Config) error { - querySources, err := LoadQuerySources(p.queryFilePaths) - if err != nil { - return fmt.Errorf("load query sources failed: %w", err) - } - - // 1. 全体のqueryDocumentを1度にparse - // 1. Parse document from source of query - queryDocument, err := ParseQueryDocuments(cfg.Schema, querySources, p.GenerateConfig) - if err != nil { - return fmt.Errorf(": %w", err) - } - - // 2. OperationごとのqueryDocumentを作成 - // 2. Separate documents for each operation - queryDocuments, err := QueryDocumentsByOperations(cfg.Schema, queryDocument.Operations) - if err != nil { - return fmt.Errorf("parse query document failed: %w", err) - } - - // 3. テンプレートと情報ソースを元にコード生成 - // 3. Generate code from template and document source - sourceGenerator := NewSourceGenerator(cfg, p.Client) - source := NewSource(cfg.Schema, queryDocument, sourceGenerator, p.GenerateConfig) - - fragments, err := source.Fragments() - if err != nil { - return fmt.Errorf("generating fragment failed: %w", err) - } - - operationResponses, err := source.OperationResponses() - if err != nil { - return fmt.Errorf("generating operation response failed: %w", err) - } - - operations, err := source.Operations(queryDocuments) - if err != nil { - return fmt.Errorf("generating operation failed: %w", err) - } - - if err := RenderTemplate(cfg, fragments, operations, operationResponses, p.GenerateConfig, p.Client); err != nil { - return fmt.Errorf("template failed: %w", err) - } - - return nil -} diff --git a/clientgen/query.go b/clientgen/query.go deleted file mode 100644 index 309798c3..00000000 --- a/clientgen/query.go +++ /dev/null @@ -1,121 +0,0 @@ -package clientgen - -import ( - "fmt" - "sort" - - "github.com/Yamashou/gqlgenc/config" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/parser" - "github.com/vektah/gqlparser/v2/validator" -) - -type merger struct { - document ast.QueryDocument - unamedIndex int - unamedPattern string -} - -func newMerger(generateConfig *config.GenerateConfig) *merger { - unamedPattern := "Unamed" - if generateConfig != nil && generateConfig.UnamedPattern != "" { - unamedPattern = generateConfig.UnamedPattern - } - - return &merger{unamedPattern: unamedPattern} -} - -func ParseQueryDocuments(schema *ast.Schema, querySources []*ast.Source, generateConfig *config.GenerateConfig) (*ast.QueryDocument, error) { - merger := newMerger(generateConfig) - for _, querySource := range querySources { - query, gqlerr := parser.ParseQuery(querySource) - if gqlerr != nil { - return nil, fmt.Errorf(": %w", gqlerr) - } - - merger.mergeQueryDocument(query) - } - - if errs := validator.Validate(schema, &merger.document); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - return &merger.document, nil -} - -func (m *merger) mergeQueryDocument(other *ast.QueryDocument) { - for _, operation := range other.Operations { - if operation.Name == "" { - // We increment first so unamed queries will start at 1 - m.unamedIndex++ - operation.Name = fmt.Sprintf("%s%d", m.unamedPattern, m.unamedIndex) - } - } - - m.document.Operations = append(m.document.Operations, other.Operations...) - m.document.Fragments = append(m.document.Fragments, other.Fragments...) -} - -func QueryDocumentsByOperations(schema *ast.Schema, operations ast.OperationList) ([]*ast.QueryDocument, error) { - queryDocuments := make([]*ast.QueryDocument, 0, len(operations)) - for _, operation := range operations { - fragments := fragmentsInOperationDefinition(operation) - - queryDocument := &ast.QueryDocument{ - Operations: ast.OperationList{operation}, - Fragments: fragments, - Position: nil, - } - - if errs := validator.Validate(schema, queryDocument); errs != nil { - return nil, fmt.Errorf(": %w", errs) - } - - queryDocuments = append(queryDocuments, queryDocument) - } - - return queryDocuments, nil -} - -func fragmentsInOperationDefinition(operation *ast.OperationDefinition) ast.FragmentDefinitionList { - fragments := fragmentsInOperationWalker(operation.SelectionSet) - uniqueFragments := fragmentsUnique(fragments) - // sort Fragments to ensure a deterministic output - sort.Slice(uniqueFragments, func(i, j int) bool { return uniqueFragments[i].Name < uniqueFragments[j].Name }) - - return uniqueFragments -} - -func fragmentsUnique(fragments ast.FragmentDefinitionList) ast.FragmentDefinitionList { - uniqueMap := make(map[string]*ast.FragmentDefinition) - for _, fragment := range fragments { - uniqueMap[fragment.Name] = fragment - } - - uniqueFragments := make(ast.FragmentDefinitionList, 0, len(uniqueMap)) - for _, fragment := range uniqueMap { - uniqueFragments = append(uniqueFragments, fragment) - } - - return uniqueFragments -} - -func fragmentsInOperationWalker(selectionSet ast.SelectionSet) ast.FragmentDefinitionList { - var fragments ast.FragmentDefinitionList - for _, selection := range selectionSet { - var selectionSet ast.SelectionSet - switch selection := selection.(type) { - case *ast.Field: - selectionSet = selection.SelectionSet - case *ast.InlineFragment: - selectionSet = selection.SelectionSet - case *ast.FragmentSpread: - fragments = append(fragments, selection.Definition) - selectionSet = selection.Definition.SelectionSet - } - - fragments = append(fragments, fragmentsInOperationWalker(selectionSet)...) - } - - return fragments -} diff --git a/clientgen/query_source.go b/clientgen/query_source.go deleted file mode 100644 index ed7b5a1d..00000000 --- a/clientgen/query_source.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright (c) 2020 gqlgen authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package clientgen - -import ( - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/v2/ast" -) - -var path2regex = strings.NewReplacer( - `.`, `\.`, - `*`, `.+`, - `\`, `[\\/]`, - `/`, `[\\/]`, -) - -// LoadQuerySourceなどは、gqlgenがLoadConfigでSchemaを読み込む時の実装をコピーして一部修正している -// **/test/*.graphqlなどに対応している -func LoadQuerySources(queryFileNames []string) ([]*ast.Source, error) { - var noGlobQueryFileNames config.StringList - - var err error - preGlobbing := queryFileNames - for _, f := range preGlobbing { - var matches []string - - // for ** we want to override default globbing patterns and walk all - // subdirectories to match schema files. - if strings.Contains(f, "**") { - pathParts := strings.SplitN(f, "**", 2) - rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`) - // turn the rest of the glob into a regex, anchored only at the end because ** allows - // for any number of dirs in between and walk will let us match against the full path name - globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`) - - if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) { - matches = append(matches, path) - } - - return nil - }); err != nil { - return nil, fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) - } - } else { - matches, err = filepath.Glob(f) - if err != nil { - return nil, fmt.Errorf("failed to glob schema filename %v: %w", f, err) - } - } - - for _, m := range matches { - if noGlobQueryFileNames.Has(m) { - continue - } - - noGlobQueryFileNames = append(noGlobQueryFileNames, m) - } - } - - querySources := make([]*ast.Source, 0, len(noGlobQueryFileNames)) - for _, filename := range noGlobQueryFileNames { - filename = filepath.ToSlash(filename) - var err error - var schemaRaw []byte - schemaRaw, err = os.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("unable to open schema: %w", err) - } - - querySources = append(querySources, &ast.Source{Name: filename, Input: string(schemaRaw)}) - } - - return querySources, nil -} diff --git a/clientgen/source.go b/clientgen/source.go deleted file mode 100644 index 84f11cd5..00000000 --- a/clientgen/source.go +++ /dev/null @@ -1,190 +0,0 @@ -package clientgen - -import ( - "bytes" - "fmt" - "go/types" - - "github.com/99designs/gqlgen/codegen/templates" - "github.com/Yamashou/gqlgenc/config" - "github.com/vektah/gqlparser/v2/ast" - "github.com/vektah/gqlparser/v2/formatter" -) - -type Source struct { - schema *ast.Schema - queryDocument *ast.QueryDocument - sourceGenerator *SourceGenerator - generateConfig *config.GenerateConfig -} - -func NewSource(schema *ast.Schema, queryDocument *ast.QueryDocument, sourceGenerator *SourceGenerator, generateConfig *config.GenerateConfig) *Source { - return &Source{ - schema: schema, - queryDocument: queryDocument, - sourceGenerator: sourceGenerator, - generateConfig: generateConfig, - } -} - -type Fragment struct { - Name string - Type types.Type -} - -func (s *Source) Fragments() ([]*Fragment, error) { - fragments := make([]*Fragment, 0, len(s.queryDocument.Fragments)) - for _, fragment := range s.queryDocument.Fragments { - responseFields := s.sourceGenerator.NewResponseFields(fragment.SelectionSet) - if s.sourceGenerator.cfg.Models.Exists(fragment.Name) { - return nil, fmt.Errorf("%s is duplicated", fragment.Name) - } - - fragment := &Fragment{ - Name: fragment.Name, - Type: responseFields.StructType(), - } - - fragments = append(fragments, fragment) - } - - for _, fragment := range fragments { - name := fragment.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return fragments, nil -} - -type Operation struct { - Name string - ResponseStructName string - Operation string - Args []*Argument - VariableDefinitions ast.VariableDefinitionList -} - -func NewOperation(operation *ast.OperationDefinition, queryDocument *ast.QueryDocument, args []*Argument, generateConfig *config.GenerateConfig) *Operation { - return &Operation{ - Name: operation.Name, - ResponseStructName: getResponseStructName(operation, generateConfig), - Operation: queryString(queryDocument), - Args: args, - VariableDefinitions: operation.VariableDefinitions, - } -} - -func (s *Source) Operations(queryDocuments []*ast.QueryDocument) ([]*Operation, error) { - operations := make([]*Operation, 0, len(s.queryDocument.Operations)) - - operationNames := make(map[string]struct{}) - - queryDocumentsMap := queryDocumentMapByOperationName(queryDocuments) - operationArgsMap := s.operationArgsMapByOperationName() - for _, operation := range s.queryDocument.Operations { - queryDocument := queryDocumentsMap[operation.Name] - - _, exist := operationNames[templates.ToGo(operation.Name)] - if exist { - return nil, fmt.Errorf("duplicate operation: %s", operation.Name) - } - operationNames[templates.ToGo(operation.Name)] = struct{}{} - - args := operationArgsMap[operation.Name] - operations = append(operations, NewOperation( - operation, - queryDocument, - args, - s.generateConfig, - )) - } - - return operations, nil -} - -func (s *Source) operationArgsMapByOperationName() map[string][]*Argument { - operationArgsMap := make(map[string][]*Argument) - for _, operation := range s.queryDocument.Operations { - operationArgsMap[operation.Name] = s.sourceGenerator.OperationArguments(operation.VariableDefinitions) - } - - return operationArgsMap -} - -func queryDocumentMapByOperationName(queryDocuments []*ast.QueryDocument) map[string]*ast.QueryDocument { - queryDocumentMap := make(map[string]*ast.QueryDocument) - for _, queryDocument := range queryDocuments { - operation := queryDocument.Operations[0] - queryDocumentMap[operation.Name] = queryDocument - } - - return queryDocumentMap -} - -func queryString(queryDocument *ast.QueryDocument) string { - var buf bytes.Buffer - astFormatter := formatter.NewFormatter(&buf) - astFormatter.FormatQueryDocument(queryDocument) - - return buf.String() -} - -type OperationResponse struct { - Name string - Type types.Type -} - -func (s *Source) OperationResponses() ([]*OperationResponse, error) { - operationResponse := make([]*OperationResponse, 0, len(s.queryDocument.Operations)) - for _, operation := range s.queryDocument.Operations { - responseFields := s.sourceGenerator.NewResponseFields(operation.SelectionSet) - name := getResponseStructName(operation, s.generateConfig) - if s.sourceGenerator.cfg.Models.Exists(name) { - return nil, fmt.Errorf("%s is duplicated", name) - } - operationResponse = append(operationResponse, &OperationResponse{ - Name: name, - Type: responseFields.StructType(), - }) - } - - for _, operationResponse := range operationResponse { - name := operationResponse.Name - s.sourceGenerator.cfg.Models.Add( - name, - fmt.Sprintf("%s.%s", s.sourceGenerator.client.Pkg(), templates.ToGo(name)), - ) - } - - return operationResponse, nil -} - -func getResponseStructName(operation *ast.OperationDefinition, generateConfig *config.GenerateConfig) string { - name := operation.Name - if generateConfig != nil { - if generateConfig.Prefix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Mutation, name) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", generateConfig.Prefix.Query, name) - } - } - - if generateConfig.Suffix != nil { - if operation.Operation == ast.Mutation { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Mutation) - } - - if operation.Operation == ast.Query { - name = fmt.Sprintf("%s%s", name, generateConfig.Suffix.Query) - } - } - } - - return name -} diff --git a/clientgen/source_generator.go b/clientgen/source_generator.go deleted file mode 100644 index a43308a3..00000000 --- a/clientgen/source_generator.go +++ /dev/null @@ -1,231 +0,0 @@ -package clientgen - -import ( - "fmt" - "go/types" - "strings" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - "github.com/vektah/gqlparser/v2/ast" -) - -type Argument struct { - Variable string - Type types.Type -} - -type ResponseField struct { - Name string - IsFragmentSpread bool - IsInlineFragment bool - Type types.Type - Tags []string - ResponseFields ResponseFieldList -} - -type ResponseFieldList []*ResponseField - -func (rs ResponseFieldList) StructType() *types.Struct { - vars := make([]*types.Var, 0) - structTags := make([]string, 0) - for _, filed := range rs { - // クエリーのフィールドの子階層がFragmentの場合、このフィールドにそのFragmentの型を追加する - if filed.IsFragmentSpread { - typ, ok := filed.ResponseFields.StructType().Underlying().(*types.Struct) - if !ok { - continue - } - for j := 0; j < typ.NumFields(); j++ { - vars = append(vars, typ.Field(j)) - structTags = append(structTags, typ.Tag(j)) - } - } else { - vars = append(vars, types.NewVar(0, nil, templates.ToGo(filed.Name), filed.Type)) - structTags = append(structTags, strings.Join(filed.Tags, " ")) - } - } - - return types.NewStruct(vars, structTags) -} - -func (rs ResponseFieldList) IsFragment() bool { - if len(rs) != 1 { - return false - } - - return rs[0].IsInlineFragment || rs[0].IsFragmentSpread -} - -func (rs ResponseFieldList) IsBasicType() bool { - return len(rs) == 0 -} - -func (rs ResponseFieldList) IsStructType() bool { - return len(rs) > 0 && !rs.IsFragment() -} - -type SourceGenerator struct { - cfg *config.Config - binder *config.Binder - client config.PackageConfig -} - -func NewSourceGenerator(cfg *config.Config, client config.PackageConfig) *SourceGenerator { - return &SourceGenerator{ - cfg: cfg, - binder: cfg.NewBinder(), - client: client, - } -} - -func (r *SourceGenerator) NewResponseFields(selectionSet ast.SelectionSet) ResponseFieldList { - responseFields := make(ResponseFieldList, 0, len(selectionSet)) - for _, selection := range selectionSet { - responseFields = append(responseFields, r.NewResponseField(selection)) - } - - return responseFields -} - -func (r *SourceGenerator) NewResponseFieldsByDefinition(definition *ast.Definition) (ResponseFieldList, error) { - fields := make(ResponseFieldList, 0, len(definition.Fields)) - for _, field := range definition.Fields { - if field.Type.Name() == "__Schema" || field.Type.Name() == "__Type" { - continue - } - - var typ types.Type - if field.Type.Name() == "Query" || field.Type.Name() == "Mutation" { - var baseType types.Type - baseType, err := r.binder.FindType(r.client.Pkg().Path(), field.Type.Name()) - if err != nil { - if !strings.Contains(err.Error(), "unable to find type") { - return nil, fmt.Errorf("not found type: %w", err) - } - - // create new type - baseType = types.NewPointer(types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(field.Type.Name()), nil), - nil, - nil, - )) - } - - // for recursive struct field in go - typ = types.NewPointer(baseType) - } else { - baseType, err := r.binder.FindTypeFromName(r.cfg.Models[field.Type.Name()].Model[0]) - if err != nil { - return nil, fmt.Errorf("not found type: %w", err) - } - - typ = r.binder.CopyModifiersFromAst(field.Type, baseType) - } - - tags := []string{ - fmt.Sprintf(`json:"%s"`, field.Name), - fmt.Sprintf(`graphql:"%s"`, field.Name), - } - - fields = append(fields, &ResponseField{ - Name: field.Name, - Type: typ, - Tags: tags, - }) - } - - return fields, nil -} - -func (r *SourceGenerator) NewResponseField(selection ast.Selection) *ResponseField { - switch selection := selection.(type) { - case *ast.Field: - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet) - - var baseType types.Type - switch { - case fieldsResponseFields.IsBasicType(): - baseType = r.Type(selection.Definition.Type.Name()) - case fieldsResponseFields.IsFragment(): - // 子フィールドがFragmentの場合はこのFragmentがフィールドの型になる - // if a child field is fragment, this field type became fragment. - baseType = fieldsResponseFields[0].Type - case fieldsResponseFields.IsStructType(): - baseType = fieldsResponseFields.StructType() - default: - // ここにきたらバグ - // here is bug - panic("not match type") - } - - // GraphQLの定義がオプショナルのはtypeのポインタ型が返り、配列の定義場合はポインタのスライスの型になって返ってきます - // return pointer type then optional type or slice pointer then slice type of definition in GraphQL. - typ := r.binder.CopyModifiersFromAst(selection.Definition.Type, baseType) - - tags := []string{ - fmt.Sprintf(`json:"%s"`, selection.Alias), - fmt.Sprintf(`graphql:"%s"`, selection.Alias), - } - - return &ResponseField{ - Name: selection.Alias, - Type: typ, - Tags: tags, - ResponseFields: fieldsResponseFields, - } - - case *ast.FragmentSpread: - // この構造体はテンプレート側で使われることはなく、ast.FieldでFragment判定するために使用する - fieldsResponseFields := r.NewResponseFields(selection.Definition.SelectionSet) - typ := types.NewNamed( - types.NewTypeName(0, r.client.Pkg(), templates.ToGo(selection.Name), nil), - fieldsResponseFields.StructType(), - nil, - ) - - return &ResponseField{ - Name: selection.Name, - Type: typ, - IsFragmentSpread: true, - ResponseFields: fieldsResponseFields, - } - - case *ast.InlineFragment: - // InlineFragmentは子要素をそのままstructとしてもつので、ここで、構造体の型を作成します - fieldsResponseFields := r.NewResponseFields(selection.SelectionSet) - - return &ResponseField{ - Name: selection.TypeCondition, - Type: fieldsResponseFields.StructType(), - IsInlineFragment: true, - Tags: []string{fmt.Sprintf(`graphql:"... on %s"`, selection.TypeCondition)}, - ResponseFields: fieldsResponseFields, - } - } - - panic("unexpected selection type") -} - -func (r *SourceGenerator) OperationArguments(variableDefinitions ast.VariableDefinitionList) []*Argument { - argumentTypes := make([]*Argument, 0, len(variableDefinitions)) - for _, v := range variableDefinitions { - argumentTypes = append(argumentTypes, &Argument{ - Variable: v.Variable, - Type: r.binder.CopyModifiersFromAst(v.Type, r.Type(v.Type.Name())), - }) - } - - return argumentTypes -} - -// Typeの引数に渡すtypeNameは解析した結果からselectionなどから求めた型の名前を渡さなければいけない -func (r *SourceGenerator) Type(typeName string) types.Type { - goType, err := r.binder.FindTypeFromName(r.cfg.Models[typeName].Model[0]) - if err != nil { - // 実装として正しいtypeNameを渡していれば必ず見つかるはずなのでpanic - panic(fmt.Sprintf("%+v", err)) - } - - return goType -} diff --git a/clientgen/template.go b/clientgen/template.go deleted file mode 100644 index 6bf5e67d..00000000 --- a/clientgen/template.go +++ /dev/null @@ -1,40 +0,0 @@ -package clientgen - -import ( - _ "embed" // blank import to embed the template - "fmt" - "sort" - - "github.com/99designs/gqlgen/codegen/config" - "github.com/99designs/gqlgen/codegen/templates" - gqlgencConfig "github.com/Yamashou/gqlgenc/config" -) - -//go:embed template.gotpl -var template string - -func RenderTemplate(cfg *config.Config, fragments []*Fragment, operations []*Operation, operationResponses []*OperationResponse, generateCfg *gqlgencConfig.GenerateConfig, client config.PackageConfig) error { - // sort to ensure a deterministic output - sort.Slice(fragments, func(i, j int) bool { return fragments[i].Name < fragments[j].Name }) - sort.Slice(operations, func(i, j int) bool { return operations[i].Name < operations[j].Name }) - sort.Slice(operationResponses, func(i, j int) bool { return operationResponses[i].Name < operationResponses[j].Name }) - - if err := templates.Render(templates.Options{ - PackageName: client.Package, - Filename: client.Filename, - Template: template, - Data: map[string]interface{}{ - "Fragment": fragments, - "Operation": operations, - "OperationResponse": operationResponses, - "GenerateClient": generateCfg.ShouldGenerateClient(), - "ClientInterfaceName": generateCfg.GetClientInterfaceName(), - }, - Packages: cfg.Packages, - PackageDoc: "// Code generated by github.com/Yamashou/gqlgenc, DO NOT EDIT.\n", - }); err != nil { - return fmt.Errorf("%s generating failed: %w", client.Filename, err) - } - - return nil -} diff --git a/clientgen/template.gotpl b/clientgen/template.gotpl deleted file mode 100644 index d9b30717..00000000 --- a/clientgen/template.gotpl +++ /dev/null @@ -1,68 +0,0 @@ -{{- if .GenerateClient }} - {{ reserveImport "bytes" }} - {{ reserveImport "context" }} - {{ reserveImport "encoding/json" }} - {{ reserveImport "fmt" }} - {{ reserveImport "io" }} - {{ reserveImport "net/http" }} - {{ reserveImport "net/url" }} - {{ reserveImport "path" }} - {{ reserveImport "time" }} - - - {{ reserveImport "github.com/Yamashou/gqlgenc/graphqljson" }} - {{ reserveImport "github.com/Yamashou/gqlgenc/client" }} - - {{- if .ClientInterfaceName }} - type {{ .ClientInterfaceName }} interface { - {{- range $model := .Operation }} - {{ $model.Name | go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, httpRequestOptions ...client.HTTPRequestOption) (*{{ $model.ResponseStructName | go }}, error) - {{- end }} - } - {{- end }} - - type Client struct { - Client *client.Client - } - - {{- if .ClientInterfaceName }} - func NewClient(cli *http.Client, baseURL string, options ...client.HTTPRequestOption) {{ .ClientInterfaceName }} { - return &Client{Client: client.NewClient(cli, baseURL, options...)} - } - {{- else }} - func NewClient(cli *http.Client, baseURL string, options ...client.HTTPRequestOption) *Client { - return &Client{Client: client.NewClient(cli, baseURL, options...)} - } - {{- end }} -{{- end }} - -{{- range $name, $element := .Fragment }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - -{{- range $name, $element := .OperationResponse }} - type {{ .Name | go }} {{ .Type | ref }} -{{- end }} - - - -{{- range $model := .Operation}} - const {{ $model.Name|go }}Document = `{{ $model.Operation }}` - - {{- if $.GenerateClient }} - func (c *Client) {{ $model.Name | go }} (ctx context.Context{{- range $arg := .Args }}, {{ $arg.Variable | goPrivate }} {{ $arg.Type | ref }} {{- end }}, httpRequestOptions ...client.HTTPRequestOption) (*{{ $model.ResponseStructName | go }}, error) { - vars := map[string]interface{}{ - {{- range $args := .VariableDefinitions}} - "{{ $args.Variable }}": {{ $args.Variable | goPrivate }}, - {{- end }} - } - - var res {{ $model.ResponseStructName | go }} - if err := c.Client.Post(ctx, "{{ $model.Name }}", {{ $model.Name|go }}Document, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil - } - {{- end}} -{{- end}} diff --git a/config/generate_config.go b/config/generate_config.go index b18d97f1..bf7441f5 100644 --- a/config/generate_config.go +++ b/config/generate_config.go @@ -11,6 +11,7 @@ type GenerateConfig struct { Client *bool `yaml:"client,omitempty"` ClientInterfaceName *string `yaml:"clientInterfaceName,omitempty"` OmitEmptyTypes *bool `yaml:"omitEmptyTypes,omitempty"` + // Deprecated: not working because v1 is deleted. Must use ClientV2 // if true, used client v2 in generate code ClientV2 bool `yaml:"clientV2,omitempty"` } diff --git a/example/annict/.gqlgenc.yml b/example/annict/.gqlgenc.yml deleted file mode 100644 index d3266a93..00000000 --- a/example/annict/.gqlgenc.yml +++ /dev/null @@ -1,20 +0,0 @@ -model: - filename: ./gen/models_gen.go -client: - filename: ./gen/client.go -models: - Int: - model: github.com/99designs/gqlgen/graphql.Int64 - DateTime: - model: github.com/99designs/gqlgen/graphql.Time -endpoint: - url: https://api.annict.com/graphql - headers: - Authorization: "Bearer ${ANNICT_KEY}" -query: - - "./query/*.graphql" -generate: - suffix: - mutation: Payload - prefix: - mutation: Hoge diff --git a/example/annict/gen/client.go b/example/annict/gen/client.go deleted file mode 100644 index 6f260675..00000000 --- a/example/annict/gen/client.go +++ /dev/null @@ -1,487 +0,0 @@ -// Code generated by github.com/Yamashou/gqlgenc, DO NOT EDIT. - -package gen - -import ( - "context" - "net/http" - "time" - - "github.com/Yamashou/gqlgenc/client" -) - -type Client struct { - Client *client.Client -} - -func NewClient(cli *http.Client, baseURL string, options ...client.HTTPRequestOption) *Client { - return &Client{Client: client.NewClient(cli, baseURL, options...)} -} - -type Query struct { - Node Node "json:\"node\" graphql:\"node\"" - Nodes []Node "json:\"nodes\" graphql:\"nodes\"" - SearchCharacters *CharacterConnection "json:\"searchCharacters\" graphql:\"searchCharacters\"" - SearchEpisodes *EpisodeConnection "json:\"searchEpisodes\" graphql:\"searchEpisodes\"" - SearchOrganizations *OrganizationConnection "json:\"searchOrganizations\" graphql:\"searchOrganizations\"" - SearchPeople *PersonConnection "json:\"searchPeople\" graphql:\"searchPeople\"" - SearchWorks *WorkConnection "json:\"searchWorks\" graphql:\"searchWorks\"" - User *User "json:\"user\" graphql:\"user\"" - Viewer *User "json:\"viewer\" graphql:\"viewer\"" -} - -type Mutation struct { - CreateRecord *CreateRecordPayload "json:\"createRecord\" graphql:\"createRecord\"" - CreateReview *CreateReviewPayload "json:\"createReview\" graphql:\"createReview\"" - DeleteRecord *DeleteRecordPayload "json:\"deleteRecord\" graphql:\"deleteRecord\"" - DeleteReview *DeleteReviewPayload "json:\"deleteReview\" graphql:\"deleteReview\"" - UpdateRecord *UpdateRecordPayload "json:\"updateRecord\" graphql:\"updateRecord\"" - UpdateReview *UpdateReviewPayload "json:\"updateReview\" graphql:\"updateReview\"" - UpdateStatus *UpdateStatusPayload "json:\"updateStatus\" graphql:\"updateStatus\"" -} - -type ViewerFragment struct { - AvatarURL *string "json:\"avatar_url\" graphql:\"avatar_url\"" - RecordsCount int64 "json:\"recordsCount\" graphql:\"recordsCount\"" - WannaWatchCount int64 "json:\"wannaWatchCount\" graphql:\"wannaWatchCount\"" - WatchingCount int64 "json:\"watchingCount\" graphql:\"watchingCount\"" - WatchedCount int64 "json:\"watchedCount\" graphql:\"watchedCount\"" -} - -type WorkFragment struct { - ID string "json:\"id\" graphql:\"id\"" - Title string "json:\"title\" graphql:\"title\"" - AnnictID int64 "json:\"annict_id\" graphql:\"annict_id\"" - SeasonYear *int64 "json:\"seasonYear\" graphql:\"seasonYear\"" - SeasonName *SeasonName "json:\"seasonName\" graphql:\"seasonName\"" - EpisodesCount int64 "json:\"episodesCount\" graphql:\"episodesCount\"" - OfficialSiteURL *string "json:\"officialSiteUrl\" graphql:\"officialSiteUrl\"" - WikipediaURL *string "json:\"wikipediaUrl\" graphql:\"wikipediaUrl\"" - ViewerStatusState *StatusState "json:\"viewerStatusState\" graphql:\"viewerStatusState\"" - Episodes *struct { - Nodes []*struct { - ID string "json:\"id\" graphql:\"id\"" - AnnictID int64 "json:\"annictId\" graphql:\"annictId\"" - Title *string "json:\"title\" graphql:\"title\"" - SortNumber int64 "json:\"sortNumber\" graphql:\"sortNumber\"" - } "json:\"nodes\" graphql:\"nodes\"" - } "json:\"episodes\" graphql:\"episodes\"" -} - -type HogeCreateRecordMutationPayload struct { - CreateRecord *struct { - ClientMutationID *string "json:\"clientMutationId\" graphql:\"clientMutationId\"" - } "json:\"createRecord\" graphql:\"createRecord\"" -} - -type HogeUpdateStatusMutationPayload struct { - UpdateStatus *struct { - ClientMutationID *string "json:\"clientMutationId\" graphql:\"clientMutationId\"" - } "json:\"updateStatus\" graphql:\"updateStatus\"" -} - -type HogeUpdateWorkStatusPayload struct { - UpdateStatus *struct { - ClientMutationID *string "json:\"clientMutationId\" graphql:\"clientMutationId\"" - } "json:\"updateStatus\" graphql:\"updateStatus\"" -} - -type GetProfile struct { - Viewer *ViewerFragment "json:\"viewer\" graphql:\"viewer\"" -} - -type ListWorks struct { - Viewer *struct { - Works *struct { - Edges []*struct { - Cursor string "json:\"cursor\" graphql:\"cursor\"" - Node *WorkFragment "json:\"node\" graphql:\"node\"" - } "json:\"edges\" graphql:\"edges\"" - } "json:\"works\" graphql:\"works\"" - } "json:\"viewer\" graphql:\"viewer\"" -} - -type ListRecords struct { - Viewer *struct { - Records *struct { - Edges []*struct { - Node *struct { - Work WorkFragment "json:\"work\" graphql:\"work\"" - Episode struct { - SortNumber int64 "json:\"sortNumber\" graphql:\"sortNumber\"" - } "json:\"episode\" graphql:\"episode\"" - CreatedAt time.Time "json:\"createdAt\" graphql:\"createdAt\"" - } "json:\"node\" graphql:\"node\"" - } "json:\"edges\" graphql:\"edges\"" - } "json:\"records\" graphql:\"records\"" - } "json:\"viewer\" graphql:\"viewer\"" -} - -type ListNextEpisodes struct { - Viewer *struct { - Records *struct { - Edges []*struct { - Node *struct { - Episode struct { - NextEpisode *struct { - ID string "json:\"id\" graphql:\"id\"" - Number *int64 "json:\"number\" graphql:\"number\"" - NumberText *string "json:\"numberText\" graphql:\"numberText\"" - Title *string "json:\"title\" graphql:\"title\"" - NextEpisode *struct { - ID string "json:\"id\" graphql:\"id\"" - } "json:\"nextEpisode\" graphql:\"nextEpisode\"" - } "json:\"nextEpisode\" graphql:\"nextEpisode\"" - Work struct { - ID string "json:\"id\" graphql:\"id\"" - Title string "json:\"title\" graphql:\"title\"" - } "json:\"work\" graphql:\"work\"" - } "json:\"episode\" graphql:\"episode\"" - } "json:\"node\" graphql:\"node\"" - } "json:\"edges\" graphql:\"edges\"" - } "json:\"records\" graphql:\"records\"" - } "json:\"viewer\" graphql:\"viewer\"" -} - -type GetWork struct { - SearchWorks *struct { - Nodes []*WorkFragment "json:\"nodes\" graphql:\"nodes\"" - } "json:\"searchWorks\" graphql:\"searchWorks\"" -} - -type SearchWorks struct { - SearchWorks *struct { - Nodes []*struct { - ID string "json:\"id\" graphql:\"id\"" - Title string "json:\"title\" graphql:\"title\"" - AnnictID int64 "json:\"annict_id\" graphql:\"annict_id\"" - SeasonYear *int64 "json:\"seasonYear\" graphql:\"seasonYear\"" - SeasonName *SeasonName "json:\"seasonName\" graphql:\"seasonName\"" - EpisodesCount int64 "json:\"episodesCount\" graphql:\"episodesCount\"" - OfficialSiteURL *string "json:\"officialSiteUrl\" graphql:\"officialSiteUrl\"" - WikipediaURL *string "json:\"wikipediaUrl\" graphql:\"wikipediaUrl\"" - ViewerStatusState *StatusState "json:\"viewerStatusState\" graphql:\"viewerStatusState\"" - Episodes *struct { - Nodes []*struct { - ID string "json:\"id\" graphql:\"id\"" - AnnictID int64 "json:\"annictId\" graphql:\"annictId\"" - Title *string "json:\"title\" graphql:\"title\"" - SortNumber int64 "json:\"sortNumber\" graphql:\"sortNumber\"" - } "json:\"nodes\" graphql:\"nodes\"" - } "json:\"episodes\" graphql:\"episodes\"" - Work struct { - Image *struct { - RecommendedImageURL *string "json:\"recommendedImageUrl\" graphql:\"recommendedImageUrl\"" - } "json:\"image\" graphql:\"image\"" - } "graphql:\"... on Work\"" - } "json:\"nodes\" graphql:\"nodes\"" - } "json:\"searchWorks\" graphql:\"searchWorks\"" -} - -const CreateRecordMutationQuery = `mutation CreateRecordMutation ($episodeId: ID!) { - createRecord(input: {episodeId:$episodeId}) { - clientMutationId - } -} -` - -func (c *Client) CreateRecordMutation(ctx context.Context, episodeID string, httpRequestOptions ...client.HTTPRequestOption) (*HogeCreateRecordMutationPayload, error) { - vars := map[string]interface{}{ - "episodeId": episodeID, - } - - var res HogeCreateRecordMutationPayload - if err := c.Client.Post(ctx, "CreateRecordMutation", CreateRecordMutationQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const UpdateStatusMutationQuery = `mutation UpdateStatusMutation ($state: StatusState!, $workId: ID!) { - updateStatus(input: {state:$state,workId:$workId}) { - clientMutationId - } -} -` - -func (c *Client) UpdateStatusMutation(ctx context.Context, state StatusState, workID string, httpRequestOptions ...client.HTTPRequestOption) (*HogeUpdateStatusMutationPayload, error) { - vars := map[string]interface{}{ - "state": state, - "workId": workID, - } - - var res HogeUpdateStatusMutationPayload - if err := c.Client.Post(ctx, "UpdateStatusMutation", UpdateStatusMutationQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const UpdateWorkStatusQuery = `mutation UpdateWorkStatus ($workId: ID!) { - updateStatus(input: {state:WATCHING,workId:$workId}) { - clientMutationId - } -} -` - -func (c *Client) UpdateWorkStatus(ctx context.Context, workID string, httpRequestOptions ...client.HTTPRequestOption) (*HogeUpdateWorkStatusPayload, error) { - vars := map[string]interface{}{ - "workId": workID, - } - - var res HogeUpdateWorkStatusPayload - if err := c.Client.Post(ctx, "UpdateWorkStatus", UpdateWorkStatusQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const GetProfileQuery = `query GetProfile { - viewer { - ... ViewerFragment - } -} -fragment ViewerFragment on User { - avatar_url: avatarUrl - recordsCount - wannaWatchCount - watchingCount - watchedCount -} -` - -func (c *Client) GetProfile(ctx context.Context, httpRequestOptions ...client.HTTPRequestOption) (*GetProfile, error) { - vars := map[string]interface{}{} - - var res GetProfile - if err := c.Client.Post(ctx, "GetProfile", GetProfileQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const ListWorksQuery = `query ListWorks ($state: StatusState, $after: String, $n: Int!) { - viewer { - works(state: $state, after: $after, first: $n, orderBy: {direction:DESC,field:SEASON}) { - edges { - cursor - node { - ... WorkFragment - } - } - } - } -} -fragment WorkFragment on Work { - id - title - annict_id: annictId - seasonYear - seasonName - episodesCount - officialSiteUrl - wikipediaUrl - viewerStatusState - episodes(orderBy: {direction:ASC,field:SORT_NUMBER}) { - nodes { - id - annictId - title - sortNumber - } - } -} -` - -func (c *Client) ListWorks(ctx context.Context, state *StatusState, after *string, n int64, httpRequestOptions ...client.HTTPRequestOption) (*ListWorks, error) { - vars := map[string]interface{}{ - "state": state, - "after": after, - "n": n, - } - - var res ListWorks - if err := c.Client.Post(ctx, "ListWorks", ListWorksQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const ListRecordsQuery = `query ListRecords { - viewer { - records { - edges { - node { - work { - ... WorkFragment - } - episode { - sortNumber - } - createdAt - } - } - } - } -} -fragment WorkFragment on Work { - id - title - annict_id: annictId - seasonYear - seasonName - episodesCount - officialSiteUrl - wikipediaUrl - viewerStatusState - episodes(orderBy: {direction:ASC,field:SORT_NUMBER}) { - nodes { - id - annictId - title - sortNumber - } - } -} -` - -func (c *Client) ListRecords(ctx context.Context, httpRequestOptions ...client.HTTPRequestOption) (*ListRecords, error) { - vars := map[string]interface{}{} - - var res ListRecords - if err := c.Client.Post(ctx, "ListRecords", ListRecordsQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const ListNextEpisodesQuery = `query ListNextEpisodes { - viewer { - records { - edges { - node { - episode { - nextEpisode { - id - number - numberText - title - nextEpisode { - id - } - } - work { - id - title - } - } - } - } - } - } -} -` - -func (c *Client) ListNextEpisodes(ctx context.Context, httpRequestOptions ...client.HTTPRequestOption) (*ListNextEpisodes, error) { - vars := map[string]interface{}{} - - var res ListNextEpisodes - if err := c.Client.Post(ctx, "ListNextEpisodes", ListNextEpisodesQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const GetWorkQuery = `query GetWork ($ids: [Int!]) { - searchWorks(annictIds: $ids) { - nodes { - ... WorkFragment - } - } -} -fragment WorkFragment on Work { - id - title - annict_id: annictId - seasonYear - seasonName - episodesCount - officialSiteUrl - wikipediaUrl - viewerStatusState - episodes(orderBy: {direction:ASC,field:SORT_NUMBER}) { - nodes { - id - annictId - title - sortNumber - } - } -} -` - -func (c *Client) GetWork(ctx context.Context, ids []int64, httpRequestOptions ...client.HTTPRequestOption) (*GetWork, error) { - vars := map[string]interface{}{ - "ids": ids, - } - - var res GetWork - if err := c.Client.Post(ctx, "GetWork", GetWorkQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} - -const SearchWorksQuery = `query SearchWorks ($seasons: [String!]) { - searchWorks(seasons: $seasons, first: 1, orderBy: {field:WATCHERS_COUNT,direction:DESC}) { - nodes { - ... WorkFragment - ... on Work { - image { - recommendedImageUrl - } - } - } - } -} -fragment WorkFragment on Work { - id - title - annict_id: annictId - seasonYear - seasonName - episodesCount - officialSiteUrl - wikipediaUrl - viewerStatusState - episodes(orderBy: {direction:ASC,field:SORT_NUMBER}) { - nodes { - id - annictId - title - sortNumber - } - } -} -` - -func (c *Client) SearchWorks(ctx context.Context, seasons []string, httpRequestOptions ...client.HTTPRequestOption) (*SearchWorks, error) { - vars := map[string]interface{}{ - "seasons": seasons, - } - - var res SearchWorks - if err := c.Client.Post(ctx, "SearchWorks", SearchWorksQuery, &res, vars, httpRequestOptions...); err != nil { - return nil, err - } - - return &res, nil -} diff --git a/example/annict/gen/models_gen.go b/example/annict/gen/models_gen.go deleted file mode 100644 index b14f5169..00000000 --- a/example/annict/gen/models_gen.go +++ /dev/null @@ -1,1633 +0,0 @@ -// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. - -package gen - -import ( - "fmt" - "io" - "strconv" - "time" -) - -type ActivityItem interface { - IsActivityItem() -} - -// An object with an ID. -type Node interface { - IsNode() -} - -type StaffResourceItem interface { - IsStaffResourceItem() -} - -type Activity struct { - AnnictID int64 `json:"annictId"` - // ID of the object. - ID string `json:"id"` - User *User `json:"user"` -} - -func (Activity) IsNode() {} - -// The connection type for Activity. -type ActivityConnection struct { - // A list of edges. - Edges []*ActivityEdge `json:"edges"` - // A list of nodes. - Nodes []*Activity `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type ActivityEdge struct { - Action ActivityAction `json:"action"` - AnnictID int64 `json:"annictId"` - // A cursor for use in pagination. - Cursor string `json:"cursor"` - Node ActivityItem `json:"node"` - User *User `json:"user"` -} - -type ActivityOrder struct { - Field ActivityOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Cast struct { - AnnictID int64 `json:"annictId"` - Character *Character `json:"character"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - Person *Person `json:"person"` - SortNumber int64 `json:"sortNumber"` - Work *Work `json:"work"` -} - -func (Cast) IsNode() {} - -// The connection type for Cast. -type CastConnection struct { - // A list of edges. - Edges []*CastEdge `json:"edges"` - // A list of nodes. - Nodes []*Cast `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type CastEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Cast `json:"node"` -} - -type CastOrder struct { - Field CastOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Channel struct { - AnnictID int64 `json:"annictId"` - ChannelGroup *ChannelGroup `json:"channelGroup"` - ID string `json:"id"` - Name string `json:"name"` - Programs *ProgramConnection `json:"programs"` - Published bool `json:"published"` - ScChid int64 `json:"scChid"` -} - -func (Channel) IsNode() {} - -// The connection type for Channel. -type ChannelConnection struct { - // A list of edges. - Edges []*ChannelEdge `json:"edges"` - // A list of nodes. - Nodes []*Channel `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type ChannelEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Channel `json:"node"` -} - -type ChannelGroup struct { - AnnictID int64 `json:"annictId"` - Channels *ChannelConnection `json:"channels"` - ID string `json:"id"` - Name string `json:"name"` - SortNumber int64 `json:"sortNumber"` -} - -func (ChannelGroup) IsNode() {} - -type Character struct { - Age string `json:"age"` - AgeEn string `json:"ageEn"` - AnnictID int64 `json:"annictId"` - Birthday string `json:"birthday"` - BirthdayEn string `json:"birthdayEn"` - BloodType string `json:"bloodType"` - BloodTypeEn string `json:"bloodTypeEn"` - Description string `json:"description"` - DescriptionEn string `json:"descriptionEn"` - DescriptionSource string `json:"descriptionSource"` - DescriptionSourceEn string `json:"descriptionSourceEn"` - FavoriteCharactersCount int64 `json:"favoriteCharactersCount"` - Height string `json:"height"` - HeightEn string `json:"heightEn"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - NameKana string `json:"nameKana"` - Nationality string `json:"nationality"` - NationalityEn string `json:"nationalityEn"` - Nickname string `json:"nickname"` - NicknameEn string `json:"nicknameEn"` - Occupation string `json:"occupation"` - OccupationEn string `json:"occupationEn"` - Series *Series `json:"series"` - Weight string `json:"weight"` - WeightEn string `json:"weightEn"` -} - -func (Character) IsNode() {} - -// The connection type for Character. -type CharacterConnection struct { - // A list of edges. - Edges []*CharacterEdge `json:"edges"` - // A list of nodes. - Nodes []*Character `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type CharacterEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Character `json:"node"` -} - -type CharacterOrder struct { - Field CharacterOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -// Autogenerated input type of CreateRecord -type CreateRecordInput struct { - EpisodeID string `json:"episodeId"` - Comment *string `json:"comment"` - RatingState *RatingState `json:"ratingState"` - ShareTwitter *bool `json:"shareTwitter"` - ShareFacebook *bool `json:"shareFacebook"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of CreateRecord -type CreateRecordPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Record *Record `json:"record"` -} - -// Autogenerated input type of CreateReview -type CreateReviewInput struct { - WorkID string `json:"workId"` - Title *string `json:"title"` - Body string `json:"body"` - RatingOverallState *RatingState `json:"ratingOverallState"` - RatingAnimationState *RatingState `json:"ratingAnimationState"` - RatingMusicState *RatingState `json:"ratingMusicState"` - RatingStoryState *RatingState `json:"ratingStoryState"` - RatingCharacterState *RatingState `json:"ratingCharacterState"` - ShareTwitter *bool `json:"shareTwitter"` - ShareFacebook *bool `json:"shareFacebook"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of CreateReview -type CreateReviewPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Review *Review `json:"review"` -} - -// Autogenerated input type of DeleteRecord -type DeleteRecordInput struct { - RecordID string `json:"recordId"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of DeleteRecord -type DeleteRecordPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Episode *Episode `json:"episode"` -} - -// Autogenerated input type of DeleteReview -type DeleteReviewInput struct { - ReviewID string `json:"reviewId"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of DeleteReview -type DeleteReviewPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Work *Work `json:"work"` -} - -// An episode of a work -type Episode struct { - AnnictID int64 `json:"annictId"` - ID string `json:"id"` - NextEpisode *Episode `json:"nextEpisode"` - Number *int64 `json:"number"` - NumberText *string `json:"numberText"` - PrevEpisode *Episode `json:"prevEpisode"` - RecordCommentsCount int64 `json:"recordCommentsCount"` - Records *RecordConnection `json:"records"` - RecordsCount int64 `json:"recordsCount"` - SatisfactionRate *float64 `json:"satisfactionRate"` - SortNumber int64 `json:"sortNumber"` - Title *string `json:"title"` - ViewerDidTrack bool `json:"viewerDidTrack"` - ViewerRecordsCount int64 `json:"viewerRecordsCount"` - Work *Work `json:"work"` -} - -func (Episode) IsNode() {} - -// The connection type for Episode. -type EpisodeConnection struct { - // A list of edges. - Edges []*EpisodeEdge `json:"edges"` - // A list of nodes. - Nodes []*Episode `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type EpisodeEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Episode `json:"node"` -} - -type EpisodeOrder struct { - Field EpisodeOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type MultipleRecord struct { - AnnictID int64 `json:"annictId"` - CreatedAt time.Time `json:"createdAt"` - ID string `json:"id"` - Records *RecordConnection `json:"records"` - User *User `json:"user"` - Work *Work `json:"work"` -} - -func (MultipleRecord) IsNode() {} -func (MultipleRecord) IsActivityItem() {} - -type Organization struct { - AnnictID int64 `json:"annictId"` - FavoriteOrganizationsCount int64 `json:"favoriteOrganizationsCount"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - NameKana string `json:"nameKana"` - StaffsCount int64 `json:"staffsCount"` - TwitterUsername string `json:"twitterUsername"` - TwitterUsernameEn string `json:"twitterUsernameEn"` - URL string `json:"url"` - URLEn string `json:"urlEn"` - WikipediaURL string `json:"wikipediaUrl"` - WikipediaURLEn string `json:"wikipediaUrlEn"` -} - -func (Organization) IsStaffResourceItem() {} -func (Organization) IsNode() {} - -// The connection type for Organization. -type OrganizationConnection struct { - // A list of edges. - Edges []*OrganizationEdge `json:"edges"` - // A list of nodes. - Nodes []*Organization `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type OrganizationEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Organization `json:"node"` -} - -type OrganizationOrder struct { - Field OrganizationOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -// Information about pagination in a connection. -type PageInfo struct { - // When paginating forwards, the cursor to continue. - EndCursor *string `json:"endCursor"` - // When paginating forwards, are there more items? - HasNextPage bool `json:"hasNextPage"` - // When paginating backwards, are there more items? - HasPreviousPage bool `json:"hasPreviousPage"` - // When paginating backwards, the cursor to continue. - StartCursor *string `json:"startCursor"` -} - -type Person struct { - AnnictID int64 `json:"annictId"` - Birthday string `json:"birthday"` - BloodType string `json:"bloodType"` - CastsCount int64 `json:"castsCount"` - FavoritePeopleCount int64 `json:"favoritePeopleCount"` - GenderText string `json:"genderText"` - Height string `json:"height"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - NameKana string `json:"nameKana"` - Nickname string `json:"nickname"` - NicknameEn string `json:"nicknameEn"` - Prefecture *Prefecture `json:"prefecture"` - StaffsCount int64 `json:"staffsCount"` - TwitterUsername string `json:"twitterUsername"` - TwitterUsernameEn string `json:"twitterUsernameEn"` - URL string `json:"url"` - URLEn string `json:"urlEn"` - WikipediaURL string `json:"wikipediaUrl"` - WikipediaURLEn string `json:"wikipediaUrlEn"` -} - -func (Person) IsNode() {} -func (Person) IsStaffResourceItem() {} - -// The connection type for Person. -type PersonConnection struct { - // A list of edges. - Edges []*PersonEdge `json:"edges"` - // A list of nodes. - Nodes []*Person `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type PersonEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Person `json:"node"` -} - -type PersonOrder struct { - Field PersonOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Prefecture struct { - AnnictID int64 `json:"annictId"` - ID string `json:"id"` - Name string `json:"name"` -} - -func (Prefecture) IsNode() {} - -type Program struct { - AnnictID int64 `json:"annictId"` - Channel *Channel `json:"channel"` - Episode *Episode `json:"episode"` - ID string `json:"id"` - Rebroadcast bool `json:"rebroadcast"` - ScPid *int64 `json:"scPid"` - StartedAt time.Time `json:"startedAt"` - State ProgramState `json:"state"` - Work *Work `json:"work"` -} - -func (Program) IsNode() {} - -// The connection type for Program. -type ProgramConnection struct { - // A list of edges. - Edges []*ProgramEdge `json:"edges"` - // A list of nodes. - Nodes []*Program `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type ProgramEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Program `json:"node"` -} - -type ProgramOrder struct { - Field ProgramOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Record struct { - AnnictID int64 `json:"annictId"` - Comment *string `json:"comment"` - CommentsCount int64 `json:"commentsCount"` - CreatedAt time.Time `json:"createdAt"` - Episode *Episode `json:"episode"` - FacebookClickCount int64 `json:"facebookClickCount"` - ID string `json:"id"` - LikesCount int64 `json:"likesCount"` - Modified bool `json:"modified"` - Rating *float64 `json:"rating"` - RatingState *RatingState `json:"ratingState"` - TwitterClickCount int64 `json:"twitterClickCount"` - UpdatedAt time.Time `json:"updatedAt"` - User *User `json:"user"` - Work *Work `json:"work"` -} - -func (Record) IsNode() {} -func (Record) IsActivityItem() {} - -// The connection type for Record. -type RecordConnection struct { - // A list of edges. - Edges []*RecordEdge `json:"edges"` - // A list of nodes. - Nodes []*Record `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type RecordEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Record `json:"node"` -} - -type RecordOrder struct { - Field RecordOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Review struct { - AnnictID int64 `json:"annictId"` - Body string `json:"body"` - CreatedAt time.Time `json:"createdAt"` - ID string `json:"id"` - ImpressionsCount int64 `json:"impressionsCount"` - LikesCount int64 `json:"likesCount"` - ModifiedAt *time.Time `json:"modifiedAt"` - RatingAnimationState *RatingState `json:"ratingAnimationState"` - RatingCharacterState *RatingState `json:"ratingCharacterState"` - RatingMusicState *RatingState `json:"ratingMusicState"` - RatingOverallState *RatingState `json:"ratingOverallState"` - RatingStoryState *RatingState `json:"ratingStoryState"` - Title *string `json:"title"` - UpdatedAt time.Time `json:"updatedAt"` - User *User `json:"user"` - Work *Work `json:"work"` -} - -func (Review) IsNode() {} -func (Review) IsActivityItem() {} - -// The connection type for Review. -type ReviewConnection struct { - // A list of edges. - Edges []*ReviewEdge `json:"edges"` - // A list of nodes. - Nodes []*Review `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type ReviewEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Review `json:"node"` -} - -type ReviewOrder struct { - Field ReviewOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Series struct { - AnnictID int64 `json:"annictId"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - NameRo string `json:"nameRo"` - Works *SeriesWorkConnection `json:"works"` -} - -func (Series) IsNode() {} - -// The connection type for Series. -type SeriesConnection struct { - // A list of edges. - Edges []*SeriesEdge `json:"edges"` - // A list of nodes. - Nodes []*Series `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type SeriesEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Series `json:"node"` -} - -// The connection type for Work. -type SeriesWorkConnection struct { - // A list of edges. - Edges []*SeriesWorkEdge `json:"edges"` - // A list of nodes. - Nodes []*Work `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type SeriesWorkEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - Node *Work `json:"node"` - Summary *string `json:"summary"` - SummaryEn *string `json:"summaryEn"` -} - -type SeriesWorkOrder struct { - Field SeriesWorkOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Staff struct { - AnnictID int64 `json:"annictId"` - ID string `json:"id"` - Name string `json:"name"` - NameEn string `json:"nameEn"` - Resource StaffResourceItem `json:"resource"` - RoleOther string `json:"roleOther"` - RoleOtherEn string `json:"roleOtherEn"` - RoleText string `json:"roleText"` - SortNumber int64 `json:"sortNumber"` - Work *Work `json:"work"` -} - -func (Staff) IsNode() {} - -// The connection type for Staff. -type StaffConnection struct { - // A list of edges. - Edges []*StaffEdge `json:"edges"` - // A list of nodes. - Nodes []*Staff `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type StaffEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Staff `json:"node"` -} - -type StaffOrder struct { - Field StaffOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type Status struct { - AnnictID int64 `json:"annictId"` - CreatedAt time.Time `json:"createdAt"` - ID string `json:"id"` - LikesCount int64 `json:"likesCount"` - State StatusState `json:"state"` - User *User `json:"user"` - Work *Work `json:"work"` -} - -func (Status) IsNode() {} -func (Status) IsActivityItem() {} - -// Autogenerated input type of UpdateRecord -type UpdateRecordInput struct { - RecordID string `json:"recordId"` - Comment *string `json:"comment"` - RatingState *RatingState `json:"ratingState"` - ShareTwitter *bool `json:"shareTwitter"` - ShareFacebook *bool `json:"shareFacebook"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of UpdateRecord -type UpdateRecordPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Record *Record `json:"record"` -} - -// Autogenerated input type of UpdateReview -type UpdateReviewInput struct { - ReviewID string `json:"reviewId"` - Title *string `json:"title"` - Body string `json:"body"` - RatingOverallState RatingState `json:"ratingOverallState"` - RatingAnimationState RatingState `json:"ratingAnimationState"` - RatingMusicState RatingState `json:"ratingMusicState"` - RatingStoryState RatingState `json:"ratingStoryState"` - RatingCharacterState RatingState `json:"ratingCharacterState"` - ShareTwitter *bool `json:"shareTwitter"` - ShareFacebook *bool `json:"shareFacebook"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of UpdateReview -type UpdateReviewPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Review *Review `json:"review"` -} - -// Autogenerated input type of UpdateStatus -type UpdateStatusInput struct { - WorkID string `json:"workId"` - State StatusState `json:"state"` - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` -} - -// Autogenerated return type of UpdateStatus -type UpdateStatusPayload struct { - // A unique identifier for the client performing the mutation. - ClientMutationID *string `json:"clientMutationId"` - Work *Work `json:"work"` -} - -type User struct { - Activities *ActivityConnection `json:"activities"` - AnnictID int64 `json:"annictId"` - AvatarURL *string `json:"avatarUrl"` - BackgroundImageURL *string `json:"backgroundImageUrl"` - CreatedAt time.Time `json:"createdAt"` - Description string `json:"description"` - Email *string `json:"email"` - Followers *UserConnection `json:"followers"` - FollowersCount int64 `json:"followersCount"` - Following *UserConnection `json:"following"` - FollowingActivities *ActivityConnection `json:"followingActivities"` - FollowingsCount int64 `json:"followingsCount"` - ID string `json:"id"` - Name string `json:"name"` - NotificationsCount *int64 `json:"notificationsCount"` - OnHoldCount int64 `json:"onHoldCount"` - Programs *ProgramConnection `json:"programs"` - Records *RecordConnection `json:"records"` - RecordsCount int64 `json:"recordsCount"` - StopWatchingCount int64 `json:"stopWatchingCount"` - URL *string `json:"url"` - Username string `json:"username"` - ViewerCanFollow bool `json:"viewerCanFollow"` - ViewerIsFollowing bool `json:"viewerIsFollowing"` - WannaWatchCount int64 `json:"wannaWatchCount"` - WatchedCount int64 `json:"watchedCount"` - WatchingCount int64 `json:"watchingCount"` - Works *WorkConnection `json:"works"` -} - -func (User) IsNode() {} - -// The connection type for User. -type UserConnection struct { - // A list of edges. - Edges []*UserEdge `json:"edges"` - // A list of nodes. - Nodes []*User `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type UserEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *User `json:"node"` -} - -// An anime title -type Work struct { - AnnictID int64 `json:"annictId"` - Casts *CastConnection `json:"casts"` - Episodes *EpisodeConnection `json:"episodes"` - EpisodesCount int64 `json:"episodesCount"` - ID string `json:"id"` - Image *WorkImage `json:"image"` - MalAnimeID *string `json:"malAnimeId"` - Media Media `json:"media"` - NoEpisodes bool `json:"noEpisodes"` - OfficialSiteURL *string `json:"officialSiteUrl"` - OfficialSiteURLEn *string `json:"officialSiteUrlEn"` - Programs *ProgramConnection `json:"programs"` - Reviews *ReviewConnection `json:"reviews"` - ReviewsCount int64 `json:"reviewsCount"` - SatisfactionRate *float64 `json:"satisfactionRate"` - SeasonName *SeasonName `json:"seasonName"` - SeasonYear *int64 `json:"seasonYear"` - SeriesList *SeriesConnection `json:"seriesList"` - Staffs *StaffConnection `json:"staffs"` - SyobocalTid *int64 `json:"syobocalTid"` - Title string `json:"title"` - TitleEn *string `json:"titleEn"` - TitleKana *string `json:"titleKana"` - TitleRo *string `json:"titleRo"` - TwitterHashtag *string `json:"twitterHashtag"` - TwitterUsername *string `json:"twitterUsername"` - ViewerStatusState *StatusState `json:"viewerStatusState"` - WatchersCount int64 `json:"watchersCount"` - WikipediaURL *string `json:"wikipediaUrl"` - WikipediaURLEn *string `json:"wikipediaUrlEn"` -} - -func (Work) IsNode() {} - -// The connection type for Work. -type WorkConnection struct { - // A list of edges. - Edges []*WorkEdge `json:"edges"` - // A list of nodes. - Nodes []*Work `json:"nodes"` - // Information to aid in pagination. - PageInfo *PageInfo `json:"pageInfo"` -} - -// An edge in a connection. -type WorkEdge struct { - // A cursor for use in pagination. - Cursor string `json:"cursor"` - // The item at the end of the edge. - Node *Work `json:"node"` -} - -type WorkImage struct { - AnnictID *int64 `json:"annictId"` - FacebookOgImageURL *string `json:"facebookOgImageUrl"` - ID string `json:"id"` - InternalURL *string `json:"internalUrl"` - RecommendedImageURL *string `json:"recommendedImageUrl"` - TwitterAvatarURL *string `json:"twitterAvatarUrl"` - TwitterBiggerAvatarURL *string `json:"twitterBiggerAvatarUrl"` - TwitterMiniAvatarURL *string `json:"twitterMiniAvatarUrl"` - TwitterNormalAvatarURL *string `json:"twitterNormalAvatarUrl"` - Work *Work `json:"work"` -} - -func (WorkImage) IsNode() {} - -type WorkOrder struct { - Field WorkOrderField `json:"field"` - Direction OrderDirection `json:"direction"` -} - -type ActivityAction string - -const ( - ActivityActionCreate ActivityAction = "CREATE" -) - -var AllActivityAction = []ActivityAction{ - ActivityActionCreate, -} - -func (e ActivityAction) IsValid() bool { - switch e { - case ActivityActionCreate: - return true - } - return false -} - -func (e ActivityAction) String() string { - return string(e) -} - -func (e *ActivityAction) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = ActivityAction(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid ActivityAction", str) - } - return nil -} - -func (e ActivityAction) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type ActivityOrderField string - -const ( - ActivityOrderFieldCreatedAt ActivityOrderField = "CREATED_AT" -) - -var AllActivityOrderField = []ActivityOrderField{ - ActivityOrderFieldCreatedAt, -} - -func (e ActivityOrderField) IsValid() bool { - switch e { - case ActivityOrderFieldCreatedAt: - return true - } - return false -} - -func (e ActivityOrderField) String() string { - return string(e) -} - -func (e *ActivityOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = ActivityOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid ActivityOrderField", str) - } - return nil -} - -func (e ActivityOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type CastOrderField string - -const ( - CastOrderFieldCreatedAt CastOrderField = "CREATED_AT" - CastOrderFieldSortNumber CastOrderField = "SORT_NUMBER" -) - -var AllCastOrderField = []CastOrderField{ - CastOrderFieldCreatedAt, - CastOrderFieldSortNumber, -} - -func (e CastOrderField) IsValid() bool { - switch e { - case CastOrderFieldCreatedAt, CastOrderFieldSortNumber: - return true - } - return false -} - -func (e CastOrderField) String() string { - return string(e) -} - -func (e *CastOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = CastOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid CastOrderField", str) - } - return nil -} - -func (e CastOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type CharacterOrderField string - -const ( - CharacterOrderFieldCreatedAt CharacterOrderField = "CREATED_AT" - CharacterOrderFieldFavoriteCharactersCount CharacterOrderField = "FAVORITE_CHARACTERS_COUNT" -) - -var AllCharacterOrderField = []CharacterOrderField{ - CharacterOrderFieldCreatedAt, - CharacterOrderFieldFavoriteCharactersCount, -} - -func (e CharacterOrderField) IsValid() bool { - switch e { - case CharacterOrderFieldCreatedAt, CharacterOrderFieldFavoriteCharactersCount: - return true - } - return false -} - -func (e CharacterOrderField) String() string { - return string(e) -} - -func (e *CharacterOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = CharacterOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid CharacterOrderField", str) - } - return nil -} - -func (e CharacterOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type EpisodeOrderField string - -const ( - EpisodeOrderFieldCreatedAt EpisodeOrderField = "CREATED_AT" - EpisodeOrderFieldSortNumber EpisodeOrderField = "SORT_NUMBER" -) - -var AllEpisodeOrderField = []EpisodeOrderField{ - EpisodeOrderFieldCreatedAt, - EpisodeOrderFieldSortNumber, -} - -func (e EpisodeOrderField) IsValid() bool { - switch e { - case EpisodeOrderFieldCreatedAt, EpisodeOrderFieldSortNumber: - return true - } - return false -} - -func (e EpisodeOrderField) String() string { - return string(e) -} - -func (e *EpisodeOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = EpisodeOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid EpisodeOrderField", str) - } - return nil -} - -func (e EpisodeOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -// Media of anime -type Media string - -const ( - MediaTv Media = "TV" - MediaOva Media = "OVA" - MediaMovie Media = "MOVIE" - MediaWeb Media = "WEB" - MediaOther Media = "OTHER" -) - -var AllMedia = []Media{ - MediaTv, - MediaOva, - MediaMovie, - MediaWeb, - MediaOther, -} - -func (e Media) IsValid() bool { - switch e { - case MediaTv, MediaOva, MediaMovie, MediaWeb, MediaOther: - return true - } - return false -} - -func (e Media) String() string { - return string(e) -} - -func (e *Media) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = Media(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid Media", str) - } - return nil -} - -func (e Media) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type OrderDirection string - -const ( - OrderDirectionAsc OrderDirection = "ASC" - OrderDirectionDesc OrderDirection = "DESC" -) - -var AllOrderDirection = []OrderDirection{ - OrderDirectionAsc, - OrderDirectionDesc, -} - -func (e OrderDirection) IsValid() bool { - switch e { - case OrderDirectionAsc, OrderDirectionDesc: - return true - } - return false -} - -func (e OrderDirection) String() string { - return string(e) -} - -func (e *OrderDirection) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = OrderDirection(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid OrderDirection", str) - } - return nil -} - -func (e OrderDirection) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type OrganizationOrderField string - -const ( - OrganizationOrderFieldCreatedAt OrganizationOrderField = "CREATED_AT" - OrganizationOrderFieldFavoriteOrganizationsCount OrganizationOrderField = "FAVORITE_ORGANIZATIONS_COUNT" -) - -var AllOrganizationOrderField = []OrganizationOrderField{ - OrganizationOrderFieldCreatedAt, - OrganizationOrderFieldFavoriteOrganizationsCount, -} - -func (e OrganizationOrderField) IsValid() bool { - switch e { - case OrganizationOrderFieldCreatedAt, OrganizationOrderFieldFavoriteOrganizationsCount: - return true - } - return false -} - -func (e OrganizationOrderField) String() string { - return string(e) -} - -func (e *OrganizationOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = OrganizationOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid OrganizationOrderField", str) - } - return nil -} - -func (e OrganizationOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type PersonOrderField string - -const ( - PersonOrderFieldCreatedAt PersonOrderField = "CREATED_AT" - PersonOrderFieldFavoritePeopleCount PersonOrderField = "FAVORITE_PEOPLE_COUNT" -) - -var AllPersonOrderField = []PersonOrderField{ - PersonOrderFieldCreatedAt, - PersonOrderFieldFavoritePeopleCount, -} - -func (e PersonOrderField) IsValid() bool { - switch e { - case PersonOrderFieldCreatedAt, PersonOrderFieldFavoritePeopleCount: - return true - } - return false -} - -func (e PersonOrderField) String() string { - return string(e) -} - -func (e *PersonOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = PersonOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid PersonOrderField", str) - } - return nil -} - -func (e PersonOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type ProgramOrderField string - -const ( - ProgramOrderFieldStartedAt ProgramOrderField = "STARTED_AT" -) - -var AllProgramOrderField = []ProgramOrderField{ - ProgramOrderFieldStartedAt, -} - -func (e ProgramOrderField) IsValid() bool { - switch e { - case ProgramOrderFieldStartedAt: - return true - } - return false -} - -func (e ProgramOrderField) String() string { - return string(e) -} - -func (e *ProgramOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = ProgramOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid ProgramOrderField", str) - } - return nil -} - -func (e ProgramOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type ProgramState string - -const ( - ProgramStatePublished ProgramState = "PUBLISHED" - ProgramStateHidden ProgramState = "HIDDEN" -) - -var AllProgramState = []ProgramState{ - ProgramStatePublished, - ProgramStateHidden, -} - -func (e ProgramState) IsValid() bool { - switch e { - case ProgramStatePublished, ProgramStateHidden: - return true - } - return false -} - -func (e ProgramState) String() string { - return string(e) -} - -func (e *ProgramState) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = ProgramState(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid ProgramState", str) - } - return nil -} - -func (e ProgramState) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type RatingState string - -const ( - RatingStateGreat RatingState = "GREAT" - RatingStateGood RatingState = "GOOD" - RatingStateAverage RatingState = "AVERAGE" - RatingStateBad RatingState = "BAD" -) - -var AllRatingState = []RatingState{ - RatingStateGreat, - RatingStateGood, - RatingStateAverage, - RatingStateBad, -} - -func (e RatingState) IsValid() bool { - switch e { - case RatingStateGreat, RatingStateGood, RatingStateAverage, RatingStateBad: - return true - } - return false -} - -func (e RatingState) String() string { - return string(e) -} - -func (e *RatingState) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = RatingState(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid RatingState", str) - } - return nil -} - -func (e RatingState) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type RecordOrderField string - -const ( - RecordOrderFieldCreatedAt RecordOrderField = "CREATED_AT" - RecordOrderFieldLikesCount RecordOrderField = "LIKES_COUNT" -) - -var AllRecordOrderField = []RecordOrderField{ - RecordOrderFieldCreatedAt, - RecordOrderFieldLikesCount, -} - -func (e RecordOrderField) IsValid() bool { - switch e { - case RecordOrderFieldCreatedAt, RecordOrderFieldLikesCount: - return true - } - return false -} - -func (e RecordOrderField) String() string { - return string(e) -} - -func (e *RecordOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = RecordOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid RecordOrderField", str) - } - return nil -} - -func (e RecordOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type ReviewOrderField string - -const ( - ReviewOrderFieldCreatedAt ReviewOrderField = "CREATED_AT" - ReviewOrderFieldLikesCount ReviewOrderField = "LIKES_COUNT" -) - -var AllReviewOrderField = []ReviewOrderField{ - ReviewOrderFieldCreatedAt, - ReviewOrderFieldLikesCount, -} - -func (e ReviewOrderField) IsValid() bool { - switch e { - case ReviewOrderFieldCreatedAt, ReviewOrderFieldLikesCount: - return true - } - return false -} - -func (e ReviewOrderField) String() string { - return string(e) -} - -func (e *ReviewOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = ReviewOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid ReviewOrderField", str) - } - return nil -} - -func (e ReviewOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -// Season name -type SeasonName string - -const ( - SeasonNameWinter SeasonName = "WINTER" - SeasonNameSpring SeasonName = "SPRING" - SeasonNameSummer SeasonName = "SUMMER" - SeasonNameAutumn SeasonName = "AUTUMN" -) - -var AllSeasonName = []SeasonName{ - SeasonNameWinter, - SeasonNameSpring, - SeasonNameSummer, - SeasonNameAutumn, -} - -func (e SeasonName) IsValid() bool { - switch e { - case SeasonNameWinter, SeasonNameSpring, SeasonNameSummer, SeasonNameAutumn: - return true - } - return false -} - -func (e SeasonName) String() string { - return string(e) -} - -func (e *SeasonName) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = SeasonName(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid SeasonName", str) - } - return nil -} - -func (e SeasonName) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type SeriesWorkOrderField string - -const ( - SeriesWorkOrderFieldSeason SeriesWorkOrderField = "SEASON" -) - -var AllSeriesWorkOrderField = []SeriesWorkOrderField{ - SeriesWorkOrderFieldSeason, -} - -func (e SeriesWorkOrderField) IsValid() bool { - switch e { - case SeriesWorkOrderFieldSeason: - return true - } - return false -} - -func (e SeriesWorkOrderField) String() string { - return string(e) -} - -func (e *SeriesWorkOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = SeriesWorkOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid SeriesWorkOrderField", str) - } - return nil -} - -func (e SeriesWorkOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type StaffOrderField string - -const ( - StaffOrderFieldCreatedAt StaffOrderField = "CREATED_AT" - StaffOrderFieldSortNumber StaffOrderField = "SORT_NUMBER" -) - -var AllStaffOrderField = []StaffOrderField{ - StaffOrderFieldCreatedAt, - StaffOrderFieldSortNumber, -} - -func (e StaffOrderField) IsValid() bool { - switch e { - case StaffOrderFieldCreatedAt, StaffOrderFieldSortNumber: - return true - } - return false -} - -func (e StaffOrderField) String() string { - return string(e) -} - -func (e *StaffOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = StaffOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid StaffOrderField", str) - } - return nil -} - -func (e StaffOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type StatusState string - -const ( - StatusStateWannaWatch StatusState = "WANNA_WATCH" - StatusStateWatching StatusState = "WATCHING" - StatusStateWatched StatusState = "WATCHED" - StatusStateOnHold StatusState = "ON_HOLD" - StatusStateStopWatching StatusState = "STOP_WATCHING" - StatusStateNoState StatusState = "NO_STATE" -) - -var AllStatusState = []StatusState{ - StatusStateWannaWatch, - StatusStateWatching, - StatusStateWatched, - StatusStateOnHold, - StatusStateStopWatching, - StatusStateNoState, -} - -func (e StatusState) IsValid() bool { - switch e { - case StatusStateWannaWatch, StatusStateWatching, StatusStateWatched, StatusStateOnHold, StatusStateStopWatching, StatusStateNoState: - return true - } - return false -} - -func (e StatusState) String() string { - return string(e) -} - -func (e *StatusState) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = StatusState(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid StatusState", str) - } - return nil -} - -func (e StatusState) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} - -type WorkOrderField string - -const ( - WorkOrderFieldCreatedAt WorkOrderField = "CREATED_AT" - WorkOrderFieldSeason WorkOrderField = "SEASON" - WorkOrderFieldWatchersCount WorkOrderField = "WATCHERS_COUNT" -) - -var AllWorkOrderField = []WorkOrderField{ - WorkOrderFieldCreatedAt, - WorkOrderFieldSeason, - WorkOrderFieldWatchersCount, -} - -func (e WorkOrderField) IsValid() bool { - switch e { - case WorkOrderFieldCreatedAt, WorkOrderFieldSeason, WorkOrderFieldWatchersCount: - return true - } - return false -} - -func (e WorkOrderField) String() string { - return string(e) -} - -func (e *WorkOrderField) UnmarshalGQL(v interface{}) error { - str, ok := v.(string) - if !ok { - return fmt.Errorf("enums must be strings") - } - - *e = WorkOrderField(str) - if !e.IsValid() { - return fmt.Errorf("%s is not a valid WorkOrderField", str) - } - return nil -} - -func (e WorkOrderField) MarshalGQL(w io.Writer) { - fmt.Fprint(w, strconv.Quote(e.String())) -} diff --git a/example/annict/main.go b/example/annict/main.go deleted file mode 100644 index e17dd991..00000000 --- a/example/annict/main.go +++ /dev/null @@ -1,76 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - "os" - - "github.com/Yamashou/gqlgenc/client" - "github.com/Yamashou/gqlgenc/example/annict/gen" -) - -func main() { - key := os.Getenv("ANNICT_KEY") - authHeader := func(req *http.Request) { - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key)) - } - - annictClient := NewAnnictClient(client.NewClient(http.DefaultClient, "https://api.annict.com/graphql", authHeader)) - ctx := context.Background() - - getProfile, err := annictClient.GetProfile(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - fmt.Println(*getProfile.Viewer.AvatarURL, getProfile.Viewer.RecordsCount, getProfile.Viewer.WatchedCount) - - list, err := annictClient.SearchWorks(ctx, []string{"2017-spring"}) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - - for _, node := range list.SearchWorks.Nodes { - fmt.Println(node.ID, node.AnnictID, node.Title, *node.Work.Image.RecommendedImageURL) - } - - getWork, err := annictClient.GetWork(ctx, []int64{list.SearchWorks.Nodes[0].AnnictID}) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - - work := getWork.SearchWorks.Nodes[0] - _, err = annictClient.UpdateWorkStatus(ctx, work.ID) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - - _, err = annictClient.CreateRecordMutation(ctx, work.Episodes.Nodes[0].ID) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - - getProfile2, err := annictClient.GetProfile(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - - fmt.Println(getProfile2.Viewer.RecordsCount, getProfile2.Viewer.WatchedCount) - - res, err := annictClient.ListWorks(ctx, nil, nil, 5) - if err != nil { - fmt.Fprintf(os.Stderr, "error: %s", err.Error()) - os.Exit(1) - } - fmt.Println(res.Viewer.Works.Edges[0].Node.Title, res.Viewer.Works.Edges[0].Cursor, len(res.Viewer.Works.Edges)) -} - -func NewAnnictClient(c *client.Client) *gen.Client { - return &gen.Client{Client: c} -} diff --git a/example/annict/query/fragment.graphql b/example/annict/query/fragment.graphql deleted file mode 100644 index 9cd34937..00000000 --- a/example/annict/query/fragment.graphql +++ /dev/null @@ -1,28 +0,0 @@ -fragment ViewerFragment on User { - avatar_url:avatarUrl - recordsCount - wannaWatchCount - watchingCount - watchedCount -} - -fragment WorkFragment on Work { - id - title - annict_id:annictId - seasonYear - seasonName - episodesCount - officialSiteUrl - wikipediaUrl - viewerStatusState - episodes(orderBy: {direction: ASC, field: SORT_NUMBER}) { - nodes { - id - annictId - title - sortNumber - } - } -} - diff --git a/example/annict/query/mutation.graphql b/example/annict/query/mutation.graphql deleted file mode 100644 index 59d88fd1..00000000 --- a/example/annict/query/mutation.graphql +++ /dev/null @@ -1,17 +0,0 @@ -mutation CreateRecordMutation($episodeId: ID!) { - createRecord(input: {episodeId: $episodeId}) { - clientMutationId - } -} - -mutation UpdateStatusMutation($state: StatusState!, $workId: ID!) { - updateStatus(input: {state: $state, workId: $workId}) { - clientMutationId - } -} - -mutation UpdateWorkStatus($workId: ID!){ - updateStatus(input:{state: WATCHING, workId: $workId}) { - clientMutationId - } -} diff --git a/example/annict/query/query.graphql b/example/annict/query/query.graphql deleted file mode 100644 index df146ada..00000000 --- a/example/annict/query/query.graphql +++ /dev/null @@ -1,83 +0,0 @@ -query GetProfile { - viewer { - ...ViewerFragment - } -} - -query ListWorks($state: StatusState, $after: String, $n: Int!) { - viewer { - works(state: $state, after: $after, first: $n, orderBy: {direction: DESC, field: SEASON}) { - edges { - cursor - node { - ...WorkFragment - } - } - } - } -} - -query ListRecords { - viewer { - records { - edges { - node { - work { - ...WorkFragment - } - episode { - sortNumber - } - createdAt - } - } - } - } -} - -query ListNextEpisodes { - viewer { - records { - edges { - node { - episode { - nextEpisode { - id - number - numberText - title - nextEpisode { - id - } - } - work { - id - title - } - } - } - } - } - } -} - -query GetWork($ids: [Int!]) { - searchWorks(annictIds: $ids) { - nodes { - ...WorkFragment - } - } -} - -query SearchWorks($seasons: [String!]) { - searchWorks(seasons: $seasons, first: 1, orderBy: { field: WATCHERS_COUNT, direction: DESC }) { - nodes { - ...WorkFragment - ... on Work{ - image { - recommendedImageUrl - } - } - } - } -} diff --git a/example/autobind/main.go b/example/autobind/main.go index 76c50a81..405df3ab 100644 --- a/example/autobind/main.go +++ b/example/autobind/main.go @@ -6,7 +6,6 @@ import ( "net/http" "os" - "github.com/Yamashou/gqlgenc/client" "github.com/Yamashou/gqlgenc/clientv2" "github.com/Yamashou/gqlgenc/example/github/gen" ) @@ -26,7 +25,7 @@ func main() { } getUser, err := githubClient.GetUser(ctx, 10, 10) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) @@ -43,7 +42,7 @@ func main() { res, err := githubClient.GetNode(ctx, repository.ID) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) diff --git a/example/github/main.go b/example/github/main.go index 76c50a81..405df3ab 100644 --- a/example/github/main.go +++ b/example/github/main.go @@ -6,7 +6,6 @@ import ( "net/http" "os" - "github.com/Yamashou/gqlgenc/client" "github.com/Yamashou/gqlgenc/clientv2" "github.com/Yamashou/gqlgenc/example/github/gen" ) @@ -26,7 +25,7 @@ func main() { } getUser, err := githubClient.GetUser(ctx, 10, 10) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) @@ -43,7 +42,7 @@ func main() { res, err := githubClient.GetNode(ctx, repository.ID) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) diff --git a/example/no-autobind/main.go b/example/no-autobind/main.go index 76c50a81..405df3ab 100644 --- a/example/no-autobind/main.go +++ b/example/no-autobind/main.go @@ -6,7 +6,6 @@ import ( "net/http" "os" - "github.com/Yamashou/gqlgenc/client" "github.com/Yamashou/gqlgenc/clientv2" "github.com/Yamashou/gqlgenc/example/github/gen" ) @@ -26,7 +25,7 @@ func main() { } getUser, err := githubClient.GetUser(ctx, 10, 10) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) @@ -43,7 +42,7 @@ func main() { res, err := githubClient.GetNode(ctx, repository.ID) if err != nil { - if handledError, ok := err.(*client.ErrorResponse); ok { + if handledError, ok := err.(*clientv2.ErrorResponse); ok { fmt.Fprintf(os.Stderr, "handled error: %s\n", handledError.Error()) } else { fmt.Fprintf(os.Stderr, "unhandled error: %s\n", err.Error()) diff --git a/generator/generator.go b/generator/generator.go index eec3e8eb..73ad6f6c 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -41,7 +41,7 @@ func mutateHook(cfg *config.Config) func(b *modelgen.ModelBuild) *modelgen.Model } } -func Generate(ctx context.Context, cfg *config.Config, option ...api.Option) error { +func Generate(ctx context.Context, cfg *config.Config, options ...api.Option) error { _ = syscall.Unlink(cfg.Client.Filename) if cfg.Model.IsDefined() { _ = syscall.Unlink(cfg.Model.Filename) @@ -57,7 +57,7 @@ func Generate(ctx context.Context, cfg *config.Config, option ...api.Option) err plugins = append(plugins, p) } - for _, o := range option { + for _, o := range options { o(cfg.GQLConfig, &plugins) } diff --git a/graphqljson/graphql.go b/graphqljson/graphql.go index c19a5755..61ac2225 100644 --- a/graphqljson/graphql.go +++ b/graphqljson/graphql.go @@ -49,7 +49,6 @@ func UnmarshalData(data json.RawMessage, v interface{}) error { return fmt.Errorf(": %w", err) } - // TODO: この処理が本当に必要かは今後検討 tok, err := d.jsonDecoder.Token() switch err { case io.EOF: diff --git a/main.go b/main.go index db0f2288..71ef79bd 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ import ( "os" "github.com/99designs/gqlgen/api" - "github.com/Yamashou/gqlgenc/clientgen" "github.com/Yamashou/gqlgenc/clientgenv2" "github.com/Yamashou/gqlgenc/config" "github.com/Yamashou/gqlgenc/generator" @@ -37,11 +36,9 @@ var generateCmd = &cli.Command{ os.Exit(2) } - clientGen := api.AddPlugin(clientgen.New(cfg.Query, cfg.Client, cfg.Generate)) + var clientGen api.Option if cfg.Generate != nil { - if cfg.Generate.ClientV2 { - clientGen = api.AddPlugin(clientgenv2.New(cfg.Query, cfg.Client, cfg.Generate)) - } + clientGen = api.AddPlugin(clientgenv2.New(cfg.Query, cfg.Client, cfg.Generate)) } if err := generator.Generate(ctx.Context, cfg, clientGen); err != nil {