🔨 chore: format
This commit is contained in:
parent
7b486a59a7
commit
646d8dc14c
25 changed files with 394 additions and 372 deletions
|
|
@ -139,7 +139,6 @@ sys-info = { version = "0.9" }
|
|||
whoami = { version = "1.5" }
|
||||
cocoa = { version = "0.25" }
|
||||
objc = { version = "0.2" }
|
||||
|
||||
webbrowser = { version = "1.0" }
|
||||
url = { version = "2.5.2" }
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
"directory": "apps/desktop"
|
||||
},
|
||||
"scripts": {
|
||||
"tauri": "tauri",
|
||||
"dev": "vite dev",
|
||||
"build": "vite build"
|
||||
"tauri": "pnpm tauri",
|
||||
"dev": "pnpm vite dev",
|
||||
"build": "pnpm vite build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/poppins": "^5.0.14",
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
"@solidjs/router": "^0.14.1",
|
||||
"@tanstack/solid-query": "^5.51.9",
|
||||
"@tauri-apps/api": "^2.0.0-beta.13",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.5",
|
||||
"@tauri-apps/plugin-clipboard-manager": "github:tauri-apps/tauri-plugin-clipboard-manager#v2",
|
||||
"@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2",
|
||||
"@thisbeyond/solid-dnd": "^0.7.5",
|
||||
"@thisbeyond/solid-select": "^0.15.0",
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ fn main() {
|
|||
"set_settings",
|
||||
// Metadata
|
||||
"get_minecraft_versions",
|
||||
// Package
|
||||
"random_mods",
|
||||
"get_mod",
|
||||
"download_mod",
|
||||
// Package
|
||||
"random_mods",
|
||||
"get_mod",
|
||||
"download_mod",
|
||||
// Other
|
||||
"get_program_info",
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ macro_rules! collect_commands {
|
|||
set_settings,
|
||||
// Metadata
|
||||
get_minecraft_versions,
|
||||
// Package
|
||||
random_mods,
|
||||
get_mod,
|
||||
download_mod,
|
||||
// Package
|
||||
random_mods,
|
||||
get_mod,
|
||||
download_mod,
|
||||
// Other
|
||||
get_program_info,
|
||||
])
|
||||
|
|
@ -110,14 +110,14 @@ pub async fn run_cluster(uuid: Uuid) -> Result<(Uuid, u32), String> {
|
|||
.id()
|
||||
.unwrap_or(0);
|
||||
|
||||
// tokio::task::spawn(async move {
|
||||
// let mut proc = c_lock.write().await;
|
||||
// tokio::task::spawn(async move {
|
||||
// let mut proc = c_lock.write().await;
|
||||
// if let Err(err) = processor::wait_for(&mut proc).await {
|
||||
// tracing::error!("Error waiting for process: {:?}", err);
|
||||
// };
|
||||
// });
|
||||
// tracing::error!("Error waiting for process: {:?}", err);
|
||||
// };
|
||||
// });
|
||||
|
||||
// let mut proc = c_lock.write().await;
|
||||
// let mut proc = c_lock.write().await;
|
||||
// processor::wait_for(&mut proc).await?;
|
||||
|
||||
Ok((p_uuid, p_pid))
|
||||
|
|
@ -252,31 +252,34 @@ pub async fn remove_user(uuid: Uuid) -> Result<(), String> {
|
|||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn random_mods() -> Result<Vec<ManagedPackage>, String> {
|
||||
let provider = content::Providers::Modrinth;
|
||||
Ok(provider.list().await?)
|
||||
let provider = content::Providers::Modrinth;
|
||||
Ok(provider.list().await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_mod(project_id: String) -> Result<ManagedPackage, String> {
|
||||
let provider = content::Providers::Modrinth;
|
||||
Ok(provider.get(&project_id).await?)
|
||||
let provider = content::Providers::Modrinth;
|
||||
Ok(provider.get(&project_id).await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn download_mod(cluster_id: Uuid, version_id: String) -> Result<(), String> {
|
||||
let cluster = cluster::get_by_uuid(cluster_id, None).await?.ok_or("cluster not found")?;
|
||||
let provider = content::Providers::Modrinth;
|
||||
let game_version = cluster.meta.mc_version.clone();
|
||||
let cluster = cluster::get_by_uuid(cluster_id, None)
|
||||
.await?
|
||||
.ok_or("cluster not found")?;
|
||||
let provider = content::Providers::Modrinth;
|
||||
let game_version = cluster.meta.mc_version.clone();
|
||||
|
||||
provider.get_version_for_game_version(&version_id, &game_version)
|
||||
.await?
|
||||
.files
|
||||
.first()
|
||||
.ok_or("no files found")?
|
||||
.download_to_cluster(&cluster)
|
||||
.await?;
|
||||
provider
|
||||
.get_version_for_game_version(&version_id, &game_version)
|
||||
.await?
|
||||
.files
|
||||
.first()
|
||||
.ok_or("no files found")?
|
||||
.download_to_cluster(&cluster)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,23 +79,18 @@ export function ClusterModalController(props: ParentProps) {
|
|||
|
||||
setVisible(false);
|
||||
|
||||
try {
|
||||
await bridge.commands.createCluster({
|
||||
name: untracked.name!,
|
||||
mod_loader: untracked.mod_loader!,
|
||||
mc_version: untracked.mc_version!,
|
||||
// TODO: Implement the rest of the fields
|
||||
icon: null,
|
||||
icon_url: null,
|
||||
loader_version: null,
|
||||
package_data: null,
|
||||
skip: null,
|
||||
skip_watch: null,
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
await bridge.commands.createCluster({
|
||||
name: untracked.name!,
|
||||
mod_loader: untracked.mod_loader!,
|
||||
mc_version: untracked.mc_version!,
|
||||
// TODO: Implement the rest of the fields
|
||||
icon: null,
|
||||
icon_url: null,
|
||||
loader_version: null,
|
||||
package_data: null,
|
||||
skip: null,
|
||||
skip_watch: null,
|
||||
});
|
||||
|
||||
setInProgress(false);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { A } from '@solidjs/router';
|
||||
import { Download01Icon, FileCode01Icon, FilterLinesIcon, SearchMdIcon } from '@untitled-theme/icons-solid';
|
||||
import { For, createEffect, createSignal, onMount } from 'solid-js';
|
||||
import { For, createSignal, onMount } from 'solid-js';
|
||||
import type { ManagedPackage } from '~bindings';
|
||||
import { bridge } from '~imports';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Dropdown from '~ui/components/base/Dropdown';
|
||||
import TextField from '~ui/components/base/TextField';
|
||||
import ModCard, { Provider } from '~ui/components/content/ModCard';
|
||||
import useCommand, { tryResult } from '~ui/hooks/useCommand';
|
||||
import { tryResult } from '~ui/hooks/useCommand';
|
||||
import createSortable from '~utils/sorting';
|
||||
|
||||
interface CardProps {
|
||||
|
|
@ -23,7 +23,7 @@ interface BrowserFilters {
|
|||
}
|
||||
|
||||
function BrowserMain() {
|
||||
const [filters, setFilters] = createSignal<BrowserFilters>({
|
||||
const [_filters, _setFilters] = createSignal<BrowserFilters>({
|
||||
provider: [Provider.Curseforge],
|
||||
});
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ function BrowserMain() {
|
|||
tryResult(bridge.commands.getMod, 'oneconfig'),
|
||||
tryResult(bridge.commands.getMod, 'chatting'),
|
||||
tryResult(bridge.commands.getMod, 'patcher'),
|
||||
]).then((res) => {
|
||||
]).then((res: ManagedPackage[]) => {
|
||||
const list: ModsRowProps[] = [
|
||||
{
|
||||
header: 'Polyfrost',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { type Params, useSearchParams } from '@solidjs/router';
|
||||
import { Download01Icon } from '@untitled-theme/icons-solid';
|
||||
import { For, Match, Switch, createSignal, onMount } from 'solid-js';
|
||||
import { For, createSignal, onMount } from 'solid-js';
|
||||
import { bridge } from '~imports';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Dropdown from '~ui/components/base/Dropdown';
|
||||
|
|
@ -16,7 +16,7 @@ interface BrowserModParams extends Params {
|
|||
// TODO: Refactor the entire browser page and subpages
|
||||
function BrowserMod() {
|
||||
const [params] = useSearchParams<BrowserModParams>();
|
||||
const isInvalid = !params.id || !params.provider;
|
||||
const _isInvalid = !params.id || !params.provider;
|
||||
const [visible, setVisible] = createSignal(false);
|
||||
const [cluster, setCluster] = createSignal<string>();
|
||||
const [clusters, setClusters] = createSignal<[string, string][]>();
|
||||
|
|
@ -28,9 +28,7 @@ function BrowserMod() {
|
|||
|
||||
function download() {
|
||||
setVisible(false);
|
||||
tryResult(bridge.commands.downloadMod, cluster()!, params.id!).then((res) => {
|
||||
console.log('finished');
|
||||
}).catch(err => console.error(err));
|
||||
tryResult(bridge.commands.downloadMod, cluster()!, params.id!).then().catch(err => console.error(err));
|
||||
}
|
||||
|
||||
function onChange(selected: number) {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-solid';
|
|||
|
||||
function ClusterLogs() {
|
||||
const [params] = useSearchParams();
|
||||
const [logs] = createResource(params.id, async (uuid: string) => {
|
||||
const [logs] = createResource(params.id, async (_uuid: string) => {
|
||||
return [] as string[];
|
||||
});
|
||||
|
||||
const [activeLogFile, setActiveLogFile] = createSignal<string | null>(null);
|
||||
const [log, setLog] = createSignal<string | null>(null);
|
||||
const [log, _setLog] = createSignal<string | null>(null);
|
||||
|
||||
// createEffect(() => {
|
||||
// const log = logs()?.[0];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ArrowRightIcon, ChevronDownIcon, ChevronUpIcon, Edit02Icon, SearchMdIcon, Trash03Icon } from '@untitled-theme/icons-solid';
|
||||
import { For, Match, Switch, createSignal, onMount } from 'solid-js';
|
||||
import * as uuid from 'uuid';
|
||||
import uFuzzy from '@leeoniya/ufuzzy';
|
||||
import UFuzzy from '@leeoniya/ufuzzy';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import TextField from '~ui/components/base/TextField';
|
||||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
|
|
@ -40,7 +40,7 @@ function ClusterMods() {
|
|||
// true - `A to Z` & false - `Z to A`
|
||||
const [sortingAtoZ, setSortingAtoZ] = createSignal<boolean>(true);
|
||||
|
||||
const uf = new uFuzzy();
|
||||
const uf = new UFuzzy();
|
||||
const [modsSearchable] = createSignal(() => mods().map(mod => mod.name));
|
||||
|
||||
function search(value: string) {
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ function DeleteModal(props: DeleteModalProps) {
|
|||
|
||||
function Banner(props: Cluster & { showDeletePrompt: () => void }) {
|
||||
async function launch() {
|
||||
const [uuid, pid] = await tryResult(bridge.commands.runCluster, props.uuid);
|
||||
const [_uuid, _pid] = await tryResult(bridge.commands.runCluster, props.uuid);
|
||||
|
||||
console.log(uuid, pid);
|
||||
// console.log(uuid, pid);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ function SettingsAccounts() {
|
|||
if (data.status === 'ok') {
|
||||
// @ts-expect-error -- aa
|
||||
window.tempData = data.data;
|
||||
console.log('set');
|
||||
// console.log('set');
|
||||
}
|
||||
else {
|
||||
console.log(data.error);
|
||||
// console.log(data.error);
|
||||
}
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
use anyhow::anyhow;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{data::{ManagedPackage, ManagedVersion}, Result};
|
||||
use crate::data::{ManagedPackage, ManagedVersion};
|
||||
use crate::Result;
|
||||
|
||||
mod modrinth;
|
||||
|
||||
|
|
@ -13,64 +14,83 @@ mod modrinth;
|
|||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
|
||||
pub enum Providers {
|
||||
// Curseforge,
|
||||
Modrinth,
|
||||
// Curseforge,
|
||||
Modrinth,
|
||||
}
|
||||
|
||||
impl Providers {
|
||||
/// Get the name of the provider
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
// Providers::Curseforge => "Curseforge",
|
||||
Providers::Modrinth => "Modrinth",
|
||||
}
|
||||
}
|
||||
/// Get the name of the provider
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
// Providers::Curseforge => "Curseforge",
|
||||
Providers::Modrinth => "Modrinth",
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the URL of the provider
|
||||
pub fn url(&self) -> &str {
|
||||
match self {
|
||||
// Providers::Curseforge => "https://curseforge.com/",
|
||||
Providers::Modrinth => "https://modrinth.com",
|
||||
}
|
||||
}
|
||||
/// Get the URL of the provider
|
||||
pub fn url(&self) -> &str {
|
||||
match self {
|
||||
// Providers::Curseforge => "https://curseforge.com/",
|
||||
Providers::Modrinth => "https://modrinth.com",
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list(&self) -> Result<Vec<ManagedPackage>> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::list(),
|
||||
Providers::Modrinth => modrinth::list(),
|
||||
}.await?.into_iter().map(|p| p.into()).collect())
|
||||
}
|
||||
pub async fn list(&self) -> Result<Vec<ManagedPackage>> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::list(),
|
||||
Providers::Modrinth => modrinth::list(),
|
||||
}
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|p| p.into())
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub async fn get(&self, slug_or_id: &str) -> Result<ManagedPackage> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get(slug),
|
||||
Providers::Modrinth => modrinth::get(slug_or_id),
|
||||
}.await?.into())
|
||||
}
|
||||
pub async fn get(&self, slug_or_id: &str) -> Result<ManagedPackage> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get(slug),
|
||||
Providers::Modrinth => modrinth::get(slug_or_id),
|
||||
}
|
||||
.await?
|
||||
.into())
|
||||
}
|
||||
|
||||
pub async fn get_versions(&self, project_id: &str) -> Result<Vec<ManagedVersion>> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get_versions(slug),
|
||||
Providers::Modrinth => modrinth::get_versions(project_id),
|
||||
}.await?.into_iter().map(|p| p.into()).collect())
|
||||
}
|
||||
pub async fn get_versions(&self, project_id: &str) -> Result<Vec<ManagedVersion>> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get_versions(slug),
|
||||
Providers::Modrinth => modrinth::get_versions(project_id),
|
||||
}
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|p| p.into())
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub async fn get_version(&self, version_id: &str) -> Result<ManagedVersion> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get_version(slug, version),
|
||||
Providers::Modrinth => modrinth::get_version(version_id),
|
||||
}.await?.into())
|
||||
}
|
||||
pub async fn get_version(&self, version_id: &str) -> Result<ManagedVersion> {
|
||||
Ok(match self {
|
||||
// Providers::Curseforge => curseforge::get_version(slug, version),
|
||||
Providers::Modrinth => modrinth::get_version(version_id),
|
||||
}
|
||||
.await?
|
||||
.into())
|
||||
}
|
||||
|
||||
pub async fn get_version_for_game_version(&self, id: &str, game_version: &str) -> Result<ManagedVersion> {
|
||||
let versions = self.get_versions(id).await?;
|
||||
Ok(versions.into_iter().find(|v| v.game_versions.contains(&game_version.to_string())).ok_or(anyhow!("no game version found"))?) // TODO: error handling
|
||||
}
|
||||
pub async fn get_version_for_game_version(
|
||||
&self,
|
||||
id: &str,
|
||||
game_version: &str,
|
||||
) -> Result<ManagedVersion> {
|
||||
let versions = self.get_versions(id).await?;
|
||||
Ok(versions
|
||||
.into_iter()
|
||||
.find(|v| v.game_versions.contains(&game_version.to_string()))
|
||||
.ok_or(anyhow!("no game version found"))?) // TODO: error handling
|
||||
}
|
||||
|
||||
// pub async fn search(&self, query: &str) -> Result<Vec<ManagedPackage>> {
|
||||
// match self {
|
||||
// // Providers::Curseforge => curseforge::search(query),
|
||||
// Providers::Modrinth => modrinth::search(query),
|
||||
// }.await
|
||||
// }
|
||||
}
|
||||
// pub async fn search(&self, query: &str) -> Result<Vec<ManagedPackage>> {
|
||||
// match self {
|
||||
// // Providers::Curseforge => curseforge::search(query),
|
||||
// Providers::Modrinth => modrinth::search(query),
|
||||
// }.await
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::data::{ManagedPackage, ManagedVersion, PackageType};
|
||||
use crate::package::from::MODRINTH_API_URL;
|
||||
use crate::store::{ManagedVersionFile, PackageFile, PackageSide};
|
||||
use crate::utils::http::fetch;
|
||||
use crate::{State, Result};
|
||||
use crate::data::{ManagedPackage, ManagedVersion, PackageType};
|
||||
use crate::{Result, State};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use chrono::{DateTime, Utc};
|
||||
|
|
@ -12,118 +12,118 @@ use serde_json::Value;
|
|||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModrinthPackage {
|
||||
pub slug: String,
|
||||
pub title: String,
|
||||
#[serde(default)]
|
||||
pub description: String,
|
||||
#[serde(default)]
|
||||
pub categories: Vec<String>,
|
||||
#[serde(rename = "client_side")]
|
||||
pub client_side: PackageSide,
|
||||
#[serde(rename = "server_side")]
|
||||
pub server_side: PackageSide,
|
||||
// #[serde(default)]
|
||||
// pub body: String,
|
||||
// #[serde(default)]
|
||||
// pub status: String,
|
||||
// #[serde(default)]
|
||||
// #[serde(rename = "requested_status")]
|
||||
// pub requested_status: String,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "additional_categories")]
|
||||
pub additional_categories: Vec<String>,
|
||||
// #[serde(rename = "issues_url")]
|
||||
// pub issues_url: String,
|
||||
// #[serde(rename = "source_url")]
|
||||
// pub source_url: String,
|
||||
// #[serde(rename = "wiki_url")]
|
||||
// pub wiki_url: String,
|
||||
// #[serde(rename = "discord_url")]
|
||||
// pub discord_url: String,
|
||||
// #[serde(rename = "donation_urls")]
|
||||
// pub donation_urls: Vec<DonationUrl>,
|
||||
// #[serde(rename = "project_type")]
|
||||
// pub project_type: String,
|
||||
pub downloads: u32,
|
||||
#[serde(rename = "icon_url")]
|
||||
#[serde(default)]
|
||||
pub icon_url: String,
|
||||
// pub color: i64,
|
||||
// #[serde(rename = "thread_id")]
|
||||
// pub thread_id: String,
|
||||
// #[serde(rename = "monetization_status")]
|
||||
// pub monetization_status: String,
|
||||
pub id: String,
|
||||
// pub team: String,
|
||||
// #[serde(rename = "body_url")]
|
||||
// pub body_url: Value,
|
||||
// #[serde(rename = "moderator_message")]
|
||||
// pub moderator_message: Value,
|
||||
pub published: DateTime<Utc>,
|
||||
pub updated: DateTime<Utc>,
|
||||
// pub approved: DateTime<Utc>,
|
||||
// pub queued: String,
|
||||
pub followers: u32,
|
||||
// pub license: License,
|
||||
#[serde(default)]
|
||||
pub versions: Vec<String>,
|
||||
#[serde(rename = "game_versions")]
|
||||
pub game_versions: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub loaders: Vec<String>,
|
||||
// pub gallery: Vec<Gallery>,
|
||||
pub slug: String,
|
||||
pub title: String,
|
||||
#[serde(default)]
|
||||
pub description: String,
|
||||
#[serde(default)]
|
||||
pub categories: Vec<String>,
|
||||
#[serde(rename = "client_side")]
|
||||
pub client_side: PackageSide,
|
||||
#[serde(rename = "server_side")]
|
||||
pub server_side: PackageSide,
|
||||
// #[serde(default)]
|
||||
// pub body: String,
|
||||
// #[serde(default)]
|
||||
// pub status: String,
|
||||
// #[serde(default)]
|
||||
// #[serde(rename = "requested_status")]
|
||||
// pub requested_status: String,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "additional_categories")]
|
||||
pub additional_categories: Vec<String>,
|
||||
// #[serde(rename = "issues_url")]
|
||||
// pub issues_url: String,
|
||||
// #[serde(rename = "source_url")]
|
||||
// pub source_url: String,
|
||||
// #[serde(rename = "wiki_url")]
|
||||
// pub wiki_url: String,
|
||||
// #[serde(rename = "discord_url")]
|
||||
// pub discord_url: String,
|
||||
// #[serde(rename = "donation_urls")]
|
||||
// pub donation_urls: Vec<DonationUrl>,
|
||||
// #[serde(rename = "project_type")]
|
||||
// pub project_type: String,
|
||||
pub downloads: u32,
|
||||
#[serde(rename = "icon_url")]
|
||||
#[serde(default)]
|
||||
pub icon_url: String,
|
||||
// pub color: i64,
|
||||
// #[serde(rename = "thread_id")]
|
||||
// pub thread_id: String,
|
||||
// #[serde(rename = "monetization_status")]
|
||||
// pub monetization_status: String,
|
||||
pub id: String,
|
||||
// pub team: String,
|
||||
// #[serde(rename = "body_url")]
|
||||
// pub body_url: Value,
|
||||
// #[serde(rename = "moderator_message")]
|
||||
// pub moderator_message: Value,
|
||||
pub published: DateTime<Utc>,
|
||||
pub updated: DateTime<Utc>,
|
||||
// pub approved: DateTime<Utc>,
|
||||
// pub queued: String,
|
||||
pub followers: u32,
|
||||
// pub license: License,
|
||||
#[serde(default)]
|
||||
pub versions: Vec<String>,
|
||||
#[serde(rename = "game_versions")]
|
||||
pub game_versions: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub loaders: Vec<String>,
|
||||
// pub gallery: Vec<Gallery>,
|
||||
}
|
||||
|
||||
impl From<ModrinthPackage> for ManagedPackage {
|
||||
fn from(value: ModrinthPackage) -> ManagedPackage {
|
||||
ManagedPackage {
|
||||
id: value.id,
|
||||
title: value.title,
|
||||
description: value.description,
|
||||
main: value.slug,
|
||||
versions: value.versions,
|
||||
game_versions: value.game_versions,
|
||||
loaders: value.loaders,
|
||||
icon_url: Some(value.icon_url),
|
||||
created: value.published,
|
||||
updated: value.updated,
|
||||
client: value.client_side,
|
||||
server: value.server_side,
|
||||
downloads: value.downloads,
|
||||
followers: value.followers,
|
||||
categories: value.categories,
|
||||
optional_categories: Some(value.additional_categories),
|
||||
uid: None,
|
||||
package_type: PackageType::Mod,
|
||||
}
|
||||
}
|
||||
fn from(value: ModrinthPackage) -> ManagedPackage {
|
||||
ManagedPackage {
|
||||
id: value.id,
|
||||
title: value.title,
|
||||
description: value.description,
|
||||
main: value.slug,
|
||||
versions: value.versions,
|
||||
game_versions: value.game_versions,
|
||||
loaders: value.loaders,
|
||||
icon_url: Some(value.icon_url),
|
||||
created: value.published,
|
||||
updated: value.updated,
|
||||
client: value.client_side,
|
||||
server: value.server_side,
|
||||
downloads: value.downloads,
|
||||
followers: value.followers,
|
||||
categories: value.categories,
|
||||
optional_categories: Some(value.additional_categories),
|
||||
uid: None,
|
||||
package_type: PackageType::Mod,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DonationUrl {
|
||||
pub id: String,
|
||||
pub platform: String,
|
||||
pub url: String,
|
||||
pub id: String,
|
||||
pub platform: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct License {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Gallery {
|
||||
pub url: String,
|
||||
pub featured: bool,
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub created: String,
|
||||
pub ordering: i64,
|
||||
pub url: String,
|
||||
pub featured: bool,
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub created: String,
|
||||
pub ordering: i64,
|
||||
}
|
||||
|
||||
macro_rules! format_url {
|
||||
|
|
@ -133,144 +133,143 @@ macro_rules! format_url {
|
|||
}
|
||||
|
||||
pub async fn list() -> Result<Vec<ModrinthPackage>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/projects_random?count=10").as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore
|
||||
).await?
|
||||
)?)
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/projects_random?count=10").as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore,
|
||||
)
|
||||
.await?,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub async fn get(id: &str) -> Result<ModrinthPackage> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/project/{}", id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore
|
||||
).await?
|
||||
)?)
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/project/{}", id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore,
|
||||
)
|
||||
.await?,
|
||||
)?)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct SearchResults {
|
||||
hits: Vec<ModrinthPackage>,
|
||||
hits: Vec<ModrinthPackage>,
|
||||
}
|
||||
|
||||
pub async fn search(
|
||||
query: &str,
|
||||
) -> Result<Vec<ModrinthPackage>> {
|
||||
// TODO: Fix date_created and date_updated inconsistency (published and updated)
|
||||
let response: SearchResults = serde_json::from_slice(
|
||||
pub async fn search(query: &str) -> Result<Vec<ModrinthPackage>> {
|
||||
// TODO: Fix date_created and date_updated inconsistency (published and updated)
|
||||
let response: SearchResults = serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/search?query={}", query).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore
|
||||
).await?,
|
||||
format_url!("/search?query={}", query).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore,
|
||||
)
|
||||
.await?,
|
||||
)?;
|
||||
|
||||
Ok(response.hits)
|
||||
Ok(response.hits)
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModrinthVersion {
|
||||
#[serde(rename = "game_versions")]
|
||||
pub game_versions: Vec<String>,
|
||||
pub loaders: Vec<String>,
|
||||
pub id: String,
|
||||
#[serde(rename = "project_id")]
|
||||
pub project_id: String,
|
||||
#[serde(rename = "author_id")]
|
||||
pub author_id: String,
|
||||
pub featured: bool,
|
||||
pub name: String,
|
||||
#[serde(rename = "version_number")]
|
||||
pub version_number: String,
|
||||
pub changelog: String,
|
||||
#[serde(rename = "changelog_url")]
|
||||
pub changelog_url: Option<String>,
|
||||
#[serde(rename = "date_published")]
|
||||
pub date_published: DateTime<Utc>,
|
||||
pub downloads: u32,
|
||||
#[serde(rename = "version_type")]
|
||||
pub version_type: String,
|
||||
pub status: String,
|
||||
#[serde(rename = "requested_status")]
|
||||
pub requested_status: Value,
|
||||
pub files: Vec<File>,
|
||||
pub dependencies: Vec<Value>,
|
||||
#[serde(rename = "game_versions")]
|
||||
pub game_versions: Vec<String>,
|
||||
pub loaders: Vec<String>,
|
||||
pub id: String,
|
||||
#[serde(rename = "project_id")]
|
||||
pub project_id: String,
|
||||
#[serde(rename = "author_id")]
|
||||
pub author_id: String,
|
||||
pub featured: bool,
|
||||
pub name: String,
|
||||
#[serde(rename = "version_number")]
|
||||
pub version_number: String,
|
||||
pub changelog: String,
|
||||
#[serde(rename = "changelog_url")]
|
||||
pub changelog_url: Option<String>,
|
||||
#[serde(rename = "date_published")]
|
||||
pub date_published: DateTime<Utc>,
|
||||
pub downloads: u32,
|
||||
#[serde(rename = "version_type")]
|
||||
pub version_type: String,
|
||||
pub status: String,
|
||||
#[serde(rename = "requested_status")]
|
||||
pub requested_status: Value,
|
||||
pub files: Vec<File>,
|
||||
pub dependencies: Vec<Value>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct File {
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub primary: bool,
|
||||
pub size: u32,
|
||||
#[serde(rename = "file_type")]
|
||||
pub file_type: Option<PackageFile>,
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub primary: bool,
|
||||
pub size: u32,
|
||||
#[serde(rename = "file_type")]
|
||||
pub file_type: Option<PackageFile>,
|
||||
}
|
||||
|
||||
impl From<File> for ManagedVersionFile {
|
||||
fn from(value: File) -> Self {
|
||||
ManagedVersionFile {
|
||||
url: value.url,
|
||||
file_name: value.filename,
|
||||
primary: value.primary,
|
||||
size: value.size,
|
||||
file_type: value.file_type,
|
||||
hashes: Default::default(), // TODO
|
||||
}
|
||||
}
|
||||
fn from(value: File) -> Self {
|
||||
ManagedVersionFile {
|
||||
url: value.url,
|
||||
file_name: value.filename,
|
||||
primary: value.primary,
|
||||
size: value.size,
|
||||
file_type: value.file_type,
|
||||
hashes: Default::default(), // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ModrinthVersion> for ManagedVersion {
|
||||
fn from(value: ModrinthVersion) -> Self {
|
||||
ManagedVersion {
|
||||
id: value.id,
|
||||
package_id: value.project_id,
|
||||
author: value.author_id,
|
||||
name: value.name,
|
||||
|
||||
featured: value.featured,
|
||||
version_id: value.version_number,
|
||||
changelog: value.changelog,
|
||||
changelog_url: value.changelog_url,
|
||||
|
||||
published: value.date_published,
|
||||
downloads: value.downloads,
|
||||
version_type: value.version_type,
|
||||
|
||||
files: value.files.into_iter().map(|f| f.into()).collect(),
|
||||
deps: vec![], // TODO [`ManagedDependency`]?
|
||||
game_versions: value.game_versions,
|
||||
loaders: value.loaders,
|
||||
}
|
||||
}
|
||||
fn from(value: ModrinthVersion) -> Self {
|
||||
ManagedVersion {
|
||||
id: value.id,
|
||||
package_id: value.project_id,
|
||||
author: value.author_id,
|
||||
name: value.name,
|
||||
|
||||
featured: value.featured,
|
||||
version_id: value.version_number,
|
||||
changelog: value.changelog,
|
||||
changelog_url: value.changelog_url,
|
||||
|
||||
published: value.date_published,
|
||||
downloads: value.downloads,
|
||||
version_type: value.version_type,
|
||||
|
||||
files: value.files.into_iter().map(|f| f.into()).collect(),
|
||||
deps: vec![], // TODO [`ManagedDependency`]?
|
||||
game_versions: value.game_versions,
|
||||
loaders: value.loaders,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_versions(
|
||||
project_id: &str,
|
||||
) -> Result<Vec<ModrinthVersion>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/project/{}/version", project_id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore
|
||||
).await?
|
||||
)?)
|
||||
pub async fn get_versions(project_id: &str) -> Result<Vec<ModrinthVersion>> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/project/{}/version", project_id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore,
|
||||
)
|
||||
.await?,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub async fn get_version(
|
||||
version_id: &str,
|
||||
) -> Result<ModrinthVersion> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/version/{}", version_id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore
|
||||
).await?
|
||||
)?)
|
||||
}
|
||||
pub async fn get_version(version_id: &str) -> Result<ModrinthVersion> {
|
||||
Ok(serde_json::from_slice(
|
||||
&fetch(
|
||||
format_url!("/version/{}", version_id).as_str(),
|
||||
None,
|
||||
&State::get().await?.fetch_semaphore,
|
||||
)
|
||||
.await?,
|
||||
)?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
//!
|
||||
//! Utilities for importing packages from and to OneLauncher.
|
||||
|
||||
pub mod content;
|
||||
pub mod from;
|
||||
pub mod import;
|
||||
pub mod mrpack;
|
||||
pub mod zip;
|
||||
pub mod content;
|
||||
|
|
@ -366,7 +366,7 @@ pub async fn launch_minecraft(
|
|||
)
|
||||
.current_dir(instance_path.clone());
|
||||
|
||||
println!("command: {:#?}", command);
|
||||
println!("command: {:#?}", command);
|
||||
|
||||
// when cargo makes the DYLD_LIBRARY_PATH it breaks Minecraft
|
||||
#[cfg(target_os = "macos")]
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
//! Global Package Metadata management.
|
||||
|
|
@ -46,8 +46,6 @@ pub use self::package::*;
|
|||
mod oneconfig;
|
||||
pub use self::oneconfig::*;
|
||||
|
||||
mod flags;
|
||||
|
||||
/// The static [`OnceCell<RwLock<State>>`] for storing the global runtime launcher state.
|
||||
static LAUNCHER_STATE: OnceCell<RwLock<State>> = OnceCell::const_new();
|
||||
|
||||
|
|
|
|||
|
|
@ -246,21 +246,26 @@ pub struct ManagedVersionFile {
|
|||
}
|
||||
|
||||
impl ManagedVersionFile {
|
||||
#[tracing::instrument]
|
||||
pub async fn download_to_cluster(
|
||||
&self,
|
||||
cluster: &Cluster,
|
||||
) -> crate::Result<()> {
|
||||
tracing::info!("downloading mod '{}' to cluster '{}'", self.file_name, cluster.meta.name);
|
||||
let path = cluster.get_full_path().await?.join("mods").join(&self.file_name);
|
||||
let state = State::get().await?;
|
||||
#[tracing::instrument]
|
||||
pub async fn download_to_cluster(&self, cluster: &Cluster) -> crate::Result<()> {
|
||||
tracing::info!(
|
||||
"downloading mod '{}' to cluster '{}'",
|
||||
self.file_name,
|
||||
cluster.meta.name
|
||||
);
|
||||
let path = cluster
|
||||
.get_full_path()
|
||||
.await?
|
||||
.join("mods")
|
||||
.join(&self.file_name);
|
||||
let state = State::get().await?;
|
||||
|
||||
// TODO: Implement hashes
|
||||
let bytes = http::fetch(&self.url, None, &state.fetch_semaphore).await?;
|
||||
http::write(&path, &bytes, &state.io_semaphore).await?;
|
||||
// TODO: Implement hashes
|
||||
let bytes = http::fetch(&self.url, None, &state.fetch_semaphore).await?;
|
||||
http::write(&path, &bytes, &state.io_semaphore).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Universal interface for managed package dependencies.
|
||||
|
|
|
|||
|
|
@ -14,5 +14,5 @@ authors = { workspace = true }
|
|||
onelauncher = { path = "../core", features = [ "cli" ] }
|
||||
|
||||
tokio = { workspace = true }
|
||||
webbrowser = { version = "0.8" }
|
||||
url = { version = "2.5.2" }
|
||||
webbrowser = { workspace = true }
|
||||
url = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -46,19 +46,19 @@ async fn main() -> onelauncher::Result<()> {
|
|||
}
|
||||
|
||||
async fn modrinth() -> onelauncher::Result<()> {
|
||||
let state = State::get().await?;
|
||||
|
||||
let provider = Providers::Modrinth;
|
||||
let state = State::get().await?;
|
||||
let provider = Providers::Modrinth;
|
||||
let result = provider.get("oneconfig").await?;
|
||||
println!("{:#?}", result);
|
||||
|
||||
let result = provider.get("oneconfig").await?;
|
||||
println!("{:#?}", result);
|
||||
let managed_version = provider
|
||||
.get_version_for_game_version(&result.id, "1.8.9")
|
||||
.await?;
|
||||
println!("{:#?}", result);
|
||||
|
||||
let managed_version = provider.get_version_for_game_version(&result.id, "1.8.9").await?;
|
||||
println!("{:#?}", result);
|
||||
|
||||
let name = "forge 1.8.9 oneconfig".to_string();
|
||||
let game = "1.8.9".to_string();
|
||||
let loader = Loader::Forge;
|
||||
let name = "Example".to_string();
|
||||
let game = "1.21".to_string();
|
||||
let loader = Loader::Fabric;
|
||||
|
||||
let cluster_path = create_cluster(
|
||||
name.clone(),
|
||||
|
|
@ -73,16 +73,23 @@ async fn modrinth() -> onelauncher::Result<()> {
|
|||
)
|
||||
.await?;
|
||||
|
||||
let cluster = cluster::get(&cluster_path, None).await?.expect("couldnt get cluster");
|
||||
managed_version.files.first().expect("no files found").download_to_cluster(&cluster).await?;
|
||||
let cluster = cluster::get(&cluster_path, None)
|
||||
.await?
|
||||
.expect("couldnt get cluster");
|
||||
managed_version
|
||||
.files
|
||||
.first()
|
||||
.expect("no files found")
|
||||
.download_to_cluster(&cluster)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn launch_and_authenticate() -> onelauncher::Result<()> {
|
||||
let state = State::get().await?;
|
||||
let state = State::get().await?;
|
||||
|
||||
if minecraft::users().await?.is_empty() {
|
||||
if minecraft::users().await?.is_empty() {
|
||||
println!("authenticating");
|
||||
authenticate_mc().await?;
|
||||
}
|
||||
|
|
@ -137,5 +144,5 @@ async fn launch_and_authenticate() -> onelauncher::Result<()> {
|
|||
let mut proc = c_lock.write().await;
|
||||
processor::wait_for(&mut proc).await?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@ export default petal({
|
|||
{
|
||||
rules: {
|
||||
'petal/consistent-list-newline': 'off',
|
||||
'no-console': 'off',
|
||||
'new-cap': 'off',
|
||||
// temporarily off
|
||||
'unused-imports/no-unused-vars': 'off',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
"gui": "pnpm --filter @onelauncher/gui -- ",
|
||||
"client": "pnpm --filter @onelauncher/client --",
|
||||
"tauri": "pnpm gui tauri",
|
||||
"format": "pnpm lint:fix && cargo +nightly fmt",
|
||||
"lint": "pnpm eslint . --cache",
|
||||
"lint:fix": "pnpm lint --fix",
|
||||
"release:node": "pnpm bumpp -r",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"sideEffects": false,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"@rspc/client": "^0.2.3",
|
||||
"@rspc/solid-query": "^0.2.3",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"tauri": "tsx tauri.ts"
|
||||
"tauri": "pnpm tsx tauri.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flowr/utils": "^3.10.0",
|
||||
|
|
|
|||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
|
|
@ -81,8 +81,8 @@ importers:
|
|||
specifier: ^2.0.0-beta.13
|
||||
version: 2.0.0-beta.14
|
||||
'@tauri-apps/plugin-clipboard-manager':
|
||||
specifier: 2.1.0-beta.5
|
||||
version: 2.1.0-beta.5
|
||||
specifier: github:tauri-apps/tauri-plugin-clipboard-manager#v2
|
||||
version: https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/d503abbce40595d0af6b36c10439b85c640b4c53
|
||||
'@tauri-apps/plugin-shell':
|
||||
specifier: github:tauri-apps/tauri-plugin-shell#v2
|
||||
version: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/adb938ddf434547ae35f74dc1a080908da03ea96
|
||||
|
|
@ -1079,8 +1079,9 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
|
||||
'@tauri-apps/plugin-clipboard-manager@2.1.0-beta.5':
|
||||
resolution: {integrity: sha512-7YQEXRHXn5dIr/YcE7RtkoAhc6XwpqI7Qz0I3FcHn5vMbVvQ5OxKnGqEa8ZGRud6R3G9pNdnEKglLXLgUXK8tA==}
|
||||
'@tauri-apps/plugin-clipboard-manager@https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/d503abbce40595d0af6b36c10439b85c640b4c53':
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/d503abbce40595d0af6b36c10439b85c640b4c53}
|
||||
version: 2.1.0-beta.5
|
||||
|
||||
'@tauri-apps/plugin-shell@https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/adb938ddf434547ae35f74dc1a080908da03ea96':
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/adb938ddf434547ae35f74dc1a080908da03ea96}
|
||||
|
|
@ -4213,7 +4214,7 @@ snapshots:
|
|||
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.20
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.20
|
||||
|
||||
'@tauri-apps/plugin-clipboard-manager@2.1.0-beta.5':
|
||||
'@tauri-apps/plugin-clipboard-manager@https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/d503abbce40595d0af6b36c10439b85c640b4c53':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.0.0-beta.15
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue