diff --git a/.trunk/configs/.golangci.json b/.trunk/configs/.golangci.json index 64b6785d6f9..dab8c4002e8 100644 --- a/.trunk/configs/.golangci.json +++ b/.trunk/configs/.golangci.json @@ -9,7 +9,13 @@ "exclusions": { "generated": "lax", "paths": ["third_party$", "builtin$", "examples$"], - "presets": ["comments", "common-false-positives", "legacy", "std-error-handling"] + "presets": ["comments", "common-false-positives", "legacy", "std-error-handling"], + "rules": [ + { + "linters": ["staticcheck"], + "text": "QF1001" + } + ] } }, "run": { diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 09f6e89529a..761b7d7d5dc 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -8,15 +8,13 @@ cli: plugins: sources: - id: trunk - ref: v1.7.2 + ref: v1.7.6 uri: https://github.com/trunk-io/plugins # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) runtimes: enabled: - - go@1.25.6 - - node@22.16.0 - - python@3.10.8 + - go@1.25.7 # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: @@ -26,25 +24,26 @@ lint: - contrib/** - protos/pb/pb.pb.go enabled: - - svgo@4.0.0 - - golangci-lint2@2.4.0 + - taplo@0.10.0 + - svgo@4.0.1 + - golangci-lint2@2.11.3 - trivy@0.69.3 - - actionlint@1.7.7 - - checkov@3.2.467 - - dotenv-linter@3.3.0 + - actionlint@1.7.11 + - checkov@3.2.510 + - dotenv-linter@4.0.0 - git-diff-check - gofmt@1.20.4 - - hadolint@2.12.1-beta - - markdownlint@0.45.0 - - osv-scanner@2.2.2 - - oxipng@9.1.5 - - prettier@3.6.2 - - renovate@41.91.3 + - hadolint@2.14.0 + - markdownlint@0.48.0 + - osv-scanner@2.3.3 + - oxipng@10.1.0 + - prettier@3.8.1 + - renovate@43.84.0 - shellcheck@0.11.0 - shfmt@3.6.0 - - tflint@0.59.1 - - trufflehog@3.90.5 - - yamllint@1.37.1 + - tflint@0.61.0 + - trufflehog@3.94.0 + - yamllint@1.38.0 actions: enabled: - trunk-announce diff --git a/graphql/e2e/federation/docker-compose.yml b/graphql/e2e/federation/docker-compose.yml new file mode 100644 index 00000000000..34cc868cb69 --- /dev/null +++ b/graphql/e2e/federation/docker-compose.yml @@ -0,0 +1,57 @@ +# Federation test setup with 2 alpha instances +# alpha1: user-service subgraph +# alpha2: reviews-service subgraph +services: + alpha1: + image: dgraph/dgraph:local + working_dir: /data/alpha1 + labels: + cluster: test + service: alpha1 + ports: + - 8080 + - 9080 + volumes: + - type: bind + source: ${LINUX_GOBIN:-$GOPATH/bin} + target: /gobin + read_only: true + command: + /gobin/dgraph ${COVERAGE_OUTPUT} alpha --my=alpha1:7080 --zero=zero1:5080 --logtostderr -v=2 + --raft="idx=1;" --security "whitelist=0.0.0.0/0;" + alpha2: + image: dgraph/dgraph:local + working_dir: /data/alpha2 + depends_on: + - alpha1 + labels: + cluster: test + service: alpha2 + ports: + - 8080 + - 9080 + volumes: + - type: bind + source: ${LINUX_GOBIN:-$GOPATH/bin} + target: /gobin + read_only: true + command: + /gobin/dgraph ${COVERAGE_OUTPUT} alpha --my=alpha2:7080 --zero=zero1:5080 --logtostderr -v=2 + --raft="idx=2;" --security "whitelist=0.0.0.0/0;" + zero1: + image: dgraph/dgraph:local + working_dir: /data/zero1 + labels: + cluster: test + ports: + - 5080 + - 6080 + volumes: + - type: bind + source: ${LINUX_GOBIN:-$GOPATH/bin} + target: /gobin + read_only: true + command: + /gobin/dgraph ${COVERAGE_OUTPUT} zero --telemetry "reports=false;" --raft="idx=1;" + --my=zero1:5080 --replicas=1 --logtostderr -v=2 --bindall +volumes: {} diff --git a/graphql/e2e/federation/federation_test.go b/graphql/e2e/federation/federation_test.go new file mode 100644 index 00000000000..d6b904537b3 --- /dev/null +++ b/graphql/e2e/federation/federation_test.go @@ -0,0 +1,185 @@ +//go:build integration + +/* + * SPDX-FileCopyrightText: © 2017-2026 Istari Digital, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package federation + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/dgraph-io/dgraph/v25/graphql/e2e/common" + "github.com/dgraph-io/dgraph/v25/testutil" + "github.com/dgraph-io/dgraph/v25/x" +) + +var ( + // Alpha1 serves the user-service subgraph + Alpha1HTTP = testutil.ContainerAddr("alpha1", 8080) + Alpha1GraphqlURL = "http://" + Alpha1HTTP + "/graphql" + Alpha1GraphqlAdminURL = "http://" + Alpha1HTTP + "/admin" + + // Alpha2 serves the reviews-service subgraph + Alpha2HTTP = testutil.ContainerAddr("alpha2", 8080) + Alpha2GraphqlURL = "http://" + Alpha2HTTP + "/graphql" + Alpha2GraphqlAdminURL = "http://" + Alpha2HTTP + "/admin" +) + +// TestMain sets up the test environment with two Dgraph alpha instances +func TestMain(m *testing.M) { + userSchema, err := os.ReadFile("testdata/user-service.graphql") + x.Panic(err) + + reviewsSchema, err := os.ReadFile("testdata/reviews-service.graphql") + x.Panic(err) + + // Wait for both alphas to be ready + err = common.CheckGraphQLStarted(Alpha1GraphqlAdminURL) + x.Panic(err) + err = common.CheckGraphQLStarted(Alpha2GraphqlAdminURL) + x.Panic(err) + + // Bootstrap alpha1 with user-service schema + common.BootstrapServer(userSchema, nil) + + // Deploy reviews-service schema to alpha2 + // Retry until schema is successfully deployed + maxRetries := 30 + for i := 0; i < maxRetries; i++ { + resp, updateErr := http.Post("http://"+Alpha2HTTP+"/admin/schema", + "application/graphql", strings.NewReader(string(reviewsSchema))) + if updateErr == nil { + resp.Body.Close() + if resp.StatusCode == 200 { + // Wait a bit for schema to be loaded + time.Sleep(500 * time.Millisecond) + break + } + } + if resp != nil && resp.Body != nil { + resp.Body.Close() + } + if i == maxRetries-1 { + x.Panic(fmt.Errorf("failed to deploy schema to alpha2 after %d retries", maxRetries)) + } + time.Sleep(200 * time.Millisecond) + } + + os.Exit(m.Run()) +} + +// TestRoverFederationComposition tests Apollo Federation supergraph composition +// with two Dgraph instances serving different federated subgraphs. +// +// This test: +// 1. Fetches SDL via _service query from alpha1 (user-service) and alpha2 (reviews-service) +// 2. Runs Apollo Rover CLI to compose a supergraph +// 3. Verifies composition succeeds (auxiliary types should be excluded for @extends types) +func TestRoverFederationComposition(t *testing.T) { + + // Test that we can run docker + testCmd := exec.Command("docker", "version") + if err := testCmd.Run(); err != nil { + t.Skip("Skipping test: docker is not running or accessible") + } + + testdataDir := "./testdata" + absTestdataDir, err := filepath.Abs(testdataDir) + require.NoError(t, err) + + // Fetch SDL from alpha1 (user-service) + serviceQuery := &common.GraphQLParams{ + Query: `query { _service { sdl } }`, + } + + userServiceResp := serviceQuery.ExecuteAsPost(t, Alpha1GraphqlURL) + common.RequireNoGQLErrors(t, userServiceResp) + + var userServiceResult struct { + Service struct { + SDL string `json:"sdl"` + } `json:"_service"` + } + require.NoError(t, json.Unmarshal(userServiceResp.Data, &userServiceResult)) + + // Fetch SDL from alpha2 (reviews-service) + reviewsServiceResp := serviceQuery.ExecuteAsPost(t, Alpha2GraphqlURL) + common.RequireNoGQLErrors(t, reviewsServiceResp) + + var reviewsServiceResult struct { + Service struct { + SDL string `json:"sdl"` + } `json:"_service"` + } + require.NoError(t, json.Unmarshal(reviewsServiceResp.Data, &reviewsServiceResult)) + + userSDL := userServiceResult.Service.SDL + reviewsSDL := reviewsServiceResult.Service.SDL + + // Write the SDL files that Rover will use + userSDLFile := filepath.Join(testdataDir, "user-service-generated.graphql") + require.NoError(t, os.WriteFile(userSDLFile, []byte(userSDL), 0644)) + defer os.Remove(userSDLFile) + + reviewsSDLFile := filepath.Join(testdataDir, "reviews-service-generated.graphql") + require.NoError(t, os.WriteFile(reviewsSDLFile, []byte(reviewsSDL), 0644)) + defer os.Remove(reviewsSDLFile) + + // Create supergraph config that points to the generated SDL files + supergraphConfig := fmt.Sprintf(`federation_version: =2.7.1 +subgraphs: + users: + routing_url: %s + schema: + file: ./user-service-generated.graphql + reviews: + routing_url: %s + schema: + file: ./reviews-service-generated.graphql +`, Alpha1GraphqlURL, Alpha2GraphqlURL) + supergraphFile := filepath.Join(testdataDir, "supergraph-generated.yml") + require.NoError(t, os.WriteFile(supergraphFile, []byte(supergraphConfig), 0644)) + defer os.Remove(supergraphFile) + + // Run rover supergraph compose using Docker + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + + cmd := exec.CommandContext(ctx, "docker", "run", "--rm", + "-e", "APOLLO_ELV2_LICENSE=accept", + "-v", absTestdataDir+":/workspace", + "-w", "/workspace", + "node:24-slim", + "sh", "-c", + `apt-get update -qq && apt-get install -y -qq curl > /dev/null 2>&1 && \ + curl -sSL https://rover.apollo.dev/nix/latest | sh > /dev/null 2>&1 && \ + $HOME/.rover/bin/rover supergraph compose --config supergraph-generated.yml`) + + output, err := cmd.CombinedOutput() + outputStr := string(output) + + // The auxiliary types for extended User should NOT be generated from alpha2 (reviews-service) + if err != nil { + if strings.Contains(outputStr, "UserPatch") || + strings.Contains(outputStr, "UserOrderable") || + strings.Contains(outputStr, "UserHasFilter") { + t.Errorf("Rover composition failed with auxiliary type conflicts. "+ + "The fix should exclude these types for @extends. Error: %v", err) + } else { + t.Errorf("Rover composition failed with unexpected error: %v", err) + } + } +} diff --git a/graphql/e2e/federation/testdata/reviews-service.graphql b/graphql/e2e/federation/testdata/reviews-service.graphql new file mode 100644 index 00000000000..178acc80b85 --- /dev/null +++ b/graphql/e2e/federation/testdata/reviews-service.graphql @@ -0,0 +1,10 @@ +type Review { + id: ID! + rating: Int! @search + comment: String @search(by: [fulltext]) +} + +extend type User @key(fields: "userId") { + userId: ID! @external + reviews: [Review] +} diff --git a/graphql/e2e/federation/testdata/user-service.graphql b/graphql/e2e/federation/testdata/user-service.graphql new file mode 100644 index 00000000000..2200302a539 --- /dev/null +++ b/graphql/e2e/federation/testdata/user-service.graphql @@ -0,0 +1,5 @@ +type User @key(fields: "userId") { + userId: ID! + username: String! @search(by: [hash]) + email: String +} diff --git a/graphql/e2e/schema/apollo_service_response.graphql b/graphql/e2e/schema/apollo_service_response.graphql index 9cf5a5d877c..a78263a3d07 100644 --- a/graphql/e2e/schema/apollo_service_response.graphql +++ b/graphql/e2e/schema/apollo_service_response.graphql @@ -290,11 +290,6 @@ input StringHashFilter { # Generated Types ####################### -type AddAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - numUids: Int -} - type AddCarPayload { car(filter: CarFilter, order: CarOrder, first: Int, offset: Int): [Car] numUids: Int @@ -305,24 +300,12 @@ type AddMissionPayload { numUids: Int } -type AstronautAggregateResult { - count: Int - idMin: ID - idMax: ID -} - type CarAggregateResult { count: Int nameMin: String nameMax: String } -type DeleteAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - msg: String - numUids: Int -} - type DeleteCarPayload { car(filter: CarFilter, order: CarOrder, first: Int, offset: Int): [Car] msg: String @@ -345,11 +328,6 @@ type MissionAggregateResult { endDateMax: String } -type UpdateAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - numUids: Int -} - type UpdateCarPayload { car(filter: CarFilter, order: CarOrder, first: Int, offset: Int): [Car] numUids: Int @@ -364,14 +342,6 @@ type UpdateMissionPayload { # Generated Enums ####################### -enum AstronautHasFilter { - missions -} - -enum AstronautOrderable { - id -} - enum CarHasFilter { name } @@ -397,45 +367,16 @@ enum MissionOrderable { # Generated Inputs ####################### -input AddAstronautInput { - id: ID! - missions: [MissionRef] -} - input AddCarInput { name: String! } input AddMissionInput { - crew: [AstronautRef] designation: String! startDate: String endDate: String } -input AstronautFilter { - id: [ID!] - has: [AstronautHasFilter] - and: [AstronautFilter] - or: [AstronautFilter] - not: AstronautFilter -} - -input AstronautOrder { - asc: AstronautOrderable - desc: AstronautOrderable - then: AstronautOrder -} - -input AstronautPatch { - missions: [MissionRef] -} - -input AstronautRef { - id: ID - missions: [MissionRef] -} - input CarFilter { id: [ID!] has: [CarHasFilter] @@ -474,7 +415,6 @@ input MissionOrder { } input MissionPatch { - crew: [AstronautRef] designation: String startDate: String endDate: String @@ -482,18 +422,11 @@ input MissionPatch { input MissionRef { id: ID - crew: [AstronautRef] designation: String startDate: String endDate: String } -input UpdateAstronautInput { - filter: AstronautFilter! - set: AstronautPatch - remove: AstronautPatch -} - input UpdateCarInput { filter: CarFilter! set: CarPatch @@ -528,9 +461,6 @@ type Mutation { addMission(input: [AddMissionInput!]!): AddMissionPayload updateMission(input: UpdateMissionInput!): UpdateMissionPayload deleteMission(filter: MissionFilter!): DeleteMissionPayload - addAstronaut(input: [AddAstronautInput!]!): AddAstronautPayload - updateAstronaut(input: UpdateAstronautInput!): UpdateAstronautPayload - deleteAstronaut(filter: AstronautFilter!): DeleteAstronautPayload addCar(input: [AddCarInput!]!): AddCarPayload updateCar(input: UpdateCarInput!): UpdateCarPayload deleteCar(filter: CarFilter!): DeleteCarPayload diff --git a/graphql/schema/federation_auxiliary_test.go b/graphql/schema/federation_auxiliary_test.go new file mode 100644 index 00000000000..ee353ff5a05 --- /dev/null +++ b/graphql/schema/federation_auxiliary_test.go @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: © 2017-2026 Istari Digital, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package schema + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +// TestApolloServiceQueryExcludesAuxiliaryTypes verifies that auxiliary types +// are not generated for @extends types when apolloServiceQuery=true +func TestApolloServiceQueryExcludesAuxiliaryTypes(t *testing.T) { + schema := ` +type Review { + id: ID! + rating: Int! @search + comment: String @search(by: [fulltext]) +} + +extend type User @key(fields: "userId") { + userId: ID! @external + reviews: [Review] +} +` + + // Parse with apolloServiceQuery=true (simulating _service query) + handler, err := NewHandler(schema, true) + require.NoError(t, err) + + // Get the SDL that would be returned by _service + sdl := handler.GQLSchemaWithoutApolloExtras() + + // These auxiliary types should NOT be present for extended User type + auxiliaryTypes := []string{ + "input UserPatch", + "input AddUserInput", + "enum UserOrderable", + "enum UserHasFilter", + "input UserFilter", + "input UserRef", + "type AddUserPayload", + "type UpdateUserPayload", + "type DeleteUserPayload", + "addUser(", + "updateUser(", + "deleteUser(", + "getUser(", + "queryUser(", + } + + for _, auxType := range auxiliaryTypes { + if strings.Contains(sdl, auxType) { + t.Errorf("SDL should NOT contain '%s' for extended User type", auxType) + } + } + + // Review types SHOULD be present (not extended) + reviewTypes := []string{ + "input ReviewPatch", + "input AddReviewInput", + "enum ReviewOrderable", + "enum ReviewHasFilter", + } + + for _, reviewType := range reviewTypes { + if !strings.Contains(sdl, reviewType) { + t.Errorf("SDL SHOULD contain '%s' for Review type", reviewType) + } + } +} + +// TestApolloServiceQueryWithoutExtends verifies that auxiliary types ARE generated +// for regular types when apolloServiceQuery=true +func TestApolloServiceQueryWithoutExtends(t *testing.T) { + schema := ` +type User @key(fields: "userId") { + userId: ID! + username: String! @search(by: [hash]) + email: String +} +` + + // Parse with apolloServiceQuery=true + handler, err := NewHandler(schema, true) + require.NoError(t, err) + + sdl := handler.GQLSchemaWithoutApolloExtras() + + // Auxiliary types SHOULD be present for non-extended User type + auxiliaryTypes := []string{ + "input UserPatch", + "input AddUserInput", + "enum UserOrderable", + "enum UserHasFilter", + } + + for _, auxType := range auxiliaryTypes { + if !strings.Contains(sdl, auxType) { + t.Errorf("SDL SHOULD contain '%s' for regular User type", auxType) + } + } +} diff --git a/graphql/schema/gqlschema.go b/graphql/schema/gqlschema.go index 32eda06f88f..c4b30ea79ad 100644 --- a/graphql/schema/gqlschema.go +++ b/graphql/schema/gqlschema.go @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: © 2017-2025 Istari Digital, Inc. + * SPDX-FileCopyrightText: © 2017-2026 Istari Digital, Inc. * SPDX-License-Identifier: Apache-2.0 */ @@ -1006,15 +1006,19 @@ func completeSchema( providesTypeMap := providesFieldsMap[key] // Common types to both Interface and Object. - addReferenceType(sch, defn, providesTypeMap) + // Don't generate reference types for @extends types in Apollo service query + if !(apolloServiceQuery && hasExtends(defn)) { + addReferenceType(sch, defn, providesTypeMap) + } - if params.generateUpdateMutation { + // Don't generate mutation input types for @extends types in Apollo service query + if params.generateUpdateMutation && !(apolloServiceQuery && hasExtends(defn)) { addPatchType(sch, defn, providesTypeMap) addUpdateType(sch, defn) addUpdatePayloadType(sch, defn, providesTypeMap) } - if params.generateDeleteMutation { + if params.generateDeleteMutation && !(apolloServiceQuery && hasExtends(defn)) { addDeletePayloadType(sch, defn, providesTypeMap) } @@ -1022,33 +1026,47 @@ func completeSchema( case ast.Interface: // addInputType doesn't make sense as interface is like an abstract class and we can't // create objects of its type. - if params.generateUpdateMutation { + // Don't generate mutations for @extends types in Apollo service query + if params.generateUpdateMutation && !(apolloServiceQuery && hasExtends(defn)) { addUpdateMutation(sch, defn) } - if params.generateDeleteMutation { + if params.generateDeleteMutation && !(apolloServiceQuery && hasExtends(defn)) { addDeleteMutation(sch, defn) } case ast.Object: // types and inputs needed for mutations - if params.generateAddMutation { + // Don't generate add input types for @extends types in Apollo service query + if params.generateAddMutation && !(apolloServiceQuery && hasExtends(defn)) { addInputType(sch, defn, providesTypeMap) addAddPayloadType(sch, defn, providesTypeMap) } - addMutations(sch, defn, params) + if !(apolloServiceQuery && hasExtends(defn)) { + addMutations(sch, defn, params) + } } // types and inputs needed for query and search - addFilterType(sch, defn, providesTypeMap) - addTypeOrderable(sch, defn, providesTypeMap) + // Don't generate filter/orderable types for @extends types in Apollo service query + // to avoid conflicts when composing federated schemas + if !(apolloServiceQuery && hasExtends(defn)) { + addFilterType(sch, defn, providesTypeMap) + addTypeOrderable(sch, defn, providesTypeMap) + } addFieldFilters(sch, defn, providesTypeMap, apolloServiceQuery) - addAggregationResultType(sch, defn, providesTypeMap) + if !(apolloServiceQuery && hasExtends(defn)) { + addAggregationResultType(sch, defn, providesTypeMap) + } // Don't expose queries for the @extends type to the gateway // as it is resolved through `_entities` resolver. if !(apolloServiceQuery && hasExtends(defn)) { addQueries(sch, defn, providesTypeMap, params) } - addTypeHasFilter(sch, defn, providesTypeMap) + // addTypeHasFilter must come after addQueries so that fields added by queries (like vector_distance) + // are included in the HasFilter enum + if !(apolloServiceQuery && hasExtends(defn)) { + addTypeHasFilter(sch, defn, providesTypeMap) + } // We need to call this at last as aggregateFields // should not be part of HasFilter or UpdatePayloadType etc. addAggregateFields(sch, defn, apolloServiceQuery) diff --git a/graphql/schema/schemagen_test.go b/graphql/schema/schemagen_test.go index 5231f829763..eae560a6c97 100644 --- a/graphql/schema/schemagen_test.go +++ b/graphql/schema/schemagen_test.go @@ -84,7 +84,6 @@ func TestSchemaString(t *testing.T) { str2, err := os.ReadFile(outputFileName) require.NoError(t, err) if diff := cmp.Diff(string(str2), newSchemaStr); diff != "" { - // fmt.Printf("Generated Schema (%s):\n%s\n", testFile.Name(), newSchemaStr) t.Errorf("schema mismatch - diff (-want +got):\n%s", diff) } }) diff --git a/graphql/schema/testdata/apolloservice/output/extended-types.graphql b/graphql/schema/testdata/apolloservice/output/extended-types.graphql index c038d23a08c..78b714e9052 100644 --- a/graphql/schema/testdata/apolloservice/output/extended-types.graphql +++ b/graphql/schema/testdata/apolloservice/output/extended-types.graphql @@ -290,51 +290,17 @@ input StringHashFilter { # Generated Types ####################### -type AddAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - numUids: Int -} - type AddMissionPayload { mission(filter: MissionFilter, order: MissionOrder, first: Int, offset: Int): [Mission] numUids: Int } -type AddProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - numUids: Int -} - -type AstronautAggregateResult { - count: Int - idMin: ID - idMax: ID - nameMin: String - nameMax: String - ageMin: Int - ageMax: Int - ageSum: Int - ageAvg: Float -} - -type DeleteAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - msg: String - numUids: Int -} - type DeleteMissionPayload { mission(filter: MissionFilter, order: MissionOrder, first: Int, offset: Int): [Mission] msg: String numUids: Int } -type DeleteProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - msg: String - numUids: Int -} - type MissionAggregateResult { count: Int designationMin: String @@ -345,47 +311,15 @@ type MissionAggregateResult { endDateMax: String } -type ProductAggregateResult { - count: Int - upcMin: String - upcMax: String - shippingEstimateMin: Float - shippingEstimateMax: Float - shippingEstimateSum: Float - shippingEstimateAvg: Float -} - -type UpdateAstronautPayload { - astronaut(filter: AstronautFilter, order: AstronautOrder, first: Int, offset: Int): [Astronaut] - numUids: Int -} - type UpdateMissionPayload { mission(filter: MissionFilter, order: MissionOrder, first: Int, offset: Int): [Mission] numUids: Int } -type UpdateProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - numUids: Int -} - ####################### # Generated Enums ####################### -enum AstronautHasFilter { - name - age - missions -} - -enum AstronautOrderable { - id - name - age -} - enum MissionHasFilter { crew designation @@ -399,68 +333,16 @@ enum MissionOrderable { endDate } -enum ProductHasFilter { - upc - inStock - shippingEstimate -} - -enum ProductOrderable { - upc - shippingEstimate -} - ####################### # Generated Inputs ####################### -input AddAstronautInput { - id: ID! - name: String - age: Int - missions: [MissionRef] -} - input AddMissionInput { - crew: [AstronautRef] designation: String! startDate: String endDate: String } -input AddProductInput { - upc: String! - inStock: Boolean - shippingEstimate: Float -} - -input AstronautFilter { - id: [ID!] - has: [AstronautHasFilter] - and: [AstronautFilter] - or: [AstronautFilter] - not: AstronautFilter -} - -input AstronautOrder { - asc: AstronautOrderable - desc: AstronautOrderable - then: AstronautOrder -} - -input AstronautPatch { - name: String - age: Int - missions: [MissionRef] -} - -input AstronautRef { - id: ID - name: String - age: Int - missions: [MissionRef] -} - input MissionFilter { id: [ID!] has: [MissionHasFilter] @@ -476,7 +358,6 @@ input MissionOrder { } input MissionPatch { - crew: [AstronautRef] designation: String startDate: String endDate: String @@ -484,56 +365,17 @@ input MissionPatch { input MissionRef { id: ID - crew: [AstronautRef] designation: String startDate: String endDate: String } -input ProductFilter { - upc: StringHashFilter - has: [ProductHasFilter] - and: [ProductFilter] - or: [ProductFilter] - not: ProductFilter -} - -input ProductOrder { - asc: ProductOrderable - desc: ProductOrderable - then: ProductOrder -} - -input ProductPatch { - upc: String - inStock: Boolean - shippingEstimate: Float -} - -input ProductRef { - upc: String - inStock: Boolean - shippingEstimate: Float -} - -input UpdateAstronautInput { - filter: AstronautFilter! - set: AstronautPatch - remove: AstronautPatch -} - input UpdateMissionInput { filter: MissionFilter! set: MissionPatch remove: MissionPatch } -input UpdateProductInput { - filter: ProductFilter! - set: ProductPatch - remove: ProductPatch -} - ####################### # Generated Query ####################### @@ -552,11 +394,5 @@ type Mutation { addMission(input: [AddMissionInput!]!): AddMissionPayload updateMission(input: UpdateMissionInput!): UpdateMissionPayload deleteMission(filter: MissionFilter!): DeleteMissionPayload - addAstronaut(input: [AddAstronautInput!]!): AddAstronautPayload - updateAstronaut(input: UpdateAstronautInput!): UpdateAstronautPayload - deleteAstronaut(filter: AstronautFilter!): DeleteAstronautPayload - addProduct(input: [AddProductInput!]!, upsert: Boolean): AddProductPayload - updateProduct(input: UpdateProductInput!): UpdateProductPayload - deleteProduct(filter: ProductFilter!): DeleteProductPayload } diff --git a/graphql/schema/testdata/apolloservice/output/single-extended-type.graphql b/graphql/schema/testdata/apolloservice/output/single-extended-type.graphql index ac3fe20c05b..7d45f7101e4 100644 --- a/graphql/schema/testdata/apolloservice/output/single-extended-type.graphql +++ b/graphql/schema/testdata/apolloservice/output/single-extended-type.graphql @@ -267,94 +267,3 @@ input StringHashFilter { in: [String] } -####################### -# Generated Types -####################### - -type AddProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - numUids: Int -} - -type DeleteProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - msg: String - numUids: Int -} - -type ProductAggregateResult { - count: Int - idMin: String - idMax: String - nameMin: String - nameMax: String -} - -type UpdateProductPayload { - product(filter: ProductFilter, order: ProductOrder, first: Int, offset: Int): [Product] - numUids: Int -} - -####################### -# Generated Enums -####################### - -enum ProductHasFilter { - id - name -} - -enum ProductOrderable { - id - name -} - -####################### -# Generated Inputs -####################### - -input AddProductInput { - id: String! - name: String! -} - -input ProductFilter { - id: StringHashFilter - has: [ProductHasFilter] - and: [ProductFilter] - or: [ProductFilter] - not: ProductFilter -} - -input ProductOrder { - asc: ProductOrderable - desc: ProductOrderable - then: ProductOrder -} - -input ProductPatch { - id: String - name: String -} - -input ProductRef { - id: String - name: String -} - -input UpdateProductInput { - filter: ProductFilter! - set: ProductPatch - remove: ProductPatch -} - -####################### -# Generated Mutations -####################### - -type Mutation { - addProduct(input: [AddProductInput!]!, upsert: Boolean): AddProductPayload - updateProduct(input: UpdateProductInput!): UpdateProductPayload - deleteProduct(filter: ProductFilter!): DeleteProductPayload -} -