From 5c473eb9cc6117f03906f88eb4261fb1f3071e59 Mon Sep 17 00:00:00 2001 From: Lucy <12953208+elvece@users.noreply.github.com> Date: Tue, 29 Apr 2025 16:12:21 -0400 Subject: [PATCH] update marketplace url to reflect build version (#2914) * update marketplace url to reflect build version * adjust marketplace config * use helper function to compare urls * rework some registry stuff * #2900, #2899, and other registry changes * alpha.1 * trailing / * add startosRegistry * fix migration --------- Co-authored-by: Matt Hill Co-authored-by: Aiden McClelland Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> --- Makefile | 14 +- core/Cargo.lock | 2 +- core/startos/Cargo.toml | 2 +- core/startos/src/registry/admin.rs | 37 +++++- core/startos/src/registry/os/asset/add.rs | 94 ++++++++++++++ core/startos/src/registry/os/asset/mod.rs | 2 + core/startos/src/registry/os/version/mod.rs | 43 +++++-- core/startos/src/registry/package/add.rs | 53 ++++++++ core/startos/src/registry/package/category.rs | 104 +++++++++++---- core/startos/src/registry/package/get.rs | 6 +- core/startos/src/registry/package/index.rs | 1 - core/startos/src/registry/package/mod.rs | 7 + core/startos/src/version/mod.rs | 14 +- core/startos/src/version/v0_4_0_alpha_1.rs | 72 +++++++++++ sdk/base/lib/osBindings/AddCategoryParams.ts | 7 +- .../osBindings/AddPackageToCategoryParams.ts | 4 + sdk/base/lib/osBindings/Category.ts | 3 +- sdk/base/lib/osBindings/GetOsVersionParams.ts | 7 +- sdk/base/lib/osBindings/GetPackageParams.ts | 2 +- sdk/base/lib/osBindings/RemoveAdminParams.ts | 4 + sdk/base/lib/osBindings/RemoveAssetParams.ts | 3 + .../RemovePackageFromCategoryParams.ts | 4 + .../lib/osBindings/RemovePackageParams.ts | 5 + sdk/base/lib/osBindings/index.ts | 37 +++--- sdk/package/lib/StartSdk.ts | 2 +- web/config-sample.json | 5 - web/package-lock.json | 4 +- web/package.json | 2 +- web/patchdb-ui-seed.json | 23 +--- .../src/components/menu/menu.component.html | 2 - .../src/components/menu/menu.component.scss | 1 - .../src/components/menu/menu.component.ts | 4 - .../src/components/registry.component.ts | 8 +- .../store-icon/store-icon.component.ts | 21 +-- .../list/categories/categories.component.ts | 10 +- web/projects/marketplace/src/types.ts | 6 +- ...community-store.png => community-icon.png} | Bin web/projects/shared/assets/img/icon_alpha.png | Bin 0 -> 53404 bytes web/projects/shared/assets/img/icon_beta.png | Bin 0 -> 52383 bytes .../shared/assets/img/storefront-outline.png | Bin 10912 -> 43384 bytes .../shared/src/types/workspace-config.ts | 19 +-- .../components/controls.component.ts | 4 +- .../marketplace/components/menu.component.ts | 6 +- .../components/notification.component.ts | 17 ++- .../marketplace/marketplace.component.ts | 18 ++- .../marketplace/modals/preview.component.ts | 2 +- .../marketplace/modals/registry.component.ts | 67 +++++----- .../marketplace/services/alerts.service.ts | 27 ++-- .../system/routes/acme/acme.component.ts | 1 - .../routes/general/general.component.ts | 7 +- .../system/routes/general/snek.directive.ts | 5 +- .../system/routes/general/update.component.ts | 11 +- .../routes/updates/updates.component.ts | 11 +- .../ui/src/app/services/api/api.fixures.ts | 24 ++-- .../ui/src/app/services/api/api.types.ts | 21 ++- .../app/services/api/embassy-api.service.ts | 32 ++--- .../services/api/embassy-live-api.service.ts | 90 ++++--------- .../services/api/embassy-mock-api.service.ts | 37 +++--- .../ui/src/app/services/api/mock-patch.ts | 24 +--- .../ui/src/app/services/config.service.ts | 4 +- .../src/app/services/marketplace.service.ts | 121 ++++++++---------- .../ui/src/app/services/os.service.ts | 17 ++- .../src/app/services/patch-db/data-model.ts | 23 +--- 63 files changed, 733 insertions(+), 470 deletions(-) create mode 100644 core/startos/src/version/v0_4_0_alpha_1.rs create mode 100644 sdk/base/lib/osBindings/AddPackageToCategoryParams.ts create mode 100644 sdk/base/lib/osBindings/RemoveAdminParams.ts create mode 100644 sdk/base/lib/osBindings/RemoveAssetParams.ts create mode 100644 sdk/base/lib/osBindings/RemovePackageFromCategoryParams.ts create mode 100644 sdk/base/lib/osBindings/RemovePackageParams.ts rename web/projects/shared/assets/img/{community-store.png => community-icon.png} (100%) create mode 100644 web/projects/shared/assets/img/icon_alpha.png create mode 100644 web/projects/shared/assets/img/icon_beta.png diff --git a/Makefile b/Makefile index d3f304abf..80d3c65b5 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ COMPAT_SRC := $(shell git ls-files system-images/compat/) UTILS_SRC := $(shell git ls-files system-images/utils/) BINFMT_SRC := $(shell git ls-files system-images/binfmt/) CORE_SRC := $(shell git ls-files core) $(shell git ls-files --recurse-submodules patch-db) $(GIT_HASH_FILE) -WEB_SHARED_SRC := $(shell git ls-files web/projects/shared) $(shell ls -p web/ | grep -v / | sed 's/^/web\//g') web/node_modules/.package-lock.json web/config.json patch-db/client/dist/index.js sdk/baseDist/package.json web/patchdb-ui-seed.json sdk/dist/package.json +WEB_SHARED_SRC := $(shell git ls-files web/projects/shared) $(shell git ls-files web/projects/marketplace) $(shell ls -p web/ | grep -v / | sed 's/^/web\//g') web/node_modules/.package-lock.json web/config.json patch-db/client/dist/index.js sdk/baseDist/package.json web/patchdb-ui-seed.json sdk/dist/package.json WEB_UI_SRC := $(shell git ls-files web/projects/ui) WEB_SETUP_WIZARD_SRC := $(shell git ls-files web/projects/setup-wizard) WEB_INSTALL_WIZARD_SRC := $(shell git ls-files web/projects/install-wizard) @@ -302,17 +302,7 @@ $(COMPRESSED_WEB_UIS): $(WEB_UIS) $(ENVIRONMENT_FILE) ./compress-uis.sh web/config.json: $(GIT_HASH_FILE) web/config-sample.json - @ver=$$(cat VERSION.txt); \ - case $$ver in \ - *alpha*) osUrl="https://alpha-registry-x.start9.com/" ;; \ - *beta*) osUrl="https://beta-registry.start9.com/" ;; \ - *) osUrl="https://registry.start9.com/" ;; \ - esac; \ - gitHash=$$(cat GIT_HASH.txt); \ - jq '.useMocks = false' web/config-sample.json \ - | jq --arg gitHash "$$gitHash" '.gitHash = $$gitHash' \ - | jq --arg osUrl "$$osUrl" '.ui.startosRegistry = $$osUrl' \ - > web/config.json; + jq '.useMocks = false' web/config-sample.json | jq '.gitHash = "$(shell cat GIT_HASH.txt)"' > web/config.json patch-db/client/node_modules/.package-lock.json: patch-db/client/package.json npm --prefix patch-db/client ci diff --git a/core/Cargo.lock b/core/Cargo.lock index a0d511d5b..02b74c15b 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -6001,7 +6001,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "start-os" -version = "0.4.0-alpha.0" +version = "0.4.0-alpha.1" dependencies = [ "aes 0.7.5", "async-acme", diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index 55d6a8622..bead9781f 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.4.0-alpha.0" # VERSION_BUMP +version = "0.4.0-alpha.1" # VERSION_BUMP license = "MIT" [lib] diff --git a/core/startos/src/registry/admin.rs b/core/startos/src/registry/admin.rs index ffc9c3b35..02a852dd1 100644 --- a/core/startos/src/registry/admin.rs +++ b/core/startos/src/registry/admin.rs @@ -22,16 +22,30 @@ pub fn admin_api() -> ParentHandler { "signer", signers_api::().with_about("Commands to add or list signers"), ) - .subcommand("add", from_fn_async(add_admin).no_cli()) + .subcommand( + "add", + from_fn_async(add_admin) + .with_metadata("admin", Value::Bool(true)) + .no_cli(), + ) .subcommand( "add", from_fn_async(cli_add_admin) .no_display() .with_about("Add admin signer"), ) + .subcommand( + "remove", + from_fn_async(remove_admin) + .with_metadata("admin", Value::Bool(true)) + .no_display() + .with_about("Remove an admin signer") + .with_call_remote::(), + ) .subcommand( "list", from_fn_async(list_admins) + .with_metadata("admin", Value::Bool(true)) .with_display_serializable() .with_custom_display_fn(|handle, result| Ok(display_signers(handle.params, result))) .with_about("List admin signers") @@ -285,6 +299,27 @@ pub async fn add_admin( .result } +#[derive(Debug, Deserialize, Serialize, Parser, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct RemoveAdminParams { + pub signer: Guid, +} + +// TODO: don't allow removing self? +pub async fn remove_admin( + ctx: RegistryContext, + RemoveAdminParams { signer }: RemoveAdminParams, +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_admins_mut().mutate(|a| Ok(a.remove(&signer)))?; + Ok(()) + }) + .await + .result +} + #[derive(Debug, Deserialize, Serialize, Parser)] #[command(rename_all = "kebab-case")] #[serde(rename_all = "camelCase")] diff --git a/core/startos/src/registry/os/asset/add.rs b/core/startos/src/registry/os/asset/add.rs index 09a6ad164..89a1ec9b1 100644 --- a/core/startos/src/registry/os/asset/add.rs +++ b/core/startos/src/registry/os/asset/add.rs @@ -51,6 +51,28 @@ pub fn add_api() -> ParentHandler { ) } +pub fn remove_api() -> ParentHandler { + ParentHandler::new() + .subcommand( + "iso", + from_fn_async(remove_iso) + .with_metadata("get_signer", Value::Bool(true)) + .no_cli(), + ) + .subcommand( + "img", + from_fn_async(remove_img) + .with_metadata("get_signer", Value::Bool(true)) + .no_cli(), + ) + .subcommand( + "squashfs", + from_fn_async(remove_squashfs) + .with_metadata("get_signer", Value::Bool(true)) + .no_cli(), + ) +} + #[derive(Debug, Deserialize, Serialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export)] @@ -99,6 +121,7 @@ async fn add_asset( .as_authorized() .de()? .contains(&signer_guid) + || db.as_admins().de()?.contains(&signer_guid) { accessor( db.as_index_mut() @@ -256,3 +279,74 @@ pub async fn cli_add_asset( Ok(()) } + +#[derive(Debug, Deserialize, Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct RemoveAssetParams { + #[ts(type = "string")] + pub version: Version, + #[ts(type = "string")] + pub platform: InternedString, + #[serde(rename = "__auth_signer")] + #[ts(skip)] + pub signer: AnyVerifyingKey, +} + +async fn remove_asset( + ctx: RegistryContext, + RemoveAssetParams { + version, + platform, + signer, + }: RemoveAssetParams, + accessor: impl FnOnce( + &mut Model, + ) -> &mut Model>> + + UnwindSafe + + Send, +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + let signer_guid = db.as_index().as_signers().get_signer(&signer)?; + if db + .as_index() + .as_os() + .as_versions() + .as_idx(&version) + .or_not_found(&version)? + .as_authorized() + .de()? + .contains(&signer_guid) + || db.as_admins().de()?.contains(&signer_guid) + { + accessor( + db.as_index_mut() + .as_os_mut() + .as_versions_mut() + .as_idx_mut(&version) + .or_not_found(&version)?, + ) + .remove(&platform)?; + Ok(()) + } else { + Err(Error::new(eyre!("UNAUTHORIZED"), ErrorKind::Authorization)) + } + }) + .await + .result?; + + Ok(()) +} + +pub async fn remove_iso(ctx: RegistryContext, params: RemoveAssetParams) -> Result<(), Error> { + remove_asset(ctx, params, |m| m.as_iso_mut()).await +} + +pub async fn remove_img(ctx: RegistryContext, params: RemoveAssetParams) -> Result<(), Error> { + remove_asset(ctx, params, |m| m.as_img_mut()).await +} + +pub async fn remove_squashfs(ctx: RegistryContext, params: RemoveAssetParams) -> Result<(), Error> { + remove_asset(ctx, params, |m| m.as_squashfs_mut()).await +} diff --git a/core/startos/src/registry/os/asset/mod.rs b/core/startos/src/registry/os/asset/mod.rs index 52c12341a..9cafa14a6 100644 --- a/core/startos/src/registry/os/asset/mod.rs +++ b/core/startos/src/registry/os/asset/mod.rs @@ -13,6 +13,7 @@ pub fn asset_api() -> ParentHandler { .no_display() .with_about("Add asset to registry"), ) + .subcommand("remove", add::remove_api::()) .subcommand("sign", sign::sign_api::()) .subcommand( "sign", @@ -20,6 +21,7 @@ pub fn asset_api() -> ParentHandler { .no_display() .with_about("Sign file and add to registry index"), ) + // TODO: remove signature api .subcommand( "get", get::get_api::().with_about("Commands to download image, iso, or squashfs files"), diff --git a/core/startos/src/registry/os/version/mod.rs b/core/startos/src/registry/os/version/mod.rs index 12661e4e1..ddbf92b24 100644 --- a/core/startos/src/registry/os/version/mod.rs +++ b/core/startos/src/registry/os/version/mod.rs @@ -3,6 +3,7 @@ use std::collections::BTreeMap; use chrono::Utc; use clap::Parser; use exver::{Version, VersionRange}; +use imbl_value::InternedString; use itertools::Itertools; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; @@ -12,6 +13,7 @@ use ts_rs::TS; use crate::context::CliContext; use crate::prelude::*; use crate::registry::context::RegistryContext; +use crate::registry::device_info::DeviceInfo; use crate::registry::os::index::OsVersionInfo; use crate::registry::signer::sign::AnyVerifyingKey; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; @@ -44,6 +46,7 @@ pub fn version_api() -> ParentHandler { .subcommand( "get", from_fn_async(get_version) + .with_metadata("get_device_info", Value::Bool(true)) .with_display_serializable() .with_custom_display_fn(|handle, result| { Ok(display_version_info(handle.params, result)) @@ -133,35 +136,47 @@ pub async fn remove_version( pub struct GetOsVersionParams { #[ts(type = "string | null")] #[arg(long = "src")] - pub source: Option, - #[ts(type = "string | null")] - #[arg(long = "target")] - pub target: Option, + pub source_version: Option, #[ts(type = "string | null")] + #[arg(long)] + pub target_version: Option, + #[arg(long)] + pub include_prerelease: Option, #[arg(long = "id")] server_id: Option, #[ts(type = "string | null")] - #[arg(long = "arch")] - arch: Option, + #[arg(long)] + platform: Option, + #[ts(skip)] + #[arg(skip)] + #[serde(rename = "__device_info")] + pub device_info: Option, } pub async fn get_version( ctx: RegistryContext, GetOsVersionParams { - source, - target, + source_version: source, + target_version: target, + include_prerelease, server_id, - arch, + platform, + device_info, }: GetOsVersionParams, ) -> Result, Error> { - if let (Some(pool), Some(server_id), Some(arch)) = (&ctx.pool, server_id, arch) { + let source = source.or_else(|| device_info.as_ref().map(|d| d.os.version.clone())); + let platform = platform.or_else(|| device_info.as_ref().map(|d| d.os.platform.clone())); + let include_prerelease = include_prerelease + .or_else(|| source.as_ref().map(|s| !s.prerelease().is_empty())) + .unwrap_or(cfg!(feature = "dev")); + if let (Some(pool), Some(server_id), Some(arch)) = (&ctx.pool, server_id, &platform) { let created_at = Utc::now(); query!( "INSERT INTO user_activity (created_at, server_id, arch) VALUES ($1, $2, $3)", created_at, server_id, - arch + &**arch ) .execute(pool) .await?; @@ -177,7 +192,11 @@ pub async fn get_version( .into_iter() .map(|(v, i)| i.de().map(|i| (v, i))) .filter_ok(|(version, info)| { - version.satisfies(&target) + (version.prerelease().is_empty() || include_prerelease) + && platform + .as_ref() + .map_or(true, |p| info.squashfs.contains_key(p)) + && version.satisfies(&target) && source .as_ref() .map_or(true, |s| s.satisfies(&info.source_version)) diff --git a/core/startos/src/registry/package/add.rs b/core/startos/src/registry/package/add.rs index bf3d36fd1..146f96334 100644 --- a/core/startos/src/registry/package/add.rs +++ b/core/startos/src/registry/package/add.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use clap::Parser; use imbl_value::InternedString; use itertools::Itertools; +use models::{PackageId, VersionString}; use rpc_toolkit::HandlerArgs; use serde::{Deserialize, Serialize}; use ts_rs::TS; @@ -158,3 +159,55 @@ pub async fn cli_add_package( Ok(()) } + +#[derive(Debug, Deserialize, Serialize, Parser, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct RemovePackageParams { + pub id: PackageId, + pub version: VersionString, + #[ts(skip)] + #[serde(rename = "__auth_signer")] + pub signer: AnyVerifyingKey, +} + +pub async fn remove_package( + ctx: RegistryContext, + RemovePackageParams { + id, + version, + signer, + }: RemovePackageParams, +) -> Result<(), Error> { + let peek = ctx.db.peek().await; + let signer_guid = peek.as_index().as_signers().get_signer(&signer)?; + + ctx.db + .mutate(|db| { + if db.as_admins().de()?.contains(&signer_guid) + || db + .as_index() + .as_package() + .as_packages() + .as_idx(&id) + .or_not_found(&id)? + .as_authorized() + .de()? + .contains(&signer_guid) + { + if let Some(package) = db + .as_index_mut() + .as_package_mut() + .as_packages_mut() + .as_idx_mut(&id) + { + package.as_versions_mut().remove(&version)?; + } + Ok(()) + } else { + Err(Error::new(eyre!("UNAUTHORIZED"), ErrorKind::Authorization)) + } + }) + .await + .result +} diff --git a/core/startos/src/registry/package/category.rs b/core/startos/src/registry/package/category.rs index 7afb8906b..7c3aafad8 100644 --- a/core/startos/src/registry/package/category.rs +++ b/core/startos/src/registry/package/category.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use clap::Parser; use imbl_value::InternedString; +use models::PackageId; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use ts_rs::TS; @@ -10,7 +11,6 @@ use crate::context::CliContext; use crate::prelude::*; use crate::registry::context::RegistryContext; use crate::registry::package::index::Category; -use crate::s9pk::manifest::Description; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; pub fn category_api() -> ParentHandler { @@ -31,6 +31,22 @@ pub fn category_api() -> ParentHandler { .with_about("Remove a category from the registry") .with_call_remote::(), ) + .subcommand( + "add-package", + from_fn_async(add_package) + .with_metadata("admin", Value::Bool(true)) + .no_display() + .with_about("Add a package to a category") + .with_call_remote::(), + ) + .subcommand( + "remove-package", + from_fn_async(remove_package) + .with_metadata("admin", Value::Bool(true)) + .no_display() + .with_about("Remove a package from a category") + .with_call_remote::(), + ) .subcommand( "list", from_fn_async(list_categories) @@ -50,33 +66,18 @@ pub struct AddCategoryParams { #[ts(type = "string")] pub id: InternedString, pub name: String, - #[arg(short, long, help = "Short description for the category")] - pub short: String, - #[arg(short, long, help = "Long description for the category")] - pub long: String, } pub async fn add_category( ctx: RegistryContext, - AddCategoryParams { - id, - name, - short, - long, - }: AddCategoryParams, + AddCategoryParams { id, name }: AddCategoryParams, ) -> Result<(), Error> { ctx.db .mutate(|db| { db.as_index_mut() .as_package_mut() .as_categories_mut() - .insert( - &id, - &Category { - name, - description: Description { short, long }, - }, - ) + .insert(&id, &Category { name }) }) .await .result?; @@ -108,6 +109,64 @@ pub async fn remove_category( Ok(()) } +#[derive(Debug, Deserialize, Serialize, Parser, TS)] +#[command(rename_all = "kebab-case")] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct AddPackageToCategoryParams { + #[ts(type = "string")] + pub id: InternedString, + pub package: PackageId, +} + +pub async fn add_package( + ctx: RegistryContext, + AddPackageToCategoryParams { id, package }: AddPackageToCategoryParams, +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_index_mut() + .as_package_mut() + .as_packages_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_categories_mut() + .mutate(|c| Ok(c.insert(id))) + }) + .await + .result?; + Ok(()) +} + +#[derive(Debug, Deserialize, Serialize, Parser, TS)] +#[command(rename_all = "kebab-case")] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct RemovePackageFromCategoryParams { + #[ts(type = "string")] + pub id: InternedString, + pub package: PackageId, +} + +pub async fn remove_package( + ctx: RegistryContext, + RemovePackageFromCategoryParams { id, package }: RemovePackageFromCategoryParams, +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_index_mut() + .as_package_mut() + .as_packages_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_categories_mut() + .mutate(|c| Ok(c.remove(&id))) + }) + .await + .result?; + Ok(()) +} + pub async fn list_categories( ctx: RegistryContext, ) -> Result, Error> { @@ -134,16 +193,9 @@ pub fn display_categories( table.add_row(row![bc => "ID", "NAME", - "SHORT DESCRIPTION", - "LONG DESCRIPTION", ]); for (id, info) in categories { - table.add_row(row![ - &*id, - &info.name, - &info.description.short, - &info.description.long, - ]); + table.add_row(row![&*id, &info.name]); } table.print_tty(false).unwrap(); } diff --git a/core/startos/src/registry/package/get.rs b/core/startos/src/registry/package/get.rs index cae1289a9..32a279fde 100644 --- a/core/startos/src/registry/package/get.rs +++ b/core/startos/src/registry/package/get.rs @@ -45,7 +45,9 @@ pub struct PackageInfoShort { pub struct GetPackageParams { pub id: Option, #[ts(type = "string | null")] - pub version: Option, + #[arg(long, short = 'v')] + pub target_version: Option, + #[arg(long)] pub source_version: Option, #[ts(skip)] #[arg(skip)] @@ -188,7 +190,7 @@ pub async fn get_package(ctx: RegistryContext, params: GetPackageParams) -> Resu let package_best = best.entry(id.clone()).or_default(); let package_other = other.entry(id.clone()).or_default(); if params - .version + .target_version .as_ref() .map_or(true, |v| version.satisfies(v)) && package_best.keys().all(|k| !(**k > version)) diff --git a/core/startos/src/registry/package/index.rs b/core/startos/src/registry/package/index.rs index d48963267..2081d4771 100644 --- a/core/startos/src/registry/package/index.rs +++ b/core/startos/src/registry/package/index.rs @@ -47,7 +47,6 @@ pub struct PackageInfo { #[ts(export)] pub struct Category { pub name: String, - pub description: Description, } #[derive(Debug, Deserialize, Serialize, HasModel, TS)] diff --git a/core/startos/src/registry/package/mod.rs b/core/startos/src/registry/package/mod.rs index 74d244deb..fa395a479 100644 --- a/core/startos/src/registry/package/mod.rs +++ b/core/startos/src/registry/package/mod.rs @@ -31,6 +31,13 @@ pub fn package_api() -> ParentHandler { .no_display() .with_about("Add package to registry index"), ) + .subcommand( + "remove", + from_fn_async(add::remove_package) + .no_display() + .with_about("Add package to registry index") + .with_call_remote::(), + ) .subcommand( "signer", signer::signer_api::().with_about("Add, remove, and list package signers"), diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index 3e8523d33..1cf615005 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -40,8 +40,9 @@ mod v0_3_6_alpha_17; mod v0_3_6_alpha_18; mod v0_4_0_alpha_0; +mod v0_4_0_alpha_1; -pub type Current = v0_4_0_alpha_0::Version; // VERSION_BUMP +pub type Current = v0_4_0_alpha_1::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -145,7 +146,8 @@ enum Version { V0_3_6_alpha_16(Wrapper), V0_3_6_alpha_17(Wrapper), V0_3_6_alpha_18(Wrapper), - V0_4_0_alpha_0(Wrapper), // VERSION_BUMP + V0_4_0_alpha_0(Wrapper), + V0_4_0_alpha_1(Wrapper), // VERSION_BUMP Other(exver::Version), } @@ -187,8 +189,9 @@ impl Version { Self::V0_3_6_alpha_15(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_16(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_17(v) => DynVersion(Box::new(v.0)), - Self::V0_3_6_alpha_18(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP - Self::V0_4_0_alpha_0(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP + Self::V0_3_6_alpha_18(v) => DynVersion(Box::new(v.0)), + Self::V0_4_0_alpha_0(v) => DynVersion(Box::new(v.0)), + Self::V0_4_0_alpha_1(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -223,7 +226,8 @@ impl Version { Version::V0_3_6_alpha_16(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_17(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_18(Wrapper(x)) => x.semver(), - Version::V0_4_0_alpha_0(Wrapper(x)) => x.semver(), // VERSION_BUMP + Version::V0_4_0_alpha_0(Wrapper(x)) => x.semver(), + Version::V0_4_0_alpha_1(Wrapper(x)) => x.semver(), // VERSION_BUMP Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_4_0_alpha_1.rs b/core/startos/src/version/v0_4_0_alpha_1.rs new file mode 100644 index 000000000..f44a5ef51 --- /dev/null +++ b/core/startos/src/version/v0_4_0_alpha_1.rs @@ -0,0 +1,72 @@ +use exver::{PreReleaseSegment, VersionRange}; +use imbl_value::json; + +use super::v0_3_5::V0_3_0_COMPAT; +use super::{v0_4_0_alpha_0, VersionT}; +use crate::prelude::*; + +lazy_static::lazy_static! { + static ref V0_4_0_alpha_1: exver::Version = exver::Version::new( + [0, 4, 0], + [PreReleaseSegment::String("alpha".into()), 1.into()] + ); +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Version; + +impl VersionT for Version { + type Previous = v0_4_0_alpha_0::Version; + type PreUpRes = (); + + async fn pre_up(self) -> Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_4_0_alpha_1.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + let Some(ui) = db["public"]["ui"].as_object_mut() else { + return Err(Error::new( + eyre!("db.public.ui is not an object"), + ErrorKind::Database, + )); + }; + ui.insert( + "registries".into(), + Value::Object( + ui.get("marketplace") + .and_then(|m| m.get("knownHosts")) + .and_then(|kh| kh.as_object()) + .into_iter() + .flatten() + .map(|(k, v)| (k.clone(), v["name"].clone())) + .collect(), + ), + ); + if let Some(highscore) = ui + .get_mut("gaming") + .and_then(|g| g.get_mut("snake")) + .and_then(|s| s.get_mut("highScore")) + .map(|hs| hs.take()) + .filter(|s| s.is_number()) + { + ui.insert("snakeHighScore".into(), highscore); + } + ui.insert( + "startosRegistry".into(), + json!("https://registry.start9.com/"), + ); + ui.remove("marketplace"); + ui.remove("gaming"); + ui.remove("theme"); + + Ok(()) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/sdk/base/lib/osBindings/AddCategoryParams.ts b/sdk/base/lib/osBindings/AddCategoryParams.ts index 799f2d4d2..62b04e6e2 100644 --- a/sdk/base/lib/osBindings/AddCategoryParams.ts +++ b/sdk/base/lib/osBindings/AddCategoryParams.ts @@ -1,8 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type AddCategoryParams = { - id: string - name: string - short: string - long: string -} +export type AddCategoryParams = { id: string; name: string } diff --git a/sdk/base/lib/osBindings/AddPackageToCategoryParams.ts b/sdk/base/lib/osBindings/AddPackageToCategoryParams.ts new file mode 100644 index 000000000..2ac9c2ff3 --- /dev/null +++ b/sdk/base/lib/osBindings/AddPackageToCategoryParams.ts @@ -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 { PackageId } from "./PackageId" + +export type AddPackageToCategoryParams = { id: string; package: PackageId } diff --git a/sdk/base/lib/osBindings/Category.ts b/sdk/base/lib/osBindings/Category.ts index 6e0815675..615094527 100644 --- a/sdk/base/lib/osBindings/Category.ts +++ b/sdk/base/lib/osBindings/Category.ts @@ -1,4 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { Description } from "./Description" -export type Category = { name: string; description: Description } +export type Category = { name: string } diff --git a/sdk/base/lib/osBindings/GetOsVersionParams.ts b/sdk/base/lib/osBindings/GetOsVersionParams.ts index de0458645..155819758 100644 --- a/sdk/base/lib/osBindings/GetOsVersionParams.ts +++ b/sdk/base/lib/osBindings/GetOsVersionParams.ts @@ -1,8 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. export type GetOsVersionParams = { - source: string | null - target: string | null + sourceVersion: string | null + targetVersion: string | null + includePrerelease: boolean | null serverId: string | null - arch: string | null + platform: string | null } diff --git a/sdk/base/lib/osBindings/GetPackageParams.ts b/sdk/base/lib/osBindings/GetPackageParams.ts index 3dde55b28..22046d8e9 100644 --- a/sdk/base/lib/osBindings/GetPackageParams.ts +++ b/sdk/base/lib/osBindings/GetPackageParams.ts @@ -5,7 +5,7 @@ import type { Version } from "./Version" export type GetPackageParams = { id: PackageId | null - version: string | null + targetVersion: string | null sourceVersion: Version | null otherVersions: PackageDetailLevel } diff --git a/sdk/base/lib/osBindings/RemoveAdminParams.ts b/sdk/base/lib/osBindings/RemoveAdminParams.ts new file mode 100644 index 000000000..80ca0e823 --- /dev/null +++ b/sdk/base/lib/osBindings/RemoveAdminParams.ts @@ -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 { Guid } from "./Guid" + +export type RemoveAdminParams = { signer: Guid } diff --git a/sdk/base/lib/osBindings/RemoveAssetParams.ts b/sdk/base/lib/osBindings/RemoveAssetParams.ts new file mode 100644 index 000000000..220c2f3b0 --- /dev/null +++ b/sdk/base/lib/osBindings/RemoveAssetParams.ts @@ -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 RemoveAssetParams = { version: string; platform: string } diff --git a/sdk/base/lib/osBindings/RemovePackageFromCategoryParams.ts b/sdk/base/lib/osBindings/RemovePackageFromCategoryParams.ts new file mode 100644 index 000000000..c12dc6002 --- /dev/null +++ b/sdk/base/lib/osBindings/RemovePackageFromCategoryParams.ts @@ -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 { PackageId } from "./PackageId" + +export type RemovePackageFromCategoryParams = { id: string; package: PackageId } diff --git a/sdk/base/lib/osBindings/RemovePackageParams.ts b/sdk/base/lib/osBindings/RemovePackageParams.ts new file mode 100644 index 000000000..aee8d50f2 --- /dev/null +++ b/sdk/base/lib/osBindings/RemovePackageParams.ts @@ -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 { PackageId } from "./PackageId" +import type { Version } from "./Version" + +export type RemovePackageParams = { id: PackageId; version: Version } diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index a1aacb61b..9162d46d0 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -4,13 +4,13 @@ export { AcmeSettings } from "./AcmeSettings" export { ActionId } from "./ActionId" export { ActionInput } from "./ActionInput" export { ActionMetadata } from "./ActionMetadata" -export { ActionRequest } from "./ActionRequest" export { ActionRequestCondition } from "./ActionRequestCondition" export { ActionRequestEntry } from "./ActionRequestEntry" export { ActionRequestInput } from "./ActionRequestInput" export { ActionRequestTrigger } from "./ActionRequestTrigger" -export { ActionResult } from "./ActionResult" +export { ActionRequest } from "./ActionRequest" export { ActionResultMember } from "./ActionResultMember" +export { ActionResult } from "./ActionResult" export { ActionResultV0 } from "./ActionResultV0" export { ActionResultV1 } from "./ActionResultV1" export { ActionResultValue } from "./ActionResultValue" @@ -20,13 +20,14 @@ export { AddAdminParams } from "./AddAdminParams" export { AddAssetParams } from "./AddAssetParams" export { AddCategoryParams } from "./AddCategoryParams" export { AddPackageParams } from "./AddPackageParams" +export { AddPackageToCategoryParams } from "./AddPackageToCategoryParams" +export { AddressInfo } from "./AddressInfo" export { AddSslOptions } from "./AddSslOptions" export { AddVersionParams } from "./AddVersionParams" -export { AddressInfo } from "./AddressInfo" export { Alerts } from "./Alerts" export { Algorithm } from "./Algorithm" -export { AllPackageData } from "./AllPackageData" export { AllowedStatuses } from "./AllowedStatuses" +export { AllPackageData } from "./AllPackageData" export { AlpnInfo } from "./AlpnInfo" export { AnySignature } from "./AnySignature" export { AnySigningKey } from "./AnySigningKey" @@ -38,9 +39,9 @@ export { BackupTargetFS } from "./BackupTargetFS" export { Base64 } from "./Base64" export { BindId } from "./BindId" export { BindInfo } from "./BindInfo" +export { BindingSetPublicParams } from "./BindingSetPublicParams" export { BindOptions } from "./BindOptions" export { BindParams } from "./BindParams" -export { BindingSetPublicParams } from "./BindingSetPublicParams" export { Blake3Commitment } from "./Blake3Commitment" export { BlockDev } from "./BlockDev" export { BuildArg } from "./BuildArg" @@ -61,11 +62,11 @@ export { CreateSubcontainerFsParams } from "./CreateSubcontainerFsParams" export { CurrentDependencies } from "./CurrentDependencies" export { CurrentDependencyInfo } from "./CurrentDependencyInfo" export { DataUrl } from "./DataUrl" -export { DepInfo } from "./DepInfo" export { Dependencies } from "./Dependencies" export { DependencyKind } from "./DependencyKind" export { DependencyMetadata } from "./DependencyMetadata" export { DependencyRequirement } from "./DependencyRequirement" +export { DepInfo } from "./DepInfo" export { Description } from "./Description" export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams" export { DeviceFilter } from "./DeviceFilter" @@ -86,8 +87,8 @@ export { GetHostInfoParams } from "./GetHostInfoParams" export { GetOsAssetParams } from "./GetOsAssetParams" export { GetOsVersionParams } from "./GetOsVersionParams" export { GetPackageParams } from "./GetPackageParams" -export { GetPackageResponse } from "./GetPackageResponse" export { GetPackageResponseFull } from "./GetPackageResponseFull" +export { GetPackageResponse } from "./GetPackageResponse" export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams" export { GetServicePortForwardParams } from "./GetServicePortForwardParams" export { GetSslCertificateParams } from "./GetSslCertificateParams" @@ -101,21 +102,21 @@ export { Governor } from "./Governor" export { Guid } from "./Guid" export { HardwareRequirements } from "./HardwareRequirements" export { HealthCheckId } from "./HealthCheckId" -export { Host } from "./Host" export { HostAddress } from "./HostAddress" export { HostId } from "./HostId" export { HostnameInfo } from "./HostnameInfo" export { Hosts } from "./Hosts" +export { Host } from "./Host" export { ImageConfig } from "./ImageConfig" export { ImageId } from "./ImageId" export { ImageMetadata } from "./ImageMetadata" export { ImageSource } from "./ImageSource" export { InitProgressRes } from "./InitProgressRes" -export { InstallParams } from "./InstallParams" export { InstalledState } from "./InstalledState" export { InstalledVersionParams } from "./InstalledVersionParams" export { InstallingInfo } from "./InstallingInfo" export { InstallingState } from "./InstallingState" +export { InstallParams } from "./InstallParams" export { IpHostname } from "./IpHostname" export { IpInfo } from "./IpInfo" export { ListPackageSignersParams } from "./ListPackageSignersParams" @@ -130,11 +131,11 @@ export { Manifest } from "./Manifest" export { MaybeUtf8String } from "./MaybeUtf8String" export { MebiBytes } from "./MebiBytes" export { MerkleArchiveCommitment } from "./MerkleArchiveCommitment" -export { Metrics } from "./Metrics" export { MetricsCpu } from "./MetricsCpu" export { MetricsDisk } from "./MetricsDisk" export { MetricsGeneral } from "./MetricsGeneral" export { MetricsMemory } from "./MetricsMemory" +export { Metrics } from "./Metrics" export { MountParams } from "./MountParams" export { MountTarget } from "./MountTarget" export { NamedHealthCheckResult } from "./NamedHealthCheckResult" @@ -146,14 +147,14 @@ export { NetworkInterfaceSetInboundParams } from "./NetworkInterfaceSetInboundPa export { NetworkInterfaceType } from "./NetworkInterfaceType" export { OnionHostname } from "./OnionHostname" export { OsIndex } from "./OsIndex" -export { OsVersionInfo } from "./OsVersionInfo" export { OsVersionInfoMap } from "./OsVersionInfoMap" +export { OsVersionInfo } from "./OsVersionInfo" export { PackageDataEntry } from "./PackageDataEntry" export { PackageDetailLevel } from "./PackageDetailLevel" export { PackageId } from "./PackageId" export { PackageIndex } from "./PackageIndex" -export { PackageInfo } from "./PackageInfo" export { PackageInfoShort } from "./PackageInfoShort" +export { PackageInfo } from "./PackageInfo" export { PackageSignerParams } from "./PackageSignerParams" export { PackageState } from "./PackageState" export { PackageVersionInfo } from "./PackageVersionInfo" @@ -166,7 +167,11 @@ export { Public } from "./Public" export { RecoverySource } from "./RecoverySource" export { RegistryAsset } from "./RegistryAsset" export { RegistryInfo } from "./RegistryInfo" +export { RemoveAdminParams } from "./RemoveAdminParams" +export { RemoveAssetParams } from "./RemoveAssetParams" export { RemoveCategoryParams } from "./RemoveCategoryParams" +export { RemovePackageFromCategoryParams } from "./RemovePackageFromCategoryParams" +export { RemovePackageParams } from "./RemovePackageParams" export { RemoveVersionParams } from "./RemoveVersionParams" export { ReplayId } from "./ReplayId" export { RequestActionParams } from "./RequestActionParams" @@ -176,18 +181,18 @@ export { Security } from "./Security" export { ServerInfo } from "./ServerInfo" export { ServerSpecs } from "./ServerSpecs" export { ServerStatus } from "./ServerStatus" -export { ServiceInterface } from "./ServiceInterface" export { ServiceInterfaceId } from "./ServiceInterfaceId" +export { ServiceInterface } from "./ServiceInterface" export { ServiceInterfaceType } from "./ServiceInterfaceType" -export { Session } from "./Session" export { SessionList } from "./SessionList" export { Sessions } from "./Sessions" +export { Session } from "./Session" export { SetDataVersionParams } from "./SetDataVersionParams" export { SetDependenciesParams } from "./SetDependenciesParams" export { SetHealth } from "./SetHealth" export { SetIconParams } from "./SetIconParams" -export { SetMainStatus } from "./SetMainStatus" export { SetMainStatusStatus } from "./SetMainStatusStatus" +export { SetMainStatus } from "./SetMainStatus" export { SetNameParams } from "./SetNameParams" export { SetStoreParams } from "./SetStoreParams" export { SetupExecuteParams } from "./SetupExecuteParams" @@ -202,7 +207,7 @@ export { TestSmtpParams } from "./TestSmtpParams" export { UnsetInboundParams } from "./UnsetInboundParams" export { UpdatingState } from "./UpdatingState" export { VerifyCifsParams } from "./VerifyCifsParams" -export { Version } from "./Version" export { VersionSignerParams } from "./VersionSignerParams" +export { Version } from "./Version" export { VolumeId } from "./VolumeId" export { WifiInfo } from "./WifiInfo" diff --git a/sdk/package/lib/StartSdk.ts b/sdk/package/lib/StartSdk.ts index 65dcb33f1..ed1f7e722 100644 --- a/sdk/package/lib/StartSdk.ts +++ b/sdk/package/lib/StartSdk.ts @@ -82,7 +82,7 @@ import * as actions from "../../base/lib/actions" import { setupInit } from "./inits/setupInit" import * as fs from "node:fs/promises" -export const OSVersion = testTypeVersion("0.4.0-alpha.0") +export const OSVersion = testTypeVersion("0.4.0-alpha.1") // prettier-ignore type AnyNeverCond = diff --git a/web/config-sample.json b/web/config-sample.json index 9dc0e2bf5..244f533b6 100644 --- a/web/config-sample.json +++ b/web/config-sample.json @@ -5,11 +5,6 @@ "url": "rpc", "version": "v1" }, - "marketplace": { - "start9": "https://registry.start9.com/", - "community": "https://community-registry.start9.com/" - }, - "startosRegistry": "https://registry.start9.com/", "mocks": { "maskAs": "tor", "maskAsHttps": true, diff --git a/web/package-lock.json b/web/package-lock.json index e13fb42bd..f8e01984c 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.4.0-alpha.0", + "version": "0.4.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.4.0-alpha.0", + "version": "0.4.0-alpha.1", "license": "MIT", "dependencies": { "@angular/animations": "^17.3.1", diff --git a/web/package.json b/web/package.json index 1df95e03b..d28baa1d9 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.4.0-alpha.0", + "version": "0.4.0-alpha.1", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT", diff --git a/web/patchdb-ui-seed.json b/web/patchdb-ui-seed.json index 6e197c7a4..5ecca58d5 100644 --- a/web/patchdb-ui-seed.json +++ b/web/patchdb-ui-seed.json @@ -1,21 +1,10 @@ { "name": null, - "marketplace": { - "selectedUrl": "https://registry.start9.com/", - "knownHosts": { - "https://registry.start9.com/": { - "name": "Start9 Registry" - }, - "https://community-registry.start9.com/": { - "name": "Community Registry" - } - } + "registries": { + "https://registry.start9.com/": "Start9 Registry", + "https://community-registry.start9.com/": "Community Registry" }, - "gaming": { - "snake": { - "highScore": 0 - } - }, - "ackInstructions": {}, - "theme": "Dark" + "startosRegisrty": "https://registry.start9.com/", + "snakeHighScore": 0, + "ackInstructions": {} } diff --git a/web/projects/marketplace/src/components/menu/menu.component.html b/web/projects/marketplace/src/components/menu/menu.component.html index 47fe4ffd0..2b4831060 100644 --- a/web/projects/marketplace/src/components/menu/menu.component.html +++ b/web/projects/marketplace/src/components/menu/menu.component.html @@ -5,7 +5,6 @@ [style.border-radius.%]="!registry ? 100 : null" size="60px" [url]="registry?.url || ''" - [marketplace]="iconConfig" />

{{ registry?.info?.name || 'Unnamed Registry' }} @@ -27,7 +26,6 @@ [style.height.px]="42" [style.border-radius.%]="100" [url]="registry?.url || ''" - [marketplace]="iconConfig" [tuiSkeleton]="!registry" /> +
{{ registry.name }}
{{ registry.url }}
@@ -24,8 +23,5 @@ import { MarketplaceConfig } from '@start9labs/shared' }) export class MarketplaceRegistryComponent { @Input() - marketplace!: MarketplaceConfig - - @Input() - registry!: { url: string; selected: boolean; name?: string } + registry!: { url: string; selected: boolean; name: string } } diff --git a/web/projects/marketplace/src/components/store-icon/store-icon.component.ts b/web/projects/marketplace/src/components/store-icon/store-icon.component.ts index 963d21ffc..de6436360 100644 --- a/web/projects/marketplace/src/components/store-icon/store-icon.component.ts +++ b/web/projects/marketplace/src/components/store-icon/store-icon.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core' -import { MarketplaceConfig, sameUrl } from '@start9labs/shared' +import { knownRegistries, sameUrl } from '@start9labs/shared' @Component({ selector: 'store-icon', @@ -9,13 +9,13 @@ import { MarketplaceConfig, sameUrl } from '@start9labs/shared' [style.border-radius.%]="100" [style.max-width]="size || '100%'" [src]="icon" - alt="Marketplace Icon" + alt="Registry Icon" /> Marketplace Icon `, @@ -27,17 +27,20 @@ export class StoreIconComponent { url = '' @Input() size?: string - @Input({ required: true }) - marketplace!: MarketplaceConfig get icon() { - const { start9, community } = this.marketplace + const { start9Alpha, start9Beta, start9, community } = knownRegistries - if (sameUrl(this.url, start9)) { + if (sameUrl(this.url, start9Alpha)) { + return 'assets/img/icon_alpha.png' + } else if (sameUrl(this.url, start9Beta)) { + return 'assets/img/icon_beta.png' + } else if (sameUrl(this.url, start9)) { return 'assets/img/icon_transparent.png' } else if (sameUrl(this.url, community)) { - return 'assets/img/community-store.png' + return 'assets/img/community-icon.png' + } else { + return 'assets/img/storefront-outline.png' } - return null } } diff --git a/web/projects/marketplace/src/pages/list/categories/categories.component.ts b/web/projects/marketplace/src/pages/list/categories/categories.component.ts index e65621f0b..735da7740 100644 --- a/web/projects/marketplace/src/pages/list/categories/categories.component.ts +++ b/web/projects/marketplace/src/pages/list/categories/categories.component.ts @@ -39,11 +39,11 @@ export class CategoriesComponent { readonly categoryChange = new EventEmitter() readonly fallback: Record = { - a: { name: '', description: { short: 'a', long: 'a' } }, - b: { name: '', description: { short: 'a', long: 'a' } }, - c: { name: '', description: { short: 'a', long: 'a' } }, - d: { name: '', description: { short: 'a', long: 'a' } }, - e: { name: '', description: { short: 'a', long: 'a' } }, + a: { name: '' }, + b: { name: '' }, + c: { name: '' }, + d: { name: '' }, + e: { name: '' }, } switchCategory(category: string): void { diff --git a/web/projects/marketplace/src/types.ts b/web/projects/marketplace/src/types.ts index 6f24fcea3..9c7f375d9 100644 --- a/web/projects/marketplace/src/types.ts +++ b/web/projects/marketplace/src/types.ts @@ -3,7 +3,7 @@ import { T } from '@start9labs/start-sdk' export type GetPackageReq = { id: string - version: string | null + targetVersion: string | null otherVersions: 'short' } export type GetPackageRes = T.GetPackageResponse & { @@ -12,7 +12,7 @@ export type GetPackageRes = T.GetPackageResponse & { export type GetPackagesReq = { id: null - version: null + targetVersion: null otherVersions: 'short' } @@ -22,7 +22,7 @@ export type GetPackagesRes = { export type StoreIdentity = { url: string - name?: string + name: string } export type Marketplace = Record diff --git a/web/projects/shared/assets/img/community-store.png b/web/projects/shared/assets/img/community-icon.png similarity index 100% rename from web/projects/shared/assets/img/community-store.png rename to web/projects/shared/assets/img/community-icon.png diff --git a/web/projects/shared/assets/img/icon_alpha.png b/web/projects/shared/assets/img/icon_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..cf8dc42c49a48021b6239dc60d79fbfd00461e19 GIT binary patch literal 53404 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

