Skip to content

Commit

Permalink
chore: adding typescript type endpoint and fixing ts types (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
sagojez authored Jul 24, 2024
1 parent 9c000a8 commit 3a7f035
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 28 deletions.
7 changes: 4 additions & 3 deletions integrationos-api/src/endpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ where
);

let store = T::get_store(state.app_stores.clone());
let count = store.count(query.filter.clone(), None);
// TODO: Investigate how to improve performance here
let total = store.count(query.filter.clone(), None);
let find = store.get_many(
Some(query.filter),
None,
Expand All @@ -193,8 +194,8 @@ where
Some(query.skip),
);

let res = match try_join!(count, find) {
Ok((total, rows)) => ReadResponse {
let res = match try_join!(find, total) {
Ok((rows, total)) => ReadResponse {
rows: rows.into_iter().map(T::public).collect(),
skip: query.skip,
limit: query.limit,
Expand Down
44 changes: 41 additions & 3 deletions integrationos-api/src/endpoints/schema_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ use axum::{
};
use bson::{doc, Document};
use futures::StreamExt;
use integrationos_domain::{ApplicationError, Id, IntegrationOSError, InternalError, Store};
use integrationos_domain::{
api_model_config::Lang, ApplicationError, Id, IntegrationOSError, InternalError, Store,
};
use mongodb::options::FindOptions;
use serde::Deserialize;
use std::sync::Arc;

pub fn get_router() -> Router<Arc<AppState>> {
Router::new()
.route("/projection", get(get_common_model_proj))
.route("/projection", get(get_common_models_projections))
.route("/:id", get(generate_schema))
.route("/types/:id/:lang", get(generate_types))
}

pub async fn get_common_model_proj(
#[tracing::instrument(name = "generate::schema::projection", skip(state))]
pub async fn get_common_models_projections(
state: State<Arc<AppState>>,
) -> Result<Json<ReadResponse<Document>>, IntegrationOSError> {
let collection = state
Expand Down Expand Up @@ -61,6 +66,39 @@ pub async fn get_common_model_proj(
}))
}

#[derive(Debug, Deserialize)]
struct TypeParams {
id: Id,
lang: Lang,
}

#[tracing::instrument(name = "generate::schema::types", skip(state), fields(id = %id, lang = %lang))]
pub async fn generate_types(
state: State<Arc<AppState>>,
Path(TypeParams { id, lang }): Path<TypeParams>,
) -> Result<String, IntegrationOSError> {
println!("id: {}, lang: {}", id, lang);

let cm_store = state.app_stores.common_model.clone();
let ce_store = state.app_stores.common_enum.clone();

let common_model = cm_store
.get_one_by_id(&id.to_string())
.await
.map_err(IntegrationOSError::from)?
.ok_or(ApplicationError::not_found(
&format!("CommonModel with id {} not found", id),
None,
))?;

let schema = common_model
.generate_as_expanded(&lang, &cm_store, &ce_store)
.await;

Ok(schema)
}

#[tracing::instrument(name = "generate::schema", skip(state, id), fields(id = %id))]
pub async fn generate_schema(
state: State<Arc<AppState>>,
Path(id): Path<Id>,
Expand Down
3 changes: 2 additions & 1 deletion integrationos-api/tests/api_tests/pagination_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async fn test_pagination() {
assert_eq!(config, pipeline.config.as_ref().unwrap());

pipelines.push(pipeline);
sleep(Duration::from_millis(1)).await;
sleep(Duration::from_millis(100)).await;
}

let pipelines: Vec<Pipeline> = pipelines.into_iter().rev().collect();
Expand All @@ -68,6 +68,7 @@ async fn check_response(server: &TestServer, limit: u64, skip: u64, pipelines: &
)
.await
.unwrap();

assert_eq!(res.code, StatusCode::OK);

let res: ReadResponse<Pipeline> = serde_json::from_value(res.data).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use js_sandbox_ios::Script;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
use strum::Display;

use crate::{prelude::schema::json_schema::JsonSchema, IntegrationOSError, InternalError};

Expand Down Expand Up @@ -169,7 +170,7 @@ pub struct Compute {
pub language: Lang,
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Default)]
#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Default, Display)]
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[serde(rename_all = "lowercase")]
pub enum Lang {
Expand Down
75 changes: 55 additions & 20 deletions integrationos-domain/src/domain/schema/common_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,61 @@ impl CommonEnum {
)
}

/// Generates a napi annotated enum for the enum rust type
pub fn as_rust_schema(&self) -> String {
format!(
"{} pub enum {} {{ {} }}\n",
"#[napi(string_enum = \"kebab-case\", js_name = {})]",
replace_reserved_keyword(&self.name, Lang::Rust)
.replace("::", "")
.pascal_case(),
self.options
.iter()
.map(|option| {
let option_name = option.pascal_case();
let option_value = if option.chars().all(char::is_uppercase) {
option.to_lowercase()
} else {
option.kebab_case()
};

let option_annotation = format!("#[napi(value = \"{}\")]", option_value);

format!("{} {}", option_annotation, option_name)
})
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<_>>()
.join(", ")
)
}

pub fn as_typescript_type(&self) -> String {
// let's add the value directly to the enum
format!(
"export const enum {} {{ {} }}\n",
replace_reserved_keyword(&self.name, Lang::TypeScript)
.replace("::", "")
.pascal_case(),
self.options
.iter()
.map(|option| {
let option_name = option.pascal_case();
let option_value = if option.chars().all(char::is_uppercase) {
option.to_lowercase()
} else {
option.kebab_case()
};

format!("{} = '{}'", option_name, option_value)
})
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<_>>()
.join(", ")
)
}

/// Generates a effect Schema for the enum
pub fn as_typescript_schema(&self) -> String {
let name = replace_reserved_keyword(&self.name, Lang::TypeScript)
Expand Down Expand Up @@ -220,22 +275,6 @@ impl CommonEnum {

format!("{}\n{}", native_enum, schema)
}

pub fn as_typescript_type(&self) -> String {
format!(
"export const enum {} {{ {} }}\n",
replace_reserved_keyword(&self.name, Lang::TypeScript)
.replace("::", "")
.pascal_case(),
self.options
.iter()
.map(|option| option.pascal_case())
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<_>>()
.join(", ")
)
}
}

impl DataType {
Expand Down Expand Up @@ -625,10 +664,6 @@ impl CommonModel {
}
}

pub fn generate_as_typescript_schema(&self) -> String {
self.as_typescript_schema()
}

/// Generates the model as a string in the specified language
/// with recursively expanded inner models and enums.
/// This is useful for generating the entire model and its
Expand Down

0 comments on commit 3a7f035

Please sign in to comment.