diff --git a/compiler/crates/graphql-ir/src/ir.rs b/compiler/crates/graphql-ir/src/ir.rs index 88b57841bf3b5..7d9887a2d9a0a 100644 --- a/compiler/crates/graphql-ir/src/ir.rs +++ b/compiler/crates/graphql-ir/src/ir.rs @@ -80,7 +80,7 @@ pub struct FragmentDefinition { } /// A variable definition of an operation or fragment -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct VariableDefinition { pub name: WithLocation, pub type_: TypeReference, @@ -326,7 +326,7 @@ impl Condition { // Associated Types /// @ Name Arguments? -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct Directive { pub name: WithLocation, pub arguments: Vec, diff --git a/compiler/crates/relay-codegen/src/build_ast.rs b/compiler/crates/relay-codegen/src/build_ast.rs index 151ad417faa9a..171f4bb1ddfcd 100644 --- a/compiler/crates/relay-codegen/src/build_ast.rs +++ b/compiler/crates/relay-codegen/src/build_ast.rs @@ -1452,10 +1452,21 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> { inline_directive_data: &InlineDirectiveMetadata, ) -> Primitive { let selections = self.build_selections(context, inline_fragment.selections.iter()); + let args = self.build_arguments(&inline_directive_data.arguments); + let argument_definitions = self.build_fragment_variable_definitions( + &inline_directive_data.variable_definitions, + &inline_directive_data.used_global_variables, + ); + Primitive::Key(self.object(object! { kind: Primitive::String(CODEGEN_CONSTANTS.inline_data_fragment_spread), name: Primitive::String(inline_directive_data.fragment_name), selections: selections, + args: match args { + None => Primitive::SkippableNull, + Some(key) => Primitive::Key(key), + }, + argument_definitions: argument_definitions, })) } diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-global-vars.expected b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-global-vars.expected index 7173049cfc5d2..970b17ecf75de 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-global-vars.expected +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-global-vars.expected @@ -53,6 +53,13 @@ fragment inlineDataFragmentGlobalVarsProfile on User @inline { ], "storageKey": null } + ], + "args": null, + "argumentDefinitions": [ + { + "kind": "RootArgument", + "name": "pictureSize" + } ] } ], diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.expected b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.expected index 7cf3edc26df19..1a0c6356ee864 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.expected +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.expected @@ -1,5 +1,4 @@ ==================================== INPUT ==================================== -# expected-to-throw fragment inlineDataFragmentLocalArgsFragment on Query { usingLiteralPassedValue: me { ...inlineDataFragmentLocalArgsProfile @arguments(sizeArg: [100]) @@ -19,53 +18,191 @@ fragment inlineDataFragmentLocalArgsProfile on User uri } } -==================================== ERROR ==================================== -✖︎ Variables from @argumentDefinitions are not yet supported inside @inline fragments. - - inline-data-fragment-local-args.graphql:14:10 - 13 │ - 14 │ fragment inlineDataFragmentLocalArgsProfile on User - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 15 │ @inline - - ℹ︎ Variable used: - - inline-data-fragment-local-args.graphql:16:24 - 15 │ @inline - 16 │ @argumentDefinitions(sizeArg: {type: "[Int]", defaultValue: [50]}) { - │ ^^^^^^^ - 17 │ profilePicture(size: $sizeArg) { - - -✖︎ Variables from @argumentDefinitions are not yet supported inside @inline fragments. - - inline-data-fragment-local-args.graphql:14:10 - 13 │ - 14 │ fragment inlineDataFragmentLocalArgsProfile on User - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 15 │ @inline - - ℹ︎ Variable used: - - inline-data-fragment-local-args.graphql:16:24 - 15 │ @inline - 16 │ @argumentDefinitions(sizeArg: {type: "[Int]", defaultValue: [50]}) { - │ ^^^^^^^ - 17 │ profilePicture(size: $sizeArg) { - - -✖︎ Variables from @argumentDefinitions are not yet supported inside @inline fragments. - - inline-data-fragment-local-args.graphql:14:10 - 13 │ - 14 │ fragment inlineDataFragmentLocalArgsProfile on User - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 15 │ @inline - - ℹ︎ Variable used: +==================================== OUTPUT =================================== +{ + "argumentDefinitions": [ + { + "kind": "RootArgument", + "name": "globalSizeVar" + } + ], + "kind": "Fragment", + "metadata": null, + "name": "inlineDataFragmentLocalArgsFragment", + "selections": [ + { + "alias": "usingLiteralPassedValue", + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "inlineDataFragmentLocalArgsProfile", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "size", + "variableName": "sizeArg" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profilePicture", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } + ], + "storageKey": null + } + ], + "args": [ + { + "kind": "Literal", + "name": "sizeArg", + "value": [ + 100 + ] + } + ], + "argumentDefinitions": [ + { + "defaultValue": [ + 50 + ], + "kind": "LocalArgument", + "name": "sizeArg" + } + ] + } + ], + "storageKey": null + }, + { + "alias": "usingGlobalPassedValue", + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "inlineDataFragmentLocalArgsProfile", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "size", + "variableName": "sizeArg" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profilePicture", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } + ], + "storageKey": null + } + ], + "args": [ + { + "kind": "Variable", + "name": "sizeArg", + "variableName": "globalSizeVar" + } + ], + "argumentDefinitions": [ + { + "defaultValue": [ + 50 + ], + "kind": "LocalArgument", + "name": "sizeArg" + } + ] + } + ], + "storageKey": null + }, + { + "alias": "usingDefaultValue", + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "inlineDataFragmentLocalArgsProfile", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "size", + "variableName": "sizeArg" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profilePicture", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } + ], + "storageKey": null + } + ], + "args": null, + "argumentDefinitions": [ + { + "defaultValue": [ + 50 + ], + "kind": "LocalArgument", + "name": "sizeArg" + } + ] + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null +} - inline-data-fragment-local-args.graphql:16:24 - 15 │ @inline - 16 │ @argumentDefinitions(sizeArg: {type: "[Int]", defaultValue: [50]}) { - │ ^^^^^^^ - 17 │ profilePicture(size: $sizeArg) { +{ + "kind": "InlineDataFragment", + "name": "inlineDataFragmentLocalArgsProfile" +} diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.graphql b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.graphql index adef320168ad6..fc2659acacc62 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.graphql +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment-local-args.graphql @@ -1,4 +1,3 @@ -# expected-to-throw fragment inlineDataFragmentLocalArgsFragment on Query { usingLiteralPassedValue: me { ...inlineDataFragmentLocalArgsProfile @arguments(sizeArg: [100]) diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment.expected b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment.expected index bf38c259506a3..d3a1869aaff9a 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment.expected +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/fixtures/inline-data-fragment.expected @@ -264,7 +264,9 @@ fragment inlineDataFragment_Profile on User { ], "storageKey": "profilePicture(size:100)" } - ] + ], + "args": null, + "argumentDefinitions": [] }, { "alias": null, @@ -356,7 +358,9 @@ fragment inlineDataFragment_Profile on User { "type": "User", "abstractKey": null } - ] + ], + "args": null, + "argumentDefinitions": [] } ], "storageKey": "username(name:\"test\")" diff --git a/compiler/crates/relay-transforms/src/inline_data_fragment.rs b/compiler/crates/relay-transforms/src/inline_data_fragment.rs index 0557b28a0cfbc..6df69c140212b 100644 --- a/compiler/crates/relay-transforms/src/inline_data_fragment.rs +++ b/compiler/crates/relay-transforms/src/inline_data_fragment.rs @@ -7,8 +7,8 @@ use common::{Diagnostic, DiagnosticsResult, Location, NamedItem, WithLocation}; use graphql_ir::{ - associated_data_impl, FragmentSpread, InlineFragment, Program, Selection, Transformed, - Transformer, + associated_data_impl, Argument, FragmentSpread, InlineFragment, Program, Selection, + Transformed, Transformer, VariableDefinition, }; use intern::string_key::{Intern, StringKey}; @@ -50,6 +50,9 @@ impl<'s> InlineDataFragmentsTransform<'s> { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct InlineDirectiveMetadata { pub fragment_name: StringKey, + pub arguments: Vec, + pub variable_definitions: Vec, + pub used_global_variables: Vec, } associated_data_impl!(InlineDirectiveMetadata); @@ -68,20 +71,6 @@ impl<'s> Transformer for InlineDataFragmentsTransform<'s> { if fragment.directives.named(*INLINE_DIRECTIVE_NAME).is_none() { next_fragment_spread } else { - if !fragment.variable_definitions.is_empty() { - let mut error = Diagnostic::error( - ValidationMessage::InlineDataFragmentArgumentsNotSupported, - fragment.name.location, - ); - for var in fragment - .variable_definitions - .iter() - .chain(fragment.used_global_variables.iter()) - { - error = error.annotate("Variable used:", var.name.location); - } - self.errors.push(error); - } match &next_fragment_spread { Transformed::Keep => { if !spread.directives.is_empty() { @@ -147,6 +136,9 @@ impl<'s> Transformer for InlineDataFragmentsTransform<'s> { directives: vec![ InlineDirectiveMetadata { fragment_name: name, + arguments: spread.arguments.clone(), + variable_definitions: fragment.variable_definitions.clone(), + used_global_variables: fragment.used_global_variables.clone(), } .into(), ], @@ -169,9 +161,6 @@ enum ValidationMessage { #[error("Found a circular reference from fragment '{fragment_name}'.")] CircularFragmentReference { fragment_name: StringKey }, - #[error("Variables from @argumentDefinitions are not yet supported inside @inline fragments.")] - InlineDataFragmentArgumentsNotSupported, - #[error("Directives on fragment spreads for @inline fragments are not yet supported")] InlineDataFragmentDirectivesNotSupported, } diff --git a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/recursive.expected b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/recursive.expected index bf161aca8c3b5..e39a1ada41d14 100644 --- a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/recursive.expected +++ b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/recursive.expected @@ -29,6 +29,9 @@ fragment InlineDataFragment on Image @inline { ... @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "AnotherInlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { @@ -43,6 +46,9 @@ fragment UserProfile on User { ... @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "InlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { @@ -50,6 +56,9 @@ fragment UserProfile on User { ... @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "AnotherInlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { @@ -62,6 +71,9 @@ fragment UserProfile on User { ... @include(if: $cond) @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "AnotherInlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { @@ -74,6 +86,9 @@ fragment UserProfile on User { ... @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "InlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { @@ -81,6 +96,9 @@ fragment UserProfile on User { ... @__InlineDirectiveMetadata # InlineDirectiveMetadata { # fragment_name: "AnotherInlineDataFragment", + # arguments: [], + # variable_definitions: [], + # used_global_variables: [], # } { ... on Image { diff --git a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.expected b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.expected new file mode 100644 index 0000000000000..89cb3813e5cd2 --- /dev/null +++ b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.expected @@ -0,0 +1,73 @@ +==================================== INPUT ==================================== +fragment User on User { + ...UserProfile @arguments(profilePictureSize: [1, 1]) +} + +fragment UserProfile on User +@inline +@argumentDefinitions(profilePictureSize: {type: "[Int]"}) { + profilePicture(size: $profilePictureSize) { + uri + } +} +==================================== OUTPUT =================================== +fragment User on User { + ... @__InlineDirectiveMetadata + # InlineDirectiveMetadata { + # fragment_name: "UserProfile", + # arguments: [ + # Argument { + # name: WithLocation { + # location: variables.graphql:52:70, + # item: "profilePictureSize", + # }, + # value: WithLocation { + # location: variables.graphql:72:78, + # item: Constant( + # List( + # [ + # Int( + # 1, + # ), + # Int( + # 1, + # ), + # ], + # ), + # ), + # }, + # }, + # ], + # variable_definitions: [ + # VariableDefinition { + # name: WithLocation { + # location: variables.graphql:141:159, + # item: "profilePictureSize", + # }, + # type_: List( + # Named( + # Scalar(0), + # ), + # ), + # default_value: None, + # directives: [], + # }, + # ], + # used_global_variables: [], + # } + { + ... on User { + profilePicture(size: $profilePictureSize) { + uri + } + } + } +} + +fragment UserProfile on User @inline @argumentDefinitions( + profilePictureSize: {type: "[Int]"} +) { + profilePicture(size: $profilePictureSize) { + uri + } +} diff --git a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.graphql b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.graphql similarity index 54% rename from compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.graphql rename to compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.graphql index 9aa3be88a71f1..35cd59d64680b 100644 --- a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.graphql +++ b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.graphql @@ -1,9 +1,10 @@ -# expected-to-throw fragment User on User { ...UserProfile @arguments(profilePictureSize: [1, 1]) } -fragment UserProfile on User @inline @argumentDefinitions(profilePictureSize: { type: "[Int]" }) { +fragment UserProfile on User +@inline +@argumentDefinitions(profilePictureSize: {type: "[Int]"}) { profilePicture(size: $profilePictureSize) { uri } diff --git a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.expected b/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.expected deleted file mode 100644 index 745db9b1a22aa..0000000000000 --- a/compiler/crates/relay-transforms/tests/inline_data_fragment/fixtures/variables.invalid.expected +++ /dev/null @@ -1,27 +0,0 @@ -==================================== INPUT ==================================== -# expected-to-throw -fragment User on User { - ...UserProfile @arguments(profilePictureSize: [1, 1]) -} - -fragment UserProfile on User @inline @argumentDefinitions(profilePictureSize: { type: "[Int]" }) { - profilePicture(size: $profilePictureSize) { - uri - } -} -==================================== ERROR ==================================== -✖︎ Variables from @argumentDefinitions are not yet supported inside @inline fragments. - - variables.invalid.graphql:6:10 - 5 │ - 6 │ fragment UserProfile on User @inline @argumentDefinitions(profilePictureSize: { type: "[Int]" }) { - │ ^^^^^^^^^^^ - 7 │ profilePicture(size: $profilePictureSize) { - - ℹ︎ Variable used: - - variables.invalid.graphql:6:59 - 5 │ - 6 │ fragment UserProfile on User @inline @argumentDefinitions(profilePictureSize: { type: "[Int]" }) { - │ ^^^^^^^^^^^^^^^^^^ - 7 │ profilePicture(size: $profilePictureSize) { diff --git a/compiler/crates/relay-transforms/tests/inline_data_fragment_test.rs b/compiler/crates/relay-transforms/tests/inline_data_fragment_test.rs index dcac7d4717915..02b88cafb2ce1 100644 --- a/compiler/crates/relay-transforms/tests/inline_data_fragment_test.rs +++ b/compiler/crates/relay-transforms/tests/inline_data_fragment_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<> + * @generated SignedSource<<0b5686d10624fd1700d69be68ba3f437>> */ mod inline_data_fragment; @@ -20,8 +20,8 @@ fn recursive() { } #[test] -fn variables_invalid() { - let input = include_str!("inline_data_fragment/fixtures/variables.invalid.graphql"); - let expected = include_str!("inline_data_fragment/fixtures/variables.invalid.expected"); - test_fixture(transform_fixture, "variables.invalid.graphql", "inline_data_fragment/fixtures/variables.invalid.expected", input, expected); +fn variables() { + let input = include_str!("inline_data_fragment/fixtures/variables.graphql"); + let expected = include_str!("inline_data_fragment/fixtures/variables.expected"); + test_fixture(transform_fixture, "variables.graphql", "inline_data_fragment/fixtures/variables.expected", input, expected); } diff --git a/packages/relay-runtime/store/RelayConcreteVariables.js b/packages/relay-runtime/store/RelayConcreteVariables.js index fc0114c5a49f6..4774e58e66a67 100644 --- a/packages/relay-runtime/store/RelayConcreteVariables.js +++ b/packages/relay-runtime/store/RelayConcreteVariables.js @@ -15,7 +15,10 @@ import type { NormalizationLocalArgumentDefinition, NormalizationOperation, } from '../util/NormalizationNode'; -import type {ReaderFragment} from '../util/ReaderNode'; +import type { + ReaderFragment, + ReaderInlineDataFragmentSpread, +} from '../util/ReaderNode'; import type {ProvidedVariablesType} from '../util/RelayConcreteNode'; import type {Variables} from '../util/RelayRuntimeTypes'; @@ -30,10 +33,16 @@ const invariant = require('invariant'); * Note that this is analagous to determining function arguments given a function call. */ function getFragmentVariables( - fragment: ReaderFragment, + fragment: ReaderFragment | ReaderInlineDataFragmentSpread, rootVariables: Variables, argumentVariables: Variables, ): Variables { + // TODO: Support for legacy ReaderInlineDataFragmentSpread nodes. + // Remove this once all we've updated the ReaderInlineDataFragmentSpread + // type to indicate that all compiled artifacts have been updated. + if (fragment.argumentDefinitions == null) { + return argumentVariables; + } let variables; fragment.argumentDefinitions.forEach(definition => { if (argumentVariables.hasOwnProperty(definition.name)) { diff --git a/packages/relay-runtime/store/RelayReader.js b/packages/relay-runtime/store/RelayReader.js index 1f7e2d52badae..a76b62904a36e 100644 --- a/packages/relay-runtime/store/RelayReader.js +++ b/packages/relay-runtime/store/RelayReader.js @@ -70,6 +70,7 @@ const { } = require('../util/RelayConcreteNode'); const RelayFeatureFlags = require('../util/RelayFeatureFlags'); const ClientID = require('./ClientID'); +const RelayConcreteVariables = require('./RelayConcreteVariables'); const RelayModernRecord = require('./RelayModernRecord'); const {getReactFlightClientResponse} = require('./RelayStoreReactFlightUtils'); const { @@ -789,6 +790,7 @@ class RelayReader { data: SelectorData, ): ?mixed { const applicationName = field.alias ?? field.name; + getStorageKey(field, this._variables); const storageKey = getStorageKey(field, this._variables); const linkedID = RelayModernRecord.getLinkedRecordID(record, storageKey); if (linkedID == null) { @@ -1109,11 +1111,35 @@ class RelayReader { const inlineData = {}; const parentFragmentName = this._fragmentName; this._fragmentName = fragmentSpreadOrFragment.name; + + const parentVariables = this._variables; + + // We only want to update `this._variables` if we have compiler artifacts that support it. + // Until we've rolled out the compiler portion of this change, we need to check at runtime. + if (fragmentSpreadOrFragment.argumentDefinitions != null) { + // If the inline fragment spread has arguments, we need to temporarily + // switch this._variables to include the fragment spread's arguments + // for the duration of its traversal. + const argumentVariables = fragmentSpreadOrFragment.args + ? getArgumentValues(fragmentSpreadOrFragment.args, this._variables) + : {}; + + this._variables = RelayConcreteVariables.getFragmentVariables( + fragmentSpreadOrFragment, + this._owner.variables, + argumentVariables, + ); + } + this._traverseSelections( fragmentSpreadOrFragment.selections, record, inlineData, ); + + // Put the parent variables back + this._variables = parentVariables; + this._fragmentName = parentFragmentName; // $FlowFixMe[cannot-write] - writing into read-only field fragmentPointers[fragmentSpreadOrFragment.name] = inlineData; diff --git a/packages/relay-runtime/store/__tests__/__generated__/RelayReaderTestReadsBasicFragmentUserProfile.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/RelayReaderTestReadsBasicFragmentUserProfile.graphql.js index d6bc724953a3d..89e3b7ee47aec 100644 --- a/packages/relay-runtime/store/__tests__/__generated__/RelayReaderTestReadsBasicFragmentUserProfile.graphql.js +++ b/packages/relay-runtime/store/__tests__/__generated__/RelayReaderTestReadsBasicFragmentUserProfile.graphql.js @@ -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<<0dd81da0c676054856c17226d1df6acb>> + * @generated SignedSource<> * @flow * @lightSyntaxTransform * @nogrep @@ -72,7 +72,9 @@ var node/*: ReaderFragment*/ = { ], "storageKey": "profilePicture(size:32)" } - ] + ], + "args": null, + "argumentDefinitions": [] } ], "type": "User", diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariables.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariables.graphql.js new file mode 100644 index 0000000000000..2541338affbb7 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariables.graphql.js @@ -0,0 +1,52 @@ +/** + * 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. + * + * @generated SignedSource<> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { InlineFragment, ReaderInlineDataFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +declare export opaque type readInlineDataTestFragmentAndQueryVariables$fragmentType: FragmentType; +export type readInlineDataTestFragmentAndQueryVariables$data = {| + +defaultVariable: ?{| + +uri: ?string, + |}, + +fragmentVariable: ?{| + +uri: ?string, + |}, + +queryVariable: ?{| + +uri: ?string, + |}, + +$fragmentType: readInlineDataTestFragmentAndQueryVariables$fragmentType, +|}; +export type readInlineDataTestFragmentAndQueryVariables$key = { + +$data?: readInlineDataTestFragmentAndQueryVariables$data, + +$fragmentSpreads: readInlineDataTestFragmentAndQueryVariables$fragmentType, + ... +}; +*/ + +var node/*: ReaderInlineDataFragment*/ = { + "kind": "InlineDataFragment", + "name": "readInlineDataTestFragmentAndQueryVariables" +}; + +if (__DEV__) { + (node/*: any*/).hash = "a43776ab4d289e45902cda8bb9553018"; +} + +module.exports = ((node/*: any*/)/*: InlineFragment< + readInlineDataTestFragmentAndQueryVariables$fragmentType, + readInlineDataTestFragmentAndQueryVariables$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariablesQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariablesQuery.graphql.js new file mode 100644 index 0000000000000..acfdb6c480aba --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentAndQueryVariablesQuery.graphql.js @@ -0,0 +1,234 @@ +/** + * 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. + * + * @generated SignedSource<> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ConcreteRequest, Query } from 'relay-runtime'; +type readInlineDataTestFragmentAndQueryVariables$fragmentType = any; +export type readInlineDataTestFragmentAndQueryVariablesQuery$variables = {| + scale1?: ?number, + scale2?: ?number, +|}; +export type readInlineDataTestFragmentAndQueryVariablesQuery$data = {| + +me: ?{| + +$fragmentSpreads: readInlineDataTestFragmentAndQueryVariables$fragmentType, + |}, +|}; +export type readInlineDataTestFragmentAndQueryVariablesQuery = {| + response: readInlineDataTestFragmentAndQueryVariablesQuery$data, + variables: readInlineDataTestFragmentAndQueryVariablesQuery$variables, +|}; +*/ + +var node/*: ConcreteRequest*/ = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "scale1" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "scale2" + } +], +v1 = [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } +], +v2 = { + "alias": "queryVariable", + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "scale1" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "readInlineDataTestFragmentAndQueryVariablesQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "readInlineDataTestFragmentAndQueryVariables", + "selections": [ + { + "alias": "fragmentVariable", + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "theScale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null + }, + (v2/*: any*/), + { + "alias": "defaultVariable", + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "defaultScale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null + } + ], + "args": [ + { + "kind": "Variable", + "name": "theScale", + "variableName": "scale2" + } + ], + "argumentDefinitions": [ + { + "defaultValue": 3, + "kind": "LocalArgument", + "name": "defaultScale" + }, + { + "kind": "RootArgument", + "name": "scale1" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "theScale" + } + ] + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "readInlineDataTestFragmentAndQueryVariablesQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "alias": "fragmentVariable", + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "scale2" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null + }, + (v2/*: any*/), + { + "alias": "defaultVariable", + "args": [ + { + "kind": "Literal", + "name": "scale", + "value": 3 + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": "profile_picture(scale:3)" + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "0f5b31604a39ecc4a5994e55a6925767", + "id": null, + "metadata": {}, + "name": "readInlineDataTestFragmentAndQueryVariablesQuery", + "operationKind": "query", + "text": "query readInlineDataTestFragmentAndQueryVariablesQuery(\n $scale1: Float\n $scale2: Float\n) {\n me {\n ...readInlineDataTestFragmentAndQueryVariables_4vY5ns\n id\n }\n}\n\nfragment readInlineDataTestFragmentAndQueryVariables_4vY5ns on User {\n fragmentVariable: profile_picture(scale: $scale2) {\n uri\n }\n queryVariable: profile_picture(scale: $scale1) {\n uri\n }\n defaultVariable: profile_picture(scale: 3) {\n uri\n }\n}\n" + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "4ec1512a8aec4bf5ece15aef3e46dc15"; +} + +module.exports = ((node/*: any*/)/*: Query< + readInlineDataTestFragmentAndQueryVariablesQuery$variables, + readInlineDataTestFragmentAndQueryVariablesQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariables.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariables.graphql.js new file mode 100644 index 0000000000000..1710c2d40ccf4 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariables.graphql.js @@ -0,0 +1,46 @@ +/** + * 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. + * + * @generated SignedSource<<1951fc5dc1f621fa0b9c78dd9e61b3eb>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { InlineFragment, ReaderInlineDataFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +declare export opaque type readInlineDataTestFragmentVariables$fragmentType: FragmentType; +export type readInlineDataTestFragmentVariables$data = {| + +profile_picture: ?{| + +uri: ?string, + |}, + +$fragmentType: readInlineDataTestFragmentVariables$fragmentType, +|}; +export type readInlineDataTestFragmentVariables$key = { + +$data?: readInlineDataTestFragmentVariables$data, + +$fragmentSpreads: readInlineDataTestFragmentVariables$fragmentType, + ... +}; +*/ + +var node/*: ReaderInlineDataFragment*/ = { + "kind": "InlineDataFragment", + "name": "readInlineDataTestFragmentVariables" +}; + +if (__DEV__) { + (node/*: any*/).hash = "232456d8209f3e1dbaa16f6f7a77945c"; +} + +module.exports = ((node/*: any*/)/*: InlineFragment< + readInlineDataTestFragmentVariables$fragmentType, + readInlineDataTestFragmentVariables$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariablesQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariablesQuery.graphql.js new file mode 100644 index 0000000000000..ca43eeb5a089a --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestFragmentVariablesQuery.graphql.js @@ -0,0 +1,169 @@ +/** + * 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. + * + * @generated SignedSource<<4909d2d2b8fe107d11da8ba1155b88f2>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ConcreteRequest, Query } from 'relay-runtime'; +type readInlineDataTestFragmentVariables$fragmentType = any; +export type readInlineDataTestFragmentVariablesQuery$variables = {| + scale?: ?number, +|}; +export type readInlineDataTestFragmentVariablesQuery$data = {| + +me: ?{| + +$fragmentSpreads: readInlineDataTestFragmentVariables$fragmentType, + |}, +|}; +export type readInlineDataTestFragmentVariablesQuery = {| + response: readInlineDataTestFragmentVariablesQuery$data, + variables: readInlineDataTestFragmentVariablesQuery$variables, +|}; +*/ + +var node/*: ConcreteRequest*/ = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "scale" + } +], +v1 = [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "readInlineDataTestFragmentVariablesQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "readInlineDataTestFragmentVariables", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "theScale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null + } + ], + "args": [ + { + "kind": "Variable", + "name": "theScale", + "variableName": "scale" + } + ], + "argumentDefinitions": [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "theScale" + } + ] + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "readInlineDataTestFragmentVariablesQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "scale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": (v1/*: any*/), + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "596ef9f1116db8016778171f3c063d74", + "id": null, + "metadata": {}, + "name": "readInlineDataTestFragmentVariablesQuery", + "operationKind": "query", + "text": "query readInlineDataTestFragmentVariablesQuery(\n $scale: Float\n) {\n me {\n ...readInlineDataTestFragmentVariables_qlgXP\n id\n }\n}\n\nfragment readInlineDataTestFragmentVariables_qlgXP on User {\n profile_picture(scale: $scale) {\n uri\n }\n}\n" + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "cff614ecb857c3bd9cfc99f00f1e5471"; +} + +module.exports = ((node/*: any*/)/*: Query< + readInlineDataTestFragmentVariablesQuery$variables, + readInlineDataTestFragmentVariablesQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesChild.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesChild.graphql.js new file mode 100644 index 0000000000000..f7574f4aeaf36 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesChild.graphql.js @@ -0,0 +1,88 @@ +/** + * 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. + * + * @generated SignedSource<<56f6329262c409a206e63def6ccfa118>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { Fragment, ReaderFragment } from 'relay-runtime'; +type readInlineDataTestNestedQueryVariablesGrandchild$fragmentType = any; +import type { FragmentType } from "relay-runtime"; +declare export opaque type readInlineDataTestNestedQueryVariablesChild$fragmentType: FragmentType; +export type readInlineDataTestNestedQueryVariablesChild$data = {| + +$fragmentSpreads: readInlineDataTestNestedQueryVariablesGrandchild$fragmentType, + +$fragmentType: readInlineDataTestNestedQueryVariablesChild$fragmentType, +|}; +export type readInlineDataTestNestedQueryVariablesChild$key = { + +$data?: readInlineDataTestNestedQueryVariablesChild$data, + +$fragmentSpreads: readInlineDataTestNestedQueryVariablesChild$fragmentType, + ... +}; +*/ + +var node/*: ReaderFragment*/ = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "readInlineDataTestNestedQueryVariablesChild", + "selections": [ + { + "kind": "InlineDataFragmentSpread", + "name": "readInlineDataTestNestedQueryVariablesGrandchild", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "scale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } + ], + "storageKey": null + } + ], + "args": null, + "argumentDefinitions": [ + { + "kind": "RootArgument", + "name": "scale" + } + ] + } + ], + "type": "User", + "abstractKey": null +}; + +if (__DEV__) { + (node/*: any*/).hash = "07443f80b006430044e79ee785ad46d9"; +} + +module.exports = ((node/*: any*/)/*: Fragment< + readInlineDataTestNestedQueryVariablesChild$fragmentType, + readInlineDataTestNestedQueryVariablesChild$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesGrandchild.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesGrandchild.graphql.js new file mode 100644 index 0000000000000..d8ee663f4e3fe --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesGrandchild.graphql.js @@ -0,0 +1,46 @@ +/** + * 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. + * + * @generated SignedSource<<4404239d55b28ca2137c3d7da0836d7c>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { InlineFragment, ReaderInlineDataFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +declare export opaque type readInlineDataTestNestedQueryVariablesGrandchild$fragmentType: FragmentType; +export type readInlineDataTestNestedQueryVariablesGrandchild$data = {| + +profile_picture: ?{| + +uri: ?string, + |}, + +$fragmentType: readInlineDataTestNestedQueryVariablesGrandchild$fragmentType, +|}; +export type readInlineDataTestNestedQueryVariablesGrandchild$key = { + +$data?: readInlineDataTestNestedQueryVariablesGrandchild$data, + +$fragmentSpreads: readInlineDataTestNestedQueryVariablesGrandchild$fragmentType, + ... +}; +*/ + +var node/*: ReaderInlineDataFragment*/ = { + "kind": "InlineDataFragment", + "name": "readInlineDataTestNestedQueryVariablesGrandchild" +}; + +if (__DEV__) { + (node/*: any*/).hash = "88f25320204f0e57533953badb8c3928"; +} + +module.exports = ((node/*: any*/)/*: InlineFragment< + readInlineDataTestNestedQueryVariablesGrandchild$fragmentType, + readInlineDataTestNestedQueryVariablesGrandchild$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesParentQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesParentQuery.graphql.js new file mode 100644 index 0000000000000..6172373e4e8ec --- /dev/null +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestNestedQueryVariablesParentQuery.graphql.js @@ -0,0 +1,137 @@ +/** + * 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. + * + * @generated SignedSource<> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ConcreteRequest, Query } from 'relay-runtime'; +type readInlineDataTestNestedQueryVariablesChild$fragmentType = any; +export type readInlineDataTestNestedQueryVariablesParentQuery$variables = {| + scale?: ?number, +|}; +export type readInlineDataTestNestedQueryVariablesParentQuery$data = {| + +me: ?{| + +$fragmentSpreads: readInlineDataTestNestedQueryVariablesChild$fragmentType, + |}, +|}; +export type readInlineDataTestNestedQueryVariablesParentQuery = {| + response: readInlineDataTestNestedQueryVariablesParentQuery$data, + variables: readInlineDataTestNestedQueryVariablesParentQuery$variables, +|}; +*/ + +var node/*: ConcreteRequest*/ = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "scale" + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "readInlineDataTestNestedQueryVariablesParentQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "readInlineDataTestNestedQueryVariablesChild" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "readInlineDataTestNestedQueryVariablesParentQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "scale", + "variableName": "scale" + } + ], + "concreteType": "Image", + "kind": "LinkedField", + "name": "profile_picture", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "uri", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "5830f2d5f3e9eac1d97ab9ebba2e6eb2", + "id": null, + "metadata": {}, + "name": "readInlineDataTestNestedQueryVariablesParentQuery", + "operationKind": "query", + "text": "query readInlineDataTestNestedQueryVariablesParentQuery(\n $scale: Float\n) {\n me {\n ...readInlineDataTestNestedQueryVariablesChild\n id\n }\n}\n\nfragment readInlineDataTestNestedQueryVariablesChild on User {\n ...readInlineDataTestNestedQueryVariablesGrandchild\n}\n\nfragment readInlineDataTestNestedQueryVariablesGrandchild on User {\n profile_picture(scale: $scale) {\n uri\n }\n}\n" + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "0895903561ebff4372478d30aaad6430"; +} + +module.exports = ((node/*: any*/)/*: Query< + readInlineDataTestNestedQueryVariablesParentQuery$variables, + readInlineDataTestNestedQueryVariablesParentQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestQueryVariablesQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestQueryVariablesQuery.graphql.js index c9693a0e0d51e..71bac5e094eb2 100644 --- a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestQueryVariablesQuery.graphql.js +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestQueryVariablesQuery.graphql.js @@ -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<> + * @generated SignedSource<> * @flow * @lightSyntaxTransform * @nogrep @@ -83,6 +83,13 @@ return { "name": "readInlineDataTestQueryVariables", "selections": [ (v1/*: any*/) + ], + "args": null, + "argumentDefinitions": [ + { + "kind": "RootArgument", + "name": "scale" + } ] } ], diff --git a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestUserQuery.graphql.js b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestUserQuery.graphql.js index 600f1c1010db0..9372a03c2ba24 100644 --- a/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestUserQuery.graphql.js +++ b/packages/relay-runtime/store/__tests__/__generated__/readInlineDataTestUserQuery.graphql.js @@ -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<> + * @generated SignedSource<<851c0f34f87cb86216ea365a4f3dc3da>> * @flow * @lightSyntaxTransform * @nogrep @@ -88,7 +88,9 @@ return { "type": "User", "abstractKey": null } - ] + ], + "args": null, + "argumentDefinitions": [] } ], "storageKey": null diff --git a/packages/relay-runtime/store/__tests__/readInlineData-test.js b/packages/relay-runtime/store/__tests__/readInlineData-test.js index fe1ea49a47990..fa7476e677381 100644 --- a/packages/relay-runtime/store/__tests__/readInlineData-test.js +++ b/packages/relay-runtime/store/__tests__/readInlineData-test.js @@ -11,6 +11,7 @@ 'use strict'; const {getRequest, graphql} = require('../../query/GraphQLTag'); +const {getSelector} = require('../../store/RelayModernSelector'); const readInlineData = require('../readInlineData'); const { createOperationDescriptor, @@ -63,8 +64,180 @@ test('unwrap inline fragment data', () => { }); describe('integration test with variables', () => { + test('works with nested fragments', () => { + const Parent = graphql` + query readInlineDataTestNestedQueryVariablesParentQuery($scale: Float) { + me { + ...readInlineDataTestNestedQueryVariablesChild + } + } + `; + + const Child = graphql` + fragment readInlineDataTestNestedQueryVariablesChild on User { + ...readInlineDataTestNestedQueryVariablesGrandchild + } + `; + + const Grandchild = graphql` + fragment readInlineDataTestNestedQueryVariablesGrandchild on User + @inline { + profile_picture(scale: $scale) { + uri + } + } + `; + + const variables = { + scale: 2, + }; + + const environment = createMockEnvironment(); + environment.commitPayload(createOperationDescriptor(Parent, variables), { + me: { + id: '7', + __typename: 'User', + profile_picture: { + uri: 'some_url', + }, + }, + }); + + const request = getRequest(Parent); + const operation = createOperationDescriptor(request, variables); + const { + data: {me: parent}, + } = environment.lookup(operation.fragment, operation); + + const {data: childData} = environment.lookup(getSelector(Child, parent)); + + const grandchild = readInlineData(Grandchild, childData); + + expect(grandchild).toEqual({ + profile_picture: { + uri: 'some_url', + }, + }); + }); + + test('works with fragment variables & query variables & default variables', () => { + const Fragment = graphql` + fragment readInlineDataTestFragmentAndQueryVariables on User + @inline + @argumentDefinitions( + theScale: {type: "Float"} + defaultScale: {type: "Float", defaultValue: 3} + ) { + fragmentVariable: profile_picture(scale: $theScale) { + uri + } + queryVariable: profile_picture(scale: $scale1) { + uri + } + defaultVariable: profile_picture(scale: $defaultScale) { + uri + } + } + `; + + const Query = graphql` + query readInlineDataTestFragmentAndQueryVariablesQuery( + $scale1: Float + $scale2: Float + ) { + me { + ...readInlineDataTestFragmentAndQueryVariables + @arguments(theScale: $scale2) + } + } + `; + + const variables = { + scale1: 1, + scale2: 2, + }; + + const environment = createMockEnvironment(); + environment.commitPayload(createOperationDescriptor(Query, variables), { + me: { + id: '7', + __typename: 'User', + fragmentVariable: { + uri: 'fragment_url', + }, + queryVariable: { + uri: 'query_url', + }, + defaultVariable: { + uri: 'default_url', + }, + }, + }); + + const request = getRequest(Query); + const operation = createOperationDescriptor(request, variables); + const snapshot = environment.lookup(operation.fragment, operation); + + expect(readInlineData(Fragment, snapshot.data.me)).toEqual({ + fragmentVariable: { + uri: 'fragment_url', + }, + queryVariable: { + uri: 'query_url', + }, + defaultVariable: { + uri: 'default_url', + }, + }); + }); + + test('works with fragment variables', () => { + const Fragment = graphql` + fragment readInlineDataTestFragmentVariables on User + @inline + @argumentDefinitions(theScale: {type: "Float"}) { + profile_picture(scale: $theScale) { + uri + } + } + `; + + const Query = graphql` + query readInlineDataTestFragmentVariablesQuery($scale: Float) { + me { + ...readInlineDataTestFragmentVariables @arguments(theScale: $scale) + } + } + `; + + const variables = { + scale: 2, + }; + + const environment = createMockEnvironment(); + environment.commitPayload(createOperationDescriptor(Query, variables), { + me: { + id: '7', + __typename: 'User', + profile_picture: { + uri: 'some_url', + }, + }, + }); + + const request = getRequest(Query); + const operation = createOperationDescriptor(request, variables); + const snapshot = environment.lookup(operation.fragment, operation); + + expect(readInlineData(Fragment, snapshot.data.me)).toEqual({ + profile_picture: { + uri: 'some_url', + }, + }); + }); + test('works with query variables', () => { - const QueryVariablesFragment = graphql` + const Fragment = graphql` fragment readInlineDataTestQueryVariables on User @inline { profile_picture(scale: $scale) { uri @@ -72,7 +245,7 @@ describe('integration test with variables', () => { } `; - const QueryVariablesQuery = graphql` + const Query = graphql` query readInlineDataTestQueryVariablesQuery($scale: Float) { me { ...readInlineDataTestQueryVariables @@ -85,8 +258,7 @@ describe('integration test with variables', () => { }; const environment = createMockEnvironment(); - const operation = createOperationDescriptor(QueryVariablesQuery, variables); - environment.commitPayload(operation, { + environment.commitPayload(createOperationDescriptor(Query, variables), { me: { id: '7', __typename: 'User', @@ -96,9 +268,11 @@ describe('integration test with variables', () => { }, }); + const request = getRequest(Query); + const operation = createOperationDescriptor(request, variables); const snapshot = environment.lookup(operation.fragment, operation); - expect(readInlineData(QueryVariablesFragment, snapshot.data.me)).toEqual({ + expect(readInlineData(Fragment, snapshot.data.me)).toEqual({ profile_picture: { uri: 'some_url', }, diff --git a/packages/relay-runtime/util/ReaderNode.js b/packages/relay-runtime/util/ReaderNode.js index 20d654012f217..046054e2e3e23 100644 --- a/packages/relay-runtime/util/ReaderNode.js +++ b/packages/relay-runtime/util/ReaderNode.js @@ -31,6 +31,10 @@ export type ReaderInlineDataFragmentSpread = { +kind: 'InlineDataFragmentSpread', +name: string, +selections: $ReadOnlyArray, + // TODO: T123948544 Mark both of these as non-optional once the compiler + // changes have rolled out. + +args?: ?$ReadOnlyArray, + +argumentDefinitions?: $ReadOnlyArray, }; export type ReaderFragment = {