Skip to content

Commit

Permalink
@required should bubble nullable to parent semantic-non-null linked f…
Browse files Browse the repository at this point in the history
…ield

Reviewed By: captbaritone

Differential Revision: D58704613

fbshipit-source-id: 467e889213008efd1933cebc203fd2c6574be698
  • Loading branch information
gordyf authored and facebook-github-bot committed Jun 18, 2024
1 parent d61ce03 commit 349334e
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
==================================== INPUT ====================================
//- PersonComponent.js
graphql`fragment PersonComponentFragment on Query @throwOnFieldError {
some_person {
name @required(action: LOG)
}
}`

//- relay.config.json
{
"language": "flow",
"jsModuleFormat": "haste",
"schema": "schema.graphql",
"experimentalEmitSemanticNullabilityTypes": true
}

//- schema.graphql
type Query {
some_person: Person @semanticNonNull
}

type Person {
name: String
}
==================================== OUTPUT ===================================
//- __generated__/PersonComponentFragment.graphql.js
/**
* <auto-generated> SignedSource<<7166e6a631b0ea4858c7b2d8825c193e>>
* @flow
* @lightSyntaxTransform
* @nogrep
*/

/* eslint-disable */

'use strict';

/*::
import type { Fragment, ReaderFragment } from 'relay-runtime';
import type { FragmentType } from "relay-runtime";
declare export opaque type PersonComponentFragment$fragmentType: FragmentType;
export type PersonComponentFragment$data = {|
+some_person: ?{|
+name: string,
|},
+$fragmentType: PersonComponentFragment$fragmentType,
|};
export type PersonComponentFragment$key = {
+$data?: PersonComponentFragment$data,
+$fragmentSpreads: PersonComponentFragment$fragmentType,
...
};
*/

var node/*: ReaderFragment*/ = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": {
"throwOnFieldError": true
},
"name": "PersonComponentFragment",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Person",
"kind": "LinkedField",
"name": "some_person",
"plural": false,
"selections": [
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
"action": "LOG",
"path": "some_person.name"
}
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
};

(node/*: any*/).hash = "76fce3bfedd135a11ccda0abc265eb69";

module.exports = ((node/*: any*/)/*: Fragment<
PersonComponentFragment$fragmentType,
PersonComponentFragment$data,
>*/);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//- PersonComponent.js
graphql`fragment PersonComponentFragment on Query @throwOnFieldError {
some_person {
name @required(action: LOG)
}
}`

//- relay.config.json
{
"language": "flow",
"jsModuleFormat": "haste",
"schema": "schema.graphql",
"experimentalEmitSemanticNullabilityTypes": true
}

//- schema.graphql
type Query {
some_person: Person @semanticNonNull
}

type Person {
name: String
}
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<<748d236bdfe163a6942c2efcf0cafcab>>
* @generated SignedSource<<399f84b890051cc63ed0d860bf73cd5e>>
*/

mod relay_compiler_integration;
Expand Down Expand Up @@ -313,6 +313,13 @@ async fn resolvers_schema_module_apply_to_normalization_ast() {
test_fixture(transform_fixture, file!(), "resolvers_schema_module_apply_to_normalization_ast.input", "relay_compiler_integration/fixtures/resolvers_schema_module_apply_to_normalization_ast.expected", input, expected).await;
}

#[tokio::test]
async fn semantic_null_require_bubbling() {
let input = include_str!("relay_compiler_integration/fixtures/semantic_null_require_bubbling.input");
let expected = include_str!("relay_compiler_integration/fixtures/semantic_null_require_bubbling.expected");
test_fixture(transform_fixture, file!(), "semantic_null_require_bubbling.input", "relay_compiler_integration/fixtures/semantic_null_require_bubbling.expected", input, expected).await;
}

#[tokio::test]
async fn simple_fragment() {
let input = include_str!("relay_compiler_integration/fixtures/simple_fragment.input");
Expand Down
7 changes: 4 additions & 3 deletions compiler/crates/relay-typegen/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2422,10 +2422,11 @@ fn apply_directive_nullability(
field: &Field,
schema_field_directives: &[Directive],
) -> TypeReference<Type> {
match field.directives.named(*SEMANTIC_NON_NULL_DIRECTIVE) {
let field_type = match field.directives.named(*SEMANTIC_NON_NULL_DIRECTIVE) {
Some(_) => field.semantic_type(),
None => apply_required_directive_nullability(&field.type_, schema_field_directives),
}
None => field.type_.clone(),
};
apply_required_directive_nullability(&field_type, schema_field_directives)
}

fn apply_required_directive_nullability(
Expand Down

0 comments on commit 349334e

Please sign in to comment.