dagger_sdk/core/
graphql_client.rs1use std::collections::HashMap;
2use std::sync::Arc;
3
4use async_trait::async_trait;
5use base64::engine::general_purpose;
6use base64::Engine;
7use thiserror::Error;
8
9use crate::core::connect_params::ConnectParams;
10use crate::core::gql_client::{ClientConfig, GQLClient};
11
12use super::config;
13use super::gql_client::GraphQLErrorMessage;
14
15#[async_trait]
16pub trait GraphQLClient {
17 async fn query(&self, query: &str) -> Result<Option<serde_json::Value>, GraphQLError>;
18}
19
20pub type DynGraphQLClient = Arc<dyn GraphQLClient + Send + Sync>;
21
22#[derive(Debug)]
23pub struct DefaultGraphQLClient {
24 client: GQLClient,
25}
26
27impl DefaultGraphQLClient {
28 pub fn new(conn: &ConnectParams, config: &config::Config) -> Self {
29 let token = general_purpose::URL_SAFE.encode(format!("{}:", conn.session_token));
30
31 let mut headers = HashMap::new();
32 headers.insert("Authorization".to_string(), format!("Basic {}", token));
33
34 Self {
35 client: GQLClient::new_with_config(ClientConfig {
36 endpoint: conn.url(),
37 connect_timeout_ms: Some(config.timeout_ms),
38 execute_timeout_ms: config.execute_timeout_ms,
39 headers: Some(headers),
40 proxy: None,
41 }),
42 }
43 }
44}
45
46#[async_trait]
47impl GraphQLClient for DefaultGraphQLClient {
48 async fn query(&self, query: &str) -> Result<Option<serde_json::Value>, GraphQLError> {
49 let res: Option<serde_json::Value> =
50 self.client.query(query).await.map_err(map_graphql_error)?;
51
52 return Ok(res);
53 }
54}
55
56fn map_graphql_error(gql_error: crate::core::gql_client::GraphQLError) -> GraphQLError {
57 let Some(json) = gql_error.json() else {
58 return GraphQLError::HttpError(gql_error.message().to_string());
59 };
60
61 let Some(message) = json.first().map(|f| f.message.clone()) else {
62 return GraphQLError::HttpError(gql_error.message().to_string());
63 };
64
65 GraphQLError::DomainError {
66 message,
67 fields: json,
68 }
69}
70
71#[derive(Error, Debug)]
72pub enum GraphQLError {
73 #[error("http error: {0}")]
74 HttpError(String),
75 #[error("domain error: {message}")]
76 DomainError {
77 message: String,
78 fields: Vec<GraphQLErrorMessage>,
79 },
80}