diff --git a/compiler/crates/relay-typegen/src/rescript.rs b/compiler/crates/relay-typegen/src/rescript.rs index b19f0c7ebf57c..99cb2793d70e2 100644 --- a/compiler/crates/relay-typegen/src/rescript.rs +++ b/compiler/crates/relay-typegen/src/rescript.rs @@ -9,6 +9,7 @@ use common::rescript_utils::get_module_name_from_file_path; use fnv::{FnvHashMap, FnvHashSet}; use graphql_ir::{FragmentDefinition, OperationDefinition}; use graphql_syntax::OperationKind; +use intern::string_key::Intern; use itertools::Itertools; use log::{debug, warn}; @@ -27,11 +28,21 @@ use std::fmt::{Result, Write}; #[derive(Debug)] pub enum TopLevelFragmentType { Object(Object), + Result(Object), Union(Union), ArrayWithObject(Object), + ArrayWithResult(Object), ArrayWithUnion(Union), } +// This is the same as TopLevelFragmentType, but for the response type. +// Mutations can be Results, otherwise everything as a response is always an object. +#[derive(Debug)] +pub enum TopLevelResponseType { + Object(Object), + Result(Object), +} + // The current operation type definition type, as given to us by the Relay // compiler. #[derive(Debug)] @@ -70,7 +81,7 @@ pub struct ReScriptPrinter { // response is nullable or not. Nullability of responses happen when the // @required directive bubbles the nullability all the way up to the // response top level. - pub response: Option<(bool, Object)>, + pub response: Option<(bool, TopLevelResponseType)>, // The @raw_response_type annotation on operations will populate this. It // holds a type that represents the full, raw response Relay expects from @@ -125,6 +136,7 @@ fn ast_to_prop_value( found_in_union: bool, found_in_array: bool, context: &Context, + is_from_result: bool ) -> Option { let (nullable, value) = unwrap_ast(ast); let is_nullable = nullable || optional; @@ -134,6 +146,16 @@ fn ast_to_prop_value( // print the types. let (safe_key, original_key) = get_safe_key(key); + let mut new_at_path = current_path.clone(); + new_at_path.push(key.to_string()); + + // The catch result type in Relay is shaped as `{ok: true, value: 'value} | {ok: false, errors: array}`. + // This sets the path up here to follow into `value`, which is where the OK result will be located if it's an OK + // response. + if is_from_result { + new_at_path.push(String::from("value")); + } + // We do special treatment for any variable definition in // mutations/subscriptions which is passed into `connections` of a // store updater directive (like @appendNode, @deleteEdge, etc). @@ -159,6 +181,39 @@ fn ast_to_prop_value( } match value { + AST::GenericType { outer, inner } => { + if outer.eq(&"Result".intern()) { + let ok_ast = inner.get(0).unwrap(); + + let ok_prop_value = ast_to_prop_value( + state, + current_path.to_vec(), + ok_ast, + key, + false, + found_in_union, + found_in_array, + context, + true + ); + + match ok_prop_value { + None => None, + Some(prop_value) => { + Some(PropValue { + key: safe_key, + original_key, + comment: None, + nullable: is_nullable, + prop_type: Box::new(PropType::Result(prop_value.prop_type)) + }) + } + } + + } else { + None + } + }, AST::Boolean => Some(PropValue { key: safe_key, original_key, @@ -210,6 +265,7 @@ fn ast_to_prop_value( found_in_union, true, context, + is_from_result ) { None => { warn!("Could not extract type from array. This should not happen."); @@ -228,8 +284,6 @@ fn ast_to_prop_value( } } AST::ExactObject(props) => { - let mut new_at_path = current_path.clone(); - new_at_path.push(key.to_string()); let record_name = path_to_name(&new_at_path); let object_props = get_object_props(state, &new_at_path, props, found_in_union, context); @@ -278,9 +332,6 @@ fn ast_to_prop_value( }) } AST::Union(members) => { - let mut new_at_path = current_path.clone(); - new_at_path.push(key.to_string()); - let (union_members, include_catch_all) = extract_union_members(state, &new_at_path, members, context); let union_record_name = path_to_name(&new_at_path); @@ -318,9 +369,6 @@ fn ast_to_prop_value( prop_type: Box::new(PropType::Enum(full_enum.name.to_string())), }), ClassifiedIdentifier::InputObject((input_object_record_name, _)) => { - let mut new_at_path = current_path.clone(); - new_at_path.push(key.to_string()); - Some(PropValue { key: safe_key, original_key, @@ -332,8 +380,6 @@ fn ast_to_prop_value( }) } ClassifiedIdentifier::RawIdentifier(identifier) => { - let mut new_at_path = current_path.clone(); - new_at_path.push(key.to_string()); let mut is_custom_scalar_that_needs_conversion = false; // Add a conversion instruction if this is a custom type @@ -531,6 +577,7 @@ fn get_object_props( found_in_union, false, context, + false ) } &Prop::KeyValuePair(key_value_pair) => { @@ -611,6 +658,7 @@ fn get_object_props( found_in_union, false, context, + false ) } } @@ -628,6 +676,18 @@ fn get_object_prop_type_as_string( field_path_name: &Vec, ) -> String { match &prop_value { + &PropType::Result(value) => { + format!( + "RescriptRelay.CatchResult.t<{}>", + get_object_prop_type_as_string( + state, + value.as_ref(), + &context, + indentation, + field_path_name + ) + ) + }, &PropType::DataId => String::from("RescriptRelay.dataId"), &PropType::Enum(enum_name) => { let has_allow_unsafe_enum_directive = state @@ -1591,6 +1651,41 @@ fn write_fragment_definition( .unwrap(); } } + &TopLevelFragmentType::Result(obj) => { + if nullable { + write_object_definition( + state, + str, + indentation, + obj, + ObjectPrintMode::Standalone, + Some(String::from("fragment_t")), + &context, + false, + false + ) + .unwrap(); + + write_indentation(str, indentation).unwrap(); + writeln!(str, "type fragment = RescriptRelay.CatchResult.t>").unwrap() + } else { + write_object_definition( + state, + str, + indentation, + obj, + ObjectPrintMode::Standalone, + Some(String::from("fragment_t")), + &context, + false, + false + ) + .unwrap(); + + write_indentation(str, indentation).unwrap(); + writeln!(str, "type fragment = RescriptRelay.CatchResult.t").unwrap() + } + } &TopLevelFragmentType::ArrayWithObject(obj) => { write_object_definition( state, @@ -1611,6 +1706,26 @@ fn write_fragment_definition( writeln!(str, "type fragment = array").unwrap() } } + &TopLevelFragmentType::ArrayWithResult(obj) => { + write_object_definition( + state, + str, + indentation, + obj, + ObjectPrintMode::Standalone, + Some(String::from("fragment_t")), + &context, + false, + false + ) + .unwrap(); + write_indentation(str, indentation).unwrap(); + if nullable { + writeln!(str, "type fragment = RescriptRelay.CatchResult.t>>").unwrap() + } else { + writeln!(str, "type fragment = RescriptRelay.CatchResult.t>").unwrap() + } + } &TopLevelFragmentType::Union(union) => { if nullable { write_union_definition( @@ -2043,34 +2158,60 @@ impl Writer for ReScriptPrinter { // Print the response and raw response (if wanted) if let Some((nullable, response)) = &self.response { - if *nullable { - write_object_definition( - &self, - &mut generated_types, - indentation, - &response, - ObjectPrintMode::Standalone, - Some(String::from("response_t")), - &Context::Response, - false, - false - ) - .unwrap(); - write_indentation(&mut generated_types, indentation).unwrap(); - writeln!(generated_types, "type response = option").unwrap() - } else { - write_object_definition( - &self, - &mut generated_types, - indentation, - &response, - ObjectPrintMode::Standalone, - None, - &Context::Response, - false, - false - ) - .unwrap(); + let is_result = match response { + TopLevelResponseType::Result(_) => true, + _ => false + }; + + match response { + TopLevelResponseType::Object(response) => { + if *nullable { + write_object_definition( + &self, + &mut generated_types, + indentation, + &response, + ObjectPrintMode::Standalone, + Some(String::from("response_t")), + &Context::Response, + false, + false + ) + .unwrap(); + write_indentation(&mut generated_types, indentation).unwrap(); + writeln!(generated_types, "type response = option").unwrap() + } else { + write_object_definition( + &self, + &mut generated_types, + indentation, + &response, + ObjectPrintMode::Standalone, + None, + &Context::Response, + false, + false + ) + .unwrap(); + } + } + TopLevelResponseType::Result(response) => { + write_object_definition( + &self, + &mut generated_types, + indentation, + &response, + ObjectPrintMode::Standalone, + None, + &Context::Response, + false, + false + ) + .unwrap(); + + write_indentation(&mut generated_types, indentation).unwrap(); + writeln!(generated_types, "type response = RescriptRelay.CatchResult.t").unwrap() + } } // This prints the rawResponse, which the Relay compiler outputs if @@ -2111,7 +2252,13 @@ impl Writer for ReScriptPrinter { // was nullable, as it might be nullable only because of // @required, and we don't care about that when using // the raw response. - if *nullable { "response_t" } else { "response" } + if *nullable { + "response_t" + } else if is_result { + "response_value" + } else { + "response" + } ) .unwrap() } @@ -2210,7 +2357,7 @@ impl Writer for ReScriptPrinter { } Some(( _, - TopLevelFragmentType::Object(_) | TopLevelFragmentType::ArrayWithObject(_), + TopLevelFragmentType::Object(_) | TopLevelFragmentType::ArrayWithObject(_) | TopLevelFragmentType::Result(_) | TopLevelFragmentType::ArrayWithResult(_), )) | None => (), } @@ -2714,14 +2861,25 @@ impl Writer for ReScriptPrinter { // for those key top level objects and treat them specially. if name.ends_with("$data") { - match classify_top_level_object_type_ast(&value) { - Some((nullable, ClassifiedTopLevelObjectType::Object(props))) => { + let cto = classify_top_level_object_type_ast(&value); + match cto { + Some((nullable, ClassifiedTopLevelObjectType::Object(props) | ClassifiedTopLevelObjectType::Result(props))) => { let context = match &self.typegen_definition { DefinitionType::Fragment(_) => Context::Fragment, _ => Context::Response, }; - let current_path = vec![root_name_from_context(&context)]; + let is_result = match cto { + Some((_, ClassifiedTopLevelObjectType::Result(_))) => true, + _ => false + }; + + let mut current_path = vec![root_name_from_context(&context)]; + + if is_result { + current_path.push(String::from("value")); + } + let object_props = get_object_props(self, ¤t_path, &props, false, &context); let record_name = path_to_name(¤t_path); @@ -2738,21 +2896,40 @@ impl Writer for ReScriptPrinter { match &self.typegen_definition { DefinitionType::Fragment(_) => { self.fragment = - Some((nullable, TopLevelFragmentType::Object(main_data_type))); + Some((nullable, if is_result { + TopLevelFragmentType::Result(main_data_type) + } else { + TopLevelFragmentType::Object(main_data_type) + })); } _ => { - self.response = Some((nullable, main_data_type)); + self.response = + Some((nullable, if is_result { + TopLevelResponseType::Result(main_data_type) + } else { + TopLevelResponseType::Object(main_data_type) + })); } }; Ok(()) } - Some((nullable, ClassifiedTopLevelObjectType::ArrayWithObject(props))) => { + Some((nullable, ClassifiedTopLevelObjectType::ArrayWithObject(props) | ClassifiedTopLevelObjectType::ArrayWithResult(props))) => { let context = match &self.typegen_definition { DefinitionType::Fragment(_) => Context::Fragment, _ => Context::Response, }; - let current_path = vec![root_name_from_context(&context)]; + + let is_result = match cto { + Some((_, ClassifiedTopLevelObjectType::Result(_))) => true, + _ => false + }; + + let mut current_path = vec![root_name_from_context(&context)]; + + if is_result { + current_path.push(String::from("value")); + } let record_name = path_to_name(¤t_path); let fragment_type = Object { @@ -2767,7 +2944,11 @@ impl Writer for ReScriptPrinter { self.fragment = Some(( nullable, - TopLevelFragmentType::ArrayWithObject(fragment_type), + if is_result { + TopLevelFragmentType::ArrayWithResult(fragment_type) + } else { + TopLevelFragmentType::ArrayWithObject(fragment_type) + }, )); Ok(()) } diff --git a/compiler/crates/relay-typegen/src/rescript_ast.rs b/compiler/crates/relay-typegen/src/rescript_ast.rs index 6a08e9e806f44..e3e999bed1ab9 100644 --- a/compiler/crates/relay-typegen/src/rescript_ast.rs +++ b/compiler/crates/relay-typegen/src/rescript_ast.rs @@ -34,6 +34,7 @@ pub enum PropType { Scalar(ScalarValues), StringLiteral(String), Enum(String), + Result(Box), Array((bool, Box)), FragmentSpreads(Vec), UpdatableFragmentSpreads(Vec), diff --git a/compiler/crates/relay-typegen/src/rescript_utils.rs b/compiler/crates/relay-typegen/src/rescript_utils.rs index 4dc83a2ae68e8..19c2c1f64f839 100644 --- a/compiler/crates/relay-typegen/src/rescript_utils.rs +++ b/compiler/crates/relay-typegen/src/rescript_utils.rs @@ -5,8 +5,6 @@ use std::ops::Add; use common::ScalarName; use common::WithLocation; use docblock_shared::RELAY_RESOLVER_WEAK_OBJECT_DIRECTIVE; -use graphql_ir::reexport::Intern; -use graphql_ir::reexport::StringKey; use graphql_ir::Argument; use graphql_ir::ConstantValue; use graphql_ir::FragmentDefinition; @@ -15,6 +13,8 @@ use graphql_ir::ProvidedVariableMetadata; use graphql_ir::Value; use graphql_ir::Variable; use graphql_ir::VariableDefinition; +use graphql_ir::reexport::Intern; +use graphql_ir::reexport::StringKey; use itertools::Itertools; use log::warn; use relay_config::CustomType; @@ -35,13 +35,13 @@ use crate::rescript_ast::ConverterInstructions; use crate::rescript_ast::FragmentReference; use crate::rescript_ast::FullEnum; use crate::rescript_ast::ProvidedVariable; -use crate::rescript_relay_visitor::find_assets_in_fragment; -use crate::rescript_relay_visitor::find_assets_in_operation; use crate::rescript_relay_visitor::CustomScalarsMap; use crate::rescript_relay_visitor::RescriptRelayOperationMetaData; +use crate::rescript_relay_visitor::find_assets_in_fragment; +use crate::rescript_relay_visitor::find_assets_in_operation; +use crate::writer::AST; use crate::writer::Prop; use crate::writer::StringLiteral; -use crate::writer::AST; pub fn uncapitalize_string(str: &String) -> String { str[..1].to_ascii_lowercase().add(&str[1..]) @@ -71,8 +71,9 @@ pub fn path_to_name(path: &Vec) -> String { pub fn extract_fragments_from_fragment_spread(ast: &AST) -> Vec { match &ast { - AST::FragmentReference(fragment_names) => { - fragment_names.iter().map(|name| { + AST::FragmentReference(fragment_names) => fragment_names + .iter() + .map(|name| { let (is_aliased, fragment_name) = if name.to_string().starts_with("$ALIAS$") { (true, name.to_string()[7..].to_string()) } else { @@ -80,11 +81,11 @@ pub fn extract_fragments_from_fragment_spread(ast: &AST) -> Vec { warn!("Found unmapped fragment spread member: {:?}", unmatched); vec![] @@ -126,9 +127,11 @@ pub fn unwrap_ast(ast: &AST) -> (bool, &AST) { #[derive(Debug)] pub enum ClassifiedTopLevelObjectType<'a> { Object(&'a Vec), + Result(&'a Vec), Union(&'a Vec), ArrayWithObject(&'a Vec), ArrayWithUnion(&'a Vec), + ArrayWithResult(&'a Vec), } // This classifies top level object types, meaning anything that comes in the @@ -162,9 +165,33 @@ pub fn classify_top_level_object_type_ast( array_item_nullable, ClassifiedTopLevelObjectType::ArrayWithUnion(&ast), )), + Some((array_item_nullable, ClassifiedTopLevelObjectType::Result(ast))) => Some(( + array_item_nullable, + ClassifiedTopLevelObjectType::ArrayWithResult(&ast), + )), _ => None, } } + &AST::GenericType { outer, inner } => { + if outer.eq(&"Result".intern()) { + let ok_ast = inner.get(0).unwrap(); + match &ok_ast { + &AST::ExactObject(props) => { + Some((nullable, ClassifiedTopLevelObjectType::Result(&props))) + } + &AST::ReadOnlyArray(inner_ast) => match &inner_ast.as_ref() { + &AST::ExactObject(props) => Some(( + nullable, + ClassifiedTopLevelObjectType::ArrayWithResult(&props), + )), + _ => None, + }, + _ => None, + } + } else { + None + } + } _ => None, } } @@ -240,13 +267,11 @@ pub fn get_rescript_relay_meta_data( &schema, typegen_config.custom_scalar_types.clone(), ), - DefinitionType::Operation((definition, _)) => { - find_assets_in_operation( - &definition, - &schema, - typegen_config.custom_scalar_types.clone(), - ) - } + DefinitionType::Operation((definition, _)) => find_assets_in_operation( + &definition, + &schema, + typegen_config.custom_scalar_types.clone(), + ), } } @@ -309,7 +334,10 @@ pub fn get_safe_key(original_key: &String) -> (String, Option) { if is_first_char_uppercase(&original_key) { let uncapitalized = uncapitalize_string(&original_key); if is_legal_key(&uncapitalized) { - (format!("{}_", uncapitalized), Some(original_key.to_string())) + ( + format!("{}_", uncapitalized), + Some(original_key.to_string()), + ) } else { (uncapitalized, Some(original_key.to_string())) } @@ -350,10 +378,9 @@ pub fn get_custom_scalar_name( ) -> String { match custom_scalar_types.get(&ScalarName(custom_scalar.to_string().intern())) { None => custom_scalar.to_string(), - Some( - CustomType::Name(name) - | CustomType::Path(CustomTypeImport { name, .. }), - ) => name.to_string(), + Some(CustomType::Name(name) | CustomType::Path(CustomTypeImport { name, .. })) => { + name.to_string() + } } } @@ -381,7 +408,6 @@ pub fn print_opt(str: &String, optional: bool, nullability_mode: &NullabilityMod NullabilityMode::Option => format!("option<{}>", str), NullabilityMode::Nullable => format!("Js.Null.t<{}>", str), NullabilityMode::NullAndUndefined => format!("Js.Nullable.t<{}>", str), - } } else { format!("{}", str) @@ -495,7 +521,11 @@ pub fn print_type_reference( "" }, enum_.name.item, - if enum_as_inputs || enum_.is_extension { "_input" } else { "" } + if enum_as_inputs || enum_.is_extension { + "_input" + } else { + "" + } ) } Type::InputObject(id) => { @@ -510,43 +540,48 @@ pub fn print_type_reference( obj.name.item, match &nullability_mode { NullabilityMode::Nullable => "_nullable", - _ => "" + _ => "", } ) } - Type::Scalar(id) => format!( - "{}", - match schema.scalar(*id).name.item.to_string().as_str() { - "Boolean" => String::from("bool"), - "Int" => String::from("int"), - "Float" => String::from("float"), - "String" | "ID" => String::from("string"), - custom_scalar => { - let is_custom_scalar = custom_scalar_types - .get(&ScalarName(custom_scalar.to_string().intern())) - .is_some(); - - if is_custom_scalar { - let custom_scalar_name = - get_custom_scalar_name(&custom_scalar_types, &custom_scalar); - - match classify_rescript_value_string(&custom_scalar_name) { - RescriptCustomTypeValue::Module => { - format!("{}.t", custom_scalar_name) - } - RescriptCustomTypeValue::Type => custom_scalar_name.to_string(), + Type::Scalar(id) => format!("{}", match schema + .scalar(*id) + .name + .item + .to_string() + .as_str() + { + "Boolean" => String::from("bool"), + "Int" => String::from("int"), + "Float" => String::from("float"), + "String" | "ID" => String::from("string"), + custom_scalar => { + let is_custom_scalar = custom_scalar_types + .get(&ScalarName(custom_scalar.to_string().intern())) + .is_some(); + + if is_custom_scalar { + let custom_scalar_name = + get_custom_scalar_name(&custom_scalar_types, &custom_scalar); + + match classify_rescript_value_string(&custom_scalar_name) { + RescriptCustomTypeValue::Module => { + format!("{}.t", custom_scalar_name) } - } else { - String::from("RescriptRelay.any") + RescriptCustomTypeValue::Type => custom_scalar_name.to_string(), } + } else { + String::from("RescriptRelay.any") } } - ), + }), Type::Object(id) => { let object = schema.object(*id); - let weak = object.directives.iter().find(|d| { - d.name == *RELAY_RESOLVER_WEAK_OBJECT_DIRECTIVE - }).is_some(); + let weak = object + .directives + .iter() + .find(|d| d.name == *RELAY_RESOLVER_WEAK_OBJECT_DIRECTIVE) + .is_some(); if weak { format!("Relay{}Model.t", object.name.item) @@ -555,7 +590,7 @@ pub fn print_type_reference( } else { format!("RescriptRelay.dataId") } - }, + } _ => String::from("RescriptRelay.any"), }, nullable, @@ -800,16 +835,14 @@ pub fn get_connection_key_maker( ) }, match (&default_value, &variable.type_) { - (Some(default_value), _) => format!( - "={}", - match dig_type_ref(&variable.type_) { + (Some(default_value), _) => + format!("={}", match dig_type_ref(&variable.type_) { Type::InputObject(_) => format!( "{}", print_constant_value(&default_value.item, false, false, false) ), _ => print_constant_value(&default_value.item, false, false, false), - } - ), + }), (None, TypeReference::List(_) | TypeReference::Named(_)) => String::from("=?"), (None, TypeReference::NonNull(_)) => String::from(""), diff --git a/compiler/test-project-res/src/Test_catchAndFriends.res b/compiler/test-project-res/src/Test_catchAndFriends.res new file mode 100644 index 0000000000000..3cdc9e968bd4d --- /dev/null +++ b/compiler/test-project-res/src/Test_catchAndFriends.res @@ -0,0 +1,59 @@ +module Query = %relay(` + query TestCatchAndFriendsQuery { + loggedInUser { + avatarUrl @catch + } + } +`) + + +module Query = %relay(` + query TestCatchAndFriends2Query { + member(id: "123") @catch { + ... on User { + id + memberOfSingular @catch { + ... on User { + createdAt + } + } + } + } + } +`) + +module Query = %relay(` + query TestCatchAndFriends3Query { + members(groupId: "123") { + edges { + node @catch { + ... on User { + id + } + } + } + } + } +`) + +module LoggedInUserFragment = %relay(` + fragment TestCatchAndFriendsUser_user on User @catch { + createdAt + } +`) + +module LoggedInUserFragment = %relay(` + fragment TestCatchAndFriendsUserPlural_user on User @relay(plural: true) @catch { + createdAt + } +`) + +module Mutation = %relay(` + mutation TestCatchAndFriendsMutation @catch { + updateUserAvatar(avatarUrl: "https://avatars.com/avatar/user") { + user { + id + } + } + } +`) \ No newline at end of file diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriends2Query_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriends2Query_graphql.res new file mode 100644 index 0000000000000..be3e1b8158613 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriends2Query_graphql.res @@ -0,0 +1,315 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + @tag("__typename") type response_member_value_User_memberOfSingular_value = + | @live User( + { + @live __typename: [ | #User], + createdAt: SomeModule.Datetime.t, + } + ) + | @live @as("__unselected") UnselectedUnionMember(string) + + @tag("__typename") type response_member_value = + | @live User( + { + @live __typename: [ | #User], + @live id: string, + memberOfSingular: RescriptRelay.CatchResult.t, + } + ) + | @live @as("__unselected") UnselectedUnionMember(string) + + type response = { + member: RescriptRelay.CatchResult.t, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +@live +let unwrap_response_member_value_User_memberOfSingular_value: Types.response_member_value_User_memberOfSingular_value => Types.response_member_value_User_memberOfSingular_value = RescriptRelay_Internal.unwrapUnion(_, ["User"]) +@live +let wrap_response_member_value_User_memberOfSingular_value: Types.response_member_value_User_memberOfSingular_value => Types.response_member_value_User_memberOfSingular_value = RescriptRelay_Internal.wrapUnion +@live +let unwrap_response_member_value: Types.response_member_value => Types.response_member_value = RescriptRelay_Internal.unwrapUnion(_, ["User"]) +@live +let wrap_response_member_value: Types.response_member_value => Types.response_member_value = RescriptRelay_Internal.wrapUnion + +type queryRef + +module Internal = { + @live + let variablesConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + Js.undefined + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"member_value_User_memberOfSingular_value_User_createdAt":{"c":"SomeModule.Datetime"},"member_value_User_memberOfSingular_value":{"u":"response_member_value_User_memberOfSingular_value"},"member_value":{"u":"response_member_value"}}}` + ) + @live + let wrapResponseConverterMap = { + "SomeModule.Datetime": SomeModule.Datetime.serialize, + "response_member_value_User_memberOfSingular_value": wrap_response_member_value_User_memberOfSingular_value, + "response_member_value": wrap_response_member_value, + } + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + Js.null + ) + @live + type responseRaw + @live + let responseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"member_value_User_memberOfSingular_value_User_createdAt":{"c":"SomeModule.Datetime"},"member_value_User_memberOfSingular_value":{"u":"response_member_value_User_memberOfSingular_value"},"member_value":{"u":"response_member_value"}}}` + ) + @live + let responseConverterMap = { + "SomeModule.Datetime": SomeModule.Datetime.parse, + "response_member_value_User_memberOfSingular_value": unwrap_response_member_value_User_memberOfSingular_value, + "response_member_value": unwrap_response_member_value, + } + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + Js.undefined + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse + type rawPreloadToken<'response> = {source: Js.Nullable.t>} + external tokenToRaw: queryRef => rawPreloadToken = "%identity" +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = [ + { + "kind": "Literal", + "name": "id", + "value": "123" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v3 = { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +}, +v4 = [ + (v2/*: any*/) +], +v5 = { + "kind": "InlineFragment", + "selections": (v4/*: any*/), + "type": "Node", + "abstractKey": "__isNode" +}, +v6 = { + "kind": "InlineFragment", + "selections": (v4/*: any*/), + "type": "person", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "TestCatchAndFriends2Query", + "selections": [ + { + "kind": "CatchField", + "field": { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "member", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v2/*: any*/), + { + "kind": "CatchField", + "field": { + "alias": null, + "args": null, + "concreteType": null, + "kind": "LinkedField", + "name": "memberOfSingular", + "plural": false, + "selections": [ + (v1/*: any*/), + (v3/*: any*/) + ], + "storageKey": null + }, + "to": "RESULT" + } + ], + "type": "User", + "abstractKey": null + } + ], + "storageKey": "member(id:\"123\")" + }, + "to": "RESULT" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestCatchAndFriends2Query", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "member", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "concreteType": null, + "kind": "LinkedField", + "name": "memberOfSingular", + "plural": false, + "selections": [ + (v1/*: any*/), + (v3/*: any*/), + (v5/*: any*/), + (v6/*: any*/) + ], + "storageKey": null + } + ], + "type": "User", + "abstractKey": null + }, + (v5/*: any*/), + (v6/*: any*/) + ], + "storageKey": "member(id:\"123\")" + } + ] + }, + "params": { + "cacheID": "409831d8a6bf938b462e1c61cb77f8cc", + "id": null, + "metadata": {}, + "name": "TestCatchAndFriends2Query", + "operationKind": "query", + "text": "query TestCatchAndFriends2Query {\n member(id: \"123\") {\n __typename\n ... on User {\n id\n memberOfSingular {\n __typename\n ... on User {\n createdAt\n }\n ... on Node {\n __isNode: __typename\n __typename\n id\n }\n ... on person {\n id\n }\n }\n }\n ... on Node {\n __isNode: __typename\n __typename\n id\n }\n ... on person {\n id\n }\n }\n}\n" + } +}; +})() `) + +@live let load: ( + ~environment: RescriptRelay.Environment.t, + ~variables: Types.variables, + ~fetchPolicy: RescriptRelay.fetchPolicy=?, + ~fetchKey: string=?, + ~networkCacheConfig: RescriptRelay.cacheConfig=?, +) => queryRef = ( + ~environment, + ~variables, + ~fetchPolicy=?, + ~fetchKey=?, + ~networkCacheConfig=?, +) => + RescriptRelay.loadQuery( + environment, + node, + variables->Internal.convertVariables, + { + fetchKey, + fetchPolicy, + networkCacheConfig, + }, + ) + +@live +let queryRefToObservable = token => { + let raw = token->Internal.tokenToRaw + raw.source->Js.Nullable.toOption +} + +@live +let queryRefToPromise = token => { + Js.Promise.make((~resolve, ~reject as _) => { + switch token->queryRefToObservable { + | None => resolve(Error()) + | Some(o) => + open RescriptRelay.Observable + let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok()))) + } + }) +} diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriends3Query_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriends3Query_graphql.res new file mode 100644 index 0000000000000..32159680b655e --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriends3Query_graphql.res @@ -0,0 +1,290 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + @tag("__typename") type response_members_edges_node_value = + | @live User( + { + @live __typename: [ | #User], + @live id: string, + } + ) + | @live @as("__unselected") UnselectedUnionMember(string) + + type rec response_members_edges = { + node: RescriptRelay.CatchResult.t, + } + and response_members = { + edges: option>>, + } + type response = { + members: option, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +@live +let unwrap_response_members_edges_node_value: Types.response_members_edges_node_value => Types.response_members_edges_node_value = RescriptRelay_Internal.unwrapUnion(_, ["User"]) +@live +let wrap_response_members_edges_node_value: Types.response_members_edges_node_value => Types.response_members_edges_node_value = RescriptRelay_Internal.wrapUnion + +type queryRef + +module Internal = { + @live + let variablesConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + Js.undefined + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"members_edges_node_value":{"u":"response_members_edges_node_value"}}}` + ) + @live + let wrapResponseConverterMap = { + "response_members_edges_node_value": wrap_response_members_edges_node_value, + } + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + Js.null + ) + @live + type responseRaw + @live + let responseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"members_edges_node_value":{"u":"response_members_edges_node_value"}}}` + ) + @live + let responseConverterMap = { + "response_members_edges_node_value": unwrap_response_members_edges_node_value, + } + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + Js.undefined + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse + type rawPreloadToken<'response> = {source: Js.Nullable.t>} + external tokenToRaw: queryRef => rawPreloadToken = "%identity" +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = [ + { + "kind": "Literal", + "name": "groupId", + "value": "123" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v2 = [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } +], +v3 = { + "kind": "InlineFragment", + "selections": (v2/*: any*/), + "type": "User", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "TestCatchAndFriends3Query", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": "MemberConnection", + "kind": "LinkedField", + "name": "members", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "MemberEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "kind": "CatchField", + "field": { + "alias": null, + "args": null, + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + (v3/*: any*/) + ], + "storageKey": null + }, + "to": "RESULT" + } + ], + "storageKey": null + } + ], + "storageKey": "members(groupId:\"123\")" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestCatchAndFriends3Query", + "selections": [ + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": "MemberConnection", + "kind": "LinkedField", + "name": "members", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "MemberEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": (v2/*: any*/), + "type": "Node", + "abstractKey": "__isNode" + }, + { + "kind": "InlineFragment", + "selections": (v2/*: any*/), + "type": "person", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "members(groupId:\"123\")" + } + ] + }, + "params": { + "cacheID": "02be2c626e610e41de0943e277c4f2d4", + "id": null, + "metadata": {}, + "name": "TestCatchAndFriends3Query", + "operationKind": "query", + "text": "query TestCatchAndFriends3Query {\n members(groupId: \"123\") {\n edges {\n node {\n __typename\n ... on User {\n id\n }\n ... on Node {\n __isNode: __typename\n __typename\n id\n }\n ... on person {\n id\n }\n }\n }\n }\n}\n" + } +}; +})() `) + +@live let load: ( + ~environment: RescriptRelay.Environment.t, + ~variables: Types.variables, + ~fetchPolicy: RescriptRelay.fetchPolicy=?, + ~fetchKey: string=?, + ~networkCacheConfig: RescriptRelay.cacheConfig=?, +) => queryRef = ( + ~environment, + ~variables, + ~fetchPolicy=?, + ~fetchKey=?, + ~networkCacheConfig=?, +) => + RescriptRelay.loadQuery( + environment, + node, + variables->Internal.convertVariables, + { + fetchKey, + fetchPolicy, + networkCacheConfig, + }, + ) + +@live +let queryRefToObservable = token => { + let raw = token->Internal.tokenToRaw + raw.source->Js.Nullable.toOption +} + +@live +let queryRefToPromise = token => { + Js.Promise.make((~resolve, ~reject as _) => { + switch token->queryRefToObservable { + | None => resolve(Error()) + | Some(o) => + open RescriptRelay.Observable + let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok()))) + } + }) +} diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriendsMutation_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsMutation_graphql.res new file mode 100644 index 0000000000000..4b10c0cb00a6b --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsMutation_graphql.res @@ -0,0 +1,151 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + @live + type rec response_value_updateUserAvatar_user = { + @live id: string, + } + @live + and response_value_updateUserAvatar = { + user: option, + } + @live + type response_value = { + updateUserAvatar: option, + } + type response = RescriptRelay.CatchResult.t + @live + type rawResponse = response_value + @live + type variables = unit +} + +module Internal = { + @live + let variablesConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + Js.undefined + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let wrapResponseConverterMap = () + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + Js.null + ) + @live + type responseRaw + @live + let responseConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let responseConverterMap = () + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + Js.undefined + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.mutationNode + + +let node: operationType = %raw(json` (function(){ +var v0 = [ + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "avatarUrl", + "value": "https://avatars.com/avatar/user" + } + ], + "concreteType": "UpdateUserAvatarPayload", + "kind": "LinkedField", + "name": "updateUserAvatar", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "user", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "updateUserAvatar(avatarUrl:\"https://avatars.com/avatar/user\")" + } +]; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "catchTo": "RESULT" + }, + "name": "TestCatchAndFriendsMutation", + "selections": (v0/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestCatchAndFriendsMutation", + "selections": (v0/*: any*/) + }, + "params": { + "cacheID": "65a04919576c8cf004f73142d2e7e232", + "id": null, + "metadata": {}, + "name": "TestCatchAndFriendsMutation", + "operationKind": "mutation", + "text": "mutation TestCatchAndFriendsMutation {\n updateUserAvatar(avatarUrl: \"https://avatars.com/avatar/user\") {\n user {\n id\n }\n }\n}\n" + } +}; +})() `) + + diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriendsQuery_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsQuery_graphql.res new file mode 100644 index 0000000000000..3e1de3c119027 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsQuery_graphql.res @@ -0,0 +1,197 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type rec response_loggedInUser = { + avatarUrl: RescriptRelay.CatchResult.t, + } + type response = { + loggedInUser: response_loggedInUser, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + + +type queryRef + +module Internal = { + @live + let variablesConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + Js.undefined + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let wrapResponseConverterMap = () + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + Js.null + ) + @live + type responseRaw + @live + let responseConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let responseConverterMap = () + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + Js.undefined + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse + type rawPreloadToken<'response> = {source: Js.Nullable.t>} + external tokenToRaw: queryRef => rawPreloadToken = "%identity" +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "avatarUrl", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "TestCatchAndFriendsQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + { + "kind": "CatchField", + "field": (v0/*: any*/), + "to": "RESULT" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestCatchAndFriendsQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "ed195a41a45830b2c899a233d7d23a90", + "id": null, + "metadata": {}, + "name": "TestCatchAndFriendsQuery", + "operationKind": "query", + "text": "query TestCatchAndFriendsQuery {\n loggedInUser {\n avatarUrl\n id\n }\n}\n" + } +}; +})() `) + +@live let load: ( + ~environment: RescriptRelay.Environment.t, + ~variables: Types.variables, + ~fetchPolicy: RescriptRelay.fetchPolicy=?, + ~fetchKey: string=?, + ~networkCacheConfig: RescriptRelay.cacheConfig=?, +) => queryRef = ( + ~environment, + ~variables, + ~fetchPolicy=?, + ~fetchKey=?, + ~networkCacheConfig=?, +) => + RescriptRelay.loadQuery( + environment, + node, + variables->Internal.convertVariables, + { + fetchKey, + fetchPolicy, + networkCacheConfig, + }, + ) + +@live +let queryRefToObservable = token => { + let raw = token->Internal.tokenToRaw + raw.source->Js.Nullable.toOption +} + +@live +let queryRefToPromise = token => { + Js.Promise.make((~resolve, ~reject as _) => { + switch token->queryRefToObservable { + | None => resolve(Error()) + | Some(o) => + open RescriptRelay.Observable + let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok()))) + } + }) +} diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUserPlural_user_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUserPlural_user_graphql.res new file mode 100644 index 0000000000000..35feebac5634f --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUserPlural_user_graphql.res @@ -0,0 +1,66 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type fragment_t = { + createdAt: SomeModule.Datetime.t, + } + type fragment = array +} + +module Internal = { + @live + type fragmentRaw + @live + let fragmentConverter: Js.Dict.t>> = %raw( + json`{"__root":{"createdAt":{"c":"SomeModule.Datetime"}}}` + ) + @live + let fragmentConverterMap = { + "SomeModule.Datetime": SomeModule.Datetime.parse, + } + @live + let convertFragment = v => v->RescriptRelay.convertObj( + fragmentConverter, + fragmentConverterMap, + Js.undefined + ) +} + +type t +type fragmentRef +external getFragmentRef: + array | #TestCatchAndFriendsUserPlural_user]>> => fragmentRef = "%identity" + +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.fragmentNode + + +let node: operationType = %raw(json` { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "plural": true, + "catchTo": "RESULT" + }, + "name": "TestCatchAndFriendsUserPlural_user", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +} `) + diff --git a/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUser_user_graphql.res b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUser_user_graphql.res new file mode 100644 index 0000000000000..ca6278cd71fd8 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestCatchAndFriendsUser_user_graphql.res @@ -0,0 +1,65 @@ +/* @sourceLoc Test_catchAndFriends.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type fragment_t = { + createdAt: SomeModule.Datetime.t, + } + type fragment = RescriptRelay.CatchResult.t +} + +module Internal = { + @live + type fragmentRaw + @live + let fragmentConverter: Js.Dict.t>> = %raw( + json`{"__root":{"value_createdAt":{"c":"SomeModule.Datetime"}}}` + ) + @live + let fragmentConverterMap = { + "SomeModule.Datetime": SomeModule.Datetime.parse, + } + @live + let convertFragment = v => v->RescriptRelay.convertObj( + fragmentConverter, + fragmentConverterMap, + Js.undefined + ) +} + +type t +type fragmentRef +external getFragmentRef: + RescriptRelay.fragmentRefs<[> | #TestCatchAndFriendsUser_user]> => fragmentRef = "%identity" + +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.fragmentNode + + +let node: operationType = %raw(json` { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "catchTo": "RESULT" + }, + "name": "TestCatchAndFriendsUser_user", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +} `) +