export patchdb ts types from rust

This commit is contained in:
Aiden McClelland
2024-03-27 17:47:12 -06:00
parent 9cf62f03fa
commit f41f5ebebd
75 changed files with 536 additions and 634 deletions

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type BindOptionsSecure = { ssl: boolean, };
export type ServiceInterfaceId = string;

View File

@@ -6,21 +6,21 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use yasi::InternedString;
mod action;
mod address;
mod health_check;
mod host;
mod image;
mod invalid_id;
mod package;
mod service_interface;
mod volume;
pub use action::ActionId;
pub use address::AddressId;
pub use health_check::HealthCheckId;
pub use host::HostId;
pub use image::ImageId;
pub use invalid_id::InvalidId;
pub use package::{PackageId, SYSTEM_PACKAGE_ID};
pub use service_interface::ServiceInterfaceId;
pub use volume::VolumeId;
lazy_static::lazy_static! {

View File

@@ -1,46 +1,48 @@
use std::path::Path;
use serde::{Deserialize, Deserializer, Serialize};
use ts_rs::TS;
use crate::Id;
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct AddressId(Id);
impl From<Id> for AddressId {
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, TS)]
#[ts(export, type = "string")]
pub struct ServiceInterfaceId(Id);
impl From<Id> for ServiceInterfaceId {
fn from(id: Id) -> Self {
Self(id)
}
}
impl std::fmt::Display for AddressId {
impl std::fmt::Display for ServiceInterfaceId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.0)
}
}
impl std::ops::Deref for AddressId {
impl std::ops::Deref for ServiceInterfaceId {
type Target = str;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl AsRef<str> for AddressId {
impl AsRef<str> for ServiceInterfaceId {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<'de> Deserialize<'de> for AddressId {
impl<'de> Deserialize<'de> for ServiceInterfaceId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(AddressId(Deserialize::deserialize(deserializer)?))
Ok(ServiceInterfaceId(Deserialize::deserialize(deserializer)?))
}
}
impl AsRef<Path> for AddressId {
impl AsRef<Path> for ServiceInterfaceId {
fn as_ref(&self) -> &Path {
self.0.as_ref().as_ref()
}
}
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for AddressId {
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for ServiceInterfaceId {
fn encode_by_ref(
&self,
buf: &mut <sqlx::Postgres as sqlx::database::HasArguments<'q>>::ArgumentBuffer,
@@ -48,7 +50,7 @@ impl<'q> sqlx::Encode<'q, sqlx::Postgres> for AddressId {
<&str as sqlx::Encode<'q, sqlx::Postgres>>::encode_by_ref(&&**self, buf)
}
}
impl sqlx::Type<sqlx::Postgres> for AddressId {
impl sqlx::Type<sqlx::Postgres> for ServiceInterfaceId {
fn type_info() -> sqlx::postgres::PgTypeInfo {
<&str as sqlx::Type<sqlx::Postgres>>::type_info()
}

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type BindKind = "static" | "single" | "multi";
export type ActionId = string;

View File

@@ -1,4 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AllowedStatuses } from "./AllowedStatuses";
export type ActionMetadata = { name: string, description: string, warning: string | null, disabled: boolean, input: {[key: string]: any}, allowedStatuses: AllowedStatuses, group: string | null, };
export type ActionMetadata = { name: string, description: string, warning: string | null, input: any, disabled: boolean, allowedStatuses: AllowedStatuses, group: string | null, };

View File

@@ -1,4 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AlpnInfo } from "./AlpnInfo";
export type AddSslOptions = { scheme: string, preferredExternalPort: number, alpn: AlpnInfo, };
export type AddSslOptions = { scheme: string | null, preferredExternalPort: number, alpn: AlpnInfo, };

View File

@@ -1,4 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { BindOptions } from "./BindOptions";
import type { HostId } from "./HostId";
export type AddressInfo = { username: string | null, hostId: string, bindOptions: BindOptions, suffix: string, };
export type AddressInfo = { username: string | null, hostId: HostId, bindOptions: BindOptions, suffix: string, };

View File

@@ -1,4 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AddSslOptions } from "./AddSslOptions";
import type { Security } from "./Security";
export type BindOptions = { scheme: string, preferredExternalPort: number, addSsl: AddSslOptions | null, secure: boolean, ssl: boolean, };
export type BindOptions = { scheme: string | null, preferredExternalPort: number, addSsl: AddSslOptions | null, secure: Security | null, };

View File

@@ -1,6 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AddSslOptions } from "./AddSslOptions";
import type { BindKind } from "./BindKind";
import type { BindOptionsSecure } from "./BindOptionsSecure";
import type { HostId } from "./HostId";
import type { HostKind } from "./HostKind";
import type { Security } from "./Security";
export type BindParams = { kind: BindKind, id: string, internalPort: number, scheme: string, preferredExternalPort: number, addSsl: AddSslOptions | null, secure: BindOptionsSecure | null, };
export type BindParams = { kind: HostKind, id: HostId, internalPort: number, scheme: string | null, preferredExternalPort: number, addSsl: AddSslOptions | null, secure: Security | null, };

View File

@@ -1,4 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { DataUrl } from "./DataUrl";
export type CurrentDependencyInfo = { title: string, icon: DataUrl, registry: string, versionSpec: string, } & ({ "kind": "exists" } | { "kind": "running", healthChecks: string[], });
export type CurrentDependencyInfo = { title: string, icon: DataUrl, registryUrl: string, versionSpec: string, } & ({ "kind": "exists" } | { "kind": "running", healthChecks: string[], });

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type DependencyRequirement = { "kind": "running", id: string, healthChecks: string[], versionSpec: string, registry: string, } | { "kind": "exists", id: string, versionSpec: string, registry: string, };
export type DependencyRequirement = { "kind": "running", id: string, healthChecks: string[], versionSpec: string, registryUrl: string, } | { "kind": "exists", id: string, versionSpec: string, registryUrl: string, };

View File

@@ -0,0 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ExportedHostnameInfo } from "./ExportedHostnameInfo";
import type { HostId } from "./HostId";
import type { HostKind } from "./HostKind";
export type ExportedHostInfo = { id: HostId, kind: HostKind, hostnames: Array<ExportedHostnameInfo>, };

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ExportedIpHostname } from "./ExportedIpHostname";
import type { ExportedOnionHostname } from "./ExportedOnionHostname";
export type ExportedHostnameInfo = { "kind": "ip", networkInterfaceId: string, public: boolean, hostname: ExportedIpHostname, } | { "kind": "onion", hostname: ExportedOnionHostname, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ExportedIpHostname = { "kind": "ipv4", value: string, port: number | null, sslPort: number | null, } | { "kind": "ipv6", value: string, port: number | null, sslPort: number | null, } | { "kind": "local", value: string, port: number | null, sslPort: number | null, } | { "kind": "domain", domain: string, subdomain: string | null, port: number | null, sslPort: number | null, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ExportedOnionHostname = { value: string, port: number | null, sslPort: number | null, };

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type HealthCheckResult = { "result": "success" } | { "result": "disabled" } | { "result": "starting" } | { "result": "loading", message: string, } | { "result": "failure", error: string, };
export type HealthCheckResult = { name: string, } & ({ "result": "success", message: string, } | { "result": "disabled" } | { "result": "starting" } | { "result": "loading", message: string, } | { "result": "failure", message: string, });

View File

@@ -1,8 +1,12 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ActionId } from "./ActionId";
import type { ActionMetadata } from "./ActionMetadata";
import type { CurrentDependencies } from "./CurrentDependencies";
import type { DataUrl } from "./DataUrl";
import type { HostInfo } from "./HostInfo";
import type { PackageState } from "./PackageState";
import type { ServiceInterfaceId } from "./ServiceInterfaceId";
import type { ServiceInterfaceWithHostInfo } from "./ServiceInterfaceWithHostInfo";
import type { Status } from "./Status";
export type PackageDataEntry = { stateInfo: PackageState, status: Status, marketplaceUrl: string | null, developerKey: string, icon: DataUrl, lastBackup: string | null, currentDependencies: CurrentDependencies, hosts: HostInfo, storeExposedDependents: string[], };
export type PackageDataEntry = { stateInfo: PackageState, status: Status, marketplaceUrl: string | null, developerKey: string, icon: DataUrl, lastBackup: string | null, currentDependencies: CurrentDependencies, actions: { [key: ActionId]: ActionMetadata }, serviceInterfaces: { [key: ServiceInterfaceId]: ServiceInterfaceWithHostInfo }, hosts: HostInfo, storeExposedDependents: string[], };

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Progress = boolean | { done: bigint, total: bigint | null, };
export type Progress = boolean | { done: number, total: number | null, };

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ConnectionAddresses = { tor: Array<string>, clearnet: Array<string>, };
export type Security = { ssl: boolean, };

View File

@@ -1,5 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ConnectionAddresses } from "./ConnectionAddresses";
import type { Governor } from "./Governor";
import type { IpInfo } from "./IpInfo";
import type { ServerStatus } from "./ServerStatus";
@@ -13,4 +12,4 @@ lastWifiRegion: string | null, eosVersionCompat: string, lanAddress: string, oni
/**
* for backwards compatibility
*/
torAddress: string, ipInfo: { [key: string]: IpInfo }, statusInfo: ServerStatus, wifi: WifiInfo, unreadNotificationCount: bigint, connectionAddresses: ConnectionAddresses, passwordHash: string, pubkey: string, caFingerprint: string, ntpSynced: boolean, zram: boolean, governor: Governor | null, };
torAddress: string, ipInfo: { [key: string]: IpInfo }, statusInfo: ServerStatus, wifi: WifiInfo, unreadNotificationCount: number, passwordHash: string, pubkey: string, caFingerprint: string, ntpSynced: boolean, zram: boolean, governor: Governor | null, };

