From af6178a7a782ca1e03200929d7c67371f6855cf8 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Wed, 28 Mar 2018 22:05:54 +1100 Subject: [PATCH] Use a raw string for schema --- codegen/templates/data.go | 2 +- codegen/templates/generated.gotpl | 4 +- codegen/templates/templates.go | 15 ++-- example/chat/generated.go | 29 ++++++- example/dataloader/generated.go | 35 +++++++- example/scalars/generated.go | 32 ++++++- example/selection/generated.go | 28 ++++++- example/starwars/generated.go | 135 +++++++++++++++++++++++++++++- example/todo/generated.go | 30 ++++++- test/generated.go | 58 ++++++++++++- 10 files changed, 346 insertions(+), 22 deletions(-) diff --git a/codegen/templates/data.go b/codegen/templates/data.go index 8afd4ca8ad8..f03929a6d2d 100644 --- a/codegen/templates/data.go +++ b/codegen/templates/data.go @@ -3,7 +3,7 @@ package templates var data = map[string]string{ "args.gotpl": "\t{{- range $i, $arg := . }}\n\t\tvar arg{{$i}} {{$arg.Signature }}\n\t\tif tmp, ok := field.Args[{{$arg.GQLName|quote}}]; ok {\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\tec.Error(err)\n\t\t\t\t{{- if $arg.Object.Stream }}\n\t\t\t\t\treturn nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn graphql.Null\n\t\t\t\t{{- end }}\n\t\t\t}\n\t\t} {{ if $arg.Default }} else {\n\t\t\tvar tmp interface{} = {{ $arg.Default | dump }}\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\tec.Error(err)\n\t\t\t\t{{- if $arg.Object.Stream }}\n\t\t\t\t\treturn nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn graphql.Null\n\t\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\t\t{{end }}\n\t{{- end -}}\n", "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\t\trctx := graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})\n\t\tresults, err := ec.resolvers.{{ $object.GQLType }}_{{ $field.GQLName }}({{ $field.CallArgs }})\n\t\tif err != nil {\n\t\t\tec.Error(err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\n\t\t{{- if $field.IsConcurrent }}\n\t\t\treturn graphql.Defer(func() (ret graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tuserErr := ec.Recover(r)\n\t\t\t\t\t\tec.Error(userErr)\n\t\t\t\t\t\tret = graphql.Null\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t{{- end }}\n\n\t\t\t{{- if $field.GoVarName }}\n\t\t\t\tres := obj.{{$field.GoVarName}}\n\t\t\t{{- else if $field.GoMethodName }}\n\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\tres := {{$field.GoMethodName}}({{ $field.CallArgs }})\n\t\t\t\t{{- else }}\n\t\t\t\t\tres, err := {{$field.GoMethodName}}({{ $field.CallArgs }})\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tec.Error(err)\n\t\t\t\t\t\treturn graphql.Null\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t{{- else }}\n\t\t\t\trctx := graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})\n\t\t\t\tres, err := ec.resolvers.{{ $object.GQLType }}_{{ $field.GQLName }}({{ $field.CallArgs }})\n\t\t\t\tif err != nil {\n\t\t\t\t\tec.Error(err)\n\t\t\t\t\treturn graphql.Null\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t{{ $field.WriteJson }}\n\t\t{{- if $field.IsConcurrent }}\n\t\t\t})\n\t\t{{- end }}\n\t}\n{{ end }}\n", - "generated.gotpl": "// This file was generated by github.com/vektah/gqlgen, DO NOT EDIT\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\nfunc MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {\n\treturn &executableSchema{resolvers: resolvers}\n}\n\ntype Resolvers interface {\n{{- range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ $field.ResolverDeclaration }}\n\t{{ end }}\n{{- end }}\n}\n\ntype executableSchema struct {\n\tresolvers Resolvers\n}\n\nfunc (e *executableSchema) Schema() *schema.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *query.Operation) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.Selections)\n\t\tvar buf bytes.Buffer\n\t\tdata.MarshalGQL(&buf)\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf.Bytes(),\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn &graphql.Response{Errors: []*errors.QueryError{ {Message: \"queries are not supported\"} }}\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *query.Operation) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.Selections)\n\t\tvar buf bytes.Buffer\n\t\tdata.MarshalGQL(&buf)\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf.Bytes(),\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn &graphql.Response{Errors: []*errors.QueryError{ {Message: \"mutations are not supported\"} }}\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *query.Operation) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.Selections)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf.Reset()\n\t\t\tdata := next()\n\t\t\tif data == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tdata.MarshalGQL(&buf)\n\n\t\t\terrs := ec.Errors\n\t\t\tec.Errors = nil\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf.Bytes(),\n\t\t\t\tErrors: errs,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(&graphql.Response{Errors: []*errors.QueryError{ {Message: \"subscriptions are not supported\"} }})\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\n\tresolvers Resolvers\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nvar parsedSchema = schema.MustParse({{.SchemaRaw|quote}})\n\nfunc (ec *executionContext) introspectSchema() *introspection.Schema {\n\treturn introspection.WrapSchema(parsedSchema)\n}\n\nfunc (ec *executionContext) introspectType(name string) *introspection.Type {\n\tt := parsedSchema.Resolve(name)\n\tif t == nil {\n\t\treturn nil\n\t}\n\treturn introspection.WrapType(t)\n}\n", + "generated.gotpl": "// This file was generated by github.com/vektah/gqlgen, DO NOT EDIT\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\nfunc MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {\n\treturn &executableSchema{resolvers: resolvers}\n}\n\ntype Resolvers interface {\n{{- range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ $field.ResolverDeclaration }}\n\t{{ end }}\n{{- end }}\n}\n\ntype executableSchema struct {\n\tresolvers Resolvers\n}\n\nfunc (e *executableSchema) Schema() *schema.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *query.Operation) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.Selections)\n\t\tvar buf bytes.Buffer\n\t\tdata.MarshalGQL(&buf)\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf.Bytes(),\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn &graphql.Response{Errors: []*errors.QueryError{ {Message: \"queries are not supported\"} }}\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *query.Operation) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.Selections)\n\t\tvar buf bytes.Buffer\n\t\tdata.MarshalGQL(&buf)\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf.Bytes(),\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn &graphql.Response{Errors: []*errors.QueryError{ {Message: \"mutations are not supported\"} }}\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *query.Operation) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.Selections)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf.Reset()\n\t\t\tdata := next()\n\t\t\tif data == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tdata.MarshalGQL(&buf)\n\n\t\t\terrs := ec.Errors\n\t\t\tec.Errors = nil\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf.Bytes(),\n\t\t\t\tErrors: errs,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(&graphql.Response{Errors: []*errors.QueryError{ {Message: \"subscriptions are not supported\"} }})\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\n\tresolvers Resolvers\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) introspectSchema() *introspection.Schema {\n\treturn introspection.WrapSchema(parsedSchema)\n}\n\nfunc (ec *executionContext) introspectType(name string) *introspection.Type {\n\tt := parsedSchema.Resolve(name)\n\tif t == nil {\n\t\treturn nil\n\t}\n\treturn introspection.WrapType(t)\n}\n\nvar parsedSchema = schema.MustParse({{.SchemaRaw|rawQuote}})\n", "input.gotpl": "\t{{- if .IsMarshaled }}\n\tfunc Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {\n\t\tvar it {{.FullName}}\n\n\t\tfor k, v := range v.(map[string]interface{}) {\n\t\t\tswitch k {\n\t\t\t{{- range $field := .Fields }}\n\t\t\tcase {{$field.GQLName|quote}}:\n\t\t\t\tvar err error\n\t\t\t\t{{ $field.Unmarshal (print \"it.\" $field.GoVarName) \"v\" }}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn it, err\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\n\t\treturn it, nil\n\t}\n\t{{- end }}\n", "interface.gotpl": "{{- $interface := . }}\n\nfunc (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel []query.Selection, obj *{{$interface.FullName}}) graphql.Marshaler {\n\tswitch obj := (*obj).(type) {\n\tcase nil:\n\t\treturn graphql.Null\n\t{{- range $implementor := $interface.Implementors }}\n\t\t{{- if $implementor.ValueReceiver }}\n\t\t\tcase {{$implementor.FullName}}:\n\t\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, &obj)\n\t\t{{- end}}\n\t\tcase *{{$implementor.FullName}}:\n\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, obj)\n\t{{- end }}\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type %T\", obj))\n\t}\n}\n", "models.gotpl": "// This file was generated by github.com/vektah/gqlgen, DO NOT EDIT\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n{{ range $model := .Models }}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- if $field.GoVarName }}\n\t\t\t\t\t{{ $field.GoVarName }} {{$field.Signature}}\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\ttype {{.GoType}} string\n\tconst (\n\t{{ range $value := .Values }}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}} {{with .Description}} // {{.}} {{end}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n", diff --git a/codegen/templates/generated.gotpl b/codegen/templates/generated.gotpl index 3e29d315626..cc8a4ba92c0 100644 --- a/codegen/templates/generated.gotpl +++ b/codegen/templates/generated.gotpl @@ -114,8 +114,6 @@ type executionContext struct { {{ template "input.gotpl" $input }} {{- end }} -var parsedSchema = schema.MustParse({{.SchemaRaw|quote}}) - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -127,3 +125,5 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse({{.SchemaRaw|rawQuote}}) diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index 875c031f5f1..e79e8ce0010 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -13,11 +13,12 @@ import ( func Run(name string, tpldata interface{}) (*bytes.Buffer, error) { t := template.New("").Funcs(template.FuncMap{ - "ucFirst": ucFirst, - "lcFirst": lcFirst, - "quote": strconv.Quote, - "toCamel": toCamel, - "dump": dump, + "ucFirst": ucFirst, + "lcFirst": lcFirst, + "quote": strconv.Quote, + "rawQuote": rawQuote, + "toCamel": toCamel, + "dump": dump, }) for filename, data := range data { @@ -80,6 +81,10 @@ func toCamel(s string) string { return string(buffer) } +func rawQuote(s string) string { + return "`" + strings.Replace(s, "'", "`+\"`\"+`", -1) + "`" +} + func dump(val interface{}) string { switch val := val.(type) { case int: diff --git a/example/chat/generated.go b/example/chat/generated.go index 38bb27213d2..c022e2c2101 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -855,8 +855,6 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.___Type(ctx, field.Selections, res) } -var parsedSchema = schema.MustParse("type Chatroom {\n name: String!\n messages: [Message!]!\n}\n\ntype Message {\n id: ID!\n text: String!\n createdBy: String!\n createdAt: Time!\n}\n\ntype Query {\n room(name:String!): Chatroom\n}\n\ntype Mutation {\n post(text: String!, username: String!, roomName: String!): Message!\n}\n\ntype Subscription {\n messageAdded(roomName: String!): Message!\n}\n\nscalar Time\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -868,3 +866,30 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`type Chatroom { + name: String! + messages: [Message!]! +} + +type Message { + id: ID! + text: String! + createdBy: String! + createdAt: Time! +} + +type Query { + room(name:String!): Chatroom +} + +type Mutation { + post(text: String!, username: String!, roomName: String!): Message! +} + +type Subscription { + messageAdded(roomName: String!): Message! +} + +scalar Time +`) diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 2e028b307f2..ac1e4e32551 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -893,8 +893,6 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.___Type(ctx, field.Selections, res) } -var parsedSchema = schema.MustParse("type Query {\n customers: [Customer!]\n\n # this method is here to test code generation of nested arrays\n torture(customerIds: [[Int]]): [[Customer!]]\n}\n\ntype Customer {\n id: Int!\n name: String!\n address: Address\n orders: [Order!]\n}\n\ntype Address {\n id: Int!\n street: String!\n country: String!\n}\n\ntype Order {\n id: Int!\n date: Time!\n amount: Float!\n items: [Item!]\n}\n\ntype Item {\n name: String!\n}\nscalar Time\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -906,3 +904,36 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`type Query { + customers: [Customer!] + + # this method is here to test code generation of nested arrays + torture(customerIds: [[Int]]): [[Customer!]] +} + +type Customer { + id: Int! + name: String! + address: Address + orders: [Order!] +} + +type Address { + id: Int! + street: String! + country: String! +} + +type Order { + id: Int! + date: Time! + amount: Float! + items: [Item!] +} + +type Item { + name: String! +} +scalar Time +`) diff --git a/example/scalars/generated.go b/example/scalars/generated.go index f46947f1009..f15596fb5f5 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -856,8 +856,6 @@ func UnmarshalSearchArgs(v interface{}) (SearchArgs, error) { return it, nil } -var parsedSchema = schema.MustParse("type Query {\n user(id: ID!): User\n search(input: SearchArgs = {location: \"37,144\"}): [User!]!\n}\n\ntype User {\n id: ID!\n name: String!\n created: Timestamp\n isBanned: Boolean!\n primitiveResolver: String!\n customResolver: Point!\n address: Address\n}\n\ntype Address {\n id: ID!\n location: Point\n}\n\ninput SearchArgs {\n location: Point\n createdAfter: Timestamp\n isBanned: Boolean\n}\n\nscalar Timestamp\nscalar Point\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -869,3 +867,33 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`type Query { + user(id: ID!): User + search(input: SearchArgs = {location: "37,144"}): [User!]! +} + +type User { + id: ID! + name: String! + created: Timestamp + isBanned: Boolean! + primitiveResolver: String! + customResolver: Point! + address: Address +} + +type Address { + id: ID! + location: Point +} + +input SearchArgs { + location: Point + createdAfter: Timestamp + isBanned: Boolean +} + +scalar Timestamp +scalar Point +`) diff --git a/example/selection/generated.go b/example/selection/generated.go index 0d22f06f1d5..fe9967658f3 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -753,8 +753,6 @@ func (ec *executionContext) _Event(ctx context.Context, sel []query.Selection, o } } -var parsedSchema = schema.MustParse("interface Event {\n selection: [String!]\n collected: [String!]\n}\n\ntype Post implements Event {\n message: String!\n sent: Time!\n selection: [String!]\n collected: [String!]\n}\n\ntype Like implements Event {\n reaction: String!\n sent: Time!\n selection: [String!]\n collected: [String!]\n}\n\ntype Query {\n events: [Event]\n}\n\nscalar Time\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -766,3 +764,29 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`interface Event { + selection: [String!] + collected: [String!] +} + +type Post implements Event { + message: String! + sent: Time! + selection: [String!] + collected: [String!] +} + +type Like implements Event { + reaction: String! + sent: Time! + selection: [String!] + collected: [String!] +} + +type Query { + events: [Event] +} + +scalar Time +`) diff --git a/example/starwars/generated.go b/example/starwars/generated.go index cc4c9cfd11b..7c9a84c0609 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -1583,8 +1583,6 @@ func UnmarshalReviewInput(v interface{}) (Review, error) { return it, nil } -var parsedSchema = schema.MustParse("# The query type, represents all of the entry points into our object graph\ntype Query {\n hero(episode: Episode = NEWHOPE): Character\n reviews(episode: Episode!, since: Time): [Review]!\n search(text: String!): [SearchResult]!\n character(id: ID!): Character\n droid(id: ID!): Droid\n human(id: ID!): Human\n starship(id: ID!): Starship\n}\n# The mutation type, represents all updates we can make to our data\ntype Mutation {\n createReview(episode: Episode!, review: ReviewInput!): Review\n}\n# The episodes in the Star Wars trilogy\nenum Episode {\n # Star Wars Episode IV: A New Hope, released in 1977.\n NEWHOPE\n # Star Wars Episode V: The Empire Strikes Back, released in 1980.\n EMPIRE\n # Star Wars Episode VI: Return of the Jedi, released in 1983.\n JEDI\n}\n# A character from the Star Wars universe\ninterface Character {\n # The ID of the character\n id: ID!\n # The name of the character\n name: String!\n # The friends of the character, or an empty list if they have none\n friends: [Character]\n # The friends of the character exposed as a connection with edges\n friendsConnection(first: Int, after: ID): FriendsConnection!\n # The movies this character appears in\n appearsIn: [Episode!]!\n}\n# Units of height\nenum LengthUnit {\n # The standard unit around the world\n METER\n # Primarily used in the United States\n FOOT\n}\n# A humanoid creature from the Star Wars universe\ntype Human implements Character {\n # The ID of the human\n id: ID!\n # What this human calls themselves\n name: String!\n # Height in the preferred unit, default is meters\n height(unit: LengthUnit = METER): Float!\n # Mass in kilograms, or null if unknown\n mass: Float\n # This human's friends, or an empty list if they have none\n friends: [Character]\n # The friends of the human exposed as a connection with edges\n friendsConnection(first: Int, after: ID): FriendsConnection!\n # The movies this human appears in\n appearsIn: [Episode!]!\n # A list of starships this person has piloted, or an empty list if none\n starships: [Starship]\n}\n# An autonomous mechanical character in the Star Wars universe\ntype Droid implements Character {\n # The ID of the droid\n id: ID!\n # What others call this droid\n name: String!\n # This droid's friends, or an empty list if they have none\n friends: [Character]\n # The friends of the droid exposed as a connection with edges\n friendsConnection(first: Int, after: ID): FriendsConnection!\n # The movies this droid appears in\n appearsIn: [Episode!]!\n # This droid's primary function\n primaryFunction: String\n}\n# A connection object for a character's friends\ntype FriendsConnection {\n # The total number of friends\n totalCount: Int!\n # The edges for each of the character's friends.\n edges: [FriendsEdge]\n # A list of the friends, as a convenience when edges are not needed.\n friends: [Character]\n # Information for paginating this connection\n pageInfo: PageInfo!\n}\n# An edge object for a character's friends\ntype FriendsEdge {\n # A cursor used for pagination\n cursor: ID!\n # The character represented by this friendship edge\n node: Character\n}\n# Information for paginating this connection\ntype PageInfo {\n startCursor: ID!\n endCursor: ID!\n hasNextPage: Boolean!\n}\n# Represents a review for a movie\ntype Review {\n # The number of stars this review gave, 1-5\n stars: Int!\n # Comment about the movie\n commentary: String\n # when the review was posted\n time: Time\n}\n# The input object sent when someone is creating a new review\ninput ReviewInput {\n # 0-5 stars\n stars: Int!\n # Comment about the movie, optional\n commentary: String\n # when the review was posted\n time: Time\n}\ntype Starship {\n # The ID of the starship\n id: ID!\n # The name of the starship\n name: String!\n # Length of the starship, along the longest axis\n length(unit: LengthUnit = METER): Float!\n # coordinates tracking this ship\n history: [[Int]]\n}\nunion SearchResult = Human | Droid | Starship\nscalar Time\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -1596,3 +1594,136 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`# The query type, represents all of the entry points into our object graph +type Query { + hero(episode: Episode = NEWHOPE): Character + reviews(episode: Episode!, since: Time): [Review]! + search(text: String!): [SearchResult]! + character(id: ID!): Character + droid(id: ID!): Droid + human(id: ID!): Human + starship(id: ID!): Starship +} +# The mutation type, represents all updates we can make to our data +type Mutation { + createReview(episode: Episode!, review: ReviewInput!): Review +} +# The episodes in the Star Wars trilogy +enum Episode { + # Star Wars Episode IV: A New Hope, released in 1977. + NEWHOPE + # Star Wars Episode V: The Empire Strikes Back, released in 1980. + EMPIRE + # Star Wars Episode VI: Return of the Jedi, released in 1983. + JEDI +} +# A character from the Star Wars universe +interface Character { + # The ID of the character + id: ID! + # The name of the character + name: String! + # The friends of the character, or an empty list if they have none + friends: [Character] + # The friends of the character exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + # The movies this character appears in + appearsIn: [Episode!]! +} +# Units of height +enum LengthUnit { + # The standard unit around the world + METER + # Primarily used in the United States + FOOT +} +# A humanoid creature from the Star Wars universe +type Human implements Character { + # The ID of the human + id: ID! + # What this human calls themselves + name: String! + # Height in the preferred unit, default is meters + height(unit: LengthUnit = METER): Float! + # Mass in kilograms, or null if unknown + mass: Float + # This human` + "`" + `s friends, or an empty list if they have none + friends: [Character] + # The friends of the human exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + # The movies this human appears in + appearsIn: [Episode!]! + # A list of starships this person has piloted, or an empty list if none + starships: [Starship] +} +# An autonomous mechanical character in the Star Wars universe +type Droid implements Character { + # The ID of the droid + id: ID! + # What others call this droid + name: String! + # This droid` + "`" + `s friends, or an empty list if they have none + friends: [Character] + # The friends of the droid exposed as a connection with edges + friendsConnection(first: Int, after: ID): FriendsConnection! + # The movies this droid appears in + appearsIn: [Episode!]! + # This droid` + "`" + `s primary function + primaryFunction: String +} +# A connection object for a character` + "`" + `s friends +type FriendsConnection { + # The total number of friends + totalCount: Int! + # The edges for each of the character` + "`" + `s friends. + edges: [FriendsEdge] + # A list of the friends, as a convenience when edges are not needed. + friends: [Character] + # Information for paginating this connection + pageInfo: PageInfo! +} +# An edge object for a character` + "`" + `s friends +type FriendsEdge { + # A cursor used for pagination + cursor: ID! + # The character represented by this friendship edge + node: Character +} +# Information for paginating this connection +type PageInfo { + startCursor: ID! + endCursor: ID! + hasNextPage: Boolean! +} +# Represents a review for a movie +type Review { + # The number of stars this review gave, 1-5 + stars: Int! + # Comment about the movie + commentary: String + # when the review was posted + time: Time +} +# The input object sent when someone is creating a new review +input ReviewInput { + # 0-5 stars + stars: Int! + # Comment about the movie, optional + commentary: String + # when the review was posted + time: Time +} +type Starship { + # The ID of the starship + id: ID! + # The name of the starship + name: String! + # Length of the starship, along the longest axis + length(unit: LengthUnit = METER): Float! + # coordinates tracking this ship + history: [[Int]] +} +union SearchResult = Human | Droid | Starship +scalar Time +`) diff --git a/example/todo/generated.go b/example/todo/generated.go index 0aeacaa4469..42c84511cd8 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -836,8 +836,6 @@ func UnmarshalTodoInput(v interface{}) (TodoInput, error) { return it, nil } -var parsedSchema = schema.MustParse("schema {\n\tquery: MyQuery\n\tmutation: MyMutation\n}\n\ntype MyQuery {\n\ttodo(id: Int!): Todo\n\tlastTodo: Todo\n\ttodos: [Todo!]!\n}\n\ntype MyMutation {\n\tcreateTodo(todo: TodoInput!): Todo!\n\tupdateTodo(id: Int!, changes: Map!): Todo\n}\n\ntype Todo {\n\tid: Int!\n\ttext: String!\n\tdone: Boolean!\n}\n\ninput TodoInput {\n\ttext: String!\n\tdone: Boolean\n}\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -849,3 +847,31 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`schema { + query: MyQuery + mutation: MyMutation +} + +type MyQuery { + todo(id: Int!): Todo + lastTodo: Todo + todos: [Todo!]! +} + +type MyMutation { + createTodo(todo: TodoInput!): Todo! + updateTodo(id: Int!, changes: Map!): Todo +} + +type Todo { + id: Int! + text: String! + done: Boolean! +} + +input TodoInput { + text: String! + done: Boolean +} +`) diff --git a/test/generated.go b/test/generated.go index 49edf4e2bac..7537947700e 100644 --- a/test/generated.go +++ b/test/generated.go @@ -1080,8 +1080,6 @@ func UnmarshalRecursiveInputSlice(v interface{}) (RecursiveInputSlice, error) { return it, nil } -var parsedSchema = schema.MustParse("input InnerInput {\n id:Int!\n}\n\ninput OuterInput {\n inner: InnerInput!\n}\n\ntype OuterObject {\n inner: InnerObject!\n}\n\ntype InnerObject {\n id: Int!\n}\n\ninterface Shape {\n area: Float\n}\n\ntype Circle implements Shape {\n radius: Float\n area: Float\n}\n\ntype Rectangle implements Shape {\n length: Float\n width: Float\n area: Float\n}\n\ninput RecursiveInputSlice {\n self: [RecursiveInputSlice!]\n}\n\nunion ShapeUnion = Circle | Rectangle\n\ninput Changes {\n a: Int\n b: Int\n}\n\ntype It {\n id: ID!\n}\n\ntype Query {\n nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean\n nestedOutputs: [[OuterObject]]\n shapes: [Shape]\n recursive(input: RecursiveInputSlice): Boolean\n mapInput(input: Changes): Boolean\n collision: It\n}\n") - func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) } @@ -1093,3 +1091,59 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { } return introspection.WrapType(t) } + +var parsedSchema = schema.MustParse(`input InnerInput { + id:Int! +} + +input OuterInput { + inner: InnerInput! +} + +type OuterObject { + inner: InnerObject! +} + +type InnerObject { + id: Int! +} + +interface Shape { + area: Float +} + +type Circle implements Shape { + radius: Float + area: Float +} + +type Rectangle implements Shape { + length: Float + width: Float + area: Float +} + +input RecursiveInputSlice { + self: [RecursiveInputSlice!] +} + +union ShapeUnion = Circle | Rectangle + +input Changes { + a: Int + b: Int +} + +type It { + id: ID! +} + +type Query { + nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean + nestedOutputs: [[OuterObject]] + shapes: [Shape] + recursive(input: RecursiveInputSlice): Boolean + mapInput(input: Changes): Boolean + collision: It +} +`)