ywJ0Bz>@V4t&!XZ8R8 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 xqvsAxetW$lT;|VX;vLelxaIf{y)fv8>IjM literal 0 HcmV?d00001 diff --git a/web/projects/shared/assets/img/storefront-outline.png b/web/projects/shared/assets/img/storefront-outline.png index aa7bd440493aac3fe53df067f6dc7382e6771c33..3de3f1c8634535eb071161048a16aecccaa3454a 100644 GIT binary patch literal 43384 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%0A_NXo6Ex(q7RNZv>`P@e?aNe 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 Ae*gdg diff --git a/web/projects/shared/src/types/workspace-config.ts b/web/projects/shared/src/types/workspace-config.ts index eced51db1..cf4cf0578 100644 --- a/web/projects/shared/src/types/workspace-config.ts +++ b/web/projects/shared/src/types/workspace-config.ts @@ -7,11 +7,6 @@ export type WorkspaceConfig = { url: string version: string } - marketplace: MarketplaceConfig - startosRegistry: - | 'https://alpha-registry-x.start9.com/' - | 'https://beta-registry.start9.com/' - | 'https://registry.start9.com/' mocks: { maskAs: 'tor' | 'local' | 'localhost' | 'ipv4' | 'ipv6' | 'clearnet' maskAsHttps: boolean @@ -20,7 +15,13 @@ export type WorkspaceConfig = { } } -export interface MarketplaceConfig { - start9: 'https://registry.start9.com/' - community: 'https://community-registry.start9.com/' -} +export const defaultRegistries = { + start9: 'https://registry.start9.com/', + community: 'https://community-registry.start9.com/', +} as const + +export const knownRegistries = { + ...defaultRegistries, + start9Alpha: 'https://alpha-registry-x.start9.com/', + start9Beta: 'https://beta-registry.start9.com/', +} as const diff --git a/web/projects/ui/src/app/routes/portal/routes/marketplace/components/controls.component.ts b/web/projects/ui/src/app/routes/portal/routes/marketplace/components/controls.component.ts index 0abef3b10..f8b651001 100644 --- a/web/projects/ui/src/app/routes/portal/routes/marketplace/components/controls.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/marketplace/components/controls.component.ts @@ -127,8 +127,8 @@ export class MarketplaceControlsComponent { async tryInstall() { const currentUrl = this.file ? null - : await firstValueFrom(this.marketplaceService.getRegistryUrl$()) - const originalUrl = this.localPkg?.registry || '' + : await firstValueFrom(this.marketplaceService.getCurrentRegistryUrl$()) + const originalUrl = this.localPkg?.registry || null if (!this.localPkg) { if (await this.alerts.alertInstall(this.pkg)) { diff --git a/web/projects/ui/src/app/routes/portal/routes/marketplace/components/menu.component.ts b/web/projects/ui/src/app/routes/portal/routes/marketplace/components/menu.component.ts index 1efb24bc2..ccb3a666b 100644 --- a/web/projects/ui/src/app/routes/portal/routes/marketplace/components/menu.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/marketplace/components/menu.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core' import { CommonModule } from '@angular/common' import { MenuModule } from '@start9labs/marketplace' import { TuiIcon, TuiButton, TuiAppearance } from '@taiga-ui/core' -import { ConfigService } from 'src/app/services/config.service' import { MARKETPLACE_REGISTRY } from '../modals/registry.component' import { MarketplaceService } from 'src/app/services/marketplace.service' import { DialogService, i18nPipe } from '@start9labs/shared' @@ -11,7 +10,7 @@ import { DialogService, i18nPipe } from '@start9labs/shared' standalone: true, selector: 'marketplace-menu', template: ` - + @@ -53,19 +45,18 @@ import { IST, utils } from '@start9labs/start-sdk'
{{ 'Add custom registry' | i18n }}
- @for (registry of stores.alt; track $index) { + @for (registry of registries.alt; track $index) {
@@ -103,26 +94,28 @@ export class MarketplaceRegistryModal { private readonly marketplaceService = inject(MarketplaceService) private readonly context = injectContext() private readonly router = inject(Router) - private readonly hosts$ = inject>(PatchDB).watch$( + private readonly rawRegistries$ = inject>(PatchDB).watch$( 'ui', - 'marketplace', - 'knownHosts', + 'registries', ) private readonly i18n = inject(i18nPipe) - readonly marketplaceConfig = inject(ConfigService).marketplace + private readonly storage = inject(StorageService) - readonly stores$ = combineLatest([ - this.marketplaceService.getKnownHosts$(), - this.marketplaceService.getRegistryUrl$(), + readonly registries$ = combineLatest([ + this.marketplaceService.getRegistries$(), + this.marketplaceService.getCurrentRegistryUrl$(), ]).pipe( - map(([stores, selectedUrl]) => - stores.map(s => ({ + map(([registries, currentUrl]) => + registries.map(s => ({ ...s, - selected: sameUrl(s.url, selectedUrl), + selected: sameUrl(s.url, currentUrl), })), ), // 0 and 1 are prod and community, 2 and beyond are alts - map(stores => ({ standard: stores.slice(0, 2), alt: stores.slice(2) })), + map(registries => ({ + standard: registries.slice(0, 2), + alt: registries.slice(2), + })), ) add() { @@ -147,7 +140,7 @@ export class MarketplaceRegistryModal { }) } - delete(url: string, name: string = '') { + delete(url: string) { this.dialog .openConfirm({ label: 'Confirm', @@ -161,19 +154,21 @@ export class MarketplaceRegistryModal { .pipe(filter(Boolean)) .subscribe(async () => { const loader = this.loader.open('Deleting').subscribe() - const hosts = await firstValueFrom(this.hosts$) - const filtered: { [url: string]: UIStore } = Object.keys(hosts) + const rawRegistries = await firstValueFrom(this.rawRegistries$) + const filtered: { [url: string]: string | null } = Object.keys( + rawRegistries, + ) .filter(key => !sameUrl(key, url)) .reduce( (prev, curr) => ({ ...prev, - [curr]: hosts[curr], + [curr]: rawRegistries[curr], }), {}, ) try { - await this.api.setDbValue(['marketplace', 'knownHosts'], filtered) + await this.api.setDbValue(['registries'], filtered) } catch (e: any) { this.errorService.handleError(e) } finally { @@ -195,7 +190,7 @@ export class MarketplaceRegistryModal { queryParams: { registry: url }, queryParamsHandling: 'merge', }) - this.api.setDbValue(['marketplace', 'selectedUrl'], url) + this.storage.set('selectedRegistry', url) this.context.$implicit.complete() } catch (e: any) { this.errorService.handleError(e) @@ -255,8 +250,8 @@ export class MarketplaceRegistryModal { loader: Subscription, ): Promise { // Error on duplicates - const hosts = await firstValueFrom(this.hosts$) - const currentUrls = Object.keys(hosts).map(toUrl) + const rawRegistries = await firstValueFrom(this.rawRegistries$) + const currentUrls = Object.keys(rawRegistries).map(toUrl) if (currentUrls.includes(url)) throw new Error(this.i18n.transform('Registry already added')) @@ -274,7 +269,7 @@ export class MarketplaceRegistryModal { loader.closed = false loader.add(this.loader.open('Saving').subscribe()) - await this.api.setDbValue(['marketplace', 'knownHosts', url], { name }) + await this.api.setDbValue(['altRegistries', url], name) } } diff --git a/web/projects/ui/src/app/routes/portal/routes/marketplace/services/alerts.service.ts b/web/projects/ui/src/app/routes/portal/routes/marketplace/services/alerts.service.ts index a108442c2..3f4f8a14e 100644 --- a/web/projects/ui/src/app/routes/portal/routes/marketplace/services/alerts.service.ts +++ b/web/projects/ui/src/app/routes/portal/routes/marketplace/services/alerts.service.ts @@ -1,29 +1,30 @@ import { inject, Injectable } from '@angular/core' import { MarketplacePkgBase } from '@start9labs/marketplace' -import { PatchDB } from 'patch-db-client' import { defaultIfEmpty, firstValueFrom } from 'rxjs' -import { DataModel } from 'src/app/services/patch-db/data-model' import { DialogService, i18nKey, i18nPipe } from '@start9labs/shared' +import { MarketplaceService } from 'src/app/services/marketplace.service' @Injectable({ providedIn: 'root', }) export class MarketplaceAlertsService { private readonly dialog = inject(DialogService) - private readonly marketplace$ = inject>(PatchDB).watch$( - 'ui', - 'marketplace', - ) + private readonly marketplaceService = inject(MarketplaceService) private readonly i18n = inject(i18nPipe) - async alertMarketplace(url: string, originalUrl: string): Promise { - const marketplaces = await firstValueFrom(this.marketplace$) - const name = marketplaces.knownHosts[url]?.name || url - const source = marketplaces.knownHosts[originalUrl]?.name || originalUrl - const message = source - ? `${this.i18n.transform('installed from')} ${source}` + async alertMarketplace( + url: string, + originalUrl: string | null, + ): Promise { + const registries = await firstValueFrom( + this.marketplaceService.getRegistries$(), + ) + const message = originalUrl + ? `${this.i18n.transform('installed from')} ${registries.find(h => h.url === originalUrl) || originalUrl}` : this.i18n.transform('sideloaded') + const currentName = registries.find(h => h.url === url) || url + return new Promise(async resolve => { this.dialog .openConfirm({ @@ -31,7 +32,7 @@ export class MarketplaceAlertsService { size: 's', data: { content: - `${this.i18n.transform('This service was originally')} ${message}, ${this.i18n.transform('but you are currently connected to')} ${name}. ${this.i18n.transform('To install from')} ${name} ${this.i18n.transform('anyway, click "Continue".')}` as i18nKey, + `${this.i18n.transform('This service was originally')} ${message}, ${this.i18n.transform('but you are currently connected to')} ${currentName}. ${this.i18n.transform('To install from')} ${currentName} ${this.i18n.transform('anyway, click "Continue".')}` as i18nKey, yes: 'Continue', no: 'Cancel', }, diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/acme/acme.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/acme/acme.component.ts index 905bad0fb..c295ac9c7 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/acme/acme.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/acme/acme.component.ts @@ -205,7 +205,6 @@ export default class SystemAcmeComponent { } private async saveAcme(providerUrl: string, contact: string[]) { - console.log(providerUrl, contact) const loader = this.loader.open('Saving').subscribe() try { diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/general.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/general.component.ts index 7bb817ad4..d78a0e8da 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/general.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/general.component.ts @@ -242,10 +242,9 @@ export default class SystemGeneralComponent { readonly translation: TuiStringHandler> = ({ $implicit, }) => this.i18n.transform($implicit)! - readonly score = toSignal( - this.patch.watch$('ui', 'gaming', 'snake', 'highScore'), - { initialValue: 0 }, - ) + readonly score = toSignal(this.patch.watch$('ui', 'snakeHighScore'), { + initialValue: 0, + }) get language(): Languages | undefined { return this.languages.find(lang => lang === this.i18nService.language) diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/snek.directive.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/snek.directive.ts index 120970a80..3a02c16cb 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/snek.directive.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/snek.directive.ts @@ -37,10 +37,7 @@ export class SnekDirective { const loader = this.loader.open('Saving high score').subscribe() try { - await this.api.setDbValue( - ['gaming', 'snake', 'highScore'], - score, - ) + await this.api.setDbValue(['snakeHighScore'], score) } catch (e: any) { this.errorService.handleError(e) } finally { diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/update.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/update.component.ts index 719ff0969..3226b6e28 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/general/update.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/general/update.component.ts @@ -16,6 +16,9 @@ import { TuiDialogContext, TuiScrollbar, TuiButton } from '@taiga-ui/core' import { NgDompurifyModule } from '@tinkoff/ng-dompurify' import { ApiService } from 'src/app/services/api/embassy-api.service' import { OSService } from 'src/app/services/os.service' +import { PatchDB } from 'patch-db-client' +import { DataModel } from 'src/app/services/patch-db/data-model' +import { firstValueFrom } from 'rxjs' @Component({ template: ` @@ -61,13 +64,19 @@ export class SystemUpdateModal { private readonly errorService: ErrorService, private readonly embassyApi: ApiService, private readonly os: OSService, + private readonly patch: PatchDB, ) {} async update() { const loader = this.loader.open('Beginning update').subscribe() + const { startosRegistry } = await firstValueFrom(this.patch.watch$('ui')) + try { - await this.embassyApi.updateServer() + await this.embassyApi.updateServer({ + targetVersion: `=${this.versions[0]!.version}`, + registry: startosRegistry, + }) this.context.$implicit.complete() } catch (e: any) { this.errorService.handleError(e) diff --git a/web/projects/ui/src/app/routes/portal/routes/updates/updates.component.ts b/web/projects/ui/src/app/routes/portal/routes/updates/updates.component.ts index 5a3f513de..33ea5f289 100644 --- a/web/projects/ui/src/app/routes/portal/routes/updates/updates.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/updates/updates.component.ts @@ -22,7 +22,6 @@ import { TuiCell } from '@taiga-ui/layout' import { PatchDB } from 'patch-db-client' import { combineLatest, map, tap } from 'rxjs' import { TableComponent } from 'src/app/routes/portal/components/table.component' -import { ConfigService } from 'src/app/services/config.service' import { MarketplaceService } from 'src/app/services/marketplace.service' import { DataModel, @@ -66,7 +65,7 @@ interface UpdatesData { (click)="current.set(registry)" > - + {{ registry.name }} @@ -221,15 +220,17 @@ export default class UpdatesComponent { private readonly isMobile = inject(TUI_IS_MOBILE) private readonly marketplaceService = inject(MarketplaceService) - readonly mp = inject(ConfigService).marketplace readonly current = signal(null) readonly data = toSignal( combineLatest({ hosts: this.marketplaceService - .getKnownHosts$(true) + .getRegistries$(true) .pipe( - tap(([store]) => !this.isMobile && store && this.current.set(store)), + tap( + ([registry]) => + !this.isMobile && registry && this.current.set(registry), + ), ), marketplace: this.marketplaceService.marketplace$, localPkgs: inject>(PatchDB) diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index e77dab33b..fac8d0be6 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -30,7 +30,7 @@ export namespace Mock { shuttingDown: false, } - export const RegistryOSUpdate: RR.GetRegistryOsUpdateRes = { + export const RegistryOSUpdate: RR.CheckOsUpdateRes = { '0.3.6-alpha.17': { headline: 'v0.3.6-alpha.17', releaseNotes: '', @@ -101,16 +101,16 @@ export namespace Mock { }, img: {}, }, - '0.4.0-alpha.0': { - headline: 'v0.4.0-alpha.0', + '0.4.0-alpha.1': { + headline: 'v0.4.0-alpha.1', releaseNotes: '', - sourceVersion: '>=0.3.5:0 <=0.4.0-alpha.0:0', + sourceVersion: '>=0.3.5:0 <=0.4.0-alpha.1:0', authorized: ['G24CSA5HNYEPIXJNMK7ZM4KD5SX5N6X4'], iso: {}, squashfs: { aarch64: { publishedAt: '2025-04-21T20:58:48.140749883Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.0/startos-0.4.0-alpha.0-33ae46f~dev_aarch64.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.1/startos-0.4.0-alpha.1-33ae46f~dev_aarch64.squashfs', commitment: { hash: '4elBFVkd/r8hNadKmKtLIs42CoPltMvKe2z3LRqkphk=', size: 1343500288, @@ -122,7 +122,7 @@ export namespace Mock { }, 'aarch64-nonfree': { publishedAt: '2025-04-21T21:07:00.249285116Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.0/startos-0.4.0-alpha.0-33ae46f~dev_aarch64-nonfree.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.1/startos-0.4.0-alpha.1-33ae46f~dev_aarch64-nonfree.squashfs', commitment: { hash: 'MrCEi4jxbmPS7zAiGk/JSKlMsiuKqQy6RbYOxlGHOIQ=', size: 1653075968, @@ -134,7 +134,7 @@ export namespace Mock { }, raspberrypi: { publishedAt: '2025-04-21T21:16:12.933319237Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.0/startos-0.4.0-alpha.0-33ae46f~dev_raspberrypi.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.1/startos-0.4.0-alpha.1-33ae46f~dev_raspberrypi.squashfs', commitment: { hash: '/XTVQRCqY3RK544PgitlKu7UplXjkmzWoXUh2E4HCw0=', size: 1490731008, @@ -146,7 +146,7 @@ export namespace Mock { }, x86_64: { publishedAt: '2025-04-21T21:14:20.246908903Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.0/startos-0.4.0-alpha.0-33ae46f~dev_x86_64.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.1/startos-0.4.0-alpha.1-33ae46f~dev_x86_64.squashfs', commitment: { hash: '/6romKTVQGSaOU7FqSZdw0kFyd7P+NBSYNwM3q7Fe44=', size: 1411657728, @@ -158,7 +158,7 @@ export namespace Mock { }, 'x86_64-nonfree': { publishedAt: '2025-04-21T21:15:17.955265284Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.0/startos-0.4.0-alpha.0-33ae46f~dev_x86_64-nonfree.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.1/startos-0.4.0-alpha.1-33ae46f~dev_x86_64-nonfree.squashfs', commitment: { hash: 'HCRq9sr/0t85pMdrEgNBeM4x11zVKHszGnD1GDyZbSE=', size: 1731035136, @@ -179,27 +179,21 @@ export namespace Mock { categories: { bitcoin: { name: 'Bitcoin', - description: mockDescription, }, featured: { name: 'Featured', - description: mockDescription, }, lightning: { name: 'Lightning', - description: mockDescription, }, communications: { name: 'Communications', - description: mockDescription, }, data: { name: 'Data', - description: mockDescription, }, ai: { name: 'AI', - description: mockDescription, }, }, } diff --git a/web/projects/ui/src/app/services/api/api.types.ts b/web/projects/ui/src/app/services/api/api.types.ts index 8c696b1f4..2cda22b7c 100644 --- a/web/projects/ui/src/app/services/api/api.types.ts +++ b/web/projects/ui/src/app/services/api/api.types.ts @@ -3,6 +3,12 @@ import { DataModel } from 'src/app/services/patch-db/data-model' import { StartOSDiskInfo, FetchLogsReq, FetchLogsRes } from '@start9labs/shared' import { IST, T } from '@start9labs/start-sdk' import { WebSocketSubjectConfig } from 'rxjs/webSocket' +import { + GetPackageReq, + GetPackageRes, + GetPackagesReq, + GetPackagesRes, +} from '@start9labs/marketplace' export namespace RR { // websocket @@ -86,7 +92,7 @@ export namespace RR { metrics: ServerMetrics } - export type UpdateServerReq = { registry: string } // server.update + export type UpdateServerReq = { registry: string; targetVersion: string } // server.update export type UpdateServerRes = 'updating' | 'no-updates' export type RestartServerReq = {} // server.restart @@ -362,8 +368,17 @@ export namespace RR { // registry /** these are returned in ASCENDING order. the newest available version will be the LAST in the object */ - export type CheckOSUpdateReq = { serverId: string } - export type GetRegistryOsUpdateRes = { [version: string]: T.OsVersionInfo } + export type CheckOsUpdateReq = { registry: string; serverId: string } + export type CheckOsUpdateRes = { [version: string]: T.OsVersionInfo } + + export type GetRegistryInfoReq = { registry: string } + export type GetRegistryInfoRes = T.RegistryInfo + + export type GetRegistryPackageReq = GetPackageReq & { registry: string } + export type GetRegistryPackageRes = GetPackageRes + + export type GetRegistryPackagesReq = GetPackagesReq & { registry: string } + export type GetRegistryPackagesRes = GetPackagesRes } export type Breakages = { diff --git a/web/projects/ui/src/app/services/api/embassy-api.service.ts b/web/projects/ui/src/app/services/api/embassy-api.service.ts index 2aec7d40d..fe309ac65 100644 --- a/web/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-api.service.ts @@ -1,9 +1,4 @@ -import { - GetPackageRes, - GetPackagesRes, - MarketplacePkg, -} from '@start9labs/marketplace' -import { RPCOptions } from '@start9labs/shared' +import { MarketplacePkg } from '@start9labs/marketplace' import { T } from '@start9labs/start-sdk' import { RR } from './api.types' import { WebSocketSubject } from 'rxjs/webSocket' @@ -113,7 +108,7 @@ export abstract class ApiService { params: RR.FollowServerMetricsReq, ): Promise - abstract updateServer(url?: string): Promise + abstract updateServer(params: RR.UpdateServerReq): Promise abstract restartServer( params: RR.RestartServerReq, @@ -145,24 +140,21 @@ export abstract class ApiService { // marketplace URLs - abstract registryRequest( - registryUrl: string, - options: RPCOptions, - ): Promise - abstract checkOSUpdate( - qp: RR.CheckOSUpdateReq, - ): Promise + params: RR.CheckOsUpdateReq, + ): Promise - abstract getRegistryInfo(registryUrl: string): Promise + abstract getRegistryInfo( + params: RR.GetRegistryInfoReq, + ): Promise abstract getRegistryPackage( - url: string, - id: string, - versionRange: string | null, - ): Promise + params: RR.GetRegistryPackageReq, + ): Promise - abstract getRegistryPackages(registryUrl: string): Promise + abstract getRegistryPackages( + params: RR.GetRegistryPackagesReq, + ): Promise // notification diff --git a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts index 2fc56270c..88e8e428c 100644 --- a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -10,7 +10,6 @@ import { import { PATCH_CACHE } from 'src/app/services/patch-db/patch-db-source' import { ApiService } from './embassy-api.service' import { RR } from './api.types' -import { ConfigService } from '../config.service' import { webSocket, WebSocketSubject } from 'rxjs/webSocket' import { Observable, filter, firstValueFrom } from 'rxjs' import { AuthService } from '../auth.service' @@ -18,13 +17,7 @@ import { DOCUMENT } from '@angular/common' import { DataModel } from '../patch-db/data-model' import { Dump, pathFromArray } from 'patch-db-client' import { T } from '@start9labs/start-sdk' -import { - GetPackageReq, - GetPackageRes, - GetPackagesReq, - GetPackagesRes, - MarketplacePkg, -} from '@start9labs/marketplace' +import { MarketplacePkg } from '@start9labs/marketplace' import { blake3 } from '@noble/hashes/blake3' @Injectable() @@ -32,7 +25,6 @@ export class LiveApiService extends ApiService { constructor( @Inject(DOCUMENT) private readonly document: Document, private readonly http: HttpService, - private readonly config: ConfigService, private readonly auth: AuthService, @Inject(PATCH_CACHE) private readonly cache$: Observable>, ) { @@ -248,10 +240,7 @@ export class LiveApiService extends ApiService { return this.rpcRequest({ method: 'server.metrics.follow', params }) } - async updateServer(url?: string): Promise { - const params = { - registry: url || this.config.startosRegistry, - } + async updateServer(params: RR.UpdateServerReq): Promise { return this.rpcRequest({ method: 'server.update', params }) } @@ -283,61 +272,38 @@ export class LiveApiService extends ApiService { // marketplace URLs - async registryRequest( - registryUrl: string, - options: RPCOptions, - ): Promise { - return this.rpcRequest({ - ...options, - method: `registry.${options.method}`, - params: { registry: registryUrl, ...options.params }, - }) - } - async checkOSUpdate( - qp: RR.CheckOSUpdateReq, - ): Promise { - const { serverId } = qp - - return this.registryRequest(this.config.startosRegistry, { - method: 'os.version.get', - params: { serverId }, - }) - } - - async getRegistryInfo(registryUrl: string): Promise { - return this.registryRequest(registryUrl, { - method: 'info', - params: {}, - }) - } - - async getRegistryPackage( - registryUrl: string, - id: string, - versionRange: string | null, - ): Promise { - const params: GetPackageReq = { - id, - version: versionRange, - otherVersions: 'short', - } - - return this.registryRequest(registryUrl, { - method: 'package.get', + params: RR.CheckOsUpdateReq, + ): Promise { + return this.rpcRequest({ + method: 'registry.os.version.get', params, }) } - async getRegistryPackages(registryUrl: string): Promise { - const params: GetPackagesReq = { - id: null, - version: null, - otherVersions: 'short', - } + async getRegistryInfo( + params: RR.GetRegistryInfoReq, + ): Promise { + return this.rpcRequest({ + method: 'registry.info', + params, + }) + } - return this.registryRequest(registryUrl, { - method: 'package.get', + async getRegistryPackage( + params: RR.GetRegistryPackageReq, + ): Promise { + return this.rpcRequest({ + method: 'registry.package.get', + params, + }) + } + + async getRegistryPackages( + params: RR.GetRegistryPackagesReq, + ): Promise { + return this.rpcRequest({ + method: 'registry.package.get', params, }) } diff --git a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 458cd309e..9014c48d5 100644 --- a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -169,6 +169,7 @@ export class MockApiService extends ApiService { pathArr: Array, value: T, ): Promise { + console.warn(pathArr, value) const pointer = pathFromArray(pathArr) const params: RR.SetDBValueReq = { pointer, value } await pauseFor(2000) @@ -367,7 +368,7 @@ export class MockApiService extends ApiService { } } - async updateServer(url?: string): Promise { + async updateServer(params?: RR.UpdateServerReq): Promise { await pauseFor(2000) const initialProgress = { size: null, @@ -475,41 +476,37 @@ export class MockApiService extends ApiService { // marketplace URLs - async registryRequest( - registryUrl: string, - options: RPCOptions, - ): Promise { - await pauseFor(2000) - - return Error('do not call directly') - } - async checkOSUpdate( - qp: RR.CheckOSUpdateReq, - ): Promise { + params: RR.CheckOsUpdateReq, + ): Promise { await pauseFor(2000) return Mock.RegistryOSUpdate } - async getRegistryInfo(registryUrl: string): Promise { + async getRegistryInfo( + params: RR.GetRegistryInfoReq, + ): Promise { await pauseFor(2000) return Mock.RegistryInfo } async getRegistryPackage( - url: string, - id: string, - versionRange: string, - ): Promise { + params: RR.GetRegistryPackageReq, + ): Promise { await pauseFor(2000) - if (!versionRange || versionRange === '=*') { + + const { targetVersion, id } = params + + if (!targetVersion || targetVersion === '=*') { return Mock.RegistryPackages[id]! } else { - return Mock.OtherPackageVersions[id]![versionRange]! + return Mock.OtherPackageVersions[id]![targetVersion]! } } - async getRegistryPackages(registryUrl: string): Promise { + async getRegistryPackages( + params: RR.GetRegistryPackagesReq, + ): Promise { await pauseFor(2000) return Mock.RegistryPackages } diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 005eb62b7..3e3fe7beb 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -6,26 +6,14 @@ const version = require('../../../../../../package.json').version export const mockPatchData: DataModel = { ui: { name: `Matt's Server`, - theme: 'Dark', - marketplace: { - selectedUrl: 'https://registry.start9.com/', - knownHosts: { - 'https://registry.start9.com/': { - name: 'Start9 Registry', - }, - 'https://community-registry.start9.com/': {}, - 'https://beta-registry.start9.com/': { - name: 'Dark9', - }, - }, + registries: { + 'https://registry.start9.com/': 'Start9 Registry', + 'https://community-registry.start9.com/': 'Community Registry', }, - gaming: { - snake: { - highScore: 0, - }, - }, - language: 'english', + startosRegistry: 'https://registry.start9.com/', + snakeHighScore: 0, ackInstructions: {}, + language: 'english', }, serverInfo: { arch: 'x86_64', diff --git a/web/projects/ui/src/app/services/config.service.ts b/web/projects/ui/src/app/services/config.service.ts index 2ed5b8eaf..e11bf78f1 100644 --- a/web/projects/ui/src/app/services/config.service.ts +++ b/web/projects/ui/src/app/services/config.service.ts @@ -7,7 +7,7 @@ import { PackageDataEntry } from './patch-db/data-model' const { gitHash, useMocks, - ui: { api, marketplace, mocks, startosRegistry }, + ui: { api, mocks }, } = require('../../../../../config.json') as WorkspaceConfig @Injectable({ @@ -26,8 +26,6 @@ export class ConfigService { mocks = mocks gitHash = gitHash api = api - marketplace = marketplace - startosRegistry = startosRegistry skipStartupAlerts = useMocks && mocks.skipStartupAlerts supportsWebSockets = !!window.WebSocket diff --git a/web/projects/ui/src/app/services/marketplace.service.ts b/web/projects/ui/src/app/services/marketplace.service.ts index b879c1ae8..6fcc25f5b 100644 --- a/web/projects/ui/src/app/services/marketplace.service.ts +++ b/web/projects/ui/src/app/services/marketplace.service.ts @@ -7,7 +7,7 @@ import { StoreDataWithUrl, StoreIdentity, } from '@start9labs/marketplace' -import { Exver, sameUrl } from '@start9labs/shared' +import { Exver, defaultRegistries, sameUrl } from '@start9labs/shared' import { T } from '@start9labs/start-sdk' import { PatchDB } from 'patch-db-client' import { @@ -31,32 +31,28 @@ import { } from 'rxjs' import { RR } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { DataModel, UIStore } from 'src/app/services/patch-db/data-model' +import { DataModel } from 'src/app/services/patch-db/data-model' import { ClientStorageService } from './client-storage.service' -import { ConfigService } from './config.service' + +const { start9, community } = defaultRegistries @Injectable({ providedIn: 'root', }) export class MarketplaceService { - private readonly registryUrlSubject$ = new ReplaySubject(1) - private readonly registryUrl$ = this.registryUrlSubject$.pipe( + private readonly currentRegistryUrlSubject$ = new ReplaySubject(1) + private readonly currentRegistryUrl$ = this.currentRegistryUrlSubject$.pipe( distinctUntilChanged(), ) - private readonly registry$: Observable = - this.registryUrl$.pipe( + private readonly currentRegistry$: Observable = + this.currentRegistryUrl$.pipe( switchMap(url => this.fetchRegistry$(url)), filter(Boolean), map(registry => { - // @TODO Aiden let's drop description. We do not use it. categories should just be Record registry.info.categories = { all: { name: 'All', - description: { - short: 'All registry packages', - long: 'An unfiltered list of all packages available on this registry.', - }, }, ...registry.info.categories, } @@ -66,36 +62,27 @@ export class MarketplaceService { shareReplay(1), ) - private readonly knownHosts$: Observable = this.patch - .watch$('ui', 'marketplace', 'knownHosts') + private readonly registries$: Observable = this.patch + .watch$('ui', 'registries') .pipe( - map(hosts => { - const { start9, community } = this.config.marketplace - let arr = [ - toStoreIdentity(start9, hosts[start9]), - toStoreIdentity(community, { - ...hosts[community], - name: 'Community Registry', - }), - ] - - return arr.concat( - Object.entries(hosts) - .filter(([url, _]) => ![start9, community].includes(url as any)) - .map(([url, store]) => toStoreIdentity(url, store)), - ) - }), + map(registries => [ + toStoreIdentity(start9, registries[start9]), + toStoreIdentity(community, registries[community]), + ...Object.entries(registries) + .filter(([url, _]) => ![start9, community].includes(url as any)) + .map(([url, name]) => toStoreIdentity(url, name)), + ]), ) - private readonly filteredKnownHosts$: Observable = + private readonly filteredRegistries$: Observable = combineLatest([ this.clientStorageService.showDevTools$, - this.knownHosts$, + this.registries$, ]).pipe( - map(([devMode, knownHosts]) => + map(([devMode, registries]) => devMode - ? knownHosts - : knownHosts.filter( + ? registries + : registries.filter( ({ url }) => !url.includes('alpha') && !url.includes('beta'), ), ), @@ -103,7 +90,7 @@ export class MarketplaceService { private readonly requestErrors$ = new BehaviorSubject([]) - readonly marketplace$: Observable = this.knownHosts$.pipe( + readonly marketplace$: Observable = this.registries$.pipe( startWith([]), pairwise(), mergeMap(([prev, curr]) => @@ -112,7 +99,8 @@ export class MarketplaceService { mergeMap(({ url, name }) => this.fetchRegistry$(url).pipe( tap(data => { - if (data?.info.name) this.updateStoreName(url, name, data.info.name) + if (data?.info.name) + this.updateRegistryName(url, name, data.info.name) }), map(data => [url, data]), startWith<[string, StoreData | null]>([url, null]), @@ -132,27 +120,25 @@ export class MarketplaceService { constructor( private readonly api: ApiService, private readonly patch: PatchDB, - private readonly config: ConfigService, private readonly clientStorageService: ClientStorageService, private readonly exver: Exver, ) {} - getKnownHosts$(filtered = false): Observable { + getRegistries$(filtered = false): Observable { // option to filter out hosts containing 'alpha' or 'beta' substrings in registryURL - return filtered ? this.filteredKnownHosts$ : this.knownHosts$ + return filtered ? this.filteredRegistries$ : this.registries$ } - getRegistryUrl$() { - return this.registryUrl$ + getCurrentRegistryUrl$() { + return this.currentRegistryUrl$ } - setRegistryUrl(url: string | null) { - const registryUrl = url || this.config.marketplace.start9 - this.registryUrlSubject$.next(registryUrl) + setRegistryUrl(url: string) { + this.currentRegistryUrlSubject$.next(url) } - getRegistry$(): Observable { - return this.registry$ + getCurrentRegistry$(): Observable { + return this.currentRegistry$ } getPackage$( @@ -161,7 +147,7 @@ export class MarketplaceService { flavor: string | null, registryUrl?: string, ): Observable { - return this.registry$.pipe( + return this.currentRegistry$.pipe( switchMap(registry => { const url = registryUrl || registry.url const pkg = registry.packages.find( @@ -176,17 +162,12 @@ export class MarketplaceService { } fetchInfo$(url: string): Observable { - return from(this.api.getRegistryInfo(url)).pipe( + return from(this.api.getRegistryInfo({ registry: url })).pipe( map(info => ({ ...info, - // @TODO Aiden let's drop description. We do not use it. categories should just be Record categories: { all: { name: 'All', - description: { - short: '', - long: '', - }, }, ...info.categories, }, @@ -202,7 +183,7 @@ export class MarketplaceService { } private fetchRegistry$(url: string): Observable { - console.log('FETCHING REGISTRY: ', url) + console.warn('FETCHING REGISTRY: ', url) return combineLatest([this.fetchInfo$(url), this.fetchPackages$(url)]).pipe( map(([info, packages]) => ({ info, packages, url })), catchError(e => { @@ -214,7 +195,14 @@ export class MarketplaceService { } private fetchPackages$(url: string): Observable { - return from(this.api.getRegistryPackages(url)).pipe( + return from( + this.api.getRegistryPackages({ + registry: url, + id: null, + targetVersion: null, + otherVersions: 'short', + }), + ).pipe( map(packages => { return Object.entries(packages).flatMap(([id, pkgInfo]) => Object.keys(pkgInfo.best).map(version => @@ -237,7 +225,12 @@ export class MarketplaceService { flavor: string | null, ): Observable { return from( - this.api.getRegistryPackage(url, id, version ? `=${version}` : null), + this.api.getRegistryPackage({ + registry: url, + id, + targetVersion: version ? `=${version}` : null, + otherVersions: 'short', + }), ).pipe( map(pkgInfo => this.convertRegistryPkgToMarketplacePkg(id, version, flavor, pkgInfo), @@ -288,23 +281,21 @@ export class MarketplaceService { await this.api.installPackage(params) } - private async updateStoreName( + private async updateRegistryName( url: string, - oldName: string | undefined, + oldName: string | null, newName: string, ): Promise { + console.warn(oldName, newName) if (oldName !== newName) { - this.api.setDbValue( - ['marketplace', 'knownHosts', url, 'name'], - newName, - ) + this.api.setDbValue(['registries', url], newName) } } } -function toStoreIdentity(url: string, uiStore: UIStore): StoreIdentity { +function toStoreIdentity(url: string, name?: string | null): StoreIdentity { return { url, - ...uiStore, + name: name || url, } } diff --git a/web/projects/ui/src/app/services/os.service.ts b/web/projects/ui/src/app/services/os.service.ts index f88d558e9..aea7ac21c 100644 --- a/web/projects/ui/src/app/services/os.service.ts +++ b/web/projects/ui/src/app/services/os.service.ts @@ -1,6 +1,12 @@ import { Injectable } from '@angular/core' import { PatchDB } from 'patch-db-client' -import { BehaviorSubject, distinctUntilChanged, map, combineLatest } from 'rxjs' +import { + BehaviorSubject, + distinctUntilChanged, + map, + combineLatest, + firstValueFrom, +} from 'rxjs' import { ApiService } from 'src/app/services/api/embassy-api.service' import { getServerInfo } from 'src/app/utils/get-server-info' import { DataModel } from './patch-db/data-model' @@ -11,7 +17,7 @@ import { RR } from './api/api.types' providedIn: 'root', }) export class OSService { - osUpdate?: RR.GetRegistryOsUpdateRes + osUpdate?: RR.CheckOsUpdateRes updateAvailable$ = new BehaviorSubject(false) readonly updating$ = this.patch.watch$('serverInfo', 'statusInfo').pipe( @@ -47,7 +53,12 @@ export class OSService { async loadOS(): Promise { const { version, id } = await getServerInfo(this.patch) - this.osUpdate = await this.api.checkOSUpdate({ serverId: id }) + const { startosRegistry } = await firstValueFrom(this.patch.watch$('ui')) + + this.osUpdate = await this.api.checkOSUpdate({ + registry: startosRegistry, + serverId: id, + }) const [latestVersion, _] = Object.entries(this.osUpdate).at(-1)! const updateAvailable = Version.parse(latestVersion).compare(Version.parse(version)) === 'greater' diff --git a/web/projects/ui/src/app/services/patch-db/data-model.ts b/web/projects/ui/src/app/services/patch-db/data-model.ts index 5c8731167..7b50028f3 100644 --- a/web/projects/ui/src/app/services/patch-db/data-model.ts +++ b/web/projects/ui/src/app/services/patch-db/data-model.ts @@ -5,30 +5,13 @@ export type DataModel = T.Public & { ui: UIData; packageData: AllPackageData } export type UIData = { name: string | null - marketplace: UIMarketplaceData - gaming: { - snake: { - highScore: number - } - } + registries: Record ackInstructions: Record - theme: string + snakeHighScore: number + startosRegistry: string language: Languages } -export type UIMarketplaceData = { - selectedUrl: string - knownHosts: { - 'https://registry.start9.com/': UIStore - 'https://community-registry.start9.com/': UIStore - [url: string]: UIStore - } -} - -export type UIStore = { - name?: string -} - export type NetworkInfo = T.NetworkInfo & { // @TODO 041 // start9To: {