Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major

This commit is contained in:
Matt Hill
2024-04-01 15:19:33 -06:00
62 changed files with 973 additions and 736 deletions

View File

@@ -182,6 +182,7 @@ container-runtime/node_modules: container-runtime/package.json container-runtime
core/startos/bindings: $(shell git ls-files -- core ':!:core/startos/bindings/*') $(ENVIRONMENT_FILE) core/startos/bindings: $(shell git ls-files -- core ':!:core/startos/bindings/*') $(ENVIRONMENT_FILE)
rm -rf core/startos/bindings rm -rf core/startos/bindings
(cd core/ && cargo test --features=test) (cd core/ && cargo test --features=test)
ls core/startos/bindings/*.ts | sed 's/core\/startos\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' > core/startos/bindings/index.ts
npm --prefix sdk exec -- prettier -w ./core/startos/bindings/*.ts npm --prefix sdk exec -- prettier -w ./core/startos/bindings/*.ts
sdk/dist: $(shell git ls-files sdk) core/startos/bindings sdk/dist: $(shell git ls-files sdk) core/startos/bindings

View File

@@ -41,6 +41,7 @@ qemu-guest-agent
rsync rsync
samba-common-bin samba-common-bin
smartmontools smartmontools
socat
sqlite3 sqlite3
squashfs-tools squashfs-tools
sudo sudo

View File

@@ -7,7 +7,7 @@
"semver-prefix": "PureBoot-Release-", "semver-prefix": "PureBoot-Release-",
"semver-range": "<29" "semver-range": "<29"
}, },
"url": "https://source.puri.sm/firmware/releases/-/raw/master/librem_mini_v2/custom/pureboot-librem_mini_v2-basic_usb_autoboot_blob_jail-Release-29.rom.gz", "url": "https://source.puri.sm/firmware/releases/-/raw/75631ad6dcf7e6ee73e06a517ac7dc4e017518b7/librem_mini_v2/custom/pureboot-librem_mini_v2-basic_usb_autoboot_blob_jail-Release-29.rom.gz",
"shasum": "96ec04f21b1cfe8e28d9a2418f1ff533efe21f9bbbbf16e162f7c814761b068b" "shasum": "96ec04f21b1cfe8e28d9a2418f1ff533efe21f9bbbbf16e162f7c814761b068b"
} }
] ]

1226
core/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ sqlx = { version = "0.7.2", features = [
"postgres", "postgres",
] } ] }
ssh-key = "0.6.2" ssh-key = "0.6.2"
ts-rs = { git = "https://github.com/dr-bonez/ts-rs.git", branch = "feature/top-level-type-override" } # "8" ts-rs = { git = "https://github.com/dr-bonez/ts-rs.git", branch = "feature/top-level-as" } # "8"
thiserror = "1.0" thiserror = "1.0"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
torut = { git = "https://github.com/Start9Labs/torut.git", branch = "update/dependencies" } torut = { git = "https://github.com/Start9Labs/torut.git", branch = "update/dependencies" }

View File

@@ -14,7 +14,7 @@ keywords = [
name = "start-os" name = "start-os"
readme = "README.md" readme = "README.md"
repository = "https://github.com/Start9Labs/start-os" repository = "https://github.com/Start9Labs/start-os"
version = "0.3.5-rev.1" version = "0.3.5-rev.2"
license = "MIT" license = "MIT"
[lib] [lib]
@@ -176,7 +176,7 @@ tracing-futures = "0.2.5"
tracing-journald = "0.3.0" tracing-journald = "0.3.0"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
trust-dns-server = "0.23.1" trust-dns-server = "0.23.1"
ts-rs = { git = "https://github.com/dr-bonez/ts-rs.git", branch = "feature/top-level-type-override" } # "8.1.0" ts-rs = { git = "https://github.com/dr-bonez/ts-rs.git", branch = "feature/top-level-as" } # "8.1.0"
typed-builder = "0.18.0" typed-builder = "0.18.0"
url = { version = "2.4.1", features = ["serde"] } url = { version = "2.4.1", features = ["serde"] }
urlencoding = "2.1.3" urlencoding = "2.1.3"

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 EncryptedWire = { encrypted: any };

View File

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

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 Session = { loggedIn: string; lastActive: string; metadata: any };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Sessions } from "./Sessions";
export type SessionList = { current: string; sessions: Sessions };

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.
export type Sessions = {
[key: string]: { loggedIn: string; lastActive: string; metadata: any };
};

View File

@@ -0,0 +1,102 @@
export { ActionId } from "./ActionId";
export { ActionMetadata } from "./ActionMetadata";
export { AddressInfo } from "./AddressInfo";
export { AddSslOptions } from "./AddSslOptions";
export { Alerts } from "./Alerts";
export { Algorithm } from "./Algorithm";
export { AllowedStatuses } from "./AllowedStatuses";
export { AllPackageData } from "./AllPackageData";
export { AlpnInfo } from "./AlpnInfo";
export { BackupProgress } from "./BackupProgress";
export { BindInfo } from "./BindInfo";
export { BindOptions } from "./BindOptions";
export { BindParams } from "./BindParams";
export { Callback } from "./Callback";
export { ChrootParams } from "./ChrootParams";
export { CreateOverlayedImageParams } from "./CreateOverlayedImageParams";
export { CurrentDependencies } from "./CurrentDependencies";
export { CurrentDependencyInfo } from "./CurrentDependencyInfo";
export { DataUrl } from "./DataUrl";
export { Dependencies } from "./Dependencies";
export { DependencyConfigErrors } from "./DependencyConfigErrors";
export { DependencyKind } from "./DependencyKind";
export { DependencyRequirement } from "./DependencyRequirement";
export { DepInfo } from "./DepInfo";
export { Description } from "./Description";
export { DestroyOverlayedImageParams } from "./DestroyOverlayedImageParams";
export { Duration } from "./Duration";
export { EncryptedWire } from "./EncryptedWire";
export { ExecuteAction } from "./ExecuteAction";
export { ExportActionParams } from "./ExportActionParams";
export { ExportedHostInfo } from "./ExportedHostInfo";
export { ExportedHostnameInfo } from "./ExportedHostnameInfo";
export { ExportedIpHostname } from "./ExportedIpHostname";
export { ExportedOnionHostname } from "./ExportedOnionHostname";
export { ExportServiceInterfaceParams } from "./ExportServiceInterfaceParams";
export { ExposeForDependentsParams } from "./ExposeForDependentsParams";
export { FullProgress } from "./FullProgress";
export { GetHostInfoParamsKind } from "./GetHostInfoParamsKind";
export { GetHostInfoParams } from "./GetHostInfoParams";
export { GetPrimaryUrlParams } from "./GetPrimaryUrlParams";
export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams";
export { GetServicePortForwardParams } from "./GetServicePortForwardParams";
export { GetSslCertificateParams } from "./GetSslCertificateParams";
export { GetSslKeyParams } from "./GetSslKeyParams";
export { GetStoreParams } from "./GetStoreParams";
export { GetSystemSmtpParams } from "./GetSystemSmtpParams";
export { Governor } from "./Governor";
export { HardwareRequirements } from "./HardwareRequirements";
export { HealthCheckId } from "./HealthCheckId";
export { HealthCheckResult } from "./HealthCheckResult";
export { HostAddress } from "./HostAddress";
export { HostId } from "./HostId";
export { HostInfo } from "./HostInfo";
export { HostKind } from "./HostKind";
export { Host } from "./Host";
export { ImageId } from "./ImageId";
export { InstalledState } from "./InstalledState";
export { InstallingInfo } from "./InstallingInfo";
export { InstallingState } from "./InstallingState";
export { IpInfo } from "./IpInfo";
export { ListServiceInterfacesParams } from "./ListServiceInterfacesParams";
export { MainStatus } from "./MainStatus";
export { Manifest } from "./Manifest";
export { MaybeUtf8String } from "./MaybeUtf8String";
export { MountParams } from "./MountParams";
export { MountTarget } from "./MountTarget";
export { NamedProgress } from "./NamedProgress";
export { PackageDataEntry } from "./PackageDataEntry";
export { PackageId } from "./PackageId";
export { PackageState } from "./PackageState";
export { ParamsMaybePackageId } from "./ParamsMaybePackageId";
export { ParamsPackageId } from "./ParamsPackageId";
export { PasswordType } from "./PasswordType";
export { Progress } from "./Progress";
export { Public } from "./Public";
export { RemoveActionParams } from "./RemoveActionParams";
export { RemoveAddressParams } from "./RemoveAddressParams";
export { ReverseProxyBind } from "./ReverseProxyBind";
export { ReverseProxyDestination } from "./ReverseProxyDestination";
export { ReverseProxyHttp } from "./ReverseProxyHttp";
export { ReverseProxyParams } from "./ReverseProxyParams";
export { Security } from "./Security";
export { ServerInfo } from "./ServerInfo";
export { ServerSpecs } from "./ServerSpecs";
export { ServerStatus } from "./ServerStatus";
export { ServiceInterfaceId } from "./ServiceInterfaceId";
export { ServiceInterface } from "./ServiceInterface";
export { ServiceInterfaceType } from "./ServiceInterfaceType";
export { ServiceInterfaceWithHostInfo } from "./ServiceInterfaceWithHostInfo";
export { SessionList } from "./SessionList";
export { Sessions } from "./Sessions";
export { Session } from "./Session";
export { SetConfigured } from "./SetConfigured";
export { SetDependenciesParams } from "./SetDependenciesParams";
export { SetHealth } from "./SetHealth";
export { SetMainStatus } from "./SetMainStatus";
export { SetStoreParams } from "./SetStoreParams";
export { Status } from "./Status";
export { UpdateProgress } from "./UpdateProgress";
export { UpdatingState } from "./UpdatingState";
export { VolumeId } from "./VolumeId";
export { WifiInfo } from "./WifiInfo";

View File

@@ -4,6 +4,7 @@ use models::PackageId;
use rpc_toolkit::command; use rpc_toolkit::command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::config::Config; use crate::config::Config;
use crate::context::RpcContext; use crate::context::RpcContext;
@@ -47,17 +48,16 @@ pub fn display_action_result(params: WithIoFormat<ActionParams>, result: ActionR
} }
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ActionParams { pub struct ActionParams {
#[arg(id = "id")] #[arg(id = "id")]
#[serde(rename = "id")] #[serde(rename = "id")]
pub package_id: PackageId, pub package_id: PackageId,
#[arg(id = "action-id")]
#[serde(rename = "action-id")]
pub action_id: ActionId, pub action_id: ActionId,
#[command(flatten)] #[command(flatten)]
#[ts(type = "{ [key: string]: any } | null")]
pub input: StdinDeserializable<Option<Config>>, pub input: StdinDeserializable<Option<Config>>,
} }
// impl C // impl C

View File

@@ -9,6 +9,7 @@ use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{command, from_fn_async, AnyContext, CallRemote, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, AnyContext, CallRemote, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel; use crate::db::model::DatabaseModel;
@@ -20,7 +21,8 @@ use crate::util::crypto::EncryptedWire;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::{ensure_code, Error, ResultExt}; use crate::{ensure_code, Error, ResultExt};
#[derive(Debug, Clone, Default, Deserialize, Serialize)] #[derive(Debug, Clone, Default, Deserialize, Serialize, TS)]
#[ts(as = "BTreeMap::<String, Session>")]
pub struct Sessions(pub BTreeMap<InternedString, Session>); pub struct Sessions(pub BTreeMap<InternedString, Session>);
impl Sessions { impl Sessions {
pub fn new() -> Self { pub fn new() -> Self {
@@ -38,8 +40,9 @@ impl Map for Sessions {
} }
} }
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize, TS)]
#[serde(untagged)] #[serde(untagged)]
#[ts(export)]
pub enum PasswordType { pub enum PasswordType {
EncryptedWire(EncryptedWire), EncryptedWire(EncryptedWire),
String(String), String(String),
@@ -177,7 +180,7 @@ pub fn check_password_against_db(db: &DatabaseModel, password: &str) -> Result<(
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct LoginParams { pub struct LoginParams {
@@ -185,6 +188,7 @@ pub struct LoginParams {
#[serde(default)] #[serde(default)]
user_agent: Option<String>, user_agent: Option<String>,
#[serde(default)] #[serde(default)]
#[ts(type = "any")]
metadata: Value, metadata: Value,
} }
@@ -218,10 +222,11 @@ pub async fn login_impl(
.await .await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct LogoutParams { pub struct LogoutParams {
#[ts(type = "string")]
session: InternedString, session: InternedString,
} }
@@ -234,18 +239,25 @@ pub async fn logout(
)) ))
} }
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct Session { pub struct Session {
#[ts(type = "string")]
pub logged_in: DateTime<Utc>, pub logged_in: DateTime<Utc>,
#[ts(type = "string")]
pub last_active: DateTime<Utc>, pub last_active: DateTime<Utc>,
#[ts(skip)]
pub user_agent: Option<String>, pub user_agent: Option<String>,
#[ts(type = "any")]
pub metadata: Value, pub metadata: Value,
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SessionList { pub struct SessionList {
#[ts(type = "string")]
current: InternedString, current: InternedString,
sessions: Sessions, sessions: Sessions,
} }
@@ -303,11 +315,12 @@ fn display_sessions(params: WithIoFormat<ListParams>, arg: SessionList) {
table.print_tty(false).unwrap(); table.print_tty(false).unwrap();
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ListParams { pub struct ListParams {
#[arg(skip)] #[arg(skip)]
#[ts(skip)]
session: InternedString, session: InternedString,
} }
@@ -338,7 +351,7 @@ impl AsLogoutSessionId for KillSessionId {
} }
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct KillParams { pub struct KillParams {
@@ -351,7 +364,7 @@ pub async fn kill(ctx: RpcContext, KillParams { ids }: KillParams) -> Result<(),
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ResetPasswordParams { pub struct ResetPasswordParams {

View File

@@ -11,6 +11,7 @@ use models::PackageId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use super::target::BackupTargetId; use super::target::BackupTargetId;
use super::PackageBackupReport; use super::PackageBackupReport;
@@ -29,7 +30,7 @@ use crate::util::io::dir_copy;
use crate::util::serde::IoFormat; use crate::util::serde::IoFormat;
use crate::version::VersionT; use crate::version::VersionT;
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct BackupParams { pub struct BackupParams {

View File

@@ -9,6 +9,7 @@ use patch_db::json_ptr::ROOT;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use torut::onion::OnionAddressV3; use torut::onion::OnionAddressV3;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use super::target::BackupTargetId; use super::target::BackupTargetId;
use crate::backup::os::OsBackup; use crate::backup::os::OsBackup;
@@ -24,7 +25,7 @@ use crate::s9pk::S9pk;
use crate::service::service_map::DownloadInstallFuture; use crate::service::service_map::DownloadInstallFuture;
use crate::util::serde::IoFormat; use crate::util::serde::IoFormat;
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct RestorePackageParams { pub struct RestorePackageParams {

View File

@@ -6,6 +6,7 @@ use color_eyre::eyre::eyre;
use imbl_value::InternedString; use imbl_value::InternedString;
use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ts_rs::TS;
use super::{BackupTarget, BackupTargetId}; use super::{BackupTarget, BackupTargetId};
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
@@ -67,7 +68,7 @@ pub fn cifs() -> ParentHandler {
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct AddParams { pub struct AddParams {
@@ -121,7 +122,7 @@ pub async fn add(
}) })
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UpdateParams { pub struct UpdateParams {
@@ -185,7 +186,7 @@ pub async fn update(
}) })
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct RemoveParams { pub struct RemoveParams {

View File

@@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use self::cifs::CifsBackupTarget; use self::cifs::CifsBackupTarget;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
@@ -46,7 +47,8 @@ pub enum BackupTarget {
Cifs(CifsBackupTarget), Cifs(CifsBackupTarget),
} }
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, TS)]
#[ts(type = "string")]
pub enum BackupTargetId { pub enum BackupTargetId {
Disk { logicalname: PathBuf }, Disk { logicalname: PathBuf },
Cifs { id: u32 }, Cifs { id: u32 },
@@ -107,7 +109,7 @@ impl Serialize for BackupTargetId {
} }
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize, TS)]
#[serde(tag = "type")] #[serde(tag = "type")]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum BackupTargetFS { pub enum BackupTargetFS {
@@ -242,7 +244,7 @@ fn display_backup_info(params: WithIoFormat<InfoParams>, info: BackupInfo) {
table.print_tty(false).unwrap(); table.print_tty(false).unwrap();
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct InfoParams { pub struct InfoParams {
@@ -276,7 +278,7 @@ lazy_static::lazy_static! {
Mutex::new(BTreeMap::new()); Mutex::new(BTreeMap::new());
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct MountParams { pub struct MountParams {
@@ -311,7 +313,7 @@ pub async fn mount(
Ok(res) Ok(res)
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UmountParams { pub struct UmountParams {

View File

@@ -12,6 +12,7 @@ use regex::Regex;
use rpc_toolkit::{from_fn_async, Empty, HandlerExt, ParentHandler}; use rpc_toolkit::{from_fn_async, Empty, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::prelude::*; use crate::prelude::*;
@@ -125,7 +126,7 @@ pub enum MatchError {
ListUniquenessViolation, ListUniquenessViolation,
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ConfigParams { pub struct ConfigParams {
@@ -156,12 +157,13 @@ pub async fn get(ctx: RpcContext, _: Empty, id: PackageId) -> Result<ConfigRes,
.await .await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SetParams { pub struct SetParams {
#[arg(long = "timeout")] #[arg(long = "timeout")]
pub timeout: Option<crate::util::serde::Duration>, pub timeout: Option<crate::util::serde::Duration>,
#[command(flatten)] #[command(flatten)]
#[ts(type = "{ [key: string]: any } | null")]
pub config: StdinDeserializable<Option<Config>>, pub config: StdinDeserializable<Option<Config>>,
} }

View File

@@ -4,12 +4,13 @@ use models::PackageId;
use rpc_toolkit::command; use rpc_toolkit::command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::RpcContext; use crate::context::RpcContext;
use crate::prelude::*; use crate::prelude::*;
use crate::Error; use crate::Error;
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ControlParams { pub struct ControlParams {

View File

@@ -19,6 +19,7 @@ use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::middleware::auth::{HasValidSession, HashSessionToken}; use crate::middleware::auth::{HasValidSession, HashSessionToken};
@@ -215,12 +216,13 @@ async fn cli_dump(
Ok(dump) Ok(dump)
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct DumpParams { pub struct DumpParams {
#[arg(long = "include-private", short = 'p')] #[arg(long = "include-private", short = 'p')]
#[serde(default)] #[serde(default)]
#[ts(skip)]
include_private: bool, include_private: bool,
} }
@@ -271,7 +273,7 @@ async fn cli_apply(
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ApplyParams { pub struct ApplyParams {
@@ -309,11 +311,13 @@ pub fn put() -> ParentHandler {
.with_remote_cli::<CliContext>(), .with_remote_cli::<CliContext>(),
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UiParams { pub struct UiParams {
#[ts(type = "string")]
pointer: JsonPointer, pointer: JsonPointer,
#[ts(type = "any")]
value: Value, value: Value,
} }

View File

@@ -43,7 +43,7 @@ pub struct DepInfo {
pub optional: bool, pub optional: bool,
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ConfigureParams { pub struct ConfigureParams {

View File

@@ -5,6 +5,7 @@ use clap::Parser;
use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{command, from_fn, from_fn_async, AnyContext, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn, from_fn_async, AnyContext, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::{CliContext, DiagnosticContext}; use crate::context::{CliContext, DiagnosticContext};
use crate::init::SYSTEM_REBUILD_PATH; use crate::init::SYSTEM_REBUILD_PATH;
@@ -40,10 +41,11 @@ pub fn error(ctx: DiagnosticContext) -> Result<Arc<RpcError>, Error> {
Ok(ctx.error.clone()) Ok(ctx.error.clone())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct LogsParams { pub struct LogsParams {
#[ts(type = "number | null")]
limit: Option<usize>, limit: Option<usize>,
cursor: Option<String>, cursor: Option<String>,
before: bool, before: bool,

View File

@@ -1,3 +1,4 @@
use std::io::Cursor;
use std::path::Path; use std::path::Path;
use tokio::process::Command; use tokio::process::Command;
@@ -23,8 +24,8 @@ pub async fn btrfs_check_repair(logicalname: impl AsRef<Path>) -> Result<Require
Command::new("btrfs") Command::new("btrfs")
.arg("check") .arg("check")
.arg("--repair") .arg("--repair")
.arg("--force")
.arg(logicalname.as_ref()) .arg(logicalname.as_ref())
.input(Some(&mut Cursor::new(b"y\n")))
.invoke(crate::ErrorKind::DiskManagement) .invoke(crate::ErrorKind::DiskManagement)
.await?; .await?;

View File

@@ -5,12 +5,14 @@ use digest::generic_array::GenericArray;
use digest::{Digest, OutputSizeUser}; use digest::{Digest, OutputSizeUser};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use ts_rs::TS;
use super::FileSystem; use super::FileSystem;
use crate::prelude::*; use crate::prelude::*;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(concrete(LogicalName = std::path::PathBuf))]
pub struct BlockDev<LogicalName: AsRef<Path>> { pub struct BlockDev<LogicalName: AsRef<Path>> {
logicalname: LogicalName, logicalname: LogicalName,
} }

View File

@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use tokio::process::Command; use tokio::process::Command;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use super::{FileSystem, MountType, ReadOnly}; use super::{FileSystem, MountType, ReadOnly};
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard}; use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
@@ -62,7 +63,7 @@ pub async fn mount_cifs(
Ok(()) Ok(())
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Cifs { pub struct Cifs {
pub hostname: String, pub hostname: String,

View File

@@ -23,7 +23,7 @@ pub fn inspect() -> ParentHandler {
.subcommand("docker-images", from_fn_async(docker_images).no_display()) .subcommand("docker-images", from_fn_async(docker_images).no_display())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct HashParams { pub struct HashParams {
@@ -38,7 +38,7 @@ pub async fn hash(_: CliContext, HashParams { path }: HashParams) -> Result<Stri
.to_owned()) .to_owned())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ManifestParams { pub struct ManifestParams {
@@ -56,7 +56,7 @@ pub async fn manifest(
todo!() todo!()
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct InspectParams { pub struct InspectParams {
@@ -88,7 +88,7 @@ pub async fn icon(
.await?; .await?;
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct InstructionParams { pub struct InstructionParams {

View File

@@ -15,6 +15,7 @@ use serde::{Deserialize, Serialize};
use serde_json::{json, Value}; use serde_json::{json, Value};
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation}; use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
@@ -63,7 +64,7 @@ pub async fn list(ctx: RpcContext) -> Result<Value, Error> {
.collect()) .collect())
} }
#[derive(Debug, Clone, Copy, serde::Deserialize, serde::Serialize)] #[derive(Debug, Clone, Copy, serde::Deserialize, serde::Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum MinMax { pub enum MinMax {
Min, Min,
@@ -102,12 +103,13 @@ impl std::fmt::Display for MinMax {
} }
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct InstallParams { pub struct InstallParams {
id: PackageId, id: PackageId,
#[arg(short = 'm', long = "marketplace-url")] #[arg(short = 'm', long = "marketplace-url")]
#[ts(type = "string | null")]
marketplace_url: Option<Url>, marketplace_url: Option<Url>,
#[arg(short = 'v', long = "version-spec")] #[arg(short = 'v', long = "version-spec")]
version_spec: Option<String>, version_spec: Option<String>,
@@ -391,7 +393,7 @@ pub async fn cli_install(ctx: CliContext, params: CliInstallParams) -> Result<()
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UninstallParams { pub struct UninstallParams {

View File

@@ -75,11 +75,12 @@ use rpc_toolkit::{
command, from_fn, from_fn_async, from_fn_blocking, AnyContext, HandlerExt, ParentHandler, command, from_fn, from_fn_async, from_fn_blocking, AnyContext, HandlerExt, ParentHandler,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::CliContext; use crate::context::CliContext;
use crate::util::serde::HandlerExtSerde; use crate::util::serde::HandlerExtSerde;
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct EchoParams { pub struct EchoParams {

View File

@@ -20,6 +20,7 @@ use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::time::Instant; use tokio::time::Instant;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation}; use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
@@ -351,8 +352,9 @@ pub async fn list(ctx: RpcContext) -> Result<Vec<InternedString>, Error> {
Ok(ctx.dev.lxc.lock().await.keys().cloned().collect()) Ok(ctx.dev.lxc.lock().await.keys().cloned().collect())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
pub struct RemoveParams { pub struct RemoveParams {
#[ts(type = "string")]
pub guid: InternedString, pub guid: InternedString,
} }
@@ -363,8 +365,9 @@ pub async fn remove(ctx: RpcContext, RemoveParams { guid }: RemoveParams) -> Res
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
pub struct ConnectParams { pub struct ConnectParams {
#[ts(type = "string")]
pub guid: InternedString, pub guid: InternedString,
} }

View File

@@ -6,6 +6,7 @@ use futures::TryStreamExt;
use rpc_toolkit::{from_fn_async, HandlerExt, ParentHandler}; use rpc_toolkit::{from_fn_async, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::RwLock; use tokio::sync::RwLock;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::db::model::public::IpInfo; use crate::db::model::public::IpInfo;
@@ -60,7 +61,7 @@ pub fn dhcp() -> ParentHandler {
.with_remote_cli::<CliContext>(), .with_remote_cli::<CliContext>(),
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UpdateParams { pub struct UpdateParams {

View File

@@ -22,6 +22,7 @@ use tokio::time::Instant;
use torut::control::{AsyncEvent, AuthenticatedConn, ConnError}; use torut::control::{AsyncEvent, AuthenticatedConn, ConnError};
use torut::onion::{OnionAddressV3, TorSecretKeyV3}; use torut::onion::{OnionAddressV3, TorSecretKeyV3};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::logs::{ use crate::logs::{
@@ -104,7 +105,7 @@ pub fn tor() -> ParentHandler {
.with_remote_cli::<CliContext>(), .with_remote_cli::<CliContext>(),
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ResetParams { pub struct ResetParams {
@@ -142,11 +143,12 @@ pub async fn list_services(ctx: RpcContext, _: Empty) -> Result<Vec<OnionAddress
ctx.net_controller.tor.list_services().await ctx.net_controller.tor.list_services().await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct LogsParams { pub struct LogsParams {
#[arg(short = 'l', long = "limit")] #[arg(short = 'l', long = "limit")]
#[ts(type = "number | null")]
limit: Option<usize>, limit: Option<usize>,
#[arg(short = 'c', long = "cursor")] #[arg(short = 'c', long = "cursor")]
cursor: Option<String>, cursor: Option<String>,

View File

@@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize};
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::prelude::*; use crate::prelude::*;
@@ -87,7 +88,7 @@ pub fn country() -> ParentHandler {
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct AddParams { pub struct AddParams {
@@ -138,7 +139,7 @@ pub async fn add(ctx: RpcContext, AddParams { ssid, password }: AddParams) -> Re
} }
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct SsidParams { pub struct SsidParams {
@@ -402,11 +403,12 @@ pub async fn get_available(ctx: RpcContext, _: Empty) -> Result<Vec<WifiListOut>
Ok(wifi_list) Ok(wifi_list)
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct SetCountryParams { pub struct SetCountryParams {
#[arg(value_parser = CountryCodeParser)] #[arg(value_parser = CountryCodeParser)]
#[ts(type = "string")]
country: CountryCode, country: CountryCode,
} }
pub async fn set_country( pub async fn set_country(

View File

@@ -11,6 +11,7 @@ use models::PackageId;
use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::backup::BackupReport; use crate::backup::BackupReport;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
@@ -48,11 +49,13 @@ pub fn notification() -> ParentHandler {
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ListParams { pub struct ListParams {
#[ts(type = "number | null")]
before: Option<u32>, before: Option<u32>,
#[ts(type = "number | null")]
limit: Option<usize>, limit: Option<usize>,
} }
// #[command(display(display_serializable))] // #[command(display(display_serializable))]
@@ -110,10 +113,11 @@ pub async fn list(
.await .await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct DeleteParams { pub struct DeleteParams {
#[ts(type = "number")]
id: u32, id: u32,
} }
@@ -125,10 +129,11 @@ pub async fn delete(ctx: RpcContext, DeleteParams { id }: DeleteParams) -> Resul
}) })
.await .await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct DeleteBeforeParams { pub struct DeleteBeforeParams {
#[ts(type = "number")]
before: u32, before: u32,
} }
@@ -148,7 +153,7 @@ pub async fn delete_before(
.await .await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct CreateParams { pub struct CreateParams {
@@ -172,7 +177,7 @@ pub async fn create(
.await .await
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum NotificationLevel { pub enum NotificationLevel {
Success, Success,

View File

@@ -6,6 +6,7 @@ use models::Error;
use rpc_toolkit::{command, from_fn_async, AnyContext, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, AnyContext, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::process::Command; use tokio::process::Command;
use ts_rs::TS;
use crate::context::config::ServerConfig; use crate::context::config::ServerConfig;
use crate::context::{CliContext, InstallContext}; use crate::context::{CliContext, InstallContext};
@@ -112,7 +113,7 @@ async fn partition(disk: &mut DiskInfo, overwrite: bool) -> Result<OsPartitionIn
} }
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ExecuteParams { pub struct ExecuteParams {

View File

@@ -9,6 +9,7 @@ use indicatif::{ProgressBar, ProgressStyle};
use reqwest::{header, Body, Client, Url}; use reqwest::{header, Body, Client, Url};
use rpc_toolkit::command; use rpc_toolkit::command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::CliContext; use crate::context::CliContext;
use crate::s9pk::S9pk; use crate::s9pk::S9pk;

View File

@@ -5,6 +5,7 @@ use reqwest::{StatusCode, Url};
use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::version::VersionT; use crate::version::VersionT;
@@ -36,10 +37,11 @@ pub fn with_query_params(ctx: RpcContext, mut url: Url) -> Url {
url url
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct GetParams { pub struct GetParams {
#[ts(type = "string")]
url: Url, url: Url,
} }

View File

@@ -8,6 +8,7 @@ use rpc_toolkit::{from_fn_async, Empty, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::fs::File; use tokio::fs::File;
use tokio::process::Command; use tokio::process::Command;
use ts_rs::TS;
use crate::context::CliContext; use crate::context::CliContext;
use crate::prelude::*; use crate::prelude::*;
@@ -67,7 +68,7 @@ fn inspect() -> ParentHandler<S9pkPath> {
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
struct AddImageParams { struct AddImageParams {
id: ImageId, id: ImageId,
image: String, image: String,
@@ -183,7 +184,7 @@ async fn add_image(
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
struct EditManifestParams { struct EditManifestParams {
expression: String, expression: String,
} }

View File

@@ -2,6 +2,7 @@ use std::path::PathBuf;
use clap::Parser; use clap::Parser;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ts_rs::TS;
pub mod builder; pub mod builder;
pub mod docker; pub mod docker;
@@ -12,7 +13,7 @@ pub mod reader;
pub const SIG_CONTEXT: &[u8] = b"s9pk"; pub const SIG_CONTEXT: &[u8] = b"s9pk";
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct VerifyParams { pub struct VerifyParams {

View File

@@ -11,7 +11,9 @@ use rpc_toolkit::{from_fn_async, CallRemoteHandler, Empty, Handler, HandlerArgs}
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use start_stop::StartStop; use start_stop::StartStop;
use tokio::sync::Notify; use tokio::sync::Notify;
use ts_rs::TS;
use crate::action::ActionResult;
use crate::config::action::ConfigRes; use crate::config::action::ConfigRes;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::core::rpc_continuations::RequestGuid; use crate::core::rpc_continuations::RequestGuid;
@@ -28,8 +30,8 @@ use crate::service::transition::TransitionKind;
use crate::status::health_check::HealthCheckResult; use crate::status::health_check::HealthCheckResult;
use crate::status::MainStatus; use crate::status::MainStatus;
use crate::util::actor::{Actor, BackgroundJobs, SimpleActor}; use crate::util::actor::{Actor, BackgroundJobs, SimpleActor};
use crate::util::serde::Pem;
use crate::volume::data_dir; use crate::volume::data_dir;
use crate::{action::ActionResult, util::serde::Pem};
pub mod cli; pub mod cli;
mod config; mod config;
@@ -498,7 +500,7 @@ impl Actor for ServiceActor {
} }
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
pub struct ConnectParams { pub struct ConnectParams {
pub id: PackageId, pub id: PackageId,
} }

View File

@@ -4,6 +4,7 @@ use imbl_value::Value;
use models::ProcedureName; use models::ProcedureName;
use rpc_toolkit::yajrc::RpcMethod; use rpc_toolkit::yajrc::RpcMethod;
use rpc_toolkit::Empty; use rpc_toolkit::Empty;
use ts_rs::TS;
use crate::prelude::*; use crate::prelude::*;
@@ -43,9 +44,10 @@ impl serde::Serialize for Exit {
} }
} }
#[derive(Clone, serde::Deserialize, serde::Serialize)] #[derive(Clone, serde::Deserialize, serde::Serialize, TS)]
pub struct ExecuteParams { pub struct ExecuteParams {
procedure: String, procedure: String,
#[ts(type = "any")]
input: Value, input: Value,
timeout: Option<u128>, timeout: Option<u128>,
} }

View File

@@ -14,6 +14,7 @@ use tokio::io::AsyncWriteExt;
use tokio::try_join; use tokio::try_join;
use torut::onion::OnionAddressV3; use torut::onion::OnionAddressV3;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::account::AccountInfo; use crate::account::AccountInfo;
use crate::backup::restore::recover_full_embassy; use crate::backup::restore::recover_full_embassy;
@@ -99,10 +100,10 @@ async fn setup_init(
)) ))
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AttachParams { pub struct AttachParams {
#[serde(rename = "embassy-password")] #[serde(rename = "startOsPassword")]
password: Option<EncryptedWire>, password: Option<EncryptedWire>,
guid: Arc<String>, guid: Arc<String>,
} }
@@ -210,7 +211,7 @@ pub fn cifs() -> ParentHandler {
ParentHandler::new().subcommand("verify", from_fn_async(verify_cifs).no_cli()) ParentHandler::new().subcommand("verify", from_fn_async(verify_cifs).no_cli())
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct VerifyCifsParams { pub struct VerifyCifsParams {
hostname: String, hostname: String,
@@ -245,7 +246,7 @@ pub async fn verify_cifs(
start_os.ok_or_else(|| Error::new(eyre!("No Backup Found"), crate::ErrorKind::NotFound)) start_os.ok_or_else(|| Error::new(eyre!("No Backup Found"), crate::ErrorKind::NotFound))
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize, TS)]
#[serde(tag = "type")] #[serde(tag = "type")]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum RecoverySource { pub enum RecoverySource {
@@ -253,7 +254,7 @@ pub enum RecoverySource {
Backup { target: BackupTargetFS }, Backup { target: BackupTargetFS },
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ExecuteParams { pub struct ExecuteParams {
start_os_logicalname: PathBuf, start_os_logicalname: PathBuf,

View File

@@ -8,6 +8,7 @@ use imbl_value::InternedString;
use rpc_toolkit::{command, from_fn_async, AnyContext, Empty, HandlerExt, ParentHandler}; use rpc_toolkit::{command, from_fn_async, AnyContext, Empty, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::prelude::*; use crate::prelude::*;
@@ -34,7 +35,8 @@ impl Map for SshKeys {
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(type = "string")]
pub struct SshPubKey( pub struct SshPubKey(
#[serde(serialize_with = "crate::util::serde::serialize_display")] #[serde(serialize_with = "crate::util::serde::serialize_display")]
#[serde(deserialize_with = "crate::util::serde::deserialize_from_str")] #[serde(deserialize_with = "crate::util::serde::deserialize_from_str")]
@@ -102,7 +104,7 @@ pub fn ssh() -> ParentHandler {
) )
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct AddParams { pub struct AddParams {
@@ -135,10 +137,11 @@ pub async fn add(ctx: RpcContext, AddParams { key }: AddParams) -> Result<SshKey
Ok(res) Ok(res)
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct DeleteParams { pub struct DeleteParams {
#[ts(type = "string")]
fingerprint: InternedString, fingerprint: InternedString,
} }

View File

@@ -12,6 +12,7 @@ use tokio::process::Command;
use tokio::sync::broadcast::Receiver; use tokio::sync::broadcast::Receiver;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext}; use crate::context::{CliContext, RpcContext};
use crate::disk::util::{get_available, get_used}; use crate::disk::util::{get_available, get_used};
@@ -73,7 +74,7 @@ pub async fn enable_zram() -> Result<(), Error> {
Ok(()) Ok(())
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct ZramParams { pub struct ZramParams {
@@ -135,7 +136,7 @@ fn display_governor_info(params: WithIoFormat<GovernorParams>, result: GovernorI
table.print_tty(false).unwrap(); table.print_tty(false).unwrap();
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct GovernorParams { pub struct GovernorParams {
@@ -229,11 +230,12 @@ pub async fn time(ctx: RpcContext, _: Empty) -> Result<TimeInfo, Error> {
uptime: ctx.start_time.elapsed().as_secs(), uptime: ctx.start_time.elapsed().as_secs(),
}) })
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct LogsParams { pub struct LogsParams {
#[arg(short = 'l', long = "limit")] #[arg(short = 'l', long = "limit")]
#[ts(type = "number | null")]
limit: Option<usize>, limit: Option<usize>,
#[arg(short = 'c', long = "cursor")] #[arg(short = 'c', long = "cursor")]
cursor: Option<String>, cursor: Option<String>,
@@ -313,11 +315,12 @@ pub async fn logs_follow(
) -> Result<LogFollowResponse, Error> { ) -> Result<LogFollowResponse, Error> {
follow_logs(ctx, LogSource::System, limit).await follow_logs(ctx, LogSource::System, limit).await
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct KernelLogsParams { pub struct KernelLogsParams {
#[arg(short = 'l', long = "limit")] #[arg(short = 'l', long = "limit")]
#[ts(type = "number | null")]
limit: Option<usize>, limit: Option<usize>,
#[arg(short = 'c', long = "cursor")] #[arg(short = 'c', long = "cursor")]
cursor: Option<String>, cursor: Option<String>,

View File

@@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};
use tokio::process::Command; use tokio::process::Command;
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::context::RpcContext; use crate::context::RpcContext;
use crate::db::model::public::UpdateProgress; use crate::db::model::public::UpdateProgress;
@@ -34,10 +35,11 @@ lazy_static! {
static ref UPDATED: AtomicBool = AtomicBool::new(false); static ref UPDATED: AtomicBool = AtomicBool::new(false);
} }
#[derive(Deserialize, Serialize, Parser)] #[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct UpdateSystemParams { pub struct UpdateSystemParams {
#[ts(type = "string")]
marketplace_url: Url, marketplace_url: Url,
} }

View File

@@ -15,6 +15,9 @@ use josekit::jwk::Jwk;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use tracing::instrument; use tracing::instrument;
use ts_rs::TS;
use crate::prelude::*;
pub fn pbkdf2(password: impl AsRef<[u8]>, salt: impl AsRef<[u8]>) -> CipherKey<Aes256Ctr> { pub fn pbkdf2(password: impl AsRef<[u8]>, salt: impl AsRef<[u8]>) -> CipherKey<Aes256Ctr> {
let mut aeskey = CipherKey::<Aes256Ctr>::default(); let mut aeskey = CipherKey::<Aes256Ctr>::default();
@@ -53,9 +56,11 @@ pub fn decrypt_slice(input: impl AsRef<[u8]>, password: impl AsRef<[u8]>) -> Vec
res res
} }
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct EncryptedWire { pub struct EncryptedWire {
encrypted: serde_json::Value, #[ts(type = "any")]
encrypted: Value,
} }
impl EncryptedWire { impl EncryptedWire {
#[instrument(skip_all)] #[instrument(skip_all)]

View File

@@ -580,7 +580,7 @@ where
} }
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize, TS)]
pub struct StdinDeserializable<T>(pub T); pub struct StdinDeserializable<T>(pub T);
impl<T> FromArgMatches for StdinDeserializable<T> impl<T> FromArgMatches for StdinDeserializable<T>
where where

View File

@@ -10,6 +10,7 @@ use crate::Error;
mod v0_3_5; mod v0_3_5;
mod v0_3_5_1; mod v0_3_5_1;
mod v0_3_5_2;
mod v0_3_6; mod v0_3_6;
pub type Current = v0_3_6::Version; pub type Current = v0_3_6::Version;
@@ -20,6 +21,7 @@ enum Version {
LT0_3_5(LTWrapper<v0_3_5::Version>), LT0_3_5(LTWrapper<v0_3_5::Version>),
V0_3_5(Wrapper<v0_3_5::Version>), V0_3_5(Wrapper<v0_3_5::Version>),
V0_3_5_1(Wrapper<v0_3_5_1::Version>), V0_3_5_1(Wrapper<v0_3_5_1::Version>),
V0_3_5_2(Wrapper<v0_3_5_2::Version>),
V0_3_6(Wrapper<v0_3_6::Version>), V0_3_6(Wrapper<v0_3_6::Version>),
Other(emver::Version), Other(emver::Version),
} }
@@ -39,6 +41,7 @@ impl Version {
Version::LT0_3_5(LTWrapper(_, x)) => x.clone(), Version::LT0_3_5(LTWrapper(_, x)) => x.clone(),
Version::V0_3_5(Wrapper(x)) => x.semver(), Version::V0_3_5(Wrapper(x)) => x.semver(),
Version::V0_3_5_1(Wrapper(x)) => x.semver(), Version::V0_3_5_1(Wrapper(x)) => x.semver(),
Version::V0_3_5_2(Wrapper(x)) => x.semver(),
Version::V0_3_6(Wrapper(x)) => x.semver(), Version::V0_3_6(Wrapper(x)) => x.semver(),
Version::Other(x) => x.clone(), Version::Other(x) => x.clone(),
} }
@@ -208,6 +211,7 @@ pub async fn init(db: &PatchDb) -> Result<(), Error> {
} }
Version::V0_3_5(v) => v.0.migrate_to(&Current::new(), &db).await?, Version::V0_3_5(v) => v.0.migrate_to(&Current::new(), &db).await?,
Version::V0_3_5_1(v) => v.0.migrate_to(&Current::new(), &db).await?, Version::V0_3_5_1(v) => v.0.migrate_to(&Current::new(), &db).await?,
Version::V0_3_5_2(v) => v.0.migrate_to(&Current::new(), &db).await?,
Version::V0_3_6(v) => v.0.migrate_to(&Current::new(), &db).await?, Version::V0_3_6(v) => v.0.migrate_to(&Current::new(), &db).await?,
Version::Other(_) => { Version::Other(_) => {
return Err(Error::new( return Err(Error::new(
@@ -242,6 +246,7 @@ mod tests {
prop_oneof![ prop_oneof![
Just(Version::V0_3_5(Wrapper(v0_3_5::Version::new()))), Just(Version::V0_3_5(Wrapper(v0_3_5::Version::new()))),
Just(Version::V0_3_5_1(Wrapper(v0_3_5_1::Version::new()))), Just(Version::V0_3_5_1(Wrapper(v0_3_5_1::Version::new()))),
Just(Version::V0_3_5_2(Wrapper(v0_3_5_2::Version::new()))),
em_version().prop_map(Version::Other), em_version().prop_map(Version::Other),
] ]
} }

View File

@@ -0,0 +1,29 @@
use emver::VersionRange;
use super::v0_3_5::V0_3_0_COMPAT;
use super::{v0_3_5_1, VersionT};
use crate::prelude::*;
const V0_3_5_2: emver::Version = emver::Version::new(0, 3, 5, 2);
#[derive(Clone, Debug)]
pub struct Version;
impl VersionT for Version {
type Previous = v0_3_5_1::Version;
fn new() -> Self {
Version
}
fn semver(&self) -> emver::Version {
V0_3_5_2
}
fn compat(&self) -> &'static VersionRange {
&V0_3_0_COMPAT
}
async fn up(&self, _db: &PatchDb) -> Result<(), Error> {
Ok(())
}
async fn down(&self, _db: &PatchDb) -> Result<(), Error> {
Ok(())
}
}

View File

@@ -6,6 +6,7 @@ export { setupManifest } from "./manifest/setupManifest"
export { FileHelper } from "./util/fileHelper" export { FileHelper } from "./util/fileHelper"
export { setupExposeStore } from "./store/setupExposeStore" export { setupExposeStore } from "./store/setupExposeStore"
export { pathBuilder } from "./store/PathBuilder" export { pathBuilder } from "./store/PathBuilder"
export * as actions from "./actions" export * as actions from "./actions"
export * as backup from "./backup" export * as backup from "./backup"
export * as config from "./config" export * as config from "./config"

View File

@@ -9,7 +9,7 @@ import { Daemons } from "./mainFn/Daemons"
import { PathBuilder, StorePath } from "./store/PathBuilder" import { PathBuilder, StorePath } from "./store/PathBuilder"
import { ExposedStorePaths } from "./store/setupExposeStore" import { ExposedStorePaths } from "./store/setupExposeStore"
import { UrlString } from "./util/getServiceInterface" import { UrlString } from "./util/getServiceInterface"
export * from "../../core/startos/bindings"
export { SDKManifest } from "./manifest/ManifestTypes" export { SDKManifest } from "./manifest/ManifestTypes"
export type ExportedAction = (options: { export type ExportedAction = (options: {

View File

@@ -1,6 +1,6 @@
{ {
"name": "startos-ui", "name": "startos-ui",
"version": "0.3.5.1", "version": "0.3.5.2",
"author": "Start9 Labs, Inc", "author": "Start9 Labs, Inc",
"homepage": "https://start9.com/", "homepage": "https://start9.com/",
"scripts": { "scripts": {

View File

@@ -1,6 +1,6 @@
{ {
"name": null, "name": null,
"ackWelcome": "0.3.4.4", "ackWelcome": "0.3.6.1",
"marketplace": { "marketplace": {
"selectedUrl": "https://registry.start9.com/", "selectedUrl": "https://registry.start9.com/",
"knownHosts": { "knownHosts": {

View File

@@ -1,5 +1,5 @@
import { Url } from '@start9labs/shared' import { Url } from '@start9labs/shared'
import { Manifest } from '../../../../core/startos/bindings/Manifest' import { T } from '@start9labs/start-sdk'
export type StoreURL = string export type StoreURL = string
export type StoreName = string export type StoreName = string
@@ -27,7 +27,7 @@ export interface MarketplacePkg {
license: Url license: Url
screenshots?: string[] screenshots?: string[]
instructions: Url instructions: Url
manifest: Manifest manifest: T.Manifest
categories: string[] categories: string[]
versions: string[] versions: string[]
dependencyMetadata: { dependencyMetadata: {

View File

@@ -1,12 +1,12 @@
import { Pipe, PipeTransform } from '@angular/core' import { Pipe, PipeTransform } from '@angular/core'
import { Progress } from '../../../../../../../../../../core/startos/bindings/Progress' import { T } from '@start9labs/start-sdk'
@Pipe({ @Pipe({
standalone: true, standalone: true,
name: 'installingProgressString', name: 'installingProgressString',
}) })
export class InstallingProgressDisplayPipe implements PipeTransform { export class InstallingProgressDisplayPipe implements PipeTransform {
transform(progress: Progress): string { transform(progress: T.Progress): string {
if (progress === true) return 'finalizing' if (progress === true) return 'finalizing'
if (progress === false || !progress.total) return 'unknown %' if (progress === false || !progress.total) return 'unknown %'
const percentage = Math.round((100 * progress.done) / progress.total) const percentage = Math.round((100 * progress.done) / progress.total)
@@ -20,7 +20,7 @@ export class InstallingProgressDisplayPipe implements PipeTransform {
name: 'installingProgress', name: 'installingProgress',
}) })
export class InstallingProgressPipe implements PipeTransform { export class InstallingProgressPipe implements PipeTransform {
transform(progress: Progress): number | null { transform(progress: T.Progress): number | null {
if (progress === true) return 1 if (progress === true) return 1
if (progress === false || !progress.total) return null if (progress === false || !progress.total) return null
return Number((progress.done / progress.total).toFixed(2)) return Number((progress.done / progress.total).toFixed(2))

View File

@@ -13,9 +13,7 @@ import { BTC_ICON, LND_ICON, PROXY_ICON } from './api-icons'
import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace' import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace'
import { Log } from '@start9labs/shared' import { Log } from '@start9labs/shared'
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec' import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
import { CT } from '@start9labs/start-sdk' import { CT, T, CB } from '@start9labs/start-sdk'
import { CB } from '@start9labs/start-sdk'
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
export module Mock { export module Mock {
export const ServerUpdated: ServerStatusInfo = { export const ServerUpdated: ServerStatusInfo = {
@@ -26,9 +24,10 @@ export module Mock {
shuttingDown: false, shuttingDown: false,
} }
export const MarketplaceEos: RR.GetMarketplaceEosRes = { export const MarketplaceEos: RR.GetMarketplaceEosRes = {
version: '0.3.5.1', version: '0.3.5.2',
headline: 'Our biggest release ever.', headline: 'Our biggest release ever.',
releaseNotes: { releaseNotes: {
'0.3.5.2': 'Some **Markdown** release _notes_ for 0.3.5.2',
'0.3.5.1': 'Some **Markdown** release _notes_ for 0.3.5.1', '0.3.5.1': 'Some **Markdown** release _notes_ for 0.3.5.1',
'0.3.4.4': 'Some **Markdown** release _notes_ for 0.3.4.4', '0.3.4.4': 'Some **Markdown** release _notes_ for 0.3.4.4',
'0.3.4.3': 'Some **Markdown** release _notes_ for 0.3.4.3', '0.3.4.3': 'Some **Markdown** release _notes_ for 0.3.4.3',
@@ -50,7 +49,7 @@ export module Mock {
'0.19.0': 'release notes for Bitcoin 0.19.0', '0.19.0': 'release notes for Bitcoin 0.19.0',
} }
export const MockManifestBitcoind: Manifest = { export const MockManifestBitcoind: T.Manifest = {
id: 'bitcoind', id: 'bitcoind',
title: 'Bitcoin Core', title: 'Bitcoin Core',
version: '0.21.0', version: '0.21.0',
@@ -88,7 +87,7 @@ export module Mock {
}, },
} }
export const MockManifestLnd: Manifest = { export const MockManifestLnd: T.Manifest = {
id: 'lnd', id: 'lnd',
title: 'Lightning Network Daemon', title: 'Lightning Network Daemon',
version: '0.11.1', version: '0.11.1',
@@ -136,7 +135,7 @@ export module Mock {
}, },
} }
export const MockManifestBitcoinProxy: Manifest = { export const MockManifestBitcoinProxy: T.Manifest = {
id: 'btc-rpc-proxy', id: 'btc-rpc-proxy',
title: 'Bitcoin Proxy', title: 'Bitcoin Proxy',
version: '0.2.2', version: '0.2.2',

View File

@@ -12,10 +12,8 @@ import {
FollowLogsRes, FollowLogsRes,
FollowLogsReq, FollowLogsReq,
} from '@start9labs/shared' } from '@start9labs/shared'
import { CT } from '@start9labs/start-sdk' import { CT, T } from '@start9labs/start-sdk'
import { config } from '@start9labs/start-sdk' import { config } from '@start9labs/start-sdk'
import { HealthCheckResult } from '../../../../../../../core/startos/bindings/HealthCheckResult'
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
export module RR { export module RR {
// DB // DB
@@ -367,7 +365,7 @@ export module RR {
} }
export type SideloadPackageReq = { export type SideloadPackageReq = {
manifest: Manifest manifest: T.Manifest
icon: string // base64 icon: string // base64
size: number // bytes size: number // bytes
} }
@@ -665,7 +663,7 @@ export interface DependencyErrorConfigUnsatisfied {
export interface DependencyErrorHealthChecksFailed { export interface DependencyErrorHealthChecksFailed {
type: 'healthChecksFailed' type: 'healthChecksFailed'
check: HealthCheckResult check: T.HealthCheckResult
} }
export interface DependencyErrorTransitive { export interface DependencyErrorTransitive {

View File

@@ -36,9 +36,9 @@ import { WebSocketSubjectConfig } from 'rxjs/webSocket'
import { AuthService } from '../auth.service' import { AuthService } from '../auth.service'
import { ConnectionService } from '../connection.service' import { ConnectionService } from '../connection.service'
import { StoreInfo } from '@start9labs/marketplace' import { StoreInfo } from '@start9labs/marketplace'
import { FullProgress } from '../../../../../../../core/startos/bindings/FullProgress' import { T } from '@start9labs/start-sdk'
const PROGRESS: FullProgress = { const PROGRESS: T.FullProgress = {
overall: { overall: {
done: 0, done: 0,
total: 120, total: 120,

View File

@@ -3,11 +3,6 @@ import { Inject, Injectable } from '@angular/core'
import { WorkspaceConfig } from '@start9labs/shared' import { WorkspaceConfig } from '@start9labs/shared'
import { T } from '@start9labs/start-sdk' import { T } from '@start9labs/start-sdk'
import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { PackageState } from '../../../../../../core/startos/bindings/PackageState'
import { MainStatus } from '../../../../../../core/startos/bindings/MainStatus'
import { ExportedOnionHostname } from '../../../../../../core/startos/bindings/ExportedOnionHostname'
import { ExportedIpHostname } from '../../../../../../core/startos/bindings/ExportedIpHostname'
import { ExportedHostnameInfo } from '../../../../../../core/startos/bindings/ExportedHostnameInfo'
const { const {
gitHash, gitHash,
@@ -79,8 +74,8 @@ export class ConfigService {
} }
isLaunchable( isLaunchable(
state: PackageState['state'], state: T.PackageState['state'],
status: MainStatus['status'], status: T.MainStatus['status'],
): boolean { ): boolean {
return state === 'installed' && status === 'running' return state === 'installed' && status === 'running'
} }
@@ -98,13 +93,13 @@ export class ConfigService {
if (host.kind === 'multi') { if (host.kind === 'multi') {
const onionHostname = host.hostnames.find(h => h.kind === 'onion') const onionHostname = host.hostnames.find(h => h.kind === 'onion')
?.hostname as ExportedOnionHostname ?.hostname as T.ExportedOnionHostname
if (this.isTor() && onionHostname) { if (this.isTor() && onionHostname) {
url.hostname = onionHostname.value url.hostname = onionHostname.value
} else { } else {
const ipHostname = host.hostnames.find(h => h.kind === 'ip') const ipHostname = host.hostnames.find(h => h.kind === 'ip')
?.hostname as ExportedIpHostname ?.hostname as T.ExportedIpHostname
if (!ipHostname) return '' if (!ipHostname) return ''
@@ -112,13 +107,12 @@ export class ConfigService {
url.port = String(ipHostname.sslPort || ipHostname.port) url.port = String(ipHostname.sslPort || ipHostname.port)
} }
} else { } else {
throw new Error('unimplemented') const hostname = {} as T.ExportedHostnameInfo // host.hostname
const hostname = {} as ExportedHostnameInfo // host.hostname
if (!hostname) return '' if (!hostname) return ''
if (this.isTor() && hostname.kind === 'onion') { if (this.isTor() && hostname.kind === 'onion') {
url.hostname = (hostname.hostname as ExportedOnionHostname).value url.hostname = (hostname.hostname as T.ExportedOnionHostname).value
} else { } else {
url.hostname = this.hostname url.hostname = this.hostname
url.port = String(hostname.hostname.sslPort || hostname.hostname.port) url.port = String(hostname.hostname.sslPort || hostname.hostname.port)

View File

@@ -1,9 +1,6 @@
import { BackupJob, ServerNotifications } from '../api/api.types' import { BackupJob, ServerNotifications } from '../api/api.types'
import { T } from '@start9labs/start-sdk' import { T } from '@start9labs/start-sdk'
import { config } from '@start9labs/start-sdk' import { config } from '@start9labs/start-sdk'
import { PackageDataEntry as PDE } from '../../../../../../../core/startos/bindings/PackageDataEntry'
import { FullProgress } from '../../../../../../../core/startos/bindings/FullProgress'
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
export type DataModel = { export type DataModel = {
ui: UIData ui: UIData
@@ -129,17 +126,18 @@ export interface ServerStatusInfo {
shuttingDown: boolean shuttingDown: boolean
} }
export type PackageDataEntry<T extends StateInfo = StateInfo> = PDE & { export type PackageDataEntry<T extends StateInfo = StateInfo> =
stateInfo: T T.PackageDataEntry & {
installedAt: string stateInfo: T
outboundProxy: string | null installedAt: string
} outboundProxy: string | null
}
export type StateInfo = InstalledState | InstallingState | UpdatingState export type StateInfo = InstalledState | InstallingState | UpdatingState
export type InstalledState = { export type InstalledState = {
state: 'installed' | 'removing' state: 'installed' | 'removing'
manifest: Manifest manifest: T.Manifest
installingInfo?: undefined installingInfo?: undefined
} }
@@ -152,10 +150,10 @@ export type InstallingState = {
export type UpdatingState = { export type UpdatingState = {
state: 'updating' state: 'updating'
installingInfo: InstallingInfo installingInfo: InstallingInfo
manifest: Manifest manifest: T.Manifest
} }
export type InstallingInfo = { export type InstallingInfo = {
progress: FullProgress progress: T.FullProgress
newManifest: Manifest newManifest: T.Manifest
} }

View File

@@ -1,6 +1,5 @@
import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { PkgDependencyErrors } from './dep-error.service' import { PkgDependencyErrors } from './dep-error.service'
import { Status } from '../../../../../../core/startos/bindings/Status'
import { T } from '@start9labs/start-sdk' import { T } from '@start9labs/start-sdk'
export interface PackageStatus { export interface PackageStatus {
@@ -28,7 +27,7 @@ export function renderPkgStatus(
return { primary, dependency, health } return { primary, dependency, health }
} }
function getInstalledPrimaryStatus(status: Status): PrimaryStatus { function getInstalledPrimaryStatus(status: T.Status): PrimaryStatus {
if (!status.configured) { if (!status.configured) {
return 'needsConfig' return 'needsConfig'
} else { } else {
@@ -40,7 +39,7 @@ function getDependencyStatus(depErrors: PkgDependencyErrors): DependencyStatus {
return Object.values(depErrors).some(err => !!err) ? 'warning' : 'satisfied' return Object.values(depErrors).some(err => !!err) ? 'warning' : 'satisfied'
} }
function getHealthStatus(status: Status): T.HealthStatus | null { function getHealthStatus(status: T.Status): T.HealthStatus | null {
if (status.main.status !== 'running' || !status.main.health) { if (status.main.status !== 'running' || !status.main.health) {
return null return null
} }

View File

@@ -7,7 +7,7 @@ import {
UpdatingState, UpdatingState,
} from 'src/app/services/patch-db/data-model' } from 'src/app/services/patch-db/data-model'
import { firstValueFrom } from 'rxjs' import { firstValueFrom } from 'rxjs'
import { Manifest } from '../../../../../../core/startos/bindings/Manifest' import { T } from '@start9labs/start-sdk'
export async function getPackage( export async function getPackage(
patch: PatchDB<DataModel>, patch: PatchDB<DataModel>,
@@ -22,7 +22,7 @@ export async function getAllPackages(
return firstValueFrom(patch.watch$('packageData')) return firstValueFrom(patch.watch$('packageData'))
} }
export function getManifest(pkg: PackageDataEntry): Manifest { export function getManifest(pkg: PackageDataEntry): T.Manifest {
return isInstalling(pkg) return isInstalling(pkg)
? pkg.stateInfo.installingInfo.newManifest ? pkg.stateInfo.installingInfo.newManifest
: pkg.stateInfo.manifest! : pkg.stateInfo.manifest!