diff --git a/compiler/crates/common/src/feature_flags.rs b/compiler/crates/common/src/feature_flags.rs index 2021c43f7cd88..ac67d37726e84 100644 --- a/compiler/crates/common/src/feature_flags.rs +++ b/compiler/crates/common/src/feature_flags.rs @@ -69,10 +69,6 @@ pub struct FeatureFlags { #[serde(default)] pub enable_resolver_normalization_ast: bool, - /// Fully build the schema resolvers artifact - #[serde(default)] - pub generate_resolvers_schema_module: bool, - /// Enforce strict flavors for relay resolvers and disallow mixing flavors #[serde(default)] pub relay_resolvers_enable_strict_resolver_flavors: FeatureFlag, diff --git a/compiler/crates/relay-codegen/src/build_ast.rs b/compiler/crates/relay-codegen/src/build_ast.rs index 1ac1416a23de3..a6947f0138c90 100644 --- a/compiler/crates/relay-codegen/src/build_ast.rs +++ b/compiler/crates/relay-codegen/src/build_ast.rs @@ -651,11 +651,7 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> { resolver_metadata: &RelayResolverMetadata, inline_fragment: Option, ) -> Primitive { - if self - .project_config - .feature_flags - .generate_resolvers_schema_module - { + if self.project_config.resolvers_schema_module.is_some() { self.build_normalization_relay_resolver_execution_time_for_worker(resolver_metadata) } else if self .project_config diff --git a/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs b/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs index 722e92928a355..5468c44147623 100644 --- a/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs +++ b/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs @@ -17,6 +17,7 @@ use graphql_text_printer::OperationPrinter; use graphql_text_printer::PrinterOptions; use intern::string_key::StringKey; use intern::Lookup; +use relay_config::ResolversSchemaModuleConfig; use relay_transforms::ArtifactSourceKeyData; use relay_transforms::ClientEdgeGeneratedQueryMetadataDirective; use relay_transforms::Programs; @@ -24,9 +25,11 @@ use relay_transforms::RawResponseGenerationMode; use relay_transforms::RefetchableDerivedFromMetadata; use relay_transforms::SplitOperationMetadata; use relay_transforms::UPDATABLE_DIRECTIVE; +use schema::SDLSchema; pub use super::artifact_content::ArtifactContent; use super::build_ir::SourceHashes; +use super::resolvers_schema_module::generate_resolvers_schema_module; use crate::artifact_map::ArtifactSourceKey; use crate::config::Config; use crate::config::ProjectConfig; @@ -44,8 +47,9 @@ pub struct Artifact { } pub fn generate_artifacts( - _config: &Config, + config: &Config, project_config: &ProjectConfig, + schema: &SDLSchema, programs: &Programs, source_hashes: Arc, ) -> Vec { @@ -187,6 +191,15 @@ pub fn generate_artifacts( artifact_source_keys, ) })) + .chain( + match project_config.resolvers_schema_module { + Some(ResolversSchemaModuleConfig { ref path }) => + vec![ + generate_resolvers_schema_module(config, project_config, schema, path.clone()).unwrap() + ], + _ => vec![], + } + ) .collect(); } diff --git a/compiler/crates/relay-compiler/src/build_project/mod.rs b/compiler/crates/relay-compiler/src/build_project/mod.rs index 4745aaabb98e4..3cba0d66f4d10 100644 --- a/compiler/crates/relay-compiler/src/build_project/mod.rs +++ b/compiler/crates/relay-compiler/src/build_project/mod.rs @@ -19,6 +19,7 @@ pub mod get_artifacts_file_hash_map; mod log_program_stats; mod persist_operations; mod project_asts; +mod resolvers_schema_module; mod source_control; mod validate; @@ -291,6 +292,7 @@ pub fn build_project( let artifacts = generate_artifacts( config, project_config, + &schema, &programs, Arc::clone(&source_hashes), ); diff --git a/compiler/crates/relay-compiler/src/build_project/resolvers_schema_module.rs b/compiler/crates/relay-compiler/src/build_project/resolvers_schema_module.rs new file mode 100644 index 0000000000000..035e5eeee0df2 --- /dev/null +++ b/compiler/crates/relay-compiler/src/build_project/resolvers_schema_module.rs @@ -0,0 +1,218 @@ +/* + * 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. + */ + +#![warn(clippy::all)] + +use std::fmt::Error; +use std::fmt::Write; +use std::path::PathBuf; + +use common::NamedItem; +use common::SourceLocationKey; +use intern::Lookup; +use relay_codegen::printer::get_module_path; +use relay_transforms::generate_relay_resolvers_model_fragments::get_resolver_source_hash; +use relay_transforms::get_fragment_filename; +use relay_transforms::get_resolver_fragment_dependency_name; +use relay_transforms::relay_resolvers::get_resolver_info; +use relay_transforms::relay_resolvers::ResolverInfo; +use relay_transforms::RESOLVER_BELONGS_TO_BASE_SCHEMA_DIRECTIVE; +use relay_typegen::TypegenLanguage; +use schema::SDLSchema; +use schema::Schema; +use schema::Type; +use signedsource::sign_file; + +use super::artifact_content::content::generate_docblock_section; +use super::artifact_content::content::write_export_generated_node; +use super::artifact_content::content_section::GenericSection; +use crate::config::Config; +use crate::config::ProjectConfig; +use crate::Artifact; +use crate::ArtifactContent; +use crate::ArtifactSourceKey; + +pub fn generate_resolvers_schema_module( + config: &Config, + project_config: &ProjectConfig, + schema: &SDLSchema, + output_path: PathBuf, +) -> Result { + let mut artifact_source_keys = vec![]; + let content = generate_resolvers_schema_module_content( + config, + project_config, + schema, + &output_path, + &mut artifact_source_keys, + )?; + Ok(Artifact { + artifact_source_keys, + path: output_path, + content: ArtifactContent::Generic { + content: sign_file(&content).into_bytes(), + }, + source_file: SourceLocationKey::generated(), + }) +} + +fn generate_resolvers_schema_module_content( + config: &Config, + project_config: &ProjectConfig, + schema: &SDLSchema, + artifact_path: &PathBuf, + artifact_source_keys: &mut Vec, +) -> Result { + let mut content = String::new(); + + let docblock = generate_docblock_section(config, project_config, vec![])?; + writeln!(content, "{}", docblock)?; + + let mut schema_resolvers_object = String::new(); + let mut schema_resolvers_type = String::new(); + let mut imports = String::new(); + + writeln!(schema_resolvers_type, "type SchemaResolvers = {{")?; + if project_config.typegen_config.language == TypegenLanguage::Flow { + writeln!( + schema_resolvers_object, + "var schema_resolvers /*:: : SchemaResolvers*/ = {{" + )?; + } else { + writeln!( + schema_resolvers_object, + "const schema_resolvers: SchemaResolvers = {{" + )?; + } + writeln!( + imports, + "import type {{NormalizationSplitOperation}} from 'relay-runtime';" + )?; + + for object in schema.get_objects() { + let mut has_resolvers = false; + + for field in object.fields.iter().map(|field_id| schema.field(*field_id)) { + if let Some(Ok(ResolverInfo { + import_path, + import_name: Some(import_name), + .. + })) = get_resolver_info(schema, field, field.name.location) + { + if field + .directives + .named(*RESOLVER_BELONGS_TO_BASE_SCHEMA_DIRECTIVE) + .is_some() + { + continue; + } + + if !has_resolvers { + has_resolvers = true; + writeln!( + schema_resolvers_type, + "\t{object_name}: {{", + object_name = object.name.item + )?; + writeln!( + schema_resolvers_object, + "\t{object_name}: {{", + object_name = object.name.item + )?; + } + if let Some(source_hash) = get_resolver_source_hash(field) { + artifact_source_keys.push(ArtifactSourceKey::ResolverHash(source_hash)); + } + + let js_import_path = project_config.js_module_import_identifier( + artifact_path, + &PathBuf::from(import_path.lookup()), + ); + let js_import_path_without_suffix = + get_module_path(project_config.js_module_format, js_import_path); + + let parent_type = match field.parent_type.unwrap() { + Type::Interface(interface_id) => schema.interface(interface_id).name.item.0, + Type::Object(object_id) => schema.object(object_id).name.item.0, + _ => panic!("Unexpected parent type for resolver."), + }; + let type_name = format!("{}_{}", &parent_type, import_name); + + writeln!( + imports, + "import typeof {{ {import_name} as {type_name} }} from '{import_path}';", + import_path = js_import_path_without_suffix, + import_name = import_name, + type_name = type_name + )?; + + writeln!(schema_resolvers_type, "\t\t{}: {{", import_name)?; + writeln!( + schema_resolvers_type, + "\t\t\tresolverFunction: {},", + type_name + )?; + writeln!( + schema_resolvers_type, + "\t\t\trootFragment: ?NormalizationSplitOperation," + )?; + writeln!(schema_resolvers_type, "\t\t}},",)?; + + writeln!(schema_resolvers_object, "\t\t{}: {{", import_name)?; + writeln!( + schema_resolvers_object, + "\t\t\tresolverFunction: require('{import_path}').{import_name},", + import_path = js_import_path_without_suffix, + import_name = import_name + )?; + writeln!( + schema_resolvers_object, + "\t\t\trootFragment: {}", + match get_resolver_fragment_dependency_name(field) { + None => "null".to_string(), + Some(fragment_name) => { + format!( + "require('{import}')", + import = get_fragment_filename(fragment_name) + ) + } + } + )?; + writeln!(schema_resolvers_object, "\t\t}},",)?; + } + } + + if has_resolvers { + writeln!(schema_resolvers_type, "\t}},")?; + writeln!(schema_resolvers_object, "\t}},")?; + } + } + + writeln!(schema_resolvers_type, "}};")?; + writeln!(schema_resolvers_object, "}};")?; + + if project_config.typegen_config.language == TypegenLanguage::Flow { + writeln!(content, "/*::")?; + } + writeln!(content, "{}\n", imports)?; + writeln!(content, "{}\n", schema_resolvers_type)?; + if project_config.typegen_config.language == TypegenLanguage::Flow { + writeln!(content, "*/")?; + } + writeln!(content, "{}\n", schema_resolvers_object)?; + + let mut export = GenericSection::default(); + write_export_generated_node( + &project_config.typegen_config, + &mut export, + "schema_resolvers", + None, + )?; + writeln!(content, "{}", export)?; + + Ok(content) +} diff --git a/compiler/crates/relay-compiler/src/config.rs b/compiler/crates/relay-compiler/src/config.rs index d54b31a66d1d9..b6950b50282e9 100644 --- a/compiler/crates/relay-compiler/src/config.rs +++ b/compiler/crates/relay-compiler/src/config.rs @@ -39,6 +39,7 @@ pub use relay_config::PersistConfig; pub use relay_config::ProjectConfig; use relay_config::ProjectName; pub use relay_config::RemotePersistConfig; +use relay_config::ResolversSchemaModuleConfig; use relay_config::SchemaConfig; pub use relay_config::SchemaLocation; use relay_config::TypegenConfig; @@ -377,6 +378,7 @@ Example file: js_module_format: config_file_project.js_module_format, module_import_config: config_file_project.module_import_config, diagnostic_report_config: config_file_project.diagnostic_report_config, + resolvers_schema_module: config_file_project.resolvers_schema_module, }; Ok((project_name, project_config)) }) @@ -740,6 +742,9 @@ pub struct SingleProjectConfigFile { /// of an union with the raw type, null and undefined. #[serde(default)] pub typescript_exclude_undefined_from_nullable_union: bool, + + #[serde(default)] + pub resolvers_schema_module: Option, } impl Default for SingleProjectConfigFile { @@ -766,6 +771,7 @@ impl Default for SingleProjectConfigFile { feature_flags: None, typescript_exclude_undefined_from_nullable_union: false, module_import_config: Default::default(), + resolvers_schema_module: Default::default(), } } } @@ -893,6 +899,7 @@ impl SingleProjectConfigFile { js_module_format: self.js_module_format, feature_flags: self.feature_flags, module_import_config: self.module_import_config, + resolvers_schema_module: self.resolvers_schema_module, ..Default::default() }; @@ -1033,6 +1040,9 @@ pub struct ConfigFileProject { #[serde(default)] pub diagnostic_report_config: DiagnosticReportConfig, + + #[serde(default)] + pub resolvers_schema_module: Option, } pub type PersistId = String; diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs index 81687791b688b..f2d792c42d49c 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts/mod.rs @@ -118,7 +118,6 @@ pub async fn transform_fixture(fixture: &Fixture<'_>) -> Result enable_resolver_normalization_ast: fixture .content .contains("# enable_resolver_normalization_ast"), - generate_resolvers_schema_module: false, relay_resolvers_enable_strict_resolver_flavors: FeatureFlag::Disabled, relay_resolvers_allow_legacy_verbose_syntax: FeatureFlag::Disabled, enable_relay_resolver_mutations: false, diff --git a/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs b/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs index 903468db663df..3f1e4cc15d2e8 100644 --- a/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs +++ b/compiler/crates/relay-compiler/tests/compile_relay_artifacts_with_custom_id/mod.rs @@ -97,7 +97,6 @@ pub async fn transform_fixture(fixture: &Fixture<'_>) -> Result relay_resolver_enable_output_type: FeatureFlag::Disabled, relay_resolver_enable_interface_output_type: FeatureFlag::Disabled, enable_resolver_normalization_ast: false, - generate_resolvers_schema_module: false, relay_resolvers_enable_strict_resolver_flavors: FeatureFlag::Disabled, relay_resolvers_allow_legacy_verbose_syntax: FeatureFlag::Disabled, enable_relay_resolver_mutations: false, diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.expected b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.expected new file mode 100644 index 0000000000000..09f5ccd5b942e --- /dev/null +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.expected @@ -0,0 +1,182 @@ +==================================== INPUT ==================================== +//- User_foo.js +/** + * @RelayResolver User.foo: RelayResolverValue + * @rootFragment UserFooFragment + */ +graphql`fragment UserFooFragment on User { + bar +}` + +//- User_bar.js +/** + * @RelayResolver User.bar: RelayResolverValue + */ + +//- relay.config.json +{ + "language": "flow", + "jsModuleFormat": "haste", + "schema": "schema.graphql", + "featureFlags": { + "enable_relay_resolver_transform": true, + "enable_resolver_normalization_ast": true + }, + "resolversSchemaModule": { + "path": "__generated__/ResolversSchemaModule.js" + } +} + +//- schema.graphql +type User { name: String } +==================================== OUTPUT =================================== +//- __generated__/ResolversSchemaModule.js +/** + * SignedSource<<61302883e149c423f14fff86ac7f776d>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/*:: +import type {NormalizationSplitOperation} from 'relay-runtime'; +import typeof { bar as User_bar } from 'User_bar'; +import typeof { foo as User_foo } from 'User_foo'; + + +type SchemaResolvers = { + User: { + bar: { + resolverFunction: User_bar, + rootFragment: ?NormalizationSplitOperation, + }, + foo: { + resolverFunction: User_foo, + rootFragment: ?NormalizationSplitOperation, + }, + }, +}; + + +*/ +var schema_resolvers /*:: : SchemaResolvers*/ = { + User: { + bar: { + resolverFunction: require('User_bar').bar, + rootFragment: null + }, + foo: { + resolverFunction: require('User_foo').foo, + rootFragment: require('UserFooFragment$normalization.graphql') + }, + }, +}; + + +module.exports = schema_resolvers; + + +//- __generated__/UserFooFragment$normalization.graphql.js +/** + * SignedSource<> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { NormalizationSplitOperation } from 'relay-runtime'; + +*/ + +var node/*: NormalizationSplitOperation*/ = { + "kind": "SplitOperation", + "metadata": {}, + "name": "UserFooFragment$normalization", + "selections": [ + { + "kind": "ClientExtension", + "selections": [ + { + "name": "bar", + "args": null, + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": true, + "resolverModule": { resolverFunctionName: "bar", fieldType: "User" } + } + ] + } + ] +}; + +(node/*: any*/).hash = "285ee53d00b8def775c9e1ed756743bf"; + +module.exports = node; + +//- __generated__/UserFooFragment.graphql.js +/** + * SignedSource<<8cc1f9903984d3c06d796d4524cf1c23>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { Fragment, ReaderFragment } from 'relay-runtime'; +import type { FragmentType } from "relay-runtime"; +import {bar as userBarResolverType} from "User_bar"; +// Type assertion validating that `userBarResolverType` resolver is correctly implemented. +// A type error here indicates that the type signature of the resolver module is incorrect. +(userBarResolverType: () => ?mixed); +declare export opaque type UserFooFragment$fragmentType: FragmentType; +export type UserFooFragment$data = {| + +bar: ?ReturnType, + +$fragmentType: UserFooFragment$fragmentType, +|}; +export type UserFooFragment$key = { + +$data?: UserFooFragment$data, + +$fragmentSpreads: UserFooFragment$fragmentType, + ... +}; +*/ + +var node/*: ReaderFragment*/ = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "UserFooFragment", + "selections": [ + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "fragment": null, + "kind": "RelayResolver", + "name": "bar", + "resolverModule": require('User_bar').bar, + "path": "bar" + } + ] + } + ], + "type": "User", + "abstractKey": null +}; + +(node/*: any*/).hash = "285ee53d00b8def775c9e1ed756743bf"; + +module.exports = ((node/*: any*/)/*: Fragment< + UserFooFragment$fragmentType, + UserFooFragment$data, +>*/); diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.input b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.input new file mode 100644 index 0000000000000..e8c038d21f0c9 --- /dev/null +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration/fixtures/resolvers_schema_module.input @@ -0,0 +1,30 @@ +//- User_foo.js +/** + * @RelayResolver User.foo: RelayResolverValue + * @rootFragment UserFooFragment + */ +graphql`fragment UserFooFragment on User { + bar +}` + +//- User_bar.js +/** + * @RelayResolver User.bar: RelayResolverValue + */ + +//- relay.config.json +{ + "language": "flow", + "jsModuleFormat": "haste", + "schema": "schema.graphql", + "featureFlags": { + "enable_relay_resolver_transform": true, + "enable_resolver_normalization_ast": true + }, + "resolversSchemaModule": { + "path": "__generated__/ResolversSchemaModule.js" + } +} + +//- schema.graphql +type User { name: String } diff --git a/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs b/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs index 802a2e17005eb..bde376b43a4fd 100644 --- a/compiler/crates/relay-compiler/tests/relay_compiler_integration_test.rs +++ b/compiler/crates/relay-compiler/tests/relay_compiler_integration_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<<70d87b3888d42dba62f8215979d8fbad>> + * @generated SignedSource<<60f611a97f09b3caa35c440952f8059b>> */ mod relay_compiler_integration; @@ -61,6 +61,13 @@ async fn custom_scalar_variable_default_arg_non_strict() { test_fixture(transform_fixture, file!(), "custom_scalar_variable_default_arg_non_strict.input", "relay_compiler_integration/fixtures/custom_scalar_variable_default_arg_non_strict.expected", input, expected).await; } +#[tokio::test] +async fn resolvers_schema_module() { + let input = include_str!("relay_compiler_integration/fixtures/resolvers_schema_module.input"); + let expected = include_str!("relay_compiler_integration/fixtures/resolvers_schema_module.expected"); + test_fixture(transform_fixture, file!(), "resolvers_schema_module.input", "relay_compiler_integration/fixtures/resolvers_schema_module.expected", input, expected).await; +} + #[tokio::test] async fn simple_fragment() { let input = include_str!("relay_compiler_integration/fixtures/simple_fragment.input"); diff --git a/compiler/crates/relay-config/src/lib.rs b/compiler/crates/relay-config/src/lib.rs index dd2eb8bcec278..1321d4a2fa68c 100644 --- a/compiler/crates/relay-config/src/lib.rs +++ b/compiler/crates/relay-config/src/lib.rs @@ -17,6 +17,7 @@ mod module_import_config; mod non_node_id_fields_config; mod project_config; mod project_name; +mod resolvers_schema_module_config; mod typegen_config; pub use connection_interface::ConnectionInterface; @@ -35,6 +36,7 @@ pub use project_config::RemotePersistConfig; pub use project_config::SchemaConfig; pub use project_config::SchemaLocation; pub use project_name::ProjectName; +pub use resolvers_schema_module_config::ResolversSchemaModuleConfig; pub use typegen_config::CustomScalarType; pub use typegen_config::CustomScalarTypeImport; pub use typegen_config::FlowTypegenConfig; diff --git a/compiler/crates/relay-config/src/project_config.rs b/compiler/crates/relay-config/src/project_config.rs index c10fbab0ea4e0..db7f937876a45 100644 --- a/compiler/crates/relay-config/src/project_config.rs +++ b/compiler/crates/relay-config/src/project_config.rs @@ -34,6 +34,7 @@ use crate::defer_stream_interface::DeferStreamInterface; use crate::diagnostic_report_config::DiagnosticReportConfig; use crate::module_import_config::ModuleImportConfig; use crate::non_node_id_fields_config::NonNodeIdFieldsConfig; +use crate::resolvers_schema_module_config::ResolversSchemaModuleConfig; use crate::JsModuleFormat; use crate::ProjectName; use crate::TypegenConfig; @@ -234,6 +235,7 @@ pub struct ProjectConfig { pub js_module_format: JsModuleFormat, pub module_import_config: ModuleImportConfig, pub diagnostic_report_config: DiagnosticReportConfig, + pub resolvers_schema_module: Option, } impl Default for ProjectConfig { @@ -261,6 +263,7 @@ impl Default for ProjectConfig { js_module_format: Default::default(), module_import_config: Default::default(), diagnostic_report_config: Default::default(), + resolvers_schema_module: Default::default(), } } } @@ -290,6 +293,7 @@ impl Debug for ProjectConfig { js_module_format, module_import_config, diagnostic_report_config, + resolvers_schema_module, } = self; f.debug_struct("ProjectConfig") .field("name", name) @@ -328,6 +332,7 @@ impl Debug for ProjectConfig { .field("js_module_format", js_module_format) .field("module_import_config", module_import_config) .field("diagnostic_report_config", diagnostic_report_config) + .field("resolvers_schema_module", resolvers_schema_module) .finish() } } diff --git a/compiler/crates/relay-config/src/resolvers_schema_module_config.rs b/compiler/crates/relay-config/src/resolvers_schema_module_config.rs new file mode 100644 index 0000000000000..46ebf2fc77bbe --- /dev/null +++ b/compiler/crates/relay-config/src/resolvers_schema_module_config.rs @@ -0,0 +1,19 @@ +/* + * 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. + */ + +use std::path::PathBuf; + +use serde::Deserialize; +use serde::Serialize; + +/// Configuration for resolvers_schema_module generation +#[derive(Default, Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +pub struct ResolversSchemaModuleConfig { + #[serde(default)] + pub path: PathBuf, +} diff --git a/compiler/crates/relay-transforms/src/apply_transforms.rs b/compiler/crates/relay-transforms/src/apply_transforms.rs index da3deaa86673e..e318d4ee9e979 100644 --- a/compiler/crates/relay-transforms/src/apply_transforms.rs +++ b/compiler/crates/relay-transforms/src/apply_transforms.rs @@ -358,10 +358,7 @@ fn apply_operation_transforms( project_config.feature_flags.enable_relay_resolver_transform, ) })?; - if project_config - .feature_flags - .generate_resolvers_schema_module - { + if project_config.resolvers_schema_module.is_some() { program = log_event.time( "generate_relay_resolvers_root_fragment_split_operation", || generate_relay_resolvers_root_fragment_split_operation(&program),