diff --git a/compiler/crates/relay-compiler/src/config.rs b/compiler/crates/relay-compiler/src/config.rs index 4c2feb06a77e0..a793105321383 100644 --- a/compiler/crates/relay-compiler/src/config.rs +++ b/compiler/crates/relay-compiler/src/config.rs @@ -994,12 +994,12 @@ impl SingleProjectConfigFile { } })?, ); - for extension_dir in self.schema_extensions.iter() { + for extension_path in self.schema_extensions.iter() { paths.push( - canonicalize(root_dir.join(extension_dir.clone())).map_err(|_| { - ConfigValidationError::ExtensionDirNotExistent { + canonicalize(root_dir.join(extension_path.clone())).map_err(|_| { + ConfigValidationError::ExtensionPathNotExistent { project_name: self.project_name, - extension_dir: extension_dir.clone(), + extension_path: extension_path.clone(), } })?, ); diff --git a/compiler/crates/relay-compiler/src/errors.rs b/compiler/crates/relay-compiler/src/errors.rs index 0f45dcb71ba1b..4c2bc417fae8a 100644 --- a/compiler/crates/relay-compiler/src/errors.rs +++ b/compiler/crates/relay-compiler/src/errors.rs @@ -218,11 +218,11 @@ pub enum ConfigValidationError { }, #[error( - "The `schemaExtensions` configured for project `{project_name}` does not exist at `{extension_dir}`." + "The `schemaExtensions` configured for project `{project_name}` does not exist at `{extension_path}`." )] - ExtensionDirNotExistent { + ExtensionPathNotExistent { project_name: ProjectName, - extension_dir: PathBuf, + extension_path: PathBuf, }, #[error( 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 2d542dd9942a1..73efb10a2552e 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 @@ -67,7 +67,7 @@ pub fn get_watchman_expr(config: &Config) -> Expr { let extension_roots = config.get_extension_roots(); if !extension_roots.is_empty() { - let extensions_expr = expr_graphql_files_in_dirs(extension_roots); + let extensions_expr = expr_graphql_file_or_dir_contents(extension_roots); expressions.push(extensions_expr); } @@ -132,13 +132,27 @@ fn expr_files_in_dirs(roots: Vec) -> Expr { fn expr_graphql_files_in_dirs(roots: Vec) -> Expr { Expr::All(vec![ - // ending in *.graphql + // ending in *.graphql or *.gql Expr::Suffix(vec!["graphql".into(), "gql".into()]), // in one of the extension directories expr_files_in_dirs(roots), ]) } +// Expression to get all graphql items by path or path of containing folder. +fn expr_graphql_file_or_dir_contents(paths: Vec) -> Expr { + Expr::All(vec![ + Expr::Suffix(vec!["graphql".into(), "gql".into()]), + Expr::Any(vec![ + Expr::Name(NameTerm { + paths: paths.clone(), + wholename: true, + }), + expr_files_in_dirs(paths), + ]), + ]) +} + /// Helper to create an `anyof` expression if multiple items are passed or just /// return the expression for a single item input `Vec`. /// Panics for empty expressions. These are not valid in Watchman. We could diff --git a/packages/relay-compiler/README.md b/packages/relay-compiler/README.md index 3213c568b1baf..42e965d006291 100644 --- a/packages/relay-compiler/README.md +++ b/packages/relay-compiler/README.md @@ -69,7 +69,7 @@ file sources, and "listen" to the file changes in the "watch" mode. If [string] - `excludes` Directories to ignore under `src`. [array] [default: ["\*\*/node_modules/\*\*", "\*\*/__mocks__/\*\*", "\*\*/__generated__/\*\*"]] -- `schemaExtensions` List of directories with schema extensions. [array] +- `schemaExtensions` List of files or directories with schema extensions. [array] - `schemaConfig` - `nodeInterfaceIdField` Configure the name of the globally unique ID field on the Node interface. Useful if you can't use the default `id` field name. diff --git a/website/docs/guides/client-schema-extensions.md b/website/docs/guides/client-schema-extensions.md index a9a0959e0d49c..ef9c7c4272e5c 100644 --- a/website/docs/guides/client-schema-extensions.md +++ b/website/docs/guides/client-schema-extensions.md @@ -29,9 +29,10 @@ The Relay Compiler fully supports client-side extensions of the schema, which al ## Extending the server schema -To extend the server schema, create a new `.graphql` file inside your `--src` directory. -Let's call it `./src/clientSchema.graphql`. -This file needs to be in a folder referenced in the `"schemaExtensions"` of your Relay config. +To extend the server schema, create a new `.graphql` file inside your `--src` +directory. Let's call it `./src/clientSchema.graphql`. This file needs to be +referenced in the `"schemaExtensions"` of your Relay config, either directly or +via its folder. This schema describes what local data can be queried on the client. It can even be used to extend an existing server schema.