diff --git a/compiler/crates/extract-graphql/src/lib.rs b/compiler/crates/extract-graphql/src/lib.rs index 197f420e15541..6199d9a89e8c6 100644 --- a/compiler/crates/extract-graphql/src/lib.rs +++ b/compiler/crates/extract-graphql/src/lib.rs @@ -88,14 +88,14 @@ impl<'a> Iterator for CharReader<'a> { // This should work for Flow or TypeScript alike. pub fn extract(input: &str) -> Vec { let mut res = Vec::new(); - if !input.contains("%relay(") && !input.contains("@RelayResolver") { + if !input.contains("%relay") && !input.contains("@RelayResolver") { return res; } let mut it = CharReader::new(input); 'code: while let Some((i, c)) = it.next() { match c { '%' => { - for expected in ['r', 'e', 'l', 'a', 'y', '('] { + for expected in ['r', 'e', 'l', 'a', 'y'] { if let Some((_, c)) = it.next() { if c != expected { consume_identifier(&mut it); @@ -106,15 +106,44 @@ pub fn extract(input: &str) -> Vec { let mut whitespace_num: usize = 0; + // ReScript uses %relay(` ... `) + // Reason / OCaml use [%relay {| ... |}] + let expected_close_char: char; + loop { if let Some((_, c)) = it.next() { match c { - '`' => { - break; + '(' => { + // ReScript + if let Some((_, c)) = it.next() { + match c { + '`' => { + expected_close_char = '`'; + break; + } + _ => { + consume_identifier(&mut it); + continue 'code; + } + } + } } ' ' | '\n' | '\r' | '\t' => { whitespace_num += 1; } + '{' => { + if let Some((_, c)) = it.next() { + match c { + '|' => { + expected_close_char = '|'; + break + } + _ => { + continue 'code; + } + } + } + } _ => { consume_identifier(&mut it); continue 'code; @@ -128,7 +157,7 @@ pub fn extract(input: &str) -> Vec { let mut has_visited_first_char = false; for (i, c) in &mut it { match c { - '`' => { + c if c == expected_close_char => { let end = i; let text = &input[start + (8 + whitespace_num)..end]; res.push(JavaScriptSourceFeature::GraphQL(GraphQLSource::new( diff --git a/compiler/crates/relay-compiler/src/file_source/file_categorizer.rs b/compiler/crates/relay-compiler/src/file_source/file_categorizer.rs index 2da489b586eff..9d14f223561be 100644 --- a/compiler/crates/relay-compiler/src/file_source/file_categorizer.rs +++ b/compiler/crates/relay-compiler/src/file_source/file_categorizer.rs @@ -340,6 +340,8 @@ fn is_source_code_extension(extension: &OsStr) -> bool { || extension == "ts" || extension == "tsx" || extension == "res" + || extension == "re" + || extension == "ml" } fn is_schema_extension(extension: &OsStr) -> bool { @@ -352,7 +354,7 @@ fn is_extra_extensions(extension: &OsStr) -> bool { fn is_valid_source_code_extension(typegen_language: &TypegenLanguage, extension: &OsStr) -> bool { match typegen_language { - TypegenLanguage::ReScript => extension == "res", + TypegenLanguage::ReScript => extension == "res" || extension == "re" || extension == "ml", TypegenLanguage::TypeScript => is_source_code_extension(extension), TypegenLanguage::Flow | TypegenLanguage::JavaScript => { extension == "js" || extension == "jsx" diff --git a/compiler/crates/relay-compiler/src/file_source/walk_dir_file_source.rs b/compiler/crates/relay-compiler/src/file_source/walk_dir_file_source.rs index 647f810e585c7..6d411a00a90fc 100644 --- a/compiler/crates/relay-compiler/src/file_source/walk_dir_file_source.rs +++ b/compiler/crates/relay-compiler/src/file_source/walk_dir_file_source.rs @@ -38,6 +38,8 @@ fn get_expected_file_extensions(config: &Config) -> HashSet<&str> { match project.typegen_config.language { TypegenLanguage::ReScript => { file_extensions.insert("res"); + file_extensions.insert("re"); + file_extensions.insert("ml"); } TypegenLanguage::Flow | TypegenLanguage::JavaScript => { file_extensions.insert("js"); diff --git a/compiler/crates/relay-compiler/src/file_source/watchman_query_builder.rs b/compiler/crates/relay-compiler/src/file_source/watchman_query_builder.rs index c5d3996750733..abde8e2055b2e 100644 --- a/compiler/crates/relay-compiler/src/file_source/watchman_query_builder.rs +++ b/compiler/crates/relay-compiler/src/file_source/watchman_query_builder.rs @@ -25,7 +25,9 @@ pub fn get_watchman_expr(config: &Config) -> Expr { Expr::All(vec![ // Ending in *.js(x) or *.ts(x) depending on the project language. Expr::Suffix(match &project.typegen_config.language { - TypegenLanguage::ReScript => vec![PathBuf::from("res")], + TypegenLanguage::ReScript => { + vec![PathBuf::from("res"), PathBuf::from("re"), PathBuf::from("ml")] + } TypegenLanguage::Flow | TypegenLanguage::JavaScript => { vec![PathBuf::from("js"), PathBuf::from("jsx")] } diff --git a/compiler/test-project-res/src/Test_ml_query.ml b/compiler/test-project-res/src/Test_ml_query.ml new file mode 100644 index 0000000000000..c44639e948d5f --- /dev/null +++ b/compiler/test-project-res/src/Test_ml_query.ml @@ -0,0 +1,29 @@ +module Query = [%relay {| + query TestMlQuery($status: OnlineStatus) { + users(status: $status) { + edges { + node { + id + firstName + onlineStatus + } + } + } + } + |}] + +module QueryWithRequired = [%relay {| + query TestMlQueryWithRequiredQuery { + loggedInUser { + avatarUrl @required(action: NONE) + } + } +|}] + +module QueryWithRequired_BubbleToTop = [%relay {| + query TestMlQueryWithRequired_BubbleToTop_Query { + loggedInUser @required(action: NONE) { + avatarUrl @required(action: NONE) + } + } +|}] diff --git a/compiler/test-project-res/src/Test_re_query.re b/compiler/test-project-res/src/Test_re_query.re new file mode 100644 index 0000000000000..4eb7b631440f8 --- /dev/null +++ b/compiler/test-project-res/src/Test_re_query.re @@ -0,0 +1,29 @@ +module Query = [%relay {| + query TestReQuery($status: OnlineStatus) { + users(status: $status) { + edges { + node { + id + firstName + onlineStatus + } + } + } + } + |}]; + +module QueryWithRequired = [%relay {| + query TestReQueryWithRequiredQuery { + loggedInUser { + avatarUrl @required(action: NONE) + } + } +|}]; + +module QueryWithRequired_BubbleToTop = [%relay {| + query TestReQueryWithRequired_BubbleToTop_Query { + loggedInUser @required(action: NONE) { + avatarUrl @required(action: NONE) + } + } +|}]; diff --git a/compiler/test-project-res/src/__generated__/TestMlQueryWithRequiredQuery_graphql.res b/compiler/test-project-res/src/__generated__/TestMlQueryWithRequiredQuery_graphql.res new file mode 100644 index 0000000000000..93ae396a37803 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestMlQueryWithRequiredQuery_graphql.res @@ -0,0 +1,164 @@ +/* @sourceLoc Test_ml_query.ml */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type rec response_loggedInUser = { + avatarUrl: string, + } + type response = { + loggedInUser: option, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live @obj external makeVariables: unit => unit = "" +} + +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": "TestMlQueryWithRequiredQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + { + "kind": "RequiredField", + "field": (v0/*: any*/), + "action": "NONE", + "path": "loggedInUser.avatarUrl" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestMlQueryWithRequiredQuery", + "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": "9c86313d621c10836a1ca4e8ba402f9b", + "id": null, + "metadata": {}, + "name": "TestMlQueryWithRequiredQuery", + "operationKind": "query", + "text": "query TestMlQueryWithRequiredQuery {\n loggedInUser {\n avatarUrl\n id\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +}); diff --git a/compiler/test-project-res/src/__generated__/TestMlQueryWithRequired_BubbleToTop_Query_graphql.res b/compiler/test-project-res/src/__generated__/TestMlQueryWithRequired_BubbleToTop_Query_graphql.res new file mode 100644 index 0000000000000..6b654b4af2d27 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestMlQueryWithRequired_BubbleToTop_Query_graphql.res @@ -0,0 +1,170 @@ +/* @sourceLoc Test_ml_query.ml */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type rec response_loggedInUser = { + avatarUrl: string, + } + type response_t = { + loggedInUser: response_loggedInUser, + } + type response = option + @live + type rawResponse = response_t + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live @obj external makeVariables: unit => unit = "" +} + +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": "TestMlQueryWithRequired_BubbleToTop_Query", + "selections": [ + { + "kind": "RequiredField", + "field": { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + { + "kind": "RequiredField", + "field": (v0/*: any*/), + "action": "NONE", + "path": "loggedInUser.avatarUrl" + } + ], + "storageKey": null + }, + "action": "NONE", + "path": "loggedInUser" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestMlQueryWithRequired_BubbleToTop_Query", + "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": "e6a499b4f7eafa5ebc0e02be6de99029", + "id": null, + "metadata": {}, + "name": "TestMlQueryWithRequired_BubbleToTop_Query", + "operationKind": "query", + "text": "query TestMlQueryWithRequired_BubbleToTop_Query {\n loggedInUser {\n avatarUrl\n id\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +}); diff --git a/compiler/test-project-res/src/__generated__/TestMlQuery_graphql.res b/compiler/test-project-res/src/__generated__/TestMlQuery_graphql.res new file mode 100644 index 0000000000000..bd0dea229e761 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestMlQuery_graphql.res @@ -0,0 +1,253 @@ +/* @sourceLoc Test_ml_query.ml */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type enum_OnlineStatus = private [> + | #Idle + | #Offline + | #Online + ] + + @live + type enum_OnlineStatus_input = [ + | #Idle + | #Offline + | #Online + ] + + + + type rec response_users_edges_node = { + firstName: string, + @live id: string, + onlineStatus: option, + } + and response_users_edges = { + node: option, + } + and response_users = { + edges: option>>, + } + type response = { + users: option, + } + @live + type rawResponse = response + @live + type variables = { + status: option<[ + | #Idle + | #Offline + | #Online + ]>, + } + @live + type refetchVariables = { + status: option>, + } + @live let makeRefetchVariables = ( + ~status=?, + () + ): refetchVariables => { + status: status + } + +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live + external onlineStatus_toString: enum_OnlineStatus => string = "%identity" + @live + external onlineStatus_input_toString: enum_OnlineStatus_input => string = "%identity" + @live + let onlineStatus_decode = (enum: enum_OnlineStatus): option => { + switch enum { + | #...enum_OnlineStatus_input as valid => Some(valid) + | _ => None + } + } + @live + let onlineStatus_fromString = (str: string): option => { + onlineStatus_decode(Obj.magic(str)) + } + @live @obj external makeVariables: ( + ~status: [ + | #Idle + | #Offline + | #Online + ]=?, + unit + ) => variables = "" + + +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "status" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "status", + "variableName": "status" + } + ], + "concreteType": "UserConnection", + "kind": "LinkedField", + "name": "users", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "UserEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "firstName", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "onlineStatus", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "TestMlQuery", + "selections": (v1/*: any*/), + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "TestMlQuery", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "680776ed9caeb5adfd104ae12723d816", + "id": null, + "metadata": {}, + "name": "TestMlQuery", + "operationKind": "query", + "text": "query TestMlQuery(\n $status: OnlineStatus\n) {\n users(status: $status) {\n edges {\n node {\n id\n firstName\n onlineStatus\n }\n }\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +}); diff --git a/compiler/test-project-res/src/__generated__/TestReQueryWithRequiredQuery_graphql.res b/compiler/test-project-res/src/__generated__/TestReQueryWithRequiredQuery_graphql.res new file mode 100644 index 0000000000000..1339dd7c36a3c --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestReQueryWithRequiredQuery_graphql.res @@ -0,0 +1,164 @@ +/* @sourceLoc Test_re_query.re */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type rec response_loggedInUser = { + avatarUrl: string, + } + type response = { + loggedInUser: option, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live @obj external makeVariables: unit => unit = "" +} + +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": "TestReQueryWithRequiredQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + { + "kind": "RequiredField", + "field": (v0/*: any*/), + "action": "NONE", + "path": "loggedInUser.avatarUrl" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestReQueryWithRequiredQuery", + "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": "c61847123b7c448027af95b3eb3d59a3", + "id": null, + "metadata": {}, + "name": "TestReQueryWithRequiredQuery", + "operationKind": "query", + "text": "query TestReQueryWithRequiredQuery {\n loggedInUser {\n avatarUrl\n id\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +}); diff --git a/compiler/test-project-res/src/__generated__/TestReQueryWithRequired_BubbleToTop_Query_graphql.res b/compiler/test-project-res/src/__generated__/TestReQueryWithRequired_BubbleToTop_Query_graphql.res new file mode 100644 index 0000000000000..c081b81518979 --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestReQueryWithRequired_BubbleToTop_Query_graphql.res @@ -0,0 +1,170 @@ +/* @sourceLoc Test_re_query.re */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type rec response_loggedInUser = { + avatarUrl: string, + } + type response_t = { + loggedInUser: response_loggedInUser, + } + type response = option + @live + type rawResponse = response_t + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live @obj external makeVariables: unit => unit = "" +} + +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": "TestReQueryWithRequired_BubbleToTop_Query", + "selections": [ + { + "kind": "RequiredField", + "field": { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + { + "kind": "RequiredField", + "field": (v0/*: any*/), + "action": "NONE", + "path": "loggedInUser.avatarUrl" + } + ], + "storageKey": null + }, + "action": "NONE", + "path": "loggedInUser" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestReQueryWithRequired_BubbleToTop_Query", + "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": "1bbd76c21f3b1895745f45e0b1a4d0ed", + "id": null, + "metadata": {}, + "name": "TestReQueryWithRequired_BubbleToTop_Query", + "operationKind": "query", + "text": "query TestReQueryWithRequired_BubbleToTop_Query {\n loggedInUser {\n avatarUrl\n id\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +}); diff --git a/compiler/test-project-res/src/__generated__/TestReQuery_graphql.res b/compiler/test-project-res/src/__generated__/TestReQuery_graphql.res new file mode 100644 index 0000000000000..7ac46209dad5a --- /dev/null +++ b/compiler/test-project-res/src/__generated__/TestReQuery_graphql.res @@ -0,0 +1,253 @@ +/* @sourceLoc Test_re_query.re */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@ocaml.warning("-30") + + type enum_OnlineStatus = private [> + | #Idle + | #Offline + | #Online + ] + + @live + type enum_OnlineStatus_input = [ + | #Idle + | #Offline + | #Online + ] + + + + type rec response_users_edges_node = { + firstName: string, + @live id: string, + onlineStatus: option, + } + and response_users_edges = { + node: option, + } + and response_users = { + edges: option>>, + } + type response = { + users: option, + } + @live + type rawResponse = response + @live + type variables = { + status: option<[ + | #Idle + | #Offline + | #Online + ]>, + } + @live + type refetchVariables = { + status: option>, + } + @live let makeRefetchVariables = ( + ~status=?, + () + ): refetchVariables => { + status: status + } + +} + +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 queryRef + +module Utils = { + @@ocaml.warning("-33") + open Types + @live + external onlineStatus_toString: enum_OnlineStatus => string = "%identity" + @live + external onlineStatus_input_toString: enum_OnlineStatus_input => string = "%identity" + @live + let onlineStatus_decode = (enum: enum_OnlineStatus): option => { + switch enum { + | #...enum_OnlineStatus_input as valid => Some(valid) + | _ => None + } + } + @live + let onlineStatus_fromString = (str: string): option => { + onlineStatus_decode(Obj.magic(str)) + } + @live @obj external makeVariables: ( + ~status: [ + | #Idle + | #Offline + | #Online + ]=?, + unit + ) => variables = "" + + +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "status" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "status", + "variableName": "status" + } + ], + "concreteType": "UserConnection", + "kind": "LinkedField", + "name": "users", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "UserEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "firstName", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "onlineStatus", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "TestReQuery", + "selections": (v1/*: any*/), + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "TestReQuery", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "c56d6f47a30727eb72b8fccafd609c56", + "id": null, + "metadata": {}, + "name": "TestReQuery", + "operationKind": "query", + "text": "query TestReQuery(\n $status: OnlineStatus\n) {\n users(status: $status) {\n edges {\n node {\n id\n firstName\n onlineStatus\n }\n }\n }\n}\n" + } +}; +})() `) + +include RescriptRelay.MakeLoadQuery({ + type variables = Types.variables + type loadedQueryRef = queryRef + type response = Types.response + type node = relayOperationNode + let query = node + let convertVariables = Internal.convertVariables +});