Skip to content

Commit

Permalink
Allow legacy resolvers with @rootFragment on model types
Browse files Browse the repository at this point in the history
Reviewed By: andreqi

Differential Revision: D45456334

fbshipit-source-id: e133da737c83dd9f389254ca7b87e15367cd3854
  • Loading branch information
captbaritone authored and facebook-github-bot committed May 1, 2023
1 parent af88daf commit 0fe2553
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 4 deletions.
6 changes: 3 additions & 3 deletions compiler/crates/relay-docblock/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,12 +829,12 @@ impl ResolverIr for RelayResolverIr {
object: Option<&Object>,
_: SchemaInfo<'_, '_>,
) -> Option<RootFragment> {
get_root_fragment_for_object(object).or_else(|| {
self.root_fragment.map(|fragment| RootFragment {
self.root_fragment
.map(|fragment| RootFragment {
fragment,
inject_fragment_data: None,
})
})
.or_else(|| get_root_fragment_for_object(object))
}

fn output_type(&self) -> Option<OutputType> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
==================================== INPUT ====================================
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @RelayResolver MyType
*/

/**
* @RelayResolver
* @onType MyType
* @fieldName my_field
* @rootFragment myRootFragment
*/

graphql`
fragment myRootFragment on MyType {
id
}
`
==================================== OUTPUT ===================================
type MyType @__RelayResolverModel {
id: ID!
__relay_model_instance: Int @relay_resolver(import_path: "/path/to/test/fixture/legacy-relay-resolver-with-root-fragment-on-model.js", fragment_name: "MyType__id", inject_fragment_data: "id", import_name: "MyType") @unselectable(reason: "This field is intended only for Relay's internal use")
}


extend type MyType {
my_field: RelayResolverValue @relay_resolver(import_path: "/path/to/test/fixture/legacy-relay-resolver-with-root-fragment-on-model.js", fragment_name: "myRootFragment", import_name: "my_field")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @RelayResolver MyType
*/

/**
* @RelayResolver
* @onType MyType
* @fieldName my_field
* @rootFragment myRootFragment
*/

graphql`
fragment myRootFragment on MyType {
id
}
`
9 changes: 8 additions & 1 deletion compiler/crates/relay-docblock/tests/to_schema_test.rs
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<<2e5845b82e759855402d5ec1f62cd56f>>
* @generated SignedSource<<b0c707529f8b045554b20820c2e3e271>>
*/

mod to_schema;
Expand Down Expand Up @@ -33,6 +33,13 @@ fn client_edge_to_plural_server_object_relay_resolver_invalid() {
test_fixture(transform_fixture, "client-edge-to-plural-server-object-relay-resolver.invalid.js", "to_schema/fixtures/client-edge-to-plural-server-object-relay-resolver.invalid.expected", input, expected);
}

#[test]
fn legacy_relay_resolver_with_root_fragment_on_model() {
let input = include_str!("to_schema/fixtures/legacy-relay-resolver-with-root-fragment-on-model.js");
let expected = include_str!("to_schema/fixtures/legacy-relay-resolver-with-root-fragment-on-model.expected");
test_fixture(transform_fixture, "legacy-relay-resolver-with-root-fragment-on-model.js", "to_schema/fixtures/legacy-relay-resolver-with-root-fragment-on-model.expected", input, expected);
}

#[test]
fn relay_resolver() {
let input = include_str!("to_schema/fixtures/relay-resolver.js");
Expand Down
29 changes: 29 additions & 0 deletions packages/react-relay/__tests__/RelayResolverModel-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,35 @@ describe.each([
expect(renderer.toJSON()).toEqual('TODO-1');
});

test('read a field with its own root fragment defined using legacy non-terse syntax', () => {
function TodoComponentWithFieldWithRootFragmentComponent(props: {
todoID: string,
}) {
const data = useClientQuery(
graphql`
query RelayResolverModelTestFieldWithRootFragmentLegacyQuery(
$id: ID!
) {
todo_model(todoID: $id) {
capitalized_id_legacy
}
}
`,
{id: props.todoID},
);
return data?.todo_model?.capitalized_id_legacy;
}

addTodo('Test todo');

const renderer = TestRenderer.create(
<EnvironmentWrapper environment={environment}>
<TodoComponentWithFieldWithRootFragmentComponent todoID="todo-1" />
</EnvironmentWrapper>,
);
expect(renderer.toJSON()).toEqual('TODO-1');
});

test('read interface field', () => {
function TodoComponentWithInterfaceComponent(props: {todoID: string}) {
const data = useClientQuery(
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions packages/relay-runtime/store/__tests__/resolvers/TodoModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import type {LiveState} from '../../experimental-live-resolvers/LiveResolverStore';
import type {TodoModelCapitalizedID$key} from './__generated__/TodoModelCapitalizedID.graphql';
import type {TodoModelCapitalizedIDLegacy$key} from './__generated__/TodoModelCapitalizedIDLegacy.graphql';
import type {TodoDescription} from './TodoDescription';
import type {ConcreteClientEdgeResolverReturnType} from 'relay-runtime';
import type {TodoItem} from 'relay-runtime/store/__tests__/resolvers/ExampleTodoStore';
Expand Down Expand Up @@ -65,6 +66,26 @@ function capitalized_id(key: TodoModelCapitalizedID$key): ?string {
return todo.id.toUpperCase();
}

/**
* @RelayResolver
* @fieldName capitalized_id_legacy
* @onType TodoModel
* @rootFragment TodoModelCapitalizedIDLegacy
*
* Like `capitalized_id`, but implemented using the non-terse legacy syntax
*/
function capitalized_id_legacy(key: TodoModelCapitalizedIDLegacy$key): ?string {
const todo = readFragment(
graphql`
fragment TodoModelCapitalizedIDLegacy on TodoModel {
id
}
`,
key,
);
return todo.id.toUpperCase();
}

/**
* @RelayResolver TodoModel.fancy_description: TodoDescription
*/
Expand Down Expand Up @@ -118,6 +139,7 @@ function live_todo_description(args: {

module.exports = {
capitalized_id,
capitalized_id_legacy,
todo_model_null,
TodoModel,
description,
Expand Down
Loading

0 comments on commit 0fe2553

Please sign in to comment.