Skip to content

Commit

Permalink
Emit semanticNonNull in generated schema
Browse files Browse the repository at this point in the history
Reviewed By: captbaritone

Differential Revision: D55775523

fbshipit-source-id: 6ef31680a4aa5099c8486e6ae70699fdbbf104c4
  • Loading branch information
gordyf authored and facebook-github-bot committed Apr 4, 2024
1 parent ddfa2b0 commit d1cf472
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 3 deletions.
15 changes: 13 additions & 2 deletions compiler/crates/relay-docblock/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ lazy_static! {
DirectiveName("deprecated".intern());
static ref DEPRECATED_REASON_ARGUMENT_NAME: ArgumentName = ArgumentName("reason".intern());
static ref MODEL_CUSTOM_SCALAR_TYPE_SUFFIX: StringKey = "Model".intern();
static ref SEMANTIC_NON_NULL_DIRECTIVE_NAME: DirectiveName =
DirectiveName("semanticNonNull".intern());
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -431,14 +433,13 @@ trait ResolverIr: Sized {
object: Option<&Object>,
project_config: ResolverProjectConfig<'_, '_>,
) -> Vec<ConstantDirective> {
let location = self.location();
let span = location.span();
let mut directives: Vec<ConstantDirective> = vec![
self.directive(object, project_config),
resolver_source_hash_directive(self.source_hash()),
];

if let Some(deprecated) = self.deprecated() {
let span = deprecated.key_location().span();
directives.push(ConstantDirective {
span,
at: dummy_token(span),
Expand All @@ -452,6 +453,16 @@ trait ResolverIr: Sized {
})
}

if let Some(semantic_non_null) = self.semantic_non_null() {
let span = semantic_non_null.key_location.span();
directives.push(ConstantDirective {
span,
at: dummy_token(span),
name: string_key_as_identifier(SEMANTIC_NON_NULL_DIRECTIVE_NAME.0),
arguments: None,
})
}

directives
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
==================================== 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.
*/

// relay:allow_legacy_verbose_syntax

/**
* @RelayResolver
*
* @onType User
* @fieldName favorite_page
* @rootFragment myRootFragment
* @semanticNonNull
*
* The user's favorite page! They probably clicked something in the UI
* to tell us that it was their favorite page and then we put that in a
* database or something. Then we got that info out again and put it out
* again. Anyway, I'm rambling now. Its a page that the user likes. A lot.
*/

graphql`
fragment myRootFragment on User {
id
}
`
==================================== OUTPUT ===================================
extend type User {
favorite_page: RelayResolverValue @relay_resolver(import_path: "/path/to/test/fixture/relay-resolver-semantic-non-null.js", fragment_name: "myRootFragment", import_name: "favorite_page") @resolver_source_hash(value: "5f25cc9a9a8677d930bf1e8b447a769d") @semanticNonNull
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 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.
*/

// relay:allow_legacy_verbose_syntax

/**
* @RelayResolver
*
* @onType User
* @fieldName favorite_page
* @rootFragment myRootFragment
* @semanticNonNull
*
* The user's favorite page! They probably clicked something in the UI
* to tell us that it was their favorite page and then we put that in a
* database or something. Then we got that info out again and put it out
* again. Anyway, I'm rambling now. Its a page that the user likes. A lot.
*/

graphql`
fragment myRootFragment on User {
id
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
==================================== 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 User.favorite_page: Page
* @rootFragment myRootFragment
* @semanticNonNull
*
* The user's favorite page! They probably clicked something in the UI
* to tell us that it was their favorite page and then we put that in a
* database or something. Then we got that info out again and put it out
* again. Anyway, I'm rambling now. Its a page that the user likes. A lot.
*/

graphql`
fragment myRootFragment on User {
id
}
`
==================================== OUTPUT ===================================
extend type User {
favorite_page: Page @relay_resolver(import_path: "/path/to/test/fixture/terse-relay-resolver-semantic-non-null.js", fragment_name: "myRootFragment", import_name: "favorite_page") @resolver_source_hash(value: "27524a0a58f36e5480cea6a72c2c0a88") @semanticNonNull
}
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 User.favorite_page: Page
* @rootFragment myRootFragment
* @semanticNonNull
*
* The user's favorite page! They probably clicked something in the UI
* to tell us that it was their favorite page and then we put that in a
* database or something. Then we got that info out again and put it out
* again. Anyway, I'm rambling now. Its a page that the user likes. A lot.
*/

graphql`
fragment myRootFragment on User {
id
}
`
16 changes: 15 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<<1ffacfeab59157dc3df605ce3d320d2c>>
* @generated SignedSource<<352f018a582767211d069064d155a271>>
*/

mod to_schema;
Expand Down Expand Up @@ -131,6 +131,13 @@ async fn relay_resolver_on_type_with_interface_invalid() {
test_fixture(transform_fixture, file!(), "relay-resolver-on-type-with-interface.invalid.js", "to_schema/fixtures/relay-resolver-on-type-with-interface.invalid.expected", input, expected).await;
}

#[tokio::test]
async fn relay_resolver_semantic_non_null() {
let input = include_str!("to_schema/fixtures/relay-resolver-semantic-non-null.js");
let expected = include_str!("to_schema/fixtures/relay-resolver-semantic-non-null.expected");
test_fixture(transform_fixture, file!(), "relay-resolver-semantic-non-null.js", "to_schema/fixtures/relay-resolver-semantic-non-null.expected", input, expected).await;
}

#[tokio::test]
async fn relay_resolver_strong_object() {
let input = include_str!("to_schema/fixtures/relay-resolver-strong-object.js");
Expand Down Expand Up @@ -243,6 +250,13 @@ async fn terse_relay_resolver_non_existent_type_invalid() {
test_fixture(transform_fixture, file!(), "terse-relay-resolver-non-existent-type.invalid.js", "to_schema/fixtures/terse-relay-resolver-non-existent-type.invalid.expected", input, expected).await;
}

#[tokio::test]
async fn terse_relay_resolver_semantic_non_null() {
let input = include_str!("to_schema/fixtures/terse-relay-resolver-semantic-non-null.js");
let expected = include_str!("to_schema/fixtures/terse-relay-resolver-semantic-non-null.expected");
test_fixture(transform_fixture, file!(), "terse-relay-resolver-semantic-non-null.js", "to_schema/fixtures/terse-relay-resolver-semantic-non-null.expected", input, expected).await;
}

#[tokio::test]
async fn terse_relay_resolver_with_output_type() {
let input = include_str!("to_schema/fixtures/terse-relay-resolver-with-output-type.js");
Expand Down

0 comments on commit d1cf472

Please sign in to comment.