mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
Feature/fe new registry (#2647)
* bugfixes * update fe types * implement new registry types in marketplace and ui * fix marketplace types to have default params * add alt implementation toggle * merge cleanup * more cleanup and notes * fix build * cleanup sync with next/minor * add exver JS parser * parse ValidExVer to string * update types to interface * add VersionRange and comparative functions * Parse ExtendedVersion from string * add conjunction, disjunction, and inversion logic * consider flavor in satisfiedBy fn * consider prerelease for ordering * add compare fn for sorting * rename fns for consistency * refactoring * update compare fn to return null if flavors don't match * begin simplifying dependencies * under construction * wip * add dependency metadata to CurrentDependencyInfo * ditch inheritance for recursive VersionRange constructor. Recursive 'satisfiedBy' fn wip * preprocess manifest * misc fixes * use sdk version as osVersion in manifest * chore: Change the type to just validate and not generate all solutions. * add publishedAt * fix pegjs exports * integrate exver into sdk * misc fixes * complete satisfiedBy fn * refactor - use greaterThanOrEqual and lessThanOrEqual fns * fix tests * update dependency details * update types * remove interim types * rename alt implementation to flavor * cleanup os update * format exver.ts * add s9pk parsing endpoints * fix build * update to exver * exver and bug fixes * update static endpoints + cleanup * cleanup * update static proxy verification * make mocks more robust; fix dep icon fallback; cleanup * refactor alert versions and update fixtures * registry bugfixes * misc fixes * cleanup unused * convert patchdb ui seed to camelCase * update otherVersions type * change otherVersions: null to 'none' * refactor and complete feature * improve static endpoints * fix install params * mask systemd-networkd-wait-online * fix static file fetching * include non-matching versions in otherVersions * convert release notes to modal and clean up displayExver * alert for no other versions * Fix ack-instructions casing * fix indeterminate loader on service install --------- Co-authored-by: Aiden McClelland <me@drbonez.dev> Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me> Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Co-authored-by: J H <dragondef@gmail.com> Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
@@ -6,10 +6,10 @@ use imbl_value::InternedString;
|
||||
use models::{mime, DataUrl, PackageId};
|
||||
use tokio::fs::File;
|
||||
|
||||
use crate::dependencies::DependencyMetadata;
|
||||
use crate::prelude::*;
|
||||
use crate::registry::signer::commitment::merkle_archive::MerkleArchiveCommitment;
|
||||
use crate::s9pk::manifest::Manifest;
|
||||
use crate::s9pk::merkle_archive::file_contents::FileContents;
|
||||
use crate::s9pk::merkle_archive::sink::Sink;
|
||||
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
|
||||
use crate::s9pk::merkle_archive::source::{
|
||||
@@ -18,6 +18,7 @@ use crate::s9pk::merkle_archive::source::{
|
||||
use crate::s9pk::merkle_archive::{Entry, MerkleArchive};
|
||||
use crate::s9pk::v2::pack::{ImageSource, PackSource};
|
||||
use crate::util::io::{open_file, TmpDir};
|
||||
use crate::util::serde::IoFormat;
|
||||
|
||||
const MAGIC_AND_VERSION: &[u8] = &[0x3b, 0x3b, 0x02];
|
||||
|
||||
@@ -33,6 +34,10 @@ pub mod pack;
|
||||
├── icon.<ext>
|
||||
├── LICENSE.md
|
||||
├── instructions.md
|
||||
├── dependencies
|
||||
│ └── <id>
|
||||
│ ├── metadata.json
|
||||
│ └── icon.<ext>
|
||||
├── javascript.squashfs
|
||||
├── assets
|
||||
│ └── <id>.squashfs (xN)
|
||||
@@ -52,9 +57,10 @@ fn priority(s: &str) -> Option<usize> {
|
||||
a if Path::new(a).file_stem() == Some(OsStr::new("icon")) => Some(1),
|
||||
"LICENSE.md" => Some(2),
|
||||
"instructions.md" => Some(3),
|
||||
"javascript.squashfs" => Some(4),
|
||||
"assets" => Some(5),
|
||||
"images" => Some(6),
|
||||
"dependencies" => Some(4),
|
||||
"javascript.squashfs" => Some(5),
|
||||
"assets" => Some(6),
|
||||
"images" => Some(7),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -101,22 +107,16 @@ impl<S: FileSource + Clone> S9pk<S> {
|
||||
filter.keep_checked(self.archive.contents_mut())
|
||||
}
|
||||
|
||||
pub async fn icon(&self) -> Result<(InternedString, FileContents<S>), Error> {
|
||||
pub async fn icon(&self) -> Result<(InternedString, Entry<S>), Error> {
|
||||
let mut best_icon = None;
|
||||
for (path, icon) in self
|
||||
.archive
|
||||
.contents()
|
||||
.with_stem("icon")
|
||||
.filter(|(p, _)| {
|
||||
Path::new(&*p)
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.and_then(mime)
|
||||
.map_or(false, |e| e.starts_with("image/"))
|
||||
})
|
||||
.filter_map(|(k, v)| v.into_file().map(|f| (k, f)))
|
||||
{
|
||||
let size = icon.size().await?;
|
||||
for (path, icon) in self.archive.contents().with_stem("icon").filter(|(p, v)| {
|
||||
Path::new(&*p)
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.and_then(mime)
|
||||
.map_or(false, |e| e.starts_with("image/") && v.as_file().is_some())
|
||||
}) {
|
||||
let size = icon.expect_file()?.size().await?;
|
||||
best_icon = match best_icon {
|
||||
Some((s, a)) if s >= size => Some((s, a)),
|
||||
_ => Some((size, (path, icon))),
|
||||
@@ -134,7 +134,75 @@ impl<S: FileSource + Clone> S9pk<S> {
|
||||
.and_then(|e| e.to_str())
|
||||
.and_then(mime)
|
||||
.unwrap_or("image/png");
|
||||
DataUrl::from_reader(mime, contents.reader().await?, Some(contents.size().await?)).await
|
||||
Ok(DataUrl::from_vec(
|
||||
mime,
|
||||
contents.expect_file()?.to_vec(contents.hash()).await?,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn dependency_icon(
|
||||
&self,
|
||||
id: &PackageId,
|
||||
) -> Result<Option<(InternedString, Entry<S>)>, Error> {
|
||||
let mut best_icon = None;
|
||||
for (path, icon) in self
|
||||
.archive
|
||||
.contents()
|
||||
.get_path(Path::new("dependencies").join(id))
|
||||
.and_then(|p| p.as_directory())
|
||||
.into_iter()
|
||||
.flat_map(|d| {
|
||||
d.with_stem("icon").filter(|(p, v)| {
|
||||
Path::new(&*p)
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.and_then(mime)
|
||||
.map_or(false, |e| e.starts_with("image/") && v.as_file().is_some())
|
||||
})
|
||||
})
|
||||
{
|
||||
let size = icon.expect_file()?.size().await?;
|
||||
best_icon = match best_icon {
|
||||
Some((s, a)) if s >= size => Some((s, a)),
|
||||
_ => Some((size, (path, icon))),
|
||||
};
|
||||
}
|
||||
Ok(best_icon.map(|(_, a)| a))
|
||||
}
|
||||
|
||||
pub async fn dependency_icon_data_url(
|
||||
&self,
|
||||
id: &PackageId,
|
||||
) -> Result<Option<DataUrl<'static>>, Error> {
|
||||
let Some((name, contents)) = self.dependency_icon(id).await? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let mime = Path::new(&*name)
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.and_then(mime)
|
||||
.unwrap_or("image/png");
|
||||
Ok(Some(DataUrl::from_vec(
|
||||
mime,
|
||||
contents.expect_file()?.to_vec(contents.hash()).await?,
|
||||
)))
|
||||
}
|
||||
|
||||
pub async fn dependency_metadata(
|
||||
&self,
|
||||
id: &PackageId,
|
||||
) -> Result<Option<DependencyMetadata>, Error> {
|
||||
if let Some(entry) = self
|
||||
.archive
|
||||
.contents()
|
||||
.get_path(Path::new("dependencies").join(id).join("metadata.json"))
|
||||
{
|
||||
Ok(Some(IoFormat::Json.from_slice(
|
||||
&entry.expect_file()?.to_vec(entry.hash()).await?,
|
||||
)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn serialize<W: Sink>(&mut self, w: &mut W, verify: bool) -> Result<(), Error> {
|
||||
|
||||
Reference in New Issue
Block a user