Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: adding typescript type endpoint and fixing ts types #97

Merged
merged 7 commits into from
Jul 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adding napi values to the rust schema generator
sagoez committed Jul 24, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit ce653e12de60713efb02a86b19b8018134f42130
18 changes: 14 additions & 4 deletions integrationos-api/src/endpoints/mod.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ use axum::{
Extension, Json,
};
use bson::{doc, SerializerOptions};
use futures::TryFutureExt;
use http::{HeaderMap, HeaderValue, StatusCode};
use integrationos_cache::local::connection_cache::ConnectionCacheArcStrHeaderKey;
use integrationos_domain::{
@@ -184,17 +185,26 @@ where
);

let store = T::get_store(state.app_stores.clone());
let count = store.count(query.filter.clone(), None);
let total = store
.collection
.estimated_document_count(None)
.map_err(|e| {
error!("Error counting documents: {e}");
internal_server_error!()
})
.await?;
let find = store.get_many(
Some(query.filter),
None,
None,
Some(doc! {
"createdAt": -1
}),
Some(query.limit),
Some(query.skip),
);

let res = match try_join!(count, find) {
Ok((total, rows)) => ReadResponse {
let res = match try_join!(find) {
Ok((rows,)) => ReadResponse {
rows: rows.into_iter().map(T::public).collect(),
skip: query.skip,
limit: query.limit,
22 changes: 17 additions & 5 deletions integrationos-api/src/endpoints/schema_generator.rs
Original file line number Diff line number Diff line change
@@ -11,16 +11,18 @@ 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", get(generate_types))
.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
@@ -64,10 +66,19 @@ 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(id): Path<Id>,
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();

@@ -81,12 +92,13 @@ pub async fn generate_types(
))?;

let schema = common_model
.generate_as_expanded(&Lang::TypeScript, &cm_store, &ce_store)
.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>,
Original file line number Diff line number Diff line change
@@ -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};

@@ -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 {
31 changes: 30 additions & 1 deletion integrationos-domain/src/domain/schema/common_model.rs
Original file line number Diff line number Diff line change
@@ -187,6 +187,35 @@ 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!(
@@ -883,7 +912,7 @@ impl CommonModel {
}

visited_enums.insert(enum_model.id);
Some(enum_model.as_rust_type())
Some(enum_model.as_rust_schema())
})
.collect::<HashSet<String>>()
.into_iter()