Skip to content

Commit

Permalink
Include Relay resolver import type when field is selected on query as…
Browse files Browse the repository at this point in the history
… well (#4820)

Summary:
A [previous PR](#4791) made changes to fix TS import codegen for queries/fragments that select Relay resolver fields. However, when that PR was manually imported, it was only partially applied and missed the necessary change to make codegen work for queries, only the fragments fix was put in place. This PR re-does that change but also adds a test to verify that the code gets generated properly on queries. Previously there were no Relay resolver tests that verified codegen behavior on queries.

Relevant issue: #4790

Pull Request resolved: #4820

Reviewed By: tyao1

Differential Revision: D64412751

Pulled By: captbaritone

fbshipit-source-id: e63b5429d72cab1c187463f2effc94c23890e14f
  • Loading branch information
ernieturner authored and facebook-github-bot committed Nov 4, 2024
1 parent 5b7dc1f commit 682ac5a
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 5 deletions.
7 changes: 3 additions & 4 deletions compiler/crates/relay-typegen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,9 @@ pub(crate) fn write_operation_type_exports_section(
if custom_error_import.is_some() {
write_import_custom_type(custom_error_import, writer)?;
}
// TODO: Add proper support for Resolver type generation in typescript: https://github.com/facebook/relay/issues/4772
if typegen_context.project_config.typegen_config.language == TypegenLanguage::Flow {
write_relay_resolver_imports(imported_resolvers, writer)?;
}

write_relay_resolver_imports(imported_resolvers, writer)?;

write_split_raw_response_type_imports(typegen_context, imported_raw_response_types, writer)?;

let mut input_object_types = IndexMap::default();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
==================================== INPUT ====================================
query Foo_user @raw_response_type {
me {
pop_star_name
}

}

fragment PopStarNameResolverFragment_name on User {
name
address {
street
}
parents {
lastName
}
}

# %extensions%

extend type User {
pop_star_name: RelayResolverValue @relay_resolver(fragment_name: "PopStarNameResolverFragment_name", import_path: "PopStarNameResolver", has_output_type: true)
}
==================================== OUTPUT ===================================
import { FragmentRefs } from "relay-runtime";
import userPopStarNameResolverType from "PopStarNameResolver";
// Type assertion validating that `userPopStarNameResolverType` resolver is correctly implemented.
// A type error here indicates that the type signature of the resolver module is incorrect.
(userPopStarNameResolverType satisfies (
rootKey: PopStarNameResolverFragment_name$key,
) => unknown | null | undefined);
export type Foo_user$variables = Record<PropertyKey, never>;
export type Foo_user$data = {
readonly me: {
readonly pop_star_name: ReturnType<typeof userPopStarNameResolverType> | null | undefined;
} | null | undefined;
};
export type Foo_user$rawResponse = {
readonly me: {
readonly address: {
readonly street: string | null | undefined;
} | null | undefined;
readonly id: string;
readonly name: string | null | undefined;
readonly parents: ReadonlyArray<{
readonly id: string;
readonly lastName: string | null | undefined;
}>;
} | {
readonly id: string;
} | null | undefined;
};
export type Foo_user = {
rawResponse: Foo_user$rawResponse;
response: Foo_user$data;
variables: Foo_user$variables;
};
-------------------------------------------------------------------------------
import { FragmentRefs } from "relay-runtime";
export type PopStarNameResolverFragment_name$data = {
readonly address: {
readonly street: string | null | undefined;
} | null | undefined;
readonly name: string | null | undefined;
readonly parents: ReadonlyArray<{
readonly lastName: string | null | undefined;
}>;
readonly " $fragmentType": "PopStarNameResolverFragment_name";
};
export type PopStarNameResolverFragment_name$key = {
readonly " $data"?: PopStarNameResolverFragment_name$data;
readonly " $fragmentSpreads": FragmentRefs<"PopStarNameResolverFragment_name">;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
query Foo_user @raw_response_type {
me {
pop_star_name
}

}

fragment PopStarNameResolverFragment_name on User {
name
address {
street
}
parents {
lastName
}
}

# %extensions%

extend type User {
pop_star_name: RelayResolverValue @relay_resolver(fragment_name: "PopStarNameResolverFragment_name", import_path: "PopStarNameResolver", has_output_type: true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<<dc6df4bac160f12fe89c63e98c18f01d>>
* @generated SignedSource<<1903a7cf2db933f9227f3b83bb115fb5>>
*/

mod generate_typescript;
Expand Down Expand Up @@ -334,6 +334,13 @@ async fn relay_client_id_field() {
test_fixture(transform_fixture, file!(), "relay-client-id-field.graphql", "generate_typescript/fixtures/relay-client-id-field.expected", input, expected).await;
}

#[tokio::test]
async fn relay_resolver_on_query_with_output_type() {
let input = include_str!("generate_typescript/fixtures/relay-resolver-on-query-with-output-type.graphql");
let expected = include_str!("generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected");
test_fixture(transform_fixture, file!(), "relay-resolver-on-query-with-output-type.graphql", "generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected", input, expected).await;
}

#[tokio::test]
async fn relay_resolver_with_output_type_client_interface() {
let input = include_str!("generate_typescript/fixtures/relay-resolver-with-output-type-client-interface.graphql");
Expand Down

0 comments on commit 682ac5a

Please sign in to comment.