View File

@@ -0,0 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AddressInfo } from "./AddressInfo";
import type { ServiceInterfaceId } from "./ServiceInterfaceId";
import type { ServiceInterfaceType } from "./ServiceInterfaceType";
export type ServiceInterface = { id: ServiceInterfaceId, name: string, description: string, hasPrimary: boolean, disabled: boolean, masked: boolean, addressInfo: AddressInfo, type: ServiceInterfaceType, };

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type HealthCheckString = "passing" | "disabled" | "starting" | "warning" | "failure";
export type ServiceInterfaceId = string;

View File

@@ -0,0 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AddressInfo } from "./AddressInfo";
import type { ExportedHostInfo } from "./ExportedHostInfo";
import type { ServiceInterfaceId } from "./ServiceInterfaceId";
import type { ServiceInterfaceType } from "./ServiceInterfaceType";
export type ServiceInterfaceWithHostInfo = { hostInfo: ExportedHostInfo, id: ServiceInterfaceId, name: string, description: string, hasPrimary: boolean, disabled: boolean, masked: boolean, addressInfo: AddressInfo, type: ServiceInterfaceType, };

View File

@@ -1,4 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { HealthCheckString } from "./HealthCheckString";
import type { HealthCheckId } from "./HealthCheckId";
export type SetHealth = { name: string, status: HealthCheckString, message: string | null, };
export type SetHealth = { id: HealthCheckId, name: string, } & ({ "result": "success", message: string, } | { "result": "disabled" } | { "result": "starting" } | { "result": "loading", message: string, } | { "result": "failure", message: string, });

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type UpdateProgress = { size: bigint | null, downloaded: bigint, };
export type UpdateProgress = { size: number | null, downloaded: number, };

