From 687e9964123f6835f55d55925fbbdc6135f6664c Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 27 Feb 2025 10:23:06 -0800 Subject: [PATCH] Add compiler validation to error on resolver that returns plural server type Reviewed By: tyao1 Differential Revision: D70109268 fbshipit-source-id: a8a0fbc58ee2c3c4a22b6344799a7d4f1c348eef --- ...eturns_plural_server_type.invalid.expected | 42 +++++++++++++++++++ ...r_returns_plural_server_type.invalid.input | 33 +++++++++++++++ .../tests/relay_compiler_integration_test.rs | 9 +++- .../relay-transforms/src/client_edges.rs | 6 +++ .../crates/relay-transforms/src/errors.rs | 6 +++ ...al-client-edge-with-required-edge.expected | 40 +++++------------- ...ral-client-edge-with-required-edge.graphql | 12 +++++- ...relay-resolver-plural-client-edge.expected | 40 +++++------------- .../relay-resolver-plural-client-edge.graphql | 12 +++++- ...ed-client-edge-with-required-edge.expected | 40 +++++------------- ...red-client-edge-with-required-edge.graphql | 12 +++++- ...olver-plural-required-client-edge.expected | 40 +++++------------- ...solver-plural-required-client-edge.graphql | 12 +++++- 13 files changed, 175 insertions(+), 129 deletions(-) create mode 100644 compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected create mode 100644 compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.input diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected new file mode 100644 index 0000000000000..fe16dfdc119e7 --- /dev/null +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected @@ -0,0 +1,42 @@ +==================================== INPUT ==================================== +//- PersonComponent.js +graphql`query PersonComponentQuery { + plural_server @waterfall { + name + } +}` + +//- QueryResolvers.js +/** + * @RelayResolver Query.plural_server: [User] + */ + +//- relay.config.json +{ + "language": "flow", + "jsModuleFormat": "haste", + "schema": "schema.graphql" +} + +//- schema.graphql +type Query { + greeting: String + node(id: ID!): Node +} + +interface Node { + id: ID! +} + +type User implements Node { + id: ID! + name: String +} +==================================== OUTPUT =================================== +✖︎ Unexpected Relay Resolver returning plual edge to type defined on the server. Relay Resolvers do not curretly support returning plural edges to server types. As a work around, consider defining a plural edge to a client type which has a singular edge to the server type. + + QueryResolvers.js:2:25 + 1 │ * + 2 │ * @RelayResolver Query.plural_server: [User] + │ ^^^^^^^^^^^^^ + 3 │ diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.input b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.input new file mode 100644 index 0000000000000..65199a9a5f064 --- /dev/null +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.input @@ -0,0 +1,33 @@ +//- PersonComponent.js +graphql`query PersonComponentQuery { + plural_server @waterfall { + name + } +}` + +//- QueryResolvers.js +/** + * @RelayResolver Query.plural_server: [User] + */ + +//- relay.config.json +{ + "language": "flow", + "jsModuleFormat": "haste", + "schema": "schema.graphql" +} + +//- schema.graphql +type Query { + greeting: String + node(id: ID!): Node +} + +interface Node { + id: ID! +} + +type User implements Node { + id: ID! + name: String +} diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs b/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs index aa69bd26c82fa..f57352a16e06e 100644 --- a/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<73cd290ab5054a643e2e27b6b67d7d1b>> + * @generated SignedSource<<18ad721b702d974f6b034f393230738d>> */ mod relay_compiler_integration; @@ -278,6 +278,13 @@ async fn resolver_returns_interface_of_live_and_non_live_strong_model_type() { test_fixture(transform_fixture, file!(), "resolver_returns_interface_of_live_and_non_live_strong_model_type.input", "relay_compiler_integration/fixtures/resolver_returns_interface_of_live_and_non_live_strong_model_type.expected", input, expected).await; } +#[tokio::test] +async fn resolver_returns_plural_server_type_invalid() { + let input = include_str!("relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.input"); + let expected = include_str!("relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected"); + test_fixture(transform_fixture, file!(), "resolver_returns_plural_server_type.invalid.input", "relay_compiler_integration/fixtures/resolver_returns_plural_server_type.invalid.expected", input, expected).await; +} + #[tokio::test] async fn resolver_returns_union_of_cse() { let input = include_str!("relay_compiler_integration/fixtures/resolver_returns_union_of_cse.input"); diff --git a/compiler/crates/relay-transforms/src/client_edges.rs b/compiler/crates/relay-transforms/src/client_edges.rs index a5e63524255ef..74b932f88ffeb 100644 --- a/compiler/crates/relay-transforms/src/client_edges.rs +++ b/compiler/crates/relay-transforms/src/client_edges.rs @@ -485,6 +485,12 @@ impl<'program, 'pc> ClientEdgesTransform<'program, 'pc> { waterfall_directive: Option<&Directive>, selections: Vec, ) -> ClientEdgeMetadataDirective { + if field_type.type_.is_list() { + self.errors.push(Diagnostic::error( + ValidationMessage::ClientEdgeToServerObjectList, + field_type.name.location, + )); + } // Client Edges to server objects must be annotated with @waterfall if waterfall_directive.is_none() { self.errors.push(Diagnostic::error_with_data( diff --git a/compiler/crates/relay-transforms/src/errors.rs b/compiler/crates/relay-transforms/src/errors.rs index 30794a4b4a72d..7af5b7b2a917e 100644 --- a/compiler/crates/relay-transforms/src/errors.rs +++ b/compiler/crates/relay-transforms/src/errors.rs @@ -131,6 +131,12 @@ pub enum ValidationMessage { name: StringKey, type_name: ObjectName, }, + + #[error( + "Unexpected Relay Resolver returning plual edge to type defined on the server. Relay Resolvers do not curretly support returning plural edges to server types. As a work around, consider defining a plural edge to a client type which has a singular edge to the server type." + )] + ClientEdgeToServerObjectList, + #[error("Invalid directive combination. @alias may not be combined with other directives.")] FragmentAliasIncompatibleDirective, diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.expected b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.expected index dbe459b6b87e4..d011c9721e97b 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.expected +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.expected @@ -5,7 +5,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -13,24 +13,18 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User!] @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser!] + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } ==================================== OUTPUT =================================== -import type { RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType } from "RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$variables = {| - id: string, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +node: ?{| - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - |}, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends = {| - response: ClientEdgeQuery_relayResolver_Query_me__best_friends$data, - variables: ClientEdgeQuery_relayResolver_Query_me__best_friends$variables, -|}; -------------------------------------------------------------------------------- import type { DataID } from "relay-runtime"; import type { relayResolver_BestFriendResolverFragment_name$key } from "relayResolver_BestFriendResolverFragment_name.graphql"; import userBestFriendsResolverType from "BestFriendResolver"; @@ -55,20 +49,6 @@ export type relayResolver_Query = {| |}; ------------------------------------------------------------------------------- import type { FragmentType } from "relay-runtime"; -declare export opaque type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType: FragmentType; -import type { ClientEdgeQuery_relayResolver_Query_me__best_friends$variables } from "ClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +id: string, - +name: ?string, - +$fragmentType: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, -|}; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$key = { - +$data?: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data, - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - ... -}; -------------------------------------------------------------------------------- -import type { FragmentType } from "relay-runtime"; declare export opaque type relayResolver_BestFriendResolverFragment_name$fragmentType: FragmentType; export type relayResolver_BestFriendResolverFragment_name$data = {| +name: ?string, diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.graphql b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.graphql index d1c5ee3543017..7c3e2e9acc1b2 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.graphql +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge-with-required-edge.graphql @@ -4,7 +4,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -12,6 +12,14 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User!] @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser!] + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.expected b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.expected index 3a8df881bba83..74f55feefe7b1 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.expected +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.expected @@ -5,7 +5,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -13,24 +13,18 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User] @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser] + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } ==================================== OUTPUT =================================== -import type { RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType } from "RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$variables = {| - id: string, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +node: ?{| - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - |}, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends = {| - response: ClientEdgeQuery_relayResolver_Query_me__best_friends$data, - variables: ClientEdgeQuery_relayResolver_Query_me__best_friends$variables, -|}; -------------------------------------------------------------------------------- import type { DataID } from "relay-runtime"; import type { relayResolver_BestFriendResolverFragment_name$key } from "relayResolver_BestFriendResolverFragment_name.graphql"; import userBestFriendsResolverType from "BestFriendResolver"; @@ -55,20 +49,6 @@ export type relayResolver_Query = {| |}; ------------------------------------------------------------------------------- import type { FragmentType } from "relay-runtime"; -declare export opaque type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType: FragmentType; -import type { ClientEdgeQuery_relayResolver_Query_me__best_friends$variables } from "ClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +id: string, - +name: ?string, - +$fragmentType: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, -|}; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$key = { - +$data?: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data, - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - ... -}; -------------------------------------------------------------------------------- -import type { FragmentType } from "relay-runtime"; declare export opaque type relayResolver_BestFriendResolverFragment_name$fragmentType: FragmentType; export type relayResolver_BestFriendResolverFragment_name$data = {| +name: ?string, diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.graphql b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.graphql index 63c02afd5ec52..db0ebd4589fe7 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.graphql +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-client-edge.graphql @@ -4,7 +4,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -12,6 +12,14 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User] @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser] + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.expected b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.expected index d0f9898a42683..8b5a2986dea14 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.expected +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.expected @@ -5,7 +5,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -13,24 +13,18 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User!]! @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser!]! + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } ==================================== OUTPUT =================================== -import type { RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType } from "RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$variables = {| - id: string, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +node: ?{| - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - |}, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends = {| - response: ClientEdgeQuery_relayResolver_Query_me__best_friends$data, - variables: ClientEdgeQuery_relayResolver_Query_me__best_friends$variables, -|}; -------------------------------------------------------------------------------- import type { DataID } from "relay-runtime"; import type { relayResolver_BestFriendResolverFragment_name$key } from "relayResolver_BestFriendResolverFragment_name.graphql"; import userBestFriendsResolverType from "BestFriendResolver"; @@ -55,20 +49,6 @@ export type relayResolver_Query = {| |}; ------------------------------------------------------------------------------- import type { FragmentType } from "relay-runtime"; -declare export opaque type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType: FragmentType; -import type { ClientEdgeQuery_relayResolver_Query_me__best_friends$variables } from "ClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +id: string, - +name: ?string, - +$fragmentType: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, -|}; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$key = { - +$data?: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data, - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - ... -}; -------------------------------------------------------------------------------- -import type { FragmentType } from "relay-runtime"; declare export opaque type relayResolver_BestFriendResolverFragment_name$fragmentType: FragmentType; export type relayResolver_BestFriendResolverFragment_name$data = {| +name: ?string, diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.graphql b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.graphql index ac9752b4046f4..e3a2bb6f955ba 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.graphql +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge-with-required-edge.graphql @@ -4,7 +4,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -12,6 +12,14 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User!]! @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser!]! + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.expected b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.expected index 84956e9fc5a43..26161ef29372b 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.expected +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.expected @@ -5,7 +5,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -13,24 +13,18 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User]! @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser]! + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) } ==================================== OUTPUT =================================== -import type { RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType } from "RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$variables = {| - id: string, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +node: ?{| - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - |}, -|}; -export type ClientEdgeQuery_relayResolver_Query_me__best_friends = {| - response: ClientEdgeQuery_relayResolver_Query_me__best_friends$data, - variables: ClientEdgeQuery_relayResolver_Query_me__best_friends$variables, -|}; -------------------------------------------------------------------------------- import type { DataID } from "relay-runtime"; import type { relayResolver_BestFriendResolverFragment_name$key } from "relayResolver_BestFriendResolverFragment_name.graphql"; import userBestFriendsResolverType from "BestFriendResolver"; @@ -55,20 +49,6 @@ export type relayResolver_Query = {| |}; ------------------------------------------------------------------------------- import type { FragmentType } from "relay-runtime"; -declare export opaque type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType: FragmentType; -import type { ClientEdgeQuery_relayResolver_Query_me__best_friends$variables } from "ClientEdgeQuery_relayResolver_Query_me__best_friends.graphql"; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data = {| - +id: string, - +name: ?string, - +$fragmentType: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, -|}; -export type RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$key = { - +$data?: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$data, - +$fragmentSpreads: RefetchableClientEdgeQuery_relayResolver_Query_me__best_friends$fragmentType, - ... -}; -------------------------------------------------------------------------------- -import type { FragmentType } from "relay-runtime"; declare export opaque type relayResolver_BestFriendResolverFragment_name$fragmentType: FragmentType; export type relayResolver_BestFriendResolverFragment_name$data = {| +name: ?string, diff --git a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.graphql b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.graphql index 2151c70bc603b..dd5ce21d14303 100644 --- a/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.graphql +++ b/compiler/crates/relay-typegen/tests/generate_flow/fixtures/relay-resolver-plural-required-client-edge.graphql @@ -4,7 +4,7 @@ fragment relayResolver_BestFriendResolverFragment_name on User { query relayResolver_Query { me { - best_friends @waterfall { + best_friends { name } } @@ -12,6 +12,14 @@ query relayResolver_Query { # %extensions% +type ClientUser { + name: String +} + extend type User { - best_friends: [User]! @relay_resolver(fragment_name: "relayResolver_BestFriendResolverFragment_name", import_path: "./foo/bar/baz/BestFriendResolver.js") + best_friends: [ClientUser]! + @relay_resolver( + fragment_name: "relayResolver_BestFriendResolverFragment_name" + import_path: "./foo/bar/baz/BestFriendResolver.js" + ) }