diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index 62a29551d1d..55fbf80df19 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -269,6 +269,16 @@ "meta": { "description": "Additional metadata pertaining to the linked resource." }, + "proto_paths": { + "description": "The proto paths to be used when resolving dependencies. Only valid when [`Link::type_of`] is [`LinkType::Protobuf`]", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "src": { "description": "The source of the link. It can be a URL or a path to a file. If a path is provided, it is relative to the file that imports the link.", "type": "string" diff --git a/src/cli/generator/generator.rs b/src/cli/generator/generator.rs index 3fa31653962..16ffdb1eadf 100644 --- a/src/cli/generator/generator.rs +++ b/src/cli/generator/generator.rs @@ -143,7 +143,18 @@ impl Generator { if let Some(relative_path_to_proto) = to_relative_path(output_dir, &path) { metadata.path = relative_path_to_proto; } - input_samples.push(Input::Proto { metadata, url, connect_rpc }); + let relative_proto_paths = proto_paths.map(|paths| { + paths + .iter() + .filter_map(|p| to_relative_path(output_dir, p)) + .collect::>() + }); + input_samples.push(Input::Proto { + metadata, + url, + connect_rpc, + proto_paths: relative_proto_paths, + }); } Source::Config { src } => { let path = src.0; diff --git a/src/core/config/directives/link.rs b/src/core/config/directives/link.rs index 5063812a2f4..e045caf98c3 100644 --- a/src/core/config/directives/link.rs +++ b/src/core/config/directives/link.rs @@ -93,4 +93,9 @@ pub struct Link { /// Additional metadata pertaining to the linked resource. #[serde(default, skip_serializing_if = "is_default")] pub meta: Option, + /// + /// The proto paths to be used when resolving dependencies. + /// Only valid when [`Link::type_of`] is [`LinkType::Protobuf`] + #[serde(default, skip_serializing_if = "is_default")] + pub proto_paths: Option>, } diff --git a/src/core/config/reader.rs b/src/core/config/reader.rs index 675c6a9d42a..5240e658e80 100644 --- a/src/core/config/reader.rs +++ b/src/core/config/reader.rs @@ -79,7 +79,13 @@ impl ConfigReader { }); } LinkType::Protobuf => { - let meta = self.proto_reader.read(path, None).await?; + let proto_paths = link.proto_paths.as_ref().map(|paths| { + paths + .iter() + .map(|p| Self::resolve_path(p, parent_dir)) + .collect::>() + }); + let meta = self.proto_reader.read(path, proto_paths.as_deref()).await?; extensions.add_proto(meta); } LinkType::Script => { diff --git a/src/core/config/transformer/ambiguous_type.rs b/src/core/config/transformer/ambiguous_type.rs index 3a3a9dc646b..e5f2e40aa77 100644 --- a/src/core/config/transformer/ambiguous_type.rs +++ b/src/core/config/transformer/ambiguous_type.rs @@ -253,6 +253,7 @@ mod tests { metadata: ProtoMetadata { descriptor_set: set, path: news_proto.to_string() }, url, connect_rpc: None, + proto_paths: None, }]) .generate(false)?; diff --git a/src/core/generator/generator.rs b/src/core/generator/generator.rs index 98cb81515ef..25966c33a29 100644 --- a/src/core/generator/generator.rs +++ b/src/core/generator/generator.rs @@ -44,6 +44,7 @@ pub enum Input { url: String, metadata: ProtoMetadata, connect_rpc: Option, + proto_paths: Option>, }, Config { schema: String, @@ -85,11 +86,13 @@ impl Generator { } /// Generates the configuration from the provided protobuf. + #[allow(clippy::too_many_arguments)] fn generate_from_proto( &self, metadata: &ProtoMetadata, operation_name: &str, url: &str, + proto_paths: &Option>, ) -> anyhow::Result { let descriptor_set = resolve_file_descriptor_set(metadata.descriptor_set.clone())?; let mut config = from_proto(&[descriptor_set], operation_name, url)?; @@ -99,6 +102,7 @@ impl Generator { type_of: LinkType::Protobuf, headers: None, meta: None, + proto_paths: proto_paths.to_owned(), }); Ok(config) } @@ -135,8 +139,9 @@ impl Generator { config = config .merge_right(self.generate_from_json(&type_name_generator, &[req_sample])?); } - Input::Proto { metadata, url, connect_rpc } => { - let proto_config = self.generate_from_proto(metadata, &self.query, url)?; + Input::Proto { metadata, url, connect_rpc, proto_paths } => { + let proto_config = + self.generate_from_proto(metadata, &self.query, url, proto_paths)?; let proto_config = if connect_rpc == &Some(true) { ConnectRPC.transform(proto_config).to_result()? } else { @@ -272,6 +277,7 @@ pub mod test { }, url: "http://localhost:50051".to_string(), connect_rpc: None, + proto_paths: None, }]) .generate(false)?; @@ -326,6 +332,7 @@ pub mod test { }, url: "http://localhost:50051".to_string(), connect_rpc: None, + proto_paths: None, }; // Config input diff --git a/src/core/grpc/data_loader_request.rs b/src/core/grpc/data_loader_request.rs index 1f49188d6f2..7ee4bba124b 100644 --- a/src/core/grpc/data_loader_request.rs +++ b/src/core/grpc/data_loader_request.rs @@ -74,6 +74,7 @@ mod tests { type_of: LinkType::Protobuf, headers: None, meta: None, + proto_paths: None, }]); let method = GrpcMethod { package: "greetings".to_string(), diff --git a/src/core/grpc/protobuf.rs b/src/core/grpc/protobuf.rs index 979b7afb2fc..6332bf9bf8a 100644 --- a/src/core/grpc/protobuf.rs +++ b/src/core/grpc/protobuf.rs @@ -268,6 +268,7 @@ pub mod tests { type_of: LinkType::Protobuf, headers: None, meta: None, + proto_paths: None, }]); let method = GrpcMethod { package: id, service: "a".to_owned(), name: "b".to_owned() }; diff --git a/src/core/grpc/request_template.rs b/src/core/grpc/request_template.rs index b1cb5653e4a..4643c5965f3 100644 --- a/src/core/grpc/request_template.rs +++ b/src/core/grpc/request_template.rs @@ -160,6 +160,7 @@ mod tests { type_of: LinkType::Protobuf, headers: None, meta: None, + proto_paths: None, }]); let method = GrpcMethod { package: id.to_string(),