View File

@@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use chrono::{DateTime, Utc};
use emver::VersionRange;
use imbl_value::InternedString;
use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId};
use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId, ServiceInterfaceId};
use patch_db::json_ptr::JsonPointer;
use patch_db::HasModel;
use reqwest::Url;
@@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::net::host::HostInfo;
use crate::net::service_interface::ServiceInterfaceWithHostInfo;
use crate::prelude::*;
use crate::progress::FullProgress;
use crate::s9pk::manifest::Manifest;
@@ -306,14 +307,14 @@ pub enum AllowedStatuses {
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
pub struct ActionMetadata {
name: String,
description: String,
warning: Option<String>,
pub name: String,
pub description: String,
pub warning: Option<String>,
#[ts(type = "any")]
input: Value,
disabled: bool,
allowedStatuses: AllowedStatuses,
group: Option<String>,
pub input: Value,
pub disabled: bool,
pub allowed_statuses: AllowedStatuses,
pub group: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
@@ -331,10 +332,11 @@ pub struct PackageDataEntry {
#[ts(type = "string | null")]
pub last_backup: Option<DateTime<Utc>>,
pub current_dependencies: CurrentDependencies,
pub actions: BTreeMap<ActionId, ActionMetadata>,
pub service_interfaces: BTreeMap<ServiceInterfaceId, ServiceInterfaceWithHostInfo>,
pub hosts: HostInfo,
#[ts(type = "string[]")]
pub store_exposed_dependents: Vec<JsonPointer>,
pub exposed_actions: BTreeMap<ActionId, ActionMetadata>,
}
impl AsRef<PackageDataEntry> for PackageDataEntry {
fn as_ref(&self) -> &PackageDataEntry {
@@ -375,7 +377,7 @@ pub struct CurrentDependencyInfo {
pub title: String,
pub icon: DataUrl<'static>,
#[ts(type = "string")]
pub registry: Url,
pub registry_url: Url,
#[ts(type = "string")]
pub version_spec: VersionRange,
}

View File

@@ -66,10 +66,6 @@ impl Public {
selected: None,
},
unread_notification_count: 0,
connection_addresses: ConnectionAddresses {
tor: Vec::new(),
clearnet: Vec::new(),
},
password_hash: account.password.clone(),
pubkey: ssh_key::PublicKey::from(&account.ssh_key)
.to_openssh()
@@ -136,8 +132,8 @@ pub struct ServerInfo {
#[serde(default)]
pub status_info: ServerStatus,
pub wifi: WifiInfo,
#[ts(type = "number")]
pub unread_notification_count: u64,
pub connection_addresses: ConnectionAddresses,
pub password_hash: String,
pub pubkey: String,
pub ca_fingerprint: String,
@@ -199,7 +195,9 @@ pub struct ServerStatus {
#[model = "Model<Self>"]
#[ts(export)]
pub struct UpdateProgress {
#[ts(type = "number | null")]
pub size: Option<u64>,
#[ts(type = "number")]
pub downloaded: u64,
}
@@ -221,11 +219,3 @@ pub struct ServerSpecs {
pub disk: String,
pub memory: String,
}
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ConnectionAddresses {
pub tor: Vec<String>,
pub clearnet: Vec<String>,
}

View File

@@ -16,7 +16,7 @@ pub struct BindInfo {
impl BindInfo {
pub fn new(available_ports: &mut AvailablePorts, options: BindOptions) -> Result<Self, Error> {
let mut assigned_lan_port = None;
if options.add_ssl.is_some() || options.secure {
if options.add_ssl.is_some() || options.secure.is_some() {
assigned_lan_port = Some(available_ports.alloc()?);
}
Ok(Self {
@@ -33,7 +33,7 @@ impl BindInfo {
mut assigned_lan_port,
..
} = self;
if options.add_ssl.is_some() || options.secure {
if options.add_ssl.is_some() || options.secure.is_some() {
assigned_lan_port = if let Some(port) = assigned_lan_port.take() {
Some(port)
} else {
@@ -51,24 +51,30 @@ impl BindInfo {
}
}
#[derive(Debug, Deserialize, Serialize, TS)]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Security {
pub ssl: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct BindOptions {
#[ts(type = "string")]
pub scheme: InternedString,
#[ts(type = "string | null")]
pub scheme: Option<InternedString>,
pub preferred_external_port: u16,
pub add_ssl: Option<AddSslOptions>,
pub secure: bool,
pub ssl: bool,
pub secure: Option<Security>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddSslOptions {
#[ts(type = "string")]
pub scheme: InternedString,
#[ts(type = "string | null")]
pub scheme: Option<InternedString>,
pub preferred_external_port: u16,
// #[serde(default)]
// pub add_x_forwarded_headers: bool, // TODO

View File

@@ -39,7 +39,7 @@ impl Host {
}
}
#[derive(Debug, Deserialize, Serialize, TS)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum HostKind {

View File

@@ -7,6 +7,7 @@ pub mod host;
pub mod keys;
pub mod mdns;
pub mod net_controller;
pub mod service_interface;
pub mod ssl;
pub mod static_server;
pub mod tor;

View File

@@ -247,7 +247,7 @@ impl NetService {
None,
external,
(self.ip, *port).into(),
if bind.options.ssl {
if bind.options.secure.as_ref().map_or(false, |s| s.ssl) {
Ok(())
} else {
Err(ssl.alpn.clone())

View File

@@ -0,0 +1,115 @@
use std::net::{Ipv4Addr, Ipv6Addr};
use models::{HostId, ServiceInterfaceId};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::net::host::binding::BindOptions;
use crate::net::host::HostKind;
use crate::prelude::*;
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ServiceInterfaceWithHostInfo {
#[serde(flatten)]
pub service_interface: ServiceInterface,
pub host_info: ExportedHostInfo,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ExportedHostInfo {
pub id: HostId,
pub kind: HostKind,
pub hostnames: Vec<ExportedHostnameInfo>,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")]
#[serde(tag = "kind")]
pub enum ExportedHostnameInfo {
Ip {
network_interface_id: String,
public: bool,
hostname: ExportedIpHostname,
},
Onion {
hostname: ExportedOnionHostname,
},
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ExportedOnionHostname {
pub value: String,
pub port: Option<u16>,
pub ssl_port: Option<u16>,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")]
#[serde(tag = "kind")]
pub enum ExportedIpHostname {
Ipv4 {
value: Ipv4Addr,
port: Option<u16>,
ssl_port: Option<u16>,
},
Ipv6 {
value: Ipv6Addr,
port: Option<u16>,
ssl_port: Option<u16>,
},
Local {
value: String,
port: Option<u16>,
ssl_port: Option<u16>,
},
Domain {
domain: String,
subdomain: Option<String>,
port: Option<u16>,
ssl_port: Option<u16>,
},
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ServiceInterface {
pub id: ServiceInterfaceId,
pub name: String,
pub description: String,
pub has_primary: bool,
pub disabled: bool,
pub masked: bool,
pub address_info: AddressInfo,
#[serde(rename = "type")]
pub interface_type: ServiceInterfaceType,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum ServiceInterfaceType {
Ui,
P2p,
Api,
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct AddressInfo {
pub username: Option<String>,
pub host_id: HostId,
pub bind_options: BindOptions,
pub suffix: String,
}

View File

@@ -24,7 +24,12 @@ lazy_static::lazy_static! {
#[serde(untagged)]
pub enum Progress {
Complete(bool),
Progress { done: u64, total: Option<u64> },
Progress {
#[ts(type = "number")]
done: u64,
#[ts(type = "number | null")]
total: Option<u64>,
},
}
impl Progress {
pub fn new() -> Self {

View File

@@ -11,7 +11,7 @@ use clap::Parser;
use emver::VersionRange;
use imbl::OrdMap;
use imbl_value::{json, InternedString};
use models::{ActionId, HealthCheckId, ImageId, PackageId, VolumeId};
use models::{ActionId, HealthCheckId, HostId, ImageId, PackageId, VolumeId};
use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{from_fn, from_fn_async, AnyContext, Context, Empty, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
@@ -25,11 +25,13 @@ use crate::db::model::package::{
use crate::disk::mount::filesystem::idmapped::IdMapped;
use crate::disk::mount::filesystem::loop_dev::LoopDev;
use crate::disk::mount::filesystem::overlayfs::OverlayGuard;
use crate::net::host::binding::BindOptions;
use crate::net::host::HostKind;
use crate::prelude::*;
use crate::s9pk::rpc::SKIP_ENV;
use crate::service::cli::ContainerCliContext;
use crate::service::ServiceActorSeed;
use crate::status::health_check::{HealthCheckResult, HealthCheckString};
use crate::status::health_check::HealthCheckResult;
use crate::status::MainStatus;
use crate::util::clap::FromStrParser;
use crate::util::{new_guid, Invoke};
@@ -185,21 +187,7 @@ struct GetServicePortForwardParams {
package_id: Option<PackageId>,
internal_port: u32,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
struct BindOptionsSecure {
ssl: bool,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
struct BindOptions {
scheme: Option<String>,
preferred_external_port: u32,
add_ssl: Option<AddSslOptions>,
secure: Option<BindOptionsSecure>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
@@ -379,7 +367,7 @@ async fn export_action(context: EffectContext, data: ExportActionParams) -> Resu
.as_package_data_mut()
.as_idx_mut(&package_id)
.or_not_found(&package_id)?
.as_exposed_actions_mut();
.as_actions_mut();
let mut value = model.de()?;
value
.insert(data.id, data.metadata)
@@ -402,7 +390,7 @@ async fn remove_action(context: EffectContext, data: RemoveActionParams) -> Resu
.as_package_data_mut()
.as_idx_mut(&package_id)
.or_not_found(&package_id)?
.as_exposed_actions_mut();
.as_actions_mut();
let mut value = model.de()?;
value.remove(&data.id).map(|_| ()).unwrap_or_default();
model.ser(&value)
@@ -447,35 +435,16 @@ async fn get_host_info(
async fn clear_bindings(context: EffectContext, _: Empty) -> Result<Value, Error> {
todo!()
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
enum BindKind {
Static,
Single,
Multi,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct AddSslOptions {
scheme: Option<String>,
preferred_external_port: u32,
add_x_forwarded_headers: Option<bool>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct BindParams {
kind: BindKind,
id: String,
internal_port: u32,
scheme: String,
preferred_external_port: u32,
add_ssl: Option<AddSslOptions>,
secure: Option<BindOptionsSecure>,
kind: HostKind,
id: HostId,
internal_port: u16,
#[serde(flatten)]
options: BindOptions,
}
async fn bind(_: AnyContext, BindParams { .. }: BindParams) -> Result<Value, Error> {
todo!()
@@ -918,19 +887,14 @@ async fn set_main_status(context: EffectContext, params: SetMainStatus) -> Resul
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct SetHealth {
#[ts(type = "string")]
name: HealthCheckId,
status: HealthCheckString,
message: Option<String>,
id: HealthCheckId,
#[serde(flatten)]
result: HealthCheckResult,
}
async fn set_health(
context: EffectContext,
SetHealth {
name,
status,
message,
}: SetHealth,
SetHealth { id, result }: SetHealth,
) -> Result<Value, Error> {
let context = context.deref()?;
@@ -939,43 +903,22 @@ async fn set_health(
.ctx
.db
.mutate(move |db| {
let mut main = db
.as_public()
.as_package_data()
.as_idx(package_id)
.or_not_found(package_id)?
.as_status()
.as_main()
.de()?;
match &mut main {
&mut MainStatus::Running { ref mut health, .. }
| &mut MainStatus::BackingUp { ref mut health, .. } => {
health.remove(&name);
health.insert(
name,
match status {
HealthCheckString::Disabled => HealthCheckResult::Disabled,
HealthCheckString::Passing => HealthCheckResult::Success,
HealthCheckString::Starting => HealthCheckResult::Starting,
HealthCheckString::Warning => HealthCheckResult::Loading {
message: message.unwrap_or_default(),
},
HealthCheckString::Failure => HealthCheckResult::Failure {
error: message.unwrap_or_default(),
},
},
);
}
_ => return Ok(()),
};
db.as_public_mut()
.as_package_data_mut()
.as_idx_mut(package_id)
.or_not_found(package_id)?
.as_status_mut()
.as_main_mut()
.ser(&main)
.mutate(|main| {
match main {
&mut MainStatus::Running { ref mut health, .. }
| &mut MainStatus::BackingUp { ref mut health, .. } => {
health.insert(id, result);
}
_ => (),
}
Ok(())
})
})
.await?;
Ok(json!(()))
@@ -1100,7 +1043,7 @@ enum DependencyRequirement {
#[ts(type = "string")]
version_spec: VersionRange,
#[ts(type = "string")]
registry: Url,
registry_url: Url,
},
#[serde(rename_all = "camelCase")]
Exists {
@@ -1109,7 +1052,7 @@ enum DependencyRequirement {
#[ts(type = "string")]
version_spec: VersionRange,
#[ts(type = "string")]
registry: Url,
registry_url: Url,
},
}
// filebrowser:exists,bitcoind:running:foo+bar+baz
@@ -1119,7 +1062,7 @@ impl FromStr for DependencyRequirement {
match s.split_once(':') {
Some((id, "e")) | Some((id, "exists")) => Ok(Self::Exists {
id: id.parse()?,
registry: "".parse()?, // TODO
registry_url: "".parse()?, // TODO
version_spec: "*".parse()?, // TODO
}),
Some((id, rest)) => {
@@ -1143,14 +1086,14 @@ impl FromStr for DependencyRequirement {
Ok(Self::Running {
id: id.parse()?,
health_checks,
registry: "".parse()?, // TODO
registry_url: "".parse()?, // TODO
version_spec: "*".parse()?, // TODO
})
}
None => Ok(Self::Running {
id: s.parse()?,
health_checks: BTreeSet::new(),
registry: "".parse()?, // TODO
registry_url: "".parse()?, // TODO
version_spec: "*".parse()?, // TODO
}),
}
@@ -1186,13 +1129,13 @@ async fn set_dependencies(
.map(|dependency| match dependency {
DependencyRequirement::Exists {
id,
registry,
registry_url,
version_spec,
} => (
id,
CurrentDependencyInfo {
kind: CurrentDependencyKind::Exists,
registry,
registry_url,
version_spec,
icon: todo!(),
title: todo!(),
@@ -1201,13 +1144,13 @@ async fn set_dependencies(
DependencyRequirement::Running {
id,
health_checks,
registry,
registry_url,
version_spec,
} => (
id,
CurrentDependencyInfo {
kind: CurrentDependencyKind::Running { health_checks },
registry,
registry_url,
version_spec,
icon: todo!(),
title: todo!(),

View File

@@ -172,6 +172,8 @@ impl ServiceMap {
icon,
last_backup: None,
current_dependencies: Default::default(),
actions: Default::default(),
service_interfaces: Default::default(),
hosts: Default::default(),
store_exposed_dependents: Default::default(),
},

View File

@@ -2,35 +2,35 @@ pub use models::HealthCheckId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
pub struct HealthCheckResult {
pub name: String,
#[serde(flatten)]
pub kind: HealthCheckResultKind,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "result")]
pub enum HealthCheckResult {
Success,
pub enum HealthCheckResultKind {
Success { message: String },
Disabled,
Starting,
Loading { message: String },
Failure { error: String },
Failure { message: String },
}
impl std::fmt::Display for HealthCheckResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
HealthCheckResult::Success => write!(f, "Succeeded"),
HealthCheckResult::Disabled => write!(f, "Disabled"),
HealthCheckResult::Starting => write!(f, "Starting"),
HealthCheckResult::Loading { message } => write!(f, "Loading ({})", message),
HealthCheckResult::Failure { error } => write!(f, "Failed ({})", error),
let name = &self.name;
match &self.kind {
HealthCheckResultKind::Success { message } => {
write!(f, "{name}: Succeeded ({message})")
}
HealthCheckResultKind::Disabled => write!(f, "{name}: Disabled"),
HealthCheckResultKind::Starting => write!(f, "{name}: Starting"),
HealthCheckResultKind::Loading { message } => write!(f, "{name}: Loading ({message})"),
HealthCheckResultKind::Failure { message } => write!(f, "{name}: Failed ({message})"),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum HealthCheckString {
Passing,
Disabled,
Starting,
Warning,
Failure,
}