Skip to main content
Glama
pkg.rs19.3 kB
use std::collections::HashMap; pub use UpdateMode::{ SkipExisting, UpdateExisting, }; use chrono::{ DateTime, Utc, }; pub use import::{ ImportOptions, Thing, ThingMap, import_func, import_funcs_for_module_update, import_only_new_funcs, import_pkg, import_pkg_from_pkg, import_schema_variant, }; use serde::{ Deserialize, Serialize, }; use si_pkg::{ FuncSpecBackendKind, FuncSpecBackendResponseType, SiPkgError, SpecError, }; use thiserror::Error; use url::ParseError; use crate::{ AttributePrototypeId, DalContext, FuncBackendKind, FuncBackendResponseType, FuncId, OutputSocketId, PropId, PropKind, SchemaError, TransactionsError, UserPk, WorkspaceError, WorkspacePk, WsEvent, WsEventResult, WsPayload, action::prototype::ActionPrototypeError, attribute::{ prototype::{ AttributePrototypeError, argument::{ AttributePrototypeArgumentError, AttributePrototypeArgumentId, }, }, value::AttributeValueError, }, change_set::ChangeSetError, func::{ FuncError, argument::{ FuncArgumentError, FuncArgumentId, }, binding::FuncBindingError, }, management::prototype::ManagementPrototypeError, module::{ ModuleError, ModulesUpdatedPayload, }, prop::PropError, schema::variant::SchemaVariantError, socket::{ connection_annotation::ConnectionAnnotationError, input::InputSocketError, output::OutputSocketError, }, workspace_snapshot::WorkspaceSnapshotError, }; pub mod export; pub mod import; #[derive(Clone, Debug, Default, PartialEq, Eq)] pub enum UpdateMode { #[default] SkipExisting, UpdateExisting, } #[remain::sorted] #[derive(Debug, Error)] pub enum PkgError { #[error("action prototype error: {0}")] ActionPrototype(#[from] Box<ActionPrototypeError>), #[error("attribute function for context {0:?} has key {1} but is not setting a prop value")] AttributeFuncForKeyMissingProp(import::AttrFuncContext, String), #[error("attribute function for prop {0} has a key {1} but prop kind is {2} not a map)")] AttributeFuncForKeySetOnWrongKind(PropId, String, PropKind), #[error("attribute prototype error: {0}")] AttributePrototype(#[from] Box<AttributePrototypeError>), #[error("attrbute prototype argument error: {0}")] AttributePrototypeArgument(#[from] Box<AttributePrototypeArgumentError>), #[error("AttributePrototypeArgument {0} missing FuncArgument {1}")] AttributePrototypeArgumentMissingFuncArgument(AttributePrototypeArgumentId, FuncArgumentId), #[error("attribute value error: {0}")] AttributeValueError(#[from] Box<AttributeValueError>), #[error("change set error: {0}")] ChangeSet(#[from] Box<ChangeSetError>), #[error("connection annotation error: {0}")] ConnectionAnnotation(#[from] Box<ConnectionAnnotationError>), #[error("expected data on an SiPkg node, but none found: {0}")] DataNotFound(String), #[error("func error: {0}")] Func(#[from] Box<FuncError>), #[error("func argument error: {0}")] FuncArgument(#[from] Box<FuncArgumentError>), #[error("func argument for {0} not found with name {1}")] FuncArgumentNotFoundByName(FuncId, String), #[error("action prototype error: {0}")] FuncBinding(#[from] Box<FuncBindingError>), #[error("input socket error: {0}")] InputSocket(#[from] Box<InputSocketError>), #[error("found multiple intrinsic func specs for name: {0}")] IntrinsicFuncSpecsMultipleForName(String), #[error("found no intrinsic func specs for name: {0}")] IntrinsicFuncSpecsNoneForName(String), #[error("management prototype error: {0}")] ManagementPrototype(#[from] Box<ManagementPrototypeError>), #[error("Missing Func {1} for AttributePrototype {0}")] MissingAttributePrototypeFunc(AttributePrototypeId, FuncId), #[error("Func {0} missing from exported funcs")] MissingExportedFunc(FuncId), #[error("Cannot find FuncArgument {0} for Func {1}")] MissingFuncArgument(String, FuncId), #[error("Package asked for a function with the unique id {0} but none could be found ({1})")] MissingFuncUniqueId(String, &'static str), #[error("Cannot find InputSocket for name: {0}")] MissingInputSocketName(String), #[error("Intrinsic function {0} not found")] MissingIntrinsicFunc(String), #[error("Unique id missing for node in workspace backup: {0}")] MissingUniqueIdForNode(String), #[error("module error: {0}")] Module(#[from] Box<ModuleError>), #[error("output socket error: {0}")] OutputSocket(#[from] Box<OutputSocketError>), #[error("output socket {0} missing attribute prototype")] OutputSocketMissingPrototype(OutputSocketId), #[error("Package with that hash already installed: {0}")] PackageAlreadyInstalled(String), #[error("si pkg error: {0}")] Pkg(#[from] SiPkgError), #[error("pkg spec error: {0}")] PkgSpec(#[from] SpecError), #[error("prop error: {0}")] Prop(#[from] Box<PropError>), #[error("prop {0} missing attribute prototype")] PropMissingPrototype(PropId), #[error("prop {0} not found")] PropNotFoundByName(String), #[error("prop spec structure is invalid: {0}")] PropSpecChildrenInvalid(String), #[error("schema error: {0}")] Schema(#[from] Box<SchemaError>), #[error("schema variant error: {0}")] SchemaVariant(#[from] Box<SchemaVariantError>), #[error("json serialization error: {0}")] SerdeJson(#[from] serde_json::Error), #[error("si db error: {0}")] SiDb(#[from] si_db::Error), #[error( "taking output socket as input for a prop is unsupported for name ({0}) and socket name ({1})" )] TakingOutputSocketAsInputForPropUnsupported(String, String), #[error("transactions error: {0}")] Transactions(#[from] Box<TransactionsError>), #[error("ulid decode error: {0}")] UlidDecode(#[from] ulid::DecodeError), #[error("url parse error: {0}")] Url(#[from] ParseError), #[error("workspace error: {0}")] Workspace(#[from] Box<WorkspaceError>), #[error("workspace export not supported")] WorkspaceExportNotSupported(), #[error("workspace pk not found on context")] WorkspacePkNone, #[error("workspace snapshot error: {0}")] WorkspaceSnaphot(#[from] Box<WorkspaceSnapshotError>), } impl From<ActionPrototypeError> for PkgError { fn from(value: ActionPrototypeError) -> Self { Box::new(value).into() } } impl From<AttributePrototypeError> for PkgError { fn from(value: AttributePrototypeError) -> Self { Box::new(value).into() } } impl From<AttributePrototypeArgumentError> for PkgError { fn from(value: AttributePrototypeArgumentError) -> Self { Box::new(value).into() } } impl From<AttributeValueError> for PkgError { fn from(value: AttributeValueError) -> Self { Box::new(value).into() } } impl From<ChangeSetError> for PkgError { fn from(value: ChangeSetError) -> Self { Box::new(value).into() } } impl From<ConnectionAnnotationError> for PkgError { fn from(value: ConnectionAnnotationError) -> Self { Box::new(value).into() } } impl From<FuncError> for PkgError { fn from(value: FuncError) -> Self { Box::new(value).into() } } impl From<FuncArgumentError> for PkgError { fn from(value: FuncArgumentError) -> Self { Box::new(value).into() } } impl From<FuncBindingError> for PkgError { fn from(value: FuncBindingError) -> Self { Box::new(value).into() } } impl From<InputSocketError> for PkgError { fn from(value: InputSocketError) -> Self { Box::new(value).into() } } impl From<ManagementPrototypeError> for PkgError { fn from(value: ManagementPrototypeError) -> Self { Box::new(value).into() } } impl From<ModuleError> for PkgError { fn from(value: ModuleError) -> Self { Box::new(value).into() } } impl From<OutputSocketError> for PkgError { fn from(value: OutputSocketError) -> Self { Box::new(value).into() } } impl From<PropError> for PkgError { fn from(value: PropError) -> Self { Box::new(value).into() } } impl From<SchemaError> for PkgError { fn from(value: SchemaError) -> Self { Box::new(value).into() } } impl From<SchemaVariantError> for PkgError { fn from(value: SchemaVariantError) -> Self { Box::new(value).into() } } impl From<TransactionsError> for PkgError { fn from(value: TransactionsError) -> Self { Box::new(value).into() } } impl From<WorkspaceError> for PkgError { fn from(value: WorkspaceError) -> Self { Box::new(value).into() } } impl From<WorkspaceSnapshotError> for PkgError { fn from(value: WorkspaceSnapshotError) -> Self { Box::new(value).into() } } pub type PkgResult<T> = Result<T, PkgError>; impl From<FuncBackendKind> for FuncSpecBackendKind { fn from(value: FuncBackendKind) -> Self { match value { FuncBackendKind::Array => Self::Array, FuncBackendKind::Boolean => Self::Boolean, FuncBackendKind::Diff => Self::Diff, FuncBackendKind::Float => Self::Float, FuncBackendKind::Identity => Self::Identity, FuncBackendKind::Integer => Self::Integer, FuncBackendKind::JsAction => Self::JsAction, FuncBackendKind::JsAttribute => Self::JsAttribute, FuncBackendKind::Json => Self::Json, FuncBackendKind::JsReconciliation => Self::JsReconciliation, FuncBackendKind::JsSchemaVariantDefinition => Self::JsSchemaVariantDefinition, FuncBackendKind::JsValidation => Self::JsValidation, FuncBackendKind::Map => Self::Map, FuncBackendKind::Object => Self::Object, FuncBackendKind::String => Self::String, FuncBackendKind::Unset => Self::Unset, FuncBackendKind::Validation => Self::Validation, FuncBackendKind::JsAuthentication => Self::JsAuthentication, FuncBackendKind::Management => Self::Management, FuncBackendKind::ResourcePayloadToValue => Self::ResourcePayloadToValue, FuncBackendKind::NormalizeToArray => Self::NormalizeToArray, FuncBackendKind::Debug => Self::Debug, } } } impl From<FuncSpecBackendKind> for FuncBackendKind { fn from(value: FuncSpecBackendKind) -> Self { match value { FuncSpecBackendKind::Array => Self::Array, FuncSpecBackendKind::Boolean => Self::Boolean, FuncSpecBackendKind::Diff => Self::Diff, FuncSpecBackendKind::Float => Self::Float, FuncSpecBackendKind::Identity => Self::Identity, FuncSpecBackendKind::Integer => Self::Integer, FuncSpecBackendKind::JsAction => Self::JsAction, FuncSpecBackendKind::JsAttribute => Self::JsAttribute, FuncSpecBackendKind::Json => Self::Json, FuncSpecBackendKind::JsReconciliation => Self::JsReconciliation, FuncSpecBackendKind::JsSchemaVariantDefinition => Self::JsSchemaVariantDefinition, FuncSpecBackendKind::JsValidation => Self::JsValidation, FuncSpecBackendKind::Map => Self::Map, FuncSpecBackendKind::Object => Self::Object, FuncSpecBackendKind::String => Self::String, FuncSpecBackendKind::Unset => Self::Unset, FuncSpecBackendKind::Validation => Self::Validation, FuncSpecBackendKind::JsAuthentication => Self::JsAuthentication, FuncSpecBackendKind::Management => Self::Management, FuncSpecBackendKind::ResourcePayloadToValue => Self::ResourcePayloadToValue, FuncSpecBackendKind::NormalizeToArray => Self::NormalizeToArray, FuncSpecBackendKind::Debug => Self::Debug, } } } impl From<FuncBackendResponseType> for FuncSpecBackendResponseType { fn from(value: FuncBackendResponseType) -> Self { match value { FuncBackendResponseType::Action => Self::Action, FuncBackendResponseType::Array => Self::Array, FuncBackendResponseType::Boolean => Self::Boolean, FuncBackendResponseType::CodeGeneration => Self::CodeGeneration, FuncBackendResponseType::Float => Self::Float, FuncBackendResponseType::Identity => Self::Identity, FuncBackendResponseType::Integer => Self::Integer, FuncBackendResponseType::Json => Self::Json, FuncBackendResponseType::Map => Self::Map, FuncBackendResponseType::Object => Self::Object, FuncBackendResponseType::Qualification => Self::Qualification, FuncBackendResponseType::Reconciliation => Self::Reconciliation, FuncBackendResponseType::SchemaVariantDefinition => Self::SchemaVariantDefinition, FuncBackendResponseType::String => Self::String, FuncBackendResponseType::Unset => Self::Unset, FuncBackendResponseType::Validation => Self::Validation, FuncBackendResponseType::Void => Self::Void, FuncBackendResponseType::Management => Self::Management, FuncBackendResponseType::Debug => Self::Debug, } } } impl From<FuncSpecBackendResponseType> for FuncBackendResponseType { fn from(value: FuncSpecBackendResponseType) -> Self { match value { FuncSpecBackendResponseType::Action => Self::Action, FuncSpecBackendResponseType::Array => Self::Array, FuncSpecBackendResponseType::Boolean => Self::Boolean, FuncSpecBackendResponseType::CodeGeneration => Self::CodeGeneration, FuncSpecBackendResponseType::Float => Self::Float, FuncSpecBackendResponseType::Identity => Self::Identity, FuncSpecBackendResponseType::Integer => Self::Integer, FuncSpecBackendResponseType::Json => Self::Json, FuncSpecBackendResponseType::Map => Self::Map, FuncSpecBackendResponseType::Object => Self::Object, FuncSpecBackendResponseType::Qualification => Self::Qualification, FuncSpecBackendResponseType::Reconciliation => Self::Reconciliation, FuncSpecBackendResponseType::SchemaVariantDefinition => Self::SchemaVariantDefinition, FuncSpecBackendResponseType::String => Self::String, FuncSpecBackendResponseType::Unset => Self::Unset, FuncSpecBackendResponseType::Validation => Self::Validation, FuncSpecBackendResponseType::Void => Self::Void, FuncSpecBackendResponseType::Management => Self::Management, FuncSpecBackendResponseType::Debug => Self::Debug, } } } /// A generic hash map of hash maps for tracking the presence of a thing in each change set. If a /// thing is asked for in a specific change set, and not found, the HEAD change set will be /// checked. #[derive(Debug)] pub struct ChangeSetThingMap<Key, Thing> { inner: HashMap<Key, Thing>, overrides: HashMap<Key, Key>, } impl<Key, Thing> Default for ChangeSetThingMap<Key, Thing> where Key: Eq + PartialEq + std::hash::Hash, { fn default() -> Self { Self::new() } } impl<Key, Thing> ChangeSetThingMap<Key, Thing> where Key: Eq + PartialEq + std::hash::Hash, { pub fn new() -> Self { Self { inner: HashMap::new(), overrides: HashMap::new(), } } pub fn get(&self, key: &Key) -> Option<&Thing> { match self.overrides.get(key) { Some(override_key) => self.inner.get(override_key), None => self.inner.get(key), } } pub fn insert(&mut self, key: Key, thing: Thing) -> Option<Thing> { self.inner.insert(key, thing) } pub fn insert_override(&mut self, to_override_unique_id: Key, override_unique_id: Key) { self.overrides .insert(to_override_unique_id, override_unique_id); } } #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct WorkspaceImportPayload { workspace_pk: Option<WorkspacePk>, user_pk: Option<UserPk>, } #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ImportWorkspaceVotePayload { workspace_pk: Option<WorkspacePk>, user_pk: UserPk, vote: String, } #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct WorkspaceActorPayload { workspace_pk: Option<WorkspacePk>, user_pk: Option<UserPk>, } #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct WorkspaceImportApprovalActorPayload { workspace_pk: Option<WorkspacePk>, user_pk: Option<UserPk>, created_at: DateTime<Utc>, created_by: String, name: String, } impl WsEvent { pub async fn module_imported( ctx: &DalContext, schema_variants: Vec<si_frontend_types::SchemaVariant>, ) -> WsEventResult<Self> { WsEvent::new(ctx, WsPayload::ModuleImported(schema_variants)).await } pub async fn modules_updated(ctx: &DalContext) -> WsEventResult<Self> { WsEvent::new( ctx, WsPayload::ModulesUpdated(ModulesUpdatedPayload { change_set_id: ctx.change_set_id(), }), ) .await } pub async fn import_workspace_vote( ctx: &DalContext, workspace_pk: Option<WorkspacePk>, user_pk: UserPk, vote: String, ) -> WsEventResult<Self> { WsEvent::new( ctx, WsPayload::ImportWorkspaceVote(ImportWorkspaceVotePayload { workspace_pk, user_pk, vote, }), ) .await } pub async fn workspace_import_begin_approval_process( ctx: &DalContext, workspace_pk: Option<WorkspacePk>, user_pk: Option<UserPk>, workspace_export_created_at: DateTime<Utc>, workspace_export_created_by: String, workspace_export_name: String, ) -> WsEventResult<Self> { WsEvent::new( ctx, WsPayload::WorkspaceImportBeginApprovalProcess(WorkspaceImportApprovalActorPayload { workspace_pk, user_pk, created_at: workspace_export_created_at, created_by: workspace_export_created_by, name: workspace_export_name, }), ) .await } pub async fn workspace_import_cancel_approval_process( ctx: &DalContext, workspace_pk: Option<WorkspacePk>, user_pk: Option<UserPk>, ) -> WsEventResult<Self> { WsEvent::new( ctx, WsPayload::WorkspaceImportCancelApprovalProcess(WorkspaceActorPayload { workspace_pk, user_pk, }), ) .await